diff --git a/package-lock.json b/package-lock.json index a9c6e3f766..53db615de6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -113,6 +113,7 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -3845,6 +3846,7 @@ "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -5705,6 +5707,7 @@ "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -10118,6 +10121,7 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" @@ -10163,7 +10167,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -10181,7 +10184,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -10199,7 +10201,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -10217,7 +10218,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -10235,7 +10235,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -10253,7 +10252,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -10271,7 +10269,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -10289,7 +10286,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -10307,7 +10303,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -10325,7 +10320,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -10833,6 +10827,7 @@ "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -10940,6 +10935,7 @@ "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -11012,6 +11008,7 @@ "integrity": "sha512-83zBE6+XUVXsdL3iFzOyUewdauaU+KviKCHEGOgSW52coAuqW7tEKQM0E9+ZC0Zk6TELQ2/JgogPvp7FavzFwg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -11231,6 +11228,7 @@ "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.1.0", "@typescript-eslint/types": "7.1.0", @@ -11780,6 +11778,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -11907,6 +11906,7 @@ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -13037,6 +13037,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -15497,34 +15498,6 @@ "node": ">= 0.4.0" } }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/cosmiconfig-typescript-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", @@ -15796,6 +15769,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", @@ -16641,7 +16615,8 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1211954.tgz", "integrity": "sha512-f6BRhngr9wpHN8omZOoSaEJFscTL+tjNhmeBqHHC3CZ3K2N75sDeKXZeTkAEkTCcrusDatfwjRRBh0uz4ov/sA==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/diff-sequences": { "version": "29.6.3", @@ -17099,31 +17074,6 @@ "node": ">= 0.8" } }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -17154,6 +17104,7 @@ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-colors": "^4.1.1" }, @@ -17297,6 +17248,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -17841,6 +17793,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -18614,6 +18567,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -19007,6 +18961,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -22101,6 +22056,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -25500,6 +25456,7 @@ "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.15.0.tgz", "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -26571,6 +26528,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "@nrwl/tao": "18.0.7", "@yarnpkg/lockfile": "^1.1.0", @@ -28001,6 +27959,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -28099,6 +28058,7 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.9.0.tgz", "integrity": "sha512-jO6/OvCRL+OT8gst/+Q2ir7dMybZAX8ioP02Zmzh3BkQMHLyqZSujvxbUriXvHi8qmhcHKC2Gwbog6Kt+YTh+Q==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -28716,6 +28676,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -28742,6 +28703,7 @@ "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -32822,6 +32784,7 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -33478,6 +33441,7 @@ "integrity": "sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -33599,6 +33563,7 @@ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", diff --git a/packages/snap-preact-demo/public/snap/bundle.html b/packages/snap-preact-demo/public/snap/bundle.html index 348534d216..f8b5eb580e 100644 --- a/packages/snap-preact-demo/public/snap/bundle.html +++ b/packages/snap-preact-demo/public/snap/bundle.html @@ -1,231 +1,284 @@ - - + + - + + + + Product Detail Page - - - - - - - - - - + - - -
-
- -
- - -
- -
-
-
- -
-
-
-
- -
- - -
-
- - + - + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/cart.html b/packages/snap-preact-demo/public/snap/cart.html index e855a6c50d..bd32766fe2 100644 --- a/packages/snap-preact-demo/public/snap/cart.html +++ b/packages/snap-preact-demo/public/snap/cart.html @@ -1,262 +1,300 @@ - - + + - - Cart Page - - - - - - - - - + + +
+
+ Skip to main content + +
+
+ +
+
+
+ + + + +
+
+
+
+ +
+
+ +
+
+
+ + +
+
+
- -
-
-
- -
-
-
-
+
+
+
+
+

Total price: $84.00

- -
+
+
+ +
-
-
-
-
-
-

Total price: $84.00

-
-
-
-
-
-
-
-

Stripe Out White Off-The-Shoulder Dress

-
-
$48.00
-
-
-
-
-
-
-
-
-
-
-

Answer To Your Layers Butterscotch Yellow Top

-
-
$36.00
-
-
-
- -
-
- -
+
+
+

Stripe Out White Off-The-Shoulder Dress

+
+
$48.00
+
+ + +
+
+
- -
- +
+
+ +
-
- - + - - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/images-logo-stacked.svg b/packages/snap-preact-demo/public/snap/images-logo-stacked.svg new file mode 100644 index 0000000000..e753a7fc36 --- /dev/null +++ b/packages/snap-preact-demo/public/snap/images-logo-stacked.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/images-logo.svg b/packages/snap-preact-demo/public/snap/images-logo.svg new file mode 100644 index 0000000000..8ef58ba7f2 --- /dev/null +++ b/packages/snap-preact-demo/public/snap/images-logo.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/index.html b/packages/snap-preact-demo/public/snap/index.html index e36e3c2d9f..fea1f05684 100644 --- a/packages/snap-preact-demo/public/snap/index.html +++ b/packages/snap-preact-demo/public/snap/index.html @@ -1,227 +1,236 @@ - - + - + + + + Search Results - - - - - - - - - + - - - - - Skip to main content - -
-
-
-
+
+
+
+
+
+
    +
  • Home
  • +
  • + + + + + +
  • +
  • Search results
  • +
+
+
-
-
-
-
    -
  • Home
  • -
  • -
  • Search Results
  • -
+
+ + +
+
+

Content to be hidden!

+
+
+
+
-
- +
- -
-
-

Content to be hidden!

+ + -
- - - - - - - + +
+
+

Login

+ +
- -
- - - - - - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/order.html b/packages/snap-preact-demo/public/snap/order.html index 894f27810b..6807a69407 100644 --- a/packages/snap-preact-demo/public/snap/order.html +++ b/packages/snap-preact-demo/public/snap/order.html @@ -1,233 +1,255 @@ - - + + - - Order Confirmation - - - - - - - - - - + - - -
-
- -
- - -
- -
-
-
-
-
-
-

Order Confirmation

-
    -
  • C-BP-G7-B1469, qty: 1, price: 22
  • -
  • C-VJ-P2-32007, qty: 1, price: 39
  • -
- Total price: $61.00 -
-
-
- -
-
-
- - - - + + + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/product.html b/packages/snap-preact-demo/public/snap/product.html index 8a326736a4..acf9db9f19 100644 --- a/packages/snap-preact-demo/public/snap/product.html +++ b/packages/snap-preact-demo/public/snap/product.html @@ -1,242 +1,295 @@ - - + + - + + + + Product Detail Page - - - - - - - - - - + - - -
-
- -
- - -
- -
-
-
- -
-
-
-
- -
- -
- - -
-
- - - - + + + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/recommendations.html b/packages/snap-preact-demo/public/snap/recommendations.html index 37c9985f91..d7f225a8ac 100644 --- a/packages/snap-preact-demo/public/snap/recommendations.html +++ b/packages/snap-preact-demo/public/snap/recommendations.html @@ -1,248 +1,299 @@ - - + + - + + + + Product Detail Page - - - - - - - - - - + + +
+
+ Skip to main content + +
+
+ +
+
+
+ + + + +
+
+
+
+ +
+
+ +
+
+
+ + +
+
+
- -
- - - -
- -
-
-
- -
-
-
-
- -
- -
stuff...
- - +
+
+
+
+
+
    +
  • Home
  • +
  • + + + + + +
  • +
  • Stripe Out White Off-The-Shoulder Dress
  • +
+
+
+ +
+

Stripe Out White Off-The-Shoulder Dress

+
+ +
+
+
+
+ +
+ Stripe Out White Off-The-Shoulder Dress +
+
+
+ +
+
+

+ Are you Stripe Out of ideas for what to wear this weekend on that trip you've got coming up with + your friends? Afraid you'll be the odd one out and everyone else will be all cute and trendy and + there you'll be ... not trendy and wearing the same old things you've been wearing on this + annual getaway for years? Lucky for you, here's the dress you've been searching for. Doesn't + matter what else you pack (it does, you'll want to continue to shop with us, we were just being + nice) this is the piece that will set you apart from everyone else (that is absolutely true, you + will be a Goddess among women). Take that, bad fashion moments of the past! Striped dress + features 3/4 sleeve bell sleeves with a partially elastic/open back. Model is wearing a small. • + 97% Cotton 3% Spandex • Machine Wash Cold... +

+
+
+
+
+ +
+
+
+

Stripe Out White Off-The-Shoulder Dress

+
+

+ $50.00 + $48.00 +

+ +
+
+
+
- +
+
stuff...
- -
-
+ - - - + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/website.css b/packages/snap-preact-demo/public/snap/website.css index 5921c38c9d..085c40aadd 100644 --- a/packages/snap-preact-demo/public/snap/website.css +++ b/packages/snap-preact-demo/public/snap/website.css @@ -1,774 +1,1760 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ +/* NORMALIZE +========================================================================== */ + +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document - ========================================================================== */ +========================================================================== */ /** - * 1. Correct the line height in all browsers. - * 2. Prevent adjustments of font size after orientation changes in iOS. - */ +* 1. Correct the line height in all browsers. +* 2. Prevent adjustments of font size after orientation changes in iOS. +*/ html { - line-height: 1.15; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ } + line-height: 1.15; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ +} /* Sections - ========================================================================== */ +========================================================================== */ /** - * Remove the margin in all browsers. - */ +* Remove the margin in all browsers. +*/ body { - margin: 0; } + margin: 0; +} + +/** +* Render the `main` element consistently in IE. +*/ +main { + display: block; +} /** - * Correct the font size and margin on `h1` elements within `section` and - * `article` contexts in Chrome, Firefox, and Safari. - */ +* Correct the font size and margin on `h1` elements within `section` and +* `article` contexts in Chrome, Firefox, and Safari. +*/ h1 { - font-size: 2em; - margin: 0.67em 0; } + font-size: 2em; + margin: 0.67em 0; +} /* Grouping content - ========================================================================== */ +========================================================================== */ /** - * 1. Add the correct box sizing in Firefox. - * 2. Show the overflow in Edge and IE. - */ +* 1. Add the correct box sizing in Firefox. +* 2. Show the overflow in Edge and IE. +*/ hr { - box-sizing: content-box; - /* 1 */ - height: 0; - /* 1 */ - overflow: visible; - /* 2 */ } + box-sizing: content-box; + /* 1 */ + height: 0; + /* 1 */ + overflow: visible; + /* 2 */ +} /** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ +* 1. Correct the inheritance and scaling of font size in all browsers. +* 2. Correct the odd `em` font sizing in all browsers. +*/ pre { - font-family: monospace, monospace; - /* 1 */ - font-size: 1em; - /* 2 */ } + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} /* Text-level semantics - ========================================================================== */ +========================================================================== */ /** - * Remove the gray background on active links in IE 10. - */ +* Remove the gray background on active links in IE 10. +*/ a { - background-color: transparent; } + background-color: transparent; +} /** - * 1. Remove the bottom border in Chrome 57- - * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. - */ +* 1. Remove the bottom border in Chrome 57- +* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. +*/ abbr[title] { - border-bottom: none; - /* 1 */ - text-decoration: underline; - /* 2 */ - text-decoration: underline dotted; - /* 2 */ } + border-bottom: none; + /* 1 */ + text-decoration: underline; + /* 2 */ + text-decoration: underline dotted; + /* 2 */ +} /** - * Add the correct font weight in Chrome, Edge, and Safari. - */ -b, -strong { - font-weight: bolder; } +* Add the correct font weight in Chrome, Edge, and Safari. +*/ +b, strong { + font-weight: bolder; +} /** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ -code, -kbd, -samp { - font-family: monospace, monospace; - /* 1 */ - font-size: 1em; - /* 2 */ } +* 1. Correct the inheritance and scaling of font size in all browsers. +* 2. Correct the odd `em` font sizing in all browsers. +*/ +code, kbd, samp { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} /** - * Add the correct font size in all browsers. - */ +* Add the correct font size in all browsers. +*/ small { - font-size: 80%; } + font-size: 80%; +} /** - * Prevent `sub` and `sup` elements from affecting the line height in - * all browsers. - */ -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; } +* Prevent `sub` and `sup` elements from affecting the line height in +* all browsers. +*/ +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} sub { - bottom: -0.25em; } + bottom: -0.25em; +} sup { - top: -0.5em; } + top: -0.5em; +} /* Embedded content - ========================================================================== */ +========================================================================== */ /** - * Remove the border on images inside links in IE 10. - */ +* Remove the border on images inside links in IE 10. +*/ img { - border-style: none; } + border-style: none; +} /* Forms - ========================================================================== */ +========================================================================== */ /** - * 1. Change the font styles in all browsers. - * 2. Remove the margin in Firefox and Safari. - */ -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - line-height: 1.15; - /* 1 */ - margin: 0; - /* 2 */ } +* 1. Change the font styles in all browsers. +* 2. Remove the margin in Firefox and Safari. +*/ +button, input, optgroup, select, textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} /** - * Show the overflow in IE. - * 1. Show the overflow in Edge. - */ -button, -input { - /* 1 */ - overflow: visible; } +* Show the overflow in IE. +* 1. Show the overflow in Edge. +*/ +button, input { + overflow: visible; /* 1 */ +} /** - * Remove the inheritance of text transform in Edge, Firefox, and IE. - * 1. Remove the inheritance of text transform in Firefox. - */ -button, -select { - /* 1 */ - text-transform: none; } +* Remove the inheritance of text transform in Edge, Firefox, and IE. +* 1. Remove the inheritance of text transform in Firefox. +*/ +button, select { + text-transform: none; /* 1 */ +} /** - * Correct the inability to style clickable types in iOS and Safari. - */ -button, -[type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; } +* Correct the inability to style clickable types in iOS and Safari. +*/ +button, [type=button], [type=reset], [type=submit] { + -webkit-appearance: button; +} /** - * Remove the inner border and padding in Firefox. - */ -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; } +* Remove the inner border and padding in Firefox. +*/ +button::-moz-focus-inner, [type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner { + border-style: none; + padding: 0; +} /** - * Restore the focus styles unset by the previous rule. - */ -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; } +* Restore the focus styles unset by the previous rule. +*/ +button:-moz-focusring, [type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring { + outline: 1px dotted ButtonText; +} /** - * Correct the padding in Firefox. - */ +* Correct the padding in Firefox. +*/ fieldset { - padding: 0.35em 0.75em 0.625em; } + padding: 0.35em 0.75em 0.625em; +} /** - * 1. Correct the text wrapping in Edge and IE. - * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. - */ +* 1. Correct the text wrapping in Edge and IE. +* 2. Correct the color inheritance from `fieldset` elements in IE. +* 3. Remove the padding so developers are not caught out when they zero out +* `fieldset` elements in all browsers. +*/ legend { - /* 1 */ - color: inherit; - /* 2 */ - display: table; - /* 1 */ - max-width: 100%; - /* 1 */ - padding: 0; - /* 3 */ - white-space: normal; - /* 1 */ } + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} /** - * Add the correct vertical alignment in Chrome, Firefox, and Opera. - */ +* Add the correct vertical alignment in Chrome, Firefox, and Opera. +*/ progress { - vertical-align: baseline; } + vertical-align: baseline; +} /** - * Remove the default vertical scrollbar in IE 10+. - */ +* Remove the default vertical scrollbar in IE 10+. +*/ textarea { - overflow: auto; } + overflow: auto; +} /** - * 1. Add the correct box sizing in IE 10. - * 2. Remove the padding in IE 10. - */ -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; - /* 1 */ - padding: 0; - /* 2 */ } +* 1. Add the correct box sizing in IE 10. +* 2. Remove the padding in IE 10. +*/ +[type=checkbox], +[type=radio] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} /** - * Correct the cursor style of increment and decrement buttons in Chrome. - */ -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; } +* Correct the cursor style of increment and decrement buttons in Chrome. +*/ +[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button { + height: auto; +} /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. - */ -[type="search"] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ } +* 1. Correct the odd appearance in Chrome and Safari. +* 2. Correct the outline style in Safari. +*/ +[type=search] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} /** - * Remove the inner padding in Chrome and Safari on macOS. - */ -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } +* Remove the inner padding in Chrome and Safari on macOS. +*/ +[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} /** - * 1. Correct the inability to style clickable types in iOS and Safari. - * 2. Change font properties to `inherit` in Safari. - */ +* 1. Correct the inability to style clickable types in iOS and Safari. +* 2. Change font properties to `inherit` in Safari. +*/ ::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ } + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} /* Interactive - ========================================================================== */ +========================================================================== */ /* - * Add the correct display in Edge, IE 10+, and Firefox. - */ +* Add the correct display in Edge, IE 10+, and Firefox. +*/ details { - display: block; } + display: block; +} /* - * Add the correct display in all browsers. - */ +* Add the correct display in all browsers. +*/ summary { - display: list-item; } + display: list-item; +} /* Misc - ========================================================================== */ +========================================================================== */ /** - * Add the correct display in IE 10+. - */ +* Add the correct display in IE 10+. +*/ template { - display: none; } + display: none; +} /** - * Add the correct display in IE 10. - */ +* Add the correct display in IE 10. +*/ [hidden] { - display: none; } + display: none; +} + +/* DEMO - BASE STYLES +========================================================================== */ -/* Base Styles -============================================== */ +*, *:before, *:after { + box-sizing: border-box; +} html, body { - min-height: 100%; } + height: 100%; + min-height: 100%; +} html { - font-size: 16px; } + font-size: 16px; +} body { - height: 100%; - -webkit-print-color-adjust: exact; - -webkit-tap-highlight-color: rgba(255, 255, 255, 0); - backface-visibility: hidden; - background-attachment: fixed; - font-family: 'Roboto', Helvetica, Arial; - font-size: 14px; - line-height: 1.5; - color: #3f3e40; } + height: 100%; + -webkit-print-color-adjust: exact; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + backface-visibility: hidden; + background-attachment: fixed; + font-size: 14px; + line-height: 1.5; +} img { - max-width: 100%; - width: auto; - height: auto; - display: block; } + max-width: 100%; + width: auto; + height: auto; + display: block; +} a { - color: #4c3ce2; - text-decoration: none; } - a:hover { - color: #3f3e40; } + text-decoration: none; +} ul { - list-style: none; - padding: 0; } + list-style: none; + padding: 0; +} h1, h2, h3, h4, h5, h6, p, ul { - margin: 0 0 20px 0; } - -h1, h2, h3, h4, h5, h6, .ss-lite-title { - font-weight: 700; - font-family: 'Roboto', Helvetica, Arial; } + margin: 0 0 20px 0; +} h1 { - font-size: 26px; } + font-size: 28px; +} h2 { - font-size: 24px; } + font-size: 26px; +} h3 { - font-size: 22px; } + font-size: 22px; +} h4 { - font-size: 20px; } + font-size: 20px; +} h5, h6 { - font-size: 18px; } + font-size: 18px; +} -hr { - border: 0; - border-top: 1px solid #ebebeb; } +.ss__demo { + height: 100%; +} + +.ss__demo .ss__demo__main { + min-height: 400px; +} + +.ss__demo .ss__demo__theme .ss__demo__pointer { + cursor: pointer; +} + +.ss__demo .ss__demo__theme .ss__demo__icon { + -webkit-flex-flow: column nowrap; + flex-flow: column nowrap; + display: -webkit-inline-flex; + display: -ms-inline-flex; + display: -moz-inline-flex; + display: inline-flex; + -webkit-flex: 0 0 auto; + -ms-flex: 0 0 auto; + -moz-flex: 0 0 auto; + flex: 0 0 auto; + width: 16px; + height: 16px; + line-height: 16px; +} + +.ss__demo .ss__demo__theme .ss__demo__icon .ss__icon { + margin: auto; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; + line-height: 1; + fill: currentColor; +} + +/* DEMO - TYPOGRAPHY +========================================================================== */ + +.ss__pike { + font-family: "Roboto", Helvetica, Arial; +} + +.ss__pike .ss__demo .ss__demo__theme { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme a { + color: #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme a:hover { + color: #515151; +} + +.ss__pike h1, .ss__pike h2, +.ss__pike h3, .ss__pike h4, +.ss__pike h5, .ss__pike h6 { + font-family: "Roboto", Helvetica, Arial; + font-weight: 700; +} + +.ss__pike .ss__demo .ss__demo__theme h1, .ss__pike .ss__demo .ss__demo__theme h2, +.ss__pike .ss__demo .ss__demo__theme h3, .ss__pike .ss__demo .ss__demo__theme h4, +.ss__pike .ss__demo .ss__demo__theme h5, .ss__pike .ss__demo .ss__demo__theme h6 { + color: #1d4990; +} + +.ss__everest { + font-family: "Source Sans 3", Helvetica, Arial; +} + +.ss__everest .ss__demo .ss__demo__theme { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme a { + color: #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme a:hover { + color: #515151; +} + +.ss__everest h1, .ss__everest h2, +.ss__everest h3, .ss__everest h4, +.ss__everest h5, .ss__everest h6 { + font-family: "Montserrat", Helvetica, Arial; + font-weight: 600; + text-transform: uppercase; +} + +.ss__everest .ss__demo .ss__demo__theme h1, .ss__everest .ss__demo .ss__demo__theme h2, +.ss__everest .ss__demo .ss__demo__theme h3, .ss__everest .ss__demo .ss__demo__theme h4, +.ss__everest .ss__demo .ss__demo__theme h5, .ss__everest .ss__demo .ss__demo__theme h6 { + color: #94280b; +} + +.ss__matterhorn { + font-family: "Poppins", Helvetica, Arial; +} + +.ss__matterhorn .ss__demo .ss__demo__theme { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme a { + color: #222222; +} + +.ss__matterhorn .ss__demo .ss__demo__theme a:hover { + color: #555555; +} + +.ss__matterhorn h1, .ss__matterhorn h2, +.ss__matterhorn h3, .ss__matterhorn h4, +.ss__matterhorn h5, .ss__matterhorn h6 { + font-family: "Lora", "Times New Roman", serif; + font-weight: 300; + font-style: italic; +} + +.ss__matterhorn .ss__demo .ss__demo__theme h1, .ss__matterhorn .ss__demo .ss__demo__theme h2, +.ss__matterhorn .ss__demo .ss__demo__theme h3, .ss__matterhorn .ss__demo .ss__demo__theme h4, +.ss__matterhorn .ss__demo .ss__demo__theme h5, .ss__matterhorn .ss__demo .ss__demo__theme h6 { + color: #222222; +} + +/* DEMO - FORM FIELDS +========================================================================== */ + +input, button, select { + padding: 0; + margin: 0; + border: 0; +} + +input, .ss__demo__button, select { + height: 40px; + line-height: 40px; + padding: 0 20px; +} -/* Form fields -============================================== */ input::-webkit-input-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input:-moz-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input::-moz-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input:-ms-input-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input :focus::-webkit-input-placeholder { - color: #3f3e40; } - -input :focus:-moz-placeholder { - color: #3f3e40; } - -input :focus::-moz-placeholder { - color: #3f3e40; } - -input :focus:-ms-input-placeholder { - color: #3f3e40; } - -input[type='text'], button { - border: 0; - line-height: 1; } + -webkit-transition: color 0.3s ease-in-out; + -o-transition: color 0.3s ease-in-out; + -ms-transition: color 0.3s ease-in-out; + -moz-transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; +} + +input::-ms-input-placeholder { + -webkit-transition: color 0.3s ease-in-out; + -o-transition: color 0.3s ease-in-out; + -ms-transition: color 0.3s ease-in-out; + -moz-transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; +} + +input::placeholder { + -webkit-transition: color 0.3s ease-in-out; + -o-transition: color 0.3s ease-in-out; + -ms-transition: color 0.3s ease-in-out; + -moz-transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; +} button { - padding: 7px 20px; - color: #ffffff; - background: #3a23ad; - font-size: 18px; - border: none; - font-weight: bold; - cursor: pointer; } - button:hover { - color: white; - background: #4e37c1; } - -input[type='text'] { - color: #3f3e40; - padding: 10px; - box-sizing: border-box; - min-height: 40px; } - -/* Layout -============================================== */ -.ss-lite-wrapper { - margin: 0 auto; - padding: 0 20px; - max-width: 1200px; - width: auto; } - -.ss-lite-flex-wrap, .ss-lite-flex-wrap-center { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: row wrap; - -ms-flex-flow: row wrap; - flex-flow: row wrap; } - -.ss-lite-flex-nowrap, .ss-lite-flex-nowrap-center { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: row nowrap; - -ms-flex-flow: row nowrap; - flex-flow: row nowrap; } - -.ss-lite-flex-wrap-center, .ss-lite-flex-nowrap-center { - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - -ms-grid-row-align: center; - align-items: center; } - -.ss-lite-row-5 { - margin: 0 -5px; } - .ss-lite-row-5 > .ss-lite-col { - padding: 0 5px; } - -.ss-lite-row-10 { - margin: 0 -10px; } - .ss-lite-row-10 > .ss-lite-col { - padding: 0 10px; } - -.ss-lite-row-20 { - margin: 0 -20px; } - .ss-lite-row-20 > .ss-lite-col { - padding: 0 20px; } - -.clear { - clear: both; } - -/* Faded background -============================================== */ -.ss-lite-header { - background-color: #f8f8f8; } - .ss-lite-header, .ss-lite-header .ss-lite-wrapper { - position: relative; } - .ss-lite-header .ss-lite-wrapper { - padding: 20px; } - -/* Header -============================================== */ -.ss-lite-header .ss-lite-subheader { - text-transform: uppercase; - color: #00cee1; } - -.ss-lite-header .ss-lite-icon { - font-size: 20px; - color: #4c3ce2; } - -.ss-lite-header .ss-lite-header-logo { - width: 250px; } - .ss-lite-header .ss-lite-header-logo .st0 { - fill: url(#SVGID_1_); } - .ss-lite-header .ss-lite-header-logo .st1 { - fill: url(#SVGID_2_); } - .ss-lite-header .ss-lite-header-logo .st2 { - fill: #515151; } - .ss-lite-header .ss-lite-header-logo a { - text-align: right; - display: block; - line-height: 0; } - .ss-lite-header .ss-lite-header-logo svg { - max-width: 100%; } - -.ss-lite-header .ss-lite-header-buttons { - width: 840px; - margin: 0 0 0 auto; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar { - -webkit-box-flex: 1; - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - position: relative; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar .ss-lite-input[type='text'] { - border: 1px solid #ebebeb; - width: 100%; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar .ss-lite-input[type='text']::placeholder { - color: #c9c9c9; - font-weight: 100; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar .ss-lite-button { - background-color: transparent; - padding: 0; - position: absolute; - top: 0; - bottom: 0; - right: 10px; - margin: auto; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons { - margin: 0 0 0 15px; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons a { - position: relative; - padding: 0 5px; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons .ss-lite-cart-count { - position: absolute; - top: 6px; - right: -6px; - color: #ffffff; - font-size: 12px; - font-weight: bold; - width: 20px; - height: 20px; - line-height: 20px; - text-align: center; - display: inline-block; - background: #00cee1; - border-radius: 100%; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons .ss-lite-cart-count:hover { - color: white; - background: #4e37c1; } - -/* Navigation -============================================== */ -.ss-lite-navigation { - background-color: #3a23ad; - border-top: 5px solid #4c3ce2; } - .ss-lite-navigation .ss-lite-list { - margin: 0 -20px -10px -20px; - text-align: center; } - .ss-lite-navigation .ss-lite-list li { - display: inline-block; - zoom: 1; - *display: inline; - vertical-align: middle; - padding: 0 20px 10px 20px; } - .ss-lite-navigation .ss-lite-list li a { - color: #ffffff; - font-size: 16px; - font-weight: bold; - text-transform: uppercase; } - .ss-lite-navigation .ss-lite-list li a.active { - border-bottom: 2px solid #00cee1; } - .ss-lite-navigation .ss-lite-list li a:hover { - color: #00cee1; } - -/* Main -============================================== */ - -.ss-lite-main { - flex: 1; - min-height: 500px; - padding: 40px 0; } - -.ss-lite-breadcrumbs .ss-lite-list { - margin: 0 -5px 40px -5px; } - .ss-lite-breadcrumbs .ss-lite-list li { - padding: 0 5px; - display: inline-block; - zoom: 1; - *display: inline; - vertical-align: middle; } - -.ss-lite-main-layout { - min-height: 600px; } - .ss-lite-main-layout .ss-lite-sidebar { - -webkit-box-flex: 0; - -webkit-flex: 0 0 250px; - -ms-flex: 0 0 250px; - flex: 0 0 250px; - max-width: 250px; - margin: 0 40px 0 0; } - .ss-lite-main-layout .ss-lite-content { - width: 100%; - min-width: 0; - } - -/* Footer -============================================== */ -.ss-lite-footer { - padding: 20px 0; - background-color: #3a23ad; - border-top: 5px solid #4c3ce2; } - .ss-lite-footer, .ss-lite-footer a, .ss-lite-footer p, .ss-lite-footer .ss-lite-title { - color: #ffffff; } - .ss-lite-footer a:hover { - color: #00cee1; } - .ss-lite-footer .ss-lite-col { - -webkit-box-flex: 1; - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } - .ss-lite-footer .ss-lite-col .ss-lite-title { - text-transform: uppercase; - font-size: 16px; - margin: 0 0 10px 0; - padding: 0 0 10px 0; - border-bottom: 1px solid #4c3ce2; } - .ss-lite-footer .ss-lite-col .ss-lite-title .ss-lite-icon { - margin: 0 10px 0 0; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit .ss-lite-list li { - display: inline-block; - margin-right: 10px; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit a { - display: inline-block; - zoom: 1; - *display: inline; - vertical-align: middle; - width: 30px; - height: 30px; - background: #4c3ce2; - text-align: center; - -webkit-border-radius: 100%; - -moz-border-radius: 100%; - -ms-border-radius: 100%; - -o-border-radius: 100%; - border-radius: 100%; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit a:hover { - color: #ffffff; - background-color: #00cee1; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit a i { - line-height: 30px; - font-size: 16px; } - -/* Footer Copyright -============================================== */ -.ss-lite-footer-copyright { - padding: 30px 0 0; - text-align: center; } - .ss-lite-footer-copyright p { - margin: 0; } - .ss-lite-footer-copyright p:first-child { - margin: 0 0 2.5px 0; } - -/* Responsive -============================================== */ -@media only screen and (max-width: 991px) { - .ss-lite-footer .ss-lite-col, .ss-lite-footer .ss-lite-footer-information { - -webkit-box-flex: 1; - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - width: 50%; } - .ss-lite-header > .ss-lite-wrapper > .ss-lite-flex-wrap-center { - display: block; } - .ss-lite-header .ss-lite-header-logo, .ss-lite-header .ss-lite-header-buttons { - width: auto; } - .ss-lite-header .ss-lite-header-logo { - max-width: 250px; - margin: 0 auto 20px auto; } - .ss-lite-main .ss-lite-flex-nowrap { - display: block; } - .ss-lite-main .ss-lite-flex-nowrap .ss-lite-sidebar { - display: none; } } - -@media only screen and (max-width: 767px) { - .ss-lite-navigation .ss-lite-list { - margin: 0 -10px -10px -10px; } - .ss-lite-navigation .ss-lite-list li { - padding: 0 10px 10px 10px; } - .ss-lite-navigation .ss-lite-list li a { - font-size: 14px; } } - -@media only screen and (max-width: 540px) { - .ss-lite-footer .ss-lite-flex-wrap { - display: block; } - .ss-lite-footer .ss-lite-col, .ss-lite-footer .ss-lite-footer-information { - width: auto; } } - -.ss-results-title .ss-oq { - font-size: 14px; - color: #3b23ad; - font-weight: normal; -} - -.ss-results-title .ss-oq em { - font-weight: bold; -} - -.ss-toolbar-row { - margin-bottom: 20px; -} - -.ss-toolbar-col { - display: inline-block; - margin: 10px 20px 10px 0; -} - -.ss-toolbar-col.pagination, -.ss-toolbar.ss-toolbar-bottom { - margin-top: 20px; - float: right; -} - -.ss-toolbar-col.pagination, -.ss-toolbar.ss-toolbar-bottom-infinite { - display: flex; - justify-content: center; -} - -.ss-slideout__button { - width: 100%; - border: 1px solid #333; - text-align: center; - padding: 10px 0; - margin: 10px 0; - font-size: 1.2em; - cursor: pointer; -} - -.ss-slider button { - color: inherit; -} -#login-modal { - background: white; - border-radius: 5px; - padding: 20px; - border: 1px solid #ccc; - width: 450px; - position: absolute; - z-index: 99999999; - top: 10%; - left: calc(50% - 225px); - box-shadow: 0px 0px 20px 0px rgb(0 0 0 / 20%); -} -#login-modal input { - width: 80%; - border: 1px solid #ccc; -} -#login-modal button { - display: block; - margin: 20px auto; -} - -.ss__autocomplete { - width: 100%; + cursor: pointer; +} + +select { + font-size: 16px; +} + +fieldset { + border: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__button { + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ss__demo .ss__demo__theme .ss__demo__input { + -webkit-flex-flow: row nowrap; + flex-flow: row nowrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; +} + +.ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__label, .ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__input { + min-width: 1px; +} + +.ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__label { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 125px; + margin: 0 10px 0 0; +} + +.ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__input { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; +} + +@media only screen and (min-width: 768px) { + select { + font-size: 14px; + } +} + +.ss__pike .ss__demo .ss__demo__theme input, .ss__pike .ss__demo .ss__demo__theme select, .ss__pike .ss__demo .ss__demo__theme .ss__demo__button { + -moz-border-radius: 0; + border-radius: 0; +} + +.ss__pike .ss__demo .ss__demo__theme input, .ss__pike .ss__demo .ss__demo__theme select { + color: #515151; + border: 2px solid #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme input::-webkit-input-placeholder, .ss__pike .ss__demo .ss__demo__theme input :focus::-webkit-input-placeholder { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme input::-ms-input-placeholder, .ss__pike .ss__demo .ss__demo__theme input :focus::-ms-input-placeholder { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme input::placeholder, .ss__pike .ss__demo .ss__demo__theme input :focus::placeholder { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__button { + background-color: #00aeef; + color: #ffffff; + font-family: "Roboto", Helvetica, Arial; + font-weight: 700; +} + +.ss__everest .ss__demo .ss__demo__theme input, .ss__everest .ss__demo .ss__demo__theme select, .ss__everest .ss__demo .ss__demo__theme .ss__demo__button { + -moz-border-radius: 3px; + border-radius: 3px; +} + +.ss__everest .ss__demo .ss__demo__theme input, .ss__everest .ss__demo .ss__demo__theme select { + color: #515151; + border: 2px solid #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme input::-webkit-input-placeholder, .ss__everest .ss__demo .ss__demo__theme input :focus::-webkit-input-placeholder { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme input::-ms-input-placeholder, .ss__everest .ss__demo .ss__demo__theme input :focus::-ms-input-placeholder { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme input::placeholder, .ss__everest .ss__demo .ss__demo__theme input :focus::placeholder { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__button { + background-color: #d15120; + color: #ffffff; + font-family: "Montserrat", Helvetica, Arial; + font-weight: 600; + text-transform: uppercase; + position: relative; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__button:after { + content: ""; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + border-bottom: 2px solid #94280b; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input, .ss__matterhorn .ss__demo .ss__demo__theme select, .ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__button { + -moz-border-radius: 0; + border-radius: 0; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input, .ss__matterhorn .ss__demo .ss__demo__theme select { + color: #555555; + border: 1px solid #111111; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input::-webkit-input-placeholder, .ss__matterhorn .ss__demo .ss__demo__theme input :focus::-webkit-input-placeholder { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input::-ms-input-placeholder, .ss__matterhorn .ss__demo .ss__demo__theme input :focus::-ms-input-placeholder { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input::placeholder, .ss__matterhorn .ss__demo .ss__demo__theme input :focus::placeholder { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__button { + background-color: #222222; + color: #ffffff; + font-family: "Lora", "Times New Roman", serif; + font-weight: 300; + font-style: italic; +} + +/* DEMO - BACKGROUND +========================================================================== */ + +.ss__demo .ss__demo__background { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; +} + +.ss__demo .ss__demo__background .ss__demo__svg { + width: 100%; + height: 100%; +} + +.ss__pike .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__background { + fill: #1d4990; +} + +.ss__pike .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__top_triangle { + stroke: #00aeef; +} + +.ss__pike .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__bottom_triangle { + stroke: #ffffff; +} + +.ss__everest .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__background { + fill: #94280b; +} + +.ss__everest .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__top_triangle { + stroke: #d15120; +} + +.ss__everest .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__bottom_triangle { + stroke: #ffffff; +} + +.ss__matterhorn .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__background { + fill: #222222; +} + +.ss__matterhorn .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__top_triangle { + stroke: #111111; +} + +.ss__matterhorn .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__bottom_triangle { + stroke: #ffffff; +} + +/* DEMO - SLIDEOUT BUTTON +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__slideout__default .ss__demo__slideout__button { + -webkit-flex-flow: row nowrap; + flex-flow: row nowrap; + display: -webkit-inline-flex; + display: -ms-inline-flex; + display: -moz-inline-flex; + display: inline-flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 5px; + gap: 5px; + height: auto; + line-height: 1; + font-size: 16px; + background-color: transparent; + padding: 0; +} + +/* DEMO - LAYOUT +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__layout { + -ms-gap: 30px; + gap: 30px; +} + +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__sidebar, +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__content { + min-width: 1px; +} + +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__sidebar { + display: none; + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 250px; +} + +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__content { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; +} + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__sidebar { + display: block; + } +} + +.ss__demo .ss__demo__wrapper { + margin: 0 auto; + padding: 0 20px; + max-width: 1200px; + width: auto; +} + +.ss__demo .ss__demo__theme .ss__demo__flex__wrap, .ss__demo .ss__demo__theme .ss__demo__flex__wrap--center { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; +} + +.ss__demo .ss__demo__theme .ss__demo__flex__nowrap, .ss__demo .ss__demo__theme .ss__demo__flex__nowrap--center { + -webkit-flex-flow: nowrap; + flex-flow: nowrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; +} + +.ss__demo .ss__demo__theme .ss__demo__flex__wrap--center, .ss__demo .ss__demo__theme .ss__demo__flex__nowrap--center { + -webkit-align-items: center; + align-items: center; +} + +.ss__demo .ss__demo__theme .ss__demo__row--5 { + -ms-gap: 5px; + gap: 5px; +} + +.ss__demo .ss__demo__theme .ss__demo__row--10 { + -ms-gap: 10px; + gap: 10px; +} + +.ss__demo .ss__demo__theme .ss__demo__row--20 { + -ms-gap: 20px; + gap: 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__row--30 { + -ms-gap: 30px; + gap: 30px; +} + +.ss__demo .ss__demo__theme .ss__demo__column { + min-width: 1px; +} + +/* DEMO - HEADER +========================================================================== */ + +.ss__demo .ss__demo__header { + padding: 40px 0; + margin: 0 0 40px 0; + position: relative; + overflow: hidden; +} + +.ss__demo .ss__demo__header .ss__demo__background { + z-index: -1; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo { + -webkit-flex: 0 0 200px; + -ms-flex: 0 0 200px; + -moz-flex: 0 0 200px; + flex: 0 0 200px; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo a { + display: block; + width: 100%; + line-height: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo img { + max-width: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search { + order: 3; + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form { + position: relative; + -webkit-flex: 1 0 auto; + -ms-flex: 1 0 auto; + -moz-flex: 1 0 auto; + flex: 1 0 auto; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__input { + width: 100%; + padding-right: 60px; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button { + background-color: transparent; + position: absolute; + top: 2px; + bottom: 2px; + right: 20px; + margin: auto; + padding: 0; + line-height: 1; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + line-height: 1; + margin-left: auto; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__icon { + width: 20px; + height: 20px; + line-height: 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__icon .ss__icon { + fill: #ffffff; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button { + position: relative; + overflow: visible; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + position: absolute; + top: 12px; + right: -6px; + z-index: 1; + color: #ffffff; + font-size: 10px; + font-weight: 700; + width: 16px; + height: 16px; + line-height: 14px; + text-align: center; + border-radius: 50%; +} + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__flex__wrap--center { + -webkit-justify-content: flex-end; + justify-content: flex-end; + } + + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo { + -webkit-flex: 0 0 300px; + -ms-flex: 0 0 300px; + -moz-flex: 0 0 300px; + flex: 0 0 300px; + margin-right: auto; + } + + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search { + order: 0; + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + max-width: 500px; + } + + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons { + margin-left: 0; + } +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button .ss__demo__icon { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + background-color: #00aeef; + border: 1px solid #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button:hover .ss__demo__cart__count { + color: #00aeef; + background-color: #ffffff; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button .ss__demo__icon { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__button:after { + display: none; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + background-color: #d15120; + border: 1px solid #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button:hover .ss__demo__cart__count { + color: #d15120; + background-color: #ffffff; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button .ss__demo__icon { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + background-color: #848484; + border: 1px solid #848484; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button:hover .ss__demo__cart__count { + color: #848484; + background-color: #ffffff; +} + +/* DEMO - NAVIGATION +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__navigation { + margin: 40px 0 0 0; + display: none; +} + +.ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 10px 20px; + gap: 10px 20px; + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-size: 16px; +} + + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__navigation { + display: block; + } +} + +@media only screen and (min-width: 992px) { + .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list { + -ms-gap: 10px 30px; + gap: 10px 30px; + } +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-family: "Roboto", Helvetica, Arial; + font-weight: 700; + color: #ffffff; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a:hover { + color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-family: "Source Sans 3", Helvetica, Arial; + font-weight: 600; + text-transform: uppercase; + color: #ffffff; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a:hover { + color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-family: "Lora", "Times New Roman", serif; + font-weight: 300; + font-style: italic; + color: #ffffff; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a:hover { + color: #555555; +} + +/* DEMO - BREADCRUMBS +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs { + margin: 0 0 30px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 10px; + gap: 10px; + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul li { + line-height: 1; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul li a { + color: #515151; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul li .ss__icon { + width: 12px; + height: 12px; + line-height: 12px; +} + +/* DEMO - HEADER TITLE +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__header__title { + margin: 0 0 30px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__header__title .ss__title { + margin: 0; +} + +/* DEMO - FOOTER +========================================================================== */ + +.ss__demo .ss__demo__footer { + padding: 40px 0; + margin: 40px 0 0 0; + position: relative; + overflow: hidden; +} + +.ss__demo .ss__demo__theme .ss__demo__footer a, .ss__demo .ss__demo__theme .ss__demo__footer p, .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + color: #ffffff; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__wrapper { + position: relative; + z-index: 2; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + font-size: 16px; + margin: 0 0 10px 0; + padding: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title .ss__demo__icon { + margin: 0 10px 0 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__list { + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__list li { + margin: 0 0 2.5px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__list li:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__column { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information p { + text-align: justify; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social { + text-align: right; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -webkit-justify-content: flex-end; + justify-content: flex-end; + -ms-gap: 10px; + gap: 10px; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + width: 30px; + height: 30px; + line-height: 30px; + -moz-border-radius: 50%; + border-radius: 50%; + text-align: center; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a:hover .ss__demo__icon .ss__icon { + fill: #ffffff; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a .ss__demo__icon { + height: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a .ss__demo__icon .ss__icon { + max-height: 16px; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright { + text-align: right; + margin: 20px 0 0 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright p { + margin: 0; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -webkit-justify-content: flex-end; + justify-content: flex-end; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright p a, .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright p span { + margin: 0 2.5px; +} + +@media only screen and (min-width: 541px) { + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__row--20 { + -ms-gap: 20px 40px; + gap: 20px 40px; + } + + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__column { + width: calc(50% - 20px); + } +} + +@media only screen and (min-width: 992px) { + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__column { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + width: auto; + } + + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information { + -webkit-flex: 0 0 400px; + -ms-flex: 0 0 400px; + -moz-flex: 0 0 400px; + flex: 0 0 400px; + } +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer { + background-color: #1d4990; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer a:hover { + color: #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + border-bottom: 2px solid #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + background-color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer { + background-color: #94280b; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer a:hover { + color: #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + border-bottom: 2px solid #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + background-color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__footer { + background-color: #222222; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__footer a:hover { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + background-color: #111111; +} + +/* DEMO - SKIP TO BUTTON +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__skip-to__button { + position: absolute; + top: -99999px; + left: -99999px; + background-color: #1d4990; + color: #ffffff; + font-size: 16px; + font-weight: 700; + text-transform: uppercase; + padding: 5px 10px; +} + +.ss__demo .ss__demo__theme .ss__skip-to__button:focus { + position: absolute; + top:0; + left: 0; + z-index: 1; +} + +/* DEMO - LOGIN MODAL +========================================================================== */ + +.ss__demo .ss__demo__theme #ss__demo__login__modal { + display: none; + background: #ffffff; + padding: 20px; + margin: 0 auto; + border: 1px solid #ebebeb; + border-radius: 15px; + box-shadow: 2px 2px 20px 0 rgba(80, 80, 100, 0.12); + width: 450px; + position: absolute; + left: 0; + right: 0; + top: 25%; + z-index: 99999999; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal.ss__demo__login__modal--active { + display: block; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header { + -webkit-flex-flow: row nowrap; + flex-flow: row nowrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 10px; + gap: 10px; + margin: 0 0 20px 0; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header .ss__demo__title { + line-height: 1; + margin: 0; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header .ss__demo__close { + background-color: rgba(0, 0, 0, 0); + border: 0; + padding: 0; + margin: 0; + margin-left: auto; + order: 10; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header .ss__demo__close .ss__icon { + fill: #515151; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__input .ss__demo__input__label { + width: auto; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__button { + display: block; + width: 100%; + margin: 20px auto 0 auto; +} + +/* DEMO - RESULT +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__result { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + -ms-gap: 30px; + gap: 30px; + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result > * { + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; + min-width: 1px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner { + position: relative; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + -ms-gap: 10px; + gap: 10px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner > * { + min-width: 1px; + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image { + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image .ss__image__link { + display: block; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image .ss__image { + position: relative; + line-height: 0; + height: 0; + padding-bottom: 150%; + overflow: hidden; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image .ss__image img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + max-width: 100%; + max-height: 100%; + -o-object-position: center center; + object-position: center center; + -o-object-fit: contain; + object-fit: contain; + width: 100%; + height: 100%; + border: 0; + display: block; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details { + text-align: left; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > p, +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > div { + margin: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > p:last-child, +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > div:last-child, +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details .ss__result__description > *:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__demo__header__title { + display: none; + margin: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__demo__header__title .ss__title { + font-size: 22px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + font-size: 16px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span ~ span { + padding-left: 5px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + text-decoration: line-through; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-size: 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__add-to-cart { + width: 100%; + height: 46px; + line-height: 46px; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + color: #737373; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-weight: 700; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price--on-sale { + color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + color: #737373; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-weight: 600; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price--on-sale { + color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + color: #848484; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-weight: 600; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price--on-sale { + color: #222222; +} + +@media only screen and (min-width: 768px) { + #ss__product__demo .ss__demo .ss__demo__theme .ss__demo__header__title { + display: none; + } + + .ss__demo .ss__demo__theme .ss__demo__result .ss__result { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + } + + .ss__demo .ss__demo__theme .ss__result .ss__result__inner { + -ms-gap: 20px; + gap: 20px; + } + + .ss__demo .ss__demo__theme .ss__result .ss__result__inner .ss__result__image { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 200px; + } + + .ss__demo .ss__demo__theme .ss__result .ss__result__inner .ss__result__details { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + } + + .ss__demo .ss__demo__theme .ss__result__side { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 300px; + } + + #ss__product__demo .ss__demo .ss__demo__theme .ss__result__side > .ss__result__details .ss__demo__header__title { + display: block; + } +} + +@media only screen and (min-width: 992px) { + .ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image { + width: 350px; + } + + .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side { + width: 350px; + } +} + +/* DEMO - CART +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product { + margin: 0 0 20px 0; + -ms-gap: 10px 20px; + gap: 10px 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image, +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details { + min-width: 1px; + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image img { + width: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details > div { + margin: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details > div:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__name { + margin-bottom: 5px; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__name h3 { + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-size: 18px; + font-weight: 700; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__actions { + -ms-gap: 10px; + gap: 10px; + max-width: 400px; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__actions .ss__demo__button { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + height: 46px; + line-height: 46px; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-weight: 700; + color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-weight: 600; + color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-weight: 600; + color: #222222; +} + +@media only screen and (min-width: 541px) { + .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image { + -webkit-flex: 0 0 150px; + -ms-flex: 0 0 150px; + -moz-flex: 0 0 150px; + flex: 0 0 150px; + } + + .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + } +} + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image { + -webkit-flex: 0 0 200px; + -ms-flex: 0 0 200px; + -moz-flex: 0 0 200px; + flex: 0 0 200px; + } } \ No newline at end of file diff --git a/packages/snap-preact-demo/public/snap/website.js b/packages/snap-preact-demo/public/snap/website.js new file mode 100644 index 0000000000..3f6244609b --- /dev/null +++ b/packages/snap-preact-demo/public/snap/website.js @@ -0,0 +1,30 @@ +var activeClass = 'ss__demo__login__modal--active'; +var modalSelector = 'ss__demo__login__modal'; +var modalInputSelector = '#ss__demo__login__modal #ss__demo__input__shopper-id'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function toggleModal() { + var modal = document.getElementById(modalSelector); + var modalInput = document.querySelector(modalInputSelector); + + if (modal.classList.contains(activeClass)) { + modal.classList.remove(activeClass); + } else { + modal.classList.add(activeClass); + modalInput.focus(); + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function setShopperID() { + var modal = document.getElementById(modalSelector); + var modalInput = document.querySelector(modalInputSelector); + var id = modalInput.value; + + if (id) { + window.searchspring.tracker.track.shopper.login({ + id: id, + }); + modal.classList.remove(activeClass); + } +} diff --git a/packages/snap-preact-demo/public/templates/bundle.html b/packages/snap-preact-demo/public/templates/bundle.html index 74ebc37725..4e9172725b 100644 --- a/packages/snap-preact-demo/public/templates/bundle.html +++ b/packages/snap-preact-demo/public/templates/bundle.html @@ -1,242 +1,294 @@ - - + + - + + + + Product Detail Page - - - - - - - - - - + - - -
- - - -
- -
-
-
- -
-
-
-
- -
- - -
stuff...
- - -
-
- - - - +
+ + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/email.html b/packages/snap-preact-demo/public/templates/email.html index e05426861d..27a32674fe 100644 --- a/packages/snap-preact-demo/public/templates/email.html +++ b/packages/snap-preact-demo/public/templates/email.html @@ -1,102 +1,96 @@ - - + + - - Email Recs - - - - - - - - - - - + const profileKey = `/api/personalized-recommendations/profile.json{"tag":"${profile}","siteId":"${siteID}","branch":"production"}`; + const recommendKey = `/v1/recommend{"tags":["${profile}"],"limits":[20],"siteId":"${siteID}"}`; - + const profileWildCardKey = `/api/personalized-recommendations/profile.json/*`; + const recommendWildCardKey = `/v1/recommend/*`; - + + + } + }); + },500)}); + - - - - + +
+ +
\ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/images-logo-stacked.svg b/packages/snap-preact-demo/public/templates/images-logo-stacked.svg new file mode 100644 index 0000000000..e753a7fc36 --- /dev/null +++ b/packages/snap-preact-demo/public/templates/images-logo-stacked.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/images-logo.svg b/packages/snap-preact-demo/public/templates/images-logo.svg new file mode 100644 index 0000000000..8ef58ba7f2 --- /dev/null +++ b/packages/snap-preact-demo/public/templates/images-logo.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/index.html b/packages/snap-preact-demo/public/templates/index.html index d5255ed8ff..48266e02c5 100644 --- a/packages/snap-preact-demo/public/templates/index.html +++ b/packages/snap-preact-demo/public/templates/index.html @@ -1,18 +1,17 @@ - - + - + + + + Search Results - - - - - - - - - + - - - - - Skip to main content - -
-
-
-
- -
-
-
-
    -
  • Home
  • -
  • -
  • Search Results
  • -
-
-
- +
+
+
+
+
+
    +
  • Home
  • +
  • + + + + + +
  • +
  • Search results
  • +
+
+
+
Content to be hidden!
-
-
-
+ - - - - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/product.html b/packages/snap-preact-demo/public/templates/product.html index 181aa08bb1..2e8fde52d4 100644 --- a/packages/snap-preact-demo/public/templates/product.html +++ b/packages/snap-preact-demo/public/templates/product.html @@ -1,18 +1,16 @@ - - + + - + + + + Product Detail Page - - - - - - - - - + + + + + - - -
-
-
- -
-
-
-
- - - + + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/recommendations.html b/packages/snap-preact-demo/public/templates/recommendations.html index 37c9985f91..a5781c21f3 100644 --- a/packages/snap-preact-demo/public/templates/recommendations.html +++ b/packages/snap-preact-demo/public/templates/recommendations.html @@ -1,248 +1,299 @@ - - + + - + + + + Product Detail Page - - - - - - - - - - + + +
+
+ Skip to main content + +
+
+ +
+
+
+ + + + +
+
+
+
+ +
+
+ +
+
+
+ + +
+
+
- -
- - - -
- -
-
-
- -
-
-
-
- -
- -
stuff...
- - +
+
+
+
+
+
    +
  • Home
  • +
  • + + + + + +
  • +
  • Stripe Out White Off-The-Shoulder Dress
  • +
+
+
+ +
+

Stripe Out White Off-The-Shoulder Dress

+
+ +
+
+
+
+ +
+ Stripe Out White Off-The-Shoulder Dress +
+
+
+ +
+
+

+ Are you Stripe Out of ideas for what to wear this weekend on that trip you've got coming up with + your friends? Afraid you'll be the odd one out and everyone else will be all cute and trendy and + there you'll be ... not trendy and wearing the same old things you've been wearing on this + annual getaway for years? Lucky for you, here's the dress you've been searching for. Doesn't + matter what else you pack (it does, you'll want to continue to shop with us, we were just being + nice) this is the piece that will set you apart from everyone else (that is absolutely true, you + will be a Goddess among women). Take that, bad fashion moments of the past! Striped dress + features 3/4 sleeve bell sleeves with a partially elastic/open back. Model is wearing a small. • + 97% Cotton 3% Spandex • Machine Wash Cold... +

+
+
+
+
+ +
+
+
+

Stripe Out White Off-The-Shoulder Dress

+
+

+ $50.00 + $48.00 +

+ +
+
+
+
- +
+
stuff...
- -
-
+ - - - +
+ + - \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/website.css b/packages/snap-preact-demo/public/templates/website.css index 470f9a69e3..085c40aadd 100644 --- a/packages/snap-preact-demo/public/templates/website.css +++ b/packages/snap-preact-demo/public/templates/website.css @@ -1,767 +1,1760 @@ -/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ +/* NORMALIZE +========================================================================== */ + +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document - ========================================================================== */ +========================================================================== */ /** - * 1. Correct the line height in all browsers. - * 2. Prevent adjustments of font size after orientation changes in iOS. - */ +* 1. Correct the line height in all browsers. +* 2. Prevent adjustments of font size after orientation changes in iOS. +*/ html { - line-height: 1.15; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ } + line-height: 1.15; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ +} /* Sections - ========================================================================== */ +========================================================================== */ /** - * Remove the margin in all browsers. - */ +* Remove the margin in all browsers. +*/ body { - margin: 0; } + margin: 0; +} + +/** +* Render the `main` element consistently in IE. +*/ +main { + display: block; +} /** - * Correct the font size and margin on `h1` elements within `section` and - * `article` contexts in Chrome, Firefox, and Safari. - */ +* Correct the font size and margin on `h1` elements within `section` and +* `article` contexts in Chrome, Firefox, and Safari. +*/ h1 { - font-size: 2em; - margin: 0.67em 0; } + font-size: 2em; + margin: 0.67em 0; +} /* Grouping content - ========================================================================== */ +========================================================================== */ /** - * 1. Add the correct box sizing in Firefox. - * 2. Show the overflow in Edge and IE. - */ +* 1. Add the correct box sizing in Firefox. +* 2. Show the overflow in Edge and IE. +*/ hr { - box-sizing: content-box; - /* 1 */ - height: 0; - /* 1 */ - overflow: visible; - /* 2 */ } + box-sizing: content-box; + /* 1 */ + height: 0; + /* 1 */ + overflow: visible; + /* 2 */ +} /** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ +* 1. Correct the inheritance and scaling of font size in all browsers. +* 2. Correct the odd `em` font sizing in all browsers. +*/ pre { - font-family: monospace, monospace; - /* 1 */ - font-size: 1em; - /* 2 */ } + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} /* Text-level semantics - ========================================================================== */ +========================================================================== */ /** - * Remove the gray background on active links in IE 10. - */ +* Remove the gray background on active links in IE 10. +*/ a { - background-color: transparent; } + background-color: transparent; +} /** - * 1. Remove the bottom border in Chrome 57- - * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. - */ +* 1. Remove the bottom border in Chrome 57- +* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. +*/ abbr[title] { - border-bottom: none; - /* 1 */ - text-decoration: underline; - /* 2 */ - text-decoration: underline dotted; - /* 2 */ } + border-bottom: none; + /* 1 */ + text-decoration: underline; + /* 2 */ + text-decoration: underline dotted; + /* 2 */ +} /** - * Add the correct font weight in Chrome, Edge, and Safari. - */ -b, -strong { - font-weight: bolder; } +* Add the correct font weight in Chrome, Edge, and Safari. +*/ +b, strong { + font-weight: bolder; +} /** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ -code, -kbd, -samp { - font-family: monospace, monospace; - /* 1 */ - font-size: 1em; - /* 2 */ } +* 1. Correct the inheritance and scaling of font size in all browsers. +* 2. Correct the odd `em` font sizing in all browsers. +*/ +code, kbd, samp { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} /** - * Add the correct font size in all browsers. - */ +* Add the correct font size in all browsers. +*/ small { - font-size: 80%; } + font-size: 80%; +} /** - * Prevent `sub` and `sup` elements from affecting the line height in - * all browsers. - */ -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; } +* Prevent `sub` and `sup` elements from affecting the line height in +* all browsers. +*/ +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} sub { - bottom: -0.25em; } + bottom: -0.25em; +} sup { - top: -0.5em; } + top: -0.5em; +} /* Embedded content - ========================================================================== */ +========================================================================== */ /** - * Remove the border on images inside links in IE 10. - */ +* Remove the border on images inside links in IE 10. +*/ img { - border-style: none; } + border-style: none; +} /* Forms - ========================================================================== */ +========================================================================== */ /** - * 1. Change the font styles in all browsers. - * 2. Remove the margin in Firefox and Safari. - */ -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - line-height: 1.15; - /* 1 */ - margin: 0; - /* 2 */ } +* 1. Change the font styles in all browsers. +* 2. Remove the margin in Firefox and Safari. +*/ +button, input, optgroup, select, textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} /** - * Show the overflow in IE. - * 1. Show the overflow in Edge. - */ -button, -input { - /* 1 */ - overflow: visible; } +* Show the overflow in IE. +* 1. Show the overflow in Edge. +*/ +button, input { + overflow: visible; /* 1 */ +} /** - * Remove the inheritance of text transform in Edge, Firefox, and IE. - * 1. Remove the inheritance of text transform in Firefox. - */ -button, -select { - /* 1 */ - text-transform: none; } +* Remove the inheritance of text transform in Edge, Firefox, and IE. +* 1. Remove the inheritance of text transform in Firefox. +*/ +button, select { + text-transform: none; /* 1 */ +} /** - * Correct the inability to style clickable types in iOS and Safari. - */ -button, -[type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; } +* Correct the inability to style clickable types in iOS and Safari. +*/ +button, [type=button], [type=reset], [type=submit] { + -webkit-appearance: button; +} /** - * Remove the inner border and padding in Firefox. - */ -button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; } +* Remove the inner border and padding in Firefox. +*/ +button::-moz-focus-inner, [type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner { + border-style: none; + padding: 0; +} /** - * Restore the focus styles unset by the previous rule. - */ -button:-moz-focusring, -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; } +* Restore the focus styles unset by the previous rule. +*/ +button:-moz-focusring, [type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring { + outline: 1px dotted ButtonText; +} /** - * Correct the padding in Firefox. - */ +* Correct the padding in Firefox. +*/ fieldset { - padding: 0.35em 0.75em 0.625em; } + padding: 0.35em 0.75em 0.625em; +} /** - * 1. Correct the text wrapping in Edge and IE. - * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. - */ +* 1. Correct the text wrapping in Edge and IE. +* 2. Correct the color inheritance from `fieldset` elements in IE. +* 3. Remove the padding so developers are not caught out when they zero out +* `fieldset` elements in all browsers. +*/ legend { - /* 1 */ - color: inherit; - /* 2 */ - display: table; - /* 1 */ - max-width: 100%; - /* 1 */ - padding: 0; - /* 3 */ - white-space: normal; - /* 1 */ } + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} /** - * Add the correct vertical alignment in Chrome, Firefox, and Opera. - */ +* Add the correct vertical alignment in Chrome, Firefox, and Opera. +*/ progress { - vertical-align: baseline; } + vertical-align: baseline; +} /** - * Remove the default vertical scrollbar in IE 10+. - */ +* Remove the default vertical scrollbar in IE 10+. +*/ textarea { - overflow: auto; } + overflow: auto; +} /** - * 1. Add the correct box sizing in IE 10. - * 2. Remove the padding in IE 10. - */ -[type="checkbox"], -[type="radio"] { - box-sizing: border-box; - /* 1 */ - padding: 0; - /* 2 */ } +* 1. Add the correct box sizing in IE 10. +* 2. Remove the padding in IE 10. +*/ +[type=checkbox], +[type=radio] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} /** - * Correct the cursor style of increment and decrement buttons in Chrome. - */ -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { - height: auto; } +* Correct the cursor style of increment and decrement buttons in Chrome. +*/ +[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button { + height: auto; +} /** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. - */ -[type="search"] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ } +* 1. Correct the odd appearance in Chrome and Safari. +* 2. Correct the outline style in Safari. +*/ +[type=search] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} /** - * Remove the inner padding in Chrome and Safari on macOS. - */ -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } +* Remove the inner padding in Chrome and Safari on macOS. +*/ +[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} /** - * 1. Correct the inability to style clickable types in iOS and Safari. - * 2. Change font properties to `inherit` in Safari. - */ +* 1. Correct the inability to style clickable types in iOS and Safari. +* 2. Change font properties to `inherit` in Safari. +*/ ::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ } + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} /* Interactive - ========================================================================== */ +========================================================================== */ /* - * Add the correct display in Edge, IE 10+, and Firefox. - */ +* Add the correct display in Edge, IE 10+, and Firefox. +*/ details { - display: block; } + display: block; +} /* - * Add the correct display in all browsers. - */ +* Add the correct display in all browsers. +*/ summary { - display: list-item; } + display: list-item; +} /* Misc - ========================================================================== */ +========================================================================== */ /** - * Add the correct display in IE 10+. - */ +* Add the correct display in IE 10+. +*/ template { - display: none; } + display: none; +} /** - * Add the correct display in IE 10. - */ +* Add the correct display in IE 10. +*/ [hidden] { - display: none; } + display: none; +} + +/* DEMO - BASE STYLES +========================================================================== */ -/* Base Styles -============================================== */ +*, *:before, *:after { + box-sizing: border-box; +} html, body { - min-height: 100%; } + height: 100%; + min-height: 100%; +} html { - font-size: 16px; } + font-size: 16px; +} body { - height: 100%; - -webkit-print-color-adjust: exact; - -webkit-tap-highlight-color: rgba(255, 255, 255, 0); - backface-visibility: hidden; - background-attachment: fixed; - font-family: 'Roboto', Helvetica, Arial; - font-size: 14px; - line-height: 1.5; - color: #3f3e40; } + height: 100%; + -webkit-print-color-adjust: exact; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + backface-visibility: hidden; + background-attachment: fixed; + font-size: 14px; + line-height: 1.5; +} img { - max-width: 100%; - width: auto; - height: auto; - display: block; } + max-width: 100%; + width: auto; + height: auto; + display: block; +} a { - color: #4c3ce2; - text-decoration: none; } - a:hover { - color: #3f3e40; } + text-decoration: none; +} ul { - list-style: none; - padding: 0; } + list-style: none; + padding: 0; +} h1, h2, h3, h4, h5, h6, p, ul { - margin: 0 0 20px 0; } - -h1, h2, h3, h4, h5, h6, .ss-lite-title { - font-weight: 700; - font-family: 'Roboto', Helvetica, Arial; } + margin: 0 0 20px 0; +} h1 { - font-size: 26px; } + font-size: 28px; +} h2 { - font-size: 24px; } + font-size: 26px; +} h3 { - font-size: 22px; } + font-size: 22px; +} h4 { - font-size: 20px; } + font-size: 20px; +} h5, h6 { - font-size: 18px; } + font-size: 18px; +} -hr { - border: 0; - border-top: 1px solid #ebebeb; } +.ss__demo { + height: 100%; +} + +.ss__demo .ss__demo__main { + min-height: 400px; +} + +.ss__demo .ss__demo__theme .ss__demo__pointer { + cursor: pointer; +} + +.ss__demo .ss__demo__theme .ss__demo__icon { + -webkit-flex-flow: column nowrap; + flex-flow: column nowrap; + display: -webkit-inline-flex; + display: -ms-inline-flex; + display: -moz-inline-flex; + display: inline-flex; + -webkit-flex: 0 0 auto; + -ms-flex: 0 0 auto; + -moz-flex: 0 0 auto; + flex: 0 0 auto; + width: 16px; + height: 16px; + line-height: 16px; +} + +.ss__demo .ss__demo__theme .ss__demo__icon .ss__icon { + margin: auto; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; + line-height: 1; + fill: currentColor; +} + +/* DEMO - TYPOGRAPHY +========================================================================== */ + +.ss__pike { + font-family: "Roboto", Helvetica, Arial; +} + +.ss__pike .ss__demo .ss__demo__theme { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme a { + color: #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme a:hover { + color: #515151; +} + +.ss__pike h1, .ss__pike h2, +.ss__pike h3, .ss__pike h4, +.ss__pike h5, .ss__pike h6 { + font-family: "Roboto", Helvetica, Arial; + font-weight: 700; +} + +.ss__pike .ss__demo .ss__demo__theme h1, .ss__pike .ss__demo .ss__demo__theme h2, +.ss__pike .ss__demo .ss__demo__theme h3, .ss__pike .ss__demo .ss__demo__theme h4, +.ss__pike .ss__demo .ss__demo__theme h5, .ss__pike .ss__demo .ss__demo__theme h6 { + color: #1d4990; +} + +.ss__everest { + font-family: "Source Sans 3", Helvetica, Arial; +} + +.ss__everest .ss__demo .ss__demo__theme { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme a { + color: #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme a:hover { + color: #515151; +} + +.ss__everest h1, .ss__everest h2, +.ss__everest h3, .ss__everest h4, +.ss__everest h5, .ss__everest h6 { + font-family: "Montserrat", Helvetica, Arial; + font-weight: 600; + text-transform: uppercase; +} + +.ss__everest .ss__demo .ss__demo__theme h1, .ss__everest .ss__demo .ss__demo__theme h2, +.ss__everest .ss__demo .ss__demo__theme h3, .ss__everest .ss__demo .ss__demo__theme h4, +.ss__everest .ss__demo .ss__demo__theme h5, .ss__everest .ss__demo .ss__demo__theme h6 { + color: #94280b; +} + +.ss__matterhorn { + font-family: "Poppins", Helvetica, Arial; +} + +.ss__matterhorn .ss__demo .ss__demo__theme { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme a { + color: #222222; +} + +.ss__matterhorn .ss__demo .ss__demo__theme a:hover { + color: #555555; +} + +.ss__matterhorn h1, .ss__matterhorn h2, +.ss__matterhorn h3, .ss__matterhorn h4, +.ss__matterhorn h5, .ss__matterhorn h6 { + font-family: "Lora", "Times New Roman", serif; + font-weight: 300; + font-style: italic; +} + +.ss__matterhorn .ss__demo .ss__demo__theme h1, .ss__matterhorn .ss__demo .ss__demo__theme h2, +.ss__matterhorn .ss__demo .ss__demo__theme h3, .ss__matterhorn .ss__demo .ss__demo__theme h4, +.ss__matterhorn .ss__demo .ss__demo__theme h5, .ss__matterhorn .ss__demo .ss__demo__theme h6 { + color: #222222; +} + +/* DEMO - FORM FIELDS +========================================================================== */ + +input, button, select { + padding: 0; + margin: 0; + border: 0; +} + +input, .ss__demo__button, select { + height: 40px; + line-height: 40px; + padding: 0 20px; +} -/* Form fields -============================================== */ input::-webkit-input-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input:-moz-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input::-moz-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input:-ms-input-placeholder { - color: #3f3e40; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; } - -input :focus::-webkit-input-placeholder { - color: #3f3e40; } - -input :focus:-moz-placeholder { - color: #3f3e40; } - -input :focus::-moz-placeholder { - color: #3f3e40; } - -input :focus:-ms-input-placeholder { - color: #3f3e40; } - -input[type='text'], button { - border: 0; - line-height: 1; } + -webkit-transition: color 0.3s ease-in-out; + -o-transition: color 0.3s ease-in-out; + -ms-transition: color 0.3s ease-in-out; + -moz-transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; +} + +input::-ms-input-placeholder { + -webkit-transition: color 0.3s ease-in-out; + -o-transition: color 0.3s ease-in-out; + -ms-transition: color 0.3s ease-in-out; + -moz-transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; +} + +input::placeholder { + -webkit-transition: color 0.3s ease-in-out; + -o-transition: color 0.3s ease-in-out; + -ms-transition: color 0.3s ease-in-out; + -moz-transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; +} button { - padding: 7px 20px; - color: #ffffff; - background: #3a23ad; - font-size: 18px; - border: none; - font-weight: bold; - cursor: pointer; } - button:hover { - color: white; - background: #4e37c1; } - -input[type='text'] { - color: #3f3e40; - padding: 10px; - box-sizing: border-box; - min-height: 40px; } - -/* Layout -============================================== */ -.ss-lite-wrapper { - margin: 0 auto; - padding: 0 20px; - max-width: 1200px; - width: auto; } - -.ss-lite-flex-wrap, .ss-lite-flex-wrap-center { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: row wrap; - -ms-flex-flow: row wrap; - flex-flow: row wrap; } - -.ss-lite-flex-nowrap, .ss-lite-flex-nowrap-center { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: row nowrap; - -ms-flex-flow: row nowrap; - flex-flow: row nowrap; } - -.ss-lite-flex-wrap-center, .ss-lite-flex-nowrap-center { - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - -ms-grid-row-align: center; - align-items: center; } - -.ss-lite-row-5 { - margin: 0 -5px; } - .ss-lite-row-5 > .ss-lite-col { - padding: 0 5px; } - -.ss-lite-row-10 { - margin: 0 -10px; } - .ss-lite-row-10 > .ss-lite-col { - padding: 0 10px; } - -.ss-lite-row-20 { - margin: 0 -20px; } - .ss-lite-row-20 > .ss-lite-col { - padding: 0 20px; } - -.clear { - clear: both; } - -/* Faded background -============================================== */ -.ss-lite-header { - background-color: #f8f8f8; } - .ss-lite-header, .ss-lite-header .ss-lite-wrapper { - position: relative; } - .ss-lite-header .ss-lite-wrapper { - padding: 20px; } - -/* Header -============================================== */ -.ss-lite-header .ss-lite-subheader { - text-transform: uppercase; - color: #00cee1; } - -.ss-lite-header .ss-lite-icon { - font-size: 20px; - color: #4c3ce2; } - -.ss-lite-header .ss-lite-header-logo { - width: 250px; } - .ss-lite-header .ss-lite-header-logo .st0 { - fill: url(#SVGID_1_); } - .ss-lite-header .ss-lite-header-logo .st1 { - fill: url(#SVGID_2_); } - .ss-lite-header .ss-lite-header-logo .st2 { - fill: #515151; } - .ss-lite-header .ss-lite-header-logo a { - text-align: right; - display: block; - line-height: 0; } - .ss-lite-header .ss-lite-header-logo svg { - max-width: 100%; } - -.ss-lite-header .ss-lite-header-buttons { - width: 840px; - margin: 0 0 0 auto; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar { - -webkit-box-flex: 1; - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - position: relative; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar .ss-lite-input[type='text'] { - border: 1px solid #ebebeb; - width: 100%; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar .ss-lite-input[type='text']::placeholder { - color: #c9c9c9; - font-weight: 100; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-search-bar .ss-lite-button { - background-color: transparent; - padding: 0; - position: absolute; - top: 0; - bottom: 0; - right: 10px; - margin: auto; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons { - margin: 0 0 0 15px; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons a { - position: relative; - padding: 0 5px; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons .ss-lite-cart-count { - position: absolute; - top: 6px; - right: -6px; - color: #ffffff; - font-size: 12px; - font-weight: bold; - width: 20px; - height: 20px; - line-height: 20px; - text-align: center; - display: inline-block; - background: #00cee1; - border-radius: 100%; } - .ss-lite-header .ss-lite-header-buttons .ss-lite-store-icons .ss-lite-cart-count:hover { - color: white; - background: #4e37c1; } - -/* Navigation -============================================== */ -.ss-lite-navigation { - background-color: #3a23ad; - border-top: 5px solid #4c3ce2; } - .ss-lite-navigation .ss-lite-list { - margin: 0 -20px -10px -20px; - text-align: center; } - .ss-lite-navigation .ss-lite-list li { - display: inline-block; - zoom: 1; - *display: inline; - vertical-align: middle; - padding: 0 20px 10px 20px; } - .ss-lite-navigation .ss-lite-list li a { - color: #ffffff; - font-size: 16px; - font-weight: bold; - text-transform: uppercase; } - .ss-lite-navigation .ss-lite-list li a.active { - border-bottom: 2px solid #00cee1; } - .ss-lite-navigation .ss-lite-list li a:hover { - color: #00cee1; } - -/* Main -============================================== */ - -.ss-lite-main { - flex: 1; - padding: 40px 0; } - -.ss-lite-breadcrumbs .ss-lite-list { - margin: 0 -5px 40px -5px; } - .ss-lite-breadcrumbs .ss-lite-list li { - padding: 0 5px; - display: inline-block; - zoom: 1; - *display: inline; - vertical-align: middle; } - - .ss-lite-main-layout .ss-lite-sidebar { - -webkit-box-flex: 0; - -webkit-flex: 0 0 250px; - -ms-flex: 0 0 250px; - flex: 0 0 250px; - max-width: 250px; - margin: 0 40px 0 0; } - .ss-lite-main-layout .ss-lite-content { - width: 100%; - min-width: 0; - } - -/* Footer -============================================== */ -.ss-lite-footer { - padding: 20px 0; - background-color: #3a23ad; - border-top: 5px solid #4c3ce2; } - .ss-lite-footer, .ss-lite-footer a, .ss-lite-footer p, .ss-lite-footer .ss-lite-title { - color: #ffffff; } - .ss-lite-footer a:hover { - color: #00cee1; } - .ss-lite-footer .ss-lite-col { - -webkit-box-flex: 1; - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } - .ss-lite-footer .ss-lite-col .ss-lite-title { - text-transform: uppercase; - font-size: 16px; - margin: 0 0 10px 0; - padding: 0 0 10px 0; - border-bottom: 1px solid #4c3ce2; } - .ss-lite-footer .ss-lite-col .ss-lite-title .ss-lite-icon { - margin: 0 10px 0 0; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit .ss-lite-list li { - display: inline-block; - margin-right: 10px; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit a { - display: inline-block; - zoom: 1; - *display: inline; - vertical-align: middle; - width: 30px; - height: 30px; - background: #4c3ce2; - text-align: center; - -webkit-border-radius: 100%; - -moz-border-radius: 100%; - -ms-border-radius: 100%; - -o-border-radius: 100%; - border-radius: 100%; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit a:hover { - color: #ffffff; - background-color: #00cee1; } - .ss-lite-footer .ss-lite-col.ss-lite-footer-visit a i { - line-height: 30px; - font-size: 16px; } - -/* Footer Copyright -============================================== */ -.ss-lite-footer-copyright { - padding: 30px 0 0; - text-align: center; } - .ss-lite-footer-copyright p { - margin: 0; } - .ss-lite-footer-copyright p:first-child { - margin: 0 0 2.5px 0; } - -/* Responsive -============================================== */ -@media only screen and (max-width: 991px) { - .ss-lite-footer .ss-lite-col, .ss-lite-footer .ss-lite-footer-information { - -webkit-box-flex: 1; - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - width: 50%; } - .ss-lite-header > .ss-lite-wrapper > .ss-lite-flex-wrap-center { - display: block; } - .ss-lite-header .ss-lite-header-logo, .ss-lite-header .ss-lite-header-buttons { - width: auto; } - .ss-lite-header .ss-lite-header-logo { - max-width: 250px; - margin: 0 auto 20px auto; } - .ss-lite-main .ss-lite-flex-nowrap { - display: block; } - .ss-lite-main .ss-lite-flex-nowrap .ss-lite-sidebar { - display: none; } } - -@media only screen and (max-width: 767px) { - .ss-lite-navigation .ss-lite-list { - margin: 0 -10px -10px -10px; } - .ss-lite-navigation .ss-lite-list li { - padding: 0 10px 10px 10px; } - .ss-lite-navigation .ss-lite-list li a { - font-size: 14px; } } - -@media only screen and (max-width: 540px) { - .ss-lite-footer .ss-lite-flex-wrap { - display: block; } - .ss-lite-footer .ss-lite-col, .ss-lite-footer .ss-lite-footer-information { - width: auto; } } - -.ss-results-title .ss-oq { - font-size: 14px; - color: #3b23ad; - font-weight: normal; -} - -.ss-results-title .ss-oq em { - font-weight: bold; -} - -.ss-toolbar-row { - margin-bottom: 20px; -} - -.ss-toolbar-col { - display: inline-block; - margin: 10px 20px 10px 0; -} - -.ss-toolbar-col.pagination, -.ss-toolbar.ss-toolbar-bottom { - margin-top: 20px; - float: right; -} - -.ss-toolbar-col.pagination, -.ss-toolbar.ss-toolbar-bottom-infinite { - display: flex; - justify-content: center; -} - -.ss-slideout__button { - width: 100%; - border: 1px solid #333; - text-align: center; - padding: 10px 0; - margin: 10px 0; - font-size: 1.2em; - cursor: pointer; -} - -.ss-slider button { - color: inherit; -} -#login-modal { - background: white; - border-radius: 5px; - padding: 20px; - border: 1px solid #ccc; - width: 450px; - position: absolute; - z-index: 99999999; - top: 10%; - left: calc(50% - 225px); - box-shadow: 0px 0px 20px 0px rgb(0 0 0 / 20%); -} -#login-modal input { - width: 80%; - border: 1px solid #ccc; -} -#login-modal button { - display: block; - margin: 20px auto; + cursor: pointer; +} + +select { + font-size: 16px; +} + +fieldset { + border: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__button { + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ss__demo .ss__demo__theme .ss__demo__input { + -webkit-flex-flow: row nowrap; + flex-flow: row nowrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; +} + +.ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__label, .ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__input { + min-width: 1px; +} + +.ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__label { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 125px; + margin: 0 10px 0 0; +} + +.ss__demo .ss__demo__theme .ss__demo__input .ss__demo__input__input { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; +} + +@media only screen and (min-width: 768px) { + select { + font-size: 14px; + } +} + +.ss__pike .ss__demo .ss__demo__theme input, .ss__pike .ss__demo .ss__demo__theme select, .ss__pike .ss__demo .ss__demo__theme .ss__demo__button { + -moz-border-radius: 0; + border-radius: 0; +} + +.ss__pike .ss__demo .ss__demo__theme input, .ss__pike .ss__demo .ss__demo__theme select { + color: #515151; + border: 2px solid #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme input::-webkit-input-placeholder, .ss__pike .ss__demo .ss__demo__theme input :focus::-webkit-input-placeholder { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme input::-ms-input-placeholder, .ss__pike .ss__demo .ss__demo__theme input :focus::-ms-input-placeholder { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme input::placeholder, .ss__pike .ss__demo .ss__demo__theme input :focus::placeholder { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__button { + background-color: #00aeef; + color: #ffffff; + font-family: "Roboto", Helvetica, Arial; + font-weight: 700; +} + +.ss__everest .ss__demo .ss__demo__theme input, .ss__everest .ss__demo .ss__demo__theme select, .ss__everest .ss__demo .ss__demo__theme .ss__demo__button { + -moz-border-radius: 3px; + border-radius: 3px; +} + +.ss__everest .ss__demo .ss__demo__theme input, .ss__everest .ss__demo .ss__demo__theme select { + color: #515151; + border: 2px solid #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme input::-webkit-input-placeholder, .ss__everest .ss__demo .ss__demo__theme input :focus::-webkit-input-placeholder { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme input::-ms-input-placeholder, .ss__everest .ss__demo .ss__demo__theme input :focus::-ms-input-placeholder { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme input::placeholder, .ss__everest .ss__demo .ss__demo__theme input :focus::placeholder { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__button { + background-color: #d15120; + color: #ffffff; + font-family: "Montserrat", Helvetica, Arial; + font-weight: 600; + text-transform: uppercase; + position: relative; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__button:after { + content: ""; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + border-bottom: 2px solid #94280b; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input, .ss__matterhorn .ss__demo .ss__demo__theme select, .ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__button { + -moz-border-radius: 0; + border-radius: 0; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input, .ss__matterhorn .ss__demo .ss__demo__theme select { + color: #555555; + border: 1px solid #111111; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input::-webkit-input-placeholder, .ss__matterhorn .ss__demo .ss__demo__theme input :focus::-webkit-input-placeholder { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input::-ms-input-placeholder, .ss__matterhorn .ss__demo .ss__demo__theme input :focus::-ms-input-placeholder { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme input::placeholder, .ss__matterhorn .ss__demo .ss__demo__theme input :focus::placeholder { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__button { + background-color: #222222; + color: #ffffff; + font-family: "Lora", "Times New Roman", serif; + font-weight: 300; + font-style: italic; +} + +/* DEMO - BACKGROUND +========================================================================== */ + +.ss__demo .ss__demo__background { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; +} + +.ss__demo .ss__demo__background .ss__demo__svg { + width: 100%; + height: 100%; +} + +.ss__pike .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__background { + fill: #1d4990; +} + +.ss__pike .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__top_triangle { + stroke: #00aeef; +} + +.ss__pike .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__bottom_triangle { + stroke: #ffffff; +} + +.ss__everest .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__background { + fill: #94280b; +} + +.ss__everest .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__top_triangle { + stroke: #d15120; +} + +.ss__everest .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__bottom_triangle { + stroke: #ffffff; +} + +.ss__matterhorn .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__background { + fill: #222222; +} + +.ss__matterhorn .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__top_triangle { + stroke: #111111; +} + +.ss__matterhorn .ss__demo .ss__demo__background .ss__demo__svg .ss__demo__svg__bottom_triangle { + stroke: #ffffff; +} + +/* DEMO - SLIDEOUT BUTTON +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__slideout__default .ss__demo__slideout__button { + -webkit-flex-flow: row nowrap; + flex-flow: row nowrap; + display: -webkit-inline-flex; + display: -ms-inline-flex; + display: -moz-inline-flex; + display: inline-flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 5px; + gap: 5px; + height: auto; + line-height: 1; + font-size: 16px; + background-color: transparent; + padding: 0; +} + +/* DEMO - LAYOUT +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__layout { + -ms-gap: 30px; + gap: 30px; +} + +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__sidebar, +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__content { + min-width: 1px; +} + +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__sidebar { + display: none; + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 250px; +} + +.ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__content { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; +} + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__layout .ss__demo__layout__sidebar { + display: block; + } +} + +.ss__demo .ss__demo__wrapper { + margin: 0 auto; + padding: 0 20px; + max-width: 1200px; + width: auto; +} + +.ss__demo .ss__demo__theme .ss__demo__flex__wrap, .ss__demo .ss__demo__theme .ss__demo__flex__wrap--center { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; +} + +.ss__demo .ss__demo__theme .ss__demo__flex__nowrap, .ss__demo .ss__demo__theme .ss__demo__flex__nowrap--center { + -webkit-flex-flow: nowrap; + flex-flow: nowrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; +} + +.ss__demo .ss__demo__theme .ss__demo__flex__wrap--center, .ss__demo .ss__demo__theme .ss__demo__flex__nowrap--center { + -webkit-align-items: center; + align-items: center; +} + +.ss__demo .ss__demo__theme .ss__demo__row--5 { + -ms-gap: 5px; + gap: 5px; +} + +.ss__demo .ss__demo__theme .ss__demo__row--10 { + -ms-gap: 10px; + gap: 10px; +} + +.ss__demo .ss__demo__theme .ss__demo__row--20 { + -ms-gap: 20px; + gap: 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__row--30 { + -ms-gap: 30px; + gap: 30px; +} + +.ss__demo .ss__demo__theme .ss__demo__column { + min-width: 1px; +} + +/* DEMO - HEADER +========================================================================== */ + +.ss__demo .ss__demo__header { + padding: 40px 0; + margin: 0 0 40px 0; + position: relative; + overflow: hidden; +} + +.ss__demo .ss__demo__header .ss__demo__background { + z-index: -1; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo { + -webkit-flex: 0 0 200px; + -ms-flex: 0 0 200px; + -moz-flex: 0 0 200px; + flex: 0 0 200px; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo a { + display: block; + width: 100%; + line-height: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo img { + max-width: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search { + order: 3; + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form { + position: relative; + -webkit-flex: 1 0 auto; + -ms-flex: 1 0 auto; + -moz-flex: 1 0 auto; + flex: 1 0 auto; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__input { + width: 100%; + padding-right: 60px; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button { + background-color: transparent; + position: absolute; + top: 2px; + bottom: 2px; + right: 20px; + margin: auto; + padding: 0; + line-height: 1; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + line-height: 1; + margin-left: auto; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__icon { + width: 20px; + height: 20px; + line-height: 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__icon .ss__icon { + fill: #ffffff; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button { + position: relative; + overflow: visible; +} + +.ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + position: absolute; + top: 12px; + right: -6px; + z-index: 1; + color: #ffffff; + font-size: 10px; + font-weight: 700; + width: 16px; + height: 16px; + line-height: 14px; + text-align: center; + border-radius: 50%; +} + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__flex__wrap--center { + -webkit-justify-content: flex-end; + justify-content: flex-end; + } + + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__logo { + -webkit-flex: 0 0 300px; + -ms-flex: 0 0 300px; + -moz-flex: 0 0 300px; + flex: 0 0 300px; + margin-right: auto; + } + + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search { + order: 0; + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + max-width: 500px; + } + + .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons { + margin-left: 0; + } +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button .ss__demo__icon { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + background-color: #00aeef; + border: 1px solid #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button:hover .ss__demo__cart__count { + color: #00aeef; + background-color: #ffffff; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button .ss__demo__icon { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__button:after { + display: none; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + background-color: #d15120; + border: 1px solid #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button:hover .ss__demo__cart__count { + color: #d15120; + background-color: #ffffff; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__search .ss__demo__search__form .ss__demo__search__button .ss__demo__icon { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button .ss__demo__cart__count { + background-color: #848484; + border: 1px solid #848484; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__header .ss__demo__store-icons .ss__demo__column--cart .ss__demo__slideout__button:hover .ss__demo__cart__count { + color: #848484; + background-color: #ffffff; +} + +/* DEMO - NAVIGATION +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__navigation { + margin: 40px 0 0 0; + display: none; +} + +.ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 10px 20px; + gap: 10px 20px; + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-size: 16px; +} + + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__navigation { + display: block; + } +} + +@media only screen and (min-width: 992px) { + .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list { + -ms-gap: 10px 30px; + gap: 10px 30px; + } +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-family: "Roboto", Helvetica, Arial; + font-weight: 700; + color: #ffffff; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a:hover { + color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-family: "Source Sans 3", Helvetica, Arial; + font-weight: 600; + text-transform: uppercase; + color: #ffffff; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a:hover { + color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a { + font-family: "Lora", "Times New Roman", serif; + font-weight: 300; + font-style: italic; + color: #ffffff; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__navigation .ss__demo__list li a:hover { + color: #555555; +} + +/* DEMO - BREADCRUMBS +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs { + margin: 0 0 30px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 10px; + gap: 10px; + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul li { + line-height: 1; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul li a { + color: #515151; +} + +.ss__demo .ss__demo__theme .ss__demo__breadcrumbs ul li .ss__icon { + width: 12px; + height: 12px; + line-height: 12px; +} + +/* DEMO - HEADER TITLE +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__header__title { + margin: 0 0 30px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__header__title .ss__title { + margin: 0; +} + +/* DEMO - FOOTER +========================================================================== */ + +.ss__demo .ss__demo__footer { + padding: 40px 0; + margin: 40px 0 0 0; + position: relative; + overflow: hidden; +} + +.ss__demo .ss__demo__theme .ss__demo__footer a, .ss__demo .ss__demo__theme .ss__demo__footer p, .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + color: #ffffff; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__wrapper { + position: relative; + z-index: 2; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + font-size: 16px; + margin: 0 0 10px 0; + padding: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title .ss__demo__icon { + margin: 0 10px 0 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__list { + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__list li { + margin: 0 0 2.5px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__list li:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__column { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information p { + text-align: justify; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social { + text-align: right; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -webkit-justify-content: flex-end; + justify-content: flex-end; + -ms-gap: 10px; + gap: 10px; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + width: 30px; + height: 30px; + line-height: 30px; + -moz-border-radius: 50%; + border-radius: 50%; + text-align: center; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a:hover .ss__demo__icon .ss__icon { + fill: #ffffff; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a .ss__demo__icon { + height: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a .ss__demo__icon .ss__icon { + max-height: 16px; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright { + text-align: right; + margin: 20px 0 0 0; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright p { + margin: 0; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -webkit-justify-content: flex-end; + justify-content: flex-end; +} + +.ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright p a, .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__copyright p span { + margin: 0 2.5px; +} + +@media only screen and (min-width: 541px) { + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__row--20 { + -ms-gap: 20px 40px; + gap: 20px 40px; + } + + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__column { + width: calc(50% - 20px); + } +} + +@media only screen and (min-width: 992px) { + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__column { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + width: auto; + } + + .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information { + -webkit-flex: 0 0 400px; + -ms-flex: 0 0 400px; + -moz-flex: 0 0 400px; + flex: 0 0 400px; + } +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer { + background-color: #1d4990; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer a:hover { + color: #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + border-bottom: 2px solid #00aeef; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + background-color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer { + background-color: #94280b; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer a:hover { + color: #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__title { + border-bottom: 2px solid #d15120; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + background-color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__footer { + background-color: #222222; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__footer a:hover { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__footer .ss__demo__information .ss__demo__social a { + background-color: #111111; +} + +/* DEMO - SKIP TO BUTTON +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__skip-to__button { + position: absolute; + top: -99999px; + left: -99999px; + background-color: #1d4990; + color: #ffffff; + font-size: 16px; + font-weight: 700; + text-transform: uppercase; + padding: 5px 10px; +} + +.ss__demo .ss__demo__theme .ss__skip-to__button:focus { + position: absolute; + top:0; + left: 0; + z-index: 1; +} + +/* DEMO - LOGIN MODAL +========================================================================== */ + +.ss__demo .ss__demo__theme #ss__demo__login__modal { + display: none; + background: #ffffff; + padding: 20px; + margin: 0 auto; + border: 1px solid #ebebeb; + border-radius: 15px; + box-shadow: 2px 2px 20px 0 rgba(80, 80, 100, 0.12); + width: 450px; + position: absolute; + left: 0; + right: 0; + top: 25%; + z-index: 99999999; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal.ss__demo__login__modal--active { + display: block; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header { + -webkit-flex-flow: row nowrap; + flex-flow: row nowrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -ms-gap: 10px; + gap: 10px; + margin: 0 0 20px 0; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header .ss__demo__title { + line-height: 1; + margin: 0; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header .ss__demo__close { + background-color: rgba(0, 0, 0, 0); + border: 0; + padding: 0; + margin: 0; + margin-left: auto; + order: 10; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__login__header .ss__demo__close .ss__icon { + fill: #515151; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__input .ss__demo__input__label { + width: auto; +} + +.ss__demo .ss__demo__theme #ss__demo__login__modal .ss__demo__button { + display: block; + width: 100%; + margin: 20px auto 0 auto; +} + +/* DEMO - RESULT +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__result { + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + -ms-gap: 30px; + gap: 30px; + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result > * { + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; + min-width: 1px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner { + position: relative; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + display: -webkit-flex; + display: -ms-flex; + display: -moz-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + -ms-gap: 10px; + gap: 10px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner > * { + min-width: 1px; + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image { + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image .ss__image__link { + display: block; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image .ss__image { + position: relative; + line-height: 0; + height: 0; + padding-bottom: 150%; + overflow: hidden; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image .ss__image img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + max-width: 100%; + max-height: 100%; + -o-object-position: center center; + object-position: center center; + -o-object-fit: contain; + object-fit: contain; + width: 100%; + height: 100%; + border: 0; + display: block; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details { + text-align: left; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > p, +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > div { + margin: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > p:last-child, +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details > div:last-child, +.ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__details .ss__result__description > *:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__demo__header__title { + display: none; + margin: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__demo__header__title .ss__title { + font-size: 22px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + font-size: 16px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span ~ span { + padding-left: 5px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + text-decoration: line-through; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-size: 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__add-to-cart { + width: 100%; + height: 46px; + line-height: 46px; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + color: #515151; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + color: #737373; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-weight: 700; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price--on-sale { + color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + color: #515151; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + color: #737373; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-weight: 600; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price--on-sale { + color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing span { + color: #555555; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__msrp { + color: #848484; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price { + font-weight: 600; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side > .ss__result__details .ss__result__pricing .ss__result__price--on-sale { + color: #222222; +} + +@media only screen and (min-width: 768px) { + #ss__product__demo .ss__demo .ss__demo__theme .ss__demo__header__title { + display: none; + } + + .ss__demo .ss__demo__theme .ss__demo__result .ss__result { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + } + + .ss__demo .ss__demo__theme .ss__result .ss__result__inner { + -ms-gap: 20px; + gap: 20px; + } + + .ss__demo .ss__demo__theme .ss__result .ss__result__inner .ss__result__image { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 200px; + } + + .ss__demo .ss__demo__theme .ss__result .ss__result__inner .ss__result__details { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + } + + .ss__demo .ss__demo__theme .ss__result__side { + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + -moz-flex: 0 1 auto; + flex: 0 1 auto; + width: 300px; + } + + #ss__product__demo .ss__demo .ss__demo__theme .ss__result__side > .ss__result__details .ss__demo__header__title { + display: block; + } +} + +@media only screen and (min-width: 992px) { + .ss__demo .ss__demo__theme .ss__demo__result .ss__result .ss__result__inner .ss__result__image { + width: 350px; + } + + .ss__demo .ss__demo__theme .ss__demo__result .ss__result__side { + width: 350px; + } +} + +/* DEMO - CART +========================================================================== */ + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product { + margin: 0 0 20px 0; + -ms-gap: 10px 20px; + gap: 10px 20px; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image, +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details { + min-width: 1px; + -webkit-flex: 1 1 100%; + -ms-flex: 1 1 100%; + -moz-flex: 1 1 100%; + flex: 1 1 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image img { + width: 100%; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details > div { + margin: 0 0 10px 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details > div:last-child { + margin-bottom: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__name { + margin-bottom: 5px; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__name h3 { + margin: 0; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-size: 18px; + font-weight: 700; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__actions { + -ms-gap: 10px; + gap: 10px; + max-width: 400px; +} + +.ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__actions .ss__demo__button { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + height: 46px; + line-height: 46px; +} + +.ss__pike .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-weight: 700; + color: #00aeef; +} + +.ss__everest .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-weight: 600; + color: #d15120; +} + +.ss__matterhorn .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details .ss__demo__cart__product__pricing { + font-weight: 600; + color: #222222; +} + +@media only screen and (min-width: 541px) { + .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image { + -webkit-flex: 0 0 150px; + -ms-flex: 0 0 150px; + -moz-flex: 0 0 150px; + flex: 0 0 150px; + } + + .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__details { + -webkit-flex: 1 1 0%; + -ms-flex: 1 1 0%; + -moz-flex: 1 1 0%; + flex: 1 1 0%; + } +} + +@media only screen and (min-width: 768px) { + .ss__demo .ss__demo__theme .ss__demo__cart__products .ss__demo__cart__product .ss__demo__cart__product__image { + -webkit-flex: 0 0 200px; + -ms-flex: 0 0 200px; + -moz-flex: 0 0 200px; + flex: 0 0 200px; + } } \ No newline at end of file diff --git a/packages/snap-preact-demo/public/templates/website.js b/packages/snap-preact-demo/public/templates/website.js new file mode 100644 index 0000000000..3f6244609b --- /dev/null +++ b/packages/snap-preact-demo/public/templates/website.js @@ -0,0 +1,30 @@ +var activeClass = 'ss__demo__login__modal--active'; +var modalSelector = 'ss__demo__login__modal'; +var modalInputSelector = '#ss__demo__login__modal #ss__demo__input__shopper-id'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function toggleModal() { + var modal = document.getElementById(modalSelector); + var modalInput = document.querySelector(modalInputSelector); + + if (modal.classList.contains(activeClass)) { + modal.classList.remove(activeClass); + } else { + modal.classList.add(activeClass); + modalInput.focus(); + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function setShopperID() { + var modal = document.getElementById(modalSelector); + var modalInput = document.querySelector(modalInputSelector); + var id = modalInput.value; + + if (id) { + window.searchspring.tracker.track.shopper.login({ + id: id, + }); + modal.classList.remove(activeClass); + } +} diff --git a/packages/snap-preact-demo/snap/src/index.ts b/packages/snap-preact-demo/snap/src/index.ts index e33c71be4c..63cfd74f03 100644 --- a/packages/snap-preact-demo/snap/src/index.ts +++ b/packages/snap-preact-demo/snap/src/index.ts @@ -243,7 +243,7 @@ let config: SnapConfig = { url: '/snap/', fields: [ { - field: 'collection_handle', + field: 'collection_name', label: 'Collection', }, { diff --git a/packages/snap-preact-demo/templates/src/components/Result.tsx b/packages/snap-preact-demo/templates/src/components/Result.tsx index f63e85843d..49a2661c5c 100644 --- a/packages/snap-preact-demo/templates/src/components/Result.tsx +++ b/packages/snap-preact-demo/templates/src/components/Result.tsx @@ -1,11 +1,85 @@ import { h, Fragment } from 'preact'; -import { Price, Image, OverlayBadge, CalloutBadge } from '@searchspring/snap-preact/components'; +import { Price, Image, OverlayBadge, CalloutBadge, Rating } from '@searchspring/snap-preact/components'; import { Product } from '@searchspring/snap-store-mobx'; import type { SearchController } from '@searchspring/snap-controller'; export const CustomResult = (props: { result: Product; controller: SearchController }) => { const { result, controller } = props; const core = result.mappings.core; + // const variants = result.variants; + + // const breadcrumbs = [ + // { url: '/', label: 'Home' }, + // { url: '/', label: 'Collections' }, + // { url: '/', label: 'Appliances' }, + // { label: 'Fridge' } + // ] + + // const errorObject = { + // code: 429, + // type: ErrorType.ERROR, + // message: 'Too many requests try again later', + // } + + // const slides = [ + // "https://picsum.photos/400/300?random=1", + // "https://picsum.photos/400/300?random=2", + // "https://picsum.photos/400/300?random=3", + // "https://picsum.photos/400/300?random=4", + // "https://picsum.photos/400/300?random=5", + // "https://picsum.photos/400/300?random=6", + // "https://picsum.photos/400/300?random=7", + // "https://picsum.photos/400/300?random=8" + // ]; + + // const gridOptions = [ + // { + // value: 'one one one', + // disabled: true, + // }, + // { + // value: 'two two two two', + // }, + // { + // value: 'three three three three', + // }, + // { + // value: 'four four four', + // background: 'red', + // disabled: true, + // }, + // { + // value: 'five', + // background: 'yellow', + // }, + // { + // value: 'six six six', + // background: 'blue', + // }, + // { + // value: 'seven seven', + // disabled: true, + // backgroundImageUrl: + // 'https://cdn.shopify.com/s/files/1/0916/6477/7582/files/Women_s_Apparel_Studio_Legging_-_Charcoal_86731d52-9ef2-4663-802a-8935249c5a7c.png?v=1747685734', + // }, + // { + // value: 'eight eight eight', + // backgroundImageUrl: + // 'https://cdn.shopify.com/s/files/1/0916/6477/7582/files/Women_s_Apparel_Align_Crewneck_-_Olive_519ac0c5-e067-4ab7-9fe5-5421f364c52a.png?v=1747685123', + // }, + // { + // value: 'nine nine', + // backgroundImageUrl: 'https://cdn.shopify.com/s/files/1/0916/6477/7582/files/red-buffalo-plaid-flannel.png?v=1765405015', + // }, + // { + // value: 'ten a big fat hen', + // background: 'url(https://searchspring-demo-content.s3.amazonaws.com/demo/fashion/product_images_large/rdb_studio_2_3312_large.jpg)', + // }, + // { + // value: 'grey', + // background: 'grey', + // }, + // ]; return (
@@ -16,6 +90,7 @@ export const CustomResult = (props: { result: Product; controller: SearchControl +
+
+
+ + {/* + + */} + + {/* {variants?.selections + ? variants.selections.map((selection) => { + return ; + }) + : null} */} + + {/* */} + + {/* */} + + {/*
+
*/} +
{core.price < core.msrp ? ( @@ -37,6 +132,8 @@ export const CustomResult = (props: { result: Product; controller: SearchControl )}
+ +
diff --git a/packages/snap-preact-demo/templates/src/index.ts b/packages/snap-preact-demo/templates/src/index.ts index 7a33e26da1..2e5f8bfa62 100644 --- a/packages/snap-preact-demo/templates/src/index.ts +++ b/packages/snap-preact-demo/templates/src/index.ts @@ -3,7 +3,7 @@ import { globalStyles } from './styles'; import deepmerge from 'deepmerge'; import { combineMerge } from '../../snap/src/middleware/functions'; import type { SnapTemplatesConfig } from '@searchspring/snap-preact'; -const siteId = 'atkzs2'; +const siteId = 'atkzs2'; // atkzs2 // atbb9x (for hierarchy) // const siteId = '8uyt2m'; @@ -36,7 +36,7 @@ const siteId = 'atkzs2'; // }; let config: SnapTemplatesConfig = { config: { - siteId, + siteId: siteId, language: 'en', currency: 'usd', platform: 'other', @@ -55,10 +55,11 @@ let config: SnapTemplatesConfig = { }, }, theme: { - extends: 'base', + extends: 'pike', + //resultComponent: 'CustomResult', variables: { breakpoints: { - mobile: 768, + mobile: 767, tablet: 1024, desktop: 1280, }, @@ -77,6 +78,7 @@ let config: SnapTemplatesConfig = { email: { Email: { component: 'RecommendationEmail', + //resultComponent: 'EmailResult', }, }, default: { @@ -97,14 +99,32 @@ let config: SnapTemplatesConfig = { component: 'Search', }, ], + settings: { + variants: { + showDisabledSelectionValues: true, + }, + // infinite: { + // backfill: 5, + // }, + }, }, autocomplete: { targets: [ { selector: 'input.searchspring-ac', - component: 'AutocompleteFixed', + component: 'AutocompleteModal', }, ], + settings: { + history: { + limit: 6, + showResults: true, + }, + trending: { + limit: 6, + showResults: true, + }, + }, }, }; diff --git a/packages/snap-preact/components/.storybook/ColorPickerTool.tsx b/packages/snap-preact/components/.storybook/ColorPickerTool.tsx new file mode 100644 index 0000000000..72513a073e --- /dev/null +++ b/packages/snap-preact/components/.storybook/ColorPickerTool.tsx @@ -0,0 +1,313 @@ +// .storybook/ColorPickerTool.tsx +// Toolbar color picker addon component for theme color overrides. + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { useGlobals } from '@storybook/manager-api'; + +export const COLOR_KEYS = ['primary', 'secondary', 'accent', 'text'] as const; +export type ColorKey = typeof COLOR_KEYS[number]; +export const GLOBAL_COLOR_PREFIX = 'themeColor_'; +export const DEFAULT_COLOR_PREFIX = 'themeDefaultColor_'; + +const DEBOUNCE_MS = 150; + +export const ColorPickerTool: React.FC = () => { + const [globals, updateGlobals] = useGlobals(); + const [open, setOpen] = React.useState(false); + const [hovered, setHovered] = React.useState(false); + const buttonRef = React.useRef(null); + const [panelPos, setPanelPos] = React.useState({ top: 0, left: 0 }); + + // Local state for instant picker feedback. + const [localColors, setLocalColors] = React.useState>(() => { + const init = {} as Record; + COLOR_KEYS.forEach((k) => { + init[k] = (globals[`${GLOBAL_COLOR_PREFIX}${k}`] as string) || ''; + }); + return init; + }); + + const timers = React.useRef>>>({}); + + const openDropdown = () => { + if (buttonRef.current) { + const rect = buttonRef.current.getBoundingClientRect(); + setPanelPos({ top: rect.bottom + 14, left: rect.left }); + } + setOpen(true); + }; + + // Close on outside click — covers both the manager document and the story iframe. + React.useEffect(() => { + if (!open) return; + const onMouseDown = (e: MouseEvent) => { + const panel = document.getElementById('ss-color-picker-panel'); + if (buttonRef.current?.contains(e.target as Node)) return; + if (panel?.contains(e.target as Node)) return; + setOpen(false); + }; + // Manager frame + document.addEventListener('mousedown', onMouseDown); + // Story iframe + const iframe = document.querySelector('#storybook-preview-iframe'); + iframe?.contentDocument?.addEventListener('mousedown', onMouseDown); + return () => { + document.removeEventListener('mousedown', onMouseDown); + iframe?.contentDocument?.removeEventListener('mousedown', onMouseDown); + }; + }, [open]); + + // Sync local state when globals change externally. + React.useEffect( + () => { + COLOR_KEYS.forEach((k) => { + const globalVal = (globals[`${GLOBAL_COLOR_PREFIX}${k}`] as string) || ''; + setLocalColors((prev) => (prev[k] === globalVal ? prev : { ...prev, [k]: globalVal })); + }); + }, + COLOR_KEYS.map((k) => globals[`${GLOBAL_COLOR_PREFIX}${k}`]) + ); + + const handleChange = (key: ColorKey, value: string) => { + setLocalColors((prev) => ({ ...prev, [key]: value })); + clearTimeout(timers.current[key]); + timers.current[key] = setTimeout(() => { + updateGlobals({ [`${GLOBAL_COLOR_PREFIX}${key}`]: value }); + }, DEBOUNCE_MS); + }; + + const handleReset = (key: ColorKey) => { + clearTimeout(timers.current[key]); + setLocalColors((prev) => ({ ...prev, [key]: '' })); + updateGlobals({ [`${GLOBAL_COLOR_PREFIX}${key}`]: '' }); + }; + + const anyOverridden = COLOR_KEYS.some((k) => localColors[k]); + + const swatches = COLOR_KEYS.map((k) => { + const override = localColors[k]; + const defaultColor = globals[`${DEFAULT_COLOR_PREFIX}${k}`] as string | undefined; + return override || defaultColor || '#cccccc'; + }); + + const panel = open + ? ReactDOM.createPortal( + React.createElement( + 'div', + { + id: 'ss-color-picker-panel', + style: { + position: 'fixed', + top: `${panelPos.top}px`, + left: `${panelPos.left}px`, + zIndex: 99999, + background: '#fff', + borderRadius: '6px', + boxShadow: '0 4px 16px rgba(0,0,0,0.14)', + padding: '10px 14px', + minWidth: '160px', + }, + }, + React.createElement('div', { style: { fontSize: '11px', fontWeight: 600, color: '#666', marginBottom: '8px' } }, 'Theme Color Overrides'), + ...COLOR_KEYS.map((key) => { + const override = localColors[key]; + const defaultColor = globals[`${DEFAULT_COLOR_PREFIX}${key}`] as string | undefined; + const effectiveColor = override || defaultColor || '#000000'; + const isOverridden = Boolean(override); + + return React.createElement( + 'div', + { + key, + style: { + display: 'flex', + alignItems: 'center', + gap: '8px', + padding: '5px 0', + }, + }, + // Swatch / color picker — far left + React.createElement( + 'div', + { + style: { + position: 'relative', + width: '32px', + height: '24px', + borderRadius: '3px', + border: `2px solid ${isOverridden ? '#1D4990' : 'transparent'}`, + background: effectiveColor, + flexShrink: 0, + overflow: 'hidden', + cursor: 'pointer', + }, + }, + React.createElement('input', { + type: 'color', + value: effectiveColor, + onChange: (e: React.ChangeEvent) => handleChange(key, e.target.value), + style: { + position: 'absolute', + inset: 0, + width: '200%', + height: '200%', + padding: 0, + margin: '-25%', + opacity: 0, + cursor: 'pointer', + border: 'none', + }, + }) + ), + // Color name label + hex underneath + React.createElement( + 'div', + { style: { display: 'flex', flexDirection: 'column', flex: 1, gap: '1px' } }, + React.createElement( + 'label', + { + style: { + fontSize: '12px', + color: isOverridden ? '#1D4990' : '#444', + textTransform: 'capitalize', + fontWeight: isOverridden ? '600' : '400', + lineHeight: '1.2', + }, + }, + key + ), + React.createElement( + 'span', + { + style: { + fontSize: '9px', + color: '#aaa', + fontFamily: 'monospace', + lineHeight: '1.2', + }, + }, + effectiveColor + ) + ), + // Reset button / spacer + isOverridden + ? React.createElement( + 'button', + { + onClick: () => handleReset(key), + title: 'Reset to theme default', + style: { + width: '22px', + height: '22px', + padding: '0', + fontSize: '13px', + lineHeight: '1', + cursor: 'pointer', + border: '1px solid #ccc', + borderRadius: '3px', + background: '#fff', + color: '#666', + flexShrink: 0, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, + }, + '×' + ) + : React.createElement('div', { style: { width: '22px', flexShrink: 0 } }) + ); + }), + anyOverridden + ? React.createElement( + 'button', + { + onClick: () => COLOR_KEYS.forEach((k) => handleReset(k)), + style: { + marginTop: '8px', + width: '100%', + padding: '4px', + fontSize: '11px', + cursor: 'pointer', + border: '1px solid #ccc', + borderRadius: '3px', + background: '#f8f8f8', + color: '#666', + }, + }, + 'Reset all' + ) + : null + ), + document.body + ) + : null; + + return React.createElement( + React.Fragment, + null, + React.createElement( + 'button', + { + ref: buttonRef, + onClick: () => (open ? setOpen(false) : openDropdown()), + onMouseEnter: () => setHovered(true), + onMouseLeave: () => setHovered(false), + title: 'Theme color overrides', + style: { + display: 'inline-flex', + alignItems: 'center', + alignSelf: 'center', + gap: '6px', + height: '28px', + padding: '0 10px', + cursor: 'pointer', + border: 'none', + borderRadius: '4px', + background: open || hovered ? 'rgba(0,0,0,0.12)' : 'rgba(0,0,0,0.06)', + color: anyOverridden ? '#1D4990' : '#444', + fontSize: '13px', + fontWeight: 700, + whiteSpace: 'nowrap', + outline: 'none', + transition: 'background 0.1s', + lineHeight: '28px', + verticalAlign: 'middle', + }, + }, + React.createElement( + 'div', + { style: { display: 'flex', gap: '2px', alignItems: 'center' } }, + ...swatches.map((color, i) => + React.createElement('div', { + key: i, + style: { + width: '9px', + height: '9px', + borderRadius: '50%', + background: color, + border: '1px solid rgba(0,0,0,0.18)', + flexShrink: 0, + }, + }) + ) + ), + React.createElement('span', { style: { letterSpacing: '0.01em' } }, 'Colors'), + anyOverridden + ? React.createElement('span', { + title: 'Colors overridden', + style: { + width: '6px', + height: '6px', + borderRadius: '50%', + background: '#1D4990', + flexShrink: 0, + marginLeft: '1px', + }, + }) + : null + ), + panel + ); +}; diff --git a/packages/snap-preact/components/.storybook/manager.ts b/packages/snap-preact/components/.storybook/manager.ts index 648d8e07ea..0949a25f3a 100644 --- a/packages/snap-preact/components/.storybook/manager.ts +++ b/packages/snap-preact/components/.storybook/manager.ts @@ -1,9 +1,17 @@ -// .storybook/manager.js -// used to style up the UI - using Searchspring Custom Theme +// .storybook/manager.ts +// Storybook manager-side config: UI theme + toolbar addon registration. -import { addons } from '@storybook/addons'; +import React from 'react'; +import { addons, types } from '@storybook/manager-api'; import searchspringTheme from './searchspringTheme'; +import { ColorPickerTool } from './ColorPickerTool'; -addons.setConfig({ - theme: searchspringTheme, +addons.setConfig({ theme: searchspringTheme }); + +addons.register('snap-theme-color-picker', () => { + addons.add('snap-theme-color-picker/tool', { + type: types.TOOL, + title: 'Theme Colors', + render: () => React.createElement(ColorPickerTool), + }); }); diff --git a/packages/snap-preact/components/.storybook/preview.tsx b/packages/snap-preact/components/.storybook/preview.tsx index d9602cc8c8..cd1a97ea49 100644 --- a/packages/snap-preact/components/.storybook/preview.tsx +++ b/packages/snap-preact/components/.storybook/preview.tsx @@ -1,14 +1,15 @@ -import { ComponentChildren, Fragment, h } from 'preact'; +import { ComponentChildren, h } from 'preact'; import { withThemeFromJSXProvider } from '@storybook/addon-themes'; +import { useGlobals, useEffect } from '@storybook/preview-api'; import { observer } from 'mobx-react-lite'; import { SnapTemplates, TemplatesStore } from '../../src'; import { ThemeComplete, ThemeProvider } from '../src/providers/theme'; -import { base, bocachica, snappy, snapnco } from '../src/themes'; +import { base, bocachica, everest, matterhorn, pike, snappy, snapnco } from '../src/themes'; // custom styles for storybook import './styles.scss'; -import { SnapProvider, Theme } from '../src'; +import { SnapProvider, Theme, TreePathProvider } from '../src'; // snap instance for theming and templates functionality const snapTemplates = new SnapTemplates({ @@ -22,50 +23,129 @@ const snapTemplates = new SnapTemplates({ }); // need to add each theme synchronously -addTheme(snapTemplates, 'snappy', snappy); +addTheme(snapTemplates, 'base', base); addTheme(snapTemplates, 'bocachica', bocachica); +addTheme(snapTemplates, 'everest', everest); +addTheme(snapTemplates, 'matterhorn', matterhorn); +addTheme(snapTemplates, 'pike', pike); addTheme(snapTemplates, 'snapnco', snapnco); -addTheme(snapTemplates, 'base', base); +addTheme(snapTemplates, 'snappy', snappy); + +// color keys that map to theme variables.colors +const COLOR_KEYS = ['primary', 'secondary', 'accent', 'text'] as const; +type ColorKey = typeof COLOR_KEYS[number]; +const GLOBAL_COLOR_PREFIX = 'themeColor_'; +const DEFAULT_COLOR_PREFIX = 'themeDefaultColor_'; + +// register globals so Storybook persists color overrides and theme defaults across story navigation +export const globalTypes = { + themeColor_primary: { defaultValue: '' }, + themeColor_secondary: { defaultValue: '' }, + themeColor_accent: { defaultValue: '' }, + themeColor_text: { defaultValue: '' }, + themeDefaultColor_primary: { defaultValue: '' }, + themeDefaultColor_secondary: { defaultValue: '' }, + themeDefaultColor_accent: { defaultValue: '' }, + themeDefaultColor_text: { defaultValue: '' }, +}; const Providers = observer( - ({ templateStore, children, themeName }: { templateStore: TemplatesStore; themeName: string; children: ComponentChildren }) => { + ({ + templateStore, + children, + themeName, + colorOverrides, + }: { + templateStore: TemplatesStore; + themeName: string; + colorOverrides: Partial>; + children: ComponentChildren; + }) => { const themeLocation = templateStore.themes.library[themeName]; - const mergedTheme = themeLocation?.theme || {}; + const baseTheme = themeLocation?.theme || {}; + + const hasOverrides = COLOR_KEYS.some((k) => colorOverrides[k]); + const mergedTheme = hasOverrides + ? { + ...baseTheme, + variables: { + ...baseTheme.variables, + colors: { + ...baseTheme.variables?.colors, + ...Object.fromEntries(COLOR_KEYS.filter((k) => colorOverrides[k]).map((k) => [k, colorOverrides[k]])), + }, + }, + } + : baseTheme; return ( - {children} + + {children} + ); } ); -const CustomThemeProvider = ({ theme, children }: { theme: Theme; children: ComponentChildren }) => { - return ( - - {children} - - ); -}; +const CustomThemeProvider = ({ + theme, + children, + colorOverrides, +}: { + theme: Theme; + children: ComponentChildren; + colorOverrides: Partial>; +}) => ( + + {children} + +); export const decorators = [ (Story: any, context: any) => { - // if the component is a template we should utilize the themeStore theme - // otherwise we should use the base theme (stripped of all props except styleScripts) + // useGlobals must be called here in the decorator (valid Storybook hook context) + const [globals, updateGlobals] = useGlobals(); + + // Sync the active theme's default colors into globals so the toolbar can display them + const activeThemeName: string = context.globals.theme || 'base'; + useEffect(() => { + const themeStore = snapTemplates.templates.themes.library[activeThemeName]; + const defaultColors = themeStore?.theme?.variables?.colors as Record | undefined; + if (defaultColors) { + const defaults: Record = {}; + COLOR_KEYS.forEach((k) => { + defaults[`${DEFAULT_COLOR_PREFIX}${k}`] = defaultColors[k] || ''; + }); + updateGlobals(defaults); + } + }, [activeThemeName]); + + const colorOverrides: Partial> = {}; + COLOR_KEYS.forEach((k) => { + const v = globals[`${GLOBAL_COLOR_PREFIX}${k}`]; + if (v) colorOverrides[k] = v; + }); - const templateStory = context.kind.match(/^Template/); + // Bind colorOverrides into the provider + const BoundProvider = ({ theme, children }: { theme: Theme; children: ComponentChildren }) => ( + + {children} + + ); const themeDecoratorFn = withThemeFromJSXProvider({ themes: { - snapnco: templateStory ? snapTemplates.templates.themes.library.snapnco.theme : snapTemplates.templates.themes.local.snapncoSimple.theme, - snappy: templateStory ? snapTemplates.templates.themes.library.snappy.theme : snapTemplates.templates.themes.local.snappySimple.theme, - bocachica: templateStory - ? snapTemplates.templates.themes.library.bocachica.theme - : snapTemplates.templates.themes.local.bocachicaSimple.theme, - base: templateStory ? snapTemplates.templates.themes.library.base.theme : snapTemplates.templates.themes.local.baseSimple.theme, + snapnco: snapTemplates.templates.themes.library.snapnco.theme, + snappy: snapTemplates.templates.themes.library.snappy.theme, + bocachica: snapTemplates.templates.themes.library.bocachica.theme, + base: snapTemplates.templates.themes.library.base.theme, + everest: snapTemplates.templates.themes.library.everest.theme, + matterhorn: snapTemplates.templates.themes.library.matterhorn.theme, + pike: snapTemplates.templates.themes.library.pike.theme, }, defaultTheme: 'base', - Provider: templateStory ? CustomThemeProvider : ThemeProvider, + Provider: BoundProvider, }); return themeDecoratorFn(Story, context); @@ -101,36 +181,4 @@ function addTheme(snapTemplates: SnapTemplates, themeName: string, theme: ThemeC currency: {}, innerWidth: window.innerWidth, }); - snapTemplates.templates.addTheme({ - name: `${themeName}Simple`, - type: 'local', - base: generateSimpleTheme(theme), - language: {}, - languageOverrides: {}, - currency: {}, - innerWidth: window.innerWidth, - }); -} - -function generateSimpleTheme(theme: ThemeComplete): ThemeComplete { - // strip off everything except for stylescripts and variables - - const simpleTheme: ThemeComplete = { - name: theme.name, - variables: theme.variables, - components: {}, - responsive: {}, - }; - - for (const componentName in theme.components) { - const componentProps = theme.components[componentName as keyof typeof theme.components]; - simpleTheme.components![componentName as keyof typeof simpleTheme.components] = { - // @ts-ignore - type was removed for overrides - styleScript: componentProps?.styleScript, - // @ts-ignore - type was removed for overrides - themeStyleScript: componentProps?.themeStyleScript, - }; - } - // return theme; - return simpleTheme; } diff --git a/packages/snap-preact/components/src/components/Atoms/Button/Button.tsx b/packages/snap-preact/components/src/components/Atoms/Button/Button.tsx index 192f1da1de..879737a0a7 100644 --- a/packages/snap-preact/components/src/components/Atoms/Button/Button.tsx +++ b/packages/snap-preact/components/src/components/Atoms/Button/Button.tsx @@ -14,7 +14,7 @@ import deepmerge from 'deepmerge'; import Color from 'color'; const defaultStyles: StyleScript = ({ native, color, backgroundColor, borderColor, theme }) => { - const lightenedPrimaryColorObj = new Color(backgroundColor || color || theme?.variables?.colors?.primary).lightness(95); + const lightenedPrimaryColorObj = new Color(backgroundColor || color || theme?.variables?.colors?.primary || undefined).lightness(95); // no styling on native if (native) { diff --git a/packages/snap-preact/components/src/components/Atoms/Icon/Icon.test.tsx b/packages/snap-preact/components/src/components/Atoms/Icon/Icon.test.tsx index f849057102..8e35efec44 100644 --- a/packages/snap-preact/components/src/components/Atoms/Icon/Icon.test.tsx +++ b/packages/snap-preact/components/src/components/Atoms/Icon/Icon.test.tsx @@ -92,7 +92,6 @@ describe('Icon Component', () => { const styles = getComputedStyle(svg); expect(styles.width).toBe(defaultProps.size); expect(styles.height).toBe(defaultProps.size); - expect(styles.fill).toBe(defaultProps.color); const path = svg.querySelector('path'); expect(path).toHaveAttribute('d', iconPaths[icon]); @@ -193,7 +192,6 @@ describe('Icon Component', () => { const styles = getComputedStyle(svg); expect(styles.width).toBe(defaultProps.size); expect(styles.height).toBe(defaultProps.size); - expect(styles.fill).toBe(defaultProps.color); const path = svg.querySelector('path'); expect(path).toHaveAttribute('d', svgPath); diff --git a/packages/snap-preact/components/src/components/Molecules/FacetGridOptions/FacetGridOptions.tsx b/packages/snap-preact/components/src/components/Molecules/FacetGridOptions/FacetGridOptions.tsx index a805c95f66..e01ddd9abb 100644 --- a/packages/snap-preact/components/src/components/Molecules/FacetGridOptions/FacetGridOptions.tsx +++ b/packages/snap-preact/components/src/components/Molecules/FacetGridOptions/FacetGridOptions.tsx @@ -15,7 +15,7 @@ import Color from 'color'; const defaultStyles: StyleScript = ({ columns, gapSize, gridSize, theme }) => { const variables = theme?.variables; - const backgroundColor = new Color(variables?.colors.primary); + const backgroundColor = new Color(variables?.colors.primary || undefined); const color = backgroundColor.isDark() ? '#fff' : '#000'; return css({ diff --git a/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/FacetPaletteOptions.tsx b/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/FacetPaletteOptions.tsx index a2b1ce87cd..68a059f844 100644 --- a/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/FacetPaletteOptions.tsx +++ b/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/FacetPaletteOptions.tsx @@ -16,6 +16,7 @@ import { Checkbox, CheckboxProps } from '../Checkbox'; import { Lang, useLang } from '../../../hooks'; import deepmerge from 'deepmerge'; import Color from 'color'; +import { Image, ImageProps } from '../../Atoms/Image'; const defaultStyles: StyleScript = ({ columns, gridSize, gapSize, horizontal, theme }) => { return css({ @@ -63,6 +64,11 @@ const defaultStyles: StyleScript = ({ columns, gridSiz strokeLinejoin: 'round', opacity: 0, }, + + '&.ss__facet-palette-options__option__palette--image': { + paddingTop: '0', + height: 'auto', + }, }, '.ss__facet-palette-options__option__value': { display: 'block', @@ -206,6 +212,17 @@ export const FacetPaletteOptions = observer((properties: FacetPaletteOptionsProp theme: props?.theme, treePath, }, + image: { + // default props + internalClassName: 'ss__facet-palette-options__image', + // inherited props + ...defined({ + disableStyles, + }), + // component theme overrides + theme: props?.theme, + treePath, + }, checkbox: { // default props internalClassName: 'ss__facet-palette-options__checkbox', @@ -262,6 +279,13 @@ export const FacetPaletteOptions = observer((properties: FacetPaletteOptionsProp ? lowerCaseColorMapping[value.label.toLowerCase()].background : value.value; + const backgroundImageUrl = + lowerCaseColorMapping && + lowerCaseColorMapping[value.label.toLowerCase()] && + lowerCaseColorMapping[value.label.toLowerCase()].backgroundImageUrl + ? lowerCaseColorMapping[value.label.toLowerCase()].backgroundImageUrl + : undefined; + let isDark = false; if (background) { try { @@ -297,12 +321,18 @@ export const FacetPaletteOptions = observer((properties: FacetPaletteOptionsProp
+ {backgroundImageUrl ? ( + {value.label + ) : ( + + )} {!hideIcon && value.filtered && layout?.toLowerCase() == 'grid' && }
@@ -341,6 +371,7 @@ export interface FacetPaletteOptionsProps extends ComponentProps { [name: string]: { label?: string; background?: string; + backgroundImageUrl?: string; }; }; lang?: Partial; @@ -354,6 +385,7 @@ export interface FacetPaletteOptionsLang { } interface FacetPaletteOptionsSubProps { - icon: IconProps; - checkbox: CheckboxProps; + icon: Partial; + checkbox: Partial; + image: Partial; } diff --git a/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/readme.md b/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/readme.md index 66546c1e5b..6ccf8fbdb4 100644 --- a/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/readme.md +++ b/packages/snap-preact/components/src/components/Molecules/FacetPaletteOptions/readme.md @@ -132,7 +132,10 @@ The `onClick` prop allows for a custom callback function for when a facet value #### colorMapping -The colorMapping prop allows for custom color mapping overrides. The object used is keyed by a color label, and can take background and label properties. The color label can be any accepted CSS background property value. So a color, string, hash, RGB, gradiant, or an image URL could be used. The label takes a string value and replaces the color's original label for display. +The colorMapping prop allows for custom color mapping overrides. The object used is keyed by a color label, and can take background, backgroundImageUrl and label properties. +The color label can be any accepted CSS background property value. So a color, string, hash, RGB, gradiant, or an image URL could be used. +The label takes a string value and replaces the color's original label for display. +The backgroundImageUrl will render an actual HTML Image element rather than css background url. ```jsx const colorMapping = { @@ -140,6 +143,10 @@ const colorMapping = { background: 'brown', label: 'Army' }, + 'Red': { + backgroundImageUrl: 'https://s3-figma-hubfile-images-production.figma.com/hub/file/carousel/img/bfbec80cfd07b650c2f02b5f8a8c29b3c726e9da', + label: 'Red' + }, 'Striped': { background: "url(https://mysite.com/cdn/shop/files/candy-stripe-square_small.jpg)", label: "stripy" diff --git a/packages/snap-preact/components/src/components/Molecules/Filter/Filter.tsx b/packages/snap-preact/components/src/components/Molecules/Filter/Filter.tsx index 9c553144ba..0cbc1db617 100644 --- a/packages/snap-preact/components/src/components/Molecules/Filter/Filter.tsx +++ b/packages/snap-preact/components/src/components/Molecules/Filter/Filter.tsx @@ -26,6 +26,7 @@ const defaultStyles: StyleScript = ({}) => { }, '& .ss__filter__label': { marginRight: '5px', + marginLeft: '5px', fontWeight: 'bold', }, }); diff --git a/packages/snap-preact/components/src/components/Molecules/Grid/Grid.stories.tsx b/packages/snap-preact/components/src/components/Molecules/Grid/Grid.stories.tsx index 85b7a3b9f7..81f609e00f 100644 --- a/packages/snap-preact/components/src/components/Molecules/Grid/Grid.stories.tsx +++ b/packages/snap-preact/components/src/components/Molecules/Grid/Grid.stories.tsx @@ -237,8 +237,8 @@ DisabledOption.args = { ], } as GridProps; -export const backgroundImages = (args: GridProps) => ; -backgroundImages.args = { +export const Images = (args: GridProps) => ; +Images.args = { options: [ { value: 'Faded Khaki', diff --git a/packages/snap-preact/components/src/components/Molecules/Grid/Grid.tsx b/packages/snap-preact/components/src/components/Molecules/Grid/Grid.tsx index dd847fc984..0338fd7222 100644 --- a/packages/snap-preact/components/src/components/Molecules/Grid/Grid.tsx +++ b/packages/snap-preact/components/src/components/Molecules/Grid/Grid.tsx @@ -307,7 +307,6 @@ export function Grid(properties: GridProps): JSX.Element { 'ss__grid__option--unavailable': option?.available === false, 'ss__grid__option--dark': isDark, })} - style={{ background: option.background ? option.background : option.backgroundImageUrl ? undefined : option.value }} onClick={(e) => !disabled && !option?.disabled && makeSelection(e as any, option)} ref={(e) => useA11y(e)} title={option.label || option.value.toString()} @@ -315,7 +314,10 @@ export function Grid(properties: GridProps): JSX.Element { aria-selected={selected} aria-disabled={option.disabled} > -
+
{!option.background && option.backgroundImageUrl ? ( {option.label ) : ( diff --git a/packages/snap-preact/components/src/components/Molecules/LoadMore/LoadMore.tsx b/packages/snap-preact/components/src/components/Molecules/LoadMore/LoadMore.tsx index 43466839fe..d42b34fc40 100644 --- a/packages/snap-preact/components/src/components/Molecules/LoadMore/LoadMore.tsx +++ b/packages/snap-preact/components/src/components/Molecules/LoadMore/LoadMore.tsx @@ -21,11 +21,8 @@ const defaultStyles: StyleScript = ({ pagination, progressIndicat flexDirection: 'column', alignItems: 'center', gap: '20px', - '& .ss__load-more__button--disabled': { opacity: 0.7, - borderColor: 'rgba(51,51,51,0.7)', - backgroundColor: 'initial', pointerEvents: 'none', '&:hover': { cursor: 'default', diff --git a/packages/snap-preact/components/src/components/Molecules/Select/Select.tsx b/packages/snap-preact/components/src/components/Molecules/Select/Select.tsx index f17d2920a1..c7cf45b08b 100644 --- a/packages/snap-preact/components/src/components/Molecules/Select/Select.tsx +++ b/packages/snap-preact/components/src/components/Molecules/Select/Select.tsx @@ -17,7 +17,7 @@ import deepmerge from 'deepmerge'; import Color from 'color'; const defaultStyles: StyleScript = ({ color, backgroundColor, borderColor, theme, native }) => { - const lightenedPrimary = new Color(backgroundColor || color || theme?.variables?.colors?.primary).lightness(95); + const lightenedPrimary = new Color(backgroundColor || color || theme?.variables?.colors?.primary || undefined).lightness(95); if (!native) { return css({ display: 'inline-flex', diff --git a/packages/snap-preact/components/src/components/Molecules/Slideshow/Slideshow.tsx b/packages/snap-preact/components/src/components/Molecules/Slideshow/Slideshow.tsx index 77a2f3bce5..359808f725 100644 --- a/packages/snap-preact/components/src/components/Molecules/Slideshow/Slideshow.tsx +++ b/packages/snap-preact/components/src/components/Molecules/Slideshow/Slideshow.tsx @@ -96,11 +96,6 @@ const defaultStyles: StyleScript = ({ theme, slidesToShow = 1, g alignItems: 'center', justifyContent: 'center', cursor: 'pointer', - transition: 'background 0.2s ease', - - '&:hover': { - background: 'rgba(255, 255, 255, 1)', - }, '&:disabled': { cursor: 'not-allowed', diff --git a/packages/snap-preact/components/src/components/Molecules/Terms/Terms.tsx b/packages/snap-preact/components/src/components/Molecules/Terms/Terms.tsx index decc9e750f..3b0af68ca8 100644 --- a/packages/snap-preact/components/src/components/Molecules/Terms/Terms.tsx +++ b/packages/snap-preact/components/src/components/Molecules/Terms/Terms.tsx @@ -7,7 +7,7 @@ import classnames from 'classnames'; import type { AutocompleteController } from '@searchspring/snap-controller'; import type { AutocompleteTermStore } from '@searchspring/snap-store-mobx'; import { ComponentProps, StyleScript } from '../../../types'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { createHoverProps } from '../../../toolbox'; import { mergeProps, mergeStyles } from '../../../utilities'; import { Term } from '@searchspring/snap-store-mobx'; @@ -80,9 +80,12 @@ const emIfyTerm = (term: string, search: string): string => { export const Terms = observer((properties: TermsProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); + const defaultProps: Partial = { vertical: true, previewOnHover: true, + treePath: globalTreePath, }; const props = mergeProps('terms', globalTheme, defaultProps, properties); diff --git a/packages/snap-preact/components/src/components/Organisms/Autocomplete/Autocomplete.tsx b/packages/snap-preact/components/src/components/Organisms/Autocomplete/Autocomplete.tsx index d1b50e72f2..0b3723d30f 100644 --- a/packages/snap-preact/components/src/components/Organisms/Autocomplete/Autocomplete.tsx +++ b/packages/snap-preact/components/src/components/Organisms/Autocomplete/Autocomplete.tsx @@ -16,7 +16,7 @@ import { Banner, BannerProps } from '../../Atoms/Banner'; import { Facets, FacetsProps } from '../Facets'; import { defined, cloneWithProps, mergeProps, mergeStyles } from '../../../utilities'; import { createHoverProps } from '../../../toolbox'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { ComponentProps, FacetDisplay, BreakpointsProps, ResultComponent, StyleScript } from '../../../types'; import { useDisplaySettings } from '../../../hooks/useDisplaySettings'; import { Lang, useA11y, useLang } from '../../../hooks'; @@ -200,6 +200,7 @@ const defaultStyles: StyleScript = ({ export const Autocomplete = observer((properties: AutocompleteProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); const defaultProps: Partial = { termsTitle: '', @@ -208,6 +209,7 @@ export const Autocomplete = observer((properties: AutocompleteProps): JSX.Elemen facetsTitle: '', contentTitle: '', width: '100%', + treePath: globalTreePath, }; let props = mergeProps('autocomplete', globalTheme, defaultProps, properties); @@ -772,7 +774,7 @@ export const Autocomplete = observer((properties: AutocompleteProps): JSX.Elemen {noResultsSlot ? ( cloneWithProps(noResultsSlot, { search, pagination, controller, treePath }) ) : ( -
+
)}
)} diff --git a/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.stories.tsx b/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.stories.tsx index ea07de511a..d6953c041f 100644 --- a/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.stories.tsx +++ b/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.stories.tsx @@ -80,7 +80,7 @@ export default { table: { type: { summary: - "['c1' | 'c2' | 'c3' | 'c4' | 'termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']", + "['c1' | 'c2' | 'c3' | 'c4' | 'termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | 'no-results' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']", }, defaultValue: { summary: "[['c1','c2', 'c3']]" }, }, @@ -91,7 +91,7 @@ export default { table: { type: { summary: - "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", + "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | 'no-results' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", }, defaultValue: { summary: `{ @@ -107,7 +107,7 @@ export default { table: { type: { summary: - "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", + "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | 'no-results' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", }, defaultValue: { summary: `{ @@ -123,7 +123,7 @@ export default { table: { type: { summary: - "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", + "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | 'no-results' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", }, defaultValue: { summary: `{ @@ -139,7 +139,7 @@ export default { table: { type: { summary: - "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", + "{width: '150px', layout: ['termsList' | 'terms.history' | 'terms.trending'| 'terms.suggestions'| 'facets' | 'facetsHorizontal' | 'button.see-more' | 'content' | 'no-results' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header']}", }, }, control: 'array', diff --git a/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.tsx b/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.tsx index b6536e4fc0..b24d4cf6cd 100644 --- a/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.tsx +++ b/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/AutocompleteLayout.tsx @@ -217,11 +217,18 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) alignContent: 'space-between', }, width: '100%', - templates: { - recommendation: { - enabled: true, - }, - }, + templates: + properties.layout == 'terms' + ? { + recommendation: { + enabled: false, + }, + } + : { + recommendation: { + enabled: true, + }, + }, }; let props = mergeProps('autocompleteLayout', globalTheme, defaultProps, properties); @@ -261,6 +268,7 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) limit: 6, disableOverflow: true, disableCollapse: true, + searchable: false, }, facetGridOptions: { columns: 3, @@ -307,7 +315,6 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) const { facetsTitle, contentTitle, - layout, column1, column2, column3, @@ -321,6 +328,8 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) internalClassName, controller, } = props; + let layout = props.layout; + const subProps: AutocompleteSubProps = { button: { internalClassName: 'ss__autocomplete__button--see-more', @@ -339,6 +348,7 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) }, termsList: { internalClassName: 'ss__autocomplete__terms-list', + verticalOptions: props.layout == 'terms' || props.layout == 'mini' ? false : true, // default props controller: controller, // inherited props @@ -350,6 +360,7 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) }, terms: { internalClassName: 'ss__autocomplete__terms', + vertical: props.layout == 'terms' || props.layout == 'mini' ? false : true, // default props controller: controller, // inherited props @@ -682,6 +693,31 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) ); } + if (module == 'no-results' && showResults) { + return ( +
+ {results.length == 0 && !loading ? ( +
+
+ {RecommendationTemplateComponent && recsController?.store?.loaded ? ( +
+ +
+ ) : null} +
+ ) : ( + <> + )} +
+ ); + } + if (module == '_') { return
; } @@ -709,12 +745,31 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) } }; + if (typeof props.layout === 'string') { + if (props.layout === 'terms') { + layout = [['termsList'], ['no-results'], ['_', 'button.see-more']]; + } + if (props.layout === 'mini') { + layout = [['termsList'], ['content'], ['_', 'button.see-more']]; + } + + if (props.layout === 'standard') { + layout = [['c1', 'c2', 'c3']]; + } + } + /***************************************/ return visible && layout?.length ? (
e.stopPropagation()} ref={(e) => useA11y(e, 0, false, reset)} > @@ -727,7 +782,7 @@ export const AutocompleteLayout = observer((properties: AutocompleteLayoutProps) {...mergedLang.closeButton?.all} > - {layout?.map((module) => { + {(layout as ModuleNamesWithColumns[])?.map((module) => { return findModule(module as ModuleNames); })}
@@ -758,12 +813,14 @@ export type ModuleNames = | 'facetsHorizontal' | 'button.see-more' | 'content' + | 'no-results' | '_' | 'banner.left' | 'banner.banner' | 'banner.footer' | 'banner.header'; type ColumnsNames = 'c1' | 'c2' | 'c3' | 'c4'; +type PrebuiltLayouts = 'terms' | 'mini' | 'standard'; type ModuleNamesWithColumns = ModuleNames | ColumnsNames | ModuleNames[] | ColumnsNames[]; type Column = { @@ -775,7 +832,7 @@ type Column = { export interface AutocompleteLayoutProps extends ComponentProps { input: Element | string; controller: AutocompleteController; - layout?: ModuleNamesWithColumns[]; + layout?: ModuleNamesWithColumns[] | PrebuiltLayouts; column1?: Column; column2?: Column; diff --git a/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/readme.md b/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/readme.md index 44dcd472ee..ff264fe356 100644 --- a/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/readme.md +++ b/packages/snap-preact/components/src/components/Organisms/AutocompleteLayout/readme.md @@ -45,7 +45,7 @@ The `_` module is used a seperator module to center|left|right justify the other available modules to use in the layout are -`c1`, `c2`, `c3`, `c4`, `termsList`, `terms.history`, `terms.trending`, `terms.suggestions`, `facets`, `facetsHorizontal`, `button.see-more`, `content`, `_`, `banner.left`, `banner.banner`, `banner.footer`, `banner.header` +`c1`, `c2`, `c3`, `c4`, `termsList`, `terms.history`, `terms.trending`, `terms.suggestions`, `facets`, `facetsHorizontal`, `button.see-more`, `content`, `no-results`, `_`, `banner.left`, `banner.banner`, `banner.footer`, `banner.header` ```jsx diff --git a/packages/snap-preact/components/src/components/Organisms/Facet/Facet.stories.tsx b/packages/snap-preact/components/src/components/Organisms/Facet/Facet.stories.tsx index 9e555c35a2..45d3a5ac46 100644 --- a/packages/snap-preact/components/src/components/Organisms/Facet/Facet.stories.tsx +++ b/packages/snap-preact/components/src/components/Organisms/Facet/Facet.stories.tsx @@ -379,6 +379,18 @@ export default { type: 'object', }, }, + display: { + defaultValue: {}, + description: 'Change props per facet display type', + table: { + type: { + summary: 'object', + }, + }, + control: { + type: 'object', + }, + }, ...componentArgs, }, }; diff --git a/packages/snap-preact/components/src/components/Organisms/Facet/Facet.tsx b/packages/snap-preact/components/src/components/Organisms/Facet/Facet.tsx index 5e22aa5b1e..368345470b 100644 --- a/packages/snap-preact/components/src/components/Organisms/Facet/Facet.tsx +++ b/packages/snap-preact/components/src/components/Organisms/Facet/Facet.tsx @@ -167,6 +167,7 @@ export const Facet = observer((properties: FacetProps): JSX.Element => { iconCollapse, iconExpand, limit, + statefulOverflow, disableOverflow, iconColor, color, @@ -325,9 +326,89 @@ export const Facet = observer((properties: FacetProps): JSX.Element => { }; let limitedValues: Array; + + function escapeRegExp(string: string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string + } + + const [overflowState, setOverflowState] = useState(); + + useEffect(() => { + if (statefulOverflow) { + const interalOverflow: { + enabled: boolean; + limited: boolean; + limit: number; + remaining: number | undefined; + setLimit: (limit: number) => void; + toggle: (val?: boolean) => void; + calculate: () => void; + } = { + enabled: false, + limited: true, + limit: 0, + remaining: undefined, + setLimit: function (limit: number) { + if (limit != this.limit) { + this.enabled = true; + this.limit = limit; + this.calculate(); + } + }, + toggle: function (val?: boolean) { + if (typeof val != 'undefined') { + this.limited = val; + } else { + this.limited = !this.limited; + } + + this.calculate(); + }, + calculate: function () { + if (this.limit > 0) { + const remaining = (facet as ValueFacet)?.values?.length - this.limit; + + if (remaining > 0 && !(facet as ValueFacet)?.search?.input) { + this.enabled = true; + + if (this.limited) { + this.remaining = remaining; + } else { + this.remaining = 0; + } + } else { + this.enabled = false; + } + } + + setOverflowState({ ...this }); + }, + }; + + setOverflowState(interalOverflow); + } + }, []); + if ((facet as ValueFacet)?.overflow && limit && Number.isInteger(limit) && !disableOverflow) { - (facet as ValueFacet).overflow?.setLimit(limit); - limitedValues = (facet as ValueFacet)?.refinedValues; + if (statefulOverflow) { + let values = (facet as ValueFacet)?.values || []; + + if ((facet as ValueFacet)?.search?.input) { + const search = new RegExp(escapeRegExp((facet as ValueFacet)?.search?.input), 'i'); + values = (facet as ValueFacet)?.values.filter((value) => String(value?.label || '').match(search)); + } + + if (overflowState?.enabled && overflowState?.limited) { + values = values.slice(0, overflowState?.limit); + } + if (overflowState?.limit !== limit) { + overflowState?.setLimit(limit); + } + limitedValues = values; + } else { + (facet as ValueFacet).overflow?.setLimit(limit); + limitedValues = (facet as ValueFacet)?.refinedValues; + } } else if ((facet as ValueFacet)?.overflow && Number.isInteger(limit)) { limitedValues = (facet as ValueFacet)?.values.slice(0, limit); } else { @@ -338,7 +419,7 @@ export const Facet = observer((properties: FacetProps): JSX.Element => { // Search within facet const searchableFacet = { - allowableTypes: ['list', 'grid', 'palette'], + allowableTypes: properties.treePath?.includes('autocomplete') ? [] : ['list', 'grid', 'palette'], searchFilter: (e: React.ChangeEvent) => { if ((facet as ValueFacet)?.search) { (facet as ValueFacet).search.input = e.target.value; @@ -353,6 +434,7 @@ export const Facet = observer((properties: FacetProps): JSX.Element => { const facetContentProps = { limitedValues, + overflowState, searchableFacet, subProps, className, @@ -402,7 +484,9 @@ export const Facet = observer((properties: FacetProps): JSX.Element => { className, internalClassName, `${facet.display ? `ss__facet--${facet.display}` : ''}`, - ((facet as ValueFacet)?.overflow?.remaining || 0) > 0 || facet?.display == 'slider' ? '' : 'ss__facet--showing-all' + (statefulOverflow ? overflowState?.remaining || 0 > 0 : ((facet as ValueFacet)?.overflow?.remaining || 0) > 0) || facet?.display == 'slider' + ? '' + : 'ss__facet--showing-all' )} > {justContent ? ( @@ -475,6 +559,7 @@ const FacetContent = ( }; subProps: FacetSubProps; mergedLang: LangAttributesObj; + overflowState?: overflowStateType; } ) => { const { @@ -484,6 +569,7 @@ const FacetContent = ( internalClassName, limitedValues, facet, + statefulOverflow, limit, overflowSlot, optionsSlot, @@ -535,6 +621,13 @@ const FacetContent = ( const submitButtonRef: MutableRef = useRef(); + let overflowState: overflowStateType | undefined; + if (!statefulOverflow) { + overflowState = (facet as ValueFacet).overflow; + } else { + overflowState = props.overflowState; + } + return ( {searchable && searchableFacet.allowableTypes.includes(facet.display) && ( @@ -670,13 +763,8 @@ const FacetContent = (
)} - {!disableOverflow && (facet as ValueFacet)?.overflow?.enabled && ( -
(facet as ValueFacet).overflow?.toggle()} - ref={(e) => useA11y(e)} - > + {!disableOverflow && overflowState?.enabled && ( +
overflowState?.toggle()} ref={(e) => useA11y(e)}> {overflowSlot ? ( cloneWithProps(overflowSlot, { facet, treePath }) ) : ( @@ -684,14 +772,12 @@ const FacetContent = ( 0 + {...((overflowState?.remaining || 0) > 0 ? { ...(typeof iconOverflowMore == 'string' ? { icon: iconOverflowMore } : (iconOverflowMore as Partial)) } : { ...(typeof iconOverflowLess == 'string' ? { icon: iconOverflowLess } : (iconOverflowLess as Partial)) })} /> {!hideShowMoreLessText && ( - 0 ? mergedLang!.showMoreText?.all : mergedLang!.showLessText?.all)} - > + 0 ? mergedLang!.showMoreText?.all : mergedLang!.showLessText?.all)}> )} )} @@ -726,6 +812,7 @@ interface OptionalFacetProps extends ComponentProps { iconColor?: string; iconExpand?: IconType | Partial; limit?: number; + statefulOverflow?: boolean; overflowSlot?: JSX.Element | JSX.Element[]; optionsSlot?: JSX.Element | JSX.Element[]; disableOverflow?: boolean; @@ -775,3 +862,13 @@ export interface FacetLang { type FieldProps = { [variable: string]: Omit; }; + +type overflowStateType = { + enabled: boolean; + limited: boolean; + limit: number; + remaining: number | undefined; + setLimit: (limit: number) => void; + toggle: (val?: boolean) => void; + calculate: () => void; +}; diff --git a/packages/snap-preact/components/src/components/Organisms/Facet/readme.md b/packages/snap-preact/components/src/components/Organisms/Facet/readme.md index 8eb9cfc103..070eff7e8e 100644 --- a/packages/snap-preact/components/src/components/Organisms/Facet/readme.md +++ b/packages/snap-preact/components/src/components/Organisms/Facet/readme.md @@ -236,6 +236,32 @@ const fieldsProp = { ``` +### display +The `display` prop allows you to manually change prop values on a per-facet display type level + +```typescript +const displayProp = { + display: { + list: { + limit: 5, + }, + hierarchy: { + limit: 3 + }, + grid: { + limit: 10 + }, + palette: { + limit: 20 + } + } +}, +``` + +```jsx + +``` + ### optionsSlot The `optionsSlot` prop is a JSX element used to manually set the options component used, regardless of the facet.display type. Returns the facet,valueProps, limit, & previewOnFocus prop values. diff --git a/packages/snap-preact/components/src/components/Organisms/FacetsHorizontal/FacetsHorizontal.tsx b/packages/snap-preact/components/src/components/Organisms/FacetsHorizontal/FacetsHorizontal.tsx index 73a95be533..6c9886dae3 100644 --- a/packages/snap-preact/components/src/components/Organisms/FacetsHorizontal/FacetsHorizontal.tsx +++ b/packages/snap-preact/components/src/components/Organisms/FacetsHorizontal/FacetsHorizontal.tsx @@ -181,6 +181,8 @@ export const FacetsHorizontal = observer((properties: FacetsHorizontalProps): JS // default props internalClassName: `ss__facets-horizontal__content__facet`, justContent: true, + // this should be turned on if there is ever a filters button rendering. + statefulOverflow: !hideFiltersButton && (isOverflowing || alwaysShowFiltersButton) ? true : undefined, // horizontal: true, // inherited props ...defined({ diff --git a/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.stories.tsx b/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.stories.tsx index 3d958cef52..51d1777dc1 100644 --- a/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.stories.tsx +++ b/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.stories.tsx @@ -152,6 +152,20 @@ export default { control: { type: 'none' }, action: 'onClick', }, + type: { + defaultValue: 'inline', + description: 'display type', + table: { + type: { + summary: 'string', + }, + defaultValue: { summary: 'inline' }, + }, + options: ['inline', 'list'], + control: { + type: 'select', + }, + }, onClearAllClick: { description: 'Filter clear click event handler', table: { diff --git a/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.test.tsx b/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.test.tsx index 5635cd8cef..b532b1b87e 100644 --- a/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.test.tsx +++ b/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.test.tsx @@ -165,7 +165,7 @@ describe('FilterSummary Component', () => { const rendered = render(); const facetsElement = rendered.container.querySelector('.ss__filter-summary'); - expect(facetsElement?.classList).toHaveLength(1); + expect(facetsElement?.classList).toHaveLength(2); }); }); diff --git a/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.tsx b/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.tsx index def5476e93..13107fe220 100644 --- a/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.tsx +++ b/packages/snap-preact/components/src/components/Organisms/FilterSummary/FilterSummary.tsx @@ -14,7 +14,8 @@ import { IconProps, IconType } from '../../Atoms/Icon'; import { Lang, useLang } from '../../../hooks'; import deepmerge from 'deepmerge'; -const defaultStyles: StyleScript = () => { +const defaultStyles: StyleScript = (props) => { + const variables = props.theme?.variables; return css({ '.ss__filter-summary__title': { fontSize: '1.2em', @@ -26,6 +27,45 @@ const defaultStyles: StyleScript = () => { gap: '10px', flexWrap: 'wrap', }, + + '&.ss__filter-summary--list': { + '& .ss__filter-summary__clear-all .ss__filter__value': { + marginLeft: '5px', + }, + + '&, .ss__filter-summary__filters': { + display: 'block', + }, + + '.ss__filter-summary__filters': { + '.ss__filter': { + display: 'block', + margin: `0 5px 5px 5px`, + '.ss__filter__button': { + padding: `0 0 0 0`, + border: 0, + '&, &:hover, &:not(.ss__button--disabled):hover, &.ss__button--disabled': { + backgroundColor: 'transparent', + }, + '.ss__button__content': { + display: 'flex', + alignItems: 'center', + + '.ss__icon': { + padding: '4px', + backgroundColor: '#f8f8f8', + border: `1px solid black`, + width: `8px`, + height: `8px`, + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + marginRight: '0px', + }, + }, + }, + }, + }, + }, }); }; @@ -35,6 +75,7 @@ export const FilterSummary = observer((properties: FilterSummaryProps): JSX.Elem const defaultProps: Partial = { title: 'Current Filters', + type: 'inline', clearAllLabel: 'Clear All', clearAllIcon: 'close-thin', filterIcon: 'close-thin', @@ -49,6 +90,7 @@ export const FilterSummary = observer((properties: FilterSummaryProps): JSX.Elem const { filters, title, + type, filterIcon, clearAllIcon, separator, @@ -102,7 +144,16 @@ export const FilterSummary = observer((properties: FilterSummaryProps): JSX.Elem return filters?.length ? ( -
+
{!hideTitle &&
}
@@ -134,6 +185,7 @@ export const FilterSummary = observer((properties: FilterSummaryProps): JSX.Elem export interface FilterSummaryProps extends ComponentProps { filters?: FilterType[]; + type?: 'inline' | 'list'; title?: string; hideTitle?: boolean; filterIcon?: IconType | Partial; diff --git a/packages/snap-preact/components/src/components/Organisms/FilterSummary/readme.md b/packages/snap-preact/components/src/components/Organisms/FilterSummary/readme.md index 3c5d5ca3ca..bd6710fcf8 100644 --- a/packages/snap-preact/components/src/components/Organisms/FilterSummary/readme.md +++ b/packages/snap-preact/components/src/components/Organisms/FilterSummary/readme.md @@ -78,6 +78,13 @@ The `hideClearAll` prop prevents the 'clear all' button from rendering. ``` +### type +The `type` prop determines what layout the filters should be rendered as. Options are `list` or `inline`. `inline` is default. + +```jsx + +``` + ### Events #### onClick diff --git a/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.stories.tsx b/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.stories.tsx index 231b201985..4f6cf1ecd8 100644 --- a/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.stories.tsx +++ b/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.stories.tsx @@ -83,17 +83,27 @@ export default { type: { summary: 'string', }, - defaultValue: { summary: 'History' }, + defaultValue: { summary: 'Recent Searches' }, }, control: { type: 'text' }, }, + verticalOptions: { + description: 'boolean to specify if the terms should be displayed vertically', + table: { + type: { + summary: 'boolean', + }, + defaultValue: { summary: undefined }, + }, + control: { type: 'boolean' }, + }, suggestionTitle: { description: 'suggested terms title', table: { type: { summary: 'string', }, - defaultValue: { summary: 'Suggestions' }, + defaultValue: { summary: 'Search Suggestions' }, }, control: { type: 'text' }, }, @@ -103,7 +113,7 @@ export default { type: { summary: 'string', }, - defaultValue: { summary: 'Trending' }, + defaultValue: { summary: 'Popular Searches' }, }, control: { type: 'text' }, }, diff --git a/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.tsx b/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.tsx index b1844918a5..04fedba46d 100644 --- a/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.tsx +++ b/packages/snap-preact/components/src/components/Organisms/TermsList/TermsList.tsx @@ -1,12 +1,11 @@ import { Fragment, h } from 'preact'; - import { observer } from 'mobx-react-lite'; import { jsx, css } from '@emotion/react'; import classnames from 'classnames'; import type { AutocompleteController } from '@searchspring/snap-controller'; import { ComponentProps, StyleScript } from '../../../types'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { defined, mergeProps, mergeStyles } from '../../../utilities'; import { Terms, TermsProps } from '../../Molecules/Terms/Terms'; import { useCleanUpEmptyDivs } from '../../../hooks/useCleanUpEmptyDivs'; @@ -38,17 +37,21 @@ const defaultStyles: StyleScript = ({}) => { export const TermsList = observer((properties: TermsListProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); + const defaultProps: Partial = { layout: [['Suggestions'], ['Trending'], ['History']], - historyTitle: 'History', - trendingTitle: 'Trending', - suggestionTitle: 'Suggestions', + historyTitle: 'Recent Searches', + trendingTitle: 'Popular Searches', + suggestionTitle: 'Search Suggestions', + treePath: globalTreePath, }; const props = mergeProps('termsList', globalTheme, defaultProps, properties); const { layout, historyTitle, + verticalOptions, trendingTitle, suggestionTitle, retainHistory, @@ -62,6 +65,7 @@ export const TermsList = observer((properties: TermsListProps): JSX.Element => { const subProps: TermsListSubProps = { terms: { + vertical: verticalOptions ? true : false, // default props // inherited props ...defined({ @@ -178,4 +182,5 @@ export interface TermsListProps extends ComponentProps { trendingTitle?: string; retainHistory?: boolean; retainTrending?: boolean; + verticalOptions?: boolean; } diff --git a/packages/snap-preact/components/src/components/Organisms/TermsList/readme.md b/packages/snap-preact/components/src/components/Organisms/TermsList/readme.md index d8ee7aea71..1147c004ea 100644 --- a/packages/snap-preact/components/src/components/Organisms/TermsList/readme.md +++ b/packages/snap-preact/components/src/components/Organisms/TermsList/readme.md @@ -22,6 +22,22 @@ The `_` module is used a seperator module to center|left|right justify the other ``` +### horizontal + +The `horizontal` prop specifies if the terms should be rendered horizontally. + +```jsx + +``` + +### verticalOptions + +The `verticalOptions` prop specifies if the terms options should be rendered vertically. + +```jsx + +``` + ### historyTitle The `historyTitle` prop specifies the title to render above the history terms. diff --git a/packages/snap-preact/components/src/components/Templates/AutocompleteSlideout/AutocompleteSlideout.tsx b/packages/snap-preact/components/src/components/Templates/AutocompleteSlideout/AutocompleteSlideout.tsx index e8ec0ae036..fd827edcd0 100644 --- a/packages/snap-preact/components/src/components/Templates/AutocompleteSlideout/AutocompleteSlideout.tsx +++ b/packages/snap-preact/components/src/components/Templates/AutocompleteSlideout/AutocompleteSlideout.tsx @@ -166,7 +166,7 @@ export const AutocompleteSlideout = observer((properties: AutocompleteSlideoutPr className={classNames('ss__autocomplete-slideout', 'ss__autocomplete-slideout__slideout', className, internalClassName)} active={active} > -
useA11y(e, 0, true, reset)}> +
useA11y(e, 0, true, reset)}> {renderInput ? ( ) : ( diff --git a/packages/snap-preact/components/src/components/Templates/Recommendation/Recommendation.tsx b/packages/snap-preact/components/src/components/Templates/Recommendation/Recommendation.tsx index 37388d1110..26b0d750e7 100644 --- a/packages/snap-preact/components/src/components/Templates/Recommendation/Recommendation.tsx +++ b/packages/snap-preact/components/src/components/Templates/Recommendation/Recommendation.tsx @@ -14,7 +14,7 @@ import { Carousel, CarouselProps, defaultCarouselBreakpoints, defaultVerticalCar import { Result, ResultProps } from '../../Molecules/Result'; import { defined, mergeProps, mergeStyles } from '../../../utilities'; import { useIntersection } from '../../../hooks'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { ComponentProps, BreakpointsProps, ResultComponent, StyleScript } from '../../../types'; import { useDisplaySettings } from '../../../hooks/useDisplaySettings'; import { RecommendationProfileTracker } from '../../Trackers/Recommendation/ProfileTracker'; @@ -32,6 +32,7 @@ const defaultStyles: StyleScript = ({ vertical }) => { export const Recommendation = observer((properties: RecommendationProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); const defaultProps: Partial = { breakpoints: properties.vertical @@ -41,6 +42,7 @@ export const Recommendation = observer((properties: RecommendationProps): JSX.El loop: true, title: properties.controller?.store?.profile?.display?.templateParameters?.title, description: properties.controller?.store?.profile?.display?.templateParameters?.description, + treePath: globalTreePath, }; //mergeprops only uses names that are passed via properties, so this cannot be put in the defaultProps diff --git a/packages/snap-preact/components/src/components/Templates/RecommendationBundle/RecommendationBundle.tsx b/packages/snap-preact/components/src/components/Templates/RecommendationBundle/RecommendationBundle.tsx index 8a612f58c7..7054515cc7 100644 --- a/packages/snap-preact/components/src/components/Templates/RecommendationBundle/RecommendationBundle.tsx +++ b/packages/snap-preact/components/src/components/Templates/RecommendationBundle/RecommendationBundle.tsx @@ -7,7 +7,7 @@ import deepmerge from 'deepmerge'; import { Carousel, CarouselProps as CarouselProps } from '../../Molecules/Carousel'; import { Result, ResultProps } from '../../Molecules/Result'; import { cloneWithProps, defined, mergeProps, mergeStyles } from '../../../utilities'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { ComponentProps, BreakpointsProps, ResultComponent, StyleScript, BreakpointsEntry } from '../../../types'; import { useDisplaySettings } from '../../../hooks/useDisplaySettings'; import { RecommendationProfileTracker } from '../../Trackers/Recommendation/ProfileTracker'; @@ -145,6 +145,8 @@ const defaultStyles: StyleScript { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); + const defaultCarouselBreakpoints = { 0: { slidesPerView: 2, @@ -179,6 +181,7 @@ export const RecommendationBundle = observer((properties: RecommendationBundlePr onAddToCart: (e, items) => controller?.addToCart && controller.addToCart(items), title: properties.controller?.store?.profile?.display?.templateParameters?.title, description: properties.controller?.store?.profile?.display?.templateParameters?.description, + treePath: globalTreePath, }; //mergeprops only uses names that are passed via properties, so this cannot be put in the defaultProps diff --git a/packages/snap-preact/components/src/components/Templates/RecommendationBundleList/RecommendationBundleList.tsx b/packages/snap-preact/components/src/components/Templates/RecommendationBundleList/RecommendationBundleList.tsx index f7d3261405..7e3b3414bf 100644 --- a/packages/snap-preact/components/src/components/Templates/RecommendationBundleList/RecommendationBundleList.tsx +++ b/packages/snap-preact/components/src/components/Templates/RecommendationBundleList/RecommendationBundleList.tsx @@ -44,7 +44,6 @@ const defaultStyles: StyleScript = () => { '.ss__button': { cursor: 'pointer', - border: '1px solid black', }, '.ss__recommendation-bundle-list__wrapper__cta__inner__images': { display: 'flex', @@ -202,7 +201,7 @@ export const CTASlot = observer((props: BundledCTAProps): JSX.Element => { const mergedLang = useLang(lang as any, {}); return ( -
+ <>
{cartStore.items.map((item: any) => { @@ -242,13 +241,13 @@ export const CTASlot = observer((props: BundledCTAProps): JSX.Element => {
-
+
-
+ ); }); diff --git a/packages/snap-preact/components/src/components/Templates/RecommendationEmail/RecommendationEmail.tsx b/packages/snap-preact/components/src/components/Templates/RecommendationEmail/RecommendationEmail.tsx index c754fdcade..714fffc5bd 100644 --- a/packages/snap-preact/components/src/components/Templates/RecommendationEmail/RecommendationEmail.tsx +++ b/packages/snap-preact/components/src/components/Templates/RecommendationEmail/RecommendationEmail.tsx @@ -7,7 +7,7 @@ import type { Product } from '@searchspring/snap-store-mobx'; import classnames from 'classnames'; import { Result, ResultProps } from '../../Molecules/Result'; import { defined, mergeProps, mergeStyles } from '../../../utilities'; -import { Theme, ThemeComponent, useTheme } from '../../../providers'; +import { Theme, ThemeComponent, useTheme, useTreePath } from '../../../providers'; import { ComponentProps, ResultComponent, StyleScript } from '../../../types'; export const recommendationEmailThemeComponentProps: ThemeComponent<'recommendationEmailThemeComponentProps', RecommendationEmailProps> = { @@ -23,9 +23,12 @@ const defaultStyles: StyleScript = () => { export const RecommendationEmail = observer((properties: RecommendationEmailProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); + const defaultProps: Partial = { resultWidth: '240px', name: properties.controller?.store?.profile?.tag?.toLowerCase(), + treePath: globalTreePath, }; const props = mergeProps('recommendationEmail', globalTheme, defaultProps, properties); diff --git a/packages/snap-preact/components/src/components/Templates/RecommendationGrid/RecommendationGrid.tsx b/packages/snap-preact/components/src/components/Templates/RecommendationGrid/RecommendationGrid.tsx index 978a10da6b..368d990279 100644 --- a/packages/snap-preact/components/src/components/Templates/RecommendationGrid/RecommendationGrid.tsx +++ b/packages/snap-preact/components/src/components/Templates/RecommendationGrid/RecommendationGrid.tsx @@ -8,7 +8,7 @@ import type { Product } from '@searchspring/snap-store-mobx'; import { Result, ResultProps } from '../../Molecules/Result'; import { ComponentProps, BreakpointsProps, ResultComponent, StyleScript } from '../../../types'; import { defined, mergeProps, mergeStyles } from '../../../utilities'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { useDisplaySettings } from '../../../hooks/useDisplaySettings'; import { RecommendationProfileTracker } from '../../Trackers/Recommendation/ProfileTracker'; import { ResultTracker } from '../../Trackers/ResultTracker'; @@ -37,11 +37,13 @@ const defaultStyles: StyleScript = ({ gapSize, columns export const RecommendationGrid = observer((properties: RecommendationGridProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); const defaultProps: Partial = { results: properties.controller?.store?.results, gapSize: '20px', title: properties.controller?.store?.profile?.display?.templateParameters?.title, + treePath: globalTreePath, }; //mergeprops only uses names that are passed via properties, so this cannot be put in the defaultProps @@ -131,7 +133,13 @@ export const RecommendationGrid = observer((properties: RecommendationGridProps) } else { return ( - + ); } diff --git a/packages/snap-preact/components/src/components/Templates/Search/Search.tsx b/packages/snap-preact/components/src/components/Templates/Search/Search.tsx index 18d87e7776..614715ca6e 100644 --- a/packages/snap-preact/components/src/components/Templates/Search/Search.tsx +++ b/packages/snap-preact/components/src/components/Templates/Search/Search.tsx @@ -7,7 +7,7 @@ import type { SearchController } from '@searchspring/snap-controller'; import { Results, ResultsProps } from '../../Organisms/Results'; import { defined, mergeProps, mergeStyles } from '../../../utilities'; import { ComponentProps, ListOption, ResultComponent, StyleScript } from '../../../types'; -import { Theme, useTheme, CacheProvider } from '../../../providers'; +import { Theme, useTheme, CacheProvider, useTreePath } from '../../../providers'; import { Sidebar, SidebarProps } from '../../Organisms/Sidebar'; import { Toolbar, ToolbarProps } from '../../Organisms/Toolbar'; import { NoResults, NoResultsProps } from '../../Organisms/NoResults'; @@ -56,11 +56,13 @@ const defaultStyles: StyleScript = (props) => { export const Search = observer((properties: SearchProps): JSX.Element => { const globalTheme: Theme = useTheme(); + const globalTreePath = useTreePath(); const defaultProps: Partial = { toggleSidebarButtonText: 'Filters', hideToggleSidebarButton: true, mobileDisplayAt: globalTheme?.variables?.breakpoints?.tablet ? `${globalTheme.variables?.breakpoints?.tablet}px` : '991px', + treePath: globalTreePath, }; const props = mergeProps(properties.alias || 'search', globalTheme, defaultProps, properties); @@ -80,6 +82,7 @@ export const Search = observer((properties: SearchProps): JSX.Element => { mobileDisplayAt, toggleSidebarStartClosed, treePath, + alias, } = props; let classNamePrefix = 'ss__search'; @@ -96,7 +99,7 @@ export const Search = observer((properties: SearchProps): JSX.Element => { const isMobile = useMediaQuery(`(max-width: ${mobileDisplayAt})`); - const [sidebarOpenState, setSidebarOpenState] = useState(Boolean(!toggleSidebarStartClosed)); + const [sidebarOpenState, setSidebarOpenState] = useState(Boolean(alias !== 'searchHorizontal' && !toggleSidebarStartClosed)); //initialize lang const defaultLang: Partial = { @@ -154,7 +157,7 @@ export const Search = observer((properties: SearchProps): JSX.Element => { name: 'middle', internalClassName: `${classNamePrefix}__content__toolbar--middle-toolbar`, layout: isMobile - ? [['mobileSidebar', '_', 'paginationInfo'], ['filterSummary'], ['banner.banner']] + ? [['mobileSidebar', '_', 'paginationInfo'], ['banner.banner']] : [['sortBy', 'perPage', '_', 'paginationInfo'], ['banner.banner']], toggleSideBarButton: { ...toggleSidebarButtonProps }, // inherited props @@ -168,7 +171,7 @@ export const Search = observer((properties: SearchProps): JSX.Element => { // default props name: 'bottom', internalClassName: `${classNamePrefix}__content__toolbar--bottom-toolbar`, - layout: [['banner.footer'], ['_', 'pagination']], + layout: [['banner.footer'], ['_', 'pagination', '_']], toggleSideBarButton: { ...toggleSidebarButtonProps }, // inherited props ...defined({ diff --git a/packages/snap-preact/components/src/components/Templates/SearchHorizontal/SearchHorizontal.tsx b/packages/snap-preact/components/src/components/Templates/SearchHorizontal/SearchHorizontal.tsx index c67bb4565c..6bb23f3ab0 100644 --- a/packages/snap-preact/components/src/components/Templates/SearchHorizontal/SearchHorizontal.tsx +++ b/packages/snap-preact/components/src/components/Templates/SearchHorizontal/SearchHorizontal.tsx @@ -8,7 +8,7 @@ import { Search, SearchProps } from '../Search/Search'; export const SearchHorizontal = observer((properties: SearchHorizontalProps): JSX.Element => { return ( - + ); }); diff --git a/packages/snap-preact/components/src/hooks/useLayoutOptions.tsx b/packages/snap-preact/components/src/hooks/useLayoutOptions.tsx index bdf77da83f..5d8cab186b 100644 --- a/packages/snap-preact/components/src/hooks/useLayoutOptions.tsx +++ b/packages/snap-preact/components/src/hooks/useLayoutOptions.tsx @@ -37,7 +37,6 @@ export const useLayoutOptions = (props: any, globalTheme: Theme) => { }, }; let shouldUseOverrides = false; - if (globalTheme.components && props.treePath) { // pull out the template (top level parent) component from the treePath to use in filtering out globalTheme overrides const templateComponent = props.treePath.split(' ')[0]; diff --git a/packages/snap-preact/components/src/providers/themeComponents.ts b/packages/snap-preact/components/src/providers/themeComponents.ts index 25e087f7c7..33d16d64e5 100644 --- a/packages/snap-preact/components/src/providers/themeComponents.ts +++ b/packages/snap-preact/components/src/providers/themeComponents.ts @@ -112,7 +112,7 @@ type ThemeComponentNamedSelectorsStartingWithTemplate< | `${TemplateComponentType} ${SubComponentType}.${ComponentNames}`; export type ThemeComponentRestrictedProps = Partial>; -type ThemeComponentOmittedProps = 'theme' | 'inherits' | 'disableStyles' | 'styleScript'; +type ThemeComponentOmittedProps = 'theme' | 'inherits' | 'disableStyles' | 'styleScript' | 'internalClassName' | 'className'; type ThemeComponentOverridesRestrictedProps = Partial>; type ThemeComponentOverrideOmittedProps = @@ -127,6 +127,7 @@ type ThemeComponentOverrideOmittedProps = | 'filter' | 'lang' | 'internalClassName' + | 'className' | 'ref' | 'snap' | 'name' diff --git a/packages/snap-preact/components/src/themes/base/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/base/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..abeed134dc --- /dev/null +++ b/packages/snap-preact/components/src/themes/base/components/organisms/autocomplete.ts @@ -0,0 +1,22 @@ +import { css } from '@emotion/react'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; + +// CSS in JS style script for the Search component +const autocompleteStyleScript = ({}: AutocompleteProps) => { + return css({}); +}; + +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + ...(autocompleteThemeComponentProps.default?.['autocomplete'] || {}), + themeStyleScript: autocompleteStyleScript, + }, + }, + mobile: autocompleteThemeComponentProps.mobile, + desktop: autocompleteThemeComponentProps.desktop, + tablet: autocompleteThemeComponentProps.tablet, +}; diff --git a/packages/snap-preact/components/src/themes/base/components/organisms/index.ts b/packages/snap-preact/components/src/themes/base/components/organisms/index.ts index 4b04b40aa9..d4300a69cb 100644 --- a/packages/snap-preact/components/src/themes/base/components/organisms/index.ts +++ b/packages/snap-preact/components/src/themes/base/components/organisms/index.ts @@ -1,10 +1,19 @@ import { ThemeResponsiveComplete } from '../../../../providers'; +import { autocomplete } from './autocomplete'; // ORGANISMS Imports export const organisms: ThemeResponsiveComplete = { - default: {}, - mobile: {}, - tablet: {}, - desktop: {}, + default: { + ...autocomplete.default, + }, + mobile: { + ...autocomplete.mobile, + }, + tablet: { + ...autocomplete.tablet, + }, + desktop: { + ...autocomplete.desktop, + }, }; diff --git a/packages/snap-preact/components/src/themes/bocachica/components/atoms/button.ts b/packages/snap-preact/components/src/themes/bocachica/components/atoms/button.ts index 82405462a7..333c08d82b 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/atoms/button.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/atoms/button.ts @@ -6,7 +6,7 @@ import Color from 'color'; // CSS in JS style script for the Button component const buttonStyleScript = ({ backgroundColor, theme }: ButtonProps) => { const variables = theme?.variables; - const hoverBackgroundColorObj = new Color(backgroundColor || variables?.colors.primary); + const hoverBackgroundColorObj = new Color(backgroundColor || variables?.colors.primary || undefined); const hoverColorObj = hoverBackgroundColorObj.isDark() ? Color('#fff') : Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/bocachica/components/molecules/checkbox.ts b/packages/snap-preact/components/src/themes/bocachica/components/molecules/checkbox.ts index c1c39a894f..c2761e1b0a 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/molecules/checkbox.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/molecules/checkbox.ts @@ -6,7 +6,7 @@ import Color from 'color'; // CSS in JS style script for the Checkbox component const checkboxStyleScript = ({ color, theme }: CheckboxProps) => { const variables = theme?.variables; - const backgroundColorObj = new Color(color || variables?.colors.primary); + const backgroundColorObj = new Color(color || variables?.colors.primary || undefined); const backgroundTextColorObj = backgroundColorObj.isDark() ? new Color('#fff') : new Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/bocachica/components/molecules/facetGridOptions.ts b/packages/snap-preact/components/src/themes/bocachica/components/molecules/facetGridOptions.ts index e30020895f..a25b2eb7ed 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/molecules/facetGridOptions.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/molecules/facetGridOptions.ts @@ -6,7 +6,7 @@ import Color from 'color'; // CSS in JS style script for the FacetGridOptions component const facetGridOptionsStyleScript = ({ theme }: FacetGridOptionsProps) => { const variables = theme?.variables; - const backgroundColorObj = new Color(variables?.colors.primary); + const backgroundColorObj = new Color(variables?.colors.primary || undefined); const colorObj = backgroundColorObj.isDark() ? new Color('#fff') : new Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/bocachica/components/molecules/filter.ts b/packages/snap-preact/components/src/themes/bocachica/components/molecules/filter.ts index ecc32acdfe..6902df7d12 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/molecules/filter.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/molecules/filter.ts @@ -7,7 +7,7 @@ import Color from 'color'; const filterStyleScript = ({ theme }: FilterProps) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const variables = theme?.variables; - const backgroundColor = new Color(variables?.colors.primary); + const backgroundColor = new Color(variables?.colors.primary || undefined); const backgroundTextColor = backgroundColor.isDark() ? '#fff' : '#000'; return css({ diff --git a/packages/snap-preact/components/src/themes/bocachica/components/molecules/loadMore.ts b/packages/snap-preact/components/src/themes/bocachica/components/molecules/loadMore.ts index b6db2ec0e8..7269ad084f 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/molecules/loadMore.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/molecules/loadMore.ts @@ -7,8 +7,8 @@ import Color from 'color'; const loadMoreStyleScript = ({ color, backgroundColor, theme }: LoadMoreProps) => { const variables = theme?.variables; - const barColour = new Color(color || variables?.colors.accent); - const backgroundColour = backgroundColor ? new Color(backgroundColor) : barColour.lightness(90); + const barColour = new Color(color || variables?.colors.accent || undefined); + const backgroundColour = backgroundColor ? new Color(backgroundColor || undefined) : barColour.lightness(90); return css({ '.ss__button': { diff --git a/packages/snap-preact/components/src/themes/bocachica/components/molecules/select.ts b/packages/snap-preact/components/src/themes/bocachica/components/molecules/select.ts index ffde53708a..775a6b73b2 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/molecules/select.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/molecules/select.ts @@ -6,7 +6,7 @@ import Color from 'color'; // CSS in JS style script for the Select component const selectStyleScript = ({ backgroundColor, theme }: SelectProps) => { const variables = theme?.variables; - const transparentSecondary = new Color(theme?.variables?.colors?.secondary).opaquer(0.2); + const transparentSecondary = new Color(theme?.variables?.colors?.secondary || undefined).opaquer(0.2); return css({ '.ss__dropdown': { '.ss__select__dropdown__button': { diff --git a/packages/snap-preact/components/src/themes/bocachica/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/bocachica/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..abeed134dc --- /dev/null +++ b/packages/snap-preact/components/src/themes/bocachica/components/organisms/autocomplete.ts @@ -0,0 +1,22 @@ +import { css } from '@emotion/react'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; + +// CSS in JS style script for the Search component +const autocompleteStyleScript = ({}: AutocompleteProps) => { + return css({}); +}; + +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + ...(autocompleteThemeComponentProps.default?.['autocomplete'] || {}), + themeStyleScript: autocompleteStyleScript, + }, + }, + mobile: autocompleteThemeComponentProps.mobile, + desktop: autocompleteThemeComponentProps.desktop, + tablet: autocompleteThemeComponentProps.tablet, +}; diff --git a/packages/snap-preact/components/src/themes/bocachica/components/organisms/index.ts b/packages/snap-preact/components/src/themes/bocachica/components/organisms/index.ts index 257776ad6e..103caf9917 100644 --- a/packages/snap-preact/components/src/themes/bocachica/components/organisms/index.ts +++ b/packages/snap-preact/components/src/themes/bocachica/components/organisms/index.ts @@ -9,9 +9,10 @@ import { noResults } from './noResults'; import { sidebar } from './sidebar'; import { termsList } from './termsList'; import { toolbar } from './toolbar'; - +import { autocomplete } from './autocomplete'; export const organisms: ThemeResponsiveComplete = { default: { + ...autocomplete.default, ...facet.default, ...facetsHorizontal.default, ...filterSummary.default, @@ -22,6 +23,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.default, }, mobile: { + ...autocomplete.mobile, ...facet.mobile, ...facetsHorizontal.mobile, ...filterSummary.mobile, @@ -32,6 +34,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.mobile, }, tablet: { + ...autocomplete.tablet, ...facet.tablet, ...facetsHorizontal.tablet, ...filterSummary.tablet, @@ -42,6 +45,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.tablet, }, desktop: { + ...autocomplete.desktop, ...facet.desktop, ...facetsHorizontal.desktop, ...filterSummary.desktop, diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/breadcrumbs.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/breadcrumbs.ts new file mode 100644 index 0000000000..c1436cbbf9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/breadcrumbs.ts @@ -0,0 +1,46 @@ +import { css } from '@emotion/react'; +import type { BreadcrumbsProps } from '../../../../components/Atoms/Breadcrumbs'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Breadcrumbs component +const breadcrumbsStyleScript = (props: BreadcrumbsProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__breadcrumbs__crumbs': { + margin: `0 -${custom.spacing.x1}px`, + '&, li': { + listStyle: 'none', + }, + '&, a': { + color: variables?.colors?.text, + }, + li: { + display: 'block', + padding: `0 ${custom.spacing.x1}px`, + '&:last-of-type': { + color: variables?.colors?.primary, + fontWeight: custom?.fonts?.weight01, + }, + }, + '.ss__breadcrumbs__crumbs__separator': { + '.ss__icon': { + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + }, + }, + }, + }); +}; + +// Breadcrumbs component props +export const breadcrumbs: ThemeComponent<'breadcrumbs', BreadcrumbsProps> = { + default: { + breadcrumbs: { + themeStyleScript: breadcrumbsStyleScript, + separator: false, + separatorIcon: custom.icons.arrowRight, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/button.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/button.ts new file mode 100644 index 0000000000..a0d2116d68 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/button.ts @@ -0,0 +1,88 @@ +import { css } from '@emotion/react'; +import type { ButtonProps } from '../../../../components/Atoms/Button'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the Button component +const buttonStyleScript = (props: ButtonProps) => { + const variables = props?.theme?.variables; + const buttonDisabledSelectors = '&.ss__button--disabled'; + const buttonSelector = `&, &:hover, &:not(.ss__button--disabled):hover, ${buttonDisabledSelectors}`; + const buttonColor = new Color(props?.backgroundColor || variables?.colors?.primary || undefined); + const bottomBorderColor = new Color(props?.backgroundColor || variables?.colors?.secondary || undefined); + const fontColor = buttonColor.isDark() || buttonColor.hex().toLowerCase() == '#d15120' ? Color(custom.colors.white) : Color(custom.colors.black); + + // shared button styles + const disabledStyles = css({ + [buttonDisabledSelectors]: { + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }, + }); + + // default styles + const defaultStyles = css([ + { + boxSizing: 'border-box', + cursor: 'pointer', + display: 'inline-flex', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + position: 'relative', + padding: `0 ${custom.spacing.x4}px`, + color: fontColor.hex(), + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight01, + textAlign: 'center', + textTransform: custom.fonts.transform, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + '&:after': { + content: '""', + display: 'block', + position: 'absolute', + top: '-1px', + bottom: '-1px', + left: '-1px', + right: '-1px', + margin: 'auto', + borderBottom: `3px solid ${bottomBorderColor}`, + borderRadius: `${custom.sizes.radius}px`, + }, + [buttonSelector]: { + border: `1px solid ${buttonColor.hex()}`, + borderRadius: `${custom.sizes.radius}px`, + backgroundColor: buttonColor.hex(), + }, + '.ss__icon': { + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + flex: `0 0 ${custom.sizes.icon12}px`, + }, + '.ss__icon--filters': { + circle: { + fill: buttonColor.hex(), + }, + }, + }, + disabledStyles, + ]); + + return defaultStyles; +}; + +// Button component props +export const button: ThemeComponent<'button', ButtonProps> = { + default: { + button: { + themeStyleScript: buttonStyleScript, + native: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/dropdown.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/dropdown.ts new file mode 100644 index 0000000000..93eed8788c --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/dropdown.ts @@ -0,0 +1,40 @@ +import { css } from '@emotion/react'; +import type { DropdownProps } from '../../../../components/Atoms/Dropdown'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Dropdown component +const dropdownStyleScript = ({ theme }: DropdownProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = theme?.variables; + + return css({ + width: 'auto', + '&:not(.ss__facet__dropdown)': { + '&.ss__dropdown--open': { + '.ss__dropdown__content': { + zIndex: 200, + }, + }, + }, + '&.ss__dropdown--open': { + '.ss__dropdown__content': { + zIndex: 5, + }, + }, + '.ss__dropdown__content': { + minWidth: '1px', + left: 0, + right: 0, + zIndex: -1, + }, + }); +}; + +// Dropdown component props +export const dropdown: ThemeComponent<'dropdown', DropdownProps> = { + default: { + dropdown: { + themeStyleScript: dropdownStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/icon.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/icon.ts new file mode 100644 index 0000000000..851bb434aa --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/icon.ts @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { IconProps } from '../../../../components/Atoms/Icon'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Icon component +const iconStyleScript = (props: IconProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + fill: 'currentColor', + stroke: 'currentColor', + }); +}; + +// Icon component props +export const icon: ThemeComponent<'icon', IconProps> = { + default: { + icon: { + themeStyleScript: iconStyleScript, + size: `${custom.sizes.icon16}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/image.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/image.ts new file mode 100644 index 0000000000..defdd577c6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/image.ts @@ -0,0 +1,46 @@ +import { css } from '@emotion/react'; +import type { ImageProps } from '../../../../components/Atoms/Image'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Image component +const imageStyleScript = (props: ImageProps & { visibility: React.CSSProperties['visibility'] }) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '&.ss__result__image': { + position: 'relative', + lineHeight: 0, + height: 0, + padding: '0 0 100% 0', + overflow: 'hidden', + '&, img': { + display: 'block', + }, + img: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + width: '100%', + height: '100%', + maxWidth: '100%', + maxHeight: '100%', + border: 0, + objectFit: 'contain', + objectPosition: 'center center', + }, + }, + }); +}; + +// Image component props +export const image: ThemeComponent<'image', ImageProps> = { + default: { + image: { + themeStyleScript: imageStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/index.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/index.ts new file mode 100644 index 0000000000..0c9983f793 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/index.ts @@ -0,0 +1,69 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// ATOMS Imports +import { breadcrumbs } from './breadcrumbs'; +import { button } from './button'; +import { dropdown } from './dropdown'; +import { icon } from './icon'; +import { image } from './image'; +import { loadingBar } from './loadingBar'; +import { overlay } from './overlay'; +import { paginationInfo } from './paginationInfo'; +import { price } from './price'; +import { searchHeader } from './searchHeader'; +import { skeleton } from './skeleton'; + +export const atoms: ThemeResponsiveComplete = { + default: { + ...breadcrumbs.default, + ...button.default, + ...dropdown.default, + ...icon.default, + ...image.default, + ...loadingBar.default, + ...overlay.default, + ...price.default, + ...searchHeader.default, + ...skeleton.default, + ...paginationInfo.default, + }, + mobile: { + ...breadcrumbs.mobile, + ...button.mobile, + ...dropdown.mobile, + ...icon.mobile, + ...image.mobile, + ...loadingBar.mobile, + ...overlay.mobile, + ...price.mobile, + ...searchHeader.mobile, + ...skeleton.mobile, + ...paginationInfo.mobile, + }, + tablet: { + ...breadcrumbs.tablet, + ...button.tablet, + ...dropdown.tablet, + ...icon.tablet, + ...image.tablet, + ...loadingBar.tablet, + ...overlay.tablet, + ...price.tablet, + ...searchHeader.tablet, + ...skeleton.tablet, + ...paginationInfo.tablet, + }, + desktop: { + ...breadcrumbs.desktop, + ...button.desktop, + ...dropdown.desktop, + ...icon.desktop, + ...image.desktop, + ...loadingBar.desktop, + ...overlay.desktop, + ...price.desktop, + ...searchHeader.desktop, + ...skeleton.desktop, + ...paginationInfo.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/loadingBar.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/loadingBar.ts new file mode 100644 index 0000000000..750f1917bb --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/loadingBar.ts @@ -0,0 +1,24 @@ +import { css } from '@emotion/react'; +import type { LoadingBarProps } from '../../../../components/Atoms/Loading'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the LoadingBar component +const loadingBarStyleScript = (props: LoadingBarProps) => { + const variables = props?.theme?.variables; + + return css({ + background: variables?.colors?.primary, + '.ss__loading-bar__bar': { + background: variables?.colors?.secondary, + }, + }); +}; + +// LoadingBar component props +export const loadingBar: ThemeComponent<'loadingBar', LoadingBarProps> = { + default: { + loadingBar: { + themeStyleScript: loadingBarStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/overlay.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/overlay.ts new file mode 100644 index 0000000000..fbdce26542 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/overlay.ts @@ -0,0 +1,24 @@ +import { css } from '@emotion/react'; +import type { OverlayProps } from '../../../../components/Atoms/Overlay'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Overlay component +const overlayStyleScript = (props: OverlayProps) => { + const backgroundColor = props?.color || 'rgba(0, 0, 0, 0.80)'; + + return css({ + cursor: 'pointer', + '&, &.ss__overlay--active': { + background: backgroundColor, + }, + }); +}; + +// Overlay component props +export const overlay: ThemeComponent<'overlay', OverlayProps> = { + default: { + overlay: { + themeStyleScript: overlayStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/paginationInfo.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/paginationInfo.ts new file mode 100644 index 0000000000..020e341105 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/paginationInfo.ts @@ -0,0 +1,23 @@ +import { css } from '@emotion/react'; +import type { PaginationInfoProps } from '../../../../components/Atoms/PaginationInfo'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Pagination component +const paginationInfoStyleScript = ({ theme }: PaginationInfoProps) => { + const variables = theme?.variables; + + return css({ + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }); +}; + +// PaginationInfo component props +export const paginationInfo: ThemeComponent<'paginationInfo', PaginationInfoProps> = { + default: { + paginationInfo: { + themeStyleScript: paginationInfoStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/price.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/price.ts new file mode 100644 index 0000000000..32bb151d0b --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/price.ts @@ -0,0 +1,27 @@ +import { css } from '@emotion/react'; +import type { PriceProps } from '../../../../components/Atoms/Price'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Price component +const priceStyleScript = (props: PriceProps) => { + const variables = props?.theme?.variables; + + return css({ + '&, span, &.ss__price, &.ss__price--strike': { + color: variables?.colors?.text, + }, + '& ~ .ss__result__price': { + paddingLeft: `${custom.spacing.x1 / 2}px`, + }, + }); +}; + +// Price component props +export const price: ThemeComponent<'price', PriceProps> = { + default: { + price: { + themeStyleScript: priceStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/searchHeader.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/searchHeader.ts new file mode 100644 index 0000000000..da5228dd20 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/searchHeader.ts @@ -0,0 +1,43 @@ +import { css } from '@emotion/react'; +import type { SearchHeaderProps } from '../../../../components/Atoms/SearchHeader'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the SearchHeader component +const searchHeaderStyleScript = (props: SearchHeaderProps) => { + const variables = props?.theme?.variables; + + return css({ + em: { + fontStyle: 'normal', + }, + '.ss__search-header__title': { + margin: 0, + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + textTransform: custom.fonts.transform, + color: variables?.colors?.secondary, + }, + '.ss__search-header__subtitle': { + margin: `${custom.spacing.x2}px 0 0 0`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: 400, + color: variables?.colors?.text, + a: { + color: variables?.colors?.secondary, + }, + }, + '.ss__search-header__results-query': { + color: variables?.colors?.primary, + }, + }); +}; + +// SearchHeader component props +export const searchHeader: ThemeComponent<'searchHeader', SearchHeaderProps> = { + default: { + searchHeader: { + themeStyleScript: searchHeaderStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/atoms/skeleton.ts b/packages/snap-preact/components/src/themes/everest/components/atoms/skeleton.ts new file mode 100644 index 0000000000..62b8061415 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/atoms/skeleton.ts @@ -0,0 +1,13 @@ +import type { SkeletonProps } from '../../../../components/Atoms/Skeleton'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// Skeleton component props +export const skeleton: ThemeComponent<'skeleton', SkeletonProps> = { + default: { + skeleton: { + backgroundColor: custom.colors.gray02, + animatedColor: custom.colors.gray01, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/index.ts b/packages/snap-preact/components/src/themes/everest/components/index.ts new file mode 100644 index 0000000000..b431ef8ce6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/index.ts @@ -0,0 +1,34 @@ +import { atoms } from './atoms'; +import { molecules } from './molecules'; +import { organisms } from './organisms'; +import { templates } from './templates'; + +import type { ThemeComponentsRestricted } from '../../../providers'; + +export const components: ThemeComponentsRestricted = { + ...atoms.default, + ...molecules.default, + ...organisms.default, + ...templates.default, +}; + +export const mobileComponents: ThemeComponentsRestricted = { + ...atoms.mobile, + ...molecules.mobile, + ...organisms.mobile, + ...templates.mobile, +}; + +export const tabletComponents: ThemeComponentsRestricted = { + ...atoms.tablet, + ...molecules.tablet, + ...organisms.tablet, + ...templates.tablet, +}; + +export const desktopComponents: ThemeComponentsRestricted = { + ...atoms.desktop, + ...molecules.desktop, + ...organisms.desktop, + ...templates.desktop, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/calloutBadge.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/calloutBadge.ts new file mode 100644 index 0000000000..367766c736 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/calloutBadge.ts @@ -0,0 +1,31 @@ +import { css } from '@emotion/react'; +import type { CalloutBadgeProps } from '../../../../components/Molecules/CalloutBadge'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const calloutBadgeStyleScript = () => { + return css({ + gap: `${custom.spacing.x2}px`, + '& > div': { + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + lineHeight: 1, + span: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + '.ss__badge-text': { + padding: `0`, + }, + }); +}; + +// CalloutBadge component props +export const calloutBadge: ThemeComponent<'calloutBadge', CalloutBadgeProps> = { + default: { + calloutBadge: { + themeStyleScript: calloutBadgeStyleScript, + limit: 3, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/carousel.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/carousel.ts new file mode 100644 index 0000000000..c1b097655d --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/carousel.ts @@ -0,0 +1,119 @@ +import { css } from '@emotion/react'; +import type { CarouselProps } from '../../../../components/Molecules/Carousel'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Carousel component +const carouselStyleScript = (props: CarouselProps) => { + const variables = props?.theme?.variables; + + // shared button styles + const disabledStyles = css({ + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }); + + return css({ + position: 'relative', + '.ss__carousel__prev-wrapper--hidden > div, .ss__carousel__next-wrapper--hidden > div': { + ...disabledStyles, + }, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + width: '32px', + height: '32px', + display: 'block', + position: 'absolute', + top: 0, + bottom: '22%', + zIndex: 2, + margin: 'auto', + '& > div': { + display: 'flex', + flexFlow: 'column nowrap', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + width: '100%', + height: '100%', + lineHeight: 1, + backgroundColor: variables?.colors?.primary, + color: custom.colors.white, + }, + '.swiper-button-disabled': { + ...disabledStyles, + }, + }, + '.ss__carousel__prev-wrapper': { + left: 0, + }, + '.ss__carousel__next-wrapper': { + right: 0, + }, + '.swiper-container': { + margin: '0 auto', + '&:has(.swiper-pagination)': { + paddingBottom: `${custom.spacing.x5}px`, + }, + '& > .swiper-wrapper': { + '& > .swiper-slide': { + '& > *, .ss__result': { + padding: 0, + margin: 0, + width: 'auto', + height: '100%', + }, + }, + }, + '& > .swiper-pagination': { + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + '.swiper-pagination-bullet': { + margin: `0 ${custom.spacing.x1 / 2}px`, + width: '12px', + height: '12px', + minWidth: '1px', + flex: '0 1 auto', + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + opacity: 1, + }, + '.swiper-pagination-bullet-active': { + backgroundColor: variables?.colors?.primary, + borderColor: variables?.colors?.primary, + }, + }, + }, + '.swiper-grid-column': { + '& > .swiper-wrapper': { + flexFlow: 'row wrap', + '& > .swiper-slide': { + height: 'auto !important', + marginTop: '0 !important', + marginBottom: `${custom.spacing.x4}px`, + }, + }, + }, + }); +}; + +// Carousel component props +export const carousel: ThemeComponent<'carousel', CarouselProps> = { + default: { + carousel: { + themeStyleScript: carouselStyleScript, + }, + 'carousel icon.prev': { + icon: custom.icons.arrowLeft, + size: `${custom.sizes.icon12}px`, + }, + 'carousel icon.next': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/checkbox.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/checkbox.ts new file mode 100644 index 0000000000..c195b8fdfc --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/checkbox.ts @@ -0,0 +1,81 @@ +import { css } from '@emotion/react'; +import type { CheckboxProps } from '../../../../components/Molecules/Checkbox'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Checkbox component +const checkboxStyleScript = (props: CheckboxProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + // shared checkbox styles + const sharedStyles = css({ + position: 'relative', + top: '-1px', + }); + const sharedDefaultStyles = css({ + border: `1px solid ${custom.colors.gray02}`, + '&, *': { + boxSizing: 'border-box', + }, + '.ss__icon': { + width: '8px', + height: '8px', + }, + '&.ss__checkbox--active': { + borderColor: darkGray, + '.ss__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }); + const disabledStyles = css({ + '&.ss__checkbox--disabled': { + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }, + }); + + // default checkbox styles + const defaultStyles = css([ + sharedStyles, + sharedDefaultStyles, + { + backgroundColor: custom.colors.gray01, + }, + disabledStyles, + ]); + + // native checkbox styles + const nativeStyles = css([ + sharedStyles, + { + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + border: `1px solid ${custom.colors.gray02}`, + cursor: 'pointer', + }, + disabledStyles, + ]); + + // return checkbox styles + if (props?.native) { + return nativeStyles; + } else { + return defaultStyles; + } +}; + +// Checkbox component props +export const checkbox: ThemeComponent<'checkbox', CheckboxProps> = { + default: { + checkbox: { + themeStyleScript: checkboxStyleScript, + icon: custom.icons.check, + size: `${custom.sizes.icon16}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/errorHandler.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/errorHandler.ts new file mode 100644 index 0000000000..c66af2df3c --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/errorHandler.ts @@ -0,0 +1,40 @@ +import { css } from '@emotion/react'; +import type { ErrorHandlerProps } from '../../../../components/Molecules/ErrorHandler'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the ErrorHandler component +const errorHandlerStyleScript = (props: ErrorHandlerProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__error-handler__message': { + display: 'block', + flex: `1 1 0%`, + color: variables?.colors?.text, + '.ss__icon': { + position: 'relative', + top: '2px', + }, + }, + '.ss__error-handler__button': { + gap: 0, + flex: `0 1 auto`, + padding: `0 ${custom.spacing.x1}px`, + height: '25px', + lineHeight: '25px', + }, + }); +}; + +// ErrorHandler component props +export const errorHandler: ThemeComponent<'errorHandler', ErrorHandlerProps> = { + default: { + errorHandler: { + themeStyleScript: errorHandlerStyleScript, + }, + 'errorHandler icon': { + size: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/facetGridOptions.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/facetGridOptions.ts new file mode 100644 index 0000000000..ab0e828ca3 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/facetGridOptions.ts @@ -0,0 +1,76 @@ +import { css } from '@emotion/react'; +import type { FacetGridOptionsProps } from '../../../../components/Molecules/FacetGridOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the FacetGridOptions component +const facetGridOptionsStyleScript = (props: FacetGridOptionsProps) => { + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const fontColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#d15120' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + const gridSize = props?.gridSize ? props.gridSize : '52px'; + + return css({ + gridTemplateColumns: `repeat(auto-fill, minmax(${gridSize}, 1fr))`, + gap: props?.gapSize ? props.gapSize : custom.spacing.x1, + alignItems: 'center', + '.ss__facet-grid-options__option': { + position: 'relative', + height: '100%', + aspectRatio: 1, + border: 0, + color: variables?.colors?.text, + '&, &:after, .ss__facet-grid-options__option__value': { + boxSizing: 'border-box', + }, + '&:after, .ss__facet-grid-options__option__value': { + display: 'block', + }, + '&:after': { + content: '""', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1, + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + }, + '.ss__facet-grid-options__option__value': { + position: 'relative', + zIndex: 2, + maxWidth: `calc(100% - ${custom.spacing.x2}px)`, + maxHeight: `calc(100% - ${custom.spacing.x2}px)`, + overflow: 'hidden', + '&, &.ss__facet-grid-options__option__value--smaller': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1, + }, + }, + }, + '.ss__facet-grid-options__option.ss__facet-grid-options__option--filtered': { + fontWeight: custom.fonts.weight01, + color: fontColor.hex(), + '&:after': { + backgroundColor: activeColor.hex(), + borderColor: activeColor.hex(), + }, + }, + }); +}; + +// FacetGridOptions component props +export const facetGridOptions: ThemeComponent<'facetGridOptions', FacetGridOptionsProps> = { + default: { + facetGridOptions: { + themeStyleScript: facetGridOptionsStyleScript, + gridSize: '52px', + gapSize: `${custom.spacing.x1}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/facetHierarchyOptions.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/facetHierarchyOptions.ts new file mode 100644 index 0000000000..13419c29d4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/facetHierarchyOptions.ts @@ -0,0 +1,64 @@ +import { css } from '@emotion/react'; +import type { FacetHierarchyOptionsProps } from '../../../../components/Molecules/FacetHierarchyOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FacetHierarchyOptions component +const facetHierarchyOptionsStyleScript = (props: FacetHierarchyOptionsProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + + return css({ + '.ss__facet-hierarchy-options__option': { + display: 'block', + margin: `0 0 ${custom.spacing.x1}px 0`, + padding: 0, + color: variables?.colors?.text, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__facet-hierarchy-options__option__value': { + margin: 0, + '.ss__facet-hierarchy-options__option__value__count': { + position: 'relative', + top: '-1px', + margin: 0, + padding: `0 ${custom.spacing.x1}px`, + fontSize: custom.utils.convertPxToEm(10), + color: lightGray, + }, + }, + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--return': { + '&:before': { + display: 'none', + }, + '.ss__icon': { + position: 'relative', + top: '1px', + margin: `0 ${custom.spacing.x1}px 0 0`, + padding: 0, + }, + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--filtered': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '& ~ .ss__facet-hierarchy-options__option:not(.ss__facet-hierarchy-options__option--filtered)': { + paddingLeft: `${custom.spacing.x6}px`, + }, + }, + }); +}; + +// FacetHierarchyOptions component props +export const facetHierarchyOptions: ThemeComponent<'facetHierarchyOptions', FacetHierarchyOptionsProps> = { + default: { + facetHierarchyOptions: { + themeStyleScript: facetHierarchyOptionsStyleScript, + returnIcon: custom.icons.arrowLeft, + }, + 'facetHierarchyOptions icon': { + size: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/facetListOptions.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/facetListOptions.ts new file mode 100644 index 0000000000..e42c39a96b --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/facetListOptions.ts @@ -0,0 +1,54 @@ +import { css } from '@emotion/react'; +import type { FacetListOptionsProps } from '../../../../components/Molecules/FacetListOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FacetListOptions component +const facetListOptionsStyleScript = (props: FacetListOptionsProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const checkboxSpacing = custom.sizes.icon16 + custom.spacing.x2; + + return css({ + '.ss__facet-list-options__option': { + display: 'block', + position: 'relative', + margin: `0 0 ${custom.spacing.x1}px 0`, + color: variables?.colors?.text, + padding: props?.hideCheckbox ? `` : `0 0 0 ${checkboxSpacing}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__checkbox, .ss__radio': { + position: 'absolute', + top: '1.5px', + left: 0, + }, + '.ss__facet-list-options__option__value': { + margin: 0, + '.ss__facet-list-options__option__value__count': { + position: 'relative', + top: '-1px', + margin: 0, + padding: `0 ${custom.spacing.x1}px`, + fontSize: custom.utils.convertPxToEm(10), + color: lightGray, + }, + }, + }, + '.ss__facet-list-options__option.ss__facet-list-options__option--filtered': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }); +}; + +// FacetListOptions component props +export const facetListOptions: ThemeComponent<'facetListOptions', FacetListOptionsProps> = { + default: { + facetListOptions: { + themeStyleScript: facetListOptionsStyleScript, + respectSingleSelect: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/facetPaletteOptions.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/facetPaletteOptions.ts new file mode 100644 index 0000000000..405114def8 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/facetPaletteOptions.ts @@ -0,0 +1,211 @@ +import { css } from '@emotion/react'; +import type { FacetPaletteOptionsProps } from '../../../../components/Molecules/FacetPaletteOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FacetPaletteOptions component +const facetPaletteStyleScript = (props: FacetPaletteOptionsProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const hasCheckbox = !props?.hideCheckbox ? true : false; + + // set details for radius + const radius = 0; + const radiusUnit = 'px'; + const paletteRadius = radius ? `${radius}${radiusUnit}` : `0`; + + // determine inner border width + let innerBorder = 5; + if (props?.layout == 'list') { + innerBorder = hasCheckbox ? 2 : 3; + } + + // shared palette styles + const sharedStyles = css({ + '.ss__facet-palette-options__option': { + display: 'block', + color: variables?.colors?.text, + '&, &.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper': { + border: 0, + borderRadius: 0, + padding: 0, + }, + }, + '&.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper .ss__facet-palette-options__option__palette': { + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + }, + }, + '.ss__facet-palette-options__option__wrapper': { + overflow: 'hidden', + '.ss__facet-palette-options__option__palette': { + border: 0, + padding: 0, + '&, &:before, &:after': { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + borderRadius: paletteRadius, + boxSizing: 'border-box', + }, + '&:before, &:after': { + content: '""', + display: 'block', + }, + '&:before': { + border: `${innerBorder}px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + }, + }, + '.ss__facet-palette-options__option__value__count': { + position: 'relative', + top: props?.layout == 'list' ? '-1px' : '', + padding: props?.layout == 'list' ? `0 ${custom.spacing.x1}px` : ``, + fontSize: custom.utils.convertPxToEm(10), + color: lightGray, + }, + }, + }); + + // grid palette styles + const gridStyles = css([ + sharedStyles, + { + gridTemplateColumns: `repeat(auto-fill, minmax(${props?.gridSize ? props.gridSize : '52px'}, 1fr))`, + gap: props?.gapSize ? props.gapSize : custom.spacing.x1, + alignItems: 'center', + '.ss__facet-palette-options__option': { + textAlign: 'center', + '&, &.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper': { + position: 'relative', + height: 0, + padding: '0 0 100% 0', + }, + }, + '.ss__checkbox, .ss__radio': { + display: 'none', + }, + '.ss__facet-palette-options__option__value, .ss__facet-palette-options__option__value__count': { + display: 'block', + lineHeight: '0.85rem', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + '.ss__facet-palette-options__option__value': { + fontSize: custom.utils.convertPxToEm(12), + overflow: 'hidden', + margin: `${custom.spacing.x1}px 0 0 0`, + }, + '.ss__facet-palette-options__option__value__count': { + margin: `${custom.spacing.x1 / 2}px 0 0 0`, + }, + }, + }, + ]); + + // list variables + const listSize = hasCheckbox ? 16 : 22; + const listCheckboxSize = 16; + const listPadding = hasCheckbox ? custom.spacing.x4 + listSize + listCheckboxSize : custom.spacing.x2 + listSize; + + // list palette styles + const listStyles = css([ + sharedStyles, + { + '&.ss__facet-palette-options--list': { + display: 'block', + }, + '.ss__facet-palette-options__option': { + position: 'relative', + padding: `${hasCheckbox ? 0 : '2px'} 0 0 ${listPadding}px`, + margin: `0 0 ${custom.spacing.x1}px 0`, + minHeight: hasCheckbox ? '' : `${listSize + 2}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__checkbox, .ss__radio, .ss__facet-palette-options__option__wrapper': { + position: 'absolute', + top: `${hasCheckbox ? 2 : 0.5}px`, + }, + '.ss__checkbox, .ss__radio': { + left: 0, + }, + '.ss__facet-palette-options__option__wrapper': { + left: hasCheckbox ? `${listCheckboxSize + custom.spacing.x2}px` : 0, + width: `${listSize}px`, + height: `${listSize}px`, + lineHeight: `${listSize}px`, + }, + '.ss__facet-palette-options__option__value, .ss__facet-palette-options__option__value__count': { + display: 'inline', + overflow: 'visible', + textOverflow: 'unset', + textAlign: 'left', + whiteSpace: 'unset', + }, + '.ss__facet-palette-options__option__value__count': { + margin: 0, + }, + }, + }, + ]); + + return props?.layout == 'list' ? listStyles : gridStyles; +}; + +// FacetPaletteOptions component props +export const facetPaletteOptions: ThemeComponent<'facetPaletteOptions', FacetPaletteOptionsProps> = { + default: { + facetPaletteOptions: { + themeStyleScript: facetPaletteStyleScript, + hideIcon: true, + gridSize: '52px', + gapSize: `${custom.spacing.x1}px`, + colorMapping: { + brown: { + background: custom.colors.brown, + }, + multi: { + background: custom.colors.rainbow, + }, + 'multi-color': { + background: custom.colors.rainbow, + }, + purple: { + background: custom.colors.purple, + }, + rainbow: { + background: custom.colors.rainbow, + }, + }, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/facetSlider.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/facetSlider.ts new file mode 100644 index 0000000000..079aead88e --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/facetSlider.ts @@ -0,0 +1,200 @@ +import { css } from '@emotion/react'; +import type { FacetSliderProps } from '../../../../components/Molecules/FacetSlider'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the FacetSlider component +const facetSliderStyleScript = (props: FacetSliderProps) => { + // slider options + const slider = { + handles: 20, // handle size + values: 14, // values size + bar: 6, // bar size + ticks: 17, // size of ticks + valuesPosition: 'top', // position of slider values (top or bottom) + valuesAlign: 'sides', // alignment of slider values (sides or center) + }; + + const variables = props?.theme?.variables; + const fontColor = props?.valueTextColor || variables?.colors?.text; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + const valuesTop = slider.valuesPosition == 'top' ? true : false; + const valuesSides = slider.valuesAlign == 'sides' ? true : false; + const hasTicks = props?.showTicks ? true : false; + const hasStickyHandles = props?.stickyHandleLabel ? true : false; + const handleColor = new Color(props?.handleColor || variables?.colors?.primary || undefined); + const handleInnerColor = + handleColor.isDark() || handleColor.hex().toLowerCase() == '#d15120' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + + // values font styles + const valuesStyles = css({ + fontSize: custom.utils.convertPxToEm(slider.values), + lineHeight: `${slider.values}px`, + color: fontColor, + }); + + // shared slider styles + const sharedStyles = css({ + '&, *': { + boxSizing: 'border-box', + }, + '&, .ss__facet-slider__slider': { + margin: 'auto', + }, + '.ss__facet-slider__slider button, .ss__facet-slider__labels label': { + margin: 0, + padding: 0, + '&:focus': { + outline: 0, + }, + }, + '.ss__facet-slider__slider': { + display: 'block', + top: 0, + width: '100%', + height: `${slider.bar}px`, + '.ss__facet-slider__segment, .ss__facet-slider__rail, .ss__facet-slider__handles': { + height: '100%', + }, + '.ss__facet-slider__tick': { + '&:before, .ss__facet-slider__tick__label': { + transform: 'translate(-50%, 0)', + }, + '&:before': { + top: `${slider.ticks / 2}px`, + backgroundColor: darkGray, + }, + '.ss__facet-slider__tick__label': { + top: `${slider.ticks}px`, + color: props?.tickTextColor || variables?.colors?.text, + lineHeight: 1, + }, + }, + '.ss__facet-slider__segment': { + backgroundColor: props?.trackColor || custom.colors.gray01, + border: `1px solid ${props?.trackColor || custom.colors.gray02}`, + borderRadius: `${slider.bar}px`, + }, + '.ss__facet-slider__rail': { + backgroundColor: props?.railColor || variables?.colors?.secondary, + border: `1px solid ${props?.railColor || variables?.colors?.secondary}`, + }, + '.ss__facet-slider__handles': { + position: 'relative', + margin: `0 ${slider.handles / 2 - 2}px`, + button: { + '.ss__facet-slider__handle': { + transform: 'none', + width: `${slider.handles}px`, + height: `${slider.handles}px`, + lineHeight: `${slider.handles}px`, + backgroundColor: handleColor.hex(), + border: `1px solid ${handleColor.hex()}`, + '&:after': { + width: `${slider.handles / 4}px`, + height: `${slider.handles / 4}px`, + backgroundColor: handleInnerColor.hex(), + border: `1px solid ${handleInnerColor.hex()}`, + }, + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + backgroundColor: 'transparent', + '&': { + ...valuesStyles, + }, + }, + }, + }, + }, + }, + '.ss__facet-slider__labels': { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + justifyContent: valuesSides ? '' : 'center', + '.ss__facet-slider__label': { + '&': { + ...valuesStyles, + }, + '&:after': { + display: valuesSides ? 'none' : '', + padding: `0 ${custom.spacing.x1}px`, + }, + '& ~ .ss__facet-slider__label': { + marginLeft: valuesSides ? 'auto' : '', + }, + }, + }, + }); + + // spacing and size calculations + const handlesSizeHalf = (slider.handles - slider.bar) / 2; + const handlesSpacing = slider.handles + custom.spacing.x2; + const ticksSpacing = slider.ticks + custom.spacing.x1; + const stickySpacing = slider.values + custom.spacing.x2; + const handlesPlusSticky = handlesSizeHalf + stickySpacing; + const ticksPlusSticky = ticksSpacing + stickySpacing; + + // spacing styles for different configurations + // note: default for facet slider is no ticks, no stick handles, values bottom + let spacingStyles = css({}); + + if (hasTicks && hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${valuesTop ? handlesPlusSticky : handlesSizeHalf}px auto ${valuesTop ? ticksSpacing : ticksPlusSticky}px auto`, + '.ss__facet-slider__handles button .ss__facet-slider__handle': { + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + top: valuesTop ? `auto` : `${handlesSizeHalf + ticksPlusSticky - slider.bar}px`, + bottom: valuesTop ? `${handlesSpacing}px` : ``, + }, + }, + }, + }); + } else if (hasTicks && !hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${handlesSizeHalf}px auto ${ticksSpacing}px auto`, + }, + '.ss__facet-slider__labels': { + order: valuesTop ? -1 : '', + margin: `${valuesTop ? 0 : custom.spacing.x2}px 0 ${valuesTop ? custom.spacing.x2 : 0}px 0`, + }, + }); + } else if (!hasTicks && hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${valuesTop ? handlesPlusSticky : handlesSizeHalf}px auto ${valuesTop ? handlesSizeHalf : handlesPlusSticky}px auto`, + '.ss__facet-slider__handles button .ss__facet-slider__handle': { + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + top: valuesTop ? 'auto' : `${handlesSpacing}px`, + bottom: valuesTop ? `${handlesSpacing}px` : ``, + }, + }, + }, + }); + } else { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${handlesSizeHalf}px auto`, + }, + '.ss__facet-slider__labels': { + order: valuesTop ? -1 : '', + margin: `${valuesTop ? 0 : custom.spacing.x2}px 0 ${valuesTop ? custom.spacing.x2 : 0}px 0`, + }, + }); + } + + return css([sharedStyles, spacingStyles]); +}; + +// FacetSlider component props +export const facetSlider: ThemeComponent<'facetSlider', FacetSliderProps> = { + default: { + facetSlider: { + themeStyleScript: facetSliderStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/filter.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/filter.ts new file mode 100644 index 0000000000..15aede8a43 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/filter.ts @@ -0,0 +1,44 @@ +import { css } from '@emotion/react'; +import type { FilterProps } from '../../../../components/Molecules/Filter'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Filter component +const filterStyleScript = (props: FilterProps) => { + const variables = props?.theme?.variables; + + return css({ + display: 'block', + padding: 0, + '.ss__filter__button': { + position: 'relative', + height: 'auto', + lineHeight: 1.5, + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + fontWeight: 'normal', + color: variables?.colors?.text, + '&, &:hover, &:not(.ss__button--disabled):hover, &.ss__button--disabled': { + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + }, + '.ss__button__content': { + '.ss__filter__label': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + }); +}; + +// Filter component props +export const filter: ThemeComponent<'filter', FilterProps> = { + default: { + filter: { + themeStyleScript: filterStyleScript, + icon: custom.icons.close, + }, + 'filter icon': { + size: `${custom.sizes.icon10}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/grid.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/grid.ts new file mode 100644 index 0000000000..9344053206 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/grid.ts @@ -0,0 +1,188 @@ +import { css } from '@emotion/react'; +import type { GridProps } from '../../../../components/Molecules/Grid'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// grid size +const gridSize = 42; + +// CSS in JS style script for the Grid component +const gridStyleScript = (props: Partial) => { + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const fontColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#d15120' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + return css({ + '.ss__grid__title': { + margin: `0 0 ${custom.spacing.x1}px 0`, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + lineHeight: 1, + }, + '.ss__grid__options': { + display: 'flex', + flexFlow: 'row wrap', + gap: props?.gapSize ? props.gapSize : custom.spacing.x1, + alignItems: 'center', + '&:before, &:after': { + display: 'none', + }, + '.ss__grid__option': { + flex: '0 1 auto', + minWidth: '1px', + '&, &.ss__grid__option--selected': { + border: 0, + }, + '.ss__grid__option__inner .ss__grid__option__label, .ss__grid__show-more-wrapper': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1, + }, + }, + '.ss__grid__option:not(.ss__grid__show-more-wrapper)': { + position: 'relative', + width: `${gridSize}px`, + maxHeight: `${gridSize}px`, + aspectRatio: 1, + color: variables?.colors?.text, + overflow: 'hidden', + '&, &:after, *': { + boxSizing: 'border-box', + }, + '&:before': { + display: 'none', + }, + '&:after': { + content: '""', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1, + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&.ss__grid__option--dark, &:has(.ss__grid__option__inner--grey)': { + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + color: fontColor.hex(), + }, + }, + }, + '&.ss__grid__option--selected': { + '&:after': { + opacity: 0.3, + }, + '&:has(.ss__grid__option__inner:not([style]))': { + backgroundColor: activeColor.hex(), + '&:after': { + borderColor: activeColor.hex(), + opacity: 1, + }, + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + color: fontColor.hex(), + }, + }, + }, + '&:has(.ss__grid__option__inner .ss__image)': { + backgroundColor: 'transparent', + '&:after': { + borderColor: custom.colors.black, + opacity: 0.3, + }, + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + color: variables?.colors?.text, + }, + }, + }, + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + '&.ss__grid__option--disabled, &.ss__grid__option--unavailable': { + opacity: 1, + cursor: 'not-allowed', + pointerEvents: 'none', + '.ss__grid__option__inner:after': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 3, + margin: 'auto', + backgroundColor: darkGray.replace('#', ''), + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center center', + backgroundImage: `url("data:image/svg+xml,%3Csvg style=%27transform: rotate%28-45deg%29%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 56 56%27 preserveAspectRatio=%27xMinYMid%27%3E%3Cpath fill=%27%23${darkGray.replace( + '#', + '' + )}%27 d=%27M0 23.297h56v9.406h-56v-9.406z%27 /%3E%3C/svg%3E")`, + }, + }, + '.ss__grid__option__inner': { + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + '.ss__grid__option__label': { + display: 'block', + position: 'absolute', + zIndex: 2, + maxWidth: `calc(100% - ${custom.spacing.x2}px)`, + maxHeight: `calc(100% - ${custom.spacing.x2}px)`, + overflow: 'hidden', + }, + }, + }, + '.ss__grid__show-more-wrapper': { + maxHeight: 'none', + }, + }, + '.ss__grid__show-more-wrapper': { + '&:not(.ss__grid__option)': { + margin: `${custom.spacing.x2}px 0 0 0`, + }, + '&, .ss__grid__show-more': { + cursor: 'pointer', + }, + '.ss__grid__show-more': { + fontSize: custom.utils.convertPxToEm(12), + fontWeight: custom.fonts.weight01, + lineHeight: 1, + color: variables?.colors?.primary, + }, + }, + }); +}; + +// Grid component props +export const grid: ThemeComponent<'grid', GridProps> = { + default: { + grid: { + themeStyleScript: gridStyleScript, + gapSize: `${custom.spacing.x1}px`, + hideLabels: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/index.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/index.ts new file mode 100644 index 0000000000..870baa5828 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/index.ts @@ -0,0 +1,144 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// MOLECULES Imports +import { calloutBadge } from './calloutBadge'; +import { carousel } from './carousel'; +import { checkbox } from './checkbox'; +import { errorHandler } from './errorHandler'; +import { facetGridOptions } from './facetGridOptions'; +import { facetHierarchyOptions } from './facetHierarchyOptions'; +import { facetListOptions } from './facetListOptions'; +import { facetPaletteOptions } from './facetPaletteOptions'; +import { facetSlider } from './facetSlider'; +import { filter } from './filter'; +import { grid } from './grid'; +import { layoutSelector } from './layoutSelector'; +import { list } from './list'; +import { loadMore } from './loadMore'; +import { overlayBadge } from './overlayBadge'; +import { pagination } from './pagination'; +import { radio } from './radio'; +import { radioList } from './radioList'; +import { result } from './result'; +import { searchInput } from './searchInput'; +import { select } from './select'; +import { slideout } from './slideout'; +import { rating } from './rating'; +import { swatches } from './swatches'; +import { variantSelection } from './variantSelection'; +import { terms } from './terms'; + +export const molecules: ThemeResponsiveComplete = { + default: { + ...carousel.default, + ...checkbox.default, + ...errorHandler.default, + ...facetGridOptions.default, + ...facetHierarchyOptions.default, + ...facetListOptions.default, + ...facetPaletteOptions.default, + ...facetSlider.default, + ...filter.default, + ...grid.default, + ...layoutSelector.default, + ...list.default, + ...loadMore.default, + ...overlayBadge.default, + ...pagination.default, + ...radio.default, + ...radioList.default, + ...result.default, + ...searchInput.default, + ...select.default, + ...slideout.default, + ...rating.default, + ...swatches.default, + ...variantSelection.default, + ...terms.default, + ...calloutBadge.default, + }, + mobile: { + ...carousel.mobile, + ...checkbox.mobile, + ...errorHandler.mobile, + ...facetGridOptions.mobile, + ...facetHierarchyOptions.mobile, + ...facetListOptions.mobile, + ...facetPaletteOptions.mobile, + ...facetSlider.mobile, + ...filter.mobile, + ...grid.mobile, + ...layoutSelector.mobile, + ...list.mobile, + ...loadMore.mobile, + ...overlayBadge.mobile, + ...pagination.mobile, + ...radio.mobile, + ...radioList.mobile, + ...result.mobile, + ...searchInput.mobile, + ...select.mobile, + ...slideout.mobile, + ...rating.mobile, + ...swatches.mobile, + ...variantSelection.mobile, + ...terms.mobile, + ...calloutBadge.mobile, + }, + tablet: { + ...carousel.tablet, + ...checkbox.tablet, + ...errorHandler.tablet, + ...facetGridOptions.tablet, + ...facetHierarchyOptions.tablet, + ...facetListOptions.tablet, + ...facetPaletteOptions.tablet, + ...facetSlider.tablet, + ...filter.tablet, + ...grid.tablet, + ...layoutSelector.tablet, + ...list.tablet, + ...loadMore.tablet, + ...overlayBadge.tablet, + ...pagination.tablet, + ...radio.tablet, + ...radioList.tablet, + ...result.tablet, + ...searchInput.tablet, + ...select.tablet, + ...slideout.tablet, + ...rating.tablet, + ...swatches.tablet, + ...variantSelection.tablet, + ...terms.tablet, + ...calloutBadge.tablet, + }, + desktop: { + ...carousel.desktop, + ...checkbox.desktop, + ...errorHandler.desktop, + ...facetGridOptions.desktop, + ...facetHierarchyOptions.desktop, + ...facetListOptions.desktop, + ...facetPaletteOptions.desktop, + ...facetSlider.desktop, + ...filter.desktop, + ...grid.desktop, + ...layoutSelector.desktop, + ...list.desktop, + ...loadMore.desktop, + ...overlayBadge.desktop, + ...pagination.desktop, + ...radio.desktop, + ...radioList.desktop, + ...result.desktop, + ...searchInput.desktop, + ...select.desktop, + ...slideout.desktop, + ...rating.desktop, + ...swatches.desktop, + ...variantSelection.desktop, + ...terms.desktop, + ...calloutBadge.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/layoutSelector.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/layoutSelector.ts new file mode 100644 index 0000000000..36639c34d8 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/layoutSelector.ts @@ -0,0 +1,76 @@ +import { css } from '@emotion/react'; +import type { LayoutSelectorProps } from '../../../../components/Molecules/LayoutSelector'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the LayoutSelector component +const layoutSelectorStyleScript = (props: LayoutSelectorProps) => { + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const activeIconColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#d15120' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + + // dropdown styles + const dropdownStyles = css({ + '.ss__dropdown': { + '.ss__dropdown__button .ss__button__content': { + gap: `${custom.spacing.x2}px`, + }, + }, + }); + + // list styles + const listStyles = css({ + '.ss__list__options': { + display: 'flex', + '.ss__list__option': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + padding: `0 ${custom.spacing.x2}px`, + margin: 0, + }, + '.ss__list__option--selected': { + borderColor: activeColor.hex(), + backgroundColor: activeColor.hex(), + color: activeIconColor.hex(), + '&, *': { + cursor: 'text', + }, + }, + }, + }); + + if (props?.type == 'dropdown') { + return dropdownStyles; + } else if (props?.type == 'list') { + return listStyles; + } else { + return dropdownStyles; + } +}; + +// LayoutSelector component props +export const layoutSelector: ThemeComponent<'layoutSelector', LayoutSelectorProps> = { + default: { + layoutSelector: { + themeStyleScript: layoutSelectorStyleScript, + type: 'list', + }, + 'layoutSelector select': { + hideSelection: false, + separator: '', + }, + 'layoutSelector list': { + hideTitleText: true, + hideOptionLabels: true, + }, + 'layoutSelector radioList': { + hideTitleText: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/list.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/list.ts new file mode 100644 index 0000000000..1ea3e14846 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/list.ts @@ -0,0 +1,45 @@ +import { css } from '@emotion/react'; +import type { ListProps } from '../../../../components/Molecules/List'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the List component +const listStyleScript = (props: ListProps) => { + const variables = props?.theme?.variables; + + return css({ + '&, .ss__list__options': { + display: 'block', + }, + '.ss__list__title, .ss__list__options .ss__list__option': { + margin: `0 0 ${custom.spacing.x1}px 0`, + }, + '.ss__list__title': { + display: 'block', + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + lineHeight: 1, + }, + '.ss__list__options': { + '.ss__list__option': { + gap: `${custom.spacing.x2}px`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__list__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }, + }); +}; + +// List component props +export const list: ThemeComponent<'list', ListProps> = { + default: { + list: { + themeStyleScript: listStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/loadMore.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/loadMore.ts new file mode 100644 index 0000000000..3da120d933 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/loadMore.ts @@ -0,0 +1,53 @@ +import { css } from '@emotion/react'; +import type { LoadMoreProps } from '../../../../components/Molecules/LoadMore'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the LoadMore component +const loadMoreStyleScript = (props: LoadMoreProps) => { + const variables = props?.theme?.variables; + const indicatorColor = new Color(props?.backgroundColor || custom.colors.gray01 || undefined); + const indicatorBorderColor = new Color(props?.backgroundColor || custom.colors.gray02 || undefined); + const barColor = new Color(props?.color || variables?.colors?.primary || undefined); + + return css({ + '&.ss__load-more': { + '&, .ss__load-more__progress': { + gap: `${custom.spacing.x2}px`, + }, + '& > .ss__load-more__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + '.ss__button': { + '.ss__button__content': { + display: 'flex', + alignItems: 'center', + }, + }, + '.ss__load-more__progress': { + '.ss__load-more__progress__indicator': { + backgroundColor: indicatorColor.hex(), + border: `1px solid ${indicatorBorderColor}`, + '.ss__load-more__progress__indicator__bar': { + backgroundColor: barColor.hex(), + margin: '-1px', + }, + }, + '.ss__load-more__progress__text': { + color: variables?.colors?.text, + }, + }, + }, + }); +}; + +// LoadMore component props +export const loadMore: ThemeComponent<'loadMore', LoadMoreProps> = { + default: { + loadMore: { + themeStyleScript: loadMoreStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/overlayBadge.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/overlayBadge.ts new file mode 100644 index 0000000000..4f5fce0659 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/overlayBadge.ts @@ -0,0 +1,34 @@ +import { css } from '@emotion/react'; +import type { OverlayBadgeProps } from '../../../../components/Molecules/OverlayBadge'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const overlayBadgeStyleScript = () => { + return css({ + '.ss__overlay-badge__grid-wrapper': { + gap: `${custom.spacing.x1}px`, + bottom: 'auto', + '.ss__overlay-badge__grid-wrapper__slot': { + gap: 0, + '& > div': { + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + lineHeight: 1, + span: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }); +}; + +// OverlayBadge component props +export const overlayBadge: ThemeComponent<'overlayBadge', OverlayBadgeProps> = { + default: { + overlayBadge: { + themeStyleScript: overlayBadgeStyleScript, + limit: 3, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/pagination.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/pagination.ts new file mode 100644 index 0000000000..855be34e36 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/pagination.ts @@ -0,0 +1,73 @@ +import { css } from '@emotion/react'; +import type { PaginationProps } from '../../../../components/Molecules/Pagination'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Pagination component +const paginationStyleScript = (props: PaginationProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + nav: { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + justifyContent: 'center', + lineHeight: 1, + '.ss__pagination__page, span': { + padding: `0 ${custom.spacing.x1}px`, + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.text, + }, + '.ss__pagination__page': { + minWidth: '1px', + minHeight: '1px', + }, + '.ss__pagination__page--active': { + color: variables?.colors?.primary, + }, + '.ss__pagination__page--previous, .ss__pagination__page--next': { + lineHeight: `${custom.sizes.icon12}px`, + '.ss__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + nav: { + '.ss__pagination__page, span': { + padding: `0 ${custom.spacing.x2}px`, + fontSize: custom.utils.convertPxToEm(16), + }, + '.ss__pagination__page--previous, .ss__pagination__page--next': { + lineHeight: `${custom.sizes.icon14}px`, + }, + }, + }, + }); +}; + +// Pagination component props +export const pagination: ThemeComponent<'pagination', PaginationProps> = { + default: { + pagination: { + themeStyleScript: paginationStyleScript, + }, + 'pagination icon': { + size: `${custom.sizes.icon12}px`, + }, + 'pagination icon.prev': { + icon: custom.icons.arrowLeft, + }, + 'pagination icon.next': { + icon: custom.icons.arrowRight, + }, + }, + mobile: { + 'pagination icon': { + size: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/radio.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/radio.ts new file mode 100644 index 0000000000..46a2b51477 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/radio.ts @@ -0,0 +1,81 @@ +import { css } from '@emotion/react'; +import type { RadioProps } from '../../../../components/Molecules/Radio'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Radio component +const radioStyleScript = (props: RadioProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + // shared radio styles + const sharedDefaultStyles = css({ + border: `1px solid ${custom.colors.gray02}`, + '&, & .ss__icon': { + borderRadius: '50%', + }, + '.ss__icon': { + display: 'none', + }, + '&.ss__radio--active': { + borderColor: darkGray, + '.ss__icon': { + display: 'block', + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }); + const disabledStyles = css({ + '&.ss__radio--disabled': { + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }, + }); + + // default radio styles + const defaultStyles = css([ + sharedDefaultStyles, + { + backgroundColor: custom.colors.gray01, + }, + disabledStyles, + ]); + + // native radio styles + const nativeStyles = css([ + { + lineHeight: 0, + '.ss__radio__input': { + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + border: `1px solid ${custom.colors.gray02}`, + cursor: 'pointer', + }, + }, + disabledStyles, + ]); + + // return radio styles + if (props?.native) { + return nativeStyles; + } else { + return defaultStyles; + } +}; + +// Radio component props +export const radio: ThemeComponent<'radio', RadioProps> = { + default: { + radio: { + themeStyleScript: radioStyleScript, + size: `${custom.sizes.icon14}px`, + }, + 'radio icon': { + icon: 'square', + size: `${custom.sizes.icon10 - 2}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/radioList.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/radioList.ts new file mode 100644 index 0000000000..0aa0632335 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/radioList.ts @@ -0,0 +1,47 @@ +import { css } from '@emotion/react'; +import type { RadioListProps } from '../../../../components/Molecules/RadioList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RadioList component +const radioListStyleScript = (props: RadioListProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__radio-list__title, .ss__radio-list__options-wrapper .ss__radio-list__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + }, + '.ss__radio-list__title': { + display: 'block', + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + lineHeight: 1, + }, + '.ss__radio-list__options-wrapper': { + '.ss__radio-list__option': { + gap: `${custom.spacing.x2}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__radio-list__option__icon, .ss__radio-list__option__label': { + padding: 0, + }, + }, + '.ss__radio-list__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }, + }); +}; + +// RadioList component props +export const radioList: ThemeComponent<'radioList', RadioListProps> = { + default: { + radioList: { + themeStyleScript: radioListStyleScript, + hideOptionLabels: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/rating.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/rating.ts new file mode 100644 index 0000000000..1371653fef --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/rating.ts @@ -0,0 +1,54 @@ +import { css } from '@emotion/react'; +import type { RatingProps } from '../../../../components/Molecules/Rating'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Rating component +const ratingStyleScript = (props: RatingProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + return css({ + flexWrap: 'wrap', + gap: `${custom.spacing.x1}px`, + lineHeight: 1, + '.ss__rating__icons': { + '.ss__rating__stars': { + margin: '0 -1px', + '.ss__rating__stars__star': { + margin: '0 1px', + }, + }, + '.ss__rating__stars--empty': { + '.ss__rating__stars__star .ss__icon': { + fill: darkGray, + stroke: darkGray, + }, + }, + '.ss__rating__stars--full': { + '.ss__rating__stars__star .ss__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }, + '.ss__rating__count, .ss__rating__text': { + fontSize: custom.utils.convertPxToEm(12), + color: variables?.colors?.text, + }, + }); +}; + +// Rating component props +export const rating: ThemeComponent<'rating', RatingProps> = { + default: { + rating: { + themeStyleScript: ratingStyleScript, + emptyIcon: 'star', + fullIcon: 'star', + }, + 'rating icon': { + size: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/result.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/result.ts new file mode 100644 index 0000000000..5a40719251 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/result.ts @@ -0,0 +1,123 @@ +import { css } from '@emotion/react'; +import type { ResultProps } from '../../../../components/Molecules/Result'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Result component +const resultStyleScript = (props: ResultProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + + return css({ + '&.ss__result--sale': { + '.ss__result__details': { + '.ss__result__details__pricing': { + '.ss__result__price:not(.ss__price--strike)': { + '&, span': { + color: variables?.colors?.primary, + }, + }, + }, + }, + }, + '&.ss__result--grid': { + display: 'block', + }, + '&.ss__result--list': { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + '.ss__result__image-wrapper, .ss__result__details': { + minWidth: '1px', + }, + '.ss__result__image-wrapper': { + flex: '0 0 33.33%', + margin: `0 ${custom.spacing.x4}px 0 0`, + }, + '.ss__result__details': { + flex: '1 1 0%', + textAlign: 'left', + margin: 0, + '.ss__callout-badge, .ss__result__rating-wrapper': { + justifyContent: 'flex-start', + }, + '.ss__result__details__title': { + flex: '1 1 0%', + a: { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + }, + }, + '.ss__result__details__pricing': { + flex: '0 1 auto', + order: -1, + }, + }, + }, + '.ss__result__image-wrapper': { + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + '.ss__result__details': { + padding: 0, + display: 'flex', + flexFlow: 'row wrap', + gap: `${custom.spacing.x2}px`, + '& > *, .ss__result__details__title, .ss__result__details__title, .ss__result__details__pricing': { + margin: 0, + }, + '& > *': { + minWidth: '1px', + flex: '1 1 100%', + }, + '.ss__result__details__title': { + order: -2, + a: { + color: variables?.colors?.text, + }, + }, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: custom.utils.convertPxToEm(16), + '&:not(.ss__price--strike)': { + fontWeight: custom.fonts.weight01, + }, + }, + '.ss__price--strike': { + fontSize: custom.utils.convertPxToEm(14), + '&, span': { + color: lightGray, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '&.ss__result--list': { + display: 'block', + '.ss__result__details': { + textAlign: 'center', + '.ss__callout-badge, .ss__result__rating-wrapper': { + justifyContent: 'center', + }, + '.ss__result__details__title, .ss__result__details__pricing': { + flex: '1 1 100%', + }, + '.ss__result__details__pricing': { + order: 0, + }, + }, + '.ss__result__image-wrapper': { + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + }, + }, + }); +}; + +// Result component props +export const result: ThemeComponent<'result', ResultProps> = { + default: { + result: { + themeStyleScript: resultStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/searchInput.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/searchInput.ts new file mode 100644 index 0000000000..8ae4ecfd19 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/searchInput.ts @@ -0,0 +1,91 @@ +import { css } from '@emotion/react'; +import type { SearchInputProps } from '../../../../components/Molecules/SearchInput'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the SearchInput component +const searchInputStyleScript = (props: SearchInputProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const darkPrimary = custom.utils.darkenColor(variables?.colors?.primary, 0.15); + + return css({ + '&.ss__search-input': { + margin: `0 0 ${custom.spacing.x2}px`, + border: 0, + height: '35px', + '& > *': { + minWidth: '1px', + }, + '.ss__search-input__input, .ss__search-input__icons, .ss__button': { + height: '100%', + lineHeight: 1, + }, + '.ss__search-input__icons, .ss__search-input__button--close-search-button': { + flex: '0 1 auto', + }, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '35px', + boxSizing: 'border-box', + justifyContent: 'center', + '&, &:hover': { + border: 0, + }, + '&, .ss__icon': { + padding: 0, + }, + '.ss__icon': { + fill: custom.colors.white, + stroke: custom.colors.white, + }, + }, + '.ss__search-input__input': { + flex: '1 1 0%', + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + padding: `0 ${custom.spacing.x2}px`, + minHeight: '1px', + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.text, + '&::-webkit-input-placeholder': { + color: lightGray, + }, + '&::-ms-input-placeholder': { + color: lightGray, + }, + '&::placeholder': { + color: lightGray, + }, + }, + '.ss__search-input__icons': { + gap: '1px', + margin: '0 0 0 -1px', + backgroundColor: darkPrimary, + }, + '.ss__search-input__button--close-search-button': { + margin: '0 -1px 0 0', + }, + }, + }); +}; + +// SearchInput component props +export const searchInput: ThemeComponent<'searchInput', SearchInputProps> = { + default: { + searchInput: { + themeStyleScript: searchInputStyleScript, + }, + 'searchInput icon': { + size: `${custom.sizes.icon14}px`, + }, + 'searchInput button.close-search icon': { + icon: custom.icons.arrowLeft, + }, + 'searchInput button.clear-search icon': { + icon: custom.icons.close, + }, + 'searchInput button.submit-search icon': { + icon: custom.icons.search, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/select.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/select.ts new file mode 100644 index 0000000000..96d04d7a14 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/select.ts @@ -0,0 +1,149 @@ +import { css } from '@emotion/react'; +import type { SelectProps } from '../../../../components/Molecules/Select'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Select component +const selectStyleScript = (props: SelectProps) => { + const variables = props?.theme?.variables; + + // shared styles for select menus + const sharedStyles = css({ + border: `1px solid ${custom.colors.gray02}`, + color: variables?.colors?.text, + backgroundColor: custom.colors.gray01, + }); + + // default styles + const defaultStyles = css([ + { + display: 'block', + '.ss__dropdown': { + '.ss__dropdown__button .ss__button, .ss__dropdown__content .ss__select__select': { + ...sharedStyles, + }, + '.ss__dropdown__button': { + '.ss__button': { + display: 'flex', + padding: `0 ${custom.spacing.x2}px`, + textAlign: 'left', + '.ss__button__content': { + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__select__selection__icon': { + margin: 0, + }, + '.ss__select__selection': { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + fontWeight: 'normal', + }, + '.ss__select__dropdown__button__icon': { + transition: 'transform ease 0.5s', + }, + }, + }, + }, + '.ss__dropdown__content': { + marginTop: `${custom.spacing.x2}px`, + '.ss__select__select': { + padding: `${custom.spacing.x2}px`, + margin: 0, + '.ss__select__select__option': { + gap: `${custom.spacing.x2}px`, + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + color: 'inherit', + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + backgroundColor: 'transparent', + }, + }, + '.ss__select__select__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }, + }, + }, + '.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__button': { + '.ss__select__dropdown__button__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + }, + }, + ]); + + // native styles + const nativeStyles = css([ + sharedStyles, + { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + padding: `0 ${custom.spacing.x2}px`, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__select__label, .ss__select__select': { + fontSize: custom.utils.convertPxToEm(14), + }, + '.ss__select__label': { + fontWeight: custom.fonts.weight01, + }, + '.ss__select__select': { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + backgroundColor: 'transparent', + border: 'none', + appearance: 'none', + color: 'inherit', + cursor: 'pointer', + '&[disabled]': { + cursor: 'not-allowed', + }, + '&::-ms-expand': { + display: 'none', + }, + }, + '.ss__select__dropdown__button__icon': { + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, + ]); + + return props?.native ? nativeStyles : defaultStyles; +}; + +// Select component props +export const select: ThemeComponent<'select', SelectProps> = { + default: { + select: { + themeStyleScript: selectStyleScript, + iconOpen: custom.icons.arrowDown, + iconClose: custom.icons.arrowDown, + }, + 'select icon.open': { + size: `${custom.sizes.icon12}px`, + }, + 'select dropdown button': { + native: false, + }, + 'select dropdown button icon': { + size: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/slideout.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/slideout.ts new file mode 100644 index 0000000000..ce31c4a0ad --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/slideout.ts @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { SlideoutProps } from '../../../../components/Molecules/Slideout'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Slideout component +const slideoutStyleScript = (props: SlideoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({}); +}; + +// Slideout component props +export const slideout: ThemeComponent<'slideout', SlideoutProps> = { + default: { + slideout: { + themeStyleScript: slideoutStyleScript, + overlayColor: '', + }, + 'slideout button.slideout': { + icon: custom.icons.filter, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/swatches.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/swatches.ts new file mode 100644 index 0000000000..2f58434d43 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/swatches.ts @@ -0,0 +1,249 @@ +import { css } from '@emotion/react'; +import type { SwatchesProps } from '../../../../components/Molecules/Swatches'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// Swatch carousel sizes and spacing +const swatchSize = 30; +const swatchSpacing = custom.spacing.x1; + +// CSS in JS style script for the Swatches component +const swatchesStyleScript = (props: SwatchesProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const fontColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#d15120' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + // shared styles for swatches + const sharedStyles = css({ + margin: 0, + }); + + // carousel styles + const carouselStyles = css([ + sharedStyles, + { + margin: 0, + '.ss__carousel': { + '& > div': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + position: 'static', + bottom: 0, + width: `${swatchSize}px`, + height: `${swatchSize}px`, + }, + '.ss__carousel__prev-wrapper': { + margin: `0 ${swatchSpacing}px 0 0`, + }, + '.ss__carousel__next-wrapper': { + margin: `0 0 0 ${swatchSpacing}px`, + }, + '.swiper-container': { + maxWidth: `calc(100% - ${swatchSize * 2 + swatchSpacing * 2}px)`, + '& > .swiper-wrapper': { + '& > .swiper-slide': { + overflow: 'hidden', + width: `${swatchSize}px`, + height: `${swatchSize}px`, + '&:has(.ss__swatches__carousel__swatch.ss__swatches__carousel__swatch--unavailable)': { + '&:before': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + margin: 'auto', + width: '100%', + height: '1px', + borderTop: `3px solid ${darkGray}`, + transform: 'rotate(-45deg)', + }, + }, + }, + }, + }, + '.swiper-container > .swiper-wrapper > .swiper-slide > *, .ss__swatches__carousel__swatch': { + height: `${swatchSize}px`, + lineHeight: 0, + border: 0, + }, + '.ss__swatches__carousel__swatch': { + position: 'relative', + aspectRatio: 1, + color: variables?.colors?.text, + overflow: 'hidden', + '&, &:before, &:after, *': { + boxSizing: 'border-box', + }, + '&:before, &:after': { + content: '""', + display: 'block', + width: 'auto', + height: 'auto', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + transform: 'none', + }, + '&:before': { + border: `3px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&.ss__swatches__carousel__swatch--dark, &:has(.ss__swatches__carousel__swatch__inner--grey)': { + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + color: fontColor.hex(), + }, + }, + }, + '&.ss__swatches__carousel__swatch--selected': { + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + '&:has(.ss__swatches__carousel__swatch__inner:not([style]))': { + backgroundColor: activeColor.hex(), + '&:after': { + borderColor: activeColor.hex(), + opacity: 1, + }, + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + color: fontColor.hex(), + }, + }, + }, + '&:has(.ss__swatches__carousel__swatch__inner .ss__image)': { + backgroundColor: 'transparent', + '&:after': { + borderColor: custom.colors.black, + opacity: 0.3, + }, + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + color: variables?.colors?.text, + }, + }, + }, + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + '&.ss__swatches__carousel__swatch--disabled, &.ss__swatches__carousel__swatch--unavailable': { + opacity: 1, + cursor: 'not-allowed', + pointerEvents: 'none', + '.ss__swatches__carousel__swatch__inner:after': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 3, + margin: 'auto', + backgroundColor: darkGray.replace('#', ''), + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center center', + backgroundImage: `url("data:image/svg+xml,%3Csvg style=%27transform: rotate%28-45deg%29%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 56 56%27 preserveAspectRatio=%27xMinYMid%27%3E%3Cpath fill=%27%23${darkGray.replace( + '#', + '' + )}%27 d=%27M0 23.297h56v9.406h-56v-9.406z%27 /%3E%3C/svg%3E")`, + }, + }, + '.ss__swatches__carousel__swatch__inner': { + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + '.ss__swatches__carousel__swatch__value': { + display: 'block', + position: 'absolute', + zIndex: 2, + maxWidth: `calc(100% - ${custom.spacing.x2}px)`, + maxHeight: `calc(100% - ${custom.spacing.x2}px)`, + overflow: 'hidden', + textAlign: 'center', + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1, + }, + }, + }, + }, + }, + ]); + + // grid styles + const gridStyles = css([ + sharedStyles, + { + '.ss__grid': { + '.ss__grid__options': { + '.ss__grid__option:not(.ss__grid__show-more-wrapper)': { + width: `${swatchSize}px`, + maxHeight: `${swatchSize}px`, + }, + }, + }, + }, + ]); + + // return swatch styles + if (props?.type == 'grid') { + return gridStyles; + } else { + return carouselStyles; + } +}; + +// Swatches component props +export const swatches: ThemeComponent<'swatches', SwatchesProps> = { + default: { + swatches: { + themeStyleScript: swatchesStyleScript, + }, + 'swatches carousel': { + autoAdjustSlides: false, + centerInsufficientSlides: false, + slidesPerView: 'auto', + slidesPerGroup: 3, + spaceBetween: `${swatchSpacing}px`, + }, + }, + desktop: { + 'swatches carousel': { + slidesPerView: 'auto', + slidesPerGroup: 2, + spaceBetween: `${swatchSpacing}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/terms.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/terms.ts new file mode 100644 index 0000000000..1edc387a21 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/terms.ts @@ -0,0 +1,87 @@ +import { css } from '@emotion/react'; +import type { TermsProps } from '../../../../components/Molecules/Terms'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Terms component +const termsStyleScript = (props: TermsProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + return css({ + width: '100%', + textAlign: 'left', + 'ul, ul li': { + padding: 0, + margin: 0, + listStyle: 'none', + }, + '.ss__terms__title': { + '&, h5': { + padding: 0, + }, + h5: { + margin: `0 0 ${custom.spacing.x4}px 0`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + textTransform: custom.fonts.transform ? custom.fonts.transform : 'none', + color: variables?.colors?.secondary, + }, + }, + '.ss__terms__options': { + flexFlow: 'row wrap', + justifyContent: 'flex-start', + gap: `${custom.spacing.x1}px ${custom.spacing.x4}px`, + '&, .ss__terms__option': { + listStyle: 'none', + padding: 0, + }, + '.ss__terms__option': { + flex: '0 1 auto', + minWidth: '1px', + color: variables?.colors?.primary, + a: { + padding: 0, + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.primary, + em: { + color: variables?.colors?.text, + fontStyle: 'normal', + fontSize: 'inherit', + fontWeight: 'inherit', + }, + }, + }, + '.ss__terms__option--active': { + 'a, a em': { + fontWeight: custom?.fonts?.weight01, + color: variables?.colors?.primary, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__terms__title': { + h5: { + fontSize: custom.utils.convertPxToEm(14), + }, + }, + '.ss__terms__options': { + '.ss__terms__option': { + a: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }); +}; + +// Terms component props +export const terms: ThemeComponent<'terms', TermsProps> = { + default: { + terms: { + themeStyleScript: termsStyleScript, + emIfy: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/molecules/variantSelection.ts b/packages/snap-preact/components/src/themes/everest/components/molecules/variantSelection.ts new file mode 100644 index 0000000000..41509c3063 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/molecules/variantSelection.ts @@ -0,0 +1,149 @@ +import { css } from '@emotion/react'; +import type { VariantSelectionProps } from '../../../../components/Molecules/VariantSelection'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Swatches component +const variantSelectionStyleScript = (props: VariantSelectionProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + + // shared styles for variant selections + const sharedStyles = css({ + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }); + + // dropdown styles + const dropdownStyles = css([ + sharedStyles, + { + '.ss__dropdown': { + '.ss__dropdown__button, .ss__dropdown__content': { + border: `1px solid ${custom.colors.gray02}`, + color: variables?.colors?.text, + backgroundColor: custom.colors.gray01, + }, + '.ss__dropdown__button': { + width: 'auto', + display: 'flex', + padding: `0 ${custom.spacing.x2}px`, + textAlign: 'left', + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__dropdown__button-wrapper': { + flex: '1 1 0%', + gap: `${custom.spacing.x1}px`, + paddingRight: `${custom.spacing.x1}px`, + fontWeight: 'normal', + '.ss__dropdown__button-wrapper__label': { + fontWeight: custom?.fonts?.weight01, + textTransform: 'capitalize', + }, + }, + '.ss__variant-selection__icon': { + transition: 'transform ease 0.5s', + }, + }, + '.ss__dropdown__content': { + marginTop: `-1px`, + padding: `${custom.spacing.x2}px`, + '.ss__variant-selection__options': { + '&, .ss__variant-selection__option': { + listStyle: 'none', + padding: 0, + margin: 0, + }, + '.ss__variant-selection__option': { + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + fontWeight: 'normal', + }, + }, + '.ss__variant-selection__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__variant-selection__option--unavailable': { + color: lightGray, + cursor: 'not-allowed', + }, + }, + }, + }, + '.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__variant-selection__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + }, + ]); + + // list styles + const listStyles = css([ + sharedStyles, + { + '.ss__list': { + '.ss__list__title, .ss__list__options, .ss__list__options .ss__list__option': { + width: '100%', + color: variables?.colors?.text, + }, + '.ss__list__title': { + textTransform: 'capitalize', + }, + '.ss__list__options': { + '.ss__list__option': { + label: { + color: 'inherit', + }, + }, + '.ss__list__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__list__option--unavailable': { + color: lightGray, + cursor: 'not-allowed', + textDecoration: 'line-through', + }, + }, + }, + }, + ]); + + // swatches syles + const swatchesStyles = css([sharedStyles]); + + // return variant selection styles + if (props?.type == 'list') { + return listStyles; + } else if (props?.type == 'swatches') { + return swatchesStyles; + } else { + return dropdownStyles; + } +}; + +// VariantSelection component props +export const variantSelection: ThemeComponent<'variantSelection', VariantSelectionProps> = { + default: { + variantSelection: { + themeStyleScript: variantSelectionStyleScript, + }, + 'variantSelection dropdown icon': { + size: `${custom.sizes.icon12}px`, + icon: custom.icons.arrowDown, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..a37374b5bd --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/autocomplete.ts @@ -0,0 +1,392 @@ +import { css } from '@emotion/react'; +import type { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; + +// CSS in JS style script for the Autocomplete component +const autocompleteStyleScript = (props: AutocompleteProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const headerSelectors = + '.ss__autocomplete__terms .ss__autocomplete__title h5, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__header, .ss__autocomplete__content__results .ss__autocomplete__title h5, .ss__autocomplete__content__info a, .ss__no-results__recommendations h3'; + const activeSelectors = + '.ss__autocomplete__terms .ss__autocomplete__terms__options .ss__autocomplete__terms__option--active a, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__options .ss__facet-list-options .ss__facet-list-options__option--filtered, .ss__autocomplete__content__results .ss__results .ss__result:hover .ss__result__details .ss__result__details__title a, .ss__autocomplete__content__info a:hover'; + + return css({ + '&.ss__autocomplete': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.white, + width: props?.width, + right: 0, + left: 'auto', + top: 'auto', + margin: `${custom.spacing.x1}px 0 0 0`, + gap: `${custom.spacing.x4}px`, + 'a, div, p': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1.5, + color: variables?.colors?.text, + }, + a: { + display: 'block', + }, + '.ss__banner': { + img: { + maxWidth: '100%', + maxHeight: '150px', + height: 'auto', + }, + }, + [headerSelectors]: { + margin: `0 0 ${custom.spacing.x4}px 0`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + lineHeight: 1.2, + color: variables?.colors?.secondary, + }, + [activeSelectors]: { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '& > div': { + minWidth: '1px', + maxWidth: 'none', + flex: '0 1 auto', + padding: `${custom.spacing.x4}px 0`, + order: 0, + '&:first-of-type': { + paddingLeft: `${custom.spacing.x4}px`, + }, + '&:last-of-type': { + paddingRight: `${custom.spacing.x4}px`, + }, + '&.ss__autocomplete__terms': { + padding: 0, + }, + }, + '.ss__autocomplete__terms': { + width: '200px', + backgroundColor: custom.colors.gray01, + textAlign: 'left', + '& > div:first-of-type .ss__autocomplete__title': { + marginTop: `${custom.spacing.x2}px`, + }, + '& > div:last-of-type .ss__autocomplete__terms__options': { + marginBottom: `${custom.spacing.x2}px`, + }, + '& > div': { + '.ss__autocomplete__title': { + padding: 0, + h5: { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms__options': { + '.ss__autocomplete__terms__option': { + a: { + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.primary, + em: { + color: variables?.colors?.text, + fontStyle: 'normal', + fontSize: 'inherit', + fontWeight: 'inherit', + }, + }, + }, + '.ss__autocomplete__terms__option--active': { + 'a, a em': { + fontWeight: custom?.fonts?.weight01, + color: variables?.colors?.primary, + }, + }, + }, + }, + }, + '.ss__autocomplete__facets': { + width: '200px', + textAlign: 'left', + '.ss__facets': { + '.ss__facet': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&.ss__facet--showing-all': { + '.ss__facet__options': { + maxHeight: 'none', + overflow: 'visible', + padding: 0, + }, + }, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__facet__header': { + borderBottom: 0, + padding: 0, + '.ss__facet__header__inner': { + fontSize: 'inherit', + fontWeight: 'inherit', + color: 'inherit', + }, + }, + '.ss__facet__options': { + margin: 0, + maxHeight: 'none', + overflow: 'visible', + '.ss__facet-hierarchy-options .ss__facet-hierarchy-options__option, .ss__facet-list-options .ss__facet-list-options__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__facet-list-options': { + '.ss__facet-list-options__option': {}, + }, + }, + }, + }, + }, + '.ss__autocomplete__content': { + flex: '1 1 0%', + overflow: 'visible', + justifyContent: 'flex-start', + }, + '.ss__autocomplete__content__results': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '.ss__results': { + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '75vh', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__result': { + '.ss__result__details': { + gap: `${custom.spacing.x1}px`, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: custom.utils.convertPxToEm(14), + }, + '.ss__price--strike': { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + '.ss__inline-banner': { + maxHeight: '250px', + overflow: 'hidden', + }, + }, + }, + '.ss__autocomplete__content__info': { + padding: 0, + a: { + margin: 0, + '.ss__icon': { + fill: 'currentColor', + stroke: 'currentColor', + }, + }, + }, + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + '.ss__no-results__recommendations': { + margin: `${custom.spacing.x4}px 0 0 0`, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '&.ss__autocomplete': { + flexFlow: 'row wrap', + gap: 0, + width: props?.width, + left: 0, + right: 0, + [headerSelectors]: { + fontSize: custom.utils.convertPxToEm(14), + }, + '& > div': { + flex: '1 1 100%', + borderBottom: `1px solid ${custom.colors.gray02}`, + '&:last-of-type': { + borderBottomWidth: 0, + }, + '&, &.ss__autocomplete__terms': { + padding: `${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms': { + backgroundColor: 'transparent', + display: 'flex', + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + width: 'auto', + '& > div': { + minWidth: '1px', + flex: '1 1 0%', + '&:first-of-type .ss__autocomplete__title': { + marginTop: 0, + }, + '&:last-of-type .ss__autocomplete__terms__options': { + marginBottom: 0, + }, + '.ss__autocomplete__title h5': { + padding: 0, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__autocomplete__terms__options': { + gap: `${custom.spacing.x1}px ${custom.spacing.x4}px`, + flexFlow: 'row wrap', + justifyContent: 'flex-start', + '.ss__autocomplete__terms__option': { + flex: '0 1 auto', + a: { + padding: 0, + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }, + '.ss__autocomplete__terms > div .ss__autocomplete__terms__options, .ss__autocomplete__facets .ss__facets': { + display: 'flex', + }, + '.ss__autocomplete__terms > div .ss__autocomplete__terms__options, .ss__autocomplete__facets .ss__facets .ss__facet': { + minWidth: '1px', + }, + '.ss__autocomplete__facets': { + width: 'auto', + '.ss__facets': { + gap: `0 ${custom.spacing.x4}px`, + flexFlow: 'row nowrap', + '.ss__facet': { + flex: '1 1 0%', + '&, &:last-of-type': { + margin: 0, + }, + }, + }, + }, + '.ss__autocomplete__content__info': { + a: { + '.ss__icon': { + position: 'relative', + top: '1px', + }, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '&.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__recommendation-grid__results': { + gridTemplateColumns: `repeat(2, 1fr)`, + '& > div:nth-of-type(n+3)': { + display: 'none', + }, + }, + }, + }, + }); +}; + +// Autocomplete component props +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + themeStyleScript: autocompleteStyleScript, + width: '900px', + }, + 'autocomplete facet': { + limit: 5, + disableOverflow: true, + disableCollapse: true, + }, + 'autocomplete facets': { + limit: 3, + }, + 'autocomplete facetListOptions': { + hideCheckbox: true, + }, + 'autocomplete facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocomplete facetGridOptions': { + gridSize: '38px', + }, + 'autocomplete results': { + rows: 2, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocomplete icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteThemeComponentProps.mobile, + autocomplete: { + width: '100%', + }, + 'autocomplete results': { + rows: 1, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 1, + columns: 3, + }, + }, + tablet: { + ...autocompleteThemeComponentProps.tablet, + autocomplete: { + width: '100%', + }, + 'autocomplete results': { + rows: 1, + columns: 4, + }, + 'autocomplete recommendationGrid': { + rows: 1, + columns: 4, + }, + }, + desktop: { + ...autocompleteThemeComponentProps.desktop, + autocomplete: {}, + 'autocomplete results': { + rows: 2, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/autocompleteLayout.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/autocompleteLayout.ts new file mode 100644 index 0000000000..c45578d695 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/autocompleteLayout.ts @@ -0,0 +1,451 @@ +import { css } from '@emotion/react'; +import type { AutocompleteLayoutProps } from '../../../../components/Organisms/AutocompleteLayout'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Autocomplete Layout component +const autocompleteLayoutStyleScript = (props: AutocompleteLayoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const textSelectors = 'a, div, p'; + const headerSelectors = + '.ss__terms-list .ss__terms .ss__terms__title h5, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__header, .ss__autocomplete__content .ss__autocomplete__content__results .ss__autocomplete__title h5, .ss__autocomplete__button--see-more .ss__button__content, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__title'; + const activeSelectors = + '.ss__terms-list .ss__terms .ss__terms__options .ss__terms__option.ss__terms__option--active a, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__options .ss__facet-list-options .ss__facet-list-options__option--filtered, .ss__autocomplete__content .ss__autocomplete__content__results .ss__results .ss__result:hover .ss__result__details .ss__result__details__title a, .ss__autocomplete__button--see-more:hover .ss__button__content'; + + // get autocomplete layout + const acLayout = props?.layout ? props.layout : 'standard'; + + // shared autocomplete styles + const sharedStyles = css({ + alignContent: acLayout == 'standard' ? 'normal' : 'flex-start', + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.white, + [textSelectors]: { + fontSize: custom.utils.convertPxToEm(acLayout == 'terms' ? 15 : 12), + lineHeight: 1.5, + color: variables?.colors?.text, + }, + a: { + display: 'block', + }, + 'ul, ul li': { + padding: 0, + margin: 0, + listStyle: 'none', + }, + '.ss__banner': { + img: { + maxWidth: '100%', + maxHeight: '150px', + height: 'auto', + }, + }, + [headerSelectors]: { + margin: `0 0 ${custom.spacing.x4}px 0`, + padding: 0, + fontSize: custom.utils.convertPxToEm(acLayout == 'terms' ? 17 : 16), + fontWeight: custom.fonts.weight02, + lineHeight: 1.2, + color: variables?.colors?.secondary, + }, + [activeSelectors]: { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__autocomplete__row, .ss__autocomplete__column': { + '.ss__search-input': { + background: 'transparent', + width: 'auto', + height: '30px', + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + }, + '.ss__autocomplete__column': { + alignContent: 'flex-start', + minWidth: '1px', + }, + }); + const sharedTabletStyles = css({ + alignContent: 'flex-start', + [textSelectors]: { + fontSize: acLayout == 'terms' ? custom.utils.convertPxToEm(12) : '', + }, + [headerSelectors]: { + fontSize: custom.utils.convertPxToEm(14), + }, + }); + + // terms wrapper styles + const termsWrapperStyles = css({ + '.ss__autocomplete__terms-wrapper': { + backgroundColor: 'transparent', + padding: `${custom.spacing.x4}px`, + }, + }); + + // facets styles + const facetsStyles = css({ + '.ss__autocomplete__facets-wrapper': { + padding: `${custom.spacing.x4}px`, + }, + '.ss__autocomplete__facets': { + padding: 0, + '.ss__facets': { + '.ss__facet': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '&.ss__facet--showing-all': { + '.ss__facet__options': { + maxHeight: 'none', + overflow: 'visible', + padding: 0, + }, + }, + '.ss__facet__header': { + borderBottom: 0, + '.ss__facet__header__inner': { + fontSize: 'inherit', + fontWeight: 'inherit', + color: 'inherit', + }, + }, + '.ss__facet__options': { + '.ss__facet-hierarchy-options .ss__facet-hierarchy-options__option, .ss__facet-list-options .ss__facet-list-options__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + }, + }, + }, + }); + + // content styles + const contentStyles = css({ + '.ss__autocomplete__column:has(.ss__autocomplete__content)': { + alignContent: 'flex-start', + }, + '.ss__autocomplete__content': { + overflow: 'visible', + justifyContent: 'flex-start', + padding: `${custom.spacing.x4}px`, + borderTop: `1px solid ${custom.colors.gray02}`, + '.ss__autocomplete__content-inner': { + padding: 0, + }, + }, + }); + + // results layout styles + const resultsLayoutStyles = css({ + gap: `${custom.spacing.x4}px`, + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '75vh', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__result': { + '.ss__result__details': { + gap: `${custom.spacing.x1}px`, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: custom.utils.convertPxToEm(14), + }, + '.ss__price--strike': { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }); + + // results styles + const resultsStyles = css({ + '.ss__autocomplete__content__results': { + '.ss__results': { + ...resultsLayoutStyles, + }, + }, + }); + + // no results styles + const noResultsStyles = css({ + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + '.ss__autocomplete__content__no-results__recommendations': { + '.ss__recommendation-grid': { + margin: `${custom.spacing.x4}px 0 0 0`, + }, + '.ss__recommendation-grid__title': { + textAlign: 'left', + }, + '.ss__recommendation-grid__results': { + ...resultsLayoutStyles, + }, + }, + }, + }); + + // see more styles + const seeMoreStyles = css({ + '.ss__autocomplete__button--see-more': { + padding: `${custom.spacing.x4}px`, + paddingTop: 0, + height: 'auto', + '&, &:hover': { + backgroundColor: 'transparent', + border: 0, + }, + '.ss__button__content': { + margin: 0, + '.ss__icon': { + position: 'relative', + top: '0.5px', + margin: `0 0 0 ${custom.spacing.x1}px`, + }, + }, + }, + }); + const seeMoreTabletStyles = css({ + order: -1, + textAlign: 'left', + '.ss__button__content': { + '.ss__icon': { + top: '1.5px', + }, + }, + }); + + // standard styles + const standardStyles = css([ + sharedStyles, + { + '.ss__autocomplete__column': { + '&:has(.ss__autocomplete__terms-wrapper)': { + flex: '1 0 200px', + maxWidth: '200px', + }, + '&:has(.ss__autocomplete__facets-wrapper)': { + flex: '1 0 200px', + maxWidth: '200px', + marginRight: `-${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms-wrapper': { + backgroundColor: custom.colors.gray01, + height: '100%', + }, + '.ss__terms-list': { + display: 'block', + '.ss__terms-list__row': { + '&:first-of-type .ss__terms .ss__terms__title': { + marginTop: `${custom.spacing.x2}px`, + }, + '&:last-of-type .ss__terms .ss__terms__options': { + marginBottom: `${custom.spacing.x2}px`, + }, + }, + '.ss__terms': { + '.ss__terms__title': { + h5: { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__terms__options': { + display: 'block', + margin: 0, + '.ss__terms__option': { + a: { + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__terms__option--active': { + backgroundColor: custom.colors.white, + }, + }, + }, + }, + }, + facetsStyles, + contentStyles, + resultsStyles, + noResultsStyles, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__row:has(.ss__autocomplete__column)': { + display: 'block', + '.ss__autocomplete__column': { + width: '100%', + maxWidth: 'none', + }, + }, + '.ss__autocomplete__column': { + '&:has(.ss__autocomplete__facets-wrapper)': { + marginRight: 0, + }, + }, + '.ss__autocomplete__terms-wrapper': { + backgroundColor: 'transparent', + padding: `${custom.spacing.x4}px`, + }, + '.ss__terms-list': { + display: 'flex', + '.ss__terms-list__row': { + '&:first-of-type .ss__terms .ss__terms__title': { + marginTop: 0, + }, + '&:last-of-type .ss__terms .ss__terms__options': { + marginBottom: 0, + }, + }, + '.ss__terms': { + '.ss__terms__title': { + h5: { + padding: 0, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + }, + '.ss__terms__options': { + display: 'flex', + '.ss__terms__option': { + a: { + padding: 0, + }, + }, + }, + }, + }, + '.ss__autocomplete__facets-wrapper': { + borderTop: `1px solid ${custom.colors.gray02}`, + }, + '.ss__autocomplete__facets': { + '.ss__facets': { + gap: `0 ${custom.spacing.x4}px`, + flexFlow: 'row nowrap', + minWidth: '1px', + '.ss__facet': { + flex: '1 1 0%', + minWidth: '1px', + '&, &:last-of-type': { + margin: 0, + }, + }, + }, + }, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + ]); + + // mini styles + const miniStyles = css([ + sharedStyles, + termsWrapperStyles, + contentStyles, + resultsStyles, + noResultsStyles, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + { + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + gridTemplateColumns: `repeat(2, 1fr)`, + }, + }, + }, + ]); + + // terms styles + const termsStyles = css([ + sharedStyles, + termsWrapperStyles, + contentStyles, + { + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + fontSize: custom.utils.convertPxToEm(14), + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + }, + }, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + ]); + + // return autocomplete styles + if (acLayout == 'terms') { + return termsStyles; + } else if (acLayout == 'mini') { + return miniStyles; + } else { + return standardStyles; + } +}; + +// Autocomplete Layout component props +export const autocompleteLayout: ThemeComponent<'autocompleteLayout', AutocompleteLayoutProps> = { + default: { + autocompleteLayout: { + themeStyleScript: autocompleteLayoutStyleScript, + contentTitle: 'Product Suggestions', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/facet.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/facet.ts new file mode 100644 index 0000000000..3108a816ac --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/facet.ts @@ -0,0 +1,80 @@ +import { css } from '@emotion/react'; +import type { FacetProps } from '../../../../components/Organisms/Facet'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Facet component +const facetStyleScript = (props: FacetProps) => { + const variables = props?.theme?.variables; + + return css({ + '&.ss__facet--collapsed': { + '.ss__facet__header': { + '.ss__icon': { + transform: 'rotate(0deg)', + }, + }, + }, + '&.ss__facet--showing-all': { + '.ss__facet__options': { + maxHeight: `490px`, + overflowY: 'auto', + overflowX: 'hidden', + paddingRight: `${custom.spacing.x2}px`, + }, + }, + '.ss__facet__header': { + gap: `${custom.spacing.x2}px`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + '.ss__icon': { + transition: 'transform ease 0.5s', + transform: 'rotate(180deg)', + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + '.ss__facet__options': { + marginTop: 0, + maxHeight: 'none', + overflow: 'visible', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + }, + '.ss__facet__show-more-less': { + margin: `${custom.spacing.x2}px 0 0 0`, + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '.ss__icon': { + position: 'relative', + top: '-0.5px', + marginRight: `${custom.spacing.x1}px`, + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + }, + }, + }); +}; + +// Facet component props +export const facet: ThemeComponent<'facet', FacetProps> = { + default: { + facet: { + themeStyleScript: facetStyleScript, + iconCollapse: custom.icons.arrowDown, + iconExpand: custom.icons.arrowDown, + iconOverflowMore: custom.icons.plus, + iconOverflowLess: custom.icons.minus, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/facets.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/facets.ts new file mode 100644 index 0000000000..ff933eb030 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/facets.ts @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { FacetsProps } from '../../../../components/Organisms/Facets'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Facets component +const facetsStyleScript = (props: FacetsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '&.ss__facets': { + display: 'block', + width: 'auto', + }, + }); +}; + +// Facets component props +export const facets: ThemeComponent<'facets', FacetsProps> = { + default: { + facets: { + themeStyleScript: facetsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/facetsHorizontal.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/facetsHorizontal.ts new file mode 100644 index 0000000000..ea6f249453 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/facetsHorizontal.ts @@ -0,0 +1,239 @@ +import { css } from '@emotion/react'; +import type { FacetsHorizontalProps } from '../../../../components/Organisms/FacetsHorizontal'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Facets component +const facetsHorizontalStyleScript = (props: FacetsHorizontalProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const columnsSelector = `.ss__facet-hierarchy-options, .ss__facet-list-options, .ss__facet-palette-options.ss__facet-palette-options--list`; + + return css({ + margin: 0, + '.ss__facets-horizontal__header': { + gap: 0, + margin: `0 -${custom.spacing.x1}px -${custom.spacing.x2}px -${custom.spacing.x1}px `, + position: 'relative', + '& > *': { + boxSizing: 'border-box', + minWidth: '1px', + width: `${100 / 6}%`, + flex: '0 1 auto', + padding: `0 ${custom.spacing.x1}px`, + }, + '& > *, .ss__facets-horizontal__header__dropdown, .ss__mobile-sidebar': { + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + '.ss__facets-horizontal__header__dropdown': { + position: 'static', + '&.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__dropdown__button__heading': { + '.ss__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + '.ss__dropdown__content': { + width: 'auto', + minWidth: '1px', + maxHeight: 'none', + overflowY: 'visible', + padding: `${custom.spacing.x2}px`, + marginTop: `${custom.spacing.x2}px`, + left: `${custom.spacing.x1}px`, + right: `${custom.spacing.x1}px`, + }, + }, + '.ss__dropdown__button, .ss__dropdown__content': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + }, + '.ss__dropdown__button': { + display: 'block', + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + padding: `0 ${custom.spacing.x2}px`, + textAlign: 'left', + color: variables?.colors?.text, + '.ss__dropdown__button__heading': { + flexFlow: 'row nowrap', + justifyContent: 'flex-start', + gap: `${custom.spacing.x1}px`, + padding: 0, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + span: { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + fontWeight: custom.fonts.weight01, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + '.ss__icon': { + transition: 'transform ease 0.5s', + }, + }, + }, + '.ss__dropdown__content': { + width: 'auto', + padding: `${custom.spacing.x2}px`, + [columnsSelector]: { + display: 'flex', + flexFlow: 'row wrap', + gap: `0 ${custom.spacing.x2}px`, + '& > *': { + flex: '0 1 auto', + width: `${100 / 4 - 2}%`, + minWidth: '1px', + boxSizing: 'border-box', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }, + '.ss__checkbox, .ss__radio, .ss__search-input .ss__search-input__input': { + backgroundColor: custom.colors.white, + }, + '.ss__facet': { + margin: 0, + }, + '.ss__facet.ss__facet--showing-all .ss__facet__options': { + maxHeight: '360px', + }, + '.ss__facet-list-options': { + marginBottom: `-${custom.spacing.x1}px`, + '.ss__facet-list-options__option:last-of-type': { + marginBottom: `${custom.spacing.x1}px`, + }, + }, + '.ss__facet-hierarchy-options': { + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--filtered': { + '& ~ .ss__facet-hierarchy-options__option:not(.ss__facet-hierarchy-options__option--filtered)': { + paddingLeft: 0, + }, + }, + }, + '.ss__facet-grid-options': { + '.ss__facet-grid-options__option:not(.ss__facet-grid-options__option--filtered)': { + '&:after': { + backgroundColor: custom.colors.white, + }, + }, + }, + '.ss__facet--slider': { + '.ss__facet__options': { + display: 'flex', + minHeight: '100px', + '.ss__facet-slider': { + width: '100%', + }, + }, + }, + '.ss__facet__show-more-less': { + textAlign: 'center', + }, + }, + }, + '.ss__mobile-sidebar': { + '.ss__slideout__button .ss__button': { + display: 'flex', + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__facets-horizontal__header': { + '& > *': { + width: `${100 / 4}%`, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content': { + [columnsSelector]: { + '& > *': { + width: `${100 / 3 - 2}%`, + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__facets-horizontal__header': { + '& > *': { + width: `${100 / 2}%`, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content': { + [columnsSelector]: { + '& > *': { + width: `${100 / 2 - 2}%`, + }, + }, + }, + }, + }, + }); +}; + +// FacetsHorizontal component props +export const facetsHorizontal: ThemeComponent<'facetsHorizontal', FacetsHorizontalProps> = { + default: { + facetsHorizontal: { + themeStyleScript: facetsHorizontalStyleScript, + iconExpand: custom.icons.arrowDown, + iconCollapse: custom.icons.arrowDown, + alwaysShowFiltersButton: true, + }, + 'facetsHorizontal dropdown button icon': { + size: `${custom.sizes.icon12}px`, + }, + 'facetsHorizontal dropdown facet': { + statefulOverflow: true, + display: { + list: { + limit: 32, + }, + hierarchy: { + limit: 32, + }, + grid: { + limit: 34, + }, + palette: { + limit: 34, + }, + }, + }, + 'facetsHorizontal mobileSidebar facet': { + statefulOverflow: true, + display: { + list: { + limit: 10, + }, + hierarchy: { + limit: 10, + }, + grid: { + limit: 12, + }, + palette: { + limit: 12, + }, + }, + }, + 'facetsHorizontal facetGridOptions': { + gridSize: '62px', + }, + 'facetsHorizontal mobileSidebar facetGridOptions': { + gridSize: '52px', + }, + 'facetsHorizontal facetPaletteOptions': { + gridSize: '62px', + }, + 'facetsHorizontal mobileSidebar facetPaletteOptions': { + gridSize: '52px', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/filterSummary.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/filterSummary.ts new file mode 100644 index 0000000000..7c60576c1f --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/filterSummary.ts @@ -0,0 +1,90 @@ +import { css } from '@emotion/react'; +import type { FilterSummaryProps } from '../../../../components/Organisms/FilterSummary'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FilterSummary component +const filterSummaryStyleScript = (props: FilterSummaryProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + const listSpacing = custom.sizes.icon16 + custom.spacing.x2; + + // shared palette styles + const sharedStyles = css({ + '.ss__filter-summary__title': { + padding: 0, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__filter-summary__filters': { + margin: 0, + }, + }); + + // inline filter summary styles + const inlineStyles = css([ + sharedStyles, + { + '&.ss__filter-summary--inline': { + '.ss__filter-summary__filters': { + gap: `${custom.spacing.x1}px`, + }, + }, + }, + ]); + + // list filter summary styles + const listStyles = css([ + sharedStyles, + { + '&.ss__filter-summary--list': { + '.ss__filter-summary__filters': { + '.ss__filter': { + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__filter__button': { + '.ss__button__content': { + position: 'relative', + padding: `0 0 0 ${listSpacing}px`, + '.ss__filter__button__icon': { + position: 'absolute', + top: '1.5px', + left: 0, + padding: '3px', + backgroundColor: custom.colors.gray01, + border: `1px solid ${darkGray}`, + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + boxSizing: 'border-box', + }, + '.ss__filter__label, .ss__filter__value': { + margin: 0, + }, + '.ss__filter__label': { + padding: '0 4px 0 0', + }, + }, + }, + }, + }, + }, + }, + ]); + + return props?.type == 'list' ? listStyles : inlineStyles; +}; + +// FilterSummary component props +export const filterSummary: ThemeComponent<'filterSummary', FilterSummaryProps> = { + default: { + filterSummary: { + themeStyleScript: filterSummaryStyleScript, + clearAllIcon: custom.icons.close, + filterIcon: custom.icons.close, + hideTitle: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/index.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/index.ts new file mode 100644 index 0000000000..11cfc74d31 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/index.ts @@ -0,0 +1,74 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// ORGANISMS Imports +import { autocomplete } from './autocomplete'; +import { autocompleteLayout } from './autocompleteLayout'; +import { facet } from './facet'; +import { facets } from './facets'; +import { facetsHorizontal } from './facetsHorizontal'; +import { filterSummary } from './filterSummary'; +import { mobileSidebar } from './mobileSidebar'; +import { noResults } from './noResults'; +import { results } from './results'; +import { sidebar } from './sidebar'; +import { termsList } from './termsList'; +import { toolbar } from './toolbar'; + +export const organisms: ThemeResponsiveComplete = { + default: { + ...autocomplete.default, + ...autocompleteLayout.default, + ...facet.default, + ...facets.default, + ...facetsHorizontal.default, + ...filterSummary.default, + ...mobileSidebar.default, + ...noResults.default, + ...results.default, + ...sidebar.default, + ...toolbar.default, + ...termsList.default, + }, + mobile: { + ...autocomplete.mobile, + ...autocompleteLayout.mobile, + ...facet.mobile, + ...facets.mobile, + ...facetsHorizontal.mobile, + ...filterSummary.mobile, + ...mobileSidebar.mobile, + ...noResults.mobile, + ...results.mobile, + ...sidebar.mobile, + ...toolbar.mobile, + ...termsList.mobile, + }, + tablet: { + ...autocomplete.tablet, + ...autocompleteLayout.tablet, + ...facet.tablet, + ...facets.tablet, + ...facetsHorizontal.tablet, + ...filterSummary.tablet, + ...mobileSidebar.tablet, + ...noResults.tablet, + ...results.tablet, + ...sidebar.tablet, + ...toolbar.tablet, + ...termsList.tablet, + }, + desktop: { + ...autocomplete.desktop, + ...autocompleteLayout.desktop, + ...facet.desktop, + ...facets.desktop, + ...facetsHorizontal.desktop, + ...filterSummary.desktop, + ...mobileSidebar.desktop, + ...noResults.desktop, + ...results.desktop, + ...sidebar.desktop, + ...toolbar.desktop, + ...termsList.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/mobileSidebar.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/mobileSidebar.ts new file mode 100644 index 0000000000..5ffe75c687 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/mobileSidebar.ts @@ -0,0 +1,130 @@ +import { css } from '@emotion/react'; +import type { MobileSidebarProps } from '../../../../components/Organisms/MobileSidebar'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the MobileSidebar component +const mobileSidebarStyleScript = (props: MobileSidebarProps) => { + const variables = props?.theme?.variables; + const headerHeight = 60; + const footerHeight = 75; + + return css({ + '.ss__mobile-sidebar__slideout': { + overflowY: 'hidden', + padding: 0, + width: '100%', + '.ss__mobile-sidebar__content': { + height: '100%', + '.ss__mobile-sidebar__header, .ss__mobile-sidebar__footer': { + padding: `0 ${custom.spacing.x4}px`, + gap: `${custom.spacing.x2}px`, + alignItems: 'center', + }, + '.ss__mobile-sidebar__header': { + height: `${headerHeight}px`, + backgroundColor: variables?.colors?.primary, + color: custom.colors.white, + '.ss__mobile-sidebar__header__title': { + margin: 0, + fontSize: custom.utils.convertPxToEm(18), + }, + '.ss__mobile-sidebar__header__close-button': { + padding: 0, + width: '16px', + height: '16px', + lineHeight: '16px', + '.ss__icon': { + width: '100%', + height: '100%', + lineHeight: 1, + }, + }, + }, + '.ss__mobile-sidebar__footer': { + height: `${footerHeight}px`, + backgroundColor: custom.colors.white, + borderTop: `1px solid ${custom.colors.gray02}`, + '.ss__button': { + flex: `1 1 0%`, + }, + }, + '.ss__mobile-sidebar__inner': { + height: `calc(100% - ${headerHeight + footerHeight}px)`, + overflowY: 'auto', + overflowX: 'hidden', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__layout': { + overflow: 'hidden', + display: 'block', + '& > *': { + borderBottom: `1px solid ${custom.colors.gray02}`, + padding: `${custom.spacing.x4}px`, + '&:last-of-type': { + borderBottomWidth: 0, + }, + }, + }, + '.ss__select--native': { + padding: `0 ${custom.spacing.x4}px`, + borderTop: 0, + height: '40px', + lineHeight: '40px', + }, + '.ss__filter-summary, .ss__facets': { + padding: 0, + }, + '.ss__filter-summary .ss__filter-summary__title, .ss__facets .ss__facet .ss__facet__header': { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: 0, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.text, + }, + '.ss__filter-summary .ss__filter-summary__filters, .ss__facets .ss__facet .ss__dropdown__content': { + padding: `${custom.spacing.x4}px`, + }, + '.ss__facets .ss__facet': { + margin: 0, + width: 'auto', + '&.ss__facet--collapsed': { + borderBottom: `1px solid ${custom.colors.gray02}`, + }, + '.ss__facet__header': { + '.ss__icon': { + fill: 'currentColor', + stroke: 'currentColor', + }, + }, + }, + }, + }, + }, + }); +}; + +// MobileSidebar component props +export const mobileSidebar: ThemeComponent<'mobileSidebar', MobileSidebarProps> = { + default: { + mobileSidebar: { + themeStyleScript: mobileSidebarStyleScript, + }, + 'mobileSidebar button.close': { + icon: custom.icons.close, + }, + 'mobileSidebar toolbar filterSummary': { + title: 'Current Filters', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/noResults.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/noResults.ts new file mode 100644 index 0000000000..c7a685676b --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/noResults.ts @@ -0,0 +1,61 @@ +import { css } from '@emotion/react'; +import type { NoResultsProps } from '../../../../components/Organisms/NoResults'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the NoResults component +const noResultsStyleScript = (props: NoResultsProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + 'h1, h2, h3, h4, h5, h6, ul': { + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + 'h1, h2, h3, h4, h5, h6, .ss__no-results__recommendations .ss__recommendation .ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(20), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + 'ul li, p': { + color: variables?.colors?.text, + }, + a: { + color: variables?.colors?.primary, + '&:hover': { + color: variables?.colors?.secondary, + }, + }, + ul: { + padding: 0, + marginLeft: `${custom.spacing.x8}px`, + listStyle: 'none', + li: { + listStyle: 'disc', + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + '.ss__no-results__recommendations': { + '.ss__recommendation': { + margin: `${custom.spacing.x4}px 0`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + 'h1, h2, h3, h4, h5, h6, .ss__no-results__recommendations .ss__recommendation .ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(18), + }, + }, + }); +}; + +// NoResults component props +export const noResults: ThemeComponent<'noResults', NoResultsProps> = { + default: { + noResults: { + themeStyleScript: noResultsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/results.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/results.ts new file mode 100644 index 0000000000..fabe87ac2f --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/results.ts @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; +import type { ResultsProps } from '../../../../components/Organisms/Results'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Results component +const resultsStyleScript = (props: ResultsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '& > *': { + minWidth: '1px', + }, + }); +}; + +// Results component props +export const results: ThemeComponent<'results', ResultsProps> = { + default: { + results: { + themeStyleScript: resultsStyleScript, + gapSize: `${custom.spacing.x6}px ${custom.spacing.x4}px`, + columns: 4, + }, + }, + mobile: { + results: { + gapSize: `${custom.spacing.x6}px ${custom.spacing.x2}px`, + columns: 2, + }, + }, + tablet: { + results: { + columns: 3, + }, + }, + desktop: {}, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/sidebar.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/sidebar.ts new file mode 100644 index 0000000000..60ef58fa2c --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/sidebar.ts @@ -0,0 +1,57 @@ +import { css } from '@emotion/react'; +import type { SidebarProps } from '../../../../components/Organisms/Sidebar'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Sidebar component +const sidebarStyleScript = (props: SidebarProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__sidebar__title': { + margin: `0 0 ${custom.spacing.x6}px 0`, + fontSize: custom.utils.convertPxToEm(20), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__sidebar__inner': { + '.ss__layout': { + '&, .ss__layout__row': { + display: 'block', + }, + '.ss__layout__row': { + minWidth: '1px', + '& > div:only-child': { + width: 'auto', + }, + }, + }, + '.ss__layout .ss__layout__row, .ss__facets .ss__facet': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__filter-summary .ss__filter-summary__title, .ss__facets .ss__facet .ss__facet__header': { + margin: ` 0 0 ${custom.spacing.x4}px 0`, + padding: ` 0 0 ${custom.spacing.x2}px 0`, + borderBottom: `2px solid ${variables?.colors?.primary}`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + }, + }); +}; + +// Sidebar component props +export const sidebar: ThemeComponent<'sidebar', SidebarProps> = { + default: { + sidebar: { + themeStyleScript: sidebarStyleScript, + }, + 'sidebar toolbar filterSummary': { + title: 'Current Filters', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/termsList.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/termsList.ts new file mode 100644 index 0000000000..82e5dcc2c3 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/termsList.ts @@ -0,0 +1,29 @@ +import { css } from '@emotion/react'; +import type { TermsListProps } from '../../../../components/Organisms/TermsList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the TermsList component +const termsListStyleScript = (props: TermsListProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + backgroundColor: 'transparent', + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + '.ss__terms-list-row': { + flex: '1 1 0%', + minWidth: '1px', + }, + }); +}; + +// TermsList component props +export const termsList: ThemeComponent<'termsList', TermsListProps> = { + default: { + termsList: { + themeStyleScript: termsListStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/organisms/toolbar.ts b/packages/snap-preact/components/src/themes/everest/components/organisms/toolbar.ts new file mode 100644 index 0000000000..8370fe5eed --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/organisms/toolbar.ts @@ -0,0 +1,73 @@ +import { css } from '@emotion/react'; +import { ThemeComponent } from '../../../../providers'; +import { ToolbarProps } from '../../../../components/Organisms/Toolbar'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Toolbar component +const toolbarStyleScript = (props: ToolbarProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '.ss__layout': { + gap: `${custom.spacing.x2}px`, + margin: 0, + }, + '&[class*="bottom"]': { + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(14), + }, + }, + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(16), + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(18), + }, + }, + '& > .ss__layout > .ss__layout__row > .ss__filter-summary': { + display: 'flex', + flexFlow: 'row wrap', + '.ss__filter-summary__title, .ss__filter-summary__filters': { + minWidth: '1px', + }, + '.ss__filter-summary__title': { + flex: '0 1 auto', + padding: `0 ${custom.spacing.x2}px 0 0`, + }, + '.ss__filter-summary__filters': { + flex: '1 1 0%', + }, + '&.ss__filter-summary--inline': { + '.ss__filter-summary__title': { + paddingTop: `${custom.spacing.x1}px`, + paddingBottom: `${custom.spacing.x1}px`, + }, + }, + '&.ss__filter-summary--list': { + '.ss__filter-summary__filters': { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + gap: `${custom.spacing.x2}px`, + '.ss__filter': { + margin: 0, + }, + }, + }, + }, + }); +}; + +// Toolbar component props +export const toolbar: ThemeComponent<'toolbar', ToolbarProps> = { + default: { + toolbar: { + themeStyleScript: toolbarStyleScript, + }, + 'toolbar filterSummary': { + title: `Current Filters:`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteFixed.ts b/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteFixed.ts new file mode 100644 index 0000000000..7e1248d02c --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteFixed.ts @@ -0,0 +1,187 @@ +import { css } from '@emotion/react'; +import { autocompleteFixedThemeComponentProps } from '../../../themeComponents/autocompleteFixed'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteFixedProps } from '../../../../components/Templates/AutocompleteFixed'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteFixedStyleScript = (props: AutocompleteFixedProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + return css({ + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-fixed__inner': { + '& > .ss__search-input.autocomplete-fixed__search-input': { + height: '40px', + margin: `0 0 ${custom.spacing.x2}px 0`, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '40px', + }, + }, + '.ss__autocomplete-fixed__inner__layout-wrapper': { + maxHeight: 'none', + width: 'auto', + '&, .ss__autocomplete': { + overflowY: 'visible', + }, + '.ss__autocomplete': { + maxWidth: 'none', + width: props?.width, + right: 0, + left: '-102px', + top: 'auto', + margin: 'auto', + }, + }, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-fixed__inner': { + '.ss__autocomplete-fixed__inner__layout-wrapper': { + '.ss__autocomplete': { + maxWidth: '100%', + width: props?.width, + left: 0, + right: 0, + }, + }, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-fixed__inner': { + '.ss__autocomplete-fixed__inner__layout-wrapper': { + '.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + '& > *:nth-of-type(n+3)': { + display: 'none', + }, + }, + }, + }, + }, + }, + }, + }, + }); +}; + +export const autocompleteFixed: ThemeComponent<'autocompleteFixed', AutocompleteFixedProps> = { + default: { + ...autocompleteFixedThemeComponentProps.default, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.default?.['autocompleteFixed'] || {}), + themeStyleScript: autocompleteFixedStyleScript, + width: '900px', + layout: 'standard', + }, + 'autocompleteFixed facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocompleteFixed facetGridOptions': { + gridSize: '38px', + }, + 'autocompleteFixed facet': { + ...(autocompleteFixedThemeComponentProps.default?.['autocompleteFixed facet'] || {}), + display: { + list: { + limit: 5, + }, + hierarchy: { + limit: 5, + }, + grid: { + limit: 6, + }, + palette: { + limit: 6, + }, + }, + }, + 'autocompleteFixed results': { + rows: 2, + columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocompleteFixed button.see-more icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteFixedThemeComponentProps.mobile, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.mobile?.['autocompleteFixed'] || {}), + width: 'auto', + layout: 'mini', + }, + 'autocompleteFixed results': { + rows: 1, + columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + rows: 1, + columns: 3, + }, + }, + tablet: { + ...autocompleteFixedThemeComponentProps.tablet, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.tablet?.['autocompleteFixed'] || {}), + width: 'auto', + layout: 'standard', + }, + 'autocompleteFixed facet': { + display: { + list: { + limit: 3, + }, + hierarchy: { + limit: 3, + }, + grid: { + limit: 4, + }, + palette: { + limit: 4, + }, + }, + }, + 'autocompleteFixed results': { + rows: 1, + columns: 4, + }, + 'autocompleteFixed recommendationGrid': { + rows: 1, + columns: 4, + }, + }, + desktop: { + ...autocompleteFixedThemeComponentProps.desktop, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.desktop?.['autocompleteFixed'] || {}), + layout: 'standard', + }, + 'autocompleteFixed results': { + rows: 2, + columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteModal.ts b/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteModal.ts new file mode 100644 index 0000000000..6c01ac334d --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteModal.ts @@ -0,0 +1,204 @@ +import { css } from '@emotion/react'; +import { autocompleteModalThemeComponentProps } from '../../../themeComponents/autocompleteModal'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteModalProps } from '../../../../components/Templates/AutocompleteModal'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteModalStyleScript = (props: AutocompleteModalProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '.ss__modal': { + '&, .ss__modal__content': { + height: '100%', + }, + '.ss__modal__content': { + backgroundColor: 'transparent', + justifyContent: 'center', + '&, .ss__autocomplete-modal__inner': { + position: 'static', + display: 'flex', + flexFlow: 'column nowrap', + }, + '.ss__autocomplete-modal__inner': { + width: props?.width, + maxHeight: 'none', + height: '80vh', + overflow: 'hidden', + '& > .ss__search-input.autocomplete-modal__search-input, .ss__autocomplete': { + minHeight: '1px', + minWidth: '1px', + }, + '& > .ss__search-input.autocomplete-modal__search-input': { + flex: '0 1 auto', + height: '40px', + margin: 0, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '40px', + }, + }, + '.ss__autocomplete': { + flex: '1 1 0%', + borderWidth: 0, + overflowY: 'auto', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + maxHeight: 'none', + overflow: 'visible', + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-modal__inner': { + width: props?.width, + height: '100%', + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-modal__inner': { + '.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + '& > *:nth-of-type(n+5)': { + display: 'none', + }, + }, + }, + }, + }, + }, + }, + }); +}; + +export const autocompleteModal: ThemeComponent<'autocompleteModal', AutocompleteModalProps> = { + default: { + ...autocompleteModalThemeComponentProps.default, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.default?.['autocompleteModal'] || {}), + themeStyleScript: autocompleteModalStyleScript, + width: '70vw', + layout: 'standard', + }, + 'autocompleteModal facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocompleteModal facetGridOptions': { + gridSize: '38px', + }, + 'autocompleteModal facet': { + ...(autocompleteModalThemeComponentProps.default?.['autocompleteModal facet'] || {}), + display: { + list: { + limit: 5, + }, + hierarchy: { + limit: 5, + }, + grid: { + limit: 6, + }, + palette: { + limit: 6, + }, + }, + }, + 'autocompleteModal results': { + rows: 2, + columns: 3, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocompleteModal button.see-more icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteModalThemeComponentProps.mobile, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.mobile?.['autocompleteModal'] || {}), + width: '100%', + layout: 'mini', + }, + 'autocompleteModal results': { + rows: 2, + columns: 3, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 3, + }, + }, + tablet: { + ...autocompleteModalThemeComponentProps.tablet, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.tablet?.['autocompleteModal'] || {}), + width: '80vw', + layout: 'standard', + }, + 'autocompleteModal facet': { + display: { + list: { + limit: 3, + }, + hierarchy: { + limit: 3, + }, + grid: { + limit: 4, + }, + palette: { + limit: 4, + }, + }, + }, + 'autocompleteModal results': { + rows: 2, + columns: 4, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 4, + }, + }, + desktop: { + ...autocompleteModalThemeComponentProps.desktop, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.desktop?.['autocompleteModal'] || {}), + width: '80vw', + layout: 'standard', + }, + 'autocompleteModal results': { + rows: 2, + columns: 3, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteSlideout.ts b/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteSlideout.ts new file mode 100644 index 0000000000..580ff67d0f --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/autocompleteSlideout.ts @@ -0,0 +1,129 @@ +import { css } from '@emotion/react'; +import { autocompleteSlideoutThemeComponentProps } from '../../../themeComponents/autocompleteSlideout'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteSlideoutProps } from '../../../../components/Templates/AutocompleteSlideout'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteSlideoutStyleScript = (props: AutocompleteSlideoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + border: 0, + padding: `${custom.spacing.x4}px`, + '.ss__autocomplete-slideout__inner': { + display: 'flex', + flexFlow: 'column nowrap', + height: '100%', + '& > .ss__search-input.autocomplete-slideout__search-input, .ss__autocomplete': { + minHeight: '1px', + minWidth: '1px', + }, + '& > .ss__search-input.autocomplete-slideout__search-input': { + flex: '0 1 auto', + height: '40px', + margin: `0 0 ${custom.spacing.x2}px 0`, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '40px', + }, + }, + '.ss__autocomplete': { + flex: '1 1 0%', + alignContent: 'flex-start', + borderWidth: 0, + overflowY: 'auto', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '& > .ss__autocomplete__row .ss__autocomplete__column': { + padding: `${custom.spacing.x4}px 0`, + }, + '.ss__autocomplete__terms-wrapper, .ss__autocomplete__content, .ss__autocomplete__button--see-more': { + paddingLeft: 0, + paddingRight: 0, + }, + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + maxHeight: 'none', + overflow: 'visible', + }, + }, + }, + }); +}; + +export const autocompleteSlideout: ThemeComponent<'autocompleteSlideout', AutocompleteSlideoutProps> = { + default: { + ...autocompleteSlideoutThemeComponentProps.default, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.default?.['autocompleteSlideout'] || {}), + themeStyleScript: autocompleteSlideoutStyleScript, + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout button.see-more icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteSlideoutThemeComponentProps.mobile, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.mobile?.['autocompleteSlideout'] || {}), + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 2, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 2, + }, + }, + tablet: { + ...autocompleteSlideoutThemeComponentProps.tablet, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.tablet?.['autocompleteSlideout'] || {}), + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 3, + }, + }, + desktop: { + ...autocompleteSlideoutThemeComponentProps.desktop, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.desktop?.['autocompleteSlideout'] || {}), + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 3, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/index.ts b/packages/snap-preact/components/src/themes/everest/components/templates/index.ts new file mode 100644 index 0000000000..e6bef36cef --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/index.ts @@ -0,0 +1,79 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// TEMPLATES +import { autocompleteFixed } from './autocompleteFixed'; +import { autocompleteModal } from './autocompleteModal'; +import { autocompleteSlideout } from './autocompleteSlideout'; +import { recommendation } from './recommendation'; +import { recommendationBundle } from './recommendationBundle'; +import { recommendationBundleEasyAdd } from './recommendationBundleEasyAdd'; +import { recommendationBundleList } from './recommendationBundleList'; +import { recommendationBundleVertical } from './recommendationBundleVertical'; +import { recommendationGrid } from './recommendationGrid'; +import { recommendationEmail } from './recommendationEmail'; +import { search } from './search'; +import { searchHorizontal } from './searchHorizontal'; +import { searchCollapsible } from './searchCollapsible'; + +export const templates: ThemeResponsiveComplete = { + default: { + ...autocompleteFixed.default, + ...autocompleteModal.default, + ...autocompleteSlideout.default, + ...recommendation.default, + ...recommendationBundle.default, + ...recommendationBundleEasyAdd.default, + ...recommendationBundleList.default, + ...recommendationBundleVertical.default, + ...recommendationGrid.default, + ...recommendationEmail.default, + ...search.default, + ...searchCollapsible.default, + ...searchHorizontal.default, + }, + mobile: { + ...autocompleteFixed.mobile, + ...autocompleteModal.mobile, + ...autocompleteSlideout.mobile, + ...recommendation.mobile, + ...recommendationBundle.mobile, + ...recommendationBundleEasyAdd.mobile, + ...recommendationBundleList.mobile, + ...recommendationBundleVertical.mobile, + ...recommendationGrid.mobile, + ...recommendationEmail.mobile, + ...search.mobile, + ...searchCollapsible.mobile, + ...searchHorizontal.mobile, + }, + tablet: { + ...autocompleteFixed.tablet, + ...autocompleteModal.tablet, + ...autocompleteSlideout.tablet, + ...recommendation.tablet, + ...recommendationBundle.tablet, + ...recommendationBundleEasyAdd.tablet, + ...recommendationBundleList.tablet, + ...recommendationBundleVertical.tablet, + ...recommendationGrid.tablet, + ...recommendationEmail.tablet, + ...search.tablet, + ...searchCollapsible.tablet, + ...searchHorizontal.tablet, + }, + desktop: { + ...autocompleteFixed.desktop, + ...autocompleteModal.desktop, + ...autocompleteSlideout.desktop, + ...recommendation.desktop, + ...recommendationBundle.desktop, + ...recommendationBundleEasyAdd.desktop, + ...recommendationBundleList.desktop, + ...recommendationBundleVertical.desktop, + ...recommendationGrid.desktop, + ...recommendationEmail.desktop, + ...search.desktop, + ...searchCollapsible.desktop, + ...searchHorizontal.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendation.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendation.ts new file mode 100644 index 0000000000..5765da87c9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendation.ts @@ -0,0 +1,122 @@ +import { css } from '@emotion/react'; +import type { RecommendationProps } from '../../../../components/Templates/Recommendation'; +import { recommendationThemeComponentProps } from '../../../themeComponents/recommendation'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Recommendation component +const recommendationStyleScript = (props: RecommendationProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + const arrowSizes = { + default: 32, + tablet: 28, + mobile: 24, + }; + + return css({ + margin: `${custom.spacing.x8}px 0`, + '.ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + textAlign: 'center', + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__carousel': { + padding: `0 ${custom.spacing.x4 + arrowSizes.default}px`, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__carousel': { + padding: `0 ${custom.spacing.x4 + arrowSizes.tablet}px`, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + width: `${arrowSizes.tablet}px`, + height: `${arrowSizes.tablet}px`, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + position: 'relative', + '.ss__recommendation__title': { + textAlign: 'left', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', + paddingRight: `${arrowSizes.mobile * 2 + custom.spacing.x1 + custom.spacing.x4}px`, + }, + '.ss__carousel': { + padding: 0, + position: 'static', + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + top: '4.5px', + bottom: 'auto', + left: 'auto', + width: `${arrowSizes.mobile}px`, + height: `${arrowSizes.mobile}px`, + }, + '.ss__carousel__prev-wrapper': { + right: `${arrowSizes.mobile + custom.spacing.x1}px`, + }, + '.ss__carousel__next-wrapper': { + right: 0, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(18), + }, + '.ss__carousel': { + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + top: 0, + }, + }, + }, + }); +}; + +// Recommendation component props come from Template export +export const recommendation: ThemeComponent<'recommendation', RecommendationProps> = { + default: { + ...recommendationThemeComponentProps.default, + recommendation: { + ...(recommendationThemeComponentProps.default?.['recommendation'] || {}), + themeStyleScript: recommendationStyleScript, + spaceBetween: custom.spacing.x4, + }, + }, + mobile: { + ...recommendationThemeComponentProps.mobile, + recommendation: { + ...(recommendationThemeComponentProps.mobile?.['recommendation'] || {}), + spaceBetween: custom.spacing.x2, + }, + 'recommendation icon.prev': { + size: `${custom.sizes.icon08}px`, + }, + 'recommendation icon.next': { + size: `${custom.sizes.icon08}px`, + }, + }, + tablet: { + ...recommendationThemeComponentProps.tablet, + recommendation: { + ...(recommendationThemeComponentProps.tablet?.['recommendation'] || {}), + spaceBetween: custom.spacing.x4, + }, + 'recommendation icon.prev': { + size: `${custom.sizes.icon10}px`, + }, + 'recommendation icon.next': { + size: `${custom.sizes.icon10}px`, + }, + }, + desktop: { + ...recommendationThemeComponentProps.desktop, + recommendation: { + ...(recommendationThemeComponentProps.desktop?.['recommendation'] || {}), + spaceBetween: custom.spacing.x4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundle.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundle.ts new file mode 100644 index 0000000000..4717911471 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundle.ts @@ -0,0 +1,250 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleProps } from '../../../../components/Templates/RecommendationBundle'; +import { recommendationBundleThemeComponentProps } from '../../../themeComponents/recommendationBundle'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundle component +const recommendationBundleStyleScript = (props: RecommendationBundleProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x8}px 0`, + '.ss__recommendation-bundle__title': { + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__recommendation-bundle__wrapper': { + flexFlow: `row nowrap`, + margin: `0 -${custom.spacing.x2}px`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + padding: `0 ${custom.spacing.x2}px`, + boxSizing: 'border-box', + }, + '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__cta': { + width: `20%`, + }, + '.ss__recommendation-bundle__wrapper__carousel': { + width: `60%`, + }, + }, + '.ss__recommendation-result-tracker, .ss__recommendation-bundle__wrapper__selector, .ss__recommendation-bundle__wrapper .ss__recommendation-bundle__wrapper__selector__result-wrapper': + { + height: '100%', + margin: 0, + }, + '.ss__recommendation-bundle__wrapper__seed-container': { + '.ss__recommendation-bundle__wrapper__selector__result-wrapper__seed-badge': { + top: '5px', + left: '5px', + backgroundColor: variables?.colors?.primary, + fontSize: custom.utils.convertPxToEm(12), + fontWeight: custom.fonts.weight01, + lineHeight: `20px`, + color: custom.colors.white, + padding: `0 ${custom.spacing.x2}px`, + }, + }, + '.ss__recommendation-bundle__wrapper__selector': { + width: 'auto !important', + }, + '.ss__recommendation-bundle__wrapper__selector__result-wrapper, .ss__carousel .swiper-container > .swiper-wrapper > .swiper-slide': { + '.ss__result': { + width: '100%', + flex: '1 1 0%', + }, + }, + '.ss__recommendation-bundle__wrapper__selector__result-wrapper': { + display: 'flex', + flexFlow: `column wrap`, + '&, .ss__result': { + position: 'relative', + }, + '&:has(.ss__overlay-badge)': { + '.ss__result': { + '.ss__overlay-badge .ss__overlay-badge__grid-wrapper': { + top: '25px', + }, + }, + }, + '.ss__checkbox': { + top: '5px', + right: '5px', + }, + }, + '.ss__icon--plus': { + display: 'none', + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + margin: 'auto 0', + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle__wrapper__cta': { + position: 'relative', + paddingTop: `${custom.spacing.x4}px`, + paddingBottom: `${custom.spacing.x4}px`, + display: 'flex', + flexFlow: 'column nowrap', + justifyContent: 'center', + alignItems: 'center', + gap: `${custom.spacing.x4}px`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + margin: `0 ${custom.spacing.x2}px 0 ${custom.spacing.x4}px`, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal, .ss__recommendation-bundle__wrapper__cta__button': { + position: 'relative', + zIndex: 2, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal': { + color: variables?.colors?.text, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__prices': { + margin: `${custom.spacing.x1}px 0 0 0`, + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + '&:after': { + content: '""', + display: 'block', + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + boxSizing: 'border-box', + position: 'absolute', + top: 0, + left: '10px', + right: 0, + bottom: 0, + zIndex: 1, + margin: 'auto', + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__recommendation-bundle__wrapper': { + '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__cta': { + width: `25%`, + }, + '.ss__recommendation-bundle__wrapper__carousel': { + width: `50%`, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle__wrapper': { + flexFlow: 'row wrap', + width: 'auto', + maxWidth: 'none', + margin: `0 -${custom.spacing.x1}px`, + '& > *': { + padding: `0 ${custom.spacing.x1}px`, + }, + '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__carousel': { + width: `50%`, + }, + }, + '.ss__recommendation-bundle__wrapper__cta': { + width: 'auto', + margin: `${custom.spacing.x4}px 0 0 0`, + padding: `${custom.spacing.x4}px`, + '& > *': { + margin: 0, + }, + '&:after': { + left: 0, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__recommendation-bundle__title': { + fontSize: custom.utils.convertPxToEm(18), + }, + }, + }); +}; + +// RecommendationBundle component props come from Template export +export const recommendationBundle: ThemeComponent<'recommendationBundle', RecommendationBundleProps> = { + default: { + ...recommendationBundleThemeComponentProps.default, + recommendationBundle: { + ...(recommendationBundleThemeComponentProps.default?.['recommendationBundle'] || {}), + themeStyleScript: recommendationBundleStyleScript, + }, + 'recommendationBundle icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + 'recommendationBundle icon.bundle-selector': { + icon: custom.icons.plus, + size: `${custom.sizes.icon14}px`, + }, + 'recommendationBundle carousel': { + spaceBetween: custom.spacing.x4, + }, + }, + mobile: { + ...recommendationBundleThemeComponentProps.mobile, + 'recommendationBundle carousel': { + spaceBetween: 0, + }, + }, + tablet: { + ...recommendationBundleThemeComponentProps.tablet, + 'recommendationBundle carousel': { + spaceBetween: custom.spacing.x4, + }, + }, + desktop: { + ...recommendationBundleThemeComponentProps.desktop, + 'recommendationBundle carousel': { + spaceBetween: custom.spacing.x4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleEasyAdd.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleEasyAdd.ts new file mode 100644 index 0000000000..0a4272b23d --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleEasyAdd.ts @@ -0,0 +1,134 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleEasyAddProps } from '../../../../components/Templates/RecommendationBundleEasyAdd'; +import { recommendationBundleEasyAddThemeComponentProps } from '../../../themeComponents/recommendationBundleEasyAdd'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleEasyAdd component +const recommendationBundleEasyAddStyleScript = (props: RecommendationBundleEasyAddProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x4}px 0`, + '.ss__recommendation-profile-tracker': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + }, + '.ss__recommendation-bundle-easy-add__title': { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle-easy-add__wrapper': { + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + '& > div': { + width: '50%', + minWidth: '1px', + flex: '0 1 auto', + boxSizing: 'border-box', + }, + '.ss__recommendation-bundle-easy-add__wrapper__selector__result-wrapper, .ss__recommendation-bundle-easy-add__wrapper__cta': { + margin: 0, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta': { + padding: `${custom.spacing.x4}px`, + width: 'auto', + display: 'flex', + flexFlow: 'column nowrap', + justifyContent: 'center', + alignItems: 'center', + gap: `${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal': { + color: variables?.colors?.text, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__prices': { + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle-easy-add__wrapper': { + flexFlow: 'row wrap', + '& > div': { + width: 'auto', + flex: '1 1 100%', + }, + }, + }, + }); +}; + +// RecommendationBundleEasyAdd component props come from Template export +export const recommendationBundleEasyAdd: ThemeComponent<'recommendationBundleEasyAdd', RecommendationBundleEasyAddProps> = { + default: { + ...recommendationBundleEasyAddThemeComponentProps.default, + recommendationBundleEasyAdd: { + ...(recommendationBundleEasyAddThemeComponentProps.default?.['recommendationBundleEasyAdd'] || {}), + themeStyleScript: recommendationBundleEasyAddStyleScript, + ctaInline: true, + }, + 'recommendationBundleEasyAdd icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + }, + mobile: { + ...recommendationBundleEasyAddThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleEasyAddThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleEasyAddThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleList.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleList.ts new file mode 100644 index 0000000000..d66f9abdf6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleList.ts @@ -0,0 +1,177 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleListProps } from '../../../../components/Templates/RecommendationBundleList'; +import { recommendationBundleListThemeComponentProps } from '../../../themeComponents/recommendationBundleList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleEasyAdd component +const recommendationBundleListStyleScript = (props: RecommendationBundleListProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x4}px 0`, + '.ss__recommendation-profile-tracker': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + }, + '.ss__recommendation-bundle-list__title': { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle-list__wrapper': { + flexFlow: 'row wrap', + margin: `0 -${custom.spacing.x1}px`, + '&, & > div': { + boxSizing: 'border-box', + }, + '& > div': { + width: '50%', + minWidth: '1px', + flex: '0 1 auto', + padding: `0 ${custom.spacing.x1}px`, + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper': { + margin: 0, + gap: `${custom.spacing.x2}px`, + '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper__checkbox, .ss__result': { + minWidth: '1px', + }, + '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper__checkbox': { + flex: '0 1 auto', + }, + '.ss__result': { + flex: '1 1 0%', + '.ss__result__image-wrapper': { + display: 'none', + }, + '.ss__result__details': { + gap: 0, + }, + }, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta': { + '.ss__recommendation-bundle-list__wrapper__cta__inner': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + lineHeight: 1, + }, + '.ss__recommendation-bundle-list__wrapper__cta__inner__images': { + flexFlow: 'row nowrap', + gap: `${custom.spacing.x2 + custom.sizes.icon12}px`, + '.ss__recommendation-bundle-list__wrapper__cta__inner__image-wrapper': { + flex: '1 1 0%', + minWidth: '1px', + padding: 0, + '.ss__icon': { + top: 0, + bottom: 0, + right: `-${custom.spacing.x2 / 2 + custom.sizes.icon12}px`, + margin: 'auto 0', + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal': { + padding: `${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__prices': { + margin: `${custom.spacing.x1}px 0 0 0`, + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + }, + '.ss__recommendation-bundle-list__cta__button__wrapper': { + margin: `${custom.spacing.x4}px 0`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle-list__wrapper': { + '& > div': { + width: 'auto', + flex: '1 1 100%', + }, + }, + }, + }); +}; + +// RecommendationBundleList component props come from Template export +export const recommendationBundleList: ThemeComponent<'recommendationBundleList', RecommendationBundleListProps> = { + default: { + ...recommendationBundleListThemeComponentProps.default, + recommendationBundleList: { + ...(recommendationBundleListThemeComponentProps.default?.['recommendationBundleList'] || {}), + themeStyleScript: recommendationBundleListStyleScript, + separatorIconSeedOnly: false, + }, + 'recommendationBundleList icon.bundle-cart-separator': { + icon: custom.icons.plus, + size: `${custom.sizes.icon12}px`, + }, + 'recommendationBundleList icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + 'recommendationBundleList result': { + hideImage: true, + hideBadge: true, + }, + }, + mobile: { + ...recommendationBundleListThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleListThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleListThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleVertical.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleVertical.ts new file mode 100644 index 0000000000..dba4de8607 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationBundleVertical.ts @@ -0,0 +1,159 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleVerticalProps } from '../../../../components/Templates/RecommendationBundleVertical'; +import { recommendationBundleVerticalThemeComponentProps } from '../../../themeComponents/recommendationBundleVertical'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleVertical component +const recommendationBundleVerticalStyleScript = (props: RecommendationBundleVerticalProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x4}px 0`, + '.ss__recommendation-profile-tracker': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + }, + '.ss__recommendation-bundle-vertical__title': { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle-vertical__wrapper': { + gap: `${custom.spacing.x4}px`, + '& > div': { + minWidth: '1px', + flex: '1 1 100%', + }, + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper': { + margin: 0, + '&, .ss__result': { + position: 'relative', + }, + '&:has(.ss__overlay-badge)': { + '.ss__result': { + '.ss__overlay-badge .ss__overlay-badge__grid-wrapper': { + top: '25px', + }, + }, + }, + '.ss__checkbox': { + top: '5px', + right: '5px', + }, + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper__seed-badge': { + top: '5px', + left: '5px', + backgroundColor: variables?.colors?.primary, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight01, + lineHeight: `24px`, + color: custom.colors.white, + padding: `0 ${custom.spacing.x2}px`, + }, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta': { + padding: `${custom.spacing.x4}px`, + width: 'auto', + display: 'flex', + flexFlow: 'column nowrap', + justifyContent: 'center', + alignItems: 'center', + gap: `${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal': { + color: variables?.colors?.text, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__prices': { + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle-vertical__wrapper': { + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper': { + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper__seed-badge': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: `20px`, + }, + }, + }, + }, + }); +}; + +// RecommendationBundleVertical component props come from Template export +export const recommendationBundleVertical: ThemeComponent<'recommendationBundleVertical', RecommendationBundleVerticalProps> = { + default: { + ...recommendationBundleVerticalThemeComponentProps.default, + recommendationBundleVertical: { + ...(recommendationBundleVerticalThemeComponentProps.default?.['recommendationBundleVertical'] || {}), + themeStyleScript: recommendationBundleVerticalStyleScript, + }, + 'recommendationBundleVertical icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + 'recommendationBundleVertical icon.bundle-selector': { + icon: custom.icons.plus, + size: `${custom.sizes.icon14}px`, + }, + }, + mobile: { + ...recommendationBundleVerticalThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleVerticalThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleVerticalThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendationEmail.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationEmail.ts new file mode 100644 index 0000000000..c87c85f658 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationEmail.ts @@ -0,0 +1,52 @@ +import { css } from '@emotion/react'; +import type { RecommendationEmailProps } from '../../../../components/Templates/RecommendationEmail'; +import { recommendationEmailThemeComponentProps } from '../../../themeComponents/recommendationEmail'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationEmail component +const recommendationEmailStyleScript = (props: RecommendationEmailProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + width: '400px !important', + height: '680px', + margin: `0 0 ${custom.spacing.x6}px 0`, + padding: `0 ${custom.spacing.x2}px`, + overflow: 'hidden', + '.ss__result': { + fontSize: '16px', + '.ss__result__details .ss__result__details__title a': { + display: 'block', + height: '26px', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }, + }); +}; + +// RecommendationEmail component props come from Template export +export const recommendationEmail: ThemeComponent<'recommendationEmail', RecommendationEmailProps> = { + default: { + ...recommendationEmailThemeComponentProps.default, + recommendationEmail: { + ...(recommendationEmailThemeComponentProps.default?.['recommendationEmail'] || {}), + themeStyleScript: recommendationEmailStyleScript, + }, + 'recommendationEmail image': { + lazy: false, + }, + }, + mobile: { + ...recommendationEmailThemeComponentProps.mobile, + }, + tablet: { + ...recommendationEmailThemeComponentProps.tablet, + }, + desktop: { + ...recommendationEmailThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/recommendationGrid.ts b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationGrid.ts new file mode 100644 index 0000000000..d14e34a467 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/recommendationGrid.ts @@ -0,0 +1,72 @@ +import { css } from '@emotion/react'; +import type { RecommendationGridProps } from '../../../../components/Templates/RecommendationGrid'; +import { recommendationGridThemeComponentProps } from '../../../themeComponents/recommendationGrid'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundle component +const recommendationGridStyleScript = (props: RecommendationGridProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x8}px 0`, + maxHeight: 'none', + '.ss__recommendation-grid__title': { + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + textAlign: 'center', + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__recommendation-grid__results': { + overflowX: 'auto', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-grid__title': { + textAlign: 'left', + }, + }, + }); +}; + +// RecommendationGrid component props come from Template export +export const recommendationGrid: ThemeComponent<'recommendationGrid', RecommendationGridProps> = { + default: { + ...recommendationGridThemeComponentProps.default, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.default?.['recommendationGrid'] || {}), + themeStyleScript: recommendationGridStyleScript, + gapSize: `${custom.spacing.x6}px ${custom.spacing.x4}px`, + columns: 4, + }, + }, + mobile: { + ...recommendationGridThemeComponentProps.mobile, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.mobile?.['recommendationGrid'] || {}), + gapSize: `${custom.spacing.x6}px ${custom.spacing.x2}px`, + columns: 2, + }, + }, + tablet: { + ...recommendationGridThemeComponentProps.tablet, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.tablet?.['recommendationGrid'] || {}), + columns: 3, + }, + }, + desktop: { + ...recommendationGridThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/search.ts b/packages/snap-preact/components/src/themes/everest/components/templates/search.ts new file mode 100644 index 0000000000..3e2a9488ea --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/search.ts @@ -0,0 +1,80 @@ +import { css } from '@emotion/react'; +import type { SearchProps } from '../../../../components/Templates/Search'; +import { searchThemeComponentProps } from '../../../themeComponents/search'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchStyleScript = (props: SearchProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '&.ss__search--sidebar-open': { + '.ss__button': { + '.ss__icon--filter': { + transform: 'rotate(-180deg)', + }, + '.ss__icon--filters': { + circle: { + '&:last-child': { + transform: 'translateX(-35%)', + }, + transform: 'translateX(35%)', + }, + }, + }, + }, + '.ss__search__header-section, .ss__search__main-section': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '.ss__toolbar .ss__layout': { + gap: `${custom.spacing.x4}px`, + }, + }, + '.ss__search__main-section': { + gap: `${custom.spacing.x6}px`, + '.ss__search__sidebar, .ss__search__content': { + minWidth: '1px', + }, + '.ss__search__sidebar': { + flex: '0 1 auto', + }, + '.ss__search__content': { + flex: '1 1 0%', + gap: `${custom.spacing.x4}px`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__search__main-section': { + '.ss__toolbar': { + '.ss__select': { + flex: '1 1 0%', + }, + }, + }, + }, + }); +}; + +// Search component props come from Template export +export const search: ThemeComponent<'search', SearchProps> = { + default: { + ...searchThemeComponentProps.default, + search: { + ...(searchThemeComponentProps.default?.['search'] || {}), + themeStyleScript: searchStyleScript, + }, + 'search filterSummary': { + type: 'list', + }, + }, + mobile: { + ...searchThemeComponentProps.mobile, + }, + tablet: { + ...searchThemeComponentProps.tablet, + }, + desktop: { + ...searchThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/searchCollapsible.ts b/packages/snap-preact/components/src/themes/everest/components/templates/searchCollapsible.ts new file mode 100644 index 0000000000..bff1a4fc4a --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/searchCollapsible.ts @@ -0,0 +1,88 @@ +import { css } from '@emotion/react'; +import type { SearchCollapsibleProps } from '../../../../components/Templates/SearchCollapsible'; +import { searchCollapsibleThemeComponentProps } from '../../../themeComponents/searchCollapsible'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchCollapsibleStyleScript = (props: SearchCollapsibleProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '&.ss__search-collapsible--sidebar-open': { + '.ss__button': { + '.ss__icon--filter': { + transform: 'rotate(-180deg)', + }, + '.ss__icon--filters': { + circle: { + '&:last-child': { + transform: 'translateX(-35%)', + }, + transform: 'translateX(35%)', + }, + }, + }, + }, + '.ss__search-collapsible__header-section, .ss__search-collapsible__main-section': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '.ss__toolbar .ss__layout': { + gap: `${custom.spacing.x4}px`, + }, + }, + '.ss__search-collapsible__header-section': { + '.ss__search-header': { + textAlign: 'center', + }, + }, + '.ss__search-collapsible__main-section': { + gap: `${custom.spacing.x6}px`, + '.ss__search-collapsible__sidebar, .ss__search-collapsible__content': { + minWidth: '1px', + }, + '.ss__search-collapsible__sidebar': { + flex: '0 1 auto', + }, + '.ss__search-collapsible__content': { + flex: '1 1 0%', + gap: `${custom.spacing.x4}px`, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__toolbar': { + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(16), + }, + }, + }, + }); +}; + +export const searchCollapsible: ThemeComponent<'searchCollapsible', SearchCollapsibleProps> = { + default: { + ...searchCollapsibleThemeComponentProps.default, + searchCollapsible: { + ...(searchCollapsibleThemeComponentProps.default?.['searchCollapsible'] || {}), + themeStyleScript: searchCollapsibleStyleScript, + }, + 'searchCollapsible sidebar': { + hideTitleText: true, + }, + 'searchCollapsible button.sidebar-toggle': { + icon: custom.icons.filter, + }, + 'searchCollapsible filterSummary': { + type: 'list', + }, + }, + mobile: { + ...searchCollapsibleThemeComponentProps.mobile, + }, + tablet: { + ...searchCollapsibleThemeComponentProps.tablet, + }, + desktop: { + ...searchCollapsibleThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/components/templates/searchHorizontal.ts b/packages/snap-preact/components/src/themes/everest/components/templates/searchHorizontal.ts new file mode 100644 index 0000000000..3501da121b --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/components/templates/searchHorizontal.ts @@ -0,0 +1,78 @@ +import { css } from '@emotion/react'; +import type { SearchHorizontalProps } from '../../../../components/Templates/SearchHorizontal'; +import { searchHorizontalThemeComponentProps } from '../../../themeComponents/searchHorizontal'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchHorizontalStyleScript = (props: SearchHorizontalProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '.ss__search-horizontal__header-section, .ss__search-horizontal__main-section': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '.ss__toolbar .ss__layout': { + gap: `${custom.spacing.x4}px`, + '.ss__layout__row': { + '&:has(.ss__facets-horizontal)': { + alignItems: 'flex-start', + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__facets-horizontal': { + flex: '1 1 0%', + }, + }, + }, + }, + }, + '.ss__search-horizontal__header-section': { + '.ss__search-header': { + textAlign: 'center', + }, + }, + '.ss__search-horizontal__main-section': { + gap: `${custom.spacing.x6}px`, + '.ss__search-horizontal__sidebar, .ss__search-horizontal__content': { + minWidth: '1px', + }, + '.ss__search-horizontal__sidebar': { + flex: '0 1 auto', + }, + '.ss__search-horizontal__content': { + flex: '1 1 0%', + gap: `${custom.spacing.x4}px`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__search-horizontal__main-section': { + '.ss__toolbar': { + '.ss__select': { + flex: '1 1 0%', + }, + }, + }, + }, + }); +}; + +export const searchHorizontal: ThemeComponent<'searchHorizontal', SearchHorizontalProps> = { + default: { + ...searchHorizontalThemeComponentProps.default, + searchHorizontal: { + ...(searchHorizontalThemeComponentProps.default?.['searchHorizontal'] || {}), + themeStyleScript: searchHorizontalStyleScript, + }, + }, + mobile: { + ...searchHorizontalThemeComponentProps.mobile, + }, + tablet: { + ...searchHorizontalThemeComponentProps.tablet, + }, + desktop: { + ...searchHorizontalThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/custom.ts b/packages/snap-preact/components/src/themes/everest/custom.ts new file mode 100644 index 0000000000..854c2f26be --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/custom.ts @@ -0,0 +1,108 @@ +import { IconType } from '../../components/Atoms/Icon'; +import Color from 'color'; + +// calculate spacing +const spacing = 5; +const spacingCalc = (value: number) => { + return spacing * value; +}; + +export const custom: { + breakpoints: { + [key: string]: number; + }; + colors: { + [key: string]: string; + }; + fonts: { + [key: string]: any; + }; + icons: { + [key: string]: IconType; + }; + sizes: { + [key: string]: number; + }; + spacing: { + [key: string]: number; + }; + utils: { + convertPxToEm: (value: number) => string; + lightenColor: (color: string | undefined, amount: number) => string; + darkenColor: (color: string | undefined, amount: number) => string; + }; +} = { + breakpoints: { + small: 540, + mobile: 767, + tablet: 1024, + desktop: 1280, + }, + colors: { + white: '#ffffff', + black: '#000000', + gray01: '#f8f8f8', // lighter gray: bg color under terms, dropdown, checkboxes + gray02: '#ebebeb', // light gray: borders for autocomplete, dropdown, checkboxes + brown: '#845329', // for color palette + purple: '#7c368e', // for color palette + rainbow: + 'linear-gradient(rgb(40, 87, 218) 20%, rgb(40, 218, 70) 20%, rgb(40, 218, 70) 40%, rgb(245, 228, 24) 40%, rgb(245, 228, 24) 60%, rgb(242, 133, 0) 60%, rgb(242, 133, 0) 80%, rgb(218, 40, 72) 80%, rgb(218, 40, 72))', // for color palette + }, + fonts: { + weight01: 700, // main font weight + weight02: 700, // header font weight + style: false, + transform: 'uppercase', + }, + icons: { + arrowLeft: 'chevron-left', + arrowRight: 'chevron-right', + arrowDown: 'chevron-down', + arrowUp: 'chevron-up', + bag: 'bag', + check: 'square', + close: 'close', + minus: 'minus', + plus: 'plus', + filter: 'filter', + filters: 'filters', + search: 'search', + sort: 'sort', + }, + sizes: { + font: 16, // base font size + height: 35, // refers to height for button and dropdown sizes + icon08: 8, + icon10: 10, + icon12: 12, + icon14: 14, + icon16: 16, + radius: 3, // global border radius value + }, + spacing: { + x1: spacing, + x2: spacingCalc(2), + x3: spacingCalc(3), + x4: spacingCalc(4), + x5: spacingCalc(5), + x6: spacingCalc(6), + x7: spacingCalc(7), + x8: spacingCalc(8), + }, + utils: { + convertPxToEm: (value: number) => { + // translates px to rem + return `${value / custom.sizes.font}rem`; + }, + lightenColor: (color: string | undefined, amount: number) => { + // lighten a color + const lightColor = new Color(color || '#515151').lighten(amount).hex().toLowerCase(); + return lightColor; + }, + darkenColor: (color: string | undefined, amount: number) => { + // darken a color + const darkColor = new Color(color || '#515151').darken(amount).hex().toLowerCase(); + return darkColor; + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/everest/everest.ts b/packages/snap-preact/components/src/themes/everest/everest.ts new file mode 100644 index 0000000000..13771cc908 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/everest.ts @@ -0,0 +1,24 @@ +import { ThemeComplete, ThemeVariables } from '../../providers'; +import { components } from './components'; +import { responsive } from './responsive'; + +const everestVariables: ThemeVariables = { + breakpoints: { + mobile: 767, + tablet: 991, + desktop: 1199, + }, + colors: { + text: '#515151', + primary: '#d15120', + secondary: '#94280b', + accent: '#a8391c', + }, +}; + +export const everest: ThemeComplete = { + name: 'everest', + variables: everestVariables, + components, + responsive, +}; diff --git a/packages/snap-preact/components/src/themes/everest/responsive.ts b/packages/snap-preact/components/src/themes/everest/responsive.ts new file mode 100644 index 0000000000..61ae08bfe4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/everest/responsive.ts @@ -0,0 +1,8 @@ +import { ThemeResponsive } from '../../providers/theme'; +import { mobileComponents, tabletComponents, desktopComponents } from './components'; + +export const responsive: ThemeResponsive = { + mobile: mobileComponents, + tablet: tabletComponents, + desktop: desktopComponents, +}; diff --git a/packages/snap-preact/components/src/themes/index.ts b/packages/snap-preact/components/src/themes/index.ts index fe1bf6ae52..b668ce1ffe 100644 --- a/packages/snap-preact/components/src/themes/index.ts +++ b/packages/snap-preact/components/src/themes/index.ts @@ -1,4 +1,7 @@ export * from './base/base'; export * from './bocachica/bocachica'; -export * from './snappy/snappy'; +export * from './everest/everest'; +export * from './matterhorn/matterhorn'; +export * from './pike/pike'; export * from './snapnco/snapnco'; +export * from './snappy/snappy'; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/breadcrumbs.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/breadcrumbs.ts new file mode 100644 index 0000000000..c1436cbbf9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/breadcrumbs.ts @@ -0,0 +1,46 @@ +import { css } from '@emotion/react'; +import type { BreadcrumbsProps } from '../../../../components/Atoms/Breadcrumbs'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Breadcrumbs component +const breadcrumbsStyleScript = (props: BreadcrumbsProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__breadcrumbs__crumbs': { + margin: `0 -${custom.spacing.x1}px`, + '&, li': { + listStyle: 'none', + }, + '&, a': { + color: variables?.colors?.text, + }, + li: { + display: 'block', + padding: `0 ${custom.spacing.x1}px`, + '&:last-of-type': { + color: variables?.colors?.primary, + fontWeight: custom?.fonts?.weight01, + }, + }, + '.ss__breadcrumbs__crumbs__separator': { + '.ss__icon': { + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + }, + }, + }, + }); +}; + +// Breadcrumbs component props +export const breadcrumbs: ThemeComponent<'breadcrumbs', BreadcrumbsProps> = { + default: { + breadcrumbs: { + themeStyleScript: breadcrumbsStyleScript, + separator: false, + separatorIcon: custom.icons.arrowRight, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/button.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/button.ts new file mode 100644 index 0000000000..3ce996b7c1 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/button.ts @@ -0,0 +1,75 @@ +import { css } from '@emotion/react'; +import type { ButtonProps } from '../../../../components/Atoms/Button'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the Button component +const buttonStyleScript = (props: ButtonProps) => { + const variables = props?.theme?.variables; + const buttonDisabledSelectors = '&.ss__button--disabled'; + const buttonSelector = `&, &:hover, &:not(.ss__button--disabled):hover, ${buttonDisabledSelectors}`; + const buttonColor = new Color(props?.backgroundColor || variables?.colors?.primary || undefined); + const fontColor = buttonColor.isDark() || buttonColor.hex().toLowerCase() == '#00aeef' ? Color(custom.colors.white) : Color(custom.colors.black); + + // shared button styles + const disabledStyles = css({ + [buttonDisabledSelectors]: { + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }, + }); + + // default styles + const defaultStyles = css([ + { + boxSizing: 'border-box', + cursor: 'pointer', + display: 'inline-flex', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + position: 'relative', + padding: `0 ${custom.spacing.x4}px`, + color: fontColor.hex(), + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight01, + textAlign: 'center', + textTransform: custom.fonts.transform, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + [buttonSelector]: { + border: `1px solid ${buttonColor.hex()}`, + borderRadius: `${custom.sizes.radius}px`, + backgroundColor: buttonColor.hex(), + }, + '.ss__icon': { + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + flex: `0 0 ${custom.sizes.icon12}px`, + }, + '.ss__icon--filters': { + circle: { + fill: buttonColor.hex(), + }, + }, + }, + disabledStyles, + ]); + + return defaultStyles; +}; + +// Button component props +export const button: ThemeComponent<'button', ButtonProps> = { + default: { + button: { + themeStyleScript: buttonStyleScript, + native: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/dropdown.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/dropdown.ts new file mode 100644 index 0000000000..93eed8788c --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/dropdown.ts @@ -0,0 +1,40 @@ +import { css } from '@emotion/react'; +import type { DropdownProps } from '../../../../components/Atoms/Dropdown'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Dropdown component +const dropdownStyleScript = ({ theme }: DropdownProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = theme?.variables; + + return css({ + width: 'auto', + '&:not(.ss__facet__dropdown)': { + '&.ss__dropdown--open': { + '.ss__dropdown__content': { + zIndex: 200, + }, + }, + }, + '&.ss__dropdown--open': { + '.ss__dropdown__content': { + zIndex: 5, + }, + }, + '.ss__dropdown__content': { + minWidth: '1px', + left: 0, + right: 0, + zIndex: -1, + }, + }); +}; + +// Dropdown component props +export const dropdown: ThemeComponent<'dropdown', DropdownProps> = { + default: { + dropdown: { + themeStyleScript: dropdownStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/icon.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/icon.ts new file mode 100644 index 0000000000..851bb434aa --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/icon.ts @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { IconProps } from '../../../../components/Atoms/Icon'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Icon component +const iconStyleScript = (props: IconProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + fill: 'currentColor', + stroke: 'currentColor', + }); +}; + +// Icon component props +export const icon: ThemeComponent<'icon', IconProps> = { + default: { + icon: { + themeStyleScript: iconStyleScript, + size: `${custom.sizes.icon16}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/image.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/image.ts new file mode 100644 index 0000000000..defdd577c6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/image.ts @@ -0,0 +1,46 @@ +import { css } from '@emotion/react'; +import type { ImageProps } from '../../../../components/Atoms/Image'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Image component +const imageStyleScript = (props: ImageProps & { visibility: React.CSSProperties['visibility'] }) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '&.ss__result__image': { + position: 'relative', + lineHeight: 0, + height: 0, + padding: '0 0 100% 0', + overflow: 'hidden', + '&, img': { + display: 'block', + }, + img: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + width: '100%', + height: '100%', + maxWidth: '100%', + maxHeight: '100%', + border: 0, + objectFit: 'contain', + objectPosition: 'center center', + }, + }, + }); +}; + +// Image component props +export const image: ThemeComponent<'image', ImageProps> = { + default: { + image: { + themeStyleScript: imageStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/index.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/index.ts new file mode 100644 index 0000000000..0c9983f793 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/index.ts @@ -0,0 +1,69 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// ATOMS Imports +import { breadcrumbs } from './breadcrumbs'; +import { button } from './button'; +import { dropdown } from './dropdown'; +import { icon } from './icon'; +import { image } from './image'; +import { loadingBar } from './loadingBar'; +import { overlay } from './overlay'; +import { paginationInfo } from './paginationInfo'; +import { price } from './price'; +import { searchHeader } from './searchHeader'; +import { skeleton } from './skeleton'; + +export const atoms: ThemeResponsiveComplete = { + default: { + ...breadcrumbs.default, + ...button.default, + ...dropdown.default, + ...icon.default, + ...image.default, + ...loadingBar.default, + ...overlay.default, + ...price.default, + ...searchHeader.default, + ...skeleton.default, + ...paginationInfo.default, + }, + mobile: { + ...breadcrumbs.mobile, + ...button.mobile, + ...dropdown.mobile, + ...icon.mobile, + ...image.mobile, + ...loadingBar.mobile, + ...overlay.mobile, + ...price.mobile, + ...searchHeader.mobile, + ...skeleton.mobile, + ...paginationInfo.mobile, + }, + tablet: { + ...breadcrumbs.tablet, + ...button.tablet, + ...dropdown.tablet, + ...icon.tablet, + ...image.tablet, + ...loadingBar.tablet, + ...overlay.tablet, + ...price.tablet, + ...searchHeader.tablet, + ...skeleton.tablet, + ...paginationInfo.tablet, + }, + desktop: { + ...breadcrumbs.desktop, + ...button.desktop, + ...dropdown.desktop, + ...icon.desktop, + ...image.desktop, + ...loadingBar.desktop, + ...overlay.desktop, + ...price.desktop, + ...searchHeader.desktop, + ...skeleton.desktop, + ...paginationInfo.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/loadingBar.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/loadingBar.ts new file mode 100644 index 0000000000..750f1917bb --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/loadingBar.ts @@ -0,0 +1,24 @@ +import { css } from '@emotion/react'; +import type { LoadingBarProps } from '../../../../components/Atoms/Loading'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the LoadingBar component +const loadingBarStyleScript = (props: LoadingBarProps) => { + const variables = props?.theme?.variables; + + return css({ + background: variables?.colors?.primary, + '.ss__loading-bar__bar': { + background: variables?.colors?.secondary, + }, + }); +}; + +// LoadingBar component props +export const loadingBar: ThemeComponent<'loadingBar', LoadingBarProps> = { + default: { + loadingBar: { + themeStyleScript: loadingBarStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/overlay.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/overlay.ts new file mode 100644 index 0000000000..fbdce26542 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/overlay.ts @@ -0,0 +1,24 @@ +import { css } from '@emotion/react'; +import type { OverlayProps } from '../../../../components/Atoms/Overlay'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Overlay component +const overlayStyleScript = (props: OverlayProps) => { + const backgroundColor = props?.color || 'rgba(0, 0, 0, 0.80)'; + + return css({ + cursor: 'pointer', + '&, &.ss__overlay--active': { + background: backgroundColor, + }, + }); +}; + +// Overlay component props +export const overlay: ThemeComponent<'overlay', OverlayProps> = { + default: { + overlay: { + themeStyleScript: overlayStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/paginationInfo.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/paginationInfo.ts new file mode 100644 index 0000000000..020e341105 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/paginationInfo.ts @@ -0,0 +1,23 @@ +import { css } from '@emotion/react'; +import type { PaginationInfoProps } from '../../../../components/Atoms/PaginationInfo'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Pagination component +const paginationInfoStyleScript = ({ theme }: PaginationInfoProps) => { + const variables = theme?.variables; + + return css({ + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }); +}; + +// PaginationInfo component props +export const paginationInfo: ThemeComponent<'paginationInfo', PaginationInfoProps> = { + default: { + paginationInfo: { + themeStyleScript: paginationInfoStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/price.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/price.ts new file mode 100644 index 0000000000..32bb151d0b --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/price.ts @@ -0,0 +1,27 @@ +import { css } from '@emotion/react'; +import type { PriceProps } from '../../../../components/Atoms/Price'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Price component +const priceStyleScript = (props: PriceProps) => { + const variables = props?.theme?.variables; + + return css({ + '&, span, &.ss__price, &.ss__price--strike': { + color: variables?.colors?.text, + }, + '& ~ .ss__result__price': { + paddingLeft: `${custom.spacing.x1 / 2}px`, + }, + }); +}; + +// Price component props +export const price: ThemeComponent<'price', PriceProps> = { + default: { + price: { + themeStyleScript: priceStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/searchHeader.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/searchHeader.ts new file mode 100644 index 0000000000..d72852e4ee --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/searchHeader.ts @@ -0,0 +1,42 @@ +import { css } from '@emotion/react'; +import type { SearchHeaderProps } from '../../../../components/Atoms/SearchHeader'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the SearchHeader component +const searchHeaderStyleScript = (props: SearchHeaderProps) => { + const variables = props?.theme?.variables; + + return css({ + em: { + fontStyle: 'normal', + }, + '.ss__search-header__title': { + margin: 0, + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__search-header__subtitle': { + margin: `${custom.spacing.x2}px 0 0 0`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: 400, + color: variables?.colors?.text, + a: { + color: variables?.colors?.secondary, + }, + }, + '.ss__search-header__results-query': { + color: variables?.colors?.primary, + }, + }); +}; + +// SearchHeader component props +export const searchHeader: ThemeComponent<'searchHeader', SearchHeaderProps> = { + default: { + searchHeader: { + themeStyleScript: searchHeaderStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/atoms/skeleton.ts b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/skeleton.ts new file mode 100644 index 0000000000..62b8061415 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/atoms/skeleton.ts @@ -0,0 +1,13 @@ +import type { SkeletonProps } from '../../../../components/Atoms/Skeleton'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// Skeleton component props +export const skeleton: ThemeComponent<'skeleton', SkeletonProps> = { + default: { + skeleton: { + backgroundColor: custom.colors.gray02, + animatedColor: custom.colors.gray01, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/index.ts b/packages/snap-preact/components/src/themes/matterhorn/components/index.ts new file mode 100644 index 0000000000..b431ef8ce6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/index.ts @@ -0,0 +1,34 @@ +import { atoms } from './atoms'; +import { molecules } from './molecules'; +import { organisms } from './organisms'; +import { templates } from './templates'; + +import type { ThemeComponentsRestricted } from '../../../providers'; + +export const components: ThemeComponentsRestricted = { + ...atoms.default, + ...molecules.default, + ...organisms.default, + ...templates.default, +}; + +export const mobileComponents: ThemeComponentsRestricted = { + ...atoms.mobile, + ...molecules.mobile, + ...organisms.mobile, + ...templates.mobile, +}; + +export const tabletComponents: ThemeComponentsRestricted = { + ...atoms.tablet, + ...molecules.tablet, + ...organisms.tablet, + ...templates.tablet, +}; + +export const desktopComponents: ThemeComponentsRestricted = { + ...atoms.desktop, + ...molecules.desktop, + ...organisms.desktop, + ...templates.desktop, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/calloutBadge.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/calloutBadge.ts new file mode 100644 index 0000000000..367766c736 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/calloutBadge.ts @@ -0,0 +1,31 @@ +import { css } from '@emotion/react'; +import type { CalloutBadgeProps } from '../../../../components/Molecules/CalloutBadge'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const calloutBadgeStyleScript = () => { + return css({ + gap: `${custom.spacing.x2}px`, + '& > div': { + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + lineHeight: 1, + span: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + '.ss__badge-text': { + padding: `0`, + }, + }); +}; + +// CalloutBadge component props +export const calloutBadge: ThemeComponent<'calloutBadge', CalloutBadgeProps> = { + default: { + calloutBadge: { + themeStyleScript: calloutBadgeStyleScript, + limit: 3, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/carousel.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/carousel.ts new file mode 100644 index 0000000000..c1b097655d --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/carousel.ts @@ -0,0 +1,119 @@ +import { css } from '@emotion/react'; +import type { CarouselProps } from '../../../../components/Molecules/Carousel'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Carousel component +const carouselStyleScript = (props: CarouselProps) => { + const variables = props?.theme?.variables; + + // shared button styles + const disabledStyles = css({ + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }); + + return css({ + position: 'relative', + '.ss__carousel__prev-wrapper--hidden > div, .ss__carousel__next-wrapper--hidden > div': { + ...disabledStyles, + }, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + width: '32px', + height: '32px', + display: 'block', + position: 'absolute', + top: 0, + bottom: '22%', + zIndex: 2, + margin: 'auto', + '& > div': { + display: 'flex', + flexFlow: 'column nowrap', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + width: '100%', + height: '100%', + lineHeight: 1, + backgroundColor: variables?.colors?.primary, + color: custom.colors.white, + }, + '.swiper-button-disabled': { + ...disabledStyles, + }, + }, + '.ss__carousel__prev-wrapper': { + left: 0, + }, + '.ss__carousel__next-wrapper': { + right: 0, + }, + '.swiper-container': { + margin: '0 auto', + '&:has(.swiper-pagination)': { + paddingBottom: `${custom.spacing.x5}px`, + }, + '& > .swiper-wrapper': { + '& > .swiper-slide': { + '& > *, .ss__result': { + padding: 0, + margin: 0, + width: 'auto', + height: '100%', + }, + }, + }, + '& > .swiper-pagination': { + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + '.swiper-pagination-bullet': { + margin: `0 ${custom.spacing.x1 / 2}px`, + width: '12px', + height: '12px', + minWidth: '1px', + flex: '0 1 auto', + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + opacity: 1, + }, + '.swiper-pagination-bullet-active': { + backgroundColor: variables?.colors?.primary, + borderColor: variables?.colors?.primary, + }, + }, + }, + '.swiper-grid-column': { + '& > .swiper-wrapper': { + flexFlow: 'row wrap', + '& > .swiper-slide': { + height: 'auto !important', + marginTop: '0 !important', + marginBottom: `${custom.spacing.x4}px`, + }, + }, + }, + }); +}; + +// Carousel component props +export const carousel: ThemeComponent<'carousel', CarouselProps> = { + default: { + carousel: { + themeStyleScript: carouselStyleScript, + }, + 'carousel icon.prev': { + icon: custom.icons.arrowLeft, + size: `${custom.sizes.icon12}px`, + }, + 'carousel icon.next': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/checkbox.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/checkbox.ts new file mode 100644 index 0000000000..c195b8fdfc --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/checkbox.ts @@ -0,0 +1,81 @@ +import { css } from '@emotion/react'; +import type { CheckboxProps } from '../../../../components/Molecules/Checkbox'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Checkbox component +const checkboxStyleScript = (props: CheckboxProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + // shared checkbox styles + const sharedStyles = css({ + position: 'relative', + top: '-1px', + }); + const sharedDefaultStyles = css({ + border: `1px solid ${custom.colors.gray02}`, + '&, *': { + boxSizing: 'border-box', + }, + '.ss__icon': { + width: '8px', + height: '8px', + }, + '&.ss__checkbox--active': { + borderColor: darkGray, + '.ss__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }); + const disabledStyles = css({ + '&.ss__checkbox--disabled': { + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }, + }); + + // default checkbox styles + const defaultStyles = css([ + sharedStyles, + sharedDefaultStyles, + { + backgroundColor: custom.colors.gray01, + }, + disabledStyles, + ]); + + // native checkbox styles + const nativeStyles = css([ + sharedStyles, + { + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + border: `1px solid ${custom.colors.gray02}`, + cursor: 'pointer', + }, + disabledStyles, + ]); + + // return checkbox styles + if (props?.native) { + return nativeStyles; + } else { + return defaultStyles; + } +}; + +// Checkbox component props +export const checkbox: ThemeComponent<'checkbox', CheckboxProps> = { + default: { + checkbox: { + themeStyleScript: checkboxStyleScript, + icon: custom.icons.check, + size: `${custom.sizes.icon16}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/errorHandler.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/errorHandler.ts new file mode 100644 index 0000000000..c66af2df3c --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/errorHandler.ts @@ -0,0 +1,40 @@ +import { css } from '@emotion/react'; +import type { ErrorHandlerProps } from '../../../../components/Molecules/ErrorHandler'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the ErrorHandler component +const errorHandlerStyleScript = (props: ErrorHandlerProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__error-handler__message': { + display: 'block', + flex: `1 1 0%`, + color: variables?.colors?.text, + '.ss__icon': { + position: 'relative', + top: '2px', + }, + }, + '.ss__error-handler__button': { + gap: 0, + flex: `0 1 auto`, + padding: `0 ${custom.spacing.x1}px`, + height: '25px', + lineHeight: '25px', + }, + }); +}; + +// ErrorHandler component props +export const errorHandler: ThemeComponent<'errorHandler', ErrorHandlerProps> = { + default: { + errorHandler: { + themeStyleScript: errorHandlerStyleScript, + }, + 'errorHandler icon': { + size: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetGridOptions.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetGridOptions.ts new file mode 100644 index 0000000000..301f495d5d --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetGridOptions.ts @@ -0,0 +1,76 @@ +import { css } from '@emotion/react'; +import type { FacetGridOptionsProps } from '../../../../components/Molecules/FacetGridOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the FacetGridOptions component +const facetGridOptionsStyleScript = (props: FacetGridOptionsProps) => { + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const fontColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#00aeef' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + const gridSize = props?.gridSize ? props.gridSize : '52px'; + + return css({ + gridTemplateColumns: `repeat(auto-fill, minmax(${gridSize}, 1fr))`, + gap: props?.gapSize ? props.gapSize : custom.spacing.x1, + alignItems: 'center', + '.ss__facet-grid-options__option': { + position: 'relative', + height: '100%', + aspectRatio: 1, + border: 0, + color: variables?.colors?.text, + '&, &:after, .ss__facet-grid-options__option__value': { + boxSizing: 'border-box', + }, + '&:after, .ss__facet-grid-options__option__value': { + display: 'block', + }, + '&:after': { + content: '""', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1, + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + }, + '.ss__facet-grid-options__option__value': { + position: 'relative', + zIndex: 2, + maxWidth: `calc(100% - ${custom.spacing.x2}px)`, + maxHeight: `calc(100% - ${custom.spacing.x2}px)`, + overflow: 'hidden', + '&, &.ss__facet-grid-options__option__value--smaller': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1, + }, + }, + }, + '.ss__facet-grid-options__option.ss__facet-grid-options__option--filtered': { + fontWeight: custom.fonts.weight01, + color: fontColor.hex(), + '&:after': { + backgroundColor: activeColor.hex(), + borderColor: activeColor.hex(), + }, + }, + }); +}; + +// FacetGridOptions component props +export const facetGridOptions: ThemeComponent<'facetGridOptions', FacetGridOptionsProps> = { + default: { + facetGridOptions: { + themeStyleScript: facetGridOptionsStyleScript, + gridSize: '52px', + gapSize: `${custom.spacing.x1}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetHierarchyOptions.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetHierarchyOptions.ts new file mode 100644 index 0000000000..13419c29d4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetHierarchyOptions.ts @@ -0,0 +1,64 @@ +import { css } from '@emotion/react'; +import type { FacetHierarchyOptionsProps } from '../../../../components/Molecules/FacetHierarchyOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FacetHierarchyOptions component +const facetHierarchyOptionsStyleScript = (props: FacetHierarchyOptionsProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + + return css({ + '.ss__facet-hierarchy-options__option': { + display: 'block', + margin: `0 0 ${custom.spacing.x1}px 0`, + padding: 0, + color: variables?.colors?.text, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__facet-hierarchy-options__option__value': { + margin: 0, + '.ss__facet-hierarchy-options__option__value__count': { + position: 'relative', + top: '-1px', + margin: 0, + padding: `0 ${custom.spacing.x1}px`, + fontSize: custom.utils.convertPxToEm(10), + color: lightGray, + }, + }, + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--return': { + '&:before': { + display: 'none', + }, + '.ss__icon': { + position: 'relative', + top: '1px', + margin: `0 ${custom.spacing.x1}px 0 0`, + padding: 0, + }, + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--filtered': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '& ~ .ss__facet-hierarchy-options__option:not(.ss__facet-hierarchy-options__option--filtered)': { + paddingLeft: `${custom.spacing.x6}px`, + }, + }, + }); +}; + +// FacetHierarchyOptions component props +export const facetHierarchyOptions: ThemeComponent<'facetHierarchyOptions', FacetHierarchyOptionsProps> = { + default: { + facetHierarchyOptions: { + themeStyleScript: facetHierarchyOptionsStyleScript, + returnIcon: custom.icons.arrowLeft, + }, + 'facetHierarchyOptions icon': { + size: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetListOptions.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetListOptions.ts new file mode 100644 index 0000000000..e42c39a96b --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetListOptions.ts @@ -0,0 +1,54 @@ +import { css } from '@emotion/react'; +import type { FacetListOptionsProps } from '../../../../components/Molecules/FacetListOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FacetListOptions component +const facetListOptionsStyleScript = (props: FacetListOptionsProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const checkboxSpacing = custom.sizes.icon16 + custom.spacing.x2; + + return css({ + '.ss__facet-list-options__option': { + display: 'block', + position: 'relative', + margin: `0 0 ${custom.spacing.x1}px 0`, + color: variables?.colors?.text, + padding: props?.hideCheckbox ? `` : `0 0 0 ${checkboxSpacing}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__checkbox, .ss__radio': { + position: 'absolute', + top: '1.5px', + left: 0, + }, + '.ss__facet-list-options__option__value': { + margin: 0, + '.ss__facet-list-options__option__value__count': { + position: 'relative', + top: '-1px', + margin: 0, + padding: `0 ${custom.spacing.x1}px`, + fontSize: custom.utils.convertPxToEm(10), + color: lightGray, + }, + }, + }, + '.ss__facet-list-options__option.ss__facet-list-options__option--filtered': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }); +}; + +// FacetListOptions component props +export const facetListOptions: ThemeComponent<'facetListOptions', FacetListOptionsProps> = { + default: { + facetListOptions: { + themeStyleScript: facetListOptionsStyleScript, + respectSingleSelect: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetPaletteOptions.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetPaletteOptions.ts new file mode 100644 index 0000000000..405114def8 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetPaletteOptions.ts @@ -0,0 +1,211 @@ +import { css } from '@emotion/react'; +import type { FacetPaletteOptionsProps } from '../../../../components/Molecules/FacetPaletteOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FacetPaletteOptions component +const facetPaletteStyleScript = (props: FacetPaletteOptionsProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const hasCheckbox = !props?.hideCheckbox ? true : false; + + // set details for radius + const radius = 0; + const radiusUnit = 'px'; + const paletteRadius = radius ? `${radius}${radiusUnit}` : `0`; + + // determine inner border width + let innerBorder = 5; + if (props?.layout == 'list') { + innerBorder = hasCheckbox ? 2 : 3; + } + + // shared palette styles + const sharedStyles = css({ + '.ss__facet-palette-options__option': { + display: 'block', + color: variables?.colors?.text, + '&, &.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper': { + border: 0, + borderRadius: 0, + padding: 0, + }, + }, + '&.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper .ss__facet-palette-options__option__palette': { + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + }, + }, + '.ss__facet-palette-options__option__wrapper': { + overflow: 'hidden', + '.ss__facet-palette-options__option__palette': { + border: 0, + padding: 0, + '&, &:before, &:after': { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + borderRadius: paletteRadius, + boxSizing: 'border-box', + }, + '&:before, &:after': { + content: '""', + display: 'block', + }, + '&:before': { + border: `${innerBorder}px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + }, + }, + '.ss__facet-palette-options__option__value__count': { + position: 'relative', + top: props?.layout == 'list' ? '-1px' : '', + padding: props?.layout == 'list' ? `0 ${custom.spacing.x1}px` : ``, + fontSize: custom.utils.convertPxToEm(10), + color: lightGray, + }, + }, + }); + + // grid palette styles + const gridStyles = css([ + sharedStyles, + { + gridTemplateColumns: `repeat(auto-fill, minmax(${props?.gridSize ? props.gridSize : '52px'}, 1fr))`, + gap: props?.gapSize ? props.gapSize : custom.spacing.x1, + alignItems: 'center', + '.ss__facet-palette-options__option': { + textAlign: 'center', + '&, &.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper': { + position: 'relative', + height: 0, + padding: '0 0 100% 0', + }, + }, + '.ss__checkbox, .ss__radio': { + display: 'none', + }, + '.ss__facet-palette-options__option__value, .ss__facet-palette-options__option__value__count': { + display: 'block', + lineHeight: '0.85rem', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + '.ss__facet-palette-options__option__value': { + fontSize: custom.utils.convertPxToEm(12), + overflow: 'hidden', + margin: `${custom.spacing.x1}px 0 0 0`, + }, + '.ss__facet-palette-options__option__value__count': { + margin: `${custom.spacing.x1 / 2}px 0 0 0`, + }, + }, + }, + ]); + + // list variables + const listSize = hasCheckbox ? 16 : 22; + const listCheckboxSize = 16; + const listPadding = hasCheckbox ? custom.spacing.x4 + listSize + listCheckboxSize : custom.spacing.x2 + listSize; + + // list palette styles + const listStyles = css([ + sharedStyles, + { + '&.ss__facet-palette-options--list': { + display: 'block', + }, + '.ss__facet-palette-options__option': { + position: 'relative', + padding: `${hasCheckbox ? 0 : '2px'} 0 0 ${listPadding}px`, + margin: `0 0 ${custom.spacing.x1}px 0`, + minHeight: hasCheckbox ? '' : `${listSize + 2}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__checkbox, .ss__radio, .ss__facet-palette-options__option__wrapper': { + position: 'absolute', + top: `${hasCheckbox ? 2 : 0.5}px`, + }, + '.ss__checkbox, .ss__radio': { + left: 0, + }, + '.ss__facet-palette-options__option__wrapper': { + left: hasCheckbox ? `${listCheckboxSize + custom.spacing.x2}px` : 0, + width: `${listSize}px`, + height: `${listSize}px`, + lineHeight: `${listSize}px`, + }, + '.ss__facet-palette-options__option__value, .ss__facet-palette-options__option__value__count': { + display: 'inline', + overflow: 'visible', + textOverflow: 'unset', + textAlign: 'left', + whiteSpace: 'unset', + }, + '.ss__facet-palette-options__option__value__count': { + margin: 0, + }, + }, + }, + ]); + + return props?.layout == 'list' ? listStyles : gridStyles; +}; + +// FacetPaletteOptions component props +export const facetPaletteOptions: ThemeComponent<'facetPaletteOptions', FacetPaletteOptionsProps> = { + default: { + facetPaletteOptions: { + themeStyleScript: facetPaletteStyleScript, + hideIcon: true, + gridSize: '52px', + gapSize: `${custom.spacing.x1}px`, + colorMapping: { + brown: { + background: custom.colors.brown, + }, + multi: { + background: custom.colors.rainbow, + }, + 'multi-color': { + background: custom.colors.rainbow, + }, + purple: { + background: custom.colors.purple, + }, + rainbow: { + background: custom.colors.rainbow, + }, + }, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetSlider.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetSlider.ts new file mode 100644 index 0000000000..5c8f9b4f0d --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/facetSlider.ts @@ -0,0 +1,200 @@ +import { css } from '@emotion/react'; +import type { FacetSliderProps } from '../../../../components/Molecules/FacetSlider'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the FacetSlider component +const facetSliderStyleScript = (props: FacetSliderProps) => { + // slider options + const slider = { + handles: 20, // handle size + values: 14, // values size + bar: 6, // bar size + ticks: 17, // size of ticks + valuesPosition: 'top', // position of slider values (top or bottom) + valuesAlign: 'sides', // alignment of slider values (sides or center) + }; + + const variables = props?.theme?.variables; + const fontColor = props?.valueTextColor || variables?.colors?.text; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + const valuesTop = slider.valuesPosition == 'top' ? true : false; + const valuesSides = slider.valuesAlign == 'sides' ? true : false; + const hasTicks = props?.showTicks ? true : false; + const hasStickyHandles = props?.stickyHandleLabel ? true : false; + const handleColor = new Color(props?.handleColor || variables?.colors?.primary || undefined); + const handleInnerColor = + handleColor.isDark() || handleColor.hex().toLowerCase() == '#00aeef' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + + // values font styles + const valuesStyles = css({ + fontSize: custom.utils.convertPxToEm(slider.values), + lineHeight: `${slider.values}px`, + color: fontColor, + }); + + // shared slider styles + const sharedStyles = css({ + '&, *': { + boxSizing: 'border-box', + }, + '&, .ss__facet-slider__slider': { + margin: 'auto', + }, + '.ss__facet-slider__slider button, .ss__facet-slider__labels label': { + margin: 0, + padding: 0, + '&:focus': { + outline: 0, + }, + }, + '.ss__facet-slider__slider': { + display: 'block', + top: 0, + width: '100%', + height: `${slider.bar}px`, + '.ss__facet-slider__segment, .ss__facet-slider__rail, .ss__facet-slider__handles': { + height: '100%', + }, + '.ss__facet-slider__tick': { + '&:before, .ss__facet-slider__tick__label': { + transform: 'translate(-50%, 0)', + }, + '&:before': { + top: `${slider.ticks / 2}px`, + backgroundColor: darkGray, + }, + '.ss__facet-slider__tick__label': { + top: `${slider.ticks}px`, + color: props?.tickTextColor || variables?.colors?.text, + lineHeight: 1, + }, + }, + '.ss__facet-slider__segment': { + backgroundColor: props?.trackColor || custom.colors.gray01, + border: `1px solid ${props?.trackColor || custom.colors.gray02}`, + borderRadius: `${slider.bar}px`, + }, + '.ss__facet-slider__rail': { + backgroundColor: props?.railColor || variables?.colors?.secondary, + border: `1px solid ${props?.railColor || variables?.colors?.secondary}`, + }, + '.ss__facet-slider__handles': { + position: 'relative', + margin: `0 ${slider.handles / 2 - 2}px`, + button: { + '.ss__facet-slider__handle': { + transform: 'none', + width: `${slider.handles}px`, + height: `${slider.handles}px`, + lineHeight: `${slider.handles}px`, + backgroundColor: handleColor.hex(), + border: `1px solid ${handleColor.hex()}`, + '&:after': { + width: `${slider.handles / 4}px`, + height: `${slider.handles / 4}px`, + backgroundColor: handleInnerColor.hex(), + border: `1px solid ${handleInnerColor.hex()}`, + }, + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + backgroundColor: 'transparent', + '&': { + ...valuesStyles, + }, + }, + }, + }, + }, + }, + '.ss__facet-slider__labels': { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + justifyContent: valuesSides ? '' : 'center', + '.ss__facet-slider__label': { + '&': { + ...valuesStyles, + }, + '&:after': { + display: valuesSides ? 'none' : '', + padding: `0 ${custom.spacing.x1}px`, + }, + '& ~ .ss__facet-slider__label': { + marginLeft: valuesSides ? 'auto' : '', + }, + }, + }, + }); + + // spacing and size calculations + const handlesSizeHalf = (slider.handles - slider.bar) / 2; + const handlesSpacing = slider.handles + custom.spacing.x2; + const ticksSpacing = slider.ticks + custom.spacing.x1; + const stickySpacing = slider.values + custom.spacing.x2; + const handlesPlusSticky = handlesSizeHalf + stickySpacing; + const ticksPlusSticky = ticksSpacing + stickySpacing; + + // spacing styles for different configurations + // note: default for facet slider is no ticks, no stick handles, values bottom + let spacingStyles = css({}); + + if (hasTicks && hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${valuesTop ? handlesPlusSticky : handlesSizeHalf}px auto ${valuesTop ? ticksSpacing : ticksPlusSticky}px auto`, + '.ss__facet-slider__handles button .ss__facet-slider__handle': { + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + top: valuesTop ? `auto` : `${handlesSizeHalf + ticksPlusSticky - slider.bar}px`, + bottom: valuesTop ? `${handlesSpacing}px` : ``, + }, + }, + }, + }); + } else if (hasTicks && !hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${handlesSizeHalf}px auto ${ticksSpacing}px auto`, + }, + '.ss__facet-slider__labels': { + order: valuesTop ? -1 : '', + margin: `${valuesTop ? 0 : custom.spacing.x2}px 0 ${valuesTop ? custom.spacing.x2 : 0}px 0`, + }, + }); + } else if (!hasTicks && hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${valuesTop ? handlesPlusSticky : handlesSizeHalf}px auto ${valuesTop ? handlesSizeHalf : handlesPlusSticky}px auto`, + '.ss__facet-slider__handles button .ss__facet-slider__handle': { + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + top: valuesTop ? 'auto' : `${handlesSpacing}px`, + bottom: valuesTop ? `${handlesSpacing}px` : ``, + }, + }, + }, + }); + } else { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${handlesSizeHalf}px auto`, + }, + '.ss__facet-slider__labels': { + order: valuesTop ? -1 : '', + margin: `${valuesTop ? 0 : custom.spacing.x2}px 0 ${valuesTop ? custom.spacing.x2 : 0}px 0`, + }, + }); + } + + return css([sharedStyles, spacingStyles]); +}; + +// FacetSlider component props +export const facetSlider: ThemeComponent<'facetSlider', FacetSliderProps> = { + default: { + facetSlider: { + themeStyleScript: facetSliderStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/filter.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/filter.ts new file mode 100644 index 0000000000..15aede8a43 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/filter.ts @@ -0,0 +1,44 @@ +import { css } from '@emotion/react'; +import type { FilterProps } from '../../../../components/Molecules/Filter'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Filter component +const filterStyleScript = (props: FilterProps) => { + const variables = props?.theme?.variables; + + return css({ + display: 'block', + padding: 0, + '.ss__filter__button': { + position: 'relative', + height: 'auto', + lineHeight: 1.5, + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + fontWeight: 'normal', + color: variables?.colors?.text, + '&, &:hover, &:not(.ss__button--disabled):hover, &.ss__button--disabled': { + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + }, + '.ss__button__content': { + '.ss__filter__label': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + }); +}; + +// Filter component props +export const filter: ThemeComponent<'filter', FilterProps> = { + default: { + filter: { + themeStyleScript: filterStyleScript, + icon: custom.icons.close, + }, + 'filter icon': { + size: `${custom.sizes.icon10}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/grid.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/grid.ts new file mode 100644 index 0000000000..0b5e93f741 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/grid.ts @@ -0,0 +1,188 @@ +import { css } from '@emotion/react'; +import type { GridProps } from '../../../../components/Molecules/Grid'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// grid size +const gridSize = 42; + +// CSS in JS style script for the Grid component +const gridStyleScript = (props: Partial) => { + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const fontColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#00aeef' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + return css({ + '.ss__grid__title': { + margin: `0 0 ${custom.spacing.x1}px 0`, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + lineHeight: 1, + }, + '.ss__grid__options': { + display: 'flex', + flexFlow: 'row wrap', + gap: props?.gapSize ? props.gapSize : custom.spacing.x1, + alignItems: 'center', + '&:before, &:after': { + display: 'none', + }, + '.ss__grid__option': { + flex: '0 1 auto', + minWidth: '1px', + '&, &.ss__grid__option--selected': { + border: 0, + }, + '.ss__grid__option__inner .ss__grid__option__label, .ss__grid__show-more-wrapper': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1, + }, + }, + '.ss__grid__option:not(.ss__grid__show-more-wrapper)': { + position: 'relative', + width: `${gridSize}px`, + maxHeight: `${gridSize}px`, + aspectRatio: 1, + color: variables?.colors?.text, + overflow: 'hidden', + '&, &:after, *': { + boxSizing: 'border-box', + }, + '&:before': { + display: 'none', + }, + '&:after': { + content: '""', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1, + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&.ss__grid__option--dark, &:has(.ss__grid__option__inner--grey)': { + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + color: fontColor.hex(), + }, + }, + }, + '&.ss__grid__option--selected': { + '&:after': { + opacity: 0.3, + }, + '&:has(.ss__grid__option__inner:not([style]))': { + backgroundColor: activeColor.hex(), + '&:after': { + borderColor: activeColor.hex(), + opacity: 1, + }, + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + color: fontColor.hex(), + }, + }, + }, + '&:has(.ss__grid__option__inner .ss__image)': { + backgroundColor: 'transparent', + '&:after': { + borderColor: custom.colors.black, + opacity: 0.3, + }, + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + color: variables?.colors?.text, + }, + }, + }, + '.ss__grid__option__inner': { + '.ss__grid__option__label': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + '&.ss__grid__option--disabled, &.ss__grid__option--unavailable': { + opacity: 1, + cursor: 'not-allowed', + pointerEvents: 'none', + '.ss__grid__option__inner:after': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 3, + margin: 'auto', + backgroundColor: darkGray.replace('#', ''), + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center center', + backgroundImage: `url("data:image/svg+xml,%3Csvg style=%27transform: rotate%28-45deg%29%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 56 56%27 preserveAspectRatio=%27xMinYMid%27%3E%3Cpath fill=%27%23${darkGray.replace( + '#', + '' + )}%27 d=%27M0 23.297h56v9.406h-56v-9.406z%27 /%3E%3C/svg%3E")`, + }, + }, + '.ss__grid__option__inner': { + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + '.ss__grid__option__label': { + display: 'block', + position: 'absolute', + zIndex: 2, + maxWidth: `calc(100% - ${custom.spacing.x2}px)`, + maxHeight: `calc(100% - ${custom.spacing.x2}px)`, + overflow: 'hidden', + }, + }, + }, + '.ss__grid__show-more-wrapper': { + maxHeight: 'none', + }, + }, + '.ss__grid__show-more-wrapper': { + '&:not(.ss__grid__option)': { + margin: `${custom.spacing.x2}px 0 0 0`, + }, + '&, .ss__grid__show-more': { + cursor: 'pointer', + }, + '.ss__grid__show-more': { + fontSize: custom.utils.convertPxToEm(12), + fontWeight: custom.fonts.weight01, + lineHeight: 1, + color: variables?.colors?.primary, + }, + }, + }); +}; + +// Grid component props +export const grid: ThemeComponent<'grid', GridProps> = { + default: { + grid: { + themeStyleScript: gridStyleScript, + gapSize: `${custom.spacing.x1}px`, + hideLabels: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/index.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/index.ts new file mode 100644 index 0000000000..870baa5828 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/index.ts @@ -0,0 +1,144 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// MOLECULES Imports +import { calloutBadge } from './calloutBadge'; +import { carousel } from './carousel'; +import { checkbox } from './checkbox'; +import { errorHandler } from './errorHandler'; +import { facetGridOptions } from './facetGridOptions'; +import { facetHierarchyOptions } from './facetHierarchyOptions'; +import { facetListOptions } from './facetListOptions'; +import { facetPaletteOptions } from './facetPaletteOptions'; +import { facetSlider } from './facetSlider'; +import { filter } from './filter'; +import { grid } from './grid'; +import { layoutSelector } from './layoutSelector'; +import { list } from './list'; +import { loadMore } from './loadMore'; +import { overlayBadge } from './overlayBadge'; +import { pagination } from './pagination'; +import { radio } from './radio'; +import { radioList } from './radioList'; +import { result } from './result'; +import { searchInput } from './searchInput'; +import { select } from './select'; +import { slideout } from './slideout'; +import { rating } from './rating'; +import { swatches } from './swatches'; +import { variantSelection } from './variantSelection'; +import { terms } from './terms'; + +export const molecules: ThemeResponsiveComplete = { + default: { + ...carousel.default, + ...checkbox.default, + ...errorHandler.default, + ...facetGridOptions.default, + ...facetHierarchyOptions.default, + ...facetListOptions.default, + ...facetPaletteOptions.default, + ...facetSlider.default, + ...filter.default, + ...grid.default, + ...layoutSelector.default, + ...list.default, + ...loadMore.default, + ...overlayBadge.default, + ...pagination.default, + ...radio.default, + ...radioList.default, + ...result.default, + ...searchInput.default, + ...select.default, + ...slideout.default, + ...rating.default, + ...swatches.default, + ...variantSelection.default, + ...terms.default, + ...calloutBadge.default, + }, + mobile: { + ...carousel.mobile, + ...checkbox.mobile, + ...errorHandler.mobile, + ...facetGridOptions.mobile, + ...facetHierarchyOptions.mobile, + ...facetListOptions.mobile, + ...facetPaletteOptions.mobile, + ...facetSlider.mobile, + ...filter.mobile, + ...grid.mobile, + ...layoutSelector.mobile, + ...list.mobile, + ...loadMore.mobile, + ...overlayBadge.mobile, + ...pagination.mobile, + ...radio.mobile, + ...radioList.mobile, + ...result.mobile, + ...searchInput.mobile, + ...select.mobile, + ...slideout.mobile, + ...rating.mobile, + ...swatches.mobile, + ...variantSelection.mobile, + ...terms.mobile, + ...calloutBadge.mobile, + }, + tablet: { + ...carousel.tablet, + ...checkbox.tablet, + ...errorHandler.tablet, + ...facetGridOptions.tablet, + ...facetHierarchyOptions.tablet, + ...facetListOptions.tablet, + ...facetPaletteOptions.tablet, + ...facetSlider.tablet, + ...filter.tablet, + ...grid.tablet, + ...layoutSelector.tablet, + ...list.tablet, + ...loadMore.tablet, + ...overlayBadge.tablet, + ...pagination.tablet, + ...radio.tablet, + ...radioList.tablet, + ...result.tablet, + ...searchInput.tablet, + ...select.tablet, + ...slideout.tablet, + ...rating.tablet, + ...swatches.tablet, + ...variantSelection.tablet, + ...terms.tablet, + ...calloutBadge.tablet, + }, + desktop: { + ...carousel.desktop, + ...checkbox.desktop, + ...errorHandler.desktop, + ...facetGridOptions.desktop, + ...facetHierarchyOptions.desktop, + ...facetListOptions.desktop, + ...facetPaletteOptions.desktop, + ...facetSlider.desktop, + ...filter.desktop, + ...grid.desktop, + ...layoutSelector.desktop, + ...list.desktop, + ...loadMore.desktop, + ...overlayBadge.desktop, + ...pagination.desktop, + ...radio.desktop, + ...radioList.desktop, + ...result.desktop, + ...searchInput.desktop, + ...select.desktop, + ...slideout.desktop, + ...rating.desktop, + ...swatches.desktop, + ...variantSelection.desktop, + ...terms.desktop, + ...calloutBadge.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/layoutSelector.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/layoutSelector.ts new file mode 100644 index 0000000000..07b7cf7753 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/layoutSelector.ts @@ -0,0 +1,76 @@ +import { css } from '@emotion/react'; +import type { LayoutSelectorProps } from '../../../../components/Molecules/LayoutSelector'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the LayoutSelector component +const layoutSelectorStyleScript = (props: LayoutSelectorProps) => { + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const activeIconColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#00aeef' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + + // dropdown styles + const dropdownStyles = css({ + '.ss__dropdown': { + '.ss__dropdown__button .ss__button__content': { + gap: `${custom.spacing.x2}px`, + }, + }, + }); + + // list styles + const listStyles = css({ + '.ss__list__options': { + display: 'flex', + '.ss__list__option': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + padding: `0 ${custom.spacing.x2}px`, + margin: 0, + }, + '.ss__list__option--selected': { + borderColor: activeColor.hex(), + backgroundColor: activeColor.hex(), + color: activeIconColor.hex(), + '&, *': { + cursor: 'text', + }, + }, + }, + }); + + if (props?.type == 'dropdown') { + return dropdownStyles; + } else if (props?.type == 'list') { + return listStyles; + } else { + return dropdownStyles; + } +}; + +// LayoutSelector component props +export const layoutSelector: ThemeComponent<'layoutSelector', LayoutSelectorProps> = { + default: { + layoutSelector: { + themeStyleScript: layoutSelectorStyleScript, + type: 'list', + }, + 'layoutSelector select': { + hideSelection: false, + separator: '', + }, + 'layoutSelector list': { + hideTitleText: true, + hideOptionLabels: true, + }, + 'layoutSelector radioList': { + hideTitleText: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/list.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/list.ts new file mode 100644 index 0000000000..1ea3e14846 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/list.ts @@ -0,0 +1,45 @@ +import { css } from '@emotion/react'; +import type { ListProps } from '../../../../components/Molecules/List'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the List component +const listStyleScript = (props: ListProps) => { + const variables = props?.theme?.variables; + + return css({ + '&, .ss__list__options': { + display: 'block', + }, + '.ss__list__title, .ss__list__options .ss__list__option': { + margin: `0 0 ${custom.spacing.x1}px 0`, + }, + '.ss__list__title': { + display: 'block', + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + lineHeight: 1, + }, + '.ss__list__options': { + '.ss__list__option': { + gap: `${custom.spacing.x2}px`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__list__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }, + }); +}; + +// List component props +export const list: ThemeComponent<'list', ListProps> = { + default: { + list: { + themeStyleScript: listStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/loadMore.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/loadMore.ts new file mode 100644 index 0000000000..3da120d933 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/loadMore.ts @@ -0,0 +1,53 @@ +import { css } from '@emotion/react'; +import type { LoadMoreProps } from '../../../../components/Molecules/LoadMore'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// CSS in JS style script for the LoadMore component +const loadMoreStyleScript = (props: LoadMoreProps) => { + const variables = props?.theme?.variables; + const indicatorColor = new Color(props?.backgroundColor || custom.colors.gray01 || undefined); + const indicatorBorderColor = new Color(props?.backgroundColor || custom.colors.gray02 || undefined); + const barColor = new Color(props?.color || variables?.colors?.primary || undefined); + + return css({ + '&.ss__load-more': { + '&, .ss__load-more__progress': { + gap: `${custom.spacing.x2}px`, + }, + '& > .ss__load-more__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + '.ss__button': { + '.ss__button__content': { + display: 'flex', + alignItems: 'center', + }, + }, + '.ss__load-more__progress': { + '.ss__load-more__progress__indicator': { + backgroundColor: indicatorColor.hex(), + border: `1px solid ${indicatorBorderColor}`, + '.ss__load-more__progress__indicator__bar': { + backgroundColor: barColor.hex(), + margin: '-1px', + }, + }, + '.ss__load-more__progress__text': { + color: variables?.colors?.text, + }, + }, + }, + }); +}; + +// LoadMore component props +export const loadMore: ThemeComponent<'loadMore', LoadMoreProps> = { + default: { + loadMore: { + themeStyleScript: loadMoreStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/overlayBadge.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/overlayBadge.ts new file mode 100644 index 0000000000..4f5fce0659 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/overlayBadge.ts @@ -0,0 +1,34 @@ +import { css } from '@emotion/react'; +import type { OverlayBadgeProps } from '../../../../components/Molecules/OverlayBadge'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const overlayBadgeStyleScript = () => { + return css({ + '.ss__overlay-badge__grid-wrapper': { + gap: `${custom.spacing.x1}px`, + bottom: 'auto', + '.ss__overlay-badge__grid-wrapper__slot': { + gap: 0, + '& > div': { + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + lineHeight: 1, + span: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }); +}; + +// OverlayBadge component props +export const overlayBadge: ThemeComponent<'overlayBadge', OverlayBadgeProps> = { + default: { + overlayBadge: { + themeStyleScript: overlayBadgeStyleScript, + limit: 3, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/pagination.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/pagination.ts new file mode 100644 index 0000000000..855be34e36 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/pagination.ts @@ -0,0 +1,73 @@ +import { css } from '@emotion/react'; +import type { PaginationProps } from '../../../../components/Molecules/Pagination'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Pagination component +const paginationStyleScript = (props: PaginationProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + nav: { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + justifyContent: 'center', + lineHeight: 1, + '.ss__pagination__page, span': { + padding: `0 ${custom.spacing.x1}px`, + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.text, + }, + '.ss__pagination__page': { + minWidth: '1px', + minHeight: '1px', + }, + '.ss__pagination__page--active': { + color: variables?.colors?.primary, + }, + '.ss__pagination__page--previous, .ss__pagination__page--next': { + lineHeight: `${custom.sizes.icon12}px`, + '.ss__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + nav: { + '.ss__pagination__page, span': { + padding: `0 ${custom.spacing.x2}px`, + fontSize: custom.utils.convertPxToEm(16), + }, + '.ss__pagination__page--previous, .ss__pagination__page--next': { + lineHeight: `${custom.sizes.icon14}px`, + }, + }, + }, + }); +}; + +// Pagination component props +export const pagination: ThemeComponent<'pagination', PaginationProps> = { + default: { + pagination: { + themeStyleScript: paginationStyleScript, + }, + 'pagination icon': { + size: `${custom.sizes.icon12}px`, + }, + 'pagination icon.prev': { + icon: custom.icons.arrowLeft, + }, + 'pagination icon.next': { + icon: custom.icons.arrowRight, + }, + }, + mobile: { + 'pagination icon': { + size: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/radio.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/radio.ts new file mode 100644 index 0000000000..46a2b51477 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/radio.ts @@ -0,0 +1,81 @@ +import { css } from '@emotion/react'; +import type { RadioProps } from '../../../../components/Molecules/Radio'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Radio component +const radioStyleScript = (props: RadioProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + // shared radio styles + const sharedDefaultStyles = css({ + border: `1px solid ${custom.colors.gray02}`, + '&, & .ss__icon': { + borderRadius: '50%', + }, + '.ss__icon': { + display: 'none', + }, + '&.ss__radio--active': { + borderColor: darkGray, + '.ss__icon': { + display: 'block', + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }); + const disabledStyles = css({ + '&.ss__radio--disabled': { + opacity: 0.65, + '&, & *': { + cursor: 'not-allowed', + }, + }, + }); + + // default radio styles + const defaultStyles = css([ + sharedDefaultStyles, + { + backgroundColor: custom.colors.gray01, + }, + disabledStyles, + ]); + + // native radio styles + const nativeStyles = css([ + { + lineHeight: 0, + '.ss__radio__input': { + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + border: `1px solid ${custom.colors.gray02}`, + cursor: 'pointer', + }, + }, + disabledStyles, + ]); + + // return radio styles + if (props?.native) { + return nativeStyles; + } else { + return defaultStyles; + } +}; + +// Radio component props +export const radio: ThemeComponent<'radio', RadioProps> = { + default: { + radio: { + themeStyleScript: radioStyleScript, + size: `${custom.sizes.icon14}px`, + }, + 'radio icon': { + icon: 'square', + size: `${custom.sizes.icon10 - 2}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/radioList.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/radioList.ts new file mode 100644 index 0000000000..0aa0632335 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/radioList.ts @@ -0,0 +1,47 @@ +import { css } from '@emotion/react'; +import type { RadioListProps } from '../../../../components/Molecules/RadioList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RadioList component +const radioListStyleScript = (props: RadioListProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__radio-list__title, .ss__radio-list__options-wrapper .ss__radio-list__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + }, + '.ss__radio-list__title': { + display: 'block', + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + lineHeight: 1, + }, + '.ss__radio-list__options-wrapper': { + '.ss__radio-list__option': { + gap: `${custom.spacing.x2}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__radio-list__option__icon, .ss__radio-list__option__label': { + padding: 0, + }, + }, + '.ss__radio-list__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }, + }); +}; + +// RadioList component props +export const radioList: ThemeComponent<'radioList', RadioListProps> = { + default: { + radioList: { + themeStyleScript: radioListStyleScript, + hideOptionLabels: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/rating.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/rating.ts new file mode 100644 index 0000000000..1371653fef --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/rating.ts @@ -0,0 +1,54 @@ +import { css } from '@emotion/react'; +import type { RatingProps } from '../../../../components/Molecules/Rating'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Rating component +const ratingStyleScript = (props: RatingProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + return css({ + flexWrap: 'wrap', + gap: `${custom.spacing.x1}px`, + lineHeight: 1, + '.ss__rating__icons': { + '.ss__rating__stars': { + margin: '0 -1px', + '.ss__rating__stars__star': { + margin: '0 1px', + }, + }, + '.ss__rating__stars--empty': { + '.ss__rating__stars__star .ss__icon': { + fill: darkGray, + stroke: darkGray, + }, + }, + '.ss__rating__stars--full': { + '.ss__rating__stars__star .ss__icon': { + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + }, + '.ss__rating__count, .ss__rating__text': { + fontSize: custom.utils.convertPxToEm(12), + color: variables?.colors?.text, + }, + }); +}; + +// Rating component props +export const rating: ThemeComponent<'rating', RatingProps> = { + default: { + rating: { + themeStyleScript: ratingStyleScript, + emptyIcon: 'star', + fullIcon: 'star', + }, + 'rating icon': { + size: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/result.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/result.ts new file mode 100644 index 0000000000..5a40719251 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/result.ts @@ -0,0 +1,123 @@ +import { css } from '@emotion/react'; +import type { ResultProps } from '../../../../components/Molecules/Result'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Result component +const resultStyleScript = (props: ResultProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + + return css({ + '&.ss__result--sale': { + '.ss__result__details': { + '.ss__result__details__pricing': { + '.ss__result__price:not(.ss__price--strike)': { + '&, span': { + color: variables?.colors?.primary, + }, + }, + }, + }, + }, + '&.ss__result--grid': { + display: 'block', + }, + '&.ss__result--list': { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + '.ss__result__image-wrapper, .ss__result__details': { + minWidth: '1px', + }, + '.ss__result__image-wrapper': { + flex: '0 0 33.33%', + margin: `0 ${custom.spacing.x4}px 0 0`, + }, + '.ss__result__details': { + flex: '1 1 0%', + textAlign: 'left', + margin: 0, + '.ss__callout-badge, .ss__result__rating-wrapper': { + justifyContent: 'flex-start', + }, + '.ss__result__details__title': { + flex: '1 1 0%', + a: { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + }, + }, + '.ss__result__details__pricing': { + flex: '0 1 auto', + order: -1, + }, + }, + }, + '.ss__result__image-wrapper': { + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + '.ss__result__details': { + padding: 0, + display: 'flex', + flexFlow: 'row wrap', + gap: `${custom.spacing.x2}px`, + '& > *, .ss__result__details__title, .ss__result__details__title, .ss__result__details__pricing': { + margin: 0, + }, + '& > *': { + minWidth: '1px', + flex: '1 1 100%', + }, + '.ss__result__details__title': { + order: -2, + a: { + color: variables?.colors?.text, + }, + }, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: custom.utils.convertPxToEm(16), + '&:not(.ss__price--strike)': { + fontWeight: custom.fonts.weight01, + }, + }, + '.ss__price--strike': { + fontSize: custom.utils.convertPxToEm(14), + '&, span': { + color: lightGray, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '&.ss__result--list': { + display: 'block', + '.ss__result__details': { + textAlign: 'center', + '.ss__callout-badge, .ss__result__rating-wrapper': { + justifyContent: 'center', + }, + '.ss__result__details__title, .ss__result__details__pricing': { + flex: '1 1 100%', + }, + '.ss__result__details__pricing': { + order: 0, + }, + }, + '.ss__result__image-wrapper': { + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + }, + }, + }); +}; + +// Result component props +export const result: ThemeComponent<'result', ResultProps> = { + default: { + result: { + themeStyleScript: resultStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/searchInput.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/searchInput.ts new file mode 100644 index 0000000000..8ae4ecfd19 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/searchInput.ts @@ -0,0 +1,91 @@ +import { css } from '@emotion/react'; +import type { SearchInputProps } from '../../../../components/Molecules/SearchInput'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the SearchInput component +const searchInputStyleScript = (props: SearchInputProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const darkPrimary = custom.utils.darkenColor(variables?.colors?.primary, 0.15); + + return css({ + '&.ss__search-input': { + margin: `0 0 ${custom.spacing.x2}px`, + border: 0, + height: '35px', + '& > *': { + minWidth: '1px', + }, + '.ss__search-input__input, .ss__search-input__icons, .ss__button': { + height: '100%', + lineHeight: 1, + }, + '.ss__search-input__icons, .ss__search-input__button--close-search-button': { + flex: '0 1 auto', + }, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '35px', + boxSizing: 'border-box', + justifyContent: 'center', + '&, &:hover': { + border: 0, + }, + '&, .ss__icon': { + padding: 0, + }, + '.ss__icon': { + fill: custom.colors.white, + stroke: custom.colors.white, + }, + }, + '.ss__search-input__input': { + flex: '1 1 0%', + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + padding: `0 ${custom.spacing.x2}px`, + minHeight: '1px', + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.text, + '&::-webkit-input-placeholder': { + color: lightGray, + }, + '&::-ms-input-placeholder': { + color: lightGray, + }, + '&::placeholder': { + color: lightGray, + }, + }, + '.ss__search-input__icons': { + gap: '1px', + margin: '0 0 0 -1px', + backgroundColor: darkPrimary, + }, + '.ss__search-input__button--close-search-button': { + margin: '0 -1px 0 0', + }, + }, + }); +}; + +// SearchInput component props +export const searchInput: ThemeComponent<'searchInput', SearchInputProps> = { + default: { + searchInput: { + themeStyleScript: searchInputStyleScript, + }, + 'searchInput icon': { + size: `${custom.sizes.icon14}px`, + }, + 'searchInput button.close-search icon': { + icon: custom.icons.arrowLeft, + }, + 'searchInput button.clear-search icon': { + icon: custom.icons.close, + }, + 'searchInput button.submit-search icon': { + icon: custom.icons.search, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/select.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/select.ts new file mode 100644 index 0000000000..96d04d7a14 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/select.ts @@ -0,0 +1,149 @@ +import { css } from '@emotion/react'; +import type { SelectProps } from '../../../../components/Molecules/Select'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Select component +const selectStyleScript = (props: SelectProps) => { + const variables = props?.theme?.variables; + + // shared styles for select menus + const sharedStyles = css({ + border: `1px solid ${custom.colors.gray02}`, + color: variables?.colors?.text, + backgroundColor: custom.colors.gray01, + }); + + // default styles + const defaultStyles = css([ + { + display: 'block', + '.ss__dropdown': { + '.ss__dropdown__button .ss__button, .ss__dropdown__content .ss__select__select': { + ...sharedStyles, + }, + '.ss__dropdown__button': { + '.ss__button': { + display: 'flex', + padding: `0 ${custom.spacing.x2}px`, + textAlign: 'left', + '.ss__button__content': { + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__select__selection__icon': { + margin: 0, + }, + '.ss__select__selection': { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + fontWeight: 'normal', + }, + '.ss__select__dropdown__button__icon': { + transition: 'transform ease 0.5s', + }, + }, + }, + }, + '.ss__dropdown__content': { + marginTop: `${custom.spacing.x2}px`, + '.ss__select__select': { + padding: `${custom.spacing.x2}px`, + margin: 0, + '.ss__select__select__option': { + gap: `${custom.spacing.x2}px`, + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + color: 'inherit', + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + backgroundColor: 'transparent', + }, + }, + '.ss__select__select__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + }, + }, + }, + '.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__button': { + '.ss__select__dropdown__button__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + }, + }, + ]); + + // native styles + const nativeStyles = css([ + sharedStyles, + { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + padding: `0 ${custom.spacing.x2}px`, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__select__label, .ss__select__select': { + fontSize: custom.utils.convertPxToEm(14), + }, + '.ss__select__label': { + fontWeight: custom.fonts.weight01, + }, + '.ss__select__select': { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + backgroundColor: 'transparent', + border: 'none', + appearance: 'none', + color: 'inherit', + cursor: 'pointer', + '&[disabled]': { + cursor: 'not-allowed', + }, + '&::-ms-expand': { + display: 'none', + }, + }, + '.ss__select__dropdown__button__icon': { + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, + ]); + + return props?.native ? nativeStyles : defaultStyles; +}; + +// Select component props +export const select: ThemeComponent<'select', SelectProps> = { + default: { + select: { + themeStyleScript: selectStyleScript, + iconOpen: custom.icons.arrowDown, + iconClose: custom.icons.arrowDown, + }, + 'select icon.open': { + size: `${custom.sizes.icon12}px`, + }, + 'select dropdown button': { + native: false, + }, + 'select dropdown button icon': { + size: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/slideout.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/slideout.ts new file mode 100644 index 0000000000..ce31c4a0ad --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/slideout.ts @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { SlideoutProps } from '../../../../components/Molecules/Slideout'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Slideout component +const slideoutStyleScript = (props: SlideoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({}); +}; + +// Slideout component props +export const slideout: ThemeComponent<'slideout', SlideoutProps> = { + default: { + slideout: { + themeStyleScript: slideoutStyleScript, + overlayColor: '', + }, + 'slideout button.slideout': { + icon: custom.icons.filter, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/swatches.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/swatches.ts new file mode 100644 index 0000000000..8e7fd1c03a --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/swatches.ts @@ -0,0 +1,249 @@ +import { css } from '@emotion/react'; +import type { SwatchesProps } from '../../../../components/Molecules/Swatches'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import Color from 'color'; + +// Swatch carousel sizes and spacing +const swatchSize = 30; +const swatchSpacing = custom.spacing.x1; + +// CSS in JS style script for the Swatches component +const swatchesStyleScript = (props: SwatchesProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const activeColor = new Color(variables?.colors?.primary || undefined); + const fontColor = + activeColor.isDark() || activeColor.hex().toLowerCase() == '#00aeef' + ? Color(custom.colors.white || undefined) + : Color(custom.colors.black || undefined); + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + + // shared styles for swatches + const sharedStyles = css({ + margin: 0, + }); + + // carousel styles + const carouselStyles = css([ + sharedStyles, + { + margin: 0, + '.ss__carousel': { + '& > div': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + position: 'static', + bottom: 0, + width: `${swatchSize}px`, + height: `${swatchSize}px`, + }, + '.ss__carousel__prev-wrapper': { + margin: `0 ${swatchSpacing}px 0 0`, + }, + '.ss__carousel__next-wrapper': { + margin: `0 0 0 ${swatchSpacing}px`, + }, + '.swiper-container': { + maxWidth: `calc(100% - ${swatchSize * 2 + swatchSpacing * 2}px)`, + '& > .swiper-wrapper': { + '& > .swiper-slide': { + overflow: 'hidden', + width: `${swatchSize}px`, + height: `${swatchSize}px`, + '&:has(.ss__swatches__carousel__swatch.ss__swatches__carousel__swatch--unavailable)': { + '&:before': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + margin: 'auto', + width: '100%', + height: '1px', + borderTop: `3px solid ${darkGray}`, + transform: 'rotate(-45deg)', + }, + }, + }, + }, + }, + '.swiper-container > .swiper-wrapper > .swiper-slide > *, .ss__swatches__carousel__swatch': { + height: `${swatchSize}px`, + lineHeight: 0, + border: 0, + }, + '.ss__swatches__carousel__swatch': { + position: 'relative', + aspectRatio: 1, + color: variables?.colors?.text, + overflow: 'hidden', + '&, &:before, &:after, *': { + boxSizing: 'border-box', + }, + '&:before, &:after': { + content: '""', + display: 'block', + width: 'auto', + height: 'auto', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + transform: 'none', + }, + '&:before': { + border: `3px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&.ss__swatches__carousel__swatch--dark, &:has(.ss__swatches__carousel__swatch__inner--grey)': { + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + color: fontColor.hex(), + }, + }, + }, + '&.ss__swatches__carousel__swatch--selected': { + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + '&:has(.ss__swatches__carousel__swatch__inner:not([style]))': { + backgroundColor: activeColor.hex(), + '&:after': { + borderColor: activeColor.hex(), + opacity: 1, + }, + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + color: fontColor.hex(), + }, + }, + }, + '&:has(.ss__swatches__carousel__swatch__inner .ss__image)': { + backgroundColor: 'transparent', + '&:after': { + borderColor: custom.colors.black, + opacity: 0.3, + }, + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + color: variables?.colors?.text, + }, + }, + }, + '.ss__swatches__carousel__swatch__inner': { + '.ss__swatches__carousel__swatch__value': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + '&.ss__swatches__carousel__swatch--disabled, &.ss__swatches__carousel__swatch--unavailable': { + opacity: 1, + cursor: 'not-allowed', + pointerEvents: 'none', + '.ss__swatches__carousel__swatch__inner:after': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 3, + margin: 'auto', + backgroundColor: darkGray.replace('#', ''), + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center center', + backgroundImage: `url("data:image/svg+xml,%3Csvg style=%27transform: rotate%28-45deg%29%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 56 56%27 preserveAspectRatio=%27xMinYMid%27%3E%3Cpath fill=%27%23${darkGray.replace( + '#', + '' + )}%27 d=%27M0 23.297h56v9.406h-56v-9.406z%27 /%3E%3C/svg%3E")`, + }, + }, + '.ss__swatches__carousel__swatch__inner': { + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + '.ss__swatches__carousel__swatch__value': { + display: 'block', + position: 'absolute', + zIndex: 2, + maxWidth: `calc(100% - ${custom.spacing.x2}px)`, + maxHeight: `calc(100% - ${custom.spacing.x2}px)`, + overflow: 'hidden', + textAlign: 'center', + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1, + }, + }, + }, + }, + }, + ]); + + // grid styles + const gridStyles = css([ + sharedStyles, + { + '.ss__grid': { + '.ss__grid__options': { + '.ss__grid__option:not(.ss__grid__show-more-wrapper)': { + width: `${swatchSize}px`, + maxHeight: `${swatchSize}px`, + }, + }, + }, + }, + ]); + + // return swatch styles + if (props?.type == 'grid') { + return gridStyles; + } else { + return carouselStyles; + } +}; + +// Swatches component props +export const swatches: ThemeComponent<'swatches', SwatchesProps> = { + default: { + swatches: { + themeStyleScript: swatchesStyleScript, + }, + 'swatches carousel': { + autoAdjustSlides: false, + centerInsufficientSlides: false, + slidesPerView: 'auto', + slidesPerGroup: 3, + spaceBetween: `${swatchSpacing}px`, + }, + }, + desktop: { + 'swatches carousel': { + slidesPerView: 'auto', + slidesPerGroup: 2, + spaceBetween: `${swatchSpacing}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/terms.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/terms.ts new file mode 100644 index 0000000000..1edc387a21 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/terms.ts @@ -0,0 +1,87 @@ +import { css } from '@emotion/react'; +import type { TermsProps } from '../../../../components/Molecules/Terms'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Terms component +const termsStyleScript = (props: TermsProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + return css({ + width: '100%', + textAlign: 'left', + 'ul, ul li': { + padding: 0, + margin: 0, + listStyle: 'none', + }, + '.ss__terms__title': { + '&, h5': { + padding: 0, + }, + h5: { + margin: `0 0 ${custom.spacing.x4}px 0`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + textTransform: custom.fonts.transform ? custom.fonts.transform : 'none', + color: variables?.colors?.secondary, + }, + }, + '.ss__terms__options': { + flexFlow: 'row wrap', + justifyContent: 'flex-start', + gap: `${custom.spacing.x1}px ${custom.spacing.x4}px`, + '&, .ss__terms__option': { + listStyle: 'none', + padding: 0, + }, + '.ss__terms__option': { + flex: '0 1 auto', + minWidth: '1px', + color: variables?.colors?.primary, + a: { + padding: 0, + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.primary, + em: { + color: variables?.colors?.text, + fontStyle: 'normal', + fontSize: 'inherit', + fontWeight: 'inherit', + }, + }, + }, + '.ss__terms__option--active': { + 'a, a em': { + fontWeight: custom?.fonts?.weight01, + color: variables?.colors?.primary, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__terms__title': { + h5: { + fontSize: custom.utils.convertPxToEm(14), + }, + }, + '.ss__terms__options': { + '.ss__terms__option': { + a: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }); +}; + +// Terms component props +export const terms: ThemeComponent<'terms', TermsProps> = { + default: { + terms: { + themeStyleScript: termsStyleScript, + emIfy: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/molecules/variantSelection.ts b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/variantSelection.ts new file mode 100644 index 0000000000..41509c3063 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/molecules/variantSelection.ts @@ -0,0 +1,149 @@ +import { css } from '@emotion/react'; +import type { VariantSelectionProps } from '../../../../components/Molecules/VariantSelection'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Swatches component +const variantSelectionStyleScript = (props: VariantSelectionProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + + // shared styles for variant selections + const sharedStyles = css({ + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }); + + // dropdown styles + const dropdownStyles = css([ + sharedStyles, + { + '.ss__dropdown': { + '.ss__dropdown__button, .ss__dropdown__content': { + border: `1px solid ${custom.colors.gray02}`, + color: variables?.colors?.text, + backgroundColor: custom.colors.gray01, + }, + '.ss__dropdown__button': { + width: 'auto', + display: 'flex', + padding: `0 ${custom.spacing.x2}px`, + textAlign: 'left', + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__dropdown__button-wrapper': { + flex: '1 1 0%', + gap: `${custom.spacing.x1}px`, + paddingRight: `${custom.spacing.x1}px`, + fontWeight: 'normal', + '.ss__dropdown__button-wrapper__label': { + fontWeight: custom?.fonts?.weight01, + textTransform: 'capitalize', + }, + }, + '.ss__variant-selection__icon': { + transition: 'transform ease 0.5s', + }, + }, + '.ss__dropdown__content': { + marginTop: `-1px`, + padding: `${custom.spacing.x2}px`, + '.ss__variant-selection__options': { + '&, .ss__variant-selection__option': { + listStyle: 'none', + padding: 0, + margin: 0, + }, + '.ss__variant-selection__option': { + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + fontWeight: 'normal', + }, + }, + '.ss__variant-selection__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__variant-selection__option--unavailable': { + color: lightGray, + cursor: 'not-allowed', + }, + }, + }, + }, + '.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__variant-selection__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + }, + ]); + + // list styles + const listStyles = css([ + sharedStyles, + { + '.ss__list': { + '.ss__list__title, .ss__list__options, .ss__list__options .ss__list__option': { + width: '100%', + color: variables?.colors?.text, + }, + '.ss__list__title': { + textTransform: 'capitalize', + }, + '.ss__list__options': { + '.ss__list__option': { + label: { + color: 'inherit', + }, + }, + '.ss__list__option--selected': { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__list__option--unavailable': { + color: lightGray, + cursor: 'not-allowed', + textDecoration: 'line-through', + }, + }, + }, + }, + ]); + + // swatches syles + const swatchesStyles = css([sharedStyles]); + + // return variant selection styles + if (props?.type == 'list') { + return listStyles; + } else if (props?.type == 'swatches') { + return swatchesStyles; + } else { + return dropdownStyles; + } +}; + +// VariantSelection component props +export const variantSelection: ThemeComponent<'variantSelection', VariantSelectionProps> = { + default: { + variantSelection: { + themeStyleScript: variantSelectionStyleScript, + }, + 'variantSelection dropdown icon': { + size: `${custom.sizes.icon12}px`, + icon: custom.icons.arrowDown, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..a37374b5bd --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/autocomplete.ts @@ -0,0 +1,392 @@ +import { css } from '@emotion/react'; +import type { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; + +// CSS in JS style script for the Autocomplete component +const autocompleteStyleScript = (props: AutocompleteProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const headerSelectors = + '.ss__autocomplete__terms .ss__autocomplete__title h5, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__header, .ss__autocomplete__content__results .ss__autocomplete__title h5, .ss__autocomplete__content__info a, .ss__no-results__recommendations h3'; + const activeSelectors = + '.ss__autocomplete__terms .ss__autocomplete__terms__options .ss__autocomplete__terms__option--active a, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__options .ss__facet-list-options .ss__facet-list-options__option--filtered, .ss__autocomplete__content__results .ss__results .ss__result:hover .ss__result__details .ss__result__details__title a, .ss__autocomplete__content__info a:hover'; + + return css({ + '&.ss__autocomplete': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.white, + width: props?.width, + right: 0, + left: 'auto', + top: 'auto', + margin: `${custom.spacing.x1}px 0 0 0`, + gap: `${custom.spacing.x4}px`, + 'a, div, p': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: 1.5, + color: variables?.colors?.text, + }, + a: { + display: 'block', + }, + '.ss__banner': { + img: { + maxWidth: '100%', + maxHeight: '150px', + height: 'auto', + }, + }, + [headerSelectors]: { + margin: `0 0 ${custom.spacing.x4}px 0`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + lineHeight: 1.2, + color: variables?.colors?.secondary, + }, + [activeSelectors]: { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '& > div': { + minWidth: '1px', + maxWidth: 'none', + flex: '0 1 auto', + padding: `${custom.spacing.x4}px 0`, + order: 0, + '&:first-of-type': { + paddingLeft: `${custom.spacing.x4}px`, + }, + '&:last-of-type': { + paddingRight: `${custom.spacing.x4}px`, + }, + '&.ss__autocomplete__terms': { + padding: 0, + }, + }, + '.ss__autocomplete__terms': { + width: '200px', + backgroundColor: custom.colors.gray01, + textAlign: 'left', + '& > div:first-of-type .ss__autocomplete__title': { + marginTop: `${custom.spacing.x2}px`, + }, + '& > div:last-of-type .ss__autocomplete__terms__options': { + marginBottom: `${custom.spacing.x2}px`, + }, + '& > div': { + '.ss__autocomplete__title': { + padding: 0, + h5: { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms__options': { + '.ss__autocomplete__terms__option': { + a: { + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + fontSize: custom.utils.convertPxToEm(14), + color: variables?.colors?.primary, + em: { + color: variables?.colors?.text, + fontStyle: 'normal', + fontSize: 'inherit', + fontWeight: 'inherit', + }, + }, + }, + '.ss__autocomplete__terms__option--active': { + 'a, a em': { + fontWeight: custom?.fonts?.weight01, + color: variables?.colors?.primary, + }, + }, + }, + }, + }, + '.ss__autocomplete__facets': { + width: '200px', + textAlign: 'left', + '.ss__facets': { + '.ss__facet': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&.ss__facet--showing-all': { + '.ss__facet__options': { + maxHeight: 'none', + overflow: 'visible', + padding: 0, + }, + }, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__facet__header': { + borderBottom: 0, + padding: 0, + '.ss__facet__header__inner': { + fontSize: 'inherit', + fontWeight: 'inherit', + color: 'inherit', + }, + }, + '.ss__facet__options': { + margin: 0, + maxHeight: 'none', + overflow: 'visible', + '.ss__facet-hierarchy-options .ss__facet-hierarchy-options__option, .ss__facet-list-options .ss__facet-list-options__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__facet-list-options': { + '.ss__facet-list-options__option': {}, + }, + }, + }, + }, + }, + '.ss__autocomplete__content': { + flex: '1 1 0%', + overflow: 'visible', + justifyContent: 'flex-start', + }, + '.ss__autocomplete__content__results': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '.ss__results': { + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '75vh', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__result': { + '.ss__result__details': { + gap: `${custom.spacing.x1}px`, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: custom.utils.convertPxToEm(14), + }, + '.ss__price--strike': { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + '.ss__inline-banner': { + maxHeight: '250px', + overflow: 'hidden', + }, + }, + }, + '.ss__autocomplete__content__info': { + padding: 0, + a: { + margin: 0, + '.ss__icon': { + fill: 'currentColor', + stroke: 'currentColor', + }, + }, + }, + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + '.ss__no-results__recommendations': { + margin: `${custom.spacing.x4}px 0 0 0`, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '&.ss__autocomplete': { + flexFlow: 'row wrap', + gap: 0, + width: props?.width, + left: 0, + right: 0, + [headerSelectors]: { + fontSize: custom.utils.convertPxToEm(14), + }, + '& > div': { + flex: '1 1 100%', + borderBottom: `1px solid ${custom.colors.gray02}`, + '&:last-of-type': { + borderBottomWidth: 0, + }, + '&, &.ss__autocomplete__terms': { + padding: `${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms': { + backgroundColor: 'transparent', + display: 'flex', + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + width: 'auto', + '& > div': { + minWidth: '1px', + flex: '1 1 0%', + '&:first-of-type .ss__autocomplete__title': { + marginTop: 0, + }, + '&:last-of-type .ss__autocomplete__terms__options': { + marginBottom: 0, + }, + '.ss__autocomplete__title h5': { + padding: 0, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__autocomplete__terms__options': { + gap: `${custom.spacing.x1}px ${custom.spacing.x4}px`, + flexFlow: 'row wrap', + justifyContent: 'flex-start', + '.ss__autocomplete__terms__option': { + flex: '0 1 auto', + a: { + padding: 0, + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }, + '.ss__autocomplete__terms > div .ss__autocomplete__terms__options, .ss__autocomplete__facets .ss__facets': { + display: 'flex', + }, + '.ss__autocomplete__terms > div .ss__autocomplete__terms__options, .ss__autocomplete__facets .ss__facets .ss__facet': { + minWidth: '1px', + }, + '.ss__autocomplete__facets': { + width: 'auto', + '.ss__facets': { + gap: `0 ${custom.spacing.x4}px`, + flexFlow: 'row nowrap', + '.ss__facet': { + flex: '1 1 0%', + '&, &:last-of-type': { + margin: 0, + }, + }, + }, + }, + '.ss__autocomplete__content__info': { + a: { + '.ss__icon': { + position: 'relative', + top: '1px', + }, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '&.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__recommendation-grid__results': { + gridTemplateColumns: `repeat(2, 1fr)`, + '& > div:nth-of-type(n+3)': { + display: 'none', + }, + }, + }, + }, + }); +}; + +// Autocomplete component props +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + themeStyleScript: autocompleteStyleScript, + width: '900px', + }, + 'autocomplete facet': { + limit: 5, + disableOverflow: true, + disableCollapse: true, + }, + 'autocomplete facets': { + limit: 3, + }, + 'autocomplete facetListOptions': { + hideCheckbox: true, + }, + 'autocomplete facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocomplete facetGridOptions': { + gridSize: '38px', + }, + 'autocomplete results': { + rows: 2, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocomplete icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteThemeComponentProps.mobile, + autocomplete: { + width: '100%', + }, + 'autocomplete results': { + rows: 1, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 1, + columns: 3, + }, + }, + tablet: { + ...autocompleteThemeComponentProps.tablet, + autocomplete: { + width: '100%', + }, + 'autocomplete results': { + rows: 1, + columns: 4, + }, + 'autocomplete recommendationGrid': { + rows: 1, + columns: 4, + }, + }, + desktop: { + ...autocompleteThemeComponentProps.desktop, + autocomplete: {}, + 'autocomplete results': { + rows: 2, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/autocompleteLayout.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/autocompleteLayout.ts new file mode 100644 index 0000000000..c45578d695 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/autocompleteLayout.ts @@ -0,0 +1,451 @@ +import { css } from '@emotion/react'; +import type { AutocompleteLayoutProps } from '../../../../components/Organisms/AutocompleteLayout'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Autocomplete Layout component +const autocompleteLayoutStyleScript = (props: AutocompleteLayoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const textSelectors = 'a, div, p'; + const headerSelectors = + '.ss__terms-list .ss__terms .ss__terms__title h5, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__header, .ss__autocomplete__content .ss__autocomplete__content__results .ss__autocomplete__title h5, .ss__autocomplete__button--see-more .ss__button__content, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__title'; + const activeSelectors = + '.ss__terms-list .ss__terms .ss__terms__options .ss__terms__option.ss__terms__option--active a, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__options .ss__facet-list-options .ss__facet-list-options__option--filtered, .ss__autocomplete__content .ss__autocomplete__content__results .ss__results .ss__result:hover .ss__result__details .ss__result__details__title a, .ss__autocomplete__button--see-more:hover .ss__button__content'; + + // get autocomplete layout + const acLayout = props?.layout ? props.layout : 'standard'; + + // shared autocomplete styles + const sharedStyles = css({ + alignContent: acLayout == 'standard' ? 'normal' : 'flex-start', + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.white, + [textSelectors]: { + fontSize: custom.utils.convertPxToEm(acLayout == 'terms' ? 15 : 12), + lineHeight: 1.5, + color: variables?.colors?.text, + }, + a: { + display: 'block', + }, + 'ul, ul li': { + padding: 0, + margin: 0, + listStyle: 'none', + }, + '.ss__banner': { + img: { + maxWidth: '100%', + maxHeight: '150px', + height: 'auto', + }, + }, + [headerSelectors]: { + margin: `0 0 ${custom.spacing.x4}px 0`, + padding: 0, + fontSize: custom.utils.convertPxToEm(acLayout == 'terms' ? 17 : 16), + fontWeight: custom.fonts.weight02, + lineHeight: 1.2, + color: variables?.colors?.secondary, + }, + [activeSelectors]: { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__autocomplete__row, .ss__autocomplete__column': { + '.ss__search-input': { + background: 'transparent', + width: 'auto', + height: '30px', + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + }, + '.ss__autocomplete__column': { + alignContent: 'flex-start', + minWidth: '1px', + }, + }); + const sharedTabletStyles = css({ + alignContent: 'flex-start', + [textSelectors]: { + fontSize: acLayout == 'terms' ? custom.utils.convertPxToEm(12) : '', + }, + [headerSelectors]: { + fontSize: custom.utils.convertPxToEm(14), + }, + }); + + // terms wrapper styles + const termsWrapperStyles = css({ + '.ss__autocomplete__terms-wrapper': { + backgroundColor: 'transparent', + padding: `${custom.spacing.x4}px`, + }, + }); + + // facets styles + const facetsStyles = css({ + '.ss__autocomplete__facets-wrapper': { + padding: `${custom.spacing.x4}px`, + }, + '.ss__autocomplete__facets': { + padding: 0, + '.ss__facets': { + '.ss__facet': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '&.ss__facet--showing-all': { + '.ss__facet__options': { + maxHeight: 'none', + overflow: 'visible', + padding: 0, + }, + }, + '.ss__facet__header': { + borderBottom: 0, + '.ss__facet__header__inner': { + fontSize: 'inherit', + fontWeight: 'inherit', + color: 'inherit', + }, + }, + '.ss__facet__options': { + '.ss__facet-hierarchy-options .ss__facet-hierarchy-options__option, .ss__facet-list-options .ss__facet-list-options__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + }, + }, + }, + }); + + // content styles + const contentStyles = css({ + '.ss__autocomplete__column:has(.ss__autocomplete__content)': { + alignContent: 'flex-start', + }, + '.ss__autocomplete__content': { + overflow: 'visible', + justifyContent: 'flex-start', + padding: `${custom.spacing.x4}px`, + borderTop: `1px solid ${custom.colors.gray02}`, + '.ss__autocomplete__content-inner': { + padding: 0, + }, + }, + }); + + // results layout styles + const resultsLayoutStyles = css({ + gap: `${custom.spacing.x4}px`, + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '75vh', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__result': { + '.ss__result__details': { + gap: `${custom.spacing.x1}px`, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: custom.utils.convertPxToEm(14), + }, + '.ss__price--strike': { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + }, + }); + + // results styles + const resultsStyles = css({ + '.ss__autocomplete__content__results': { + '.ss__results': { + ...resultsLayoutStyles, + }, + }, + }); + + // no results styles + const noResultsStyles = css({ + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + '.ss__autocomplete__content__no-results__recommendations': { + '.ss__recommendation-grid': { + margin: `${custom.spacing.x4}px 0 0 0`, + }, + '.ss__recommendation-grid__title': { + textAlign: 'left', + }, + '.ss__recommendation-grid__results': { + ...resultsLayoutStyles, + }, + }, + }, + }); + + // see more styles + const seeMoreStyles = css({ + '.ss__autocomplete__button--see-more': { + padding: `${custom.spacing.x4}px`, + paddingTop: 0, + height: 'auto', + '&, &:hover': { + backgroundColor: 'transparent', + border: 0, + }, + '.ss__button__content': { + margin: 0, + '.ss__icon': { + position: 'relative', + top: '0.5px', + margin: `0 0 0 ${custom.spacing.x1}px`, + }, + }, + }, + }); + const seeMoreTabletStyles = css({ + order: -1, + textAlign: 'left', + '.ss__button__content': { + '.ss__icon': { + top: '1.5px', + }, + }, + }); + + // standard styles + const standardStyles = css([ + sharedStyles, + { + '.ss__autocomplete__column': { + '&:has(.ss__autocomplete__terms-wrapper)': { + flex: '1 0 200px', + maxWidth: '200px', + }, + '&:has(.ss__autocomplete__facets-wrapper)': { + flex: '1 0 200px', + maxWidth: '200px', + marginRight: `-${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms-wrapper': { + backgroundColor: custom.colors.gray01, + height: '100%', + }, + '.ss__terms-list': { + display: 'block', + '.ss__terms-list__row': { + '&:first-of-type .ss__terms .ss__terms__title': { + marginTop: `${custom.spacing.x2}px`, + }, + '&:last-of-type .ss__terms .ss__terms__options': { + marginBottom: `${custom.spacing.x2}px`, + }, + }, + '.ss__terms': { + '.ss__terms__title': { + h5: { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__terms__options': { + display: 'block', + margin: 0, + '.ss__terms__option': { + a: { + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__terms__option--active': { + backgroundColor: custom.colors.white, + }, + }, + }, + }, + }, + facetsStyles, + contentStyles, + resultsStyles, + noResultsStyles, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__row:has(.ss__autocomplete__column)': { + display: 'block', + '.ss__autocomplete__column': { + width: '100%', + maxWidth: 'none', + }, + }, + '.ss__autocomplete__column': { + '&:has(.ss__autocomplete__facets-wrapper)': { + marginRight: 0, + }, + }, + '.ss__autocomplete__terms-wrapper': { + backgroundColor: 'transparent', + padding: `${custom.spacing.x4}px`, + }, + '.ss__terms-list': { + display: 'flex', + '.ss__terms-list__row': { + '&:first-of-type .ss__terms .ss__terms__title': { + marginTop: 0, + }, + '&:last-of-type .ss__terms .ss__terms__options': { + marginBottom: 0, + }, + }, + '.ss__terms': { + '.ss__terms__title': { + h5: { + padding: 0, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + }, + '.ss__terms__options': { + display: 'flex', + '.ss__terms__option': { + a: { + padding: 0, + }, + }, + }, + }, + }, + '.ss__autocomplete__facets-wrapper': { + borderTop: `1px solid ${custom.colors.gray02}`, + }, + '.ss__autocomplete__facets': { + '.ss__facets': { + gap: `0 ${custom.spacing.x4}px`, + flexFlow: 'row nowrap', + minWidth: '1px', + '.ss__facet': { + flex: '1 1 0%', + minWidth: '1px', + '&, &:last-of-type': { + margin: 0, + }, + }, + }, + }, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + ]); + + // mini styles + const miniStyles = css([ + sharedStyles, + termsWrapperStyles, + contentStyles, + resultsStyles, + noResultsStyles, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + { + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + gridTemplateColumns: `repeat(2, 1fr)`, + }, + }, + }, + ]); + + // terms styles + const termsStyles = css([ + sharedStyles, + termsWrapperStyles, + contentStyles, + { + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + fontSize: custom.utils.convertPxToEm(14), + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + }, + }, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + fontSize: custom.utils.convertPxToEm(12), + }, + }, + }, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + ]); + + // return autocomplete styles + if (acLayout == 'terms') { + return termsStyles; + } else if (acLayout == 'mini') { + return miniStyles; + } else { + return standardStyles; + } +}; + +// Autocomplete Layout component props +export const autocompleteLayout: ThemeComponent<'autocompleteLayout', AutocompleteLayoutProps> = { + default: { + autocompleteLayout: { + themeStyleScript: autocompleteLayoutStyleScript, + contentTitle: 'Product Suggestions', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facet.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facet.ts new file mode 100644 index 0000000000..3108a816ac --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facet.ts @@ -0,0 +1,80 @@ +import { css } from '@emotion/react'; +import type { FacetProps } from '../../../../components/Organisms/Facet'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Facet component +const facetStyleScript = (props: FacetProps) => { + const variables = props?.theme?.variables; + + return css({ + '&.ss__facet--collapsed': { + '.ss__facet__header': { + '.ss__icon': { + transform: 'rotate(0deg)', + }, + }, + }, + '&.ss__facet--showing-all': { + '.ss__facet__options': { + maxHeight: `490px`, + overflowY: 'auto', + overflowX: 'hidden', + paddingRight: `${custom.spacing.x2}px`, + }, + }, + '.ss__facet__header': { + gap: `${custom.spacing.x2}px`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + '.ss__icon': { + transition: 'transform ease 0.5s', + transform: 'rotate(180deg)', + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + fill: variables?.colors?.primary, + stroke: variables?.colors?.primary, + }, + }, + '.ss__facet__options': { + marginTop: 0, + maxHeight: 'none', + overflow: 'visible', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + }, + '.ss__facet__show-more-less': { + margin: `${custom.spacing.x2}px 0 0 0`, + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '.ss__icon': { + position: 'relative', + top: '-0.5px', + marginRight: `${custom.spacing.x1}px`, + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + }, + }, + }); +}; + +// Facet component props +export const facet: ThemeComponent<'facet', FacetProps> = { + default: { + facet: { + themeStyleScript: facetStyleScript, + iconCollapse: custom.icons.arrowDown, + iconExpand: custom.icons.arrowDown, + iconOverflowMore: custom.icons.plus, + iconOverflowLess: custom.icons.minus, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facets.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facets.ts new file mode 100644 index 0000000000..ff933eb030 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facets.ts @@ -0,0 +1,25 @@ +import { css } from '@emotion/react'; +import type { FacetsProps } from '../../../../components/Organisms/Facets'; +import { ThemeComponent } from '../../../../providers'; + +// CSS in JS style script for the Facets component +const facetsStyleScript = (props: FacetsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '&.ss__facets': { + display: 'block', + width: 'auto', + }, + }); +}; + +// Facets component props +export const facets: ThemeComponent<'facets', FacetsProps> = { + default: { + facets: { + themeStyleScript: facetsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facetsHorizontal.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facetsHorizontal.ts new file mode 100644 index 0000000000..ea6f249453 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/facetsHorizontal.ts @@ -0,0 +1,239 @@ +import { css } from '@emotion/react'; +import type { FacetsHorizontalProps } from '../../../../components/Organisms/FacetsHorizontal'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Facets component +const facetsHorizontalStyleScript = (props: FacetsHorizontalProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const columnsSelector = `.ss__facet-hierarchy-options, .ss__facet-list-options, .ss__facet-palette-options.ss__facet-palette-options--list`; + + return css({ + margin: 0, + '.ss__facets-horizontal__header': { + gap: 0, + margin: `0 -${custom.spacing.x1}px -${custom.spacing.x2}px -${custom.spacing.x1}px `, + position: 'relative', + '& > *': { + boxSizing: 'border-box', + minWidth: '1px', + width: `${100 / 6}%`, + flex: '0 1 auto', + padding: `0 ${custom.spacing.x1}px`, + }, + '& > *, .ss__facets-horizontal__header__dropdown, .ss__mobile-sidebar': { + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + '.ss__facets-horizontal__header__dropdown': { + position: 'static', + '&.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__dropdown__button__heading': { + '.ss__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + '.ss__dropdown__content': { + width: 'auto', + minWidth: '1px', + maxHeight: 'none', + overflowY: 'visible', + padding: `${custom.spacing.x2}px`, + marginTop: `${custom.spacing.x2}px`, + left: `${custom.spacing.x1}px`, + right: `${custom.spacing.x1}px`, + }, + }, + '.ss__dropdown__button, .ss__dropdown__content': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.gray01, + }, + '.ss__dropdown__button': { + display: 'block', + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + padding: `0 ${custom.spacing.x2}px`, + textAlign: 'left', + color: variables?.colors?.text, + '.ss__dropdown__button__heading': { + flexFlow: 'row nowrap', + justifyContent: 'flex-start', + gap: `${custom.spacing.x1}px`, + padding: 0, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + span: { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + fontWeight: custom.fonts.weight01, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + '.ss__icon': { + transition: 'transform ease 0.5s', + }, + }, + }, + '.ss__dropdown__content': { + width: 'auto', + padding: `${custom.spacing.x2}px`, + [columnsSelector]: { + display: 'flex', + flexFlow: 'row wrap', + gap: `0 ${custom.spacing.x2}px`, + '& > *': { + flex: '0 1 auto', + width: `${100 / 4 - 2}%`, + minWidth: '1px', + boxSizing: 'border-box', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }, + '.ss__checkbox, .ss__radio, .ss__search-input .ss__search-input__input': { + backgroundColor: custom.colors.white, + }, + '.ss__facet': { + margin: 0, + }, + '.ss__facet.ss__facet--showing-all .ss__facet__options': { + maxHeight: '360px', + }, + '.ss__facet-list-options': { + marginBottom: `-${custom.spacing.x1}px`, + '.ss__facet-list-options__option:last-of-type': { + marginBottom: `${custom.spacing.x1}px`, + }, + }, + '.ss__facet-hierarchy-options': { + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--filtered': { + '& ~ .ss__facet-hierarchy-options__option:not(.ss__facet-hierarchy-options__option--filtered)': { + paddingLeft: 0, + }, + }, + }, + '.ss__facet-grid-options': { + '.ss__facet-grid-options__option:not(.ss__facet-grid-options__option--filtered)': { + '&:after': { + backgroundColor: custom.colors.white, + }, + }, + }, + '.ss__facet--slider': { + '.ss__facet__options': { + display: 'flex', + minHeight: '100px', + '.ss__facet-slider': { + width: '100%', + }, + }, + }, + '.ss__facet__show-more-less': { + textAlign: 'center', + }, + }, + }, + '.ss__mobile-sidebar': { + '.ss__slideout__button .ss__button': { + display: 'flex', + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__facets-horizontal__header': { + '& > *': { + width: `${100 / 4}%`, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content': { + [columnsSelector]: { + '& > *': { + width: `${100 / 3 - 2}%`, + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__facets-horizontal__header': { + '& > *': { + width: `${100 / 2}%`, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content': { + [columnsSelector]: { + '& > *': { + width: `${100 / 2 - 2}%`, + }, + }, + }, + }, + }, + }); +}; + +// FacetsHorizontal component props +export const facetsHorizontal: ThemeComponent<'facetsHorizontal', FacetsHorizontalProps> = { + default: { + facetsHorizontal: { + themeStyleScript: facetsHorizontalStyleScript, + iconExpand: custom.icons.arrowDown, + iconCollapse: custom.icons.arrowDown, + alwaysShowFiltersButton: true, + }, + 'facetsHorizontal dropdown button icon': { + size: `${custom.sizes.icon12}px`, + }, + 'facetsHorizontal dropdown facet': { + statefulOverflow: true, + display: { + list: { + limit: 32, + }, + hierarchy: { + limit: 32, + }, + grid: { + limit: 34, + }, + palette: { + limit: 34, + }, + }, + }, + 'facetsHorizontal mobileSidebar facet': { + statefulOverflow: true, + display: { + list: { + limit: 10, + }, + hierarchy: { + limit: 10, + }, + grid: { + limit: 12, + }, + palette: { + limit: 12, + }, + }, + }, + 'facetsHorizontal facetGridOptions': { + gridSize: '62px', + }, + 'facetsHorizontal mobileSidebar facetGridOptions': { + gridSize: '52px', + }, + 'facetsHorizontal facetPaletteOptions': { + gridSize: '62px', + }, + 'facetsHorizontal mobileSidebar facetPaletteOptions': { + gridSize: '52px', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/filterSummary.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/filterSummary.ts new file mode 100644 index 0000000000..7c60576c1f --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/filterSummary.ts @@ -0,0 +1,90 @@ +import { css } from '@emotion/react'; +import type { FilterSummaryProps } from '../../../../components/Organisms/FilterSummary'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FilterSummary component +const filterSummaryStyleScript = (props: FilterSummaryProps) => { + const variables = props?.theme?.variables; + const darkGray = custom.utils.darkenColor(custom.colors.gray02, 0.075); + const listSpacing = custom.sizes.icon16 + custom.spacing.x2; + + // shared palette styles + const sharedStyles = css({ + '.ss__filter-summary__title': { + padding: 0, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__filter-summary__filters': { + margin: 0, + }, + }); + + // inline filter summary styles + const inlineStyles = css([ + sharedStyles, + { + '&.ss__filter-summary--inline': { + '.ss__filter-summary__filters': { + gap: `${custom.spacing.x1}px`, + }, + }, + }, + ]); + + // list filter summary styles + const listStyles = css([ + sharedStyles, + { + '&.ss__filter-summary--list': { + '.ss__filter-summary__filters': { + '.ss__filter': { + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__filter__button': { + '.ss__button__content': { + position: 'relative', + padding: `0 0 0 ${listSpacing}px`, + '.ss__filter__button__icon': { + position: 'absolute', + top: '1.5px', + left: 0, + padding: '3px', + backgroundColor: custom.colors.gray01, + border: `1px solid ${darkGray}`, + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + boxSizing: 'border-box', + }, + '.ss__filter__label, .ss__filter__value': { + margin: 0, + }, + '.ss__filter__label': { + padding: '0 4px 0 0', + }, + }, + }, + }, + }, + }, + }, + ]); + + return props?.type == 'list' ? listStyles : inlineStyles; +}; + +// FilterSummary component props +export const filterSummary: ThemeComponent<'filterSummary', FilterSummaryProps> = { + default: { + filterSummary: { + themeStyleScript: filterSummaryStyleScript, + clearAllIcon: custom.icons.close, + filterIcon: custom.icons.close, + hideTitle: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/index.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/index.ts new file mode 100644 index 0000000000..11cfc74d31 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/index.ts @@ -0,0 +1,74 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// ORGANISMS Imports +import { autocomplete } from './autocomplete'; +import { autocompleteLayout } from './autocompleteLayout'; +import { facet } from './facet'; +import { facets } from './facets'; +import { facetsHorizontal } from './facetsHorizontal'; +import { filterSummary } from './filterSummary'; +import { mobileSidebar } from './mobileSidebar'; +import { noResults } from './noResults'; +import { results } from './results'; +import { sidebar } from './sidebar'; +import { termsList } from './termsList'; +import { toolbar } from './toolbar'; + +export const organisms: ThemeResponsiveComplete = { + default: { + ...autocomplete.default, + ...autocompleteLayout.default, + ...facet.default, + ...facets.default, + ...facetsHorizontal.default, + ...filterSummary.default, + ...mobileSidebar.default, + ...noResults.default, + ...results.default, + ...sidebar.default, + ...toolbar.default, + ...termsList.default, + }, + mobile: { + ...autocomplete.mobile, + ...autocompleteLayout.mobile, + ...facet.mobile, + ...facets.mobile, + ...facetsHorizontal.mobile, + ...filterSummary.mobile, + ...mobileSidebar.mobile, + ...noResults.mobile, + ...results.mobile, + ...sidebar.mobile, + ...toolbar.mobile, + ...termsList.mobile, + }, + tablet: { + ...autocomplete.tablet, + ...autocompleteLayout.tablet, + ...facet.tablet, + ...facets.tablet, + ...facetsHorizontal.tablet, + ...filterSummary.tablet, + ...mobileSidebar.tablet, + ...noResults.tablet, + ...results.tablet, + ...sidebar.tablet, + ...toolbar.tablet, + ...termsList.tablet, + }, + desktop: { + ...autocomplete.desktop, + ...autocompleteLayout.desktop, + ...facet.desktop, + ...facets.desktop, + ...facetsHorizontal.desktop, + ...filterSummary.desktop, + ...mobileSidebar.desktop, + ...noResults.desktop, + ...results.desktop, + ...sidebar.desktop, + ...toolbar.desktop, + ...termsList.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/mobileSidebar.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/mobileSidebar.ts new file mode 100644 index 0000000000..5ffe75c687 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/mobileSidebar.ts @@ -0,0 +1,130 @@ +import { css } from '@emotion/react'; +import type { MobileSidebarProps } from '../../../../components/Organisms/MobileSidebar'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the MobileSidebar component +const mobileSidebarStyleScript = (props: MobileSidebarProps) => { + const variables = props?.theme?.variables; + const headerHeight = 60; + const footerHeight = 75; + + return css({ + '.ss__mobile-sidebar__slideout': { + overflowY: 'hidden', + padding: 0, + width: '100%', + '.ss__mobile-sidebar__content': { + height: '100%', + '.ss__mobile-sidebar__header, .ss__mobile-sidebar__footer': { + padding: `0 ${custom.spacing.x4}px`, + gap: `${custom.spacing.x2}px`, + alignItems: 'center', + }, + '.ss__mobile-sidebar__header': { + height: `${headerHeight}px`, + backgroundColor: variables?.colors?.primary, + color: custom.colors.white, + '.ss__mobile-sidebar__header__title': { + margin: 0, + fontSize: custom.utils.convertPxToEm(18), + }, + '.ss__mobile-sidebar__header__close-button': { + padding: 0, + width: '16px', + height: '16px', + lineHeight: '16px', + '.ss__icon': { + width: '100%', + height: '100%', + lineHeight: 1, + }, + }, + }, + '.ss__mobile-sidebar__footer': { + height: `${footerHeight}px`, + backgroundColor: custom.colors.white, + borderTop: `1px solid ${custom.colors.gray02}`, + '.ss__button': { + flex: `1 1 0%`, + }, + }, + '.ss__mobile-sidebar__inner': { + height: `calc(100% - ${headerHeight + footerHeight}px)`, + overflowY: 'auto', + overflowX: 'hidden', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__layout': { + overflow: 'hidden', + display: 'block', + '& > *': { + borderBottom: `1px solid ${custom.colors.gray02}`, + padding: `${custom.spacing.x4}px`, + '&:last-of-type': { + borderBottomWidth: 0, + }, + }, + }, + '.ss__select--native': { + padding: `0 ${custom.spacing.x4}px`, + borderTop: 0, + height: '40px', + lineHeight: '40px', + }, + '.ss__filter-summary, .ss__facets': { + padding: 0, + }, + '.ss__filter-summary .ss__filter-summary__title, .ss__facets .ss__facet .ss__facet__header': { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: 0, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.text, + }, + '.ss__filter-summary .ss__filter-summary__filters, .ss__facets .ss__facet .ss__dropdown__content': { + padding: `${custom.spacing.x4}px`, + }, + '.ss__facets .ss__facet': { + margin: 0, + width: 'auto', + '&.ss__facet--collapsed': { + borderBottom: `1px solid ${custom.colors.gray02}`, + }, + '.ss__facet__header': { + '.ss__icon': { + fill: 'currentColor', + stroke: 'currentColor', + }, + }, + }, + }, + }, + }, + }); +}; + +// MobileSidebar component props +export const mobileSidebar: ThemeComponent<'mobileSidebar', MobileSidebarProps> = { + default: { + mobileSidebar: { + themeStyleScript: mobileSidebarStyleScript, + }, + 'mobileSidebar button.close': { + icon: custom.icons.close, + }, + 'mobileSidebar toolbar filterSummary': { + title: 'Current Filters', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/noResults.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/noResults.ts new file mode 100644 index 0000000000..c7a685676b --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/noResults.ts @@ -0,0 +1,61 @@ +import { css } from '@emotion/react'; +import type { NoResultsProps } from '../../../../components/Organisms/NoResults'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the NoResults component +const noResultsStyleScript = (props: NoResultsProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + 'h1, h2, h3, h4, h5, h6, ul': { + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + 'h1, h2, h3, h4, h5, h6, .ss__no-results__recommendations .ss__recommendation .ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(20), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + 'ul li, p': { + color: variables?.colors?.text, + }, + a: { + color: variables?.colors?.primary, + '&:hover': { + color: variables?.colors?.secondary, + }, + }, + ul: { + padding: 0, + marginLeft: `${custom.spacing.x8}px`, + listStyle: 'none', + li: { + listStyle: 'disc', + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + '.ss__no-results__recommendations': { + '.ss__recommendation': { + margin: `${custom.spacing.x4}px 0`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + 'h1, h2, h3, h4, h5, h6, .ss__no-results__recommendations .ss__recommendation .ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(18), + }, + }, + }); +}; + +// NoResults component props +export const noResults: ThemeComponent<'noResults', NoResultsProps> = { + default: { + noResults: { + themeStyleScript: noResultsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/results.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/results.ts new file mode 100644 index 0000000000..fabe87ac2f --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/results.ts @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; +import type { ResultsProps } from '../../../../components/Organisms/Results'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Results component +const resultsStyleScript = (props: ResultsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '& > *': { + minWidth: '1px', + }, + }); +}; + +// Results component props +export const results: ThemeComponent<'results', ResultsProps> = { + default: { + results: { + themeStyleScript: resultsStyleScript, + gapSize: `${custom.spacing.x6}px ${custom.spacing.x4}px`, + columns: 4, + }, + }, + mobile: { + results: { + gapSize: `${custom.spacing.x6}px ${custom.spacing.x2}px`, + columns: 2, + }, + }, + tablet: { + results: { + columns: 3, + }, + }, + desktop: {}, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/sidebar.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/sidebar.ts new file mode 100644 index 0000000000..60ef58fa2c --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/sidebar.ts @@ -0,0 +1,57 @@ +import { css } from '@emotion/react'; +import type { SidebarProps } from '../../../../components/Organisms/Sidebar'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Sidebar component +const sidebarStyleScript = (props: SidebarProps) => { + const variables = props?.theme?.variables; + + return css({ + '.ss__sidebar__title': { + margin: `0 0 ${custom.spacing.x6}px 0`, + fontSize: custom.utils.convertPxToEm(20), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__sidebar__inner': { + '.ss__layout': { + '&, .ss__layout__row': { + display: 'block', + }, + '.ss__layout__row': { + minWidth: '1px', + '& > div:only-child': { + width: 'auto', + }, + }, + }, + '.ss__layout .ss__layout__row, .ss__facets .ss__facet': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__filter-summary .ss__filter-summary__title, .ss__facets .ss__facet .ss__facet__header': { + margin: ` 0 0 ${custom.spacing.x4}px 0`, + padding: ` 0 0 ${custom.spacing.x2}px 0`, + borderBottom: `2px solid ${variables?.colors?.primary}`, + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + }, + }); +}; + +// Sidebar component props +export const sidebar: ThemeComponent<'sidebar', SidebarProps> = { + default: { + sidebar: { + themeStyleScript: sidebarStyleScript, + }, + 'sidebar toolbar filterSummary': { + title: 'Current Filters', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/termsList.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/termsList.ts new file mode 100644 index 0000000000..82e5dcc2c3 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/termsList.ts @@ -0,0 +1,29 @@ +import { css } from '@emotion/react'; +import type { TermsListProps } from '../../../../components/Organisms/TermsList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the TermsList component +const termsListStyleScript = (props: TermsListProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + backgroundColor: 'transparent', + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + '.ss__terms-list-row': { + flex: '1 1 0%', + minWidth: '1px', + }, + }); +}; + +// TermsList component props +export const termsList: ThemeComponent<'termsList', TermsListProps> = { + default: { + termsList: { + themeStyleScript: termsListStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/organisms/toolbar.ts b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/toolbar.ts new file mode 100644 index 0000000000..8370fe5eed --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/organisms/toolbar.ts @@ -0,0 +1,73 @@ +import { css } from '@emotion/react'; +import { ThemeComponent } from '../../../../providers'; +import { ToolbarProps } from '../../../../components/Organisms/Toolbar'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Toolbar component +const toolbarStyleScript = (props: ToolbarProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '.ss__layout': { + gap: `${custom.spacing.x2}px`, + margin: 0, + }, + '&[class*="bottom"]': { + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(14), + }, + }, + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(16), + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(18), + }, + }, + '& > .ss__layout > .ss__layout__row > .ss__filter-summary': { + display: 'flex', + flexFlow: 'row wrap', + '.ss__filter-summary__title, .ss__filter-summary__filters': { + minWidth: '1px', + }, + '.ss__filter-summary__title': { + flex: '0 1 auto', + padding: `0 ${custom.spacing.x2}px 0 0`, + }, + '.ss__filter-summary__filters': { + flex: '1 1 0%', + }, + '&.ss__filter-summary--inline': { + '.ss__filter-summary__title': { + paddingTop: `${custom.spacing.x1}px`, + paddingBottom: `${custom.spacing.x1}px`, + }, + }, + '&.ss__filter-summary--list': { + '.ss__filter-summary__filters': { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + gap: `${custom.spacing.x2}px`, + '.ss__filter': { + margin: 0, + }, + }, + }, + }, + }); +}; + +// Toolbar component props +export const toolbar: ThemeComponent<'toolbar', ToolbarProps> = { + default: { + toolbar: { + themeStyleScript: toolbarStyleScript, + }, + 'toolbar filterSummary': { + title: `Current Filters:`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteFixed.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteFixed.ts new file mode 100644 index 0000000000..7e1248d02c --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteFixed.ts @@ -0,0 +1,187 @@ +import { css } from '@emotion/react'; +import { autocompleteFixedThemeComponentProps } from '../../../themeComponents/autocompleteFixed'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteFixedProps } from '../../../../components/Templates/AutocompleteFixed'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteFixedStyleScript = (props: AutocompleteFixedProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + return css({ + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-fixed__inner': { + '& > .ss__search-input.autocomplete-fixed__search-input': { + height: '40px', + margin: `0 0 ${custom.spacing.x2}px 0`, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '40px', + }, + }, + '.ss__autocomplete-fixed__inner__layout-wrapper': { + maxHeight: 'none', + width: 'auto', + '&, .ss__autocomplete': { + overflowY: 'visible', + }, + '.ss__autocomplete': { + maxWidth: 'none', + width: props?.width, + right: 0, + left: '-102px', + top: 'auto', + margin: 'auto', + }, + }, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-fixed__inner': { + '.ss__autocomplete-fixed__inner__layout-wrapper': { + '.ss__autocomplete': { + maxWidth: '100%', + width: props?.width, + left: 0, + right: 0, + }, + }, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-fixed__inner': { + '.ss__autocomplete-fixed__inner__layout-wrapper': { + '.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + '& > *:nth-of-type(n+3)': { + display: 'none', + }, + }, + }, + }, + }, + }, + }, + }, + }); +}; + +export const autocompleteFixed: ThemeComponent<'autocompleteFixed', AutocompleteFixedProps> = { + default: { + ...autocompleteFixedThemeComponentProps.default, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.default?.['autocompleteFixed'] || {}), + themeStyleScript: autocompleteFixedStyleScript, + width: '900px', + layout: 'standard', + }, + 'autocompleteFixed facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocompleteFixed facetGridOptions': { + gridSize: '38px', + }, + 'autocompleteFixed facet': { + ...(autocompleteFixedThemeComponentProps.default?.['autocompleteFixed facet'] || {}), + display: { + list: { + limit: 5, + }, + hierarchy: { + limit: 5, + }, + grid: { + limit: 6, + }, + palette: { + limit: 6, + }, + }, + }, + 'autocompleteFixed results': { + rows: 2, + columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocompleteFixed button.see-more icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteFixedThemeComponentProps.mobile, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.mobile?.['autocompleteFixed'] || {}), + width: 'auto', + layout: 'mini', + }, + 'autocompleteFixed results': { + rows: 1, + columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + rows: 1, + columns: 3, + }, + }, + tablet: { + ...autocompleteFixedThemeComponentProps.tablet, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.tablet?.['autocompleteFixed'] || {}), + width: 'auto', + layout: 'standard', + }, + 'autocompleteFixed facet': { + display: { + list: { + limit: 3, + }, + hierarchy: { + limit: 3, + }, + grid: { + limit: 4, + }, + palette: { + limit: 4, + }, + }, + }, + 'autocompleteFixed results': { + rows: 1, + columns: 4, + }, + 'autocompleteFixed recommendationGrid': { + rows: 1, + columns: 4, + }, + }, + desktop: { + ...autocompleteFixedThemeComponentProps.desktop, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.desktop?.['autocompleteFixed'] || {}), + layout: 'standard', + }, + 'autocompleteFixed results': { + rows: 2, + columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteModal.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteModal.ts new file mode 100644 index 0000000000..6c01ac334d --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteModal.ts @@ -0,0 +1,204 @@ +import { css } from '@emotion/react'; +import { autocompleteModalThemeComponentProps } from '../../../themeComponents/autocompleteModal'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteModalProps } from '../../../../components/Templates/AutocompleteModal'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteModalStyleScript = (props: AutocompleteModalProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '.ss__modal': { + '&, .ss__modal__content': { + height: '100%', + }, + '.ss__modal__content': { + backgroundColor: 'transparent', + justifyContent: 'center', + '&, .ss__autocomplete-modal__inner': { + position: 'static', + display: 'flex', + flexFlow: 'column nowrap', + }, + '.ss__autocomplete-modal__inner': { + width: props?.width, + maxHeight: 'none', + height: '80vh', + overflow: 'hidden', + '& > .ss__search-input.autocomplete-modal__search-input, .ss__autocomplete': { + minHeight: '1px', + minWidth: '1px', + }, + '& > .ss__search-input.autocomplete-modal__search-input': { + flex: '0 1 auto', + height: '40px', + margin: 0, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '40px', + }, + }, + '.ss__autocomplete': { + flex: '1 1 0%', + borderWidth: 0, + overflowY: 'auto', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + maxHeight: 'none', + overflow: 'visible', + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-modal__inner': { + width: props?.width, + height: '100%', + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__modal': { + '.ss__modal__content': { + '.ss__autocomplete-modal__inner': { + '.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + '& > *:nth-of-type(n+5)': { + display: 'none', + }, + }, + }, + }, + }, + }, + }, + }); +}; + +export const autocompleteModal: ThemeComponent<'autocompleteModal', AutocompleteModalProps> = { + default: { + ...autocompleteModalThemeComponentProps.default, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.default?.['autocompleteModal'] || {}), + themeStyleScript: autocompleteModalStyleScript, + width: '70vw', + layout: 'standard', + }, + 'autocompleteModal facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocompleteModal facetGridOptions': { + gridSize: '38px', + }, + 'autocompleteModal facet': { + ...(autocompleteModalThemeComponentProps.default?.['autocompleteModal facet'] || {}), + display: { + list: { + limit: 5, + }, + hierarchy: { + limit: 5, + }, + grid: { + limit: 6, + }, + palette: { + limit: 6, + }, + }, + }, + 'autocompleteModal results': { + rows: 2, + columns: 3, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocompleteModal button.see-more icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteModalThemeComponentProps.mobile, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.mobile?.['autocompleteModal'] || {}), + width: '100%', + layout: 'mini', + }, + 'autocompleteModal results': { + rows: 2, + columns: 3, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 3, + }, + }, + tablet: { + ...autocompleteModalThemeComponentProps.tablet, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.tablet?.['autocompleteModal'] || {}), + width: '80vw', + layout: 'standard', + }, + 'autocompleteModal facet': { + display: { + list: { + limit: 3, + }, + hierarchy: { + limit: 3, + }, + grid: { + limit: 4, + }, + palette: { + limit: 4, + }, + }, + }, + 'autocompleteModal results': { + rows: 2, + columns: 4, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 4, + }, + }, + desktop: { + ...autocompleteModalThemeComponentProps.desktop, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.desktop?.['autocompleteModal'] || {}), + width: '80vw', + layout: 'standard', + }, + 'autocompleteModal results': { + rows: 2, + columns: 3, + }, + 'autocompleteModal recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteSlideout.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteSlideout.ts new file mode 100644 index 0000000000..580ff67d0f --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/autocompleteSlideout.ts @@ -0,0 +1,129 @@ +import { css } from '@emotion/react'; +import { autocompleteSlideoutThemeComponentProps } from '../../../themeComponents/autocompleteSlideout'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteSlideoutProps } from '../../../../components/Templates/AutocompleteSlideout'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteSlideoutStyleScript = (props: AutocompleteSlideoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + border: 0, + padding: `${custom.spacing.x4}px`, + '.ss__autocomplete-slideout__inner': { + display: 'flex', + flexFlow: 'column nowrap', + height: '100%', + '& > .ss__search-input.autocomplete-slideout__search-input, .ss__autocomplete': { + minHeight: '1px', + minWidth: '1px', + }, + '& > .ss__search-input.autocomplete-slideout__search-input': { + flex: '0 1 auto', + height: '40px', + margin: `0 0 ${custom.spacing.x2}px 0`, + '.ss__button, .ss__search-input__button--close-search-button': { + width: '40px', + }, + }, + '.ss__autocomplete': { + flex: '1 1 0%', + alignContent: 'flex-start', + borderWidth: 0, + overflowY: 'auto', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '& > .ss__autocomplete__row .ss__autocomplete__column': { + padding: `${custom.spacing.x4}px 0`, + }, + '.ss__autocomplete__terms-wrapper, .ss__autocomplete__content, .ss__autocomplete__button--see-more': { + paddingLeft: 0, + paddingRight: 0, + }, + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + maxHeight: 'none', + overflow: 'visible', + }, + }, + }, + }); +}; + +export const autocompleteSlideout: ThemeComponent<'autocompleteSlideout', AutocompleteSlideoutProps> = { + default: { + ...autocompleteSlideoutThemeComponentProps.default, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.default?.['autocompleteSlideout'] || {}), + themeStyleScript: autocompleteSlideoutStyleScript, + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout button.see-more icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteSlideoutThemeComponentProps.mobile, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.mobile?.['autocompleteSlideout'] || {}), + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 2, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 2, + }, + }, + tablet: { + ...autocompleteSlideoutThemeComponentProps.tablet, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.tablet?.['autocompleteSlideout'] || {}), + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 3, + }, + }, + desktop: { + ...autocompleteSlideoutThemeComponentProps.desktop, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.desktop?.['autocompleteSlideout'] || {}), + layout: 'mini', + }, + 'autocompleteSlideout results': { + rows: 2, + columns: 3, + }, + 'autocompleteSlideout recommendationGrid': { + rows: 2, + columns: 3, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/index.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/index.ts new file mode 100644 index 0000000000..e6bef36cef --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/index.ts @@ -0,0 +1,79 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// TEMPLATES +import { autocompleteFixed } from './autocompleteFixed'; +import { autocompleteModal } from './autocompleteModal'; +import { autocompleteSlideout } from './autocompleteSlideout'; +import { recommendation } from './recommendation'; +import { recommendationBundle } from './recommendationBundle'; +import { recommendationBundleEasyAdd } from './recommendationBundleEasyAdd'; +import { recommendationBundleList } from './recommendationBundleList'; +import { recommendationBundleVertical } from './recommendationBundleVertical'; +import { recommendationGrid } from './recommendationGrid'; +import { recommendationEmail } from './recommendationEmail'; +import { search } from './search'; +import { searchHorizontal } from './searchHorizontal'; +import { searchCollapsible } from './searchCollapsible'; + +export const templates: ThemeResponsiveComplete = { + default: { + ...autocompleteFixed.default, + ...autocompleteModal.default, + ...autocompleteSlideout.default, + ...recommendation.default, + ...recommendationBundle.default, + ...recommendationBundleEasyAdd.default, + ...recommendationBundleList.default, + ...recommendationBundleVertical.default, + ...recommendationGrid.default, + ...recommendationEmail.default, + ...search.default, + ...searchCollapsible.default, + ...searchHorizontal.default, + }, + mobile: { + ...autocompleteFixed.mobile, + ...autocompleteModal.mobile, + ...autocompleteSlideout.mobile, + ...recommendation.mobile, + ...recommendationBundle.mobile, + ...recommendationBundleEasyAdd.mobile, + ...recommendationBundleList.mobile, + ...recommendationBundleVertical.mobile, + ...recommendationGrid.mobile, + ...recommendationEmail.mobile, + ...search.mobile, + ...searchCollapsible.mobile, + ...searchHorizontal.mobile, + }, + tablet: { + ...autocompleteFixed.tablet, + ...autocompleteModal.tablet, + ...autocompleteSlideout.tablet, + ...recommendation.tablet, + ...recommendationBundle.tablet, + ...recommendationBundleEasyAdd.tablet, + ...recommendationBundleList.tablet, + ...recommendationBundleVertical.tablet, + ...recommendationGrid.tablet, + ...recommendationEmail.tablet, + ...search.tablet, + ...searchCollapsible.tablet, + ...searchHorizontal.tablet, + }, + desktop: { + ...autocompleteFixed.desktop, + ...autocompleteModal.desktop, + ...autocompleteSlideout.desktop, + ...recommendation.desktop, + ...recommendationBundle.desktop, + ...recommendationBundleEasyAdd.desktop, + ...recommendationBundleList.desktop, + ...recommendationBundleVertical.desktop, + ...recommendationGrid.desktop, + ...recommendationEmail.desktop, + ...search.desktop, + ...searchCollapsible.desktop, + ...searchHorizontal.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendation.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendation.ts new file mode 100644 index 0000000000..5765da87c9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendation.ts @@ -0,0 +1,122 @@ +import { css } from '@emotion/react'; +import type { RecommendationProps } from '../../../../components/Templates/Recommendation'; +import { recommendationThemeComponentProps } from '../../../themeComponents/recommendation'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Recommendation component +const recommendationStyleScript = (props: RecommendationProps) => { + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + const arrowSizes = { + default: 32, + tablet: 28, + mobile: 24, + }; + + return css({ + margin: `${custom.spacing.x8}px 0`, + '.ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + textAlign: 'center', + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__carousel': { + padding: `0 ${custom.spacing.x4 + arrowSizes.default}px`, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__carousel': { + padding: `0 ${custom.spacing.x4 + arrowSizes.tablet}px`, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + width: `${arrowSizes.tablet}px`, + height: `${arrowSizes.tablet}px`, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + position: 'relative', + '.ss__recommendation__title': { + textAlign: 'left', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', + paddingRight: `${arrowSizes.mobile * 2 + custom.spacing.x1 + custom.spacing.x4}px`, + }, + '.ss__carousel': { + padding: 0, + position: 'static', + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + top: '4.5px', + bottom: 'auto', + left: 'auto', + width: `${arrowSizes.mobile}px`, + height: `${arrowSizes.mobile}px`, + }, + '.ss__carousel__prev-wrapper': { + right: `${arrowSizes.mobile + custom.spacing.x1}px`, + }, + '.ss__carousel__next-wrapper': { + right: 0, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__recommendation__title': { + fontSize: custom.utils.convertPxToEm(18), + }, + '.ss__carousel': { + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + top: 0, + }, + }, + }, + }); +}; + +// Recommendation component props come from Template export +export const recommendation: ThemeComponent<'recommendation', RecommendationProps> = { + default: { + ...recommendationThemeComponentProps.default, + recommendation: { + ...(recommendationThemeComponentProps.default?.['recommendation'] || {}), + themeStyleScript: recommendationStyleScript, + spaceBetween: custom.spacing.x4, + }, + }, + mobile: { + ...recommendationThemeComponentProps.mobile, + recommendation: { + ...(recommendationThemeComponentProps.mobile?.['recommendation'] || {}), + spaceBetween: custom.spacing.x2, + }, + 'recommendation icon.prev': { + size: `${custom.sizes.icon08}px`, + }, + 'recommendation icon.next': { + size: `${custom.sizes.icon08}px`, + }, + }, + tablet: { + ...recommendationThemeComponentProps.tablet, + recommendation: { + ...(recommendationThemeComponentProps.tablet?.['recommendation'] || {}), + spaceBetween: custom.spacing.x4, + }, + 'recommendation icon.prev': { + size: `${custom.sizes.icon10}px`, + }, + 'recommendation icon.next': { + size: `${custom.sizes.icon10}px`, + }, + }, + desktop: { + ...recommendationThemeComponentProps.desktop, + recommendation: { + ...(recommendationThemeComponentProps.desktop?.['recommendation'] || {}), + spaceBetween: custom.spacing.x4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundle.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundle.ts new file mode 100644 index 0000000000..4717911471 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundle.ts @@ -0,0 +1,250 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleProps } from '../../../../components/Templates/RecommendationBundle'; +import { recommendationBundleThemeComponentProps } from '../../../themeComponents/recommendationBundle'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundle component +const recommendationBundleStyleScript = (props: RecommendationBundleProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x8}px 0`, + '.ss__recommendation-bundle__title': { + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__recommendation-bundle__wrapper': { + flexFlow: `row nowrap`, + margin: `0 -${custom.spacing.x2}px`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + padding: `0 ${custom.spacing.x2}px`, + boxSizing: 'border-box', + }, + '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__cta': { + width: `20%`, + }, + '.ss__recommendation-bundle__wrapper__carousel': { + width: `60%`, + }, + }, + '.ss__recommendation-result-tracker, .ss__recommendation-bundle__wrapper__selector, .ss__recommendation-bundle__wrapper .ss__recommendation-bundle__wrapper__selector__result-wrapper': + { + height: '100%', + margin: 0, + }, + '.ss__recommendation-bundle__wrapper__seed-container': { + '.ss__recommendation-bundle__wrapper__selector__result-wrapper__seed-badge': { + top: '5px', + left: '5px', + backgroundColor: variables?.colors?.primary, + fontSize: custom.utils.convertPxToEm(12), + fontWeight: custom.fonts.weight01, + lineHeight: `20px`, + color: custom.colors.white, + padding: `0 ${custom.spacing.x2}px`, + }, + }, + '.ss__recommendation-bundle__wrapper__selector': { + width: 'auto !important', + }, + '.ss__recommendation-bundle__wrapper__selector__result-wrapper, .ss__carousel .swiper-container > .swiper-wrapper > .swiper-slide': { + '.ss__result': { + width: '100%', + flex: '1 1 0%', + }, + }, + '.ss__recommendation-bundle__wrapper__selector__result-wrapper': { + display: 'flex', + flexFlow: `column wrap`, + '&, .ss__result': { + position: 'relative', + }, + '&:has(.ss__overlay-badge)': { + '.ss__result': { + '.ss__overlay-badge .ss__overlay-badge__grid-wrapper': { + top: '25px', + }, + }, + }, + '.ss__checkbox': { + top: '5px', + right: '5px', + }, + }, + '.ss__icon--plus': { + display: 'none', + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + margin: 'auto 0', + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle__wrapper__cta': { + position: 'relative', + paddingTop: `${custom.spacing.x4}px`, + paddingBottom: `${custom.spacing.x4}px`, + display: 'flex', + flexFlow: 'column nowrap', + justifyContent: 'center', + alignItems: 'center', + gap: `${custom.spacing.x4}px`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + margin: `0 ${custom.spacing.x2}px 0 ${custom.spacing.x4}px`, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal, .ss__recommendation-bundle__wrapper__cta__button': { + position: 'relative', + zIndex: 2, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal': { + color: variables?.colors?.text, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__prices': { + margin: `${custom.spacing.x1}px 0 0 0`, + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + '&:after': { + content: '""', + display: 'block', + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + boxSizing: 'border-box', + position: 'absolute', + top: 0, + left: '10px', + right: 0, + bottom: 0, + zIndex: 1, + margin: 'auto', + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__recommendation-bundle__wrapper': { + '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__cta': { + width: `25%`, + }, + '.ss__recommendation-bundle__wrapper__carousel': { + width: `50%`, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle__wrapper': { + flexFlow: 'row wrap', + width: 'auto', + maxWidth: 'none', + margin: `0 -${custom.spacing.x1}px`, + '& > *': { + padding: `0 ${custom.spacing.x1}px`, + }, + '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__carousel': { + width: `50%`, + }, + }, + '.ss__recommendation-bundle__wrapper__cta': { + width: 'auto', + margin: `${custom.spacing.x4}px 0 0 0`, + padding: `${custom.spacing.x4}px`, + '& > *': { + margin: 0, + }, + '&:after': { + left: 0, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__recommendation-bundle__title': { + fontSize: custom.utils.convertPxToEm(18), + }, + }, + }); +}; + +// RecommendationBundle component props come from Template export +export const recommendationBundle: ThemeComponent<'recommendationBundle', RecommendationBundleProps> = { + default: { + ...recommendationBundleThemeComponentProps.default, + recommendationBundle: { + ...(recommendationBundleThemeComponentProps.default?.['recommendationBundle'] || {}), + themeStyleScript: recommendationBundleStyleScript, + }, + 'recommendationBundle icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + 'recommendationBundle icon.bundle-selector': { + icon: custom.icons.plus, + size: `${custom.sizes.icon14}px`, + }, + 'recommendationBundle carousel': { + spaceBetween: custom.spacing.x4, + }, + }, + mobile: { + ...recommendationBundleThemeComponentProps.mobile, + 'recommendationBundle carousel': { + spaceBetween: 0, + }, + }, + tablet: { + ...recommendationBundleThemeComponentProps.tablet, + 'recommendationBundle carousel': { + spaceBetween: custom.spacing.x4, + }, + }, + desktop: { + ...recommendationBundleThemeComponentProps.desktop, + 'recommendationBundle carousel': { + spaceBetween: custom.spacing.x4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleEasyAdd.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleEasyAdd.ts new file mode 100644 index 0000000000..0a4272b23d --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleEasyAdd.ts @@ -0,0 +1,134 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleEasyAddProps } from '../../../../components/Templates/RecommendationBundleEasyAdd'; +import { recommendationBundleEasyAddThemeComponentProps } from '../../../themeComponents/recommendationBundleEasyAdd'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleEasyAdd component +const recommendationBundleEasyAddStyleScript = (props: RecommendationBundleEasyAddProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x4}px 0`, + '.ss__recommendation-profile-tracker': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + }, + '.ss__recommendation-bundle-easy-add__title': { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle-easy-add__wrapper': { + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + '& > div': { + width: '50%', + minWidth: '1px', + flex: '0 1 auto', + boxSizing: 'border-box', + }, + '.ss__recommendation-bundle-easy-add__wrapper__selector__result-wrapper, .ss__recommendation-bundle-easy-add__wrapper__cta': { + margin: 0, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta': { + padding: `${custom.spacing.x4}px`, + width: 'auto', + display: 'flex', + flexFlow: 'column nowrap', + justifyContent: 'center', + alignItems: 'center', + gap: `${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal': { + color: variables?.colors?.text, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__prices': { + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle-easy-add__wrapper': { + flexFlow: 'row wrap', + '& > div': { + width: 'auto', + flex: '1 1 100%', + }, + }, + }, + }); +}; + +// RecommendationBundleEasyAdd component props come from Template export +export const recommendationBundleEasyAdd: ThemeComponent<'recommendationBundleEasyAdd', RecommendationBundleEasyAddProps> = { + default: { + ...recommendationBundleEasyAddThemeComponentProps.default, + recommendationBundleEasyAdd: { + ...(recommendationBundleEasyAddThemeComponentProps.default?.['recommendationBundleEasyAdd'] || {}), + themeStyleScript: recommendationBundleEasyAddStyleScript, + ctaInline: true, + }, + 'recommendationBundleEasyAdd icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + }, + mobile: { + ...recommendationBundleEasyAddThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleEasyAddThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleEasyAddThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleList.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleList.ts new file mode 100644 index 0000000000..d66f9abdf6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleList.ts @@ -0,0 +1,177 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleListProps } from '../../../../components/Templates/RecommendationBundleList'; +import { recommendationBundleListThemeComponentProps } from '../../../themeComponents/recommendationBundleList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleEasyAdd component +const recommendationBundleListStyleScript = (props: RecommendationBundleListProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x4}px 0`, + '.ss__recommendation-profile-tracker': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + }, + '.ss__recommendation-bundle-list__title': { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle-list__wrapper': { + flexFlow: 'row wrap', + margin: `0 -${custom.spacing.x1}px`, + '&, & > div': { + boxSizing: 'border-box', + }, + '& > div': { + width: '50%', + minWidth: '1px', + flex: '0 1 auto', + padding: `0 ${custom.spacing.x1}px`, + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper': { + margin: 0, + gap: `${custom.spacing.x2}px`, + '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper__checkbox, .ss__result': { + minWidth: '1px', + }, + '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper__checkbox': { + flex: '0 1 auto', + }, + '.ss__result': { + flex: '1 1 0%', + '.ss__result__image-wrapper': { + display: 'none', + }, + '.ss__result__details': { + gap: 0, + }, + }, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta': { + '.ss__recommendation-bundle-list__wrapper__cta__inner': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + lineHeight: 1, + }, + '.ss__recommendation-bundle-list__wrapper__cta__inner__images': { + flexFlow: 'row nowrap', + gap: `${custom.spacing.x2 + custom.sizes.icon12}px`, + '.ss__recommendation-bundle-list__wrapper__cta__inner__image-wrapper': { + flex: '1 1 0%', + minWidth: '1px', + padding: 0, + '.ss__icon': { + top: 0, + bottom: 0, + right: `-${custom.spacing.x2 / 2 + custom.sizes.icon12}px`, + margin: 'auto 0', + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal': { + padding: `${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__prices': { + margin: `${custom.spacing.x1}px 0 0 0`, + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle-list__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + }, + '.ss__recommendation-bundle-list__cta__button__wrapper': { + margin: `${custom.spacing.x4}px 0`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle-list__wrapper': { + '& > div': { + width: 'auto', + flex: '1 1 100%', + }, + }, + }, + }); +}; + +// RecommendationBundleList component props come from Template export +export const recommendationBundleList: ThemeComponent<'recommendationBundleList', RecommendationBundleListProps> = { + default: { + ...recommendationBundleListThemeComponentProps.default, + recommendationBundleList: { + ...(recommendationBundleListThemeComponentProps.default?.['recommendationBundleList'] || {}), + themeStyleScript: recommendationBundleListStyleScript, + separatorIconSeedOnly: false, + }, + 'recommendationBundleList icon.bundle-cart-separator': { + icon: custom.icons.plus, + size: `${custom.sizes.icon12}px`, + }, + 'recommendationBundleList icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + 'recommendationBundleList result': { + hideImage: true, + hideBadge: true, + }, + }, + mobile: { + ...recommendationBundleListThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleListThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleListThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleVertical.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleVertical.ts new file mode 100644 index 0000000000..dba4de8607 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationBundleVertical.ts @@ -0,0 +1,159 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleVerticalProps } from '../../../../components/Templates/RecommendationBundleVertical'; +import { recommendationBundleVerticalThemeComponentProps } from '../../../themeComponents/recommendationBundleVertical'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleVertical component +const recommendationBundleVerticalStyleScript = (props: RecommendationBundleVerticalProps) => { + const variables = props?.theme?.variables; + const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x4}px 0`, + '.ss__recommendation-profile-tracker': { + '& > *': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + }, + '.ss__recommendation-bundle-vertical__title': { + fontSize: custom.utils.convertPxToEm(18), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + '.ss__recommendation-bundle-vertical__wrapper': { + gap: `${custom.spacing.x4}px`, + '& > div': { + minWidth: '1px', + flex: '1 1 100%', + }, + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper': { + margin: 0, + '&, .ss__result': { + position: 'relative', + }, + '&:has(.ss__overlay-badge)': { + '.ss__result': { + '.ss__overlay-badge .ss__overlay-badge__grid-wrapper': { + top: '25px', + }, + }, + }, + '.ss__checkbox': { + top: '5px', + right: '5px', + }, + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper__seed-badge': { + top: '5px', + left: '5px', + backgroundColor: variables?.colors?.primary, + fontSize: custom.utils.convertPxToEm(14), + fontWeight: custom.fonts.weight01, + lineHeight: `24px`, + color: custom.colors.white, + padding: `0 ${custom.spacing.x2}px`, + }, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta': { + padding: `${custom.spacing.x4}px`, + width: 'auto', + display: 'flex', + flexFlow: 'column nowrap', + justifyContent: 'center', + alignItems: 'center', + gap: `${custom.spacing.x4}px`, + backgroundColor: custom.colors.gray01, + border: `1px solid ${custom.colors.gray02}`, + '& > *': { + flex: '0 1 auto', + minWidth: '1px', + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal': { + color: variables?.colors?.text, + '& > *': { + lineHeight: 1, + margin: `0 0 ${custom.spacing.x2}px 0`, + '&:last-child': { + marginBottom: 0, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__icon__wrapper': { + '.ss__icon': { + fill: variables?.colors?.secondary, + stroke: variables?.colors?.secondary, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__title': { + display: 'block', + fontWeight: custom.fonts.weight02, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__prices': { + label: { + margin: 0, + padding: 0, + '& ~ label': { + paddingLeft: `${custom.spacing.x1}px`, + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__strike': { + color: lightGray, + '*': { + color: 'inherit', + }, + }, + '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__price': { + fontSize: custom.utils.convertPxToEm(16), + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + '*': { + color: 'inherit', + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-bundle-vertical__wrapper': { + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper': { + '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper__seed-badge': { + fontSize: custom.utils.convertPxToEm(12), + lineHeight: `20px`, + }, + }, + }, + }, + }); +}; + +// RecommendationBundleVertical component props come from Template export +export const recommendationBundleVertical: ThemeComponent<'recommendationBundleVertical', RecommendationBundleVerticalProps> = { + default: { + ...recommendationBundleVerticalThemeComponentProps.default, + recommendationBundleVertical: { + ...(recommendationBundleVerticalThemeComponentProps.default?.['recommendationBundleVertical'] || {}), + themeStyleScript: recommendationBundleVerticalStyleScript, + }, + 'recommendationBundleVertical icon.bundle-cart': { + icon: custom.icons.bag, + size: `${custom.sizes.icon16 * 2}px`, + }, + 'recommendationBundleVertical icon.bundle-selector': { + icon: custom.icons.plus, + size: `${custom.sizes.icon14}px`, + }, + }, + mobile: { + ...recommendationBundleVerticalThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleVerticalThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleVerticalThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationEmail.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationEmail.ts new file mode 100644 index 0000000000..c87c85f658 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationEmail.ts @@ -0,0 +1,52 @@ +import { css } from '@emotion/react'; +import type { RecommendationEmailProps } from '../../../../components/Templates/RecommendationEmail'; +import { recommendationEmailThemeComponentProps } from '../../../themeComponents/recommendationEmail'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationEmail component +const recommendationEmailStyleScript = (props: RecommendationEmailProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + width: '400px !important', + height: '680px', + margin: `0 0 ${custom.spacing.x6}px 0`, + padding: `0 ${custom.spacing.x2}px`, + overflow: 'hidden', + '.ss__result': { + fontSize: '16px', + '.ss__result__details .ss__result__details__title a': { + display: 'block', + height: '26px', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }, + }); +}; + +// RecommendationEmail component props come from Template export +export const recommendationEmail: ThemeComponent<'recommendationEmail', RecommendationEmailProps> = { + default: { + ...recommendationEmailThemeComponentProps.default, + recommendationEmail: { + ...(recommendationEmailThemeComponentProps.default?.['recommendationEmail'] || {}), + themeStyleScript: recommendationEmailStyleScript, + }, + 'recommendationEmail image': { + lazy: false, + }, + }, + mobile: { + ...recommendationEmailThemeComponentProps.mobile, + }, + tablet: { + ...recommendationEmailThemeComponentProps.tablet, + }, + desktop: { + ...recommendationEmailThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationGrid.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationGrid.ts new file mode 100644 index 0000000000..d14e34a467 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/recommendationGrid.ts @@ -0,0 +1,72 @@ +import { css } from '@emotion/react'; +import type { RecommendationGridProps } from '../../../../components/Templates/RecommendationGrid'; +import { recommendationGridThemeComponentProps } from '../../../themeComponents/recommendationGrid'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundle component +const recommendationGridStyleScript = (props: RecommendationGridProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + margin: `${custom.spacing.x8}px 0`, + maxHeight: 'none', + '.ss__recommendation-grid__title': { + fontSize: custom.utils.convertPxToEm(22), + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + textAlign: 'center', + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__recommendation-grid__results': { + overflowX: 'auto', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__recommendation-grid__title': { + textAlign: 'left', + }, + }, + }); +}; + +// RecommendationGrid component props come from Template export +export const recommendationGrid: ThemeComponent<'recommendationGrid', RecommendationGridProps> = { + default: { + ...recommendationGridThemeComponentProps.default, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.default?.['recommendationGrid'] || {}), + themeStyleScript: recommendationGridStyleScript, + gapSize: `${custom.spacing.x6}px ${custom.spacing.x4}px`, + columns: 4, + }, + }, + mobile: { + ...recommendationGridThemeComponentProps.mobile, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.mobile?.['recommendationGrid'] || {}), + gapSize: `${custom.spacing.x6}px ${custom.spacing.x2}px`, + columns: 2, + }, + }, + tablet: { + ...recommendationGridThemeComponentProps.tablet, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.tablet?.['recommendationGrid'] || {}), + columns: 3, + }, + }, + desktop: { + ...recommendationGridThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/search.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/search.ts new file mode 100644 index 0000000000..3e2a9488ea --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/search.ts @@ -0,0 +1,80 @@ +import { css } from '@emotion/react'; +import type { SearchProps } from '../../../../components/Templates/Search'; +import { searchThemeComponentProps } from '../../../themeComponents/search'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchStyleScript = (props: SearchProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '&.ss__search--sidebar-open': { + '.ss__button': { + '.ss__icon--filter': { + transform: 'rotate(-180deg)', + }, + '.ss__icon--filters': { + circle: { + '&:last-child': { + transform: 'translateX(-35%)', + }, + transform: 'translateX(35%)', + }, + }, + }, + }, + '.ss__search__header-section, .ss__search__main-section': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '.ss__toolbar .ss__layout': { + gap: `${custom.spacing.x4}px`, + }, + }, + '.ss__search__main-section': { + gap: `${custom.spacing.x6}px`, + '.ss__search__sidebar, .ss__search__content': { + minWidth: '1px', + }, + '.ss__search__sidebar': { + flex: '0 1 auto', + }, + '.ss__search__content': { + flex: '1 1 0%', + gap: `${custom.spacing.x4}px`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__search__main-section': { + '.ss__toolbar': { + '.ss__select': { + flex: '1 1 0%', + }, + }, + }, + }, + }); +}; + +// Search component props come from Template export +export const search: ThemeComponent<'search', SearchProps> = { + default: { + ...searchThemeComponentProps.default, + search: { + ...(searchThemeComponentProps.default?.['search'] || {}), + themeStyleScript: searchStyleScript, + }, + 'search filterSummary': { + type: 'list', + }, + }, + mobile: { + ...searchThemeComponentProps.mobile, + }, + tablet: { + ...searchThemeComponentProps.tablet, + }, + desktop: { + ...searchThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/searchCollapsible.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/searchCollapsible.ts new file mode 100644 index 0000000000..bff1a4fc4a --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/searchCollapsible.ts @@ -0,0 +1,88 @@ +import { css } from '@emotion/react'; +import type { SearchCollapsibleProps } from '../../../../components/Templates/SearchCollapsible'; +import { searchCollapsibleThemeComponentProps } from '../../../themeComponents/searchCollapsible'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchCollapsibleStyleScript = (props: SearchCollapsibleProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + '&.ss__search-collapsible--sidebar-open': { + '.ss__button': { + '.ss__icon--filter': { + transform: 'rotate(-180deg)', + }, + '.ss__icon--filters': { + circle: { + '&:last-child': { + transform: 'translateX(-35%)', + }, + transform: 'translateX(35%)', + }, + }, + }, + }, + '.ss__search-collapsible__header-section, .ss__search-collapsible__main-section': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '.ss__toolbar .ss__layout': { + gap: `${custom.spacing.x4}px`, + }, + }, + '.ss__search-collapsible__header-section': { + '.ss__search-header': { + textAlign: 'center', + }, + }, + '.ss__search-collapsible__main-section': { + gap: `${custom.spacing.x6}px`, + '.ss__search-collapsible__sidebar, .ss__search-collapsible__content': { + minWidth: '1px', + }, + '.ss__search-collapsible__sidebar': { + flex: '0 1 auto', + }, + '.ss__search-collapsible__content': { + flex: '1 1 0%', + gap: `${custom.spacing.x4}px`, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__toolbar': { + '.ss__pagination-info': { + fontSize: custom.utils.convertPxToEm(16), + }, + }, + }, + }); +}; + +export const searchCollapsible: ThemeComponent<'searchCollapsible', SearchCollapsibleProps> = { + default: { + ...searchCollapsibleThemeComponentProps.default, + searchCollapsible: { + ...(searchCollapsibleThemeComponentProps.default?.['searchCollapsible'] || {}), + themeStyleScript: searchCollapsibleStyleScript, + }, + 'searchCollapsible sidebar': { + hideTitleText: true, + }, + 'searchCollapsible button.sidebar-toggle': { + icon: custom.icons.filter, + }, + 'searchCollapsible filterSummary': { + type: 'list', + }, + }, + mobile: { + ...searchCollapsibleThemeComponentProps.mobile, + }, + tablet: { + ...searchCollapsibleThemeComponentProps.tablet, + }, + desktop: { + ...searchCollapsibleThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/components/templates/searchHorizontal.ts b/packages/snap-preact/components/src/themes/matterhorn/components/templates/searchHorizontal.ts new file mode 100644 index 0000000000..3501da121b --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/components/templates/searchHorizontal.ts @@ -0,0 +1,78 @@ +import { css } from '@emotion/react'; +import type { SearchHorizontalProps } from '../../../../components/Templates/SearchHorizontal'; +import { searchHorizontalThemeComponentProps } from '../../../themeComponents/searchHorizontal'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchHorizontalStyleScript = (props: SearchHorizontalProps) => { + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + '.ss__search-horizontal__header-section, .ss__search-horizontal__main-section': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '.ss__toolbar .ss__layout': { + gap: `${custom.spacing.x4}px`, + '.ss__layout__row': { + '&:has(.ss__facets-horizontal)': { + alignItems: 'flex-start', + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__facets-horizontal': { + flex: '1 1 0%', + }, + }, + }, + }, + }, + '.ss__search-horizontal__header-section': { + '.ss__search-header': { + textAlign: 'center', + }, + }, + '.ss__search-horizontal__main-section': { + gap: `${custom.spacing.x6}px`, + '.ss__search-horizontal__sidebar, .ss__search-horizontal__content': { + minWidth: '1px', + }, + '.ss__search-horizontal__sidebar': { + flex: '0 1 auto', + }, + '.ss__search-horizontal__content': { + flex: '1 1 0%', + gap: `${custom.spacing.x4}px`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__search-horizontal__main-section': { + '.ss__toolbar': { + '.ss__select': { + flex: '1 1 0%', + }, + }, + }, + }, + }); +}; + +export const searchHorizontal: ThemeComponent<'searchHorizontal', SearchHorizontalProps> = { + default: { + ...searchHorizontalThemeComponentProps.default, + searchHorizontal: { + ...(searchHorizontalThemeComponentProps.default?.['searchHorizontal'] || {}), + themeStyleScript: searchHorizontalStyleScript, + }, + }, + mobile: { + ...searchHorizontalThemeComponentProps.mobile, + }, + tablet: { + ...searchHorizontalThemeComponentProps.tablet, + }, + desktop: { + ...searchHorizontalThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/custom.ts b/packages/snap-preact/components/src/themes/matterhorn/custom.ts new file mode 100644 index 0000000000..0c61729e40 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/custom.ts @@ -0,0 +1,108 @@ +import { IconType } from '../../components/Atoms/Icon'; +import Color from 'color'; + +// calculate spacing +const spacing = 5; +const spacingCalc = (value: number) => { + return spacing * value; +}; + +export const custom: { + breakpoints: { + [key: string]: number; + }; + colors: { + [key: string]: string; + }; + fonts: { + [key: string]: any; + }; + icons: { + [key: string]: IconType; + }; + sizes: { + [key: string]: number; + }; + spacing: { + [key: string]: number; + }; + utils: { + convertPxToEm: (value: number) => string; + lightenColor: (color: string | undefined, amount: number) => string; + darkenColor: (color: string | undefined, amount: number) => string; + }; +} = { + breakpoints: { + small: 540, + mobile: 767, + tablet: 1024, + desktop: 1280, + }, + colors: { + white: '#ffffff', + black: '#000000', + gray01: '#f8f8f8', // lighter gray: bg color under terms, dropdown, checkboxes + gray02: '#ebebeb', // light gray: borders for autocomplete, dropdown, checkboxes + brown: '#845329', // for color palette + purple: '#7c368e', // for color palette + rainbow: + 'linear-gradient(rgb(40, 87, 218) 20%, rgb(40, 218, 70) 20%, rgb(40, 218, 70) 40%, rgb(245, 228, 24) 40%, rgb(245, 228, 24) 60%, rgb(242, 133, 0) 60%, rgb(242, 133, 0) 80%, rgb(218, 40, 72) 80%, rgb(218, 40, 72))', // for color palette + }, + fonts: { + weight01: 700, // main font weight + weight02: 700, // header font weight + style: false, + transform: false, + }, + icons: { + arrowLeft: 'chevron-left', + arrowRight: 'chevron-right', + arrowDown: 'chevron-down', + arrowUp: 'chevron-up', + bag: 'bag', + check: 'square', + close: 'close', + minus: 'minus', + plus: 'plus', + filter: 'filter', + filters: 'filters', + search: 'search', + sort: 'sort', + }, + sizes: { + font: 16, // base font size + height: 35, // refers to height for button and dropdown sizes + icon08: 8, + icon10: 10, + icon12: 12, + icon14: 14, + icon16: 16, + radius: 0, // global border radius value + }, + spacing: { + x1: spacing, + x2: spacingCalc(2), + x3: spacingCalc(3), + x4: spacingCalc(4), + x5: spacingCalc(5), + x6: spacingCalc(6), + x7: spacingCalc(7), + x8: spacingCalc(8), + }, + utils: { + convertPxToEm: (value: number) => { + // translates px to rem + return `${value / custom.sizes.font}rem`; + }, + lightenColor: (color: string | undefined, amount: number) => { + // lighten a color + const lightColor = new Color(color || '#515151').lighten(amount).hex().toLowerCase(); + return lightColor; + }, + darkenColor: (color: string | undefined, amount: number) => { + // darken a color + const darkColor = new Color(color || '#515151').darken(amount).hex().toLowerCase(); + return darkColor; + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/matterhorn.ts b/packages/snap-preact/components/src/themes/matterhorn/matterhorn.ts new file mode 100644 index 0000000000..92be27d14c --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/matterhorn.ts @@ -0,0 +1,24 @@ +import { ThemeComplete, ThemeVariables } from '../../providers'; +import { components } from './components'; +import { responsive } from './responsive'; + +const matterhornVariables: ThemeVariables = { + breakpoints: { + mobile: 767, + tablet: 991, + desktop: 1199, + }, + colors: { + text: '#515151', + primary: '#00aeef', + secondary: '#1d4990', + accent: '#2154a5', + }, +}; + +export const matterhorn: ThemeComplete = { + name: 'matterhorn', + variables: matterhornVariables, + components, + responsive, +}; diff --git a/packages/snap-preact/components/src/themes/matterhorn/responsive.ts b/packages/snap-preact/components/src/themes/matterhorn/responsive.ts new file mode 100644 index 0000000000..61ae08bfe4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/matterhorn/responsive.ts @@ -0,0 +1,8 @@ +import { ThemeResponsive } from '../../providers/theme'; +import { mobileComponents, tabletComponents, desktopComponents } from './components'; + +export const responsive: ThemeResponsive = { + mobile: mobileComponents, + tablet: tabletComponents, + desktop: desktopComponents, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/badgeImage.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/badgeImage.ts new file mode 100644 index 0000000000..36a085368d --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/badgeImage.ts @@ -0,0 +1,27 @@ +import { css } from '@emotion/react'; +import type { BadgeImageProps } from '../../../../components/Atoms/BadgeImage'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the BadgeImage component +const badgeImageStyleScript = (props: BadgeImageProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // badge image styles + const badgeImageStyles = css({ + lineHeight: 0, + ...custom.styles.boxSizing('badgeImage', props?.treePath, props?.name), + }); + + return badgeImageStyles; +}; + +// BadgeImage component props +export const badgeImage: ThemeComponent<'badgeImage', BadgeImageProps> = { + default: { + badgeImage: { + themeStyleScript: badgeImageStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/badgePill.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/badgePill.ts new file mode 100644 index 0000000000..641ee0670c --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/badgePill.ts @@ -0,0 +1,30 @@ +import { css } from '@emotion/react'; +import type { BadgePillProps } from '../../../../components/Atoms/BadgePill'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the BadgePill component +const badgePillStyleScript = (props: BadgePillProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // badge pill styles + const badgePillStyles = css({ + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + ...custom.styles.boxSizing('badgePill', props?.treePath, props?.name), + span: { + ...custom.styles.badgeText(12), + }, + }); + + return badgePillStyles; +}; + +// BadgePill component props +export const badgePill: ThemeComponent<'badgePill', BadgePillProps> = { + default: { + badgePill: { + themeStyleScript: badgePillStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/badgeRectangle.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/badgeRectangle.ts new file mode 100644 index 0000000000..7a6f15d266 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/badgeRectangle.ts @@ -0,0 +1,30 @@ +import { css } from '@emotion/react'; +import type { BadgeRectangleProps } from '../../../../components/Atoms/BadgeRectangle'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the BadgeRectangle component +const badgeRectangleStyleScript = (props: BadgeRectangleProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // badge rectangle styles + const badgeRectangleStyles = css({ + padding: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + ...custom.styles.boxSizing('badgeRectangle', props?.treePath, props?.name), + span: { + ...custom.styles.badgeText(12), + }, + }); + + return badgeRectangleStyles; +}; + +// BadgeRectangle component props +export const badgeRectangle: ThemeComponent<'badgeRectangle', BadgeRectangleProps> = { + default: { + badgeRectangle: { + themeStyleScript: badgeRectangleStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/badgeText.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/badgeText.ts new file mode 100644 index 0000000000..80ea779d80 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/badgeText.ts @@ -0,0 +1,30 @@ +import { css } from '@emotion/react'; +import type { BadgeTextProps } from '../../../../components/Atoms/BadgeText'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the BadgeText component +const badgeTextStyleScript = (props: BadgeTextProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // badge text styles + const badgeTextStyles = css({ + padding: 0, + ...custom.styles.boxSizing('badgeText', props?.treePath, props?.name), + span: { + ...custom.styles.badgeText(12), + }, + }); + + return badgeTextStyles; +}; + +// BadgeText component props +export const badgeText: ThemeComponent<'badgeText', BadgeTextProps> = { + default: { + badgeText: { + themeStyleScript: badgeTextStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/banner.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/banner.ts new file mode 100644 index 0000000000..3fcd7c6d39 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/banner.ts @@ -0,0 +1,27 @@ +import { css } from '@emotion/react'; +import type { BannerProps } from '../../../../components/Atoms/Banner'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Banner component +const bannerStyleScript = (props: BannerProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // banner styles + const bannerStyles = css({ + color: variables?.colors?.text, + ...custom.styles.boxSizing('banner', props?.treePath, props?.name), + }); + + return bannerStyles; +}; + +// Banner component props +export const banner: ThemeComponent<'banner', BannerProps> = { + default: { + banner: { + themeStyleScript: bannerStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/breadcrumbs.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/breadcrumbs.ts new file mode 100644 index 0000000000..0ed6d3f04e --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/breadcrumbs.ts @@ -0,0 +1,49 @@ +import { css } from '@emotion/react'; +import type { BreadcrumbsProps } from '../../../../components/Atoms/Breadcrumbs'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Breadcrumbs component +const breadcrumbsStyleScript = (props: BreadcrumbsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // breadcrumbs styles + const breadcrumbsStyles = css({ + ...custom.styles.boxSizing('breadcrumbs', props?.treePath, props?.name), + '.ss__breadcrumbs__crumbs': { + gap: `${custom.spacing.x2}px`, + '&, li': { + listStyle: 'none', + }, + '&, a': { + color: variables?.colors?.text, + }, + li: { + display: 'block', + padding: 0, + '&:last-of-type': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + }, + }); + + return breadcrumbsStyles; +}; + +// Breadcrumbs component props +export const breadcrumbs: ThemeComponent<'breadcrumbs', BreadcrumbsProps> = { + default: { + breadcrumbs: { + themeStyleScript: breadcrumbsStyleScript, + separator: false, + separatorIcon: custom.icons.arrowRight, + }, + 'breadcrumbs icon': { + size: `${custom.sizes.icon10}px`, + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/button.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/button.ts new file mode 100644 index 0000000000..3d5a4edbd8 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/button.ts @@ -0,0 +1,89 @@ +import { css } from '@emotion/react'; +import type { ButtonProps } from '../../../../components/Atoms/Button'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const buttonDisabledSelectors = '&.ss__button--disabled'; + +// CSS in JS style script for the Button component +const buttonStyleScript = (props: ButtonProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const activeColors = custom.utils.activeColors(props?.backgroundColor); + const buttonColor = activeColors[0]; + const fontColor = activeColors[1]; + + // shared styles + const sharedStyles = css([ + { + cursor: 'pointer', + padding: `0 ${custom.spacing.x4}px`, + justifyContent: 'center', + fontSize: '14px', + fontWeight: custom.fonts.weight01, + textAlign: 'center', + textTransform: custom.fonts.transform, + color: fontColor, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + ...custom.styles.borderRadius(), + ...custom.styles.boxSizing('button', props?.treePath, props?.name), + [buttonDisabledSelectors]: { + ...custom.styles.disabled(), + }, + '.ss__button__content': { + '&:has(span)': { + display: 'inline-flex', + flexFlow: 'row nowrap', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + span: { + ...custom.styles.textOverflow(), + }, + }, + '&:not(:has(span))': { + ...custom.styles.textOverflow(), + }, + '&, *': { + minWidth: '1px', + }, + }, + [`&, &:hover, &:not(.ss__button--disabled):hover, ${buttonDisabledSelectors}`]: { + border: `1px solid ${buttonColor}`, + backgroundColor: buttonColor, + }, + }, + ]); + + // default button styles + const defaultButtonStyles = sharedStyles; + + // native button styles + const nativeButtonStyles = css([ + { + display: 'inline-flex', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + position: 'relative', + outline: 0, + }, + sharedStyles, + ]); + + return props?.native ? nativeButtonStyles : defaultButtonStyles; +}; + +// Button component props +export const button: ThemeComponent<'button', ButtonProps> = { + default: { + button: { + themeStyleScript: buttonStyleScript, + }, + 'button icon': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/dropdown.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/dropdown.ts new file mode 100644 index 0000000000..9c3d3b1a75 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/dropdown.ts @@ -0,0 +1,74 @@ +import { css } from '@emotion/react'; +import type { DropdownProps } from '../../../../components/Atoms/Dropdown'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Dropdown component +const dropdownStyleScript = (props: DropdownProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // dropdown styles + const dropdownStyles = css({ + width: 'auto', + ...custom.styles.boxSizing('dropdown', props?.treePath, props?.name), + '&.ss__dropdown__portal': { + '.ss__dropdown__content': { + marginTop: `${custom.spacing.x2}px`, + ...custom.styles.box(variables?.colors?.text, ''), + '.ss__select__select, .ss__variant-selection__options': { + margin: 0, + padding: 0, + border: 0, + backgroundColor: 'transparent', + }, + '.ss__select__select .ss__select__select__option, .ss__variant-selection__options .ss__variant-selection__option': { + color: 'inherit', + gap: `${custom.spacing.x2}px`, + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + backgroundColor: 'transparent', + fontWeight: 'normal', + }, + 'a, span': { + cursor: 'pointer', + }, + }, + '.ss__select__select .ss__select__select__option--selected, .ss__variant-selection__options .ss__variant-selection__option--selected': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + '.ss__select__select .ss__select__select__option----unavailable, .ss__select__select .ss__select__select__option--disabled, .ss__variant-selection__options .ss__variant-selection__option--unavailable, .ss__variant-selection__options .ss__variant-selection__option--disabled': + { + color: 'inherit', + ...custom.styles.disabled(), + }, + }, + }, + '&.ss__dropdown--open': { + '.ss__dropdown__content': { + zIndex: 5, + }, + }, + '.ss__dropdown__content': { + minWidth: '1px', + left: 0, + right: 0, + zIndex: -1, + }, + }); + + return dropdownStyles; +}; + +// Dropdown component props +export const dropdown: ThemeComponent<'dropdown', DropdownProps> = { + default: { + dropdown: { + themeStyleScript: dropdownStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/formattedNumber.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/formattedNumber.ts new file mode 100644 index 0000000000..4bc889a913 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/formattedNumber.ts @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { FormattedNumberProps } from '../../../../components/Atoms/FormattedNumber'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FormattedNumber component +const formattedNumberStyleScript = (props: FormattedNumberProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // formatted number styles + const formattedNumberStyles = css({ + ...custom.styles.boxSizing('formattedNumber', props?.treePath, props?.name), + }); + + return formattedNumberStyles; +}; + +// FormattedNumber component props +export const formattedNumber: ThemeComponent<'formattedNumber', FormattedNumberProps> = { + default: { + formattedNumber: { + themeStyleScript: formattedNumberStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/icon.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/icon.ts new file mode 100644 index 0000000000..e0bc5d1ef3 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/icon.ts @@ -0,0 +1,47 @@ +import { css } from '@emotion/react'; +import type { IconProps } from '../../../../components/Atoms/Icon'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Icon component +const iconStyleScript = (props: IconProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // set flex size for icons that are flex children + let flexSize = ''; + if (props?.width) { + flexSize = `0 0 ${props.width}`; + } else if (props?.size) { + flexSize = `0 0 ${props.size}`; + } + + // icon styles + const iconStyles = css({ + minWidth: '1px', + flex: flexSize, + lineHeight: 1, + '&.ss__icon--filters': { + fill: custom.colors.white, + stroke: variables?.colors?.primary, + circle: { + fill: 'inherit', + }, + }, + }); + + return iconStyles; +}; + +// Icon component props +export const icon: ThemeComponent<'icon', IconProps> = { + default: { + icon: { + themeStyleScript: iconStyleScript, + size: `${custom.sizes.icon16}px`, + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + fill: 'currentColor', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/image.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/image.ts new file mode 100644 index 0000000000..c49068cde1 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/image.ts @@ -0,0 +1,52 @@ +import { css } from '@emotion/react'; +import type { ImageProps } from '../../../../components/Atoms/Image'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Image component +const imageStyleScript = (props: ImageProps & { visibility: React.CSSProperties['visibility'] }) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // image styles + const imageStyles = css({ + ...custom.styles.boxSizing('image', props?.treePath, props?.name), + '&, img': { + lineHeight: 0, + }, + img: { + border: 0, + }, + '&.ss__result__image': { + position: 'relative', + height: 0, + padding: '0 0 100% 0', + overflow: 'hidden', + '&, img': { + display: 'block', + }, + img: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + width: '100%', + height: '100%', + objectPosition: 'center center', + }, + }, + }); + + return imageStyles; +}; + +// Image component props +export const image: ThemeComponent<'image', ImageProps> = { + default: { + image: { + themeStyleScript: imageStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/index.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/index.ts new file mode 100644 index 0000000000..126b3601d4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/index.ts @@ -0,0 +1,104 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// ATOMS Imports +import { badgeImage } from './badgeImage'; +import { badgePill } from './badgePill'; +import { badgeRectangle } from './badgeRectangle'; +import { badgeText } from './badgeText'; +import { banner } from './banner'; +import { breadcrumbs } from './breadcrumbs'; +import { button } from './button'; +import { dropdown } from './dropdown'; +import { formattedNumber } from './formattedNumber'; +import { icon } from './icon'; +import { image } from './image'; +import { inlineBanner } from './inlineBanner'; +import { loadingBar } from './loadingBar'; +import { overlay } from './overlay'; +import { paginationInfo } from './paginationInfo'; +import { price } from './price'; +import { searchHeader } from './searchHeader'; +import { skeleton } from './skeleton'; + +export const atoms: ThemeResponsiveComplete = { + default: { + ...badgeImage.default, + ...badgePill.default, + ...badgeRectangle.default, + ...badgeText.default, + ...banner.default, + ...breadcrumbs.default, + ...button.default, + ...dropdown.default, + ...formattedNumber.default, + ...icon.default, + ...image.default, + ...inlineBanner.default, + ...loadingBar.default, + ...overlay.default, + ...paginationInfo.default, + ...price.default, + ...searchHeader.default, + ...skeleton.default, + }, + mobile: { + ...badgeImage.mobile, + ...badgePill.mobile, + ...badgeRectangle.mobile, + ...badgeText.mobile, + ...banner.mobile, + ...breadcrumbs.mobile, + ...button.mobile, + ...dropdown.mobile, + ...formattedNumber.mobile, + ...icon.mobile, + ...image.mobile, + ...inlineBanner.mobile, + ...loadingBar.mobile, + ...overlay.mobile, + ...paginationInfo.mobile, + ...price.mobile, + ...searchHeader.mobile, + ...skeleton.mobile, + }, + tablet: { + ...badgeImage.tablet, + ...badgePill.tablet, + ...badgeRectangle.tablet, + ...badgeText.tablet, + ...banner.tablet, + ...breadcrumbs.tablet, + ...button.tablet, + ...dropdown.tablet, + ...formattedNumber.tablet, + ...icon.tablet, + ...image.tablet, + ...inlineBanner.tablet, + ...loadingBar.tablet, + ...overlay.tablet, + ...paginationInfo.tablet, + ...price.tablet, + ...searchHeader.tablet, + ...skeleton.tablet, + }, + desktop: { + ...badgeImage.desktop, + ...badgePill.desktop, + ...badgeRectangle.desktop, + ...badgeText.desktop, + ...banner.desktop, + ...breadcrumbs.desktop, + ...button.desktop, + ...dropdown.desktop, + ...formattedNumber.desktop, + ...icon.desktop, + ...image.desktop, + ...inlineBanner.desktop, + ...loadingBar.desktop, + ...overlay.desktop, + ...paginationInfo.desktop, + ...price.desktop, + ...searchHeader.desktop, + ...skeleton.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/inlineBanner.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/inlineBanner.ts new file mode 100644 index 0000000000..dfbd0ea1a8 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/inlineBanner.ts @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { InlineBannerProps } from '../../../../components/Atoms/InlineBanner'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the InlineBanner component +const inlineBannerStyleScript = (props: InlineBannerProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // inline banner styles + const inlineBannerStyles = css({ + ...custom.styles.boxSizing('inlineBanner', props?.treePath, props?.name), + }); + + return inlineBannerStyles; +}; + +// InlineBanner component props +export const inlineBanner: ThemeComponent<'inlineBanner', InlineBannerProps> = { + default: { + inlineBanner: { + themeStyleScript: inlineBannerStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/loadingBar.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/loadingBar.ts new file mode 100644 index 0000000000..dc428cd04e --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/loadingBar.ts @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { LoadingBarProps } from '../../../../components/Atoms/Loading'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the LoadingBar component +const loadingBarStyleScript = (props: LoadingBarProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // loading bar styles + const loadingBarStyles = css({ + ...custom.styles.boxSizing('loadingBar', props?.treePath, props?.name), + }); + + return loadingBarStyles; +}; + +// LoadingBar component props +export const loadingBar: ThemeComponent<'loadingBar', LoadingBarProps> = { + default: { + loadingBar: { + themeStyleScript: loadingBarStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/overlay.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/overlay.ts new file mode 100644 index 0000000000..b5cea5d34a --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/overlay.ts @@ -0,0 +1,28 @@ +import { css } from '@emotion/react'; +import type { OverlayProps } from '../../../../components/Atoms/Overlay'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Overlay component +const overlayStyleScript = (props: OverlayProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // overlay styles + const overlayStyles = css({ + cursor: 'pointer', + ...custom.styles.boxSizing('overlay', props?.treePath, props?.name), + }); + + return overlayStyles; +}; + +// Overlay component props +export const overlay: ThemeComponent<'overlay', OverlayProps> = { + default: { + overlay: { + themeStyleScript: overlayStyleScript, + color: 'rgba(0, 0, 0, 0.80)', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/paginationInfo.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/paginationInfo.ts new file mode 100644 index 0000000000..e93fdf311a --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/paginationInfo.ts @@ -0,0 +1,27 @@ +import { css } from '@emotion/react'; +import type { PaginationInfoProps } from '../../../../components/Atoms/PaginationInfo'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Pagination component +const paginationInfoStyleScript = (props: PaginationInfoProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // pagination info styles + const paginationInfoStyles = css({ + ...custom.styles.headerText(variables?.colors?.secondary, '16px'), + ...custom.styles.boxSizing('paginationInfo', props?.treePath, props?.name), + }); + + return paginationInfoStyles; +}; + +// PaginationInfo component props +export const paginationInfo: ThemeComponent<'paginationInfo', PaginationInfoProps> = { + default: { + paginationInfo: { + themeStyleScript: paginationInfoStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/price.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/price.ts new file mode 100644 index 0000000000..f4af14a52e --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/price.ts @@ -0,0 +1,32 @@ +import { css } from '@emotion/react'; +import type { PriceProps } from '../../../../components/Atoms/Price'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Price component +const priceStyleScript = (props: PriceProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // price styles + const priceStyles = css({ + ...custom.styles.boxSizing('price', props?.treePath, props?.name), + '&, span, &.ss__price, &.ss__price--strike': { + color: variables?.colors?.text, + }, + '& ~ .ss__result__price': { + paddingLeft: `${custom.spacing.x1 / 2}px`, + }, + }); + + return priceStyles; +}; + +// Price component props +export const price: ThemeComponent<'price', PriceProps> = { + default: { + price: { + themeStyleScript: priceStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/searchHeader.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/searchHeader.ts new file mode 100644 index 0000000000..26850e1787 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/searchHeader.ts @@ -0,0 +1,45 @@ +import { css } from '@emotion/react'; +import type { SearchHeaderProps } from '../../../../components/Atoms/SearchHeader'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the SearchHeader component +const searchHeaderStyleScript = (props: SearchHeaderProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // search header styles + const searchHeaderStyles = css({ + ...custom.styles.boxSizing('searchHeader', props?.treePath, props?.name), + em: { + fontStyle: 'normal', + }, + '.ss__search-header__title': { + margin: 0, + ...custom.styles.headerText(variables?.colors?.secondary, '22px'), + }, + '.ss__search-header__subtitle': { + margin: `${custom.spacing.x2}px 0 0 0`, + fontSize: '16px', + fontWeight: 400, + color: variables?.colors?.text, + a: { + color: variables?.colors?.primary, + }, + }, + '.ss__search-header__results-query': { + color: variables?.colors?.primary, + }, + }); + + return searchHeaderStyles; +}; + +// SearchHeader component props +export const searchHeader: ThemeComponent<'searchHeader', SearchHeaderProps> = { + default: { + searchHeader: { + themeStyleScript: searchHeaderStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/atoms/skeleton.ts b/packages/snap-preact/components/src/themes/pike/components/atoms/skeleton.ts new file mode 100644 index 0000000000..678ce766eb --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/atoms/skeleton.ts @@ -0,0 +1,28 @@ +import { css } from '@emotion/react'; +import type { SkeletonProps } from '../../../../components/Atoms/Skeleton'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Skeleton component +const skeletonStyleScript = (props: SkeletonProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // skeleton styles + const skeletonStyles = css({ + ...custom.styles.boxSizing('skeleton', props?.treePath, props?.name), + }); + + return skeletonStyles; +}; + +// Skeleton component props +export const skeleton: ThemeComponent<'skeleton', SkeletonProps> = { + default: { + skeleton: { + themeStyleScript: skeletonStyleScript, + backgroundColor: custom.colors.gray02, + animatedColor: custom.colors.gray01, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/index.ts b/packages/snap-preact/components/src/themes/pike/components/index.ts new file mode 100644 index 0000000000..b431ef8ce6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/index.ts @@ -0,0 +1,34 @@ +import { atoms } from './atoms'; +import { molecules } from './molecules'; +import { organisms } from './organisms'; +import { templates } from './templates'; + +import type { ThemeComponentsRestricted } from '../../../providers'; + +export const components: ThemeComponentsRestricted = { + ...atoms.default, + ...molecules.default, + ...organisms.default, + ...templates.default, +}; + +export const mobileComponents: ThemeComponentsRestricted = { + ...atoms.mobile, + ...molecules.mobile, + ...organisms.mobile, + ...templates.mobile, +}; + +export const tabletComponents: ThemeComponentsRestricted = { + ...atoms.tablet, + ...molecules.tablet, + ...organisms.tablet, + ...templates.tablet, +}; + +export const desktopComponents: ThemeComponentsRestricted = { + ...atoms.desktop, + ...molecules.desktop, + ...organisms.desktop, + ...templates.desktop, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/calloutBadge.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/calloutBadge.ts new file mode 100644 index 0000000000..5c824aefc9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/calloutBadge.ts @@ -0,0 +1,27 @@ +import { css } from '@emotion/react'; +import type { CalloutBadgeProps } from '../../../../components/Molecules/CalloutBadge'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const calloutBadgeStyleScript = (props: CalloutBadgeProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // callout badge styles + const calloutBadgeStyles = css({ + gap: `${custom.spacing.x2}px`, + ...custom.styles.boxSizing('calloutBadge', props?.treePath, props?.name), + }); + + return calloutBadgeStyles; +}; + +// CalloutBadge component props +export const calloutBadge: ThemeComponent<'calloutBadge', CalloutBadgeProps> = { + default: { + calloutBadge: { + themeStyleScript: calloutBadgeStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/carousel.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/carousel.ts new file mode 100644 index 0000000000..156c1a9a95 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/carousel.ts @@ -0,0 +1,138 @@ +import { css } from '@emotion/react'; +import type { CarouselProps } from '../../../../components/Molecules/Carousel'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const carouselSpacing = custom.spacing.x2; +const carouselButtonSize = 32; +const carouselPaginationSize = 12; +const carouselPaginationSpacing = carouselSpacing + carouselPaginationSize; + +// CSS in JS style script for the Carousel component +const carouselStyleScript = (props: CarouselProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // carousel styles + const carouselStyles = css({ + position: 'relative', + width: '100%', + minWidth: '1px', + ...custom.styles.boxSizing('carousel', props?.treePath, props?.name), + '.ss__carousel__prev-wrapper--hidden > div, .ss__carousel__next-wrapper--hidden > div': { + ...custom.styles.disabled(), + }, + '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + width: `${carouselButtonSize}px`, + height: `${carouselButtonSize}px`, + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + zIndex: 2, + margin: 'auto', + '& > div': { + display: 'flex', + flexFlow: 'column nowrap', + alignItems: 'center', + justifyContent: 'center', + padding: 0, + width: '100%', + height: '100%', + lineHeight: 1, + backgroundColor: variables?.colors?.primary, + color: custom.colors.white, + }, + '.swiper-button-disabled': { + ...custom.styles.disabled(), + }, + }, + '.ss__carousel__prev-wrapper': { + left: 0, + '& > div .ss__icon': { + left: '-1.5px', + }, + }, + '.ss__carousel__next-wrapper': { + right: 0, + '& > div .ss__icon': { + right: '-1.5px', + }, + }, + '.swiper-container': { + margin: '0 auto', + '&:has(.swiper-pagination)': { + paddingBottom: `${carouselPaginationSpacing}px`, + }, + '& > .swiper-wrapper': { + '& > .swiper-slide': { + '& > *, .ss__result': { + padding: 0, + margin: 0, + width: 'auto', + height: '100%', + }, + }, + }, + '& > .swiper-pagination': { + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + gap: `${custom.spacing.x1}px`, + '.swiper-pagination-bullet': { + opacity: 1, + flex: '0 1 auto', + width: `${carouselPaginationSize}px`, + height: `${carouselPaginationSize}px`, + lineHeight: `${carouselPaginationSize}px`, + minWidth: '1px', + margin: 0, + ...custom.styles.box('', 0, false), + }, + '.swiper-pagination-bullet-active': { + backgroundColor: variables?.colors?.primary, + borderColor: variables?.colors?.primary, + }, + }, + }, + '.swiper-grid-column': { + '& > .swiper-wrapper': { + flexFlow: 'row wrap', + '& > .swiper-slide': { + height: 'auto !important', + marginTop: '0 !important', + marginBottom: `${custom.spacing.x4}px`, + }, + }, + }, + }); + + return carouselStyles; +}; + +// Carousel component props +export const carousel: ThemeComponent<'carousel', CarouselProps> = { + default: { + carousel: { + themeStyleScript: carouselStyleScript, + speed: 600, + spaceBetween: carouselSpacing, + autoAdjustSlides: false, + centerInsufficientSlides: false, + }, + 'carousel icon': { + size: `${custom.sizes.icon08}px`, + width: `${custom.sizes.icon08}px`, + height: `${custom.sizes.icon08}px`, + }, + 'carousel icon.prev': { + icon: custom.icons.arrowLeft, + }, + 'carousel icon.next': { + icon: custom.icons.arrowRight, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/checkbox.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/checkbox.ts new file mode 100644 index 0000000000..7611ce58ed --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/checkbox.ts @@ -0,0 +1,68 @@ +import { css } from '@emotion/react'; +import type { CheckboxProps } from '../../../../components/Molecules/Checkbox'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const darkGray = custom.utils.darkenColor(); + +// CSS in JS style script for the Checkbox component +const checkboxStyleScript = (props: CheckboxProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // shared styles + const sharedStyles = css({ + position: 'relative', + top: '-1px', + }); + + // default checkbox styles + const defaultCheckboxStyles = css([ + sharedStyles, + { + ...custom.styles.box('', 0), + ...custom.styles.boxSizing('checkbox', props?.treePath, props?.name), + '&.ss__checkbox--active': { + borderColor: darkGray, + }, + '&.ss__checkbox--disabled': { + ...custom.styles.disabled(), + }, + }, + ]); + + // native checkbox styles + const nativeCheckboxStyles = css([ + sharedStyles, + { + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + lineHeight: 1, + cursor: 'pointer', + ...custom.styles.boxSizing('checkbox', props?.treePath, props?.name), + '&.ss__checkbox--disabled': { + ...custom.styles.disabled(), + }, + }, + ]); + + return props?.native ? nativeCheckboxStyles : defaultCheckboxStyles; +}; + +// Checkbox component props +export const checkbox: ThemeComponent<'checkbox', CheckboxProps> = { + default: { + checkbox: { + themeStyleScript: checkboxStyleScript, + icon: custom.icons.check, + size: `${custom.sizes.icon16}px`, + }, + 'checkbox icon': { + size: `${custom.sizes.icon08}px`, + width: `${custom.sizes.icon08}px`, + height: `${custom.sizes.icon08}px`, + fill: custom.colors.primary, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/errorHandler.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/errorHandler.ts new file mode 100644 index 0000000000..04c5281564 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/errorHandler.ts @@ -0,0 +1,59 @@ +import { css } from '@emotion/react'; +import type { ErrorHandlerProps } from '../../../../components/Molecules/ErrorHandler'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the ErrorHandler component +const errorHandlerStyleScript = (props: ErrorHandlerProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // error handler styles + const errorHandlerStyles = css({ + gap: `${custom.spacing.x2}px`, + padding: `${custom.spacing.x2}px`, + ...custom.styles.boxSizing('errorHandler', props?.treePath, props?.name), + '.ss__error-handler__message, .ss__error-handler__button': { + gap: `${custom.spacing.x1}px`, + }, + '.ss__error-handler__message': { + padding: 0, + flexFlow: 'row wrap', + flex: `1 1 0%`, + color: variables?.colors?.text, + 'span, .ss__icon, .ss__error-handler__message__type': { + margin: 0, + }, + '.ss__icon': { + top: '-0.5px', + stroke: 'transparent', + }, + }, + '.ss__error-handler__button': { + flex: `0 1 auto`, + margin: 0, + padding: `0 ${custom.spacing.x2}px`, + height: '28px', + lineHeight: '28px', + '.ss__button__content, .ss__icon': { + margin: 0, + }, + }, + }); + + return errorHandlerStyles; +}; + +// ErrorHandler component props +export const errorHandler: ThemeComponent<'errorHandler', ErrorHandlerProps> = { + default: { + errorHandler: { + themeStyleScript: errorHandlerStyleScript, + }, + 'errorHandler icon': { + size: `${custom.sizes.icon14}px`, + width: `${custom.sizes.icon14}px`, + height: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/facetGridOptions.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/facetGridOptions.ts new file mode 100644 index 0000000000..d47a2dffbe --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/facetGridOptions.ts @@ -0,0 +1,59 @@ +import { css } from '@emotion/react'; +import type { FacetGridOptionsProps } from '../../../../components/Molecules/FacetGridOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const activeColors = custom.utils.activeColors(); +const activeColor = activeColors[0]; +const fontColor = activeColors[1]; + +// CSS in JS style script for the FacetGridOptions component +const facetGridOptionsStyleScript = (props: FacetGridOptionsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // facet grid styles + const facetGridStyles = css({ + alignItems: 'center', + ...custom.styles.boxSizing('facetGridOptions', props?.treePath, props?.name), + '.ss__facet-grid-options__option': { + height: '100%', + aspectRatio: 1, + padding: `${custom.spacing.x2}px`, + '.ss__facet-grid-options__option__value': { + display: 'block', + overflow: 'hidden', + maxWidth: '100%', + maxHeight: '100%', + color: 'inherit', + '&, &.ss__facet-grid-options__option__value--smaller': { + fontSize: '12px', + lineHeight: 1, + }, + }, + '&, &:hover:not(.ss__facet-grid-options__option--filtered)': { + ...custom.styles.box(variables?.colors?.text, 0), + }, + '&.ss__facet-grid-options__option--filtered': { + backgroundColor: activeColor, + borderColor: activeColor, + ...custom.styles.activeText(fontColor), + }, + }, + }); + + return facetGridStyles; +}; + +// FacetGridOptions component props +export const facetGridOptions: ThemeComponent<'facetGridOptions', FacetGridOptionsProps> = { + default: { + facetGridOptions: { + themeStyleScript: facetGridOptionsStyleScript, + horizontal: true, + gridSize: '52px', + gapSize: `${custom.spacing.x1}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/facetHierarchyOptions.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/facetHierarchyOptions.ts new file mode 100644 index 0000000000..558ce841d6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/facetHierarchyOptions.ts @@ -0,0 +1,66 @@ +import { css } from '@emotion/react'; +import type { FacetHierarchyOptionsProps } from '../../../../components/Molecules/FacetHierarchyOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const lightGray = custom.utils.lightenColor(); + +// CSS in JS style script for the FacetHierarchyOptions component +const facetHierarchyOptionsStyleScript = (props: FacetHierarchyOptionsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // facet hierarchy styles + const facetHierarchyStyles = css({ + ...custom.styles.boxSizing('facetHierarchyOptions', props?.treePath, props?.name), + '.ss__facet-hierarchy-options__option': { + color: variables?.colors?.text, + gap: `${custom.spacing.x1}px`, + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__facet-hierarchy-options__option__value': { + margin: 0, + '.ss__facet-hierarchy-options__option__value__count': { + position: 'relative', + top: '-1px', + margin: 0, + padding: `0 ${custom.spacing.x1}px`, + fontSize: '10px', + color: lightGray, + }, + }, + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--return': { + '.ss__icon': { + padding: 0, + }, + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--filtered': { + ...custom.styles.activeText(variables?.colors?.primary), + '& ~ .ss__facet-hierarchy-options__option:not(.ss__facet-hierarchy-options__option--filtered)': { + paddingLeft: `${custom.spacing.x6}px`, + }, + }, + }); + + return facetHierarchyStyles; +}; + +// FacetHierarchyOptions component props +export const facetHierarchyOptions: ThemeComponent<'facetHierarchyOptions', FacetHierarchyOptionsProps> = { + default: { + facetHierarchyOptions: { + themeStyleScript: facetHierarchyOptionsStyleScript, + returnIcon: custom.icons.arrowLeft, + }, + 'facetHierarchyOptions icon': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/facetListOptions.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/facetListOptions.ts new file mode 100644 index 0000000000..a3b398953c --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/facetListOptions.ts @@ -0,0 +1,59 @@ +import { css } from '@emotion/react'; +import type { FacetListOptionsProps } from '../../../../components/Molecules/FacetListOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const lightGray = custom.utils.lightenColor(); +const checkboxSpacing = custom.sizes.icon16 + custom.spacing.x2; + +// CSS in JS style script for the FacetListOptions component +const facetListOptionsStyleScript = (props: FacetListOptionsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // facet list styles + const facetListStyles = css({ + ...custom.styles.boxSizing('facetListOptions', props?.treePath, props?.name), + '.ss__facet-list-options__option': { + color: variables?.colors?.text, + position: 'relative', + gap: `${custom.spacing.x1}px`, + padding: props?.hideCheckbox ? `` : `0 0 0 ${checkboxSpacing}px`, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__checkbox, .ss__radio': { + position: 'absolute', + top: '1.5px', + left: 0, + }, + '.ss__facet-list-options__option__value': { + margin: 0, + '.ss__facet-list-options__option__value__count': { + position: 'relative', + top: '-1px', + margin: 0, + padding: `0 ${custom.spacing.x1}px`, + fontSize: '10px', + color: lightGray, + }, + }, + }, + '.ss__facet-list-options__option.ss__facet-list-options__option--filtered': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }); + + return facetListStyles; +}; + +// FacetListOptions component props +export const facetListOptions: ThemeComponent<'facetListOptions', FacetListOptionsProps> = { + default: { + facetListOptions: { + themeStyleScript: facetListOptionsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/facetPaletteOptions.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/facetPaletteOptions.ts new file mode 100644 index 0000000000..ace1855acb --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/facetPaletteOptions.ts @@ -0,0 +1,207 @@ +import { css } from '@emotion/react'; +import type { FacetPaletteOptionsProps } from '../../../../components/Molecules/FacetPaletteOptions'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const lightGray = custom.utils.lightenColor(); +const paletteColors = { + brown: '#845329', + purple: '#7c368e', + rainbow: + 'linear-gradient(rgb(40, 87, 218) 20%, rgb(40, 218, 70) 20%, rgb(40, 218, 70) 40%, rgb(245, 228, 24) 40%, rgb(245, 228, 24) 60%, rgb(242, 133, 0) 60%, rgb(242, 133, 0) 80%, rgb(218, 40, 72) 80%, rgb(218, 40, 72))', +}; + +// CSS in JS style script for the FacetPaletteOptions component +const facetPaletteStyleScript = (props: FacetPaletteOptionsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const hasCheckbox = !props?.hideCheckbox ? true : false; + const isList = props?.layout == 'list' ? true : false; + const innerBorder = isList ? 3 : 5; + + // shared styles + const sharedStyles = css({ + ...custom.styles.boxSizing('facetPaletteOptions', props?.treePath, props?.name), + '.ss__facet-palette-options__option': { + color: variables?.colors?.text, + '&.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper .ss__facet-palette-options__option__palette': { + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + }, + '.ss__facet-palette-options__option__value': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + '.ss__facet-palette-options__option__wrapper': { + border: 0, + ...custom.styles.borderRadius(0), + '.ss__facet-palette-options__option__palette': { + overflow: 'hidden', + border: 0, + padding: 0, + '&, &:before, &:after': { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + ...custom.styles.borderRadius(0), + }, + '&:before, &:after': { + content: '""', + display: 'block', + }, + '&:before': { + border: `${innerBorder}px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '&[style*="url"]': { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + '.ss__image': { + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + }, + }, + '.ss__facet-palette-options__option__value__count': { + position: 'relative', + top: isList ? '-1px' : '', + padding: isList ? `0 ${custom.spacing.x1}px` : ``, + fontSize: '10px', + color: lightGray, + }, + }, + }); + + // facet palette grid styles + const facetPaletteGridStyles = css([ + sharedStyles, + { + alignItems: 'center', + '.ss__facet-palette-options__option': { + display: 'block', + textAlign: 'center', + '&, &.ss__facet-palette-options__option--filtered': { + '.ss__facet-palette-options__option__wrapper': { + position: 'relative', + height: 0, + padding: '0 0 100% 0', + }, + }, + '.ss__checkbox, .ss__radio': { + display: 'none', + }, + '.ss__facet-palette-options__option__value, .ss__facet-palette-options__option__value__count': { + display: 'block', + lineHeight: '0.85rem', + }, + '.ss__facet-palette-options__option__value': { + fontSize: '12px', + overflow: 'hidden', + margin: `${custom.spacing.x1}px 0 0 0`, + }, + '.ss__facet-palette-options__option__value__count': { + margin: `${custom.spacing.x1 / 2}px 0 0 0`, + }, + }, + }, + ]); + + // list variables + const listSize = hasCheckbox ? 16 : 22; + const listCheckboxSize = 16; + const listPadding = hasCheckbox ? custom.spacing.x4 + listSize + listCheckboxSize : custom.spacing.x2 + listSize; + + // facet palette list styles + const facetPaletteListStyles = css([ + sharedStyles, + { + '&.ss__facet-palette-options--list': { + display: 'block', + }, + '.ss__facet-palette-options__option': { + minHeight: hasCheckbox ? '' : `${listSize + 2}px`, + position: 'relative', + gap: `${custom.spacing.x1}px`, + padding: `${hasCheckbox ? 0 : '2px'} 0 0 ${listPadding}px`, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__checkbox, .ss__radio, .ss__facet-palette-options__option__wrapper': { + position: 'absolute', + top: `${hasCheckbox ? 2 : 0.5}px`, + }, + '.ss__checkbox, .ss__radio': { + left: 0, + }, + '.ss__facet-palette-options__option__wrapper': { + left: hasCheckbox ? `${listCheckboxSize + custom.spacing.x2}px` : 0, + width: `${listSize}px`, + height: `${listSize}px`, + lineHeight: `${listSize}px`, + }, + '.ss__facet-palette-options__option__value, .ss__facet-palette-options__option__value__count': { + display: 'inline-block', + overflow: 'visible', + textOverflow: 'unset', + textAlign: 'left', + whiteSpace: 'unset', + }, + '.ss__facet-palette-options__option__value__count': { + margin: 0, + }, + }, + }, + ]); + + return isList ? facetPaletteListStyles : facetPaletteGridStyles; +}; + +// FacetPaletteOptions component props +export const facetPaletteOptions: ThemeComponent<'facetPaletteOptions', FacetPaletteOptionsProps> = { + default: { + facetPaletteOptions: { + themeStyleScript: facetPaletteStyleScript, + hideIcon: true, + horizontal: true, + gridSize: '52px', + gapSize: `${custom.spacing.x1}px`, + colorMapping: { + brown: { + background: paletteColors.brown, + }, + multi: { + background: paletteColors.rainbow, + }, + 'multi-color': { + background: paletteColors.rainbow, + }, + purple: { + background: paletteColors.purple, + }, + rainbow: { + background: paletteColors.rainbow, + }, + }, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/facetSlider.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/facetSlider.ts new file mode 100644 index 0000000000..abd6834ad9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/facetSlider.ts @@ -0,0 +1,193 @@ +import { css } from '@emotion/react'; +import type { FacetSliderProps } from '../../../../components/Molecules/FacetSlider'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// slider options +const slider = { + handles: 20, // handle size + values: 14, // values size + bar: 6, // bar size + ticks: 17, // size of ticks + valuesPosition: 'top', // position of slider values (top or bottom) + valuesAlign: 'sides', // alignment of slider values (sides or center) +}; + +// value settings +const valuesTop = slider.valuesPosition == 'top' ? true : false; +const valuesSides = slider.valuesAlign == 'sides' ? true : false; + +// spacing and size calculations +const handlesSizeHalf = (slider.handles - slider.bar) / 2; +const handlesSpacing = slider.handles + custom.spacing.x2; +const ticksSpacing = slider.ticks + custom.spacing.x1; +const stickySpacing = slider.values + custom.spacing.x2; +const handlesPlusSticky = handlesSizeHalf + stickySpacing; +const ticksPlusSticky = ticksSpacing + stickySpacing; + +// CSS in JS style script for the FacetSlider component +const facetSliderStyleScript = (props: FacetSliderProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const hasTicks = props?.showTicks ? true : false; + const hasStickyHandles = props?.stickyHandleLabel ? true : false; + const activeColors = custom.utils.activeColors(props?.handleColor); + + // values font styles + const valuesStyles = css({ + fontSize: `${slider.values}px`, + lineHeight: `${slider.values}px`, + }); + + // shared styles + const sharedStyles = css({ + ...custom.styles.boxSizing('facetSlider', props?.treePath, props?.name), + '&, .ss__facet-slider__slider': { + margin: 'auto', + }, + '.ss__facet-slider__slider button, .ss__facet-slider__labels label': { + margin: 0, + padding: 0, + '&:focus': { + outline: 0, + }, + }, + '.ss__facet-slider__slider': { + display: 'block', + top: 0, + width: '100%', + height: `${slider.bar}px`, + '.ss__facet-slider__segment, .ss__facet-slider__rail, .ss__facet-slider__handles': { + height: '100%', + }, + '.ss__facet-slider__tick': { + '&:before, .ss__facet-slider__tick__label': { + transform: 'translate(-50%, 0)', + }, + '&:before': { + top: `${slider.ticks / 2}px`, + backgroundColor: custom.colors.gray02, + }, + '.ss__facet-slider__tick__label': { + top: `${slider.ticks}px`, + lineHeight: 1, + }, + }, + '.ss__facet-slider__segment': { + ...custom.styles.box('', 0), + ...custom.styles.borderRadius(slider.bar), + }, + '.ss__facet-slider__rail': {}, + '.ss__facet-slider__handles': { + position: 'relative', + margin: `0 ${slider.handles / 2 - 2}px`, + button: { + '.ss__facet-slider__handle': { + transform: 'none', + width: `${slider.handles}px`, + height: `${slider.handles}px`, + lineHeight: `${slider.handles}px`, + '&:after': { + width: `${slider.handles / 4}px`, + height: `${slider.handles / 4}px`, + backgroundColor: activeColors[1], + }, + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + backgroundColor: 'transparent', + '&': { + ...valuesStyles, + }, + }, + }, + }, + }, + }, + '.ss__facet-slider__labels': { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + justifyContent: valuesSides ? '' : 'center', + '.ss__facet-slider__label': { + '&': { + ...valuesStyles, + }, + '&:after': { + display: valuesSides ? 'none' : '', + padding: `0 ${custom.spacing.x1}px`, + }, + '& ~ .ss__facet-slider__label': { + marginLeft: valuesSides ? 'auto' : '', + }, + }, + }, + }); + + // spacing styles for different configurations + // note: default for facet slider is no ticks, no stick handles, values bottom + let spacingStyles = css({}); + + if (hasTicks && hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${valuesTop ? handlesPlusSticky : handlesSizeHalf}px auto ${valuesTop ? ticksSpacing : ticksPlusSticky}px auto`, + '.ss__facet-slider__handles button .ss__facet-slider__handle': { + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + top: valuesTop ? `auto` : `${handlesSizeHalf + ticksPlusSticky - slider.bar}px`, + bottom: valuesTop ? `${handlesSpacing}px` : ``, + }, + }, + }, + }); + } else if (hasTicks && !hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${handlesSizeHalf}px auto ${ticksSpacing}px auto`, + }, + '.ss__facet-slider__labels': { + order: valuesTop ? -1 : '', + margin: `${valuesTop ? 0 : custom.spacing.x2}px 0 ${valuesTop ? custom.spacing.x2 : 0}px 0`, + }, + }); + } else if (!hasTicks && hasStickyHandles) { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${valuesTop ? handlesPlusSticky : handlesSizeHalf}px auto ${valuesTop ? handlesSizeHalf : handlesPlusSticky}px auto`, + '.ss__facet-slider__handles button .ss__facet-slider__handle': { + '.ss__facet-slider__handle__label.ss__facet-slider__handle__label--sticky': { + top: valuesTop ? 'auto' : `${handlesSpacing}px`, + bottom: valuesTop ? `${handlesSpacing}px` : ``, + }, + }, + }, + }); + } else { + spacingStyles = css({ + '.ss__facet-slider__slider': { + margin: `${handlesSizeHalf}px auto`, + }, + '.ss__facet-slider__labels': { + order: valuesTop ? -1 : '', + margin: `${valuesTop ? 0 : custom.spacing.x2}px 0 ${valuesTop ? custom.spacing.x2 : 0}px 0`, + }, + }); + } + + // facet slider styles + const facetSliderStyles = css([sharedStyles, spacingStyles]); + + return facetSliderStyles; +}; + +// FacetSlider component props +export const facetSlider: ThemeComponent<'facetSlider', FacetSliderProps> = { + default: { + facetSlider: { + themeStyleScript: facetSliderStyleScript, + handleColor: custom.colors.primary, + handleDraggingColor: custom.colors.primary, + railColor: custom.colors.secondary, + tickTextColor: custom.colors.text, + valueTextColor: custom.colors.text, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/filter.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/filter.ts new file mode 100644 index 0000000000..fbd368d3f5 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/filter.ts @@ -0,0 +1,58 @@ +import { css } from '@emotion/react'; +import type { FilterProps } from '../../../../components/Molecules/Filter'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Filter component +const filterStyleScript = (props: FilterProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // filter styles + const filterStyles = css({ + ...custom.styles.boxSizing('filter', props?.treePath, props?.name), + '&, .ss__filter__button': { + padding: 0, + }, + '&.ss__filter-summary__clear-all .ss__filter__button .ss__button__content .ss__filter__value': { + margin: 0, + }, + '.ss__filter__button': { + position: 'relative', + height: 'auto', + lineHeight: 1.5, + fontWeight: 'normal', + color: variables?.colors?.text, + '&, &:hover, &:not(.ss__button--disabled):hover, &.ss__button--disabled': { + backgroundColor: 'transparent', + borderColor: 'transparent', + }, + '.ss__button__content': { + position: 'relative', + '.ss__filter__button__icon, .ss__filter__label, .ss__filter__value': { + margin: 0, + }, + '.ss__filter__label': { + fontWeight: custom.fonts.weight01, + }, + }, + }, + }); + + return filterStyles; +}; + +// Filter component props +export const filter: ThemeComponent<'filter', FilterProps> = { + default: { + filter: { + themeStyleScript: filterStyleScript, + icon: custom.icons.close, + }, + 'filter icon': { + size: `${custom.sizes.icon10}px`, + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/grid.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/grid.ts new file mode 100644 index 0000000000..044a6bb71b --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/grid.ts @@ -0,0 +1,202 @@ +import { css } from '@emotion/react'; +import type { GridProps } from '../../../../components/Molecules/Grid'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const gridSize = 42; +const gridSelector = 'ss__grid__option'; +const darkSelector = `&.${gridSelector}--dark, &:has(.${gridSelector}__inner--grey), &:has(.${gridSelector}__inner--gray)`; +const imageSelector = '&:has(.ss__image)'; +const urlSelector = '&[style*="url"]'; +const styleSelector = '&[style], &:has(.ss__image)'; +const activeColors = custom.utils.activeColors(); +const activeColor = activeColors[0]; +const fontColor = activeColors[1]; + +// CSS in JS style script for the Grid component +const gridStyleScript = (props: Partial) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // grid styles + const gridStyles = css({ + ...custom.styles.boxSizing('grid', props?.treePath, props?.name), + '.ss__grid__title': { + margin: `0 0 ${custom.spacing.x1}px 0`, + ...custom.styles.headerText(variables?.colors?.secondary, '14px'), + }, + '.ss__grid__options .ss__grid__option .ss__grid__option__inner .ss__grid__option__label, .ss__grid__show-more-wrapper': { + fontSize: '12px', + lineHeight: 1, + }, + '.ss__grid__options': { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + '&:before, &:after': { + display: 'none', + }, + '.ss__grid__option': { + flex: '0 1 auto', + minWidth: '1px', + '&, &.ss__grid__option--selected': { + border: 0, + }, + }, + '.ss__grid__option:not(.ss__grid__show-more-wrapper)': { + position: 'relative', + width: `${gridSize}px`, + maxHeight: `${gridSize}px`, + height: '100%', + aspectRatio: 1, + '.ss__grid__option__inner': { + position: 'relative', + width: '100%', + ...custom.styles.box(variables?.colors?.text, `${custom.spacing.x1}px`), + '&, .ss__grid__option__label': { + overflow: 'hidden', + }, + '.ss__grid__option__label': { + maxWidth: '100%', + maxHeight: '100%', + }, + [styleSelector]: { + border: 0, + backgroundColor: 'transparent', + '&:before, &:after': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + ...custom.styles.borderRadius(), + }, + '&:before': { + border: `3px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '.ss__grid__option__label': { + ...custom.styles.srOnly(), + }, + }, + [`${urlSelector}, ${imageSelector}`]: { + '&:before': { + margin: 0, + borderWidth: '4px', + }, + }, + [urlSelector]: { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + [imageSelector]: { + '&:before, &:after': { + zIndex: 3, + }, + '.ss__image, .ss__grid__option__label': { + position: 'absolute', + }, + '.ss__image': { + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1, + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + '.ss__grid__option__label': { + zIndex: 2, + }, + }, + }, + [darkSelector]: { + '.ss__grid__option__inner': { + color: fontColor, + }, + }, + '&.ss__grid__option--disabled, &.ss__grid__option--unavailable': { + opacity: 1, + cursor: 'not-allowed !important', + pointerEvents: 'unset', + '&:before': { + maxWidth: `${gridSize - 4}px`, + top: 0, + bottom: 0, + zIndex: 3, + margin: 'auto 0', + borderTop: `2px solid ${custom.colors.white}`, + outlineColor: custom.colors.gray02, + ...custom.styles.borderRadius(3), + }, + '.ss__grid__option__inner': { + opacity: 0.65, + }, + }, + '&.ss__grid__option--selected': { + '.ss__grid__option__inner': { + borderColor: activeColor, + backgroundColor: activeColor, + color: fontColor, + [styleSelector]: { + border: 0, + backgroundColor: 'transparent', + color: variables?.colors?.text, + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + }, + '.ss__grid__option__label': { + fontWeight: custom.fonts.weight01, + }, + }, + [darkSelector]: { + '.ss__grid__option__inner': { + color: fontColor, + }, + }, + }, + }, + }, + '.ss__grid__show-more-wrapper': { + '&:not(.ss__grid__option)': { + margin: `${custom.spacing.x1}px 0 0 0`, + }, + '&, .ss__grid__show-more': { + cursor: 'pointer', + }, + '.ss__grid__show-more': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + }); + + return gridStyles; +}; + +// Grid component props +export const grid: ThemeComponent<'grid', GridProps> = { + default: { + grid: { + themeStyleScript: gridStyleScript, + gapSize: `${custom.spacing.x1}px`, + hideLabels: false, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/index.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/index.ts new file mode 100644 index 0000000000..ec794bac9d --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/index.ts @@ -0,0 +1,164 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// MOLECULES Imports +import { calloutBadge } from './calloutBadge'; +import { carousel } from './carousel'; +import { checkbox } from './checkbox'; +import { errorHandler } from './errorHandler'; +import { facetGridOptions } from './facetGridOptions'; +import { facetHierarchyOptions } from './facetHierarchyOptions'; +import { facetListOptions } from './facetListOptions'; +import { facetPaletteOptions } from './facetPaletteOptions'; +import { facetSlider } from './facetSlider'; +import { filter } from './filter'; +import { grid } from './grid'; +import { layoutSelector } from './layoutSelector'; +import { list } from './list'; +import { loadMore } from './loadMore'; +import { modal } from './modal'; +import { overlayBadge } from './overlayBadge'; +import { pagination } from './pagination'; +import { perPage } from './perPage'; +import { radio } from './radio'; +import { radioList } from './radioList'; +import { result } from './result'; +import { searchInput } from './searchInput'; +import { select } from './select'; +import { slideshow } from './slideshow'; +import { slideout } from './slideout'; +import { sortBy } from './sortBy'; +import { rating } from './rating'; +import { swatches } from './swatches'; +import { variantSelection } from './variantSelection'; +import { terms } from './terms'; + +export const molecules: ThemeResponsiveComplete = { + default: { + ...calloutBadge.default, + ...carousel.default, + ...checkbox.default, + ...errorHandler.default, + ...facetGridOptions.default, + ...facetHierarchyOptions.default, + ...facetListOptions.default, + ...facetPaletteOptions.default, + ...facetSlider.default, + ...filter.default, + ...grid.default, + ...layoutSelector.default, + ...list.default, + ...loadMore.default, + ...modal.default, + ...overlayBadge.default, + ...pagination.default, + ...perPage.default, + ...radio.default, + ...radioList.default, + ...rating.default, + ...result.default, + ...searchInput.default, + ...select.default, + ...slideshow.default, + ...slideout.default, + ...sortBy.default, + ...swatches.default, + ...terms.default, + ...variantSelection.default, + }, + mobile: { + ...calloutBadge.mobile, + ...carousel.mobile, + ...checkbox.mobile, + ...errorHandler.mobile, + ...facetGridOptions.mobile, + ...facetHierarchyOptions.mobile, + ...facetListOptions.mobile, + ...facetPaletteOptions.mobile, + ...facetSlider.mobile, + ...filter.mobile, + ...grid.mobile, + ...layoutSelector.mobile, + ...list.mobile, + ...loadMore.mobile, + ...modal.mobile, + ...overlayBadge.mobile, + ...pagination.mobile, + ...perPage.mobile, + ...radio.mobile, + ...radioList.mobile, + ...rating.mobile, + ...result.mobile, + ...searchInput.mobile, + ...select.mobile, + ...slideshow.mobile, + ...slideout.mobile, + ...sortBy.mobile, + ...swatches.mobile, + ...terms.mobile, + ...variantSelection.mobile, + }, + tablet: { + ...calloutBadge.tablet, + ...carousel.tablet, + ...checkbox.tablet, + ...errorHandler.tablet, + ...facetGridOptions.tablet, + ...facetHierarchyOptions.tablet, + ...facetListOptions.tablet, + ...facetPaletteOptions.tablet, + ...facetSlider.tablet, + ...filter.tablet, + ...grid.tablet, + ...layoutSelector.tablet, + ...list.tablet, + ...loadMore.tablet, + ...modal.tablet, + ...overlayBadge.tablet, + ...pagination.tablet, + ...perPage.tablet, + ...radio.tablet, + ...radioList.tablet, + ...rating.tablet, + ...result.tablet, + ...searchInput.tablet, + ...select.tablet, + ...slideshow.tablet, + ...slideout.tablet, + ...sortBy.tablet, + ...swatches.tablet, + ...terms.tablet, + ...variantSelection.tablet, + }, + desktop: { + ...calloutBadge.desktop, + ...carousel.desktop, + ...checkbox.desktop, + ...errorHandler.desktop, + ...facetGridOptions.desktop, + ...facetHierarchyOptions.desktop, + ...facetListOptions.desktop, + ...facetPaletteOptions.desktop, + ...facetSlider.desktop, + ...filter.desktop, + ...grid.desktop, + ...layoutSelector.desktop, + ...list.desktop, + ...loadMore.desktop, + ...modal.desktop, + ...overlayBadge.desktop, + ...pagination.desktop, + ...perPage.desktop, + ...radio.desktop, + ...radioList.desktop, + ...rating.desktop, + ...result.desktop, + ...searchInput.desktop, + ...select.desktop, + ...slideshow.desktop, + ...slideout.desktop, + ...sortBy.desktop, + ...swatches.desktop, + ...terms.desktop, + ...variantSelection.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/layoutSelector.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/layoutSelector.ts new file mode 100644 index 0000000000..56b7cfd5b4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/layoutSelector.ts @@ -0,0 +1,88 @@ +import { css } from '@emotion/react'; +import type { LayoutSelectorProps } from '../../../../components/Molecules/LayoutSelector'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const activeColors = custom.utils.activeColors(); +const activeColor = activeColors[0]; +const activeIconColor = activeColors[1]; + +// CSS in JS style script for the LayoutSelector component +const layoutSelectorStyleScript = (props: LayoutSelectorProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // shared styles + const sharedStyles = css({ + ...custom.styles.boxSizing('layoutSelector', props?.treePath, props?.name), + }); + + // dropdown styles + const dropdownStyles = css([ + sharedStyles, + { + '.ss__dropdown': { + '.ss__dropdown__button .ss__button__content .ss__select__label': { + paddingRight: `${custom.spacing.x1 / 2}px`, + }, + }, + }, + ]); + + // radio styles + const radioStyles = css([sharedStyles]); + + // list styles + const listStyles = css([ + sharedStyles, + { + '.ss__list__options': { + display: 'flex', + '.ss__list__option': { + ...custom.styles.box(variables?.colors?.text, `0 ${custom.spacing.x2}px`), + margin: 0, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + }, + '.ss__list__option--selected': { + '&, &:hover': { + borderColor: activeColor, + backgroundColor: activeColor, + color: activeIconColor, + }, + '&, *': { + cursor: 'text', + }, + }, + }, + }, + ]); + + if (props?.type == 'list') { + return listStyles; + } else if (props?.type == 'radio') { + return radioStyles; + } else { + return dropdownStyles; + } +}; + +// LayoutSelector component props +export const layoutSelector: ThemeComponent<'layoutSelector', LayoutSelectorProps> = { + default: { + layoutSelector: { + themeStyleScript: layoutSelectorStyleScript, + }, + 'layoutSelector select': { + hideSelection: false, + }, + 'layoutSelector list': { + hideTitleText: true, + hideOptionLabels: true, + }, + 'layoutSelector radioList': { + hideTitleText: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/list.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/list.ts new file mode 100644 index 0000000000..bcab2747fd --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/list.ts @@ -0,0 +1,74 @@ +import { css } from '@emotion/react'; +import type { ListProps } from '../../../../components/Molecules/List'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const checkboxSpacing = custom.sizes.icon16 + custom.spacing.x2; + +// CSS in JS style script for the List component +const listStyleScript = (props: ListProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // list styles + const listStyles = css({ + ...custom.styles.boxSizing('list', props?.treePath, props?.name), + '&, .ss__list__options, .ss__list__title': { + display: 'block', + }, + '&.ss__list--disabled': { + ...custom.styles.disabled(), + '*': { + cursor: 'not-allowed !important', + }, + }, + '.ss__list__title, .ss__list__options': { + width: '100%', + }, + '.ss__list__title, .ss__list__options .ss__list__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + }, + '.ss__list__title': { + ...custom.styles.headerText(variables?.colors?.secondary, '14px'), + }, + '.ss__list__options': { + '.ss__list__option': { + position: 'relative', + color: variables?.colors?.text, + gap: `${custom.spacing.x2}px`, + padding: props?.hideOptionCheckboxes ? `` : `0 0 0 ${checkboxSpacing}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__list__option__label, .ss__list__option__icon': { + padding: 0, + }, + '.ss__checkbox': { + position: 'absolute', + top: '1.5px', + left: 0, + }, + '.ss__list__option__icon': { + position: 'relative', + top: '-1px', + }, + }, + '.ss__list__option--selected': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + }); + + return listStyles; +}; + +// List component props +export const list: ThemeComponent<'list', ListProps> = { + default: { + list: { + themeStyleScript: listStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/loadMore.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/loadMore.ts new file mode 100644 index 0000000000..c977cf1b40 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/loadMore.ts @@ -0,0 +1,50 @@ +import { css } from '@emotion/react'; +import type { LoadMoreProps } from '../../../../components/Molecules/LoadMore'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the LoadMore component +const loadMoreStyleScript = (props: LoadMoreProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // load more styles + const loadMoreStyles = css({ + ...custom.styles.boxSizing('loadMore', props?.treePath, props?.name), + '&.ss__load-more': { + '&, .ss__load-more__progress': { + gap: `${custom.spacing.x2}px`, + }, + '.ss__load-more__progress': { + '.ss__load-more__progress__indicator': { + ...custom.styles.box('', 0), + ...custom.styles.borderRadius(5), + '.ss__load-more__progress__indicator__bar': { + margin: '-1px', + }, + }, + '.ss__load-more__progress__text': { + color: variables?.colors?.text, + }, + }, + }, + }); + + return loadMoreStyles; +}; + +// LoadMore component props +export const loadMore: ThemeComponent<'loadMore', LoadMoreProps> = { + default: { + loadMore: { + themeStyleScript: loadMoreStyleScript, + color: custom.colors.primary, + }, + 'loadMore icon': { + fill: custom.colors.primary, + }, + 'loadMore button icon': { + fill: 'currentColor', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/modal.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/modal.ts new file mode 100644 index 0000000000..38402a88c4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/modal.ts @@ -0,0 +1,30 @@ +import { css } from '@emotion/react'; +import type { ModalProps } from '../../../../components/Molecules/Modal'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Modal component +const modalStyleScript = (props: ModalProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // modal styles + const modalStyles = css({ + cursor: 'pointer', + ...custom.styles.boxSizing('modal', props?.treePath, props?.name), + '.ss__modal__content': { + backgroundColor: 'transparent', + }, + }); + + return modalStyles; +}; + +// Modal component props +export const modal: ThemeComponent<'modal', ModalProps> = { + default: { + modal: { + themeStyleScript: modalStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/overlayBadge.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/overlayBadge.ts new file mode 100644 index 0000000000..a2d5fa77e9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/overlayBadge.ts @@ -0,0 +1,34 @@ +import { css } from '@emotion/react'; +import type { OverlayBadgeProps } from '../../../../components/Molecules/OverlayBadge'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const overlayBadgeStyleScript = (props: OverlayBadgeProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // overlay badge styles + const overlayBadgeStyles = css({ + ...custom.styles.boxSizing('overlayBadge', props?.treePath, props?.name), + '.ss__overlay-badge__grid-wrapper': { + zIndex: 1, + gap: `${custom.spacing.x2}px`, + bottom: 'auto', + '.ss__overlay-badge__grid-wrapper__slot': { + gap: `${custom.spacing.x1}px`, + }, + }, + }); + + return overlayBadgeStyles; +}; + +// OverlayBadge component props +export const overlayBadge: ThemeComponent<'overlayBadge', OverlayBadgeProps> = { + default: { + overlayBadge: { + themeStyleScript: overlayBadgeStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/pagination.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/pagination.ts new file mode 100644 index 0000000000..10f6843d68 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/pagination.ts @@ -0,0 +1,76 @@ +import { css } from '@emotion/react'; +import type { PaginationProps } from '../../../../components/Molecules/Pagination'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Pagination component +const paginationStyleScript = (props: PaginationProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + const paginationStyles = css({ + ...custom.styles.boxSizing('pagination', props?.treePath, props?.name), + nav: { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + justifyContent: 'center', + gap: `${custom.spacing.x2}px`, + '.ss__pagination__page, span': { + padding: 0, + fontSize: '14px', + color: variables?.colors?.text, + }, + '.ss__pagination__page': { + minWidth: '1px', + minHeight: '1px', + '&.ss__pagination__page--active': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + '.ss__pagination__page--previous, .ss__pagination__page--next': { + lineHeight: `10px`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + nav: { + gap: `${custom.spacing.x4}px`, + '.ss__pagination__page, span': { + fontSize: '16px', + }, + }, + }, + }); + + return paginationStyles; +}; + +// Pagination component props +export const pagination: ThemeComponent<'pagination', PaginationProps> = { + default: { + pagination: { + themeStyleScript: paginationStyleScript, + }, + 'pagination icon': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + 'pagination icon.prev': { + icon: custom.icons.arrowLeft, + fill: custom.colors.primary, + }, + 'pagination icon.next': { + icon: custom.icons.arrowRight, + fill: custom.colors.primary, + }, + }, + mobile: { + 'pagination icon': { + size: `${custom.sizes.icon14}px`, + width: `${custom.sizes.icon14}px`, + height: `${custom.sizes.icon14}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/perPage.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/perPage.ts new file mode 100644 index 0000000000..3854de64d5 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/perPage.ts @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { PerPageProps } from '../../../../components/Molecules/PerPage'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the PerPage component +const perPageStyleScript = (props: PerPageProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // perPage styles + const perPageStyles = css({ + ...custom.styles.boxSizing('perPage', props?.treePath, props?.name), + }); + + return perPageStyles; +}; + +// PerPage component props +export const perPage: ThemeComponent<'perPage', PerPageProps> = { + default: { + perPage: { + themeStyleScript: perPageStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/radio.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/radio.ts new file mode 100644 index 0000000000..6f5d073cd2 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/radio.ts @@ -0,0 +1,75 @@ +import { css } from '@emotion/react'; +import type { RadioProps } from '../../../../components/Molecules/Radio'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const darkGray = custom.utils.darkenColor(); + +// CSS in JS style script for the Radio component +const radioStyleScript = (props: RadioProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // default radio styles + const defaultRadiosStyles = css([ + { + position: 'relative', + top: '-1px', + ...custom.styles.box('', 0), + ...custom.styles.borderRadius(50, '%'), + ...custom.styles.boxSizing('radio', props?.treePath, props?.name), + '&.ss__radio--disabled': { + ...custom.styles.disabled(), + }, + '&.ss__radio--active': { + borderColor: darkGray, + '.ss__icon': { + opacity: 1, + }, + }, + '.ss__icon': { + opacity: 0, + }, + }, + ]); + + // native radio styles + const nativeRadiosStyles = css([ + { + lineHeight: 0, + ...custom.styles.boxSizing('radio', props?.treePath, props?.name), + '&.ss__radio--disabled .ss__radio__input': { + ...custom.styles.disabled(), + }, + '.ss__radio__input': { + position: 'relative', + top: '-0.5px', + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + lineHeight: 1, + cursor: 'pointer', + }, + }, + ]); + + return props?.native ? nativeRadiosStyles : defaultRadiosStyles; +}; + +// Radio component props +export const radio: ThemeComponent<'radio', RadioProps> = { + default: { + radio: { + themeStyleScript: radioStyleScript, + checkedIcon: 'circle', + unCheckedIcon: 'circle', + size: `${custom.sizes.icon16}px`, + }, + 'radio icon': { + size: `${custom.sizes.icon08}px`, + width: `${custom.sizes.icon08}px`, + height: `${custom.sizes.icon08}px`, + fill: custom.colors.primary, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/radioList.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/radioList.ts new file mode 100644 index 0000000000..107e33bcdf --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/radioList.ts @@ -0,0 +1,77 @@ +import { css } from '@emotion/react'; +import type { RadioListProps } from '../../../../components/Molecules/RadioList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const radioSpacing = custom.sizes.icon16 + custom.spacing.x2; + +// CSS in JS style script for the RadioList component +const radioListStyleScript = (props: RadioListProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // radio list styles + const radioListStyles = css({ + ...custom.styles.boxSizing('radioList', props?.treePath, props?.name), + '&, .ss__radio-list__options-wrapper, .ss__radio-list__title': { + display: 'block', + }, + '&.ss__radio-list--disabled': { + ...custom.styles.disabled(), + '*': { + cursor: 'not-allowed !important', + }, + }, + '.ss__radio-list__title, .ss__radio-list__options-wrapper': { + width: '100%', + }, + '.ss__radio-list__title, .ss__radio-list__options-wrapper .ss__radio-list__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + }, + '.ss__radio-list__title': { + ...custom.styles.headerText(variables?.colors?.secondary, '14px'), + }, + '.ss__radio-list__options-wrapper': { + '.ss__radio-list__option': { + position: 'relative', + color: variables?.colors?.text, + gap: `${custom.spacing.x2}px`, + padding: props?.hideOptionRadios ? `` : `0 0 0 ${radioSpacing}px`, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__radio-list__option__label, .ss__radio-list__option__icon': { + padding: 0, + }, + '.ss__radio': { + position: 'absolute', + top: '1.5px', + left: 0, + '&:has(.ss__radio__input)': { + top: '2.5px', + }, + }, + '.ss__radio-list__option__icon': { + position: 'relative', + top: '-1px', + }, + }, + '.ss__radio-list__option--selected': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + }); + + return radioListStyles; +}; + +// RadioList component props +export const radioList: ThemeComponent<'radioList', RadioListProps> = { + default: { + radioList: { + themeStyleScript: radioListStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/rating.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/rating.ts new file mode 100644 index 0000000000..fc604438c3 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/rating.ts @@ -0,0 +1,55 @@ +import { css } from '@emotion/react'; +import type { RatingProps } from '../../../../components/Molecules/Rating'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const darkGray = custom.utils.darkenColor(); + +// CSS in JS style script for the Rating component +const ratingStyleScript = (props: RatingProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // rating styles + const ratingStyles = css({ + flexWrap: 'wrap', + gap: `${custom.spacing.x1}px`, + lineHeight: 1, + ...custom.styles.boxSizing('rating', props?.treePath, props?.name), + '.ss__rating__icons': { + '.ss__rating__stars': { + gap: '2px', + gridTemplateColumns: 'repeat(5, 1fr)', + }, + }, + '.ss__rating__count, .ss__rating__text': { + fontSize: '12px', + color: variables?.colors?.text, + }, + }); + + return ratingStyles; +}; + +// Rating component props +export const rating: ThemeComponent<'rating', RatingProps> = { + default: { + rating: { + themeStyleScript: ratingStyleScript, + emptyIcon: 'star', + fullIcon: 'star', + }, + 'rating icon': { + size: `${custom.sizes.icon14}px`, + width: `${custom.sizes.icon14}px`, + height: `${custom.sizes.icon14}px`, + }, + 'rating icon.star--empty': { + fill: darkGray, + }, + 'rating icon.star--full': { + fill: custom.colors.primary, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/result.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/result.ts new file mode 100644 index 0000000000..515f54f3c6 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/result.ts @@ -0,0 +1,187 @@ +import { css } from '@emotion/react'; +import type { ResultProps } from '../../../../components/Molecules/Result'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const lightGray = custom.utils.lightenColor(); + +// CSS in JS style script for the Result component +const resultStyleScript = (props: ResultProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + // result styles + const resultStyles = css({ + ...custom.styles.boxSizing('result', props?.treePath, props?.name), + '&.ss__result--sale': { + '.ss__result__details': { + '.ss__result__details__pricing': { + '.ss__result__price:not(.ss__price--strike)': { + '&, span': { + color: variables?.colors?.primary, + }, + }, + }, + }, + }, + '&.ss__result--grid': { + gap: `${custom.spacing.x2}px`, + '&, .ss__result__details': { + flexFlow: 'column nowrap', + }, + '.ss__result__image-wrapper': { + flex: '0 1 auto', + }, + '.ss__result__details': { + flex: '1 1 0%', + '& > *': { + flex: '0 1 auto', + }, + '.ss__result__add-to-cart-wrapper .ss__button': { + width: `100%`, + }, + }, + }, + '&.ss__result--list': { + alignItems: 'center', + gap: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + '&, .ss__result__details': { + flexFlow: 'row wrap', + }, + '.ss__result__image-wrapper': { + flex: '0 0 33.33%', + }, + '.ss__result__details': { + flex: '1 1 0%', + textAlign: 'left', + margin: 0, + '&:after': { + display: 'none', + }, + '& > *': { + flex: '1 1 100%', + }, + '.ss__callout-badge, .ss__result__details__rating-wrapper': { + justifyContent: 'flex-start', + }, + '.ss__result__details__title': { + flex: '1 1 0%', + a: { + fontSize: '18px', + fontWeight: custom.fonts.weight02, + }, + }, + '.ss__result__details__pricing': { + flex: '0 1 auto', + order: -1, + }, + '.ss__result__details__variant-selection:not(:empty)': { + display: 'flex', + flexFlow: 'row wrap', + alignItems: 'center', + gap: `${custom.spacing.x2}px`, + '.ss__variant-selection': { + width: `calc((100% - ${custom.spacing.x2}px) / 2)`, + margin: 0, + '.ss__slideshow .ss__slideshow__container .ss__slideshow__track': { + justifyContent: 'flex-start', + }, + }, + }, + }, + }, + '& > *': { + minWidth: '1px', + }, + '.ss__result__details': { + display: 'flex', + gap: `${custom.spacing.x2}px`, + padding: 0, + margin: 0, + '&:after': { + content: '""', + display: 'block', + margin: `auto 0 -${custom.spacing.x2}px 0`, + }, + '& > *, .ss__result__details__title, .ss__result__details__title, .ss__result__details__pricing': { + margin: 0, + }, + '& > *': { + minWidth: '1px', + '&:empty': { + display: 'none', + }, + }, + '.ss__result__details__title': { + order: -2, + a: { + color: variables?.colors?.text, + }, + }, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: '16px', + '&:not(.ss__price--strike)': { + fontWeight: custom.fonts.weight01, + }, + }, + '.ss__price--strike': { + fontSize: '14px', + '&, span': { + color: lightGray, + }, + }, + }, + '.ss__result__details__variant-selection, .ss__result__add-to-cart-wrapper': { + order: 20, + }, + }, + [`@media (max-width: ${mobileBp - 100}px)`]: { + '&.ss__result--list': { + alignItems: 'stretch', + '&, .ss__result__details': { + flexFlow: 'column nowrap', + }, + '.ss__result__image-wrapper': { + flex: '0 1 auto', + }, + '.ss__result__details': { + flex: '1 1 0%', + textAlign: 'center', + '&:after': { + display: 'block', + }, + '.ss__callout-badge, .ss__result__details__rating-wrapper': { + justifyContent: 'center', + }, + '& > *, .ss__result__details__title': { + flex: '0 1 auto', + }, + '.ss__result__details__pricing': { + order: 0, + }, + '.ss__result__details__variant-selection:not(:empty) .ss__variant-selection .ss__slideshow .ss__slideshow__container .ss__slideshow__track': + { + justifyContent: 'center', + }, + '.ss__result__details__variant-selection:not(:empty) .ss__variant-selection, .ss__result__add-to-cart-wrapper .ss__button': { + width: `100%`, + }, + }, + }, + }, + }); + + return resultStyles; +}; + +// Result component props +export const result: ThemeComponent<'result', ResultProps> = { + default: { + result: { + themeStyleScript: resultStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/searchInput.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/searchInput.ts new file mode 100644 index 0000000000..3865decc15 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/searchInput.ts @@ -0,0 +1,111 @@ +import { css } from '@emotion/react'; +import type { SearchInputProps } from '../../../../components/Molecules/SearchInput'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const searchInputHeight = custom.sizes.height; +const lightGray = custom.utils.lightenColor(); + +// CSS in JS style script for the SearchInput component +const searchInputStyleScript = (props: SearchInputProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const darkPrimary = custom.utils.darkenColor(variables?.colors?.primary, 0.15); + + // search input styles + const searchInputStyles = css({ + ...custom.styles.boxSizing('searchInput', props?.treePath, props?.name), + '&.ss__search-input': { + margin: `0 0 ${custom.spacing.x4}px`, + height: `${searchInputHeight}px`, + border: 0, + '& > *': { + minWidth: '1px', + '&:first-child, &:last-child': { + ...custom.styles.borderRadius(), + }, + '&:first-child': { + borderTopRightRadius: custom.sizes.radius ? 0 : '', + borderBottomRightRadius: custom.sizes.radius ? 0 : '', + }, + '&:last-child': { + borderTopLeftRadius: custom.sizes.radius ? 0 : '', + borderBottomLeftRadius: custom.sizes.radius ? 0 : '', + overflow: custom.sizes.radius ? `hidden` : ``, + }, + }, + '.ss__search-input__input, .ss__search-input__icons, .ss__button': { + height: '100%', + lineHeight: 1, + }, + '.ss__search-input__icons, .ss__search-input__button--close-search-button': { + flex: '0 1 auto', + }, + '.ss__button, .ss__search-input__button--close-search-button': { + width: `${searchInputHeight}px`, + justifyContent: 'center', + '&, &:hover': { + border: 0, + }, + '&, .ss__icon': { + padding: 0, + }, + }, + '.ss__search-input__input': { + flex: '1 1 0%', + minHeight: '1px', + ...custom.styles.box(variables?.colors?.text, `0 ${custom.spacing.x2}px`, false), + fontSize: '14px', + '&::-webkit-input-placeholder': { + color: lightGray, + }, + '&::-ms-input-placeholder': { + color: lightGray, + }, + '&::placeholder': { + color: lightGray, + }, + }, + '.ss__search-input__icons': { + gap: '1px', + margin: '0 0 0 -1px', + backgroundColor: darkPrimary, + }, + '.ss__button': { + borderRadius: custom.sizes.radius ? 0 : '', + }, + '.ss__search-input__button--close-search-button': { + margin: '0 -1px 0 0', + }, + }, + }); + + return searchInputStyles; +}; + +// SearchInput component props +export const searchInput: ThemeComponent<'searchInput', SearchInputProps> = { + default: { + searchInput: { + themeStyleScript: searchInputStyleScript, + }, + 'searchInput icon': { + size: `${custom.sizes.icon14}px`, + width: `${custom.sizes.icon14}px`, + height: `${custom.sizes.icon14}px`, + }, + 'searchInput button icon': { + fill: custom.colors.white, + }, + 'searchInput button.close-search icon': { + icon: custom.icons.arrowLeft, + }, + 'searchInput button.clear-search icon': { + icon: custom.icons.close, + }, + 'searchInput button.submit-search icon': { + icon: custom.icons.search, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/select.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/select.ts new file mode 100644 index 0000000000..9cff2b7e16 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/select.ts @@ -0,0 +1,144 @@ +import { css } from '@emotion/react'; +import type { SelectProps } from '../../../../components/Molecules/Select'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const dropdownIcon = `.ss__icon--${custom.icons.arrowDown}`; + +// CSS in JS style script for the Select component +const selectStyleScript = (props: SelectProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // default styles + const defaultStyles = css([ + { + display: 'block', + ...custom.styles.boxSizing('select', props?.treePath, props?.name), + '.ss__dropdown': { + '.ss__dropdown__button .ss__button, .ss__dropdown__content': { + ...custom.styles.box(variables?.colors?.text), + }, + '.ss__dropdown__button': { + '.ss__button': { + width: '100%', + paddingTop: 0, + paddingBottom: 0, + textAlign: 'left', + '.ss__button__content': { + '.ss__select__selection__icon': { + margin: 0, + }, + '.ss__select__selection': { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + fontWeight: 'normal', + }, + [dropdownIcon]: { + transition: 'transform ease 0.5s', + }, + }, + }, + }, + '.ss__dropdown__content': { + marginTop: `${custom.spacing.x2}px`, + '.ss__select__select': { + margin: 0, + padding: 0, + border: 0, + backgroundColor: 'transparent', + '.ss__select__select__option': { + color: 'inherit', + gap: `${custom.spacing.x2}px`, + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + backgroundColor: 'transparent', + fontWeight: 'normal', + }, + 'a, span': { + cursor: 'pointer', + }, + }, + '.ss__select__select__option--selected': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + }, + }, + '.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__button': { + [dropdownIcon]: { + transform: 'rotate(180deg)', + }, + }, + }, + }, + }, + ]); + + // native styles + const nativeStyles = css([ + { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + gap: `${custom.spacing.x1}px`, + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + ...custom.styles.box(variables?.colors?.text, `0 ${custom.spacing.x2}px`), + ...custom.styles.boxSizing('select', props?.treePath, props?.name), + '.ss__select__label, .ss__select__select': { + fontSize: '14px', + }, + '.ss__select__label': { + fontWeight: custom.fonts.weight01, + }, + '.ss__select__select': { + flex: '1 1 0%', + padding: `0 ${custom.spacing.x1}px 0 0`, + backgroundColor: 'transparent', + height: '100%', + lineHeight: '100%', + border: 'none', + appearance: 'none', + color: 'inherit', + cursor: 'pointer', + '&::-ms-expand': { + display: 'none', + }, + '&[disabled]': { + ...custom.styles.disabled(), + }, + }, + }, + ]); + + return props?.native ? nativeStyles : defaultStyles; +}; + +// Select component props +export const select: ThemeComponent<'select', SelectProps> = { + default: { + select: { + themeStyleScript: selectStyleScript, + iconOpen: custom.icons.arrowDown, + iconClose: custom.icons.arrowDown, + }, + 'select icon.open': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + 'select dropdown button icon': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/slideout.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/slideout.ts new file mode 100644 index 0000000000..2f7faa9b36 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/slideout.ts @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { SlideoutProps } from '../../../../components/Molecules/Slideout'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Slideout component +const slideoutStyleScript = (props: SlideoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // slideout styles + const slideoutStyles = css({ + ...custom.styles.boxSizing('slideout', props?.treePath, props?.name), + }); + + return slideoutStyles; +}; + +// Slideout component props +export const slideout: ThemeComponent<'slideout', SlideoutProps> = { + default: { + slideout: { + themeStyleScript: slideoutStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/slideshow.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/slideshow.ts new file mode 100644 index 0000000000..20fddd4fe3 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/slideshow.ts @@ -0,0 +1,114 @@ +import { css } from '@emotion/react'; +import type { SlideshowProps } from '../../../../components/Molecules/Slideshow'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const slideshowSpacing = custom.spacing.x2; +const slideshowButtonSize = 32; +const slideshowPaginationSize = 12; +const slideshowPaginationSpacing = slideshowSpacing + slideshowPaginationSize; +const activeColors = custom.utils.activeColors(); +const buttonColor = activeColors[0]; +const fontColor = activeColors[1]; + +// CSS in JS style script for the Slideshow component +const slideshowStyleScript = (props: SlideshowProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // slideshow styles + const slideshowStyles = css({ + position: 'relative', + width: '100%', + minWidth: '1px', + ...custom.styles.boxSizing('slideshow', props?.treePath, props?.name), + '&:has(.ss__slideshow__pagination)': { + paddingBottom: `${slideshowPaginationSpacing}px`, + '.ss__slideshow__navigation--prev, .ss__slideshow__navigation--next': { + top: `-${slideshowPaginationSpacing}px`, + }, + }, + '.ss__slideshow__container': { + width: 'auto', + margin: `0 -${slideshowSpacing / 2}px`, + }, + '.ss__slideshow__navigation--prev, .ss__slideshow__navigation--next': { + width: `${slideshowButtonSize}px`, + height: `${slideshowButtonSize}px`, + top: 0, + bottom: 0, + margin: 'auto', + transform: 'none', + '.ss__button': { + flexFlow: 'column nowrap', + padding: 0, + width: '100%', + height: '100%', + lineHeight: 1, + color: fontColor, + [`&, &:hover, &:not(.ss__button--disabled):hover, &.ss__button--disabled`]: { + border: `1px solid ${buttonColor}`, + backgroundColor: buttonColor, + }, + }, + }, + '.ss__slideshow__navigation--prev': { + '.ss__button .ss__icon': { + left: '-1.5px', + }, + }, + '.ss__slideshow__navigation--next': { + '.ss__button .ss__icon': { + right: '-1.5px', + }, + }, + '.ss__slideshow__pagination': { + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + margin: 'auto', + width: 'auto', + gap: `${custom.spacing.x1}px`, + '.ss__slideshow__dot': { + opacity: 1, + flex: '0 1 auto', + width: `${slideshowPaginationSize}px`, + height: `${slideshowPaginationSize}px`, + lineHeight: `${slideshowPaginationSize}px`, + minWidth: '1px', + margin: 0, + ...custom.styles.box('', 0, false), + }, + '.ss__slideshow__dot--active': { + backgroundColor: variables?.colors?.primary, + borderColor: variables?.colors?.primary, + }, + }, + }); + + return slideshowStyles; +}; + +// Slideshow component props +export const slideshow: ThemeComponent<'slideshow', SlideshowProps> = { + default: { + slideshow: { + themeStyleScript: slideshowStyleScript, + gap: slideshowSpacing, + centerInsufficientSlides: false, + }, + 'slideshow button icon': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + 'slideshow button.prev icon': { + icon: custom.icons.arrowLeft, + }, + 'slideshow button.next icon': { + icon: custom.icons.arrowRight, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/sortBy.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/sortBy.ts new file mode 100644 index 0000000000..19de98c1ca --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/sortBy.ts @@ -0,0 +1,26 @@ +import { css } from '@emotion/react'; +import type { SortByProps } from '../../../../components/Molecules/SortBy'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the SortBy component +const sortByStyleScript = (props: SortByProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // sortBy styles + const sortByStyles = css({ + ...custom.styles.boxSizing('sortBy', props?.treePath, props?.name), + }); + + return sortByStyles; +}; + +// SortBy component props +export const sortBy: ThemeComponent<'sortBy', SortByProps> = { + default: { + sortBy: { + themeStyleScript: sortByStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/swatches.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/swatches.ts new file mode 100644 index 0000000000..789223a563 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/swatches.ts @@ -0,0 +1,229 @@ +import { css } from '@emotion/react'; +import type { SwatchesProps } from '../../../../components/Molecules/Swatches'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +//import Color from 'color'; + +// static variables +const swatchesSpacing = custom.spacing.x1; +const swatchesSize = 28; +const swatchesSelector = 'ss__swatches__slideshow__swatch'; +const darkSelector = `&.${swatchesSelector}--dark, &:has(.${swatchesSelector}__inner--grey), &:has(.${swatchesSelector}__inner--gray)`; +const imageSelector = '&:has(.ss__image)'; +const urlSelector = '&[style*="url"]'; +const styleSelector = '&[style], &:has(.ss__image)'; +const activeColors = custom.utils.activeColors(); +const activeColor = activeColors[0]; +const fontColor = activeColors[1]; + +// CSS in JS style script for the Swatches component +const swatchesStyleScript = (props: SwatchesProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // shared styles + const sharedStyles = css({ + ...custom.styles.boxSizing('swatches', props?.treePath, props?.name), + }); + + // swatches carousel styles + const swatchesCarouselStyles = css([ + sharedStyles, + { + '.ss__slideshow': { + display: 'flex', + flexFlow: 'row wrap', + gap: `${swatchesSpacing}px`, + '& > *': { + minWidth: '1px', + flex: '1 1 100%', + }, + '.ss__slideshow__sr-only': { + order: -2, + }, + '.ss__slideshow__container': { + flex: '1 1 0%', + margin: `0 -${swatchesSpacing / 2}px`, + '.ss__slideshow__track': { + '.ss__slideshow__slide': { + '.ss__swatches__slideshow__swatch': { + position: 'relative', + height: `${swatchesSize}px`, + aspectRatio: 1, + border: 0, + '.ss__swatches__slideshow__swatch__inner': { + position: 'relative', + width: '100%', + height: '100%', + ...custom.styles.box(variables?.colors?.text, `${custom.spacing.x1}px`), + '&, .ss__swatches__slideshow__swatch__value': { + overflow: 'hidden', + }, + '.ss__swatches__slideshow__swatch__value': { + maxWidth: '100%', + maxHeight: '100%', + textAlign: 'center', + fontSize: '10px', + lineHeight: 1, + }, + [styleSelector]: { + border: 0, + backgroundColor: 'transparent', + '&:before, &:after': { + content: '""', + display: 'block', + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + ...custom.styles.borderRadius(), + }, + '&:before': { + border: `3px solid ${custom.colors.white}`, + margin: '1px', + opacity: 0, + }, + '&:after': { + border: `1px solid ${custom.colors.black}`, + opacity: 0.15, + }, + '.ss__swatches__slideshow__swatch__value': { + ...custom.styles.srOnly(), + }, + }, + [`${urlSelector}, ${imageSelector}`]: { + '&:before': { + margin: 0, + borderWidth: '4px', + }, + }, + [urlSelector]: { + backgroundRepeat: 'no-repeat !important', + backgroundSize: 'cover !important', + backgroundPosition: 'center !important', + }, + [imageSelector]: { + '&:before, &:after': { + zIndex: 3, + }, + '.ss__image, .ss__swatches__slideshow__swatch__value': { + position: 'absolute', + }, + '.ss__image': { + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1, + img: { + width: '100%', + height: '100%', + objectFit: 'cover', + objectPosition: 'center center', + }, + }, + '.ss__swatches__slideshow__swatch__value': { + zIndex: 2, + }, + }, + }, + [darkSelector]: { + '.ss__swatches__slideshow__swatch__inner': { + color: fontColor, + }, + }, + '&.ss__swatches__slideshow__swatch--disabled, &.ss__swatches__slideshow__swatch--unavailable': { + opacity: 1, + cursor: 'not-allowed !important', + pointerEvents: 'unset', + '&:before': { + maxWidth: `${swatchesSize - 4}px`, + top: 0, + bottom: 0, + zIndex: 3, + margin: 'auto 0', + borderTop: `2px solid ${custom.colors.white}`, + outlineColor: custom.colors.gray02, + ...custom.styles.borderRadius(3), + }, + '.ss__swatches__slideshow__swatch__inner': { + opacity: 0.65, + }, + }, + '&.ss__swatches__slideshow__swatch--selected': { + '.ss__swatches__slideshow__swatch__inner': { + borderColor: activeColor, + backgroundColor: activeColor, + color: fontColor, + [styleSelector]: { + border: 0, + backgroundColor: 'transparent', + color: variables?.colors?.text, + '&:before': { + opacity: 1, + }, + '&:after': { + opacity: 0.3, + }, + }, + '.ss__swatches__slideshow__swatch__value': { + fontWeight: custom.fonts.weight01, + }, + }, + [darkSelector]: { + '.ss__swatches__slideshow__swatch__inner': { + color: fontColor, + }, + }, + }, + }, + }, + }, + }, + '.ss__slideshow__navigation--prev, .ss__slideshow__navigation--next': { + flex: '0 1 auto', + width: `${swatchesSize}px`, + height: `${swatchesSize}px`, + margin: 0, + position: 'static', + }, + '.ss__slideshow__navigation--prev': { + order: -1, + }, + }, + }, + ]); + + // swatches grid styles + const swatchesGridStyles = css([ + sharedStyles, + { + '.ss__grid': { + '.ss__grid__options': { + '.ss__grid__option:not(.ss__grid__show-more-wrapper)': { + width: `${swatchesSize}px`, + maxHeight: `${swatchesSize}px`, + }, + }, + }, + }, + ]); + + return props?.type == 'grid' ? swatchesGridStyles : swatchesCarouselStyles; +}; + +// Swatches component props +export const swatches: ThemeComponent<'swatches', SwatchesProps> = { + default: { + swatches: { + themeStyleScript: swatchesStyleScript, + hideLabels: false, + }, + 'swatches slideshow': { + slidesToShow: 4, + gap: swatchesSpacing, + centerInsufficientSlides: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/terms.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/terms.ts new file mode 100644 index 0000000000..eb61b2bf1c --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/terms.ts @@ -0,0 +1,74 @@ +import { css } from '@emotion/react'; +import type { TermsProps } from '../../../../components/Molecules/Terms'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Terms component +const termsStyleScript = (props: TermsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + // terms styles + const termsStyles = css({ + ...custom.styles.boxSizing('terms', props?.treePath, props?.name), + '.ss__terms__title': { + '&, h5': { + padding: 0, + }, + h5: { + margin: `0 0 ${custom.spacing.x4}px 0`, + ...custom.styles.headerText(variables?.colors?.secondary, '16px'), + }, + }, + '.ss__terms__options': { + flexFlow: 'row wrap', + justifyContent: 'flex-start', + gap: `${custom.spacing.x1}px ${custom.spacing.x4}px`, + '&, .ss__terms__option': { + listStyle: 'none', + padding: 0, + margin: 0, + }, + '.ss__terms__option': { + flex: '0 1 auto', + minWidth: '1px', + '&, a': { + color: variables?.colors?.primary, + }, + a: { + padding: 0, + fontSize: '16px', + em: { + color: variables?.colors?.text, + fontStyle: 'normal', + fontSize: 'inherit', + fontWeight: 'inherit', + }, + }, + }, + '.ss__terms__option--active': { + 'a, a em': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__terms__title h5, .ss__terms__options .ss__terms__option a': { + fontSize: '14px', + }, + }, + }); + + return termsStyles; +}; + +// Terms component props +export const terms: ThemeComponent<'terms', TermsProps> = { + default: { + terms: { + themeStyleScript: termsStyleScript, + emIfy: true, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/molecules/variantSelection.ts b/packages/snap-preact/components/src/themes/pike/components/molecules/variantSelection.ts new file mode 100644 index 0000000000..6c34c31ce4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/molecules/variantSelection.ts @@ -0,0 +1,140 @@ +import { css } from '@emotion/react'; +import type { VariantSelectionProps } from '../../../../components/Molecules/VariantSelection'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Swatches component +const variantSelectionStyleScript = (props: VariantSelectionProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // shared styles + const sharedStyles = css({ + ...custom.styles.boxSizing('variantSelection', props?.treePath, props?.name), + }); + + // variant selection dropdown styles + const variantSelectionDropdownStyles = css([ + sharedStyles, + { + '.ss__dropdown': { + '.ss__dropdown__button, .ss__dropdown__content': { + ...custom.styles.box(variables?.colors?.text), + }, + '.ss__dropdown__button': { + gap: `${custom.spacing.x1}px`, + paddingTop: 0, + paddingBottom: 0, + textAlign: 'left', + height: `${custom.sizes.height}px`, + lineHeight: `${custom.sizes.height}px`, + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + }, + '.ss__dropdown__button-wrapper': { + flex: '1 1 0%', + '.ss__dropdown__button-wrapper__label': { + fontWeight: custom?.fonts?.weight01, + textTransform: 'capitalize', + }, + }, + '.ss__variant-selection__icon': { + transition: 'transform ease 0.5s', + }, + }, + '.ss__dropdown__content': { + marginTop: `${custom.spacing.x2}px`, + '.ss__variant-selection__options': { + border: 0, + background: 'none', + textAlign: 'left', + '&, .ss__variant-selection__option': { + listStyle: 'none', + padding: 0, + margin: 0, + }, + '.ss__variant-selection__option': { + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: '0', + }, + '&:hover': { + fontWeight: 'normal', + }, + }, + '.ss__variant-selection__option--selected': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + '.ss__variant-selection__option--unavailable, .ss__variant-selection__option--disabled': { + color: 'inherit', + ...custom.styles.disabled(), + }, + }, + }, + }, + '.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__variant-selection__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + }, + ]); + + // variant selection list styles + const variantSelectionListStyles = css([ + sharedStyles, + { + '.ss__list': { + '.ss__list__title': { + fontSize: '14px', + textAlign: 'left', + }, + '.ss__list__options': { + '.ss__list__option': { + color: variables?.colors?.text, + label: { + color: 'inherit', + cursor: 'inherit', + }, + }, + '.ss__list__option--selected': { + ...custom.styles.activeText(variables?.colors?.primary), + }, + '.ss__list__option--unavailable, .ss__list__option--disabled': { + ...custom.styles.disabled(), + textDecoration: 'line-through', + }, + }, + }, + }, + ]); + + // variant selection swatches syles + const variantSelectionSwatchesStyles = css([sharedStyles]); + + if (props?.type == 'list') { + return variantSelectionListStyles; + } else if (props?.type == 'swatches') { + return variantSelectionSwatchesStyles; + } else { + return variantSelectionDropdownStyles; + } +}; + +// VariantSelection component props +export const variantSelection: ThemeComponent<'variantSelection', VariantSelectionProps> = { + default: { + variantSelection: { + themeStyleScript: variantSelectionStyleScript, + }, + 'variantSelection dropdown icon': { + icon: custom.icons.arrowDown, + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..41206a709e --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/autocomplete.ts @@ -0,0 +1,392 @@ +import { css } from '@emotion/react'; +import type { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; + +// CSS in JS style script for the Autocomplete component +const autocompleteStyleScript = (props: AutocompleteProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const headerSelectors = + '.ss__autocomplete__terms .ss__autocomplete__title h5, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__header, .ss__autocomplete__content__results .ss__autocomplete__title h5, .ss__autocomplete__content__info a, .ss__no-results__recommendations h3'; + const activeSelectors = + '.ss__autocomplete__terms .ss__autocomplete__terms__options .ss__autocomplete__terms__option--active a, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__options .ss__facet-list-options .ss__facet-list-options__option--filtered, .ss__autocomplete__content__results .ss__results .ss__result:hover .ss__result__details .ss__result__details__title a, .ss__autocomplete__content__info a:hover'; + + return css({ + ...custom.styles.boxSizing('autocomplete', props?.treePath, props?.name), + '&.ss__autocomplete': { + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.white, + width: props?.width, + right: 0, + left: 'auto', + top: 'auto', + margin: `${custom.spacing.x1}px 0 0 0`, + gap: `${custom.spacing.x4}px`, + 'a, div, p': { + fontSize: '12px', + lineHeight: 1.5, + color: variables?.colors?.text, + }, + a: { + display: 'block', + }, + '.ss__banner': { + img: { + maxWidth: '100%', + maxHeight: '150px', + height: 'auto', + }, + }, + [headerSelectors]: { + margin: `0 0 ${custom.spacing.x4}px 0`, + fontSize: '16px', + fontWeight: custom.fonts.weight02, + lineHeight: 1.2, + color: variables?.colors?.secondary, + }, + [activeSelectors]: { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '& > div': { + minWidth: '1px', + maxWidth: 'none', + flex: '0 1 auto', + padding: `${custom.spacing.x4}px 0`, + order: 0, + '&:first-of-type': { + paddingLeft: `${custom.spacing.x4}px`, + }, + '&:last-of-type': { + paddingRight: `${custom.spacing.x4}px`, + }, + '&.ss__autocomplete__terms': { + padding: 0, + }, + }, + '.ss__autocomplete__terms': { + width: '200px', + backgroundColor: custom.colors.gray01, + textAlign: 'left', + '& > div:first-of-type .ss__autocomplete__title': { + marginTop: `${custom.spacing.x2}px`, + }, + '& > div:last-of-type .ss__autocomplete__terms__options': { + marginBottom: `${custom.spacing.x2}px`, + }, + '& > div': { + '.ss__autocomplete__title': { + padding: 0, + h5: { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms__options': { + '.ss__autocomplete__terms__option': { + a: { + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + fontSize: '14px', + color: variables?.colors?.primary, + em: { + color: variables?.colors?.text, + fontStyle: 'normal', + fontSize: 'inherit', + fontWeight: 'inherit', + }, + }, + }, + '.ss__autocomplete__terms__option--active': { + 'a, a em': { + fontWeight: custom?.fonts?.weight01, + color: variables?.colors?.primary, + }, + }, + }, + }, + }, + '.ss__autocomplete__facets': { + width: '200px', + textAlign: 'left', + '.ss__facets': { + '.ss__facet': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&.ss__facet--showing-all:has(.ss__facet__show-more-less)': { + '.ss__facet__options': { + maxHeight: 'none', + overflow: 'visible', + padding: 0, + }, + }, + '&:last-of-type': { + marginBottom: 0, + }, + '.ss__facet__header': { + borderBottom: 0, + padding: 0, + '.ss__facet__header__inner': { + fontSize: 'inherit', + fontWeight: 'inherit', + color: 'inherit', + }, + }, + '.ss__facet__options': { + margin: 0, + maxHeight: 'none', + overflow: 'visible', + '.ss__facet-hierarchy-options .ss__facet-hierarchy-options__option, .ss__facet-list-options .ss__facet-list-options__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + '.ss__facet-list-options': { + '.ss__facet-list-options__option': {}, + }, + }, + }, + }, + }, + '.ss__autocomplete__content': { + flex: '1 1 0%', + overflow: 'visible', + justifyContent: 'flex-start', + }, + '.ss__autocomplete__content__results': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '.ss__results': { + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '75vh', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__result': { + '.ss__result__details': { + gap: `${custom.spacing.x1}px`, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: '14px', + }, + '.ss__price--strike': { + fontSize: '12px', + }, + }, + }, + }, + '.ss__inline-banner': { + maxHeight: '250px', + overflow: 'hidden', + }, + }, + }, + '.ss__autocomplete__content__info': { + padding: 0, + a: { + margin: 0, + }, + }, + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + '.ss__no-results__recommendations': { + margin: `${custom.spacing.x4}px 0 0 0`, + }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '&.ss__autocomplete': { + flexFlow: 'row wrap', + gap: 0, + width: props?.width, + left: 0, + right: 0, + [headerSelectors]: { + fontSize: '14px', + }, + '& > div': { + flex: '1 1 100%', + borderBottom: `1px solid ${custom.colors.gray02}`, + '&:last-of-type': { + borderBottomWidth: 0, + }, + '&, &.ss__autocomplete__terms': { + padding: `${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms': { + backgroundColor: 'transparent', + display: 'flex', + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + width: 'auto', + '& > div': { + minWidth: '1px', + flex: '1 1 0%', + '&:first-of-type .ss__autocomplete__title': { + marginTop: 0, + }, + '&:last-of-type .ss__autocomplete__terms__options': { + marginBottom: 0, + }, + '.ss__autocomplete__title h5': { + padding: 0, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + '.ss__autocomplete__terms__options': { + gap: `${custom.spacing.x1}px ${custom.spacing.x4}px`, + flexFlow: 'row wrap', + justifyContent: 'flex-start', + '.ss__autocomplete__terms__option': { + flex: '0 1 auto', + a: { + padding: 0, + fontSize: '12px', + }, + }, + }, + }, + }, + '.ss__autocomplete__terms > div .ss__autocomplete__terms__options, .ss__autocomplete__facets .ss__facets': { + display: 'flex', + }, + '.ss__autocomplete__terms > div .ss__autocomplete__terms__options, .ss__autocomplete__facets .ss__facets .ss__facet': { + minWidth: '1px', + }, + '.ss__autocomplete__facets': { + width: 'auto', + '.ss__facets': { + gap: `0 ${custom.spacing.x4}px`, + flexFlow: 'row nowrap', + '.ss__facet': { + flex: '1 1 0%', + '&, &:last-of-type': { + margin: 0, + }, + }, + }, + }, + '.ss__autocomplete__content__info': { + a: { + '.ss__icon': { + position: 'relative', + top: '1px', + }, + }, + }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '&.ss__autocomplete': { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__recommendation-grid__results': { + gridTemplateColumns: `repeat(2, 1fr)`, + '& > div:nth-of-type(n+3)': { + display: 'none', + }, + }, + }, + }, + }); +}; + +// Autocomplete component props +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + themeStyleScript: autocompleteStyleScript, + width: '900px', + }, + 'autocomplete facet': { + limit: 5, + disableOverflow: true, + disableCollapse: true, + }, + 'autocomplete facets': { + limit: 3, + }, + 'autocomplete facetListOptions': { + hideCheckbox: true, + }, + 'autocomplete facetPaletteOptions': { + gridSize: '38px', + hideLabel: false, + }, + 'autocomplete facetGridOptions': { + gridSize: '38px', + }, + 'autocomplete results': { + rows: 2, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 2, + columns: 4, + }, + 'autocomplete icon': { + icon: custom.icons.arrowRight, + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + }, + mobile: { + ...autocompleteThemeComponentProps.mobile, + autocomplete: { + width: '100%', + }, + 'autocomplete results': { + rows: 1, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 1, + columns: 3, + }, + }, + tablet: { + ...autocompleteThemeComponentProps.tablet, + autocomplete: { + width: '100%', + }, + 'autocomplete results': { + rows: 1, + columns: 4, + }, + 'autocomplete recommendationGrid': { + rows: 1, + columns: 4, + }, + }, + desktop: { + ...autocompleteThemeComponentProps.desktop, + autocomplete: {}, + 'autocomplete results': { + rows: 2, + columns: 3, + }, + 'autocomplete recommendationGrid': { + rows: 2, + columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/autocompleteLayout.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/autocompleteLayout.ts new file mode 100644 index 0000000000..b2ba185490 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/autocompleteLayout.ts @@ -0,0 +1,441 @@ +import { css } from '@emotion/react'; +import type { AutocompleteLayoutProps } from '../../../../components/Organisms/AutocompleteLayout'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Autocomplete Layout component +const autocompleteLayoutStyleScript = (props: AutocompleteLayoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + const textSelectors = 'a, div, p'; + const headerSelectors = + '.ss__terms-list .ss__terms .ss__terms__title h5, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__header, .ss__autocomplete__content .ss__autocomplete__content__results .ss__autocomplete__title h5, .ss__autocomplete__button--see-more .ss__button__content, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__title'; + const activeSelectors = + '.ss__terms-list .ss__terms .ss__terms__options .ss__terms__option.ss__terms__option--active a, .ss__autocomplete__facets .ss__facets .ss__facet .ss__facet__options .ss__facet-list-options .ss__facet-list-options__option--filtered, .ss__autocomplete__content .ss__autocomplete__content__results .ss__results .ss__result:hover .ss__result__details .ss__result__details__title a, .ss__autocomplete__button--see-more:hover .ss__button__content'; + + // get autocomplete layout + const acLayout = props?.layout ? props.layout : 'standard'; + + // shared styles + const sharedStyles = css({ + alignContent: acLayout == 'standard' ? 'normal' : 'flex-start', + border: `1px solid ${custom.colors.gray02}`, + backgroundColor: custom.colors.white, + ...custom.styles.boxSizing('autocompleteLayout', props?.treePath, props?.name), + [textSelectors]: { + fontSize: `${acLayout == 'terms' ? 15 : 12}px`, + lineHeight: 1.5, + color: variables?.colors?.text, + }, + a: { + display: 'block', + }, + 'ul, ul li': { + padding: 0, + margin: 0, + listStyle: 'none', + }, + '.ss__banner': { + img: { + maxWidth: '100%', + maxHeight: '150px', + height: 'auto', + }, + }, + [headerSelectors]: { + margin: `0 0 ${custom.spacing.x4}px 0`, + padding: 0, + fontSize: `${acLayout == 'terms' ? 17 : 16}px`, + fontWeight: custom.fonts.weight02, + lineHeight: 1.2, + color: variables?.colors?.secondary, + }, + [activeSelectors]: { + fontWeight: custom.fonts.weight01, + color: variables?.colors?.primary, + }, + '.ss__autocomplete__row, .ss__autocomplete__column': { + '.ss__search-input': { + background: 'transparent', + width: 'auto', + height: '30px', + margin: `0 0 ${custom.spacing.x2}px 0`, + }, + }, + '.ss__autocomplete__column': { + alignContent: 'flex-start', + minWidth: '1px', + }, + }); + const sharedTabletStyles = css({ + alignContent: 'flex-start', + [textSelectors]: { + fontSize: acLayout == 'terms' ? '12px' : '', + }, + [headerSelectors]: { + fontSize: '14px', + }, + }); + + // terms wrapper styles + const termsWrapperStyles = css({ + '.ss__autocomplete__terms-wrapper': { + backgroundColor: 'transparent', + padding: `${custom.spacing.x4}px`, + }, + }); + + // facets styles + const facetsStyles = css({ + '.ss__autocomplete__facets-wrapper': { + padding: `${custom.spacing.x4}px`, + }, + '.ss__autocomplete__facets': { + padding: 0, + '.ss__facets': { + '.ss__facet': { + margin: `0 0 ${custom.spacing.x4}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + '&.ss__facet--showing-all:has(.ss__facet__show-more-less)': { + '.ss__facet__options': { + maxHeight: 'none', + overflow: 'visible', + padding: 0, + }, + }, + '.ss__facet__header': { + borderBottom: 0, + '.ss__facet__header__inner': { + fontSize: 'inherit', + fontWeight: 'inherit', + color: 'inherit', + }, + }, + '.ss__facet__options': { + '.ss__facet-hierarchy-options .ss__facet-hierarchy-options__option, .ss__facet-list-options .ss__facet-list-options__option': { + padding: 0, + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + }, + }, + }, + }); + + // content styles + const contentStyles = css({ + '.ss__autocomplete__column:has(.ss__autocomplete__content)': { + alignContent: 'flex-start', + }, + '.ss__autocomplete__content': { + overflow: 'visible', + justifyContent: 'flex-start', + padding: `${custom.spacing.x4}px`, + borderTop: `1px solid ${custom.colors.gray02}`, + '.ss__autocomplete__content-inner': { + padding: 0, + }, + }, + }); + + // results layout styles + const resultsLayoutStyles = css({ + gap: `${custom.spacing.x4}px`, + overflowY: 'auto', + overflowX: 'hidden', + maxHeight: '75vh', + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + '.ss__result': { + '.ss__result__details': { + gap: `${custom.spacing.x1}px`, + '.ss__result__details__pricing': { + '.ss__result__price': { + fontSize: '14px', + }, + '.ss__price--strike': { + fontSize: '12px', + }, + }, + }, + }, + }); + + // results styles + const resultsStyles = css({ + '.ss__autocomplete__content__results': { + '.ss__results': { + ...resultsLayoutStyles, + }, + }, + }); + + // no results styles + const noResultsStyles = css({ + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + '.ss__autocomplete__content__no-results__recommendations': { + '.ss__recommendation-grid': { + margin: `${custom.spacing.x4}px 0 0 0`, + }, + '.ss__recommendation-grid__title': { + textAlign: 'left', + }, + '.ss__recommendation-grid__results': { + ...resultsLayoutStyles, + }, + }, + }, + }); + + // see more styles + const seeMoreStyles = css({ + '.ss__autocomplete__button--see-more': { + padding: `${custom.spacing.x4}px`, + paddingTop: 0, + height: 'auto', + '&, &:hover': { + backgroundColor: 'transparent', + border: 0, + }, + '.ss__button__content': { + margin: 0, + }, + }, + }); + const seeMoreTabletStyles = css({ + order: -1, + textAlign: 'left', + }); + + // standard styles + const standardStyles = css([ + sharedStyles, + { + '.ss__autocomplete__column': { + '&:has(.ss__autocomplete__terms-wrapper)': { + flex: '1 0 200px', + maxWidth: '200px', + }, + '&:has(.ss__autocomplete__facets-wrapper)': { + flex: '1 0 200px', + maxWidth: '200px', + marginRight: `-${custom.spacing.x4}px`, + }, + }, + '.ss__autocomplete__terms-wrapper': { + backgroundColor: custom.colors.gray01, + height: '100%', + }, + '.ss__terms-list': { + display: 'block', + '.ss__terms-list__row': { + '&:first-of-type .ss__terms .ss__terms__title': { + marginTop: `${custom.spacing.x2}px`, + }, + '&:last-of-type .ss__terms .ss__terms__options': { + marginBottom: `${custom.spacing.x2}px`, + }, + }, + '.ss__terms': { + '.ss__terms__title': { + h5: { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__terms__options': { + display: 'block', + margin: 0, + '.ss__terms__option': { + a: { + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + }, + }, + '.ss__terms__option--active': { + backgroundColor: custom.colors.white, + }, + }, + }, + }, + }, + facetsStyles, + contentStyles, + resultsStyles, + noResultsStyles, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__row:has(.ss__autocomplete__column)': { + display: 'block', + '.ss__autocomplete__column': { + width: '100%', + maxWidth: 'none', + }, + }, + '.ss__autocomplete__column': { + '&:has(.ss__autocomplete__facets-wrapper)': { + marginRight: 0, + }, + }, + '.ss__autocomplete__terms-wrapper': { + backgroundColor: 'transparent', + padding: `${custom.spacing.x4}px`, + }, + '.ss__terms-list': { + display: 'flex', + '.ss__terms-list__row': { + '&:first-of-type .ss__terms .ss__terms__title': { + marginTop: 0, + }, + '&:last-of-type .ss__terms .ss__terms__options': { + marginBottom: 0, + }, + }, + '.ss__terms': { + '.ss__terms__title': { + h5: { + padding: 0, + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + }, + '.ss__terms__options': { + display: 'flex', + '.ss__terms__option': { + a: { + padding: 0, + }, + }, + }, + }, + }, + '.ss__autocomplete__facets-wrapper': { + borderTop: `1px solid ${custom.colors.gray02}`, + }, + '.ss__autocomplete__facets': { + '.ss__facets': { + gap: `0 ${custom.spacing.x4}px`, + flexFlow: 'row nowrap', + minWidth: '1px', + '.ss__facet': { + flex: '1 1 0%', + minWidth: '1px', + '&, &:last-of-type': { + margin: 0, + }, + }, + }, + }, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + ]); + + // mini styles + const miniStyles = css([ + sharedStyles, + termsWrapperStyles, + contentStyles, + resultsStyles, + noResultsStyles, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + { + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + { + gridTemplateColumns: `repeat(2, 1fr)`, + }, + }, + }, + ]); + + // terms styles + const termsStyles = css([ + sharedStyles, + termsWrapperStyles, + contentStyles, + { + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + display: 'inline', + margin: 0, + padding: 0, + fontSize: '14px', + '& ~ p': { + paddingLeft: '4px', + }, + }, + }, + }, + }, + seeMoreStyles, + { + [`@media (max-width: ${tabletBp}px)`]: { + '&': sharedTabletStyles, + '.ss__autocomplete__content__no-results': { + '.ss__autocomplete__content__no-results__text': { + p: { + fontSize: '12px', + }, + }, + }, + '.ss__autocomplete__button--see-more': { + ...seeMoreTabletStyles, + }, + }, + }, + ]); + + if (acLayout == 'terms') { + return termsStyles; + } else if (acLayout == 'mini') { + return miniStyles; + } else { + return standardStyles; + } +}; + +// Autocomplete Layout component props +export const autocompleteLayout: ThemeComponent<'autocompleteLayout', AutocompleteLayoutProps> = { + default: { + autocompleteLayout: { + themeStyleScript: autocompleteLayoutStyleScript, + contentTitle: 'Product Suggestions', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/facet.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/facet.ts new file mode 100644 index 0000000000..f6f8d1cc5c --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/facet.ts @@ -0,0 +1,171 @@ +import { css } from '@emotion/react'; +import type { FacetProps } from '../../../../components/Organisms/Facet'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const lightGray = custom.utils.lightenColor(); + +// CSS in JS style script for the Facet component +const facetStyleScript = (props: FacetProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // facet styles + const facetStyles = css({ + ...custom.styles.boxSizing('facet', props?.treePath, props?.name), + '&.ss__facet--collapsed': { + '.ss__facet__header': { + '.ss__icon': { + transform: 'rotate(0deg)', + }, + }, + }, + '&.ss__facet--showing-all:has(.ss__facet__show-more-less)': { + '.ss__facet__options': { + maxHeight: `490px`, + overflowY: 'auto', + overflowX: 'hidden', + paddingRight: `${custom.spacing.x2}px`, + }, + }, + '.ss__facet__header': { + margin: ` 0 0 ${custom.spacing.x4}px 0`, + padding: ` 0 0 ${custom.spacing.x2}px 0`, + borderBottom: `2px solid ${variables?.colors?.primary}`, + gap: `${custom.spacing.x2}px`, + ...custom.styles.headerText(props?.color || variables?.colors?.secondary, '16px'), + '.ss__facet__header__inner': { + flex: '1 1 0%', + gap: `${custom.spacing.x1}px`, + alignItems: 'center', + '.ss__facet__header__selected-count, .ss__facet__header__clear-all': { + fontSize: '12px', + margin: 0, + }, + '.ss__facet__header__clear-all': { + padding: 0, + height: 'auto', + lineHeight: 'inherit', + marginLeft: 'auto', + '&, &:hover': { + border: 0, + backgroundColor: 'transparent', + color: 'inherit', + }, + '&:hover': { + textDecoration: 'none', + }, + }, + }, + '.ss__icon': { + transition: 'transform ease 0.5s', + transform: 'rotate(180deg)', + }, + }, + '.ss__facet__options': { + marginTop: 0, + maxHeight: 'none', + overflow: 'visible', + ...custom.styles.scrollbar(), + }, + '.ss__search-input': { + margin: `0 0 ${custom.spacing.x4}px`, + }, + '.ss__facet__range-inputs': { + margin: `${custom.spacing.x4}px 0 0 0`, + fontSize: '14px', + color: variables?.colors?.text, + '&, .ss__facet__range-inputs__row': { + gap: `${custom.spacing.x2}px`, + }, + '.ss__facet__range-inputs__row': { + ' > *': { + minWidth: '1px', + flex: '1 1 0%', + }, + '.ss__facet__range-inputs__separator': { + flex: '0 1 auto', + }, + }, + '.ss__facet__range-inputs__separator, .ss__facet__range-inputs__row--button-wrapper .ss__button': { + margin: 0, + }, + '.ss__facet__range-input': { + gap: `${custom.spacing.x1 / 2}px`, + border: 0, + backgroundColor: 'transparent', + }, + '.ss__facet__range-input__prefix': { + padding: 0, + }, + '.ss__facet__range-input__input': { + height: custom.sizes.height, + lineHeight: custom.sizes.height, + ...custom.styles.box(variables?.colors?.text, `0 ${custom.spacing.x2}px`, false), + '&::-webkit-input-placeholder': { + color: lightGray, + }, + '&::-ms-input-placeholder': { + color: lightGray, + }, + '&::placeholder': { + color: lightGray, + }, + }, + '.ss__facet__range-inputs__row--button-wrapper .ss__button': { + width: '100%', + }, + }, + '.ss__facet__show-more-less': { + margin: `${custom.spacing.x2}px 0 0 0`, + flexFlow: 'row nowrap', + display: 'inline-flex', + alignItems: 'center', + gap: `${custom.spacing.x2}px`, + ...custom.styles.activeText(variables?.colors?.primary), + lineHeight: 1, + '.ss__icon': { + margin: 0, + width: `${custom.sizes.icon10}px`, + height: `${custom.sizes.icon10}px`, + flex: `0 0 ${custom.sizes.icon10}px`, + }, + }, + }); + + return facetStyles; +}; + +// Facet component props +export const facet: ThemeComponent<'facet', FacetProps> = { + default: { + facet: { + themeStyleScript: facetStyleScript, + iconCollapse: custom.icons.arrowDown, + iconExpand: custom.icons.arrowDown, + iconOverflowMore: custom.icons.plus, + iconOverflowLess: custom.icons.minus, + // showSelectedCount: true, + // hideSelectedCountParenthesis: false, + // rangeInputs: true, + // rangeInputsPrefix: '$', + // rangeInputsSeparatorText: 'to', + // rangeInputsInheritDefaultValues: true, + // showClearAllText: true, + searchable: true, + }, + 'facet icon.collapse': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + fill: custom.colors.primary, + }, + 'facet icon.expand': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + fill: custom.colors.primary, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/facets.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/facets.ts new file mode 100644 index 0000000000..62715d0102 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/facets.ts @@ -0,0 +1,36 @@ +import { css } from '@emotion/react'; +import type { FacetsProps } from '../../../../components/Organisms/Facets'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Facets component +const facetsStyleScript = (props: FacetsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // facets styles + const facetsStyles = css({ + ...custom.styles.boxSizing('facets', props?.treePath, props?.name), + '&.ss__facets': { + display: 'block', + width: 'auto', + '.ss__facet': { + margin: `0 0 ${custom.spacing.x6}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + }); + + return facetsStyles; +}; + +// Facets component props +export const facets: ThemeComponent<'facets', FacetsProps> = { + default: { + facets: { + themeStyleScript: facetsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/facetsHorizontal.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/facetsHorizontal.ts new file mode 100644 index 0000000000..74e2b9795e --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/facetsHorizontal.ts @@ -0,0 +1,233 @@ +import { css } from '@emotion/react'; +import type { FacetsHorizontalProps } from '../../../../components/Organisms/FacetsHorizontal'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const dropdownButtonHeight = custom.sizes.height; +const columnsSelector = `.ss__facet-hierarchy-options, .ss__facet-list-options, .ss__facet-palette-options.ss__facet-palette-options--list`; + +// CSS in JS style script for the Facets component +const facetsHorizontalStyleScript = (props: FacetsHorizontalProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + // facets horizontal styles + const facetsHorizontalStyles = css({ + margin: 0, + ...custom.styles.boxSizing('facetsHorizontal', props?.treePath, props?.name), + '.ss__facets-horizontal__header': { + gap: `${custom.spacing.x2}px`, + position: 'relative', + '& > *': { + minWidth: '1px', + flex: '0 1 auto', + width: `calc((100% - ${custom.spacing.x2 * 5}px) / 6)`, + }, + '& > *, .ss__facets-horizontal__header__dropdown, .ss__mobile-sidebar': { + margin: 0, + }, + '.ss__facets-horizontal__header__dropdown': { + position: 'static', + '&.ss__dropdown--open': { + '.ss__dropdown__button': { + '.ss__dropdown__button__heading': { + '.ss__icon': { + transform: 'rotate(180deg)', + }, + }, + }, + '.ss__dropdown__content': { + width: 'auto', + minWidth: '1px', + maxHeight: 'none', + overflowY: 'visible', + padding: `${custom.spacing.x4}px`, + marginTop: `${custom.spacing.x2}px`, + right: 0, + }, + }, + '.ss__dropdown__button, .ss__dropdown__content': { + ...custom.styles.box(variables?.colors?.text, `0 ${custom.spacing.x2}px`), + }, + '.ss__dropdown__button': { + height: `${dropdownButtonHeight}px`, + lineHeight: `${dropdownButtonHeight}px`, + '&, .ss__dropdown__button__heading': { + width: '100%', + }, + '.ss__dropdown__button__heading': { + flexFlow: 'row nowrap', + justifyContent: 'flex-start', + gap: `${custom.spacing.x1}px`, + padding: 0, + '& > *': { + minWidth: '1px', + }, + span: { + flex: '1 1 0%', + paddingRight: `${custom.spacing.x1}px`, + fontWeight: custom.fonts.weight01, + ...custom.styles.textOverflow(), + }, + '.ss__icon': { + transition: 'transform ease 0.5s', + }, + }, + }, + '.ss__dropdown__content': { + [columnsSelector]: { + display: 'flex', + flexFlow: 'row wrap', + gap: `${custom.spacing.x1}px ${custom.spacing.x2}px`, + '& > *': { + flex: '0 1 auto', + width: `calc((100% - ${custom.spacing.x2 * 3}px) / 4)`, + minWidth: '1px', + margin: 0, + }, + }, + '.ss__checkbox, .ss__radio, .ss__search-input .ss__search-input__input, .ss__facet__range-inputs .ss__facet__range-input__input': { + backgroundColor: custom.colors.white, + }, + '.ss__facet': { + margin: 0, + }, + '.ss__facet.ss__facet--showing-all:has(.ss__facet__show-more-less) .ss__facet__options': { + maxHeight: '360px', + }, + '.ss__facet-list-options': { + '.ss__facet-list-options__option .ss__facet-list-options__option__value': { + ...custom.styles.textOverflow(), + }, + }, + '.ss__facet-hierarchy-options': { + '.ss__facet-hierarchy-options__option .ss__facet-hierarchy-options__option__value': { + ...custom.styles.textOverflow(), + }, + '.ss__facet-hierarchy-options__option--return, .ss__facet-hierarchy-options__option--filtered': { + width: '100%', + }, + '.ss__facet-hierarchy-options__option.ss__facet-hierarchy-options__option--filtered': { + '& ~ .ss__facet-hierarchy-options__option:not(.ss__facet-hierarchy-options__option--filtered)': { + paddingLeft: 0, + }, + }, + }, + '.ss__facet-grid-options': { + '.ss__facet-grid-options__option:not(.ss__facet-grid-options__option--filtered)': { + backgroundColor: custom.colors.white, + }, + }, + '.ss__facet--slider .ss__facet__options, .ss__facet__range-inputs': { + maxWidth: '50%', + marginLeft: 'auto', + marginRight: 'auto', + }, + '.ss__facet__show-more-less': { + justifyContent: 'center', + }, + }, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content .ss__facet__show-more-less, .ss__mobile-sidebar .ss__slideout__button .ss__button': + { + display: 'flex', + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__facets-horizontal__header': { + '& > *': { + width: `calc((100% - ${custom.spacing.x2 * 3}px) / 4)`, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content': { + [columnsSelector]: { + '& > *': { + width: `calc((100% - ${custom.spacing.x2 * 2}px) / 3)`, + }, + }, + }, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__facets-horizontal__header': { + '& > *': { + width: `calc((100% - ${custom.spacing.x2 * 2}px) / 3)`, + }, + '.ss__facets-horizontal__header__dropdown .ss__dropdown__content': { + [columnsSelector]: { + '& > *': { + width: `calc((100% - ${custom.spacing.x2}px) / 2)`, + }, + }, + }, + }, + }, + }); + + return facetsHorizontalStyles; +}; + +// FacetsHorizontal component props +export const facetsHorizontal: ThemeComponent<'facetsHorizontal', FacetsHorizontalProps> = { + default: { + facetsHorizontal: { + themeStyleScript: facetsHorizontalStyleScript, + iconExpand: custom.icons.arrowDown, + iconCollapse: custom.icons.arrowDown, + alwaysShowFiltersButton: true, + }, + 'facetsHorizontal dropdown button icon': { + size: `${custom.sizes.icon12}px`, + width: `${custom.sizes.icon12}px`, + height: `${custom.sizes.icon12}px`, + }, + 'facetsHorizontal dropdown facet': { + statefulOverflow: true, + display: { + list: { + limit: 32, + }, + hierarchy: { + limit: 32, + }, + grid: { + limit: 36, + }, + palette: { + limit: 36, + }, + }, + }, + 'facetsHorizontal mobileSidebar facet': { + statefulOverflow: true, + display: { + list: { + limit: 10, + }, + hierarchy: { + limit: 10, + }, + grid: { + limit: 12, + }, + palette: { + limit: 12, + }, + }, + }, + 'facetsHorizontal facetGridOptions': { + gridSize: '48px', + }, + 'facetsHorizontal mobileSidebar facetGridOptions': { + gridSize: '52px', + }, + 'facetsHorizontal facetPaletteOptions': { + gridSize: '48px', + }, + 'facetsHorizontal mobileSidebar facetPaletteOptions': { + gridSize: '52px', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/filterSummary.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/filterSummary.ts new file mode 100644 index 0000000000..c6588db602 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/filterSummary.ts @@ -0,0 +1,115 @@ +import { css } from '@emotion/react'; +import type { FilterSummaryProps } from '../../../../components/Organisms/FilterSummary'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the FilterSummary component +const filterSummaryStyleScript = (props: FilterSummaryProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const isSidebar = props?.treePath && (props.treePath.includes('sidebar') || props.treePath.includes('mobileSidebar')) ? true : false; + + // filter summary styles + const filterSummaryStyles = isSidebar + ? { + display: 'block', + } + : { + display: 'flex', + alignItems: 'center', + gap: `${custom.spacing.x2}px`, + }; + + // header styles + const headerStyles = isSidebar + ? { + margin: `0 0 ${custom.spacing.x4}px 0`, + padding: `0 0 ${custom.spacing.x2}px 0`, + borderBottom: `2px solid ${variables?.colors?.primary}`, + ...custom.styles.headerText(variables?.colors?.secondary, '16px'), + } + : { + padding: 0, + ...custom.styles.headerText(variables?.colors?.secondary, '14px'), + }; + + // shared styles + const sharedStyles = css({ + width: 'auto', + ...filterSummaryStyles, + ...custom.styles.boxSizing('filterSummary', props?.treePath, props?.name), + '.ss__filter-summary__title': { + ...headerStyles, + }, + '.ss__filter-summary__filters': { + margin: 0, + }, + }); + + // inline filter summary styles + // note: inline is a grid type summary style + const inlineFilterSummaryStyles = css([ + sharedStyles, + { + '&.ss__filter-summary--inline': { + '.ss__filter-summary__filters': { + gap: `${custom.spacing.x2}px`, + '.ss__filter': { + '.ss__filter__button': { + ...custom.styles.box('', `${custom.spacing.x1}px ${custom.spacing.x2}px`), + '.ss__button__content': { + '.ss__filter__button__icon': { + marginRight: `${custom.spacing.x1}px`, + }, + }, + }, + }, + }, + }, + }, + ]); + + // list filter summary styles + const listFilterSummaryStyles = css([ + sharedStyles, + { + '&.ss__filter-summary--list': { + '&, .ss__filter-summary__filters': { + display: isSidebar ? '' : 'flex', + }, + '.ss__filter-summary__filters': { + '.ss__filter': { + margin: isSidebar ? `0 0 ${custom.spacing.x1}px 0` : 0, + '&:last-of-type': { + marginBottom: isSidebar ? 0 : '', + }, + '.ss__filter__button': { + '.ss__button__content': { + padding: `0 0 0 ${custom.sizes.icon16 + custom.spacing.x2}px`, + '.ss__filter__button__icon': { + position: 'absolute', + top: '1.5px', + left: 0, + ...custom.styles.box('', '3px'), + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + }, + }, + }, + }, + }, + }, + }, + ]); + + return props?.type == 'list' ? listFilterSummaryStyles : inlineFilterSummaryStyles; +}; + +// FilterSummary component props +export const filterSummary: ThemeComponent<'filterSummary', FilterSummaryProps> = { + default: { + filterSummary: { + themeStyleScript: filterSummaryStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/index.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/index.ts new file mode 100644 index 0000000000..11cfc74d31 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/index.ts @@ -0,0 +1,74 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// ORGANISMS Imports +import { autocomplete } from './autocomplete'; +import { autocompleteLayout } from './autocompleteLayout'; +import { facet } from './facet'; +import { facets } from './facets'; +import { facetsHorizontal } from './facetsHorizontal'; +import { filterSummary } from './filterSummary'; +import { mobileSidebar } from './mobileSidebar'; +import { noResults } from './noResults'; +import { results } from './results'; +import { sidebar } from './sidebar'; +import { termsList } from './termsList'; +import { toolbar } from './toolbar'; + +export const organisms: ThemeResponsiveComplete = { + default: { + ...autocomplete.default, + ...autocompleteLayout.default, + ...facet.default, + ...facets.default, + ...facetsHorizontal.default, + ...filterSummary.default, + ...mobileSidebar.default, + ...noResults.default, + ...results.default, + ...sidebar.default, + ...toolbar.default, + ...termsList.default, + }, + mobile: { + ...autocomplete.mobile, + ...autocompleteLayout.mobile, + ...facet.mobile, + ...facets.mobile, + ...facetsHorizontal.mobile, + ...filterSummary.mobile, + ...mobileSidebar.mobile, + ...noResults.mobile, + ...results.mobile, + ...sidebar.mobile, + ...toolbar.mobile, + ...termsList.mobile, + }, + tablet: { + ...autocomplete.tablet, + ...autocompleteLayout.tablet, + ...facet.tablet, + ...facets.tablet, + ...facetsHorizontal.tablet, + ...filterSummary.tablet, + ...mobileSidebar.tablet, + ...noResults.tablet, + ...results.tablet, + ...sidebar.tablet, + ...toolbar.tablet, + ...termsList.tablet, + }, + desktop: { + ...autocomplete.desktop, + ...autocompleteLayout.desktop, + ...facet.desktop, + ...facets.desktop, + ...facetsHorizontal.desktop, + ...filterSummary.desktop, + ...mobileSidebar.desktop, + ...noResults.desktop, + ...results.desktop, + ...sidebar.desktop, + ...toolbar.desktop, + ...termsList.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/mobileSidebar.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/mobileSidebar.ts new file mode 100644 index 0000000000..07ae4690b9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/mobileSidebar.ts @@ -0,0 +1,165 @@ +import { css } from '@emotion/react'; +import type { MobileSidebarProps } from '../../../../components/Organisms/MobileSidebar'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// static variables +const headerHeight = 60; +const footerHeight = 75; +const activeColors = custom.utils.activeColors(); +const activeColor = activeColors[0]; +const fontColor = activeColors[1]; + +// CSS in JS style script for the MobileSidebar component +const mobileSidebarStyleScript = (props: MobileSidebarProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const hideHeader = typeof props?.hideHeader == 'boolean' ? props.hideHeader : false; + const hideFooter = typeof props?.hideFooter == 'boolean' ? props.hideFooter : false; + + // determine inner content height + let innerHeight = 100; + if (!hideHeader && !hideFooter) { + innerHeight = headerHeight + footerHeight; + } else if (hideHeader && !hideFooter) { + innerHeight = headerHeight; + } else if (hideFooter && !hideHeader) { + innerHeight = footerHeight; + } + + // mobile sidebar styles + const mobileSidebarStyles = css({ + ...custom.styles.boxSizing('mobileSidebar', props?.treePath, props?.name), + '.ss__slideout__button .ss__button': { + '&[active="true"]': { + '.ss__icon--filter': { + transform: 'rotate(-180deg)', + }, + '.ss__icon--filters': { + circle: { + '&:last-child': { + transform: 'translateX(-35%)', + }, + transform: 'translateX(35%)', + }, + }, + }, + '.ss__button__content': { + textAlign: 'left', + }, + '.ss__icon--filters': { + fill: activeColor, + stroke: fontColor, + }, + }, + '.ss__mobile-sidebar__slideout': { + overflowY: 'hidden', + padding: 0, + width: '100%', + '.ss__mobile-sidebar__content': { + height: '100%', + '.ss__mobile-sidebar__header, .ss__mobile-sidebar__footer': { + padding: `0 ${custom.spacing.x4}px`, + gap: `${custom.spacing.x2}px`, + flexFlow: 'row nowrap', + alignItems: 'center', + }, + '.ss__mobile-sidebar__header': { + height: `${headerHeight}px`, + backgroundColor: activeColor, + color: fontColor, + '.ss__mobile-sidebar__header__title': { + margin: 0, + fontSize: '18px', + }, + '.ss__mobile-sidebar__header__close-button': { + padding: 0, + width: 'auto', + height: 'auto', + lineHeight: '0', + border: 0, + backgroundColor: 'transparent', + }, + }, + '.ss__mobile-sidebar__inner': { + height: innerHeight == 100 ? `${innerHeight}%` : `calc(100% - ${innerHeight}px)`, + overflowY: 'auto', + overflowX: 'hidden', + ...custom.styles.scrollbar(), + '.ss__layout': { + overflow: 'hidden', + display: 'block', + '& > *': { + borderBottom: `1px solid ${custom.colors.gray02}`, + padding: `${custom.spacing.x4}px`, + '&:last-of-type': { + borderBottomWidth: 0, + }, + }, + }, + '.ss__filter-summary, .ss__facets': { + padding: 0, + }, + '.ss__filter-summary .ss__filter-summary__title, .ss__facets .ss__facet .ss__facet__header': { + margin: 0, + padding: `${custom.spacing.x2}px ${custom.spacing.x4}px`, + borderBottom: `1px solid ${custom.colors.gray01}`, + backgroundColor: custom.colors.gray01, + color: variables?.colors?.text, + fontSize: '14px', + }, + '.ss__filter-summary .ss__filter-summary__filters, .ss__facets .ss__facet .ss__dropdown__content': { + padding: `${custom.spacing.x4}px`, + }, + '.ss__facets .ss__facet': { + margin: 0, + '&.ss__facet--collapsed': { + borderBottom: `1px solid ${custom.colors.gray02}`, + }, + }, + '.ss__select .ss__dropdown .ss__dropdown__content': { + zIndex: 6, + }, + '.ss__select--native': { + padding: `0 ${custom.spacing.x4}px`, + borderTop: 0, + height: '40px', + lineHeight: '40px', + }, + }, + '.ss__mobile-sidebar__footer': { + height: `${footerHeight}px`, + backgroundColor: custom.colors.white, + borderTop: `1px solid ${custom.colors.gray02}`, + '.ss__button': { + flex: `1 1 0%`, + }, + }, + }, + }, + }); + + return mobileSidebarStyles; +}; + +// MobileSidebar component props +export const mobileSidebar: ThemeComponent<'mobileSidebar', MobileSidebarProps> = { + default: { + mobileSidebar: { + themeStyleScript: mobileSidebarStyleScript, + openButtonIcon: custom.icons.filter, + closeButtonIcon: custom.icons.close, + }, + 'mobileSidebar button.close icon': { + size: `${custom.sizes.icon16}px`, + width: `${custom.sizes.icon16}px`, + height: `${custom.sizes.icon16}px`, + }, + 'mobileSidebar facets icon.collapse': { + fill: 'currentColor', + }, + 'mobileSidebar facets icon.expand': { + fill: 'currentColor', + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/noResults.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/noResults.ts new file mode 100644 index 0000000000..cb61322c3c --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/noResults.ts @@ -0,0 +1,63 @@ +import { css } from '@emotion/react'; +import type { NoResultsProps } from '../../../../components/Organisms/NoResults'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the NoResults component +const noResultsStyleScript = (props: NoResultsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + ...custom.styles.boxSizing('noResults', props?.treePath, props?.name), + 'h1, h2, h3, h4, h5, h6, ul': { + margin: `0 0 ${custom.spacing.x4}px 0`, + }, + 'h1, h2, h3, h4, h5, h6, .ss__no-results__recommendations .ss__recommendation .ss__recommendation__title': { + fontSize: '20px', + fontWeight: custom.fonts.weight02, + color: variables?.colors?.secondary, + }, + 'ul li, p': { + color: variables?.colors?.text, + }, + a: { + color: variables?.colors?.primary, + '&:hover': { + color: variables?.colors?.secondary, + }, + }, + ul: { + padding: 0, + marginLeft: `${custom.spacing.x8}px`, + listStyle: 'none', + li: { + listStyle: 'disc', + margin: `0 0 ${custom.spacing.x1}px 0`, + '&:last-of-type': { + marginBottom: 0, + }, + }, + }, + '.ss__no-results__recommendations': { + '.ss__recommendation': { + margin: `${custom.spacing.x4}px 0`, + }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + 'h1, h2, h3, h4, h5, h6, .ss__no-results__recommendations .ss__recommendation .ss__recommendation__title': { + fontSize: '18px', + }, + }, + }); +}; + +// NoResults component props +export const noResults: ThemeComponent<'noResults', NoResultsProps> = { + default: { + noResults: { + themeStyleScript: noResultsStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/results.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/results.ts new file mode 100644 index 0000000000..b2a4d8cc71 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/results.ts @@ -0,0 +1,40 @@ +import { css } from '@emotion/react'; +import type { ResultsProps } from '../../../../components/Organisms/Results'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Results component +const resultsStyleScript = (props: ResultsProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + ...custom.styles.boxSizing('results', props?.treePath, props?.name), + '& > *': { + minWidth: '1px', + }, + }); +}; + +// Results component props +export const results: ThemeComponent<'results', ResultsProps> = { + default: { + results: { + themeStyleScript: resultsStyleScript, + gapSize: `${custom.spacing.x6}px ${custom.spacing.x4}px`, + columns: 4, + }, + }, + mobile: { + results: { + gapSize: `${custom.spacing.x6}px ${custom.spacing.x2}px`, + columns: 2, + }, + }, + tablet: { + results: { + columns: 3, + }, + }, + desktop: {}, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/sidebar.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/sidebar.ts new file mode 100644 index 0000000000..5613193d62 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/sidebar.ts @@ -0,0 +1,38 @@ +import { css } from '@emotion/react'; +import type { SidebarProps } from '../../../../components/Organisms/Sidebar'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Sidebar component +const sidebarStyleScript = (props: SidebarProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // sidebar styles + const sidebarStyles = css({ + ...custom.styles.boxSizing('sidebar', props?.treePath, props?.name), + '.ss__sidebar__title': { + margin: `0 0 ${custom.spacing.x6}px 0`, + ...custom.styles.headerText(variables?.colors?.secondary, '20px'), + }, + '.ss__sidebar__inner': { + '.ss__layout': { + gap: `${custom.spacing.x6}px`, + }, + '.ss__select': { + width: '100%', + }, + }, + }); + + return sidebarStyles; +}; + +// Sidebar component props +export const sidebar: ThemeComponent<'sidebar', SidebarProps> = { + default: { + sidebar: { + themeStyleScript: sidebarStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/termsList.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/termsList.ts new file mode 100644 index 0000000000..9bc58ab58e --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/termsList.ts @@ -0,0 +1,33 @@ +import { css } from '@emotion/react'; +import type { TermsListProps } from '../../../../components/Organisms/TermsList'; +import { ThemeComponent } from '../../../../providers'; +import { custom } from '../../custom'; + +// CSS in JS style script for the TermsList component +const termsListStyleScript = (props: TermsListProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + // terms list styles + const termsListStyles = css({ + backgroundColor: 'transparent', + flexFlow: 'row nowrap', + gap: `${custom.spacing.x4}px`, + ...custom.styles.boxSizing('termsList', props?.treePath, props?.name), + '.ss__terms-list__row': { + flex: '1 1 0%', + minWidth: '1px', + }, + }); + + return termsListStyles; +}; + +// TermsList component props +export const termsList: ThemeComponent<'termsList', TermsListProps> = { + default: { + termsList: { + themeStyleScript: termsListStyleScript, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/organisms/toolbar.ts b/packages/snap-preact/components/src/themes/pike/components/organisms/toolbar.ts new file mode 100644 index 0000000000..4cbf925a50 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/organisms/toolbar.ts @@ -0,0 +1,60 @@ +import { css } from '@emotion/react'; +import { ThemeComponent } from '../../../../providers'; +import { ToolbarProps } from '../../../../components/Organisms/Toolbar'; +import { custom } from '../../custom'; + +// static variables +const activeColors = custom.utils.activeColors(); +const activeColor = activeColors[0]; +const fontColor = activeColors[1]; + +// CSS in JS style script for the Toolbar component +const toolbarStyleScript = (props: ToolbarProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + // toolbar styles + const toolbarStyles = css({ + ...custom.styles.boxSizing('toolbar', props?.treePath, props?.name), + '.ss__button--sidebar-toggle-button-wrapper .ss__button': { + '.ss__button__content': { + textAlign: 'left', + }, + '.ss__icon--filters': { + fill: activeColor, + stroke: fontColor, + }, + }, + '.ss__layout': { + '&, .ss__layout__row': { + gap: `${custom.spacing.x2}px`, + }, + }, + '.ss__pagination-info': { + fontSize: props?.name == 'bottom' ? '14px' : '', + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__pagination-info': { + fontSize: props?.name == 'bottom' ? '16px' : '18px', + }, + }, + }); + + return toolbarStyles; +}; + +// Toolbar component props +export const toolbar: ThemeComponent<'toolbar', ToolbarProps> = { + default: { + toolbar: { + themeStyleScript: toolbarStyleScript, + }, + 'toolbar filterSummary': { + title: `Current Filters:`, + }, + 'toolbar mobileSidebar filterSummary': { + title: `Current Filters`, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteFixed.ts b/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteFixed.ts new file mode 100644 index 0000000000..9e6aad4110 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteFixed.ts @@ -0,0 +1,191 @@ +import { css } from '@emotion/react'; +import { autocompleteFixedThemeComponentProps } from '../../../themeComponents/autocompleteFixed'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteFixedProps } from '../../../../components/Templates/AutocompleteFixed'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteFixedStyleScript = (props: AutocompleteFixedProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + + return css({ + ...custom.styles.boxSizing('autocompleteFixed', props?.treePath, props?.name), + '.ss__modal': { + '.ss__modal__content': { + // '.ss__autocomplete-fixed__inner': { + // '& > .ss__search-input.autocomplete-fixed__search-input': { + // height: '40px', + // margin: `0 0 ${custom.spacing.x2}px 0`, + // '.ss__button, .ss__search-input__button--close-search-button': { + // width: '40px', + // }, + // }, + // '.ss__autocomplete-fixed__inner__layout-wrapper': { + // maxHeight: 'none', + // width: 'auto', + // '&, .ss__autocomplete': { + // overflowY: 'visible', + // }, + // '.ss__autocomplete': { + // maxWidth: 'none', + // width: props?.width, + // right: 0, + // left: '-102px', + // top: 'auto', + // margin: 'auto', + // }, + // }, + // }, + }, + }, + [`@media (max-width: ${tabletBp}px)`]: { + '.ss__modal': { + // '.ss__modal__content': { + // '.ss__autocomplete-fixed__inner': { + // '.ss__autocomplete-fixed__inner__layout-wrapper': { + // '.ss__autocomplete': { + // maxWidth: '100%', + // width: props?.width, + // left: 0, + // right: 0, + // }, + // }, + // }, + // }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__modal': { + // '.ss__modal__content': { + // '.ss__autocomplete-fixed__inner': { + // '.ss__autocomplete-fixed__inner__layout-wrapper': { + // '.ss__autocomplete': { + // '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + // { + // '& > *:nth-of-type(n+3)': { + // display: 'none', + // }, + // }, + // }, + // }, + // }, + // }, + }, + }, + }); +}; + +export const autocompleteFixed: ThemeComponent<'autocompleteFixed', AutocompleteFixedProps> = { + default: { + ...autocompleteFixedThemeComponentProps.default, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.default?.['autocompleteFixed'] || {}), + themeStyleScript: autocompleteFixedStyleScript, + // width: '900px', + // layout: 'standard', + }, + 'autocompleteFixed facetPaletteOptions': { + // gridSize: '38px', + // hideLabel: false, + }, + 'autocompleteFixed facetGridOptions': { + //gridSize: '38px', + }, + 'autocompleteFixed facet': { + ...(autocompleteFixedThemeComponentProps.default?.['autocompleteFixed facet'] || {}), + // display: { + // list: { + // limit: 5, + // }, + // hierarchy: { + // limit: 5, + // }, + // grid: { + // limit: 6, + // }, + // palette: { + // limit: 6, + // }, + // }, + }, + 'autocompleteFixed results': { + // rows: 2, + // columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + // rows: 2, + // columns: 4, + }, + 'autocompleteFixed button.see-more icon': { + // size: `${custom.sizes.icon12}px`, + // width: `${custom.sizes.icon12}px`, + // height: `${custom.sizes.icon12}px`, + // icon: custom.icons.arrowRight, + }, + }, + mobile: { + ...autocompleteFixedThemeComponentProps.mobile, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.mobile?.['autocompleteFixed'] || {}), + // width: 'auto', + // layout: 'mini', + }, + 'autocompleteFixed results': { + // rows: 1, + // columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + // rows: 1, + // columns: 3, + }, + }, + tablet: { + ...autocompleteFixedThemeComponentProps.tablet, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.tablet?.['autocompleteFixed'] || {}), + // width: 'auto', + // layout: 'standard', + }, + 'autocompleteFixed facet': { + // display: { + // list: { + // limit: 3, + // }, + // hierarchy: { + // limit: 3, + // }, + // grid: { + // limit: 4, + // }, + // palette: { + // limit: 4, + // }, + // }, + }, + 'autocompleteFixed results': { + // rows: 1, + // columns: 4, + }, + 'autocompleteFixed recommendationGrid': { + // rows: 1, + // columns: 4, + }, + }, + desktop: { + ...autocompleteFixedThemeComponentProps.desktop, + autocompleteFixed: { + ...(autocompleteFixedThemeComponentProps.desktop?.['autocompleteFixed'] || {}), + //layout: 'standard', + }, + 'autocompleteFixed results': { + // rows: 2, + // columns: 3, + }, + 'autocompleteFixed recommendationGrid': { + // rows: 2, + // columns: 4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteModal.ts b/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteModal.ts new file mode 100644 index 0000000000..c18c4c3a65 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteModal.ts @@ -0,0 +1,208 @@ +import { css } from '@emotion/react'; +import { autocompleteModalThemeComponentProps } from '../../../themeComponents/autocompleteModal'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteModalProps } from '../../../../components/Templates/AutocompleteModal'; +import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteModalStyleScript = (props: AutocompleteModalProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + ...custom.styles.boxSizing('autocompleteModal', props?.treePath, props?.name), + '.ss__modal': { + // '&, .ss__modal__content': { + // height: '100%', + // }, + // '.ss__modal__content': { + // backgroundColor: 'transparent', + // justifyContent: 'center', + // '&, .ss__autocomplete-modal__inner': { + // position: 'static', + // display: 'flex', + // flexFlow: 'column nowrap', + // }, + // '.ss__autocomplete-modal__inner': { + // width: props?.width, + // maxHeight: 'none', + // height: '80vh', + // overflow: 'hidden', + // '& > .ss__search-input.autocomplete-modal__search-input, .ss__autocomplete': { + // minHeight: '1px', + // minWidth: '1px', + // }, + // '& > .ss__search-input.autocomplete-modal__search-input': { + // flex: '0 1 auto', + // height: '40px', + // margin: 0, + // '.ss__button, .ss__search-input__button--close-search-button': { + // width: '40px', + // }, + // }, + // '.ss__autocomplete': { + // flex: '1 1 0%', + // borderWidth: 0, + // overflowY: 'auto', + // '&::-webkit-scrollbar': { + // width: '8px', + // height: '8px', + // }, + // '&::-webkit-scrollbar-track': { + // backgroundColor: custom.colors.gray01, + // }, + // '&::-webkit-scrollbar-thumb': { + // backgroundColor: custom.colors.gray02, + // }, + // '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + // { + // maxHeight: 'none', + // overflow: 'visible', + // }, + // }, + // }, + // }, + }, + [`@media (max-width: ${mobileBp}px)`]: { + '.ss__modal': { + // '.ss__modal__content': { + // '.ss__autocomplete-modal__inner': { + // width: props?.width, + // height: '100%', + // }, + // }, + }, + }, + [`@media (max-width: ${custom.breakpoints.small}px)`]: { + '.ss__modal': { + // '.ss__modal__content': { + // '.ss__autocomplete-modal__inner': { + // '.ss__autocomplete': { + // '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + // { + // '& > *:nth-of-type(n+5)': { + // display: 'none', + // }, + // }, + // }, + // }, + // }, + }, + }, + }); +}; + +export const autocompleteModal: ThemeComponent<'autocompleteModal', AutocompleteModalProps> = { + default: { + ...autocompleteModalThemeComponentProps.default, + autocompleteModal: { + ...(autocompleteModalThemeComponentProps.default?.['autocompleteModal'] || {}), + themeStyleScript: autocompleteModalStyleScript, + // width: '70vw', + // layout: 'standard', + }, + // 'autocompleteModal facetPaletteOptions': { + // gridSize: '38px', + // hideLabel: false, + // }, + // 'autocompleteModal facetGridOptions': { + // gridSize: '38px', + // }, + // 'autocompleteModal facet': { + // ...(autocompleteModalThemeComponentProps.default?.['autocompleteModal facet'] || {}), + // display: { + // list: { + // limit: 5, + // }, + // hierarchy: { + // limit: 5, + // }, + // grid: { + // limit: 6, + // }, + // palette: { + // limit: 6, + // }, + // }, + // }, + // 'autocompleteModal results': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteModal recommendationGrid': { + // rows: 2, + // columns: 4, + // }, + // 'autocompleteModal button.see-more icon': { + // size: `${custom.sizes.icon12}px`, + // width: `${custom.sizes.icon12}px`, + // height: `${custom.sizes.icon12}px`, + // icon: custom.icons.arrowRight, + // }, + }, + mobile: { + ...autocompleteModalThemeComponentProps.mobile, + // autocompleteModal: { + // ...(autocompleteModalThemeComponentProps.mobile?.['autocompleteModal'] || {}), + // width: '100%', + // layout: 'mini', + // }, + // 'autocompleteModal results': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteModal recommendationGrid': { + // rows: 2, + // columns: 3, + // }, + }, + tablet: { + ...autocompleteModalThemeComponentProps.tablet, + // autocompleteModal: { + // ...(autocompleteModalThemeComponentProps.tablet?.['autocompleteModal'] || {}), + // width: '80vw', + // layout: 'standard', + // }, + // 'autocompleteModal facet': { + // display: { + // list: { + // limit: 3, + // }, + // hierarchy: { + // limit: 3, + // }, + // grid: { + // limit: 4, + // }, + // palette: { + // limit: 4, + // }, + // }, + // }, + // 'autocompleteModal results': { + // rows: 2, + // columns: 4, + // }, + // 'autocompleteModal recommendationGrid': { + // rows: 2, + // columns: 4, + // }, + }, + desktop: { + ...autocompleteModalThemeComponentProps.desktop, + // autocompleteModal: { + // ...(autocompleteModalThemeComponentProps.desktop?.['autocompleteModal'] || {}), + // width: '80vw', + // layout: 'standard', + // }, + // 'autocompleteModal results': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteModal recommendationGrid': { + // rows: 2, + // columns: 4, + // }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteSlideout.ts b/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteSlideout.ts new file mode 100644 index 0000000000..0bbbe5d83c --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/autocompleteSlideout.ts @@ -0,0 +1,132 @@ +import { css } from '@emotion/react'; +import { autocompleteSlideoutThemeComponentProps } from '../../../themeComponents/autocompleteSlideout'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteSlideoutProps } from '../../../../components/Templates/AutocompleteSlideout'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const autocompleteSlideoutStyleScript = (props: AutocompleteSlideoutProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + // border: 0, + // padding: `${custom.spacing.x4}px`, + // ...custom.styles.boxSizing('autocompleteSlideout', props?.treePath, props?.name), + // '.ss__autocomplete-slideout__inner': { + // display: 'flex', + // flexFlow: 'column nowrap', + // height: '100%', + // '& > .ss__search-input.autocomplete-slideout__search-input, .ss__autocomplete': { + // minHeight: '1px', + // minWidth: '1px', + // }, + // '& > .ss__search-input.autocomplete-slideout__search-input': { + // flex: '0 1 auto', + // height: '40px', + // margin: `0 0 ${custom.spacing.x2}px 0`, + // '.ss__button, .ss__search-input__button--close-search-button': { + // width: '40px', + // }, + // }, + // '.ss__autocomplete': { + // flex: '1 1 0%', + // alignContent: 'flex-start', + // borderWidth: 0, + // overflowY: 'auto', + // '&::-webkit-scrollbar': { + // width: '8px', + // height: '8px', + // }, + // '&::-webkit-scrollbar-track': { + // backgroundColor: custom.colors.gray01, + // }, + // '&::-webkit-scrollbar-thumb': { + // backgroundColor: custom.colors.gray02, + // }, + // '& > .ss__autocomplete__row .ss__autocomplete__column': { + // padding: `${custom.spacing.x4}px 0`, + // }, + // '.ss__autocomplete__terms-wrapper, .ss__autocomplete__content, .ss__autocomplete__button--see-more': { + // paddingLeft: 0, + // paddingRight: 0, + // }, + // '.ss__autocomplete__content__results .ss__results, .ss__autocomplete__content__no-results .ss__autocomplete__content__no-results__recommendations .ss__recommendation-grid__results': + // { + // maxHeight: 'none', + // overflow: 'visible', + // }, + // }, + // }, + }); +}; + +export const autocompleteSlideout: ThemeComponent<'autocompleteSlideout', AutocompleteSlideoutProps> = { + default: { + ...autocompleteSlideoutThemeComponentProps.default, + autocompleteSlideout: { + ...(autocompleteSlideoutThemeComponentProps.default?.['autocompleteSlideout'] || {}), + themeStyleScript: autocompleteSlideoutStyleScript, + //layout: 'mini', + }, + // 'autocompleteSlideout results': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteSlideout recommendationGrid': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteSlideout button.see-more icon': { + // size: `${custom.sizes.icon12}px`, + // width: `${custom.sizes.icon12}px`, + // height: `${custom.sizes.icon12}px`, + // icon: custom.icons.arrowRight, + // }, + }, + mobile: { + ...autocompleteSlideoutThemeComponentProps.mobile, + // autocompleteSlideout: { + // ...(autocompleteSlideoutThemeComponentProps.mobile?.['autocompleteSlideout'] || {}), + // layout: 'mini', + // }, + // 'autocompleteSlideout results': { + // rows: 2, + // columns: 2, + // }, + // 'autocompleteSlideout recommendationGrid': { + // rows: 2, + // columns: 2, + // }, + }, + tablet: { + ...autocompleteSlideoutThemeComponentProps.tablet, + // autocompleteSlideout: { + // ...(autocompleteSlideoutThemeComponentProps.tablet?.['autocompleteSlideout'] || {}), + // layout: 'mini', + // }, + // 'autocompleteSlideout results': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteSlideout recommendationGrid': { + // rows: 2, + // columns: 3, + // }, + }, + desktop: { + ...autocompleteSlideoutThemeComponentProps.desktop, + // autocompleteSlideout: { + // ...(autocompleteSlideoutThemeComponentProps.desktop?.['autocompleteSlideout'] || {}), + // layout: 'mini', + // }, + // 'autocompleteSlideout results': { + // rows: 2, + // columns: 3, + // }, + // 'autocompleteSlideout recommendationGrid': { + // rows: 2, + // columns: 3, + // }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/index.ts b/packages/snap-preact/components/src/themes/pike/components/templates/index.ts new file mode 100644 index 0000000000..e6bef36cef --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/index.ts @@ -0,0 +1,79 @@ +import { ThemeResponsiveComplete } from '../../../../providers'; + +// TEMPLATES +import { autocompleteFixed } from './autocompleteFixed'; +import { autocompleteModal } from './autocompleteModal'; +import { autocompleteSlideout } from './autocompleteSlideout'; +import { recommendation } from './recommendation'; +import { recommendationBundle } from './recommendationBundle'; +import { recommendationBundleEasyAdd } from './recommendationBundleEasyAdd'; +import { recommendationBundleList } from './recommendationBundleList'; +import { recommendationBundleVertical } from './recommendationBundleVertical'; +import { recommendationGrid } from './recommendationGrid'; +import { recommendationEmail } from './recommendationEmail'; +import { search } from './search'; +import { searchHorizontal } from './searchHorizontal'; +import { searchCollapsible } from './searchCollapsible'; + +export const templates: ThemeResponsiveComplete = { + default: { + ...autocompleteFixed.default, + ...autocompleteModal.default, + ...autocompleteSlideout.default, + ...recommendation.default, + ...recommendationBundle.default, + ...recommendationBundleEasyAdd.default, + ...recommendationBundleList.default, + ...recommendationBundleVertical.default, + ...recommendationGrid.default, + ...recommendationEmail.default, + ...search.default, + ...searchCollapsible.default, + ...searchHorizontal.default, + }, + mobile: { + ...autocompleteFixed.mobile, + ...autocompleteModal.mobile, + ...autocompleteSlideout.mobile, + ...recommendation.mobile, + ...recommendationBundle.mobile, + ...recommendationBundleEasyAdd.mobile, + ...recommendationBundleList.mobile, + ...recommendationBundleVertical.mobile, + ...recommendationGrid.mobile, + ...recommendationEmail.mobile, + ...search.mobile, + ...searchCollapsible.mobile, + ...searchHorizontal.mobile, + }, + tablet: { + ...autocompleteFixed.tablet, + ...autocompleteModal.tablet, + ...autocompleteSlideout.tablet, + ...recommendation.tablet, + ...recommendationBundle.tablet, + ...recommendationBundleEasyAdd.tablet, + ...recommendationBundleList.tablet, + ...recommendationBundleVertical.tablet, + ...recommendationGrid.tablet, + ...recommendationEmail.tablet, + ...search.tablet, + ...searchCollapsible.tablet, + ...searchHorizontal.tablet, + }, + desktop: { + ...autocompleteFixed.desktop, + ...autocompleteModal.desktop, + ...autocompleteSlideout.desktop, + ...recommendation.desktop, + ...recommendationBundle.desktop, + ...recommendationBundleEasyAdd.desktop, + ...recommendationBundleList.desktop, + ...recommendationBundleVertical.desktop, + ...recommendationGrid.desktop, + ...recommendationEmail.desktop, + ...search.desktop, + ...searchCollapsible.desktop, + ...searchHorizontal.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendation.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendation.ts new file mode 100644 index 0000000000..6d4ae26359 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendation.ts @@ -0,0 +1,122 @@ +import { css } from '@emotion/react'; +import type { RecommendationProps } from '../../../../components/Templates/Recommendation'; +import { recommendationThemeComponentProps } from '../../../themeComponents/recommendation'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the Recommendation component +const recommendationStyleScript = (props: RecommendationProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + // const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + // const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + // const arrowSizes = { + // default: 32, + // tablet: 28, + // mobile: 24, + // }; + + return css({ + // margin: `${custom.spacing.x8}px 0`, + // ...custom.styles.boxSizing('recommendation', props?.treePath, props?.name), + // '.ss__recommendation__title': { + // fontSize: '22px', + // fontWeight: custom.fonts.weight02, + // color: variables?.colors?.secondary, + // textAlign: 'center', + // margin: `0 0 ${custom.spacing.x4}px 0`, + // }, + // '.ss__carousel': { + // padding: `0 ${custom.spacing.x4 + arrowSizes.default}px`, + // }, + // [`@media (max-width: ${tabletBp}px)`]: { + // '.ss__carousel': { + // padding: `0 ${custom.spacing.x4 + arrowSizes.tablet}px`, + // '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + // width: `${arrowSizes.tablet}px`, + // height: `${arrowSizes.tablet}px`, + // }, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // position: 'relative', + // '.ss__recommendation__title': { + // textAlign: 'left', + // textOverflow: 'ellipsis', + // whiteSpace: 'nowrap', + // overflow: 'hidden', + // paddingRight: `${arrowSizes.mobile * 2 + custom.spacing.x1 + custom.spacing.x4}px`, + // }, + // '.ss__carousel': { + // padding: 0, + // position: 'static', + // '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + // top: '4.5px', + // bottom: 'auto', + // left: 'auto', + // width: `${arrowSizes.mobile}px`, + // height: `${arrowSizes.mobile}px`, + // }, + // '.ss__carousel__prev-wrapper': { + // right: `${arrowSizes.mobile + custom.spacing.x1}px`, + // }, + // '.ss__carousel__next-wrapper': { + // right: 0, + // }, + // }, + // }, + // [`@media (max-width: ${custom.breakpoints.small}px)`]: { + // '.ss__recommendation__title': { + // fontSize: '18px', + // }, + // '.ss__carousel': { + // '.ss__carousel__prev-wrapper, .ss__carousel__next-wrapper': { + // top: 0, + // }, + // }, + // }, + }); +}; + +// Recommendation component props come from Template export +export const recommendation: ThemeComponent<'recommendation', RecommendationProps> = { + default: { + ...recommendationThemeComponentProps.default, + recommendation: { + ...(recommendationThemeComponentProps.default?.['recommendation'] || {}), + themeStyleScript: recommendationStyleScript, + //spaceBetween: custom.spacing.x4, + }, + // 'recommendation icon': { + // size: `${custom.sizes.icon10}px`, + // width: `${custom.sizes.icon10}px`, + // height: `${custom.sizes.icon10}px`, + // }, + }, + mobile: { + ...recommendationThemeComponentProps.mobile, + recommendation: { + ...(recommendationThemeComponentProps.mobile?.['recommendation'] || {}), + //spaceBetween: custom.spacing.x2, + }, + // 'recommendation icon': { + // size: `${custom.sizes.icon08}px`, + // width: `${custom.sizes.icon08}px`, + // height: `${custom.sizes.icon08}px`, + // }, + }, + tablet: { + ...recommendationThemeComponentProps.tablet, + recommendation: { + ...(recommendationThemeComponentProps.tablet?.['recommendation'] || {}), + //spaceBetween: custom.spacing.x4, + }, + }, + desktop: { + ...recommendationThemeComponentProps.desktop, + recommendation: { + ...(recommendationThemeComponentProps.desktop?.['recommendation'] || {}), + //spaceBetween: custom.spacing.x4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundle.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundle.ts new file mode 100644 index 0000000000..c060e3260a --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundle.ts @@ -0,0 +1,247 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleProps } from '../../../../components/Templates/RecommendationBundle'; +import { recommendationBundleThemeComponentProps } from '../../../themeComponents/recommendationBundle'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundle component +const recommendationBundleStyleScript = (props: RecommendationBundleProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + // const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + // const tabletBp = variables?.breakpoints?.tablet || custom.breakpoints.tablet; + // const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // margin: `${custom.spacing.x8}px 0`, + // ...custom.styles.boxSizing('recommendationBundle', props?.treePath, props?.name), + // '.ss__recommendation-bundle__title': { + // fontSize: '22px', + // fontWeight: custom.fonts.weight02, + // color: variables?.colors?.secondary, + // margin: `0 0 ${custom.spacing.x4}px 0`, + // }, + // '.ss__recommendation-bundle__wrapper': { + // flexFlow: `row nowrap`, + // margin: `0 -${custom.spacing.x2}px`, + // '& > *': { + // flex: '0 1 auto', + // minWidth: '1px', + // padding: `0 ${custom.spacing.x2}px`, + // }, + // '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__cta': { + // width: `20%`, + // }, + // '.ss__recommendation-bundle__wrapper__carousel': { + // width: `60%`, + // }, + // }, + // '.ss__recommendation-result-tracker, .ss__recommendation-bundle__wrapper__selector, .ss__recommendation-bundle__wrapper .ss__recommendation-bundle__wrapper__selector__result-wrapper': + // { + // height: '100%', + // margin: 0, + // }, + // '.ss__recommendation-bundle__wrapper__seed-container': { + // '.ss__recommendation-bundle__wrapper__selector__result-wrapper__seed-badge': { + // top: '5px', + // left: '5px', + // backgroundColor: variables?.colors?.primary, + // fontSize: '12px', + // fontWeight: custom.fonts.weight01, + // lineHeight: `20px`, + // color: custom.colors.white, + // padding: `0 ${custom.spacing.x2}px`, + // }, + // }, + // '.ss__recommendation-bundle__wrapper__selector': { + // width: 'auto !important', + // }, + // '.ss__recommendation-bundle__wrapper__selector__result-wrapper, .ss__carousel .swiper-container > .swiper-wrapper > .swiper-slide': { + // '.ss__result': { + // width: '100%', + // flex: '1 1 0%', + // }, + // }, + // '.ss__recommendation-bundle__wrapper__selector__result-wrapper': { + // display: 'flex', + // flexFlow: `column wrap`, + // '&, .ss__result': { + // position: 'relative', + // }, + // '&:has(.ss__overlay-badge)': { + // '.ss__result': { + // '.ss__overlay-badge .ss__overlay-badge__grid-wrapper': { + // top: '25px', + // }, + // }, + // }, + // '.ss__checkbox': { + // top: '5px', + // right: '5px', + // }, + // }, + // '.ss__icon--plus': { + // display: 'none', + // position: 'absolute', + // top: 0, + // right: 0, + // bottom: 0, + // margin: 'auto 0', + // }, + // '.ss__recommendation-bundle__wrapper__cta': { + // position: 'relative', + // paddingTop: `${custom.spacing.x4}px`, + // paddingBottom: `${custom.spacing.x4}px`, + // display: 'flex', + // flexFlow: 'column nowrap', + // justifyContent: 'center', + // alignItems: 'center', + // gap: `${custom.spacing.x4}px`, + // '& > *': { + // flex: '0 1 auto', + // minWidth: '1px', + // margin: `0 ${custom.spacing.x2}px 0 ${custom.spacing.x4}px`, + // }, + // '.ss__recommendation-bundle__wrapper__cta__subtotal, .ss__recommendation-bundle__wrapper__cta__button': { + // position: 'relative', + // zIndex: 2, + // }, + // '.ss__recommendation-bundle__wrapper__cta__subtotal': { + // color: variables?.colors?.text, + // '& > *': { + // margin: `0 0 ${custom.spacing.x2}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // '.ss__recommendation-bundle__wrapper__cta__subtotal__title': { + // display: 'block', + // fontWeight: custom.fonts.weight02, + // }, + // '.ss__recommendation-bundle__wrapper__cta__subtotal__prices': { + // margin: `${custom.spacing.x1}px 0 0 0`, + // label: { + // margin: 0, + // padding: 0, + // '& ~ label': { + // paddingLeft: `${custom.spacing.x1}px`, + // }, + // }, + // '.ss__recommendation-bundle__wrapper__cta__subtotal__strike': { + // color: lightGray, + // '*': { + // color: 'inherit', + // }, + // }, + // '.ss__recommendation-bundle__wrapper__cta__subtotal__price': { + // fontSize: '16px', + // fontWeight: custom.fonts.weight01, + // color: variables?.colors?.primary, + // '*': { + // color: 'inherit', + // }, + // }, + // }, + // }, + // '&:after': { + // content: '""', + // display: 'block', + // backgroundColor: custom.colors.gray01, + // border: `1px solid ${custom.colors.gray02}`, + // position: 'absolute', + // top: 0, + // left: '10px', + // right: 0, + // bottom: 0, + // zIndex: 1, + // margin: 'auto', + // }, + // }, + // [`@media (max-width: ${tabletBp}px)`]: { + // '.ss__recommendation-bundle__wrapper': { + // '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__cta': { + // width: `25%`, + // }, + // '.ss__recommendation-bundle__wrapper__carousel': { + // width: `50%`, + // }, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__recommendation-bundle__wrapper': { + // flexFlow: 'row wrap', + // width: 'auto', + // maxWidth: 'none', + // margin: `0 -${custom.spacing.x1}px`, + // '& > *': { + // padding: `0 ${custom.spacing.x1}px`, + // }, + // '.ss__recommendation-bundle__wrapper__seed-container, .ss__recommendation-bundle__wrapper__carousel': { + // width: `50%`, + // }, + // }, + // '.ss__recommendation-bundle__wrapper__cta': { + // width: 'auto', + // margin: `${custom.spacing.x4}px 0 0 0`, + // padding: `${custom.spacing.x4}px`, + // '& > *': { + // margin: 0, + // }, + // '&:after': { + // left: 0, + // }, + // }, + // }, + // [`@media (max-width: ${custom.breakpoints.small}px)`]: { + // '.ss__recommendation-bundle__title': { + // fontSize: '18px', + // }, + // }, + }); +}; + +// RecommendationBundle component props come from Template export +export const recommendationBundle: ThemeComponent<'recommendationBundle', RecommendationBundleProps> = { + default: { + ...recommendationBundleThemeComponentProps.default, + recommendationBundle: { + ...(recommendationBundleThemeComponentProps.default?.['recommendationBundle'] || {}), + themeStyleScript: recommendationBundleStyleScript, + }, + // 'recommendationBundle icon.bundle-cart': { + // size: `${custom.sizes.icon16 * 2}px`, + // width: `${custom.sizes.icon16 * 2}px`, + // height: `${custom.sizes.icon16 * 2}px`, + // icon: custom.icons.bag, + // fill: custom.colors.secondary, + // }, + // 'recommendationBundle icon.bundle-selector': { + // size: `${custom.sizes.icon14}px`, + // width: `${custom.sizes.icon14}px`, + // height: `${custom.sizes.icon14}px`, + // icon: custom.icons.plus, + // fill: custom.colors.secondary, + // }, + // 'recommendationBundle carousel': { + // spaceBetween: custom.spacing.x4, + // }, + }, + mobile: { + ...recommendationBundleThemeComponentProps.mobile, + 'recommendationBundle carousel': { + //spaceBetween: 0, + }, + }, + tablet: { + ...recommendationBundleThemeComponentProps.tablet, + 'recommendationBundle carousel': { + //spaceBetween: custom.spacing.x4, + }, + }, + desktop: { + ...recommendationBundleThemeComponentProps.desktop, + 'recommendationBundle carousel': { + //spaceBetween: custom.spacing.x4, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleEasyAdd.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleEasyAdd.ts new file mode 100644 index 0000000000..988c03c5d1 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleEasyAdd.ts @@ -0,0 +1,131 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleEasyAddProps } from '../../../../components/Templates/RecommendationBundleEasyAdd'; +import { recommendationBundleEasyAddThemeComponentProps } from '../../../themeComponents/recommendationBundleEasyAdd'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleEasyAdd component +const recommendationBundleEasyAddStyleScript = (props: RecommendationBundleEasyAddProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + // const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + // const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // margin: `${custom.spacing.x4}px 0`, + // ...custom.styles.boxSizing('recommendationBundleEasyAdd', props?.treePath, props?.name), + // '.ss__recommendation-profile-tracker': { + // '& > *': { + // margin: `0 0 ${custom.spacing.x4}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // }, + // '.ss__recommendation-bundle-easy-add__title': { + // fontSize: '18px', + // fontWeight: custom.fonts.weight02, + // color: variables?.colors?.secondary, + // }, + // '.ss__recommendation-bundle-easy-add__wrapper': { + // flexFlow: 'row nowrap', + // gap: `${custom.spacing.x4}px`, + // '& > div': { + // width: '50%', + // minWidth: '1px', + // flex: '0 1 auto', + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__selector__result-wrapper, .ss__recommendation-bundle-easy-add__wrapper__cta': { + // margin: 0, + // }, + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__cta': { + // padding: `${custom.spacing.x4}px`, + // width: 'auto', + // display: 'flex', + // flexFlow: 'column nowrap', + // justifyContent: 'center', + // alignItems: 'center', + // gap: `${custom.spacing.x4}px`, + // backgroundColor: custom.colors.gray01, + // border: `1px solid ${custom.colors.gray02}`, + // '& > *': { + // flex: '0 1 auto', + // minWidth: '1px', + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal': { + // color: variables?.colors?.text, + // '& > *': { + // margin: `0 0 ${custom.spacing.x2}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__title': { + // display: 'block', + // fontWeight: custom.fonts.weight02, + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__prices': { + // label: { + // margin: 0, + // padding: 0, + // '& ~ label': { + // paddingLeft: `${custom.spacing.x1}px`, + // }, + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__strike': { + // color: lightGray, + // '*': { + // color: 'inherit', + // }, + // }, + // '.ss__recommendation-bundle-easy-add__wrapper__cta__subtotal__price': { + // fontSize: '16px', + // fontWeight: custom.fonts.weight01, + // color: variables?.colors?.primary, + // '*': { + // color: 'inherit', + // }, + // }, + // }, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__recommendation-bundle-easy-add__wrapper': { + // flexFlow: 'row wrap', + // '& > div': { + // width: 'auto', + // flex: '1 1 100%', + // }, + // }, + // }, + }); +}; + +// RecommendationBundleEasyAdd component props come from Template export +export const recommendationBundleEasyAdd: ThemeComponent<'recommendationBundleEasyAdd', RecommendationBundleEasyAddProps> = { + default: { + ...recommendationBundleEasyAddThemeComponentProps.default, + recommendationBundleEasyAdd: { + ...(recommendationBundleEasyAddThemeComponentProps.default?.['recommendationBundleEasyAdd'] || {}), + themeStyleScript: recommendationBundleEasyAddStyleScript, + //ctaInline: true, + }, + // 'recommendationBundleEasyAdd icon.bundle-cart': { + // size: `${custom.sizes.icon16 * 2}px`, + // width: `${custom.sizes.icon16 * 2}px`, + // height: `${custom.sizes.icon16 * 2}px`, + // icon: custom.icons.bag, + // fill: custom.colors.secondary, + // }, + }, + mobile: { + ...recommendationBundleEasyAddThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleEasyAddThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleEasyAddThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleList.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleList.ts new file mode 100644 index 0000000000..63b13a7993 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleList.ts @@ -0,0 +1,172 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleListProps } from '../../../../components/Templates/RecommendationBundleList'; +import { recommendationBundleListThemeComponentProps } from '../../../themeComponents/recommendationBundleList'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleEasyAdd component +const recommendationBundleListStyleScript = (props: RecommendationBundleListProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + // const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + // const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // margin: `${custom.spacing.x4}px 0`, + // ...custom.styles.boxSizing('recommendationBundleList', props?.treePath, props?.name), + // '.ss__recommendation-profile-tracker': { + // '& > *': { + // margin: `0 0 ${custom.spacing.x4}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // }, + // '.ss__recommendation-bundle-list__title': { + // fontSize: '18px', + // fontWeight: custom.fonts.weight02, + // color: variables?.colors?.secondary, + // }, + // '.ss__recommendation-bundle-list__wrapper': { + // flexFlow: 'row wrap', + // margin: `0 -${custom.spacing.x1}px`, + // '& > div': { + // width: '50%', + // minWidth: '1px', + // flex: '0 1 auto', + // padding: `0 ${custom.spacing.x1}px`, + // margin: `0 0 ${custom.spacing.x2}px 0`, + // }, + // '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper': { + // margin: 0, + // gap: `${custom.spacing.x2}px`, + // '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper__checkbox, .ss__result': { + // minWidth: '1px', + // }, + // '.ss__recommendation-bundle-list__wrapper__selector__result-wrapper__checkbox': { + // flex: '0 1 auto', + // }, + // '.ss__result': { + // flex: '1 1 0%', + // '.ss__result__image-wrapper': { + // display: 'none', + // }, + // '.ss__result__details': { + // gap: 0, + // }, + // }, + // }, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta': { + // '.ss__recommendation-bundle-list__wrapper__cta__inner': { + // '& > *': { + // margin: `0 0 ${custom.spacing.x4}px 0`, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta__inner__images': { + // flexFlow: 'row nowrap', + // gap: `${custom.spacing.x2 + custom.sizes.icon12}px`, + // '.ss__recommendation-bundle-list__wrapper__cta__inner__image-wrapper': { + // flex: '1 1 0%', + // minWidth: '1px', + // padding: 0, + // '.ss__icon': { + // top: 0, + // bottom: 0, + // right: `-${custom.spacing.x2 / 2 + custom.sizes.icon12}px`, + // margin: 'auto 0', + // }, + // }, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta__subtotal': { + // padding: `${custom.spacing.x4}px`, + // backgroundColor: custom.colors.gray01, + // border: `1px solid ${custom.colors.gray02}`, + // '& > *': { + // margin: `0 0 ${custom.spacing.x2}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta__subtotal__title': { + // display: 'block', + // fontWeight: custom.fonts.weight02, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta__subtotal__prices': { + // margin: `${custom.spacing.x1}px 0 0 0`, + // label: { + // margin: 0, + // padding: 0, + // '& ~ label': { + // paddingLeft: `${custom.spacing.x1}px`, + // }, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta__subtotal__strike': { + // color: lightGray, + // '*': { + // color: 'inherit', + // }, + // }, + // '.ss__recommendation-bundle-list__wrapper__cta__subtotal__price': { + // fontSize: '16px', + // fontWeight: custom.fonts.weight01, + // color: variables?.colors?.primary, + // '*': { + // color: 'inherit', + // }, + // }, + // }, + // }, + // }, + // '.ss__recommendation-bundle-list__cta__button__wrapper': { + // margin: `${custom.spacing.x4}px 0`, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__recommendation-bundle-list__wrapper': { + // '& > div': { + // width: 'auto', + // flex: '1 1 100%', + // }, + // }, + // }, + }); +}; + +// RecommendationBundleList component props come from Template export +export const recommendationBundleList: ThemeComponent<'recommendationBundleList', RecommendationBundleListProps> = { + default: { + ...recommendationBundleListThemeComponentProps.default, + recommendationBundleList: { + ...(recommendationBundleListThemeComponentProps.default?.['recommendationBundleList'] || {}), + themeStyleScript: recommendationBundleListStyleScript, + //separatorIconSeedOnly: false, + }, + // 'recommendationBundleList icon.bundle-cart-separator': { + // size: `${custom.sizes.icon12}px`, + // width: `${custom.sizes.icon12}px`, + // height: `${custom.sizes.icon12}px`, + // icon: custom.icons.plus, + // fill: custom.colors.secondary, + // }, + // 'recommendationBundleList icon.bundle-cart': { + // size: `${custom.sizes.icon16 * 2}px`, + // width: `${custom.sizes.icon16 * 2}px`, + // height: `${custom.sizes.icon16 * 2}px`, + // icon: custom.icons.bag, + // fill: custom.colors.secondary, + // }, + // 'recommendationBundleList result': { + // hideImage: true, + // hideBadge: true, + // }, + }, + mobile: { + ...recommendationBundleListThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleListThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleListThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleVertical.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleVertical.ts new file mode 100644 index 0000000000..eaa43634cb --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationBundleVertical.ts @@ -0,0 +1,160 @@ +import { css } from '@emotion/react'; +import type { RecommendationBundleVerticalProps } from '../../../../components/Templates/RecommendationBundleVertical'; +import { recommendationBundleVerticalThemeComponentProps } from '../../../themeComponents/recommendationBundleVertical'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundleVertical component +const recommendationBundleVerticalStyleScript = (props: RecommendationBundleVerticalProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + // const lightGray = custom.utils.lightenColor(variables?.colors?.text, 0.65); + // const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // margin: `${custom.spacing.x4}px 0`, + // ...custom.styles.boxSizing('recommendationBundleVertical', props?.treePath, props?.name), + // '.ss__recommendation-profile-tracker': { + // '& > *': { + // margin: `0 0 ${custom.spacing.x4}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // }, + // '.ss__recommendation-bundle-vertical__title': { + // fontSize: '18px', + // fontWeight: custom.fonts.weight02, + // color: variables?.colors?.secondary, + // }, + // '.ss__recommendation-bundle-vertical__wrapper': { + // gap: `${custom.spacing.x4}px`, + // '& > div': { + // minWidth: '1px', + // flex: '1 1 100%', + // }, + // '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper': { + // margin: 0, + // '&, .ss__result': { + // position: 'relative', + // }, + // '&:has(.ss__overlay-badge)': { + // '.ss__result': { + // '.ss__overlay-badge .ss__overlay-badge__grid-wrapper': { + // top: '25px', + // }, + // }, + // }, + // '.ss__checkbox': { + // top: '5px', + // right: '5px', + // }, + // '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper__seed-badge': { + // top: '5px', + // left: '5px', + // backgroundColor: variables?.colors?.primary, + // fontSize: '14px', + // fontWeight: custom.fonts.weight01, + // lineHeight: `24px`, + // color: custom.colors.white, + // padding: `0 ${custom.spacing.x2}px`, + // }, + // }, + // }, + // '.ss__recommendation-bundle-vertical__wrapper__cta': { + // padding: `${custom.spacing.x4}px`, + // width: 'auto', + // display: 'flex', + // flexFlow: 'column nowrap', + // justifyContent: 'center', + // alignItems: 'center', + // gap: `${custom.spacing.x4}px`, + // backgroundColor: custom.colors.gray01, + // border: `1px solid ${custom.colors.gray02}`, + // '& > *': { + // flex: '0 1 auto', + // minWidth: '1px', + // }, + // '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal': { + // color: variables?.colors?.text, + // '& > *': { + // margin: `0 0 ${custom.spacing.x2}px 0`, + // '&:last-child': { + // marginBottom: 0, + // }, + // }, + // '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__title': { + // display: 'block', + // fontWeight: custom.fonts.weight02, + // }, + // '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__prices': { + // label: { + // margin: 0, + // padding: 0, + // '& ~ label': { + // paddingLeft: `${custom.spacing.x1}px`, + // }, + // }, + // '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__strike': { + // color: lightGray, + // '*': { + // color: 'inherit', + // }, + // }, + // '.ss__recommendation-bundle-vertical__wrapper__cta__subtotal__price': { + // fontSize: '16px', + // fontWeight: custom.fonts.weight01, + // color: variables?.colors?.primary, + // '*': { + // color: 'inherit', + // }, + // }, + // }, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__recommendation-bundle-vertical__wrapper': { + // '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper': { + // '.ss__recommendation-bundle-vertical__wrapper__selector__result-wrapper__seed-badge': { + // fontSize: '12px', + // lineHeight: `20px`, + // }, + // }, + // }, + // }, + }); +}; + +// RecommendationBundleVertical component props come from Template export +export const recommendationBundleVertical: ThemeComponent<'recommendationBundleVertical', RecommendationBundleVerticalProps> = { + default: { + ...recommendationBundleVerticalThemeComponentProps.default, + recommendationBundleVertical: { + ...(recommendationBundleVerticalThemeComponentProps.default?.['recommendationBundleVertical'] || {}), + themeStyleScript: recommendationBundleVerticalStyleScript, + }, + // 'recommendationBundleVertical icon.bundle-cart': { + // size: `${custom.sizes.icon16 * 2}px`, + // width: `${custom.sizes.icon16 * 2}px`, + // height: `${custom.sizes.icon16 * 2}px`, + // icon: custom.icons.bag, + // fill: custom.colors.secondary, + // }, + // 'recommendationBundleVertical icon.bundle-selector': { + // size: `${custom.sizes.icon16 * 2}px`, + // width: `${custom.sizes.icon16 * 2}px`, + // height: `${custom.sizes.icon16 * 2}px`, + // icon: custom.icons.plus, + // fill: custom.colors.secondary, + // }, + }, + mobile: { + ...recommendationBundleVerticalThemeComponentProps.mobile, + }, + tablet: { + ...recommendationBundleVerticalThemeComponentProps.tablet, + }, + desktop: { + ...recommendationBundleVerticalThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendationEmail.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationEmail.ts new file mode 100644 index 0000000000..21bef95938 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationEmail.ts @@ -0,0 +1,53 @@ +import { css } from '@emotion/react'; +import type { RecommendationEmailProps } from '../../../../components/Templates/RecommendationEmail'; +import { recommendationEmailThemeComponentProps } from '../../../themeComponents/recommendationEmail'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationEmail component +const recommendationEmailStyleScript = (props: RecommendationEmailProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + // width: '400px !important', + // height: '680px', + // margin: `0 0 ${custom.spacing.x6}px 0`, + // padding: `0 ${custom.spacing.x2}px`, + // overflow: 'hidden', + // ...custom.styles.boxSizing('recommendationEmail', props?.treePath, props?.name), + // '.ss__result': { + // fontSize: '16px', + // '.ss__result__details .ss__result__details__title a': { + // display: 'block', + // height: '26px', + // overflow: 'hidden', + // textOverflow: 'ellipsis', + // whiteSpace: 'nowrap', + // }, + // }, + }); +}; + +// RecommendationEmail component props come from Template export +export const recommendationEmail: ThemeComponent<'recommendationEmail', RecommendationEmailProps> = { + default: { + ...recommendationEmailThemeComponentProps.default, + recommendationEmail: { + ...(recommendationEmailThemeComponentProps.default?.['recommendationEmail'] || {}), + themeStyleScript: recommendationEmailStyleScript, + }, + // 'recommendationEmail image': { + // lazy: false, + // }, + }, + mobile: { + ...recommendationEmailThemeComponentProps.mobile, + }, + tablet: { + ...recommendationEmailThemeComponentProps.tablet, + }, + desktop: { + ...recommendationEmailThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/recommendationGrid.ts b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationGrid.ts new file mode 100644 index 0000000000..5e62dd3fa0 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/recommendationGrid.ts @@ -0,0 +1,74 @@ +import { css } from '@emotion/react'; +import type { RecommendationGridProps } from '../../../../components/Templates/RecommendationGrid'; +import { recommendationGridThemeComponentProps } from '../../../themeComponents/recommendationGrid'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the RecommendationBundle component +const recommendationGridStyleScript = (props: RecommendationGridProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + //const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // margin: `${custom.spacing.x8}px 0`, + // maxHeight: 'none', + // ...custom.styles.boxSizing('recommendationGrid', props?.treePath, props?.name), + // '.ss__recommendation-grid__title': { + // fontSize: '22px', + // fontWeight: custom.fonts.weight02, + // color: variables?.colors?.secondary, + // textAlign: 'center', + // margin: `0 0 ${custom.spacing.x4}px 0`, + // }, + // '.ss__recommendation-grid__results': { + // overflowX: 'auto', + // '&::-webkit-scrollbar': { + // width: '8px', + // height: '8px', + // }, + // '&::-webkit-scrollbar-track': { + // backgroundColor: custom.colors.gray01, + // }, + // '&::-webkit-scrollbar-thumb': { + // backgroundColor: custom.colors.gray02, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__recommendation-grid__title': { + // textAlign: 'left', + // }, + // }, + }); +}; + +// RecommendationGrid component props come from Template export +export const recommendationGrid: ThemeComponent<'recommendationGrid', RecommendationGridProps> = { + default: { + ...recommendationGridThemeComponentProps.default, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.default?.['recommendationGrid'] || {}), + themeStyleScript: recommendationGridStyleScript, + // gapSize: `${custom.spacing.x6}px ${custom.spacing.x4}px`, + // columns: 4, + }, + }, + mobile: { + ...recommendationGridThemeComponentProps.mobile, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.mobile?.['recommendationGrid'] || {}), + // gapSize: `${custom.spacing.x6}px ${custom.spacing.x2}px`, + // columns: 2, + }, + }, + tablet: { + ...recommendationGridThemeComponentProps.tablet, + recommendationGrid: { + ...(recommendationGridThemeComponentProps.tablet?.['recommendationGrid'] || {}), + //columns: 3, + }, + }, + desktop: { + ...recommendationGridThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/search.ts b/packages/snap-preact/components/src/themes/pike/components/templates/search.ts new file mode 100644 index 0000000000..b7504539a9 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/search.ts @@ -0,0 +1,77 @@ +import { css } from '@emotion/react'; +import type { SearchProps } from '../../../../components/Templates/Search'; +import { searchThemeComponentProps } from '../../../themeComponents/search'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchStyleScript = (props: SearchProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + //const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // ...custom.styles.boxSizing('search', props?.treePath, props?.name), + // '&.ss__search--sidebar-open .ss__button--sidebar-toggle-button-wrapper .ss__button': { + // '.ss__icon--filter': { + // transform: 'rotate(-180deg)', + // }, + // '.ss__icon--filters': { + // circle: { + // '&:last-child': { + // transform: 'translateX(-35%)', + // }, + // transform: 'translateX(35%)', + // }, + // }, + // }, + // '.ss__search__header-section, .ss__search__main-section': { + // margin: `0 0 ${custom.spacing.x6}px 0`, + // '.ss__toolbar .ss__layout': { + // gap: `${custom.spacing.x4}px`, + // }, + // }, + // '.ss__search__main-section': { + // gap: `${custom.spacing.x6}px`, + // '.ss__search__sidebar, .ss__search__content': { + // minWidth: '1px', + // }, + // '.ss__search__sidebar': { + // flex: '0 1 auto', + // }, + // '.ss__search__content': { + // flex: '1 1 0%', + // gap: `${custom.spacing.x4}px`, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__search__main-section': { + // '.ss__toolbar': { + // '.ss__select': { + // flex: '1 1 0%', + // }, + // }, + // }, + // }, + }); +}; + +// Search component props come from Template export +export const search: ThemeComponent<'search', SearchProps> = { + default: { + ...searchThemeComponentProps.default, + search: { + ...(searchThemeComponentProps.default?.['search'] || {}), + themeStyleScript: searchStyleScript, + }, + }, + mobile: { + ...searchThemeComponentProps.mobile, + }, + tablet: { + ...searchThemeComponentProps.tablet, + }, + desktop: { + ...searchThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/searchCollapsible.ts b/packages/snap-preact/components/src/themes/pike/components/templates/searchCollapsible.ts new file mode 100644 index 0000000000..53bfd5d6e1 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/searchCollapsible.ts @@ -0,0 +1,87 @@ +import { css } from '@emotion/react'; +import type { SearchCollapsibleProps } from '../../../../components/Templates/SearchCollapsible'; +import { searchCollapsibleThemeComponentProps } from '../../../themeComponents/searchCollapsible'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchCollapsibleStyleScript = (props: SearchCollapsibleProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + + return css({ + // ...custom.styles.boxSizing('searchCollapsible', props?.treePath, props?.name), + // '&.ss__search-collapsible--sidebar-open .ss__button--sidebar-toggle-button-wrapper .ss__button': { + // '.ss__icon--filter': { + // transform: 'rotate(-180deg)', + // }, + // '.ss__icon--filters': { + // circle: { + // '&:last-child': { + // transform: 'translateX(-35%)', + // }, + // transform: 'translateX(35%)', + // }, + // }, + // }, + // '.ss__search-collapsible__header-section, .ss__search-collapsible__main-section': { + // margin: `0 0 ${custom.spacing.x6}px 0`, + // '.ss__toolbar .ss__layout': { + // gap: `${custom.spacing.x4}px`, + // }, + // }, + // '.ss__search-collapsible__header-section': { + // '.ss__search-header': { + // textAlign: 'center', + // }, + // }, + // '.ss__search-collapsible__main-section': { + // gap: `${custom.spacing.x6}px`, + // '.ss__search-collapsible__sidebar, .ss__search-collapsible__content': { + // minWidth: '1px', + // }, + // '.ss__search-collapsible__sidebar': { + // flex: '0 1 auto', + // }, + // '.ss__search-collapsible__content': { + // flex: '1 1 0%', + // gap: `${custom.spacing.x4}px`, + // }, + // }, + // [`@media (max-width: ${custom.breakpoints.small}px)`]: { + // '.ss__toolbar': { + // '.ss__pagination-info': { + // fontSize: '16px', + // }, + // }, + // }, + }); +}; + +export const searchCollapsible: ThemeComponent<'searchCollapsible', SearchCollapsibleProps> = { + default: { + ...searchCollapsibleThemeComponentProps.default, + searchCollapsible: { + ...(searchCollapsibleThemeComponentProps.default?.['searchCollapsible'] || {}), + themeStyleScript: searchCollapsibleStyleScript, + }, + // 'searchCollapsible sidebar': { + // hideTitleText: true, + // }, + // 'searchCollapsible button.sidebar-toggle': { + // icon: custom.icons.filter, + // }, + // 'searchCollapsible filterSummary': { + // type: 'list', + // }, + }, + mobile: { + ...searchCollapsibleThemeComponentProps.mobile, + }, + tablet: { + ...searchCollapsibleThemeComponentProps.tablet, + }, + desktop: { + ...searchCollapsibleThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/components/templates/searchHorizontal.ts b/packages/snap-preact/components/src/themes/pike/components/templates/searchHorizontal.ts new file mode 100644 index 0000000000..e5d1832917 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/components/templates/searchHorizontal.ts @@ -0,0 +1,93 @@ +import { css } from '@emotion/react'; +import type { SearchHorizontalProps } from '../../../../components/Templates/SearchHorizontal'; +import { searchHorizontalThemeComponentProps } from '../../../themeComponents/searchHorizontal'; +import { ThemeComponent } from '../../../../providers'; +//import { custom } from '../../custom'; + +// CSS in JS style script for the Search component +const searchHorizontalStyleScript = (props: SearchHorizontalProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const variables = props?.theme?.variables; + //const mobileBp = variables?.breakpoints?.mobile || custom.breakpoints.mobile; + + return css({ + // ...custom.styles.boxSizing('searchHorizontal', props?.treePath, props?.name), + // '&.ss__search-horizontal--sidebar-open .ss__button--sidebar-toggle-button-wrapper .ss__button': { + // '.ss__icon--filter': { + // transform: 'rotate(-180deg)', + // }, + // '.ss__icon--filters': { + // circle: { + // '&:last-child': { + // transform: 'translateX(-35%)', + // }, + // transform: 'translateX(35%)', + // }, + // }, + // }, + // '.ss__search-horizontal__header-section, .ss__search-horizontal__main-section': { + // margin: `0 0 ${custom.spacing.x6}px 0`, + // '.ss__toolbar .ss__layout': { + // gap: `${custom.spacing.x4}px`, + // '.ss__layout__row': { + // '&:has(.ss__facets-horizontal)': { + // alignItems: 'flex-start', + // '& > *': { + // minWidth: '1px', + // flex: '0 1 auto', + // }, + // '.ss__facets-horizontal': { + // flex: '1 1 0%', + // }, + // }, + // }, + // }, + // }, + // '.ss__search-horizontal__header-section': { + // '.ss__search-header': { + // textAlign: 'center', + // }, + // }, + // '.ss__search-horizontal__main-section': { + // gap: `${custom.spacing.x6}px`, + // '.ss__search-horizontal__sidebar, .ss__search-horizontal__content': { + // minWidth: '1px', + // }, + // '.ss__search-horizontal__sidebar': { + // flex: '0 1 auto', + // }, + // '.ss__search-horizontal__content': { + // flex: '1 1 0%', + // gap: `${custom.spacing.x4}px`, + // }, + // }, + // [`@media (max-width: ${mobileBp}px)`]: { + // '.ss__search-horizontal__main-section': { + // '.ss__toolbar': { + // '.ss__select': { + // flex: '1 1 0%', + // }, + // }, + // }, + // }, + }); +}; + +export const searchHorizontal: ThemeComponent<'searchHorizontal', SearchHorizontalProps> = { + default: { + ...searchHorizontalThemeComponentProps.default, + searchHorizontal: { + ...(searchHorizontalThemeComponentProps.default?.['searchHorizontal'] || {}), + themeStyleScript: searchHorizontalStyleScript, + }, + }, + mobile: { + ...searchHorizontalThemeComponentProps.mobile, + }, + tablet: { + ...searchHorizontalThemeComponentProps.tablet, + }, + desktop: { + ...searchHorizontalThemeComponentProps.desktop, + }, +}; diff --git a/packages/snap-preact/components/src/themes/pike/custom.ts b/packages/snap-preact/components/src/themes/pike/custom.ts new file mode 100644 index 0000000000..966a5cb30a --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/custom.ts @@ -0,0 +1,268 @@ +import { IconType } from '../../components/Atoms/Icon'; +import Color from 'color'; + +// calculate spacing +const spacing = 5; +const spacingCalc = (value: number) => { + return spacing * value; +}; + +// custom theme object +// contains defaults, colors, utils, global styles, etc. +export const custom: CustomThemeType = { + breakpoints: { + small: 540, + mobile: 767, + tablet: 991, + desktop: 1199, + }, + colors: { + text: '#515151', // theme color + primary: '#00aeef', // theme color + secondary: '#1d4990', // theme color + accent: '#2154a5', // theme color + white: '#ffffff', + black: '#000000', + gray01: '#f8f8f8', // lighter gray: bg color under terms, dropdown, checkboxes + gray02: '#ebebeb', // light gray: borders for autocomplete, dropdown, checkboxes + }, + fonts: { + weight01: 700, // main font weight + weight02: 700, // header font weight + style: false, + transform: 'none', + }, + icons: { + arrowLeft: 'chevron-left', + arrowRight: 'chevron-right', + arrowDown: 'chevron-down', + arrowUp: 'chevron-up', + bag: 'bag', + check: 'square', + close: 'close', + minus: 'minus', + plus: 'plus', + filter: 'filter', + search: 'search', + sort: 'sort', + }, + sizes: { + font: 16, // base font size + height: 35, // refers to height for button and dropdown sizes + icon08: 8, + icon10: 10, + icon12: 12, + icon14: 14, + icon16: 16, + radius: 0, // global border radius value + }, + spacing: { + x1: spacing, + x2: spacingCalc(2), + x3: spacingCalc(3), + x4: spacingCalc(4), + x5: spacingCalc(5), + x6: spacingCalc(6), + x7: spacingCalc(7), + x8: spacingCalc(8), + }, + styles: { + activeText: (value?: string) => { + // active text styles + return { + '&, &:hover': { + fontWeight: custom?.fonts?.weight01, + color: value ? value : '', + }, + }; + }, + badgeText: (value: number) => { + // badge text styles + return { + display: 'block', + fontSize: value, + lineHeight: 1.2, + }; + }, + borderRadius: (value?: number, unit?: string) => { + const hasValue = value || value === 0 ? true : false; + value = hasValue ? value : custom.sizes.radius; + unit = unit ? unit : value === 0 ? '' : 'px'; + + // sets border radius + return { + borderRadius: hasValue || custom.sizes.radius ? `${value}${unit}` : ``, + }; + }, + box: (text?: string, paddingValue?: number | string, radius?: boolean) => { + // styles for box designs + + // define padding value + let padding = `${custom.spacing.x2}px` as number | string; + if (paddingValue) { + padding = paddingValue; + } else if (paddingValue === 0) { + padding = ''; + } + + // check if radius setting is available + const hasRadius = typeof radius == 'boolean' ? radius : true; + + // radius style if available + const radiusStyle = hasRadius && custom.sizes.radius ? custom.styles.borderRadius() : null; + + return { + border: `1px solid ${custom.colors.gray02}`, + ...radiusStyle, + backgroundColor: custom.colors.gray01, + color: text ? text : '', + padding: padding, + }; + }, + boxSizing: (component: string, treePath?: string, name?: string) => { + treePath = treePath ? treePath : component; + component = name ? `${component}.${name}` : component; // if name is present, add to component + + // box-sizing rules for uniform sizing + // if path and component are same, apply box-sizing + // if they are not the same, this means some parent component will have the box sizing rules + if (treePath == component) { + return { + '&, *, *:before, *:after': { + boxSizing: 'border-box', + }, + }; + } else { + return null; + } + }, + disabled: () => { + // disabled styles + return { + opacity: 0.65, + cursor: 'not-allowed !important', + pointerEvents: 'unset', + }; + }, + headerText: (value?: string, size?: string) => { + // header text styles + return { + fontSize: size ? size : '', + fontWeight: custom?.fonts?.weight02, + textTransform: custom?.fonts?.transform, + color: value ? value : '', + }; + }, + scrollbar: () => { + // scrollbar styles + return { + '&::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '&::-webkit-scrollbar-track': { + backgroundColor: custom.colors.gray01, + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: custom.colors.gray02, + }, + }; + }, + srOnly: () => { + // screen reader only styles + return { + position: 'absolute', + width: '1px', + height: '1px', + padding: 0, + margin: '-1px', + overflow: 'hidden', + clip: 'rect(0, 0, 0, 0)', + }; + }, + textOverflow: () => { + // text overflow styles + return { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }; + }, + }, + utils: { + activeColors: (color?: string) => { + // get active color and related font color + color = color ? color : custom.colors.primary; + const whiteColor = new Color(custom.colors.white); + const blackColor = new Color(custom.colors.black); + const activeColor = new Color(color); + const accentColor = activeColor.isDark() || activeColor.hex().toLowerCase() == custom.colors.primary ? whiteColor : blackColor; + return [activeColor.hex().toLowerCase(), accentColor.hex().toLowerCase()]; + }, + lightenColor: (color?: string, amount?: number) => { + // lighten a color + amount = amount ? amount : 0.65; + color = color ? color : custom.colors.text; + const lightColor = new Color(color).lighten(amount).hex().toLowerCase(); + return lightColor; + }, + darkenColor: (color?: string, amount?: number) => { + // darken a color + amount = amount ? amount : 0.075; + color = color ? color : custom.colors.gray02; + const darkColor = new Color(color).darken(amount).hex().toLowerCase(); + return darkColor; + }, + }, +}; + +// types for custom theme object +type ObjectAnyType = { + [key: string]: any; +}; + +type ObjectIconType = { + [key: string]: IconType; +}; + +type ObjectNestedType = { + [key: string]: ObjectNumberOrStringType; +}; + +type ObjectNumberType = { + [key: string]: number; +}; + +type ObjectNumberOrStringType = { + [key: string]: number | string; +}; + +type ObjectStringType = { + [key: string]: string; +}; + +type CustomThemeType = { + breakpoints: ObjectNumberType; + colors: ObjectStringType; + fonts: ObjectAnyType; + icons: ObjectIconType; + sizes: ObjectNumberType; + spacing: ObjectNumberType; + styles: { + activeText: (value?: string) => ObjectNestedType; + badgeText: (value: number) => ObjectNumberOrStringType; + borderRadius: (value?: number, unit?: string) => ObjectStringType | null; + box: (text?: string, paddingValue?: number | string, radius?: boolean) => ObjectNumberOrStringType; + boxSizing: (component: string, treePath?: string, name?: string) => ObjectNestedType | null; + disabled: () => ObjectNumberOrStringType; + headerText: (value?: string, size?: string) => ObjectNumberOrStringType; + scrollbar: () => ObjectNestedType; + srOnly: () => ObjectNumberOrStringType; + textOverflow: () => ObjectNumberOrStringType; + }; + utils: { + activeColors: (color?: string) => string[]; + lightenColor: (color?: string, amount?: number) => string; + darkenColor: (color?: string, amount?: number) => string; + }; +}; diff --git a/packages/snap-preact/components/src/themes/pike/pike.ts b/packages/snap-preact/components/src/themes/pike/pike.ts new file mode 100644 index 0000000000..cf08d19a76 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/pike.ts @@ -0,0 +1,25 @@ +import { ThemeComplete, ThemeVariables } from '../../providers'; +import { components } from './components'; +import { responsive } from './responsive'; +import { custom } from './custom'; + +const pikeVariables: ThemeVariables = { + breakpoints: { + mobile: custom.breakpoints.mobile, + tablet: custom.breakpoints.tablet, + desktop: custom.breakpoints.desktop, + }, + colors: { + text: custom.colors.text, + primary: custom.colors.primary, + secondary: custom.colors.secondary, + accent: custom.colors.accent, + }, +}; + +export const pike: ThemeComplete = { + name: 'pike', + variables: pikeVariables, + components, + responsive, +}; diff --git a/packages/snap-preact/components/src/themes/pike/responsive.ts b/packages/snap-preact/components/src/themes/pike/responsive.ts new file mode 100644 index 0000000000..61ae08bfe4 --- /dev/null +++ b/packages/snap-preact/components/src/themes/pike/responsive.ts @@ -0,0 +1,8 @@ +import { ThemeResponsive } from '../../providers/theme'; +import { mobileComponents, tabletComponents, desktopComponents } from './components'; + +export const responsive: ThemeResponsive = { + mobile: mobileComponents, + tablet: tabletComponents, + desktop: desktopComponents, +}; diff --git a/packages/snap-preact/components/src/themes/snapnco/components/molecules/checkbox.ts b/packages/snap-preact/components/src/themes/snapnco/components/molecules/checkbox.ts index ffd9898a5e..85d07d096d 100644 --- a/packages/snap-preact/components/src/themes/snapnco/components/molecules/checkbox.ts +++ b/packages/snap-preact/components/src/themes/snapnco/components/molecules/checkbox.ts @@ -6,7 +6,7 @@ import { ThemeComponent } from '../../../../providers'; // CSS in JS style script for the Checkbox component const checkboxStyleScript = ({ color, theme }: CheckboxProps) => { const variables = theme?.variables; - const backgroundColorObj = new Color(color || variables?.colors.primary); + const backgroundColorObj = new Color(color || variables?.colors.primary || undefined); const backgroundTextColorObj = backgroundColorObj.isDark() ? new Color('#fff') : new Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/snapnco/components/molecules/facetGridOptions.ts b/packages/snap-preact/components/src/themes/snapnco/components/molecules/facetGridOptions.ts index dab3894178..58f32f712a 100644 --- a/packages/snap-preact/components/src/themes/snapnco/components/molecules/facetGridOptions.ts +++ b/packages/snap-preact/components/src/themes/snapnco/components/molecules/facetGridOptions.ts @@ -6,7 +6,7 @@ import { ThemeComponent } from '../../../../providers'; // CSS in JS style script for the FacetGridOptions component const facetGridOptionsStyleScript = ({ theme }: FacetGridOptionsProps) => { const variables = theme?.variables; - const backgroundColorObj = new Color(variables?.colors.primary); + const backgroundColorObj = new Color(variables?.colors.primary || undefined); const colorObj = backgroundColorObj.isDark() ? new Color('#fff') : new Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/snapnco/components/molecules/loadMore.ts b/packages/snap-preact/components/src/themes/snapnco/components/molecules/loadMore.ts index 4b3d911f7d..c7424eab75 100644 --- a/packages/snap-preact/components/src/themes/snapnco/components/molecules/loadMore.ts +++ b/packages/snap-preact/components/src/themes/snapnco/components/molecules/loadMore.ts @@ -7,7 +7,7 @@ import { ThemeComponent } from '../../../../providers'; const loadMoreStyleScript = ({ color, backgroundColor, theme }: LoadMoreProps) => { const variables = theme?.variables; - const barColour = new Color(color || variables?.colors.accent); + const barColour = new Color(color || variables?.colors.accent || undefined); const backgroundColour = backgroundColor ? new Color(backgroundColor) : barColour.lightness(90); return css({ diff --git a/packages/snap-preact/components/src/themes/snapnco/components/molecules/select.ts b/packages/snap-preact/components/src/themes/snapnco/components/molecules/select.ts index 7541ff95b2..04bb584c57 100644 --- a/packages/snap-preact/components/src/themes/snapnco/components/molecules/select.ts +++ b/packages/snap-preact/components/src/themes/snapnco/components/molecules/select.ts @@ -5,7 +5,7 @@ import { ThemeComponent } from '../../../../providers'; // CSS in JS style script for the Select component const selectStyleScript = ({ backgroundColor, theme }: SelectProps) => { const variables = theme?.variables; - const transparentSecondary = new Color(theme?.variables?.colors?.secondary).opaquer(0.2); + const transparentSecondary = new Color(theme?.variables?.colors?.secondary || undefined).opaquer(0.2); return css({ '.ss__dropdown': { '.ss__select__dropdown__button': { diff --git a/packages/snap-preact/components/src/themes/snapnco/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/snapnco/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..abeed134dc --- /dev/null +++ b/packages/snap-preact/components/src/themes/snapnco/components/organisms/autocomplete.ts @@ -0,0 +1,22 @@ +import { css } from '@emotion/react'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; + +// CSS in JS style script for the Search component +const autocompleteStyleScript = ({}: AutocompleteProps) => { + return css({}); +}; + +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + ...(autocompleteThemeComponentProps.default?.['autocomplete'] || {}), + themeStyleScript: autocompleteStyleScript, + }, + }, + mobile: autocompleteThemeComponentProps.mobile, + desktop: autocompleteThemeComponentProps.desktop, + tablet: autocompleteThemeComponentProps.tablet, +}; diff --git a/packages/snap-preact/components/src/themes/snapnco/components/organisms/index.ts b/packages/snap-preact/components/src/themes/snapnco/components/organisms/index.ts index 257776ad6e..598caab613 100644 --- a/packages/snap-preact/components/src/themes/snapnco/components/organisms/index.ts +++ b/packages/snap-preact/components/src/themes/snapnco/components/organisms/index.ts @@ -9,9 +9,11 @@ import { noResults } from './noResults'; import { sidebar } from './sidebar'; import { termsList } from './termsList'; import { toolbar } from './toolbar'; +import { autocomplete } from './autocomplete'; export const organisms: ThemeResponsiveComplete = { default: { + ...autocomplete.default, ...facet.default, ...facetsHorizontal.default, ...filterSummary.default, @@ -22,6 +24,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.default, }, mobile: { + ...autocomplete.mobile, ...facet.mobile, ...facetsHorizontal.mobile, ...filterSummary.mobile, @@ -32,6 +35,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.mobile, }, tablet: { + ...autocomplete.tablet, ...facet.tablet, ...facetsHorizontal.tablet, ...filterSummary.tablet, @@ -42,6 +46,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.tablet, }, desktop: { + ...autocomplete.desktop, ...facet.desktop, ...facetsHorizontal.desktop, ...filterSummary.desktop, diff --git a/packages/snap-preact/components/src/themes/snappy/components/molecules/checkbox.ts b/packages/snap-preact/components/src/themes/snappy/components/molecules/checkbox.ts index 070279010e..eacea51459 100644 --- a/packages/snap-preact/components/src/themes/snappy/components/molecules/checkbox.ts +++ b/packages/snap-preact/components/src/themes/snappy/components/molecules/checkbox.ts @@ -5,7 +5,7 @@ import { ThemeComponent } from '../../../../providers'; // CSS in JS style script for the Checkbox component const checkboxStyleScript = ({ color, theme }: CheckboxProps) => { const variables = theme?.variables; - const backgroundColorObj = new Color(color || variables?.colors.primary); + const backgroundColorObj = new Color(color || variables?.colors.primary || undefined); const backgroundTextColorObj = backgroundColorObj.isDark() ? new Color('#fff') : new Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/snappy/components/molecules/facetGridOptions.ts b/packages/snap-preact/components/src/themes/snappy/components/molecules/facetGridOptions.ts index 02931aac1b..614656f38e 100644 --- a/packages/snap-preact/components/src/themes/snappy/components/molecules/facetGridOptions.ts +++ b/packages/snap-preact/components/src/themes/snappy/components/molecules/facetGridOptions.ts @@ -5,7 +5,7 @@ import { ThemeComponent } from '../../../../providers'; // CSS in JS style script for the FacetGridOptions component const facetGridOptionsStyleScript = ({ theme }: FacetGridOptionsProps) => { const variables = theme?.variables; - const backgroundColorObj = new Color(variables?.colors.primary); + const backgroundColorObj = new Color(variables?.colors.primary || undefined); const colorObj = backgroundColorObj.isDark() ? new Color('#fff') : new Color('#000'); return css({ diff --git a/packages/snap-preact/components/src/themes/snappy/components/molecules/loadMore.ts b/packages/snap-preact/components/src/themes/snappy/components/molecules/loadMore.ts index d8b6ac091e..806306731f 100644 --- a/packages/snap-preact/components/src/themes/snappy/components/molecules/loadMore.ts +++ b/packages/snap-preact/components/src/themes/snappy/components/molecules/loadMore.ts @@ -6,8 +6,8 @@ import { ThemeComponent } from '../../../../providers'; const loadMoreStyleScript = ({ color, backgroundColor, theme }: LoadMoreProps) => { const variables = theme?.variables; - const barColour = new Color(color || variables?.colors.accent); - const backgroundColour = backgroundColor ? new Color(backgroundColor) : barColour.lightness(90); + const barColour = new Color(color || variables?.colors.accent || undefined); + const backgroundColour = backgroundColor ? new Color(backgroundColor || undefined) : barColour.lightness(90); return css({ '.ss__button': { diff --git a/packages/snap-preact/components/src/themes/snappy/components/molecules/select.ts b/packages/snap-preact/components/src/themes/snappy/components/molecules/select.ts index 7541ff95b2..04bb584c57 100644 --- a/packages/snap-preact/components/src/themes/snappy/components/molecules/select.ts +++ b/packages/snap-preact/components/src/themes/snappy/components/molecules/select.ts @@ -5,7 +5,7 @@ import { ThemeComponent } from '../../../../providers'; // CSS in JS style script for the Select component const selectStyleScript = ({ backgroundColor, theme }: SelectProps) => { const variables = theme?.variables; - const transparentSecondary = new Color(theme?.variables?.colors?.secondary).opaquer(0.2); + const transparentSecondary = new Color(theme?.variables?.colors?.secondary || undefined).opaquer(0.2); return css({ '.ss__dropdown': { '.ss__select__dropdown__button': { diff --git a/packages/snap-preact/components/src/themes/snappy/components/organisms/autocomplete.ts b/packages/snap-preact/components/src/themes/snappy/components/organisms/autocomplete.ts new file mode 100644 index 0000000000..abeed134dc --- /dev/null +++ b/packages/snap-preact/components/src/themes/snappy/components/organisms/autocomplete.ts @@ -0,0 +1,22 @@ +import { css } from '@emotion/react'; +import { autocompleteThemeComponentProps } from '../../../themeComponents/autocomplete'; +import { ThemeComponent } from '../../../../providers'; +import { AutocompleteProps } from '../../../../components/Organisms/Autocomplete'; + +// CSS in JS style script for the Search component +const autocompleteStyleScript = ({}: AutocompleteProps) => { + return css({}); +}; + +export const autocomplete: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + ...autocompleteThemeComponentProps.default, + autocomplete: { + ...(autocompleteThemeComponentProps.default?.['autocomplete'] || {}), + themeStyleScript: autocompleteStyleScript, + }, + }, + mobile: autocompleteThemeComponentProps.mobile, + desktop: autocompleteThemeComponentProps.desktop, + tablet: autocompleteThemeComponentProps.tablet, +}; diff --git a/packages/snap-preact/components/src/themes/snappy/components/organisms/index.ts b/packages/snap-preact/components/src/themes/snappy/components/organisms/index.ts index 257776ad6e..598caab613 100644 --- a/packages/snap-preact/components/src/themes/snappy/components/organisms/index.ts +++ b/packages/snap-preact/components/src/themes/snappy/components/organisms/index.ts @@ -9,9 +9,11 @@ import { noResults } from './noResults'; import { sidebar } from './sidebar'; import { termsList } from './termsList'; import { toolbar } from './toolbar'; +import { autocomplete } from './autocomplete'; export const organisms: ThemeResponsiveComplete = { default: { + ...autocomplete.default, ...facet.default, ...facetsHorizontal.default, ...filterSummary.default, @@ -22,6 +24,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.default, }, mobile: { + ...autocomplete.mobile, ...facet.mobile, ...facetsHorizontal.mobile, ...filterSummary.mobile, @@ -32,6 +35,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.mobile, }, tablet: { + ...autocomplete.tablet, ...facet.tablet, ...facetsHorizontal.tablet, ...filterSummary.tablet, @@ -42,6 +46,7 @@ export const organisms: ThemeResponsiveComplete = { ...termsList.tablet, }, desktop: { + ...autocomplete.desktop, ...facet.desktop, ...facetsHorizontal.desktop, ...filterSummary.desktop, diff --git a/packages/snap-preact/components/src/themes/themeComponents/autocomplete.ts b/packages/snap-preact/components/src/themes/themeComponents/autocomplete.ts new file mode 100644 index 0000000000..c3c692e90b --- /dev/null +++ b/packages/snap-preact/components/src/themes/themeComponents/autocomplete.ts @@ -0,0 +1,73 @@ +import { AutocompleteProps } from '../../components/Organisms/Autocomplete'; +import { ThemeComponent } from '../../providers'; + +export const autocompleteThemeComponentProps: ThemeComponent<'autocomplete', AutocompleteProps> = { + default: { + 'autocomplete facet': { + // valueProps, + previewOnFocus: true, + limit: 6, + disableOverflow: true, + disableCollapse: true, + searchable: false, + }, + 'autocomplete facetGridOptions': { + // onClick: facetClickEvent, + columns: 3, + }, + 'autocomplete facetHierarchyOptions': { + // onClick: facetClickEvent, + hideCount: true, + }, + 'autocomplete facetListOptions': { + // onClick: facetClickEvent, + hideCheckbox: true, + hideCount: true, + }, + 'autocomplete facetPaletteOptions': { + // onClick: facetClickEvent, + hideLabel: true, + columns: 3, + }, + 'autocomplete result': { + hideBadge: true, + hideVariantSelections: true, + }, + 'autocomplete recommendationGrid': { + columns: 4, + rows: 2, + }, + }, + mobile: { + 'autocomplete results': { + columns: 2, + rows: 1, + }, + + 'autocomplete recommendationGrid': { + columns: 2, + rows: 1, + }, + 'autocomplete searchInput': { + closeSearchButton: { + icon: 'angle-left', + }, + }, + }, + tablet: { + 'autocomplete results': { + columns: 3, + rows: 1, + }, + }, + desktop: { + 'autocomplete results': { + columns: 2, + rows: 2, + }, + 'autocomplete recommendationGrid': { + columns: 3, + rows: 2, + }, + }, +}; diff --git a/packages/snap-preact/components/src/themes/themeComponents/autocompleteFixed.ts b/packages/snap-preact/components/src/themes/themeComponents/autocompleteFixed.ts index 0ff70fee53..aecc7d6125 100644 --- a/packages/snap-preact/components/src/themes/themeComponents/autocompleteFixed.ts +++ b/packages/snap-preact/components/src/themes/themeComponents/autocompleteFixed.ts @@ -40,11 +40,7 @@ export const autocompleteFixedThemeComponentProps: ThemeComponent<'autocompleteF }, mobile: { autocompleteFixed: { - layout: [['c1']], - column1: { - layout: [['termsList'], ['content'], ['_', 'button.see-more']], - width: '100%', - }, + layout: 'mini', }, 'autocompleteFixed results': { columns: 2, diff --git a/packages/snap-preact/components/src/themes/themeComponents/autocompleteModal.ts b/packages/snap-preact/components/src/themes/themeComponents/autocompleteModal.ts index 6249316d3a..da24ac9913 100644 --- a/packages/snap-preact/components/src/themes/themeComponents/autocompleteModal.ts +++ b/packages/snap-preact/components/src/themes/themeComponents/autocompleteModal.ts @@ -40,11 +40,7 @@ export const autocompleteModalThemeComponentProps: ThemeComponent<'autocompleteM }, mobile: { autocompleteModal: { - layout: [['c1']], - column1: { - layout: [['termsList'], ['content'], ['_', 'button.see-more']], - width: '100%', - }, + layout: 'mini', }, 'autocompleteModal results': { columns: 2, diff --git a/packages/snap-preact/components/src/themes/themeComponents/autocompleteSlideout.ts b/packages/snap-preact/components/src/themes/themeComponents/autocompleteSlideout.ts index 4a98292b8a..2ec14ce7de 100644 --- a/packages/snap-preact/components/src/themes/themeComponents/autocompleteSlideout.ts +++ b/packages/snap-preact/components/src/themes/themeComponents/autocompleteSlideout.ts @@ -44,11 +44,7 @@ export const autocompleteSlideoutThemeComponentProps: ThemeComponent<'autocomple }, mobile: { autocompleteSlideout: { - layout: [['c1']], - column1: { - layout: [['button.see-more'], ['termsList'], ['content']], - width: '100%', - }, + layout: 'mini', }, 'autocompleteSlideout recommendationGrid': { columns: 2, diff --git a/packages/snap-preact/components/src/themes/themeComponents/searchHorizontal.ts b/packages/snap-preact/components/src/themes/themeComponents/searchHorizontal.ts index 68113cf6d1..16fd5a3619 100644 --- a/packages/snap-preact/components/src/themes/themeComponents/searchHorizontal.ts +++ b/packages/snap-preact/components/src/themes/themeComponents/searchHorizontal.ts @@ -5,25 +5,27 @@ export const searchHorizontalThemeComponentProps: ThemeComponent<'searchHorizont default: { searchHorizontal: { hideSidebar: true, - internalClassName: 'ss__search-horizontal', }, 'searchHorizontal toolbar.top': { - layout: [['banner.header'], ['searchHeader'], ['banner.banner'], ['filterSummary'], ['paginationInfo', '_', 'sortBy', 'perPage']], + layout: [['searchHeader'], ['banner.header']], }, 'searchHorizontal toolbar.middle': { - layout: ['facetsHorizontal'], + layout: [['filterSummary'], ['facetsHorizontal'], ['paginationInfo', '_', 'sortBy', 'perPage'], ['banner.banner']], }, 'searchHorizontal toolbar.bottom': { - layout: [['banner.footer'], ['_', 'pagination']], + layout: [['banner.footer'], ['_', 'pagination', '_']], }, 'searchHorizontal facetsHorizontal': { limit: 9, }, + 'searchHorizontal mobileSidebar': { + layout: ['filterSummary', 'facets', 'banner.left'], + }, }, mobile: { - 'searchHorizontal toolbar.top': { - layout: [['banner.header'], ['searchHeader'], ['banner.banner'], ['paginationInfo', '_'], ['filterSummary'], ['_', 'sortBy', 'perPage']], + 'searchHorizontal toolbar.middle': { + layout: [['paginationInfo', '_', 'mobileSidebar'], ['sortBy', 'perPage'], ['banner.banner']], }, 'searchHorizontal facetsHorizontal': { limit: 4, diff --git a/packages/snap-preact/components/src/utilities/mergeProps.ts b/packages/snap-preact/components/src/utilities/mergeProps.ts index ad0ef47dcd..849e338d62 100644 --- a/packages/snap-preact/components/src/utilities/mergeProps.ts +++ b/packages/snap-preact/components/src/utilities/mergeProps.ts @@ -107,11 +107,12 @@ export function mergeProps( mergedProps.theme.variables = globalTheme.variables; } - //if custom component, re-spread props again - if (treePath && treePath.indexOf('customComponent') > -1) { + // if custom component, re-spread props again + if (treePath && (treePath.indexOf('customComponent') > -1 || treePath.startsWith('storybook'))) { mergedProps = { ...mergedProps, ...props, + treePath, }; } } diff --git a/packages/snap-preact/components/src/utilities/snapify.ts b/packages/snap-preact/components/src/utilities/snapify.ts index 0c5e69c79a..bcaaf55234 100644 --- a/packages/snap-preact/components/src/utilities/snapify.ts +++ b/packages/snap-preact/components/src/utilities/snapify.ts @@ -27,7 +27,7 @@ const controllers: { } = {}; const client = { - globals: { siteId: '8uyt2m' }, + globals: { siteId: 'atkzs2' }, }; export class Snapify { diff --git a/packages/snap-preact/components/tests/cypress/component/molecules/swatches.cy.tsx b/packages/snap-preact/components/tests/cypress/component/molecules/swatches.cy.tsx index 5b22fea65c..ca63b815f4 100644 --- a/packages/snap-preact/components/tests/cypress/component/molecules/swatches.cy.tsx +++ b/packages/snap-preact/components/tests/cypress/component/molecules/swatches.cy.tsx @@ -287,7 +287,7 @@ describe('Swatches Component', async () => { cy.get('.ss__swatches__grid').should('exist'); cy.get('.ss__grid__option').should('have.length', defaultColumns); - cy.get('.ss__grid__option').should('satisfy', ($el) => { + cy.get('.ss__grid__option .ss__grid__option__inner').should('satisfy', ($el) => { for (let i = 0; i < $el.length; i++) { const backgroundStyle = $el[i].style.background; return backgroundStyle == options[i].value.toLowerCase(); @@ -313,7 +313,7 @@ describe('Swatches Component', async () => { cy.get('.ss__slideshow__next').should('not.exist'); cy.get('.ss__swatches__grid').should('exist'); cy.get('.ss__grid__option').should('have.length', defaultColumns); - cy.get('.ss__grid__option--selected') + cy.get('.ss__grid__option--selected .ss__grid__option__inner') .should('exist') .should('satisfy', ($el) => { const backgroundStyle = $el[0].style.background; diff --git a/packages/snap-preact/src/Templates/Stores/LibraryStore.ts b/packages/snap-preact/src/Templates/Stores/LibraryStore.ts index c3aea288e6..293492e5a1 100644 --- a/packages/snap-preact/src/Templates/Stores/LibraryStore.ts +++ b/packages/snap-preact/src/Templates/Stores/LibraryStore.ts @@ -29,8 +29,11 @@ export type LibraryImports = { theme: { base: (args?: any) => Promise; bocachica: (args?: any) => Promise; - snappy: (args?: any) => Promise; + everest: (args?: any) => Promise; + matterhorn: (args?: any) => Promise; + pike: (args?: any) => Promise; snapnco: (args?: any) => Promise; + snappy: (args?: any) => Promise; }; plugins: { shopify: { @@ -150,12 +153,21 @@ export class LibraryStore { bocachica: async () => { return this.themes.bocachica || (this.themes.bocachica = (await import('./library/themes/bocachica')).bocachica); }, - snappy: async () => { - return this.themes.snappy || (this.themes.snappy = (await import('./library/themes/snappy')).snappy); + everest: async () => { + return this.themes.everest || (this.themes.everest = (await import('../../../components/src/themes/everest/everest')).everest); + }, + matterhorn: async () => { + return this.themes.matterhorn || (this.themes.matterhorn = (await import('../../../components/src/themes/matterhorn/matterhorn')).matterhorn); + }, + pike: async () => { + return this.themes.pike || (this.themes.pike = (await import('../../../components/src/themes/pike/pike')).pike); }, snapnco: async () => { return this.themes.snapnco || (this.themes.snapnco = (await import('./library/themes/snapnco')).snapnco); }, + snappy: async () => { + return this.themes.snappy || (this.themes.snappy = (await import('./library/themes/snappy')).snappy); + }, }, plugins: { shopify: { diff --git a/packages/snap-preact/src/Templates/Stores/ThemeStore.tsx b/packages/snap-preact/src/Templates/Stores/ThemeStore.tsx index 6b5b7c252b..5e1eb84d52 100644 --- a/packages/snap-preact/src/Templates/Stores/ThemeStore.tsx +++ b/packages/snap-preact/src/Templates/Stores/ThemeStore.tsx @@ -297,6 +297,12 @@ function prefixComponentKeys(prefix: string, components?: ThemeComponents): Them if (components) { Object.keys(components).forEach((key) => { + //does the key already have the prefix? - this is needed when using the editor. + if (key.indexOf(prefix) === 0) { + newComponents[key as keyof typeof newComponents] = components![key as keyof typeof components]; + return; + } + // add the prefix to the key newComponents[`${prefix}${key}` as keyof typeof newComponents] = components![key as keyof typeof components]; }); }