From adad825611a4bda25fc2e8202afb514f4640dc8a Mon Sep 17 00:00:00 2001 From: "Mark J. Becker" Date: Mon, 29 Jan 2024 14:52:51 +0100 Subject: [PATCH 001/160] Add urlKey parameter to route config --- dev-template.html | 2 +- src/components/ProductItem/MockData.ts | 3 +++ src/components/ProductItem/ProductItem.tsx | 2 +- src/components/ProductList/MockData.ts | 2 ++ src/types/interface.ts | 3 ++- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dev-template.html b/dev-template.html index ef62690e..bb0bab1c 100644 --- a/dev-template.html +++ b/dev-template.html @@ -75,7 +75,7 @@ apiKey: '', environmentType: '', // searchQuery: 'search_query', // Optional: providing searchQuery will override 'q' query param - // route: ({ sku }) => { + // route: ({ sku, urlKey }) => { // const storeConfig = JSON.parse( // document // .querySelector("meta[name='store-config']") diff --git a/src/components/ProductItem/MockData.ts b/src/components/ProductItem/MockData.ts index 3deacd69..2d6dbb78 100644 --- a/src/components/ProductItem/MockData.ts +++ b/src/components/ProductItem/MockData.ts @@ -123,6 +123,7 @@ export const sampleProductNoImage: Product = { }, gift_message_available: null, url: 'http://master-7rqtwti-eragxvhtzr4am.us-4.magentosite.cloud/sprite-foam-yoga-brick.html', + urlKey: 'sprite-foam-yoga-brick', media_gallery: null, custom_attributes: null, add_to_cart_allowed: null, @@ -294,6 +295,7 @@ export const sampleProductDiscounted: Product = { }, gift_message_available: null, url: 'http://master-7rqtwti-eragxvhtzr4am.us-4.magentosite.cloud/sprite-foam-yoga-brick.html', + urlKey: 'sprite-foam-yoga-brick', media_gallery: null, custom_attributes: null, add_to_cart_allowed: null, @@ -465,6 +467,7 @@ export const sampleProductNotDiscounted: Product = { }, gift_message_available: null, url: 'http://master-7rqtwti-eragxvhtzr4am.us-4.magentosite.cloud/sprite-foam-yoga-brick.html', + urlKey: 'sprite-foam-yoga-brick', media_gallery: null, custom_attributes: null, add_to_cart_allowed: null, diff --git a/src/components/ProductItem/ProductItem.tsx b/src/components/ProductItem/ProductItem.tsx index 036cb839..ed54538e 100644 --- a/src/components/ProductItem/ProductItem.tsx +++ b/src/components/ProductItem/ProductItem.tsx @@ -82,7 +82,7 @@ export const ProductItem: FunctionComponent = ({ }; const productUrl = setRoute - ? setRoute({ sku: productView?.sku }) + ? setRoute({ sku: productView?.sku, urlKey: productView?.urlKey }) : product?.canonical_url; return ( diff --git a/src/components/ProductList/MockData.ts b/src/components/ProductList/MockData.ts index be450c8b..1793aa13 100644 --- a/src/components/ProductList/MockData.ts +++ b/src/components/ProductList/MockData.ts @@ -13,6 +13,7 @@ const SimpleProduct = { sku: '24-WG088', name: 'Sprite Foam Roller', url: 'http://master-7rqtwti-grxawiljl6f4y.us-4.magentosite.cloud/sprite-foam-roller.html', + urlKey: 'sprite-foam-roller', images: [ { label: 'Image', @@ -49,6 +50,7 @@ const ComplexProduct = { sku: 'MSH06', name: 'Lono Yoga Short', url: 'http://master-7rqtwti-grxawiljl6f4y.us-4.magentosite.cloud/lono-yoga-short.html', + urlKey: 'lono-yoga-short', images: [ { label: '', diff --git a/src/types/interface.ts b/src/types/interface.ts index 70d2e0c3..ced39b53 100644 --- a/src/types/interface.ts +++ b/src/types/interface.ts @@ -50,7 +50,7 @@ export type BucketTypename = | 'StatsBucket' | 'CategoryView'; -export type RedirectRouteFunc = ({ sku }: { sku: string }) => string; +export type RedirectRouteFunc = ({ sku, urlKey }: { sku: string, urlKey: null | string }) => string; export interface MagentoHeaders { environmentId: string; @@ -212,6 +212,7 @@ export interface Product { }; gift_message_available: null | string; url: null | string; + urlKey: null | string; media_gallery: null | ProductViewMedia; custom_attributes: null | CustomAttribute; add_to_cart_allowed: null | boolean; From e3ce857d481a4b053e73ec2e52d554a630029f18 Mon Sep 17 00:00:00 2001 From: "Mark J. Becker" Date: Tue, 30 Jan 2024 13:39:14 +0100 Subject: [PATCH 002/160] Add image optimization feature --- README.md | 2 + dev-template.html | 2 + .../ProductItem/ProductItem.test.tsx | 34 +++++++++++---- src/components/ProductItem/ProductItem.tsx | 22 +++++----- src/types/interface.ts | 2 + src/utils/getProductImage.ts | 42 ++++++++++++++++++- 6 files changed, 85 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 87b96ef8..64234ce0 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,8 @@ const storeDetails = { displaySearchBox: true, displayOutOfStock: true, allowAllProducts: false, + optimizeImages: true, + imageBaseWidth: 200, }, context: { customerGroup: 'CUSTOMER_GROUP_CODE', diff --git a/dev-template.html b/dev-template.html index ef62690e..55109cb2 100644 --- a/dev-template.html +++ b/dev-template.html @@ -68,6 +68,8 @@ displaySearchBox: true, // display search box displayOutOfStock: true, allowAllProducts: false, + optimizeImages: true, + imageBaseWidth: 200, }, context: { customerGroup: '', diff --git a/src/components/ProductItem/ProductItem.test.tsx b/src/components/ProductItem/ProductItem.test.tsx index b7272f0b..2532cfd1 100644 --- a/src/components/ProductItem/ProductItem.test.tsx +++ b/src/components/ProductItem/ProductItem.test.tsx @@ -9,19 +9,39 @@ it. import { render } from '@testing-library/preact'; +import { StoreContextProvider } from '../../context'; import { sampleProductNotDiscounted } from './MockData'; import ProductItem from './ProductItem'; describe('WidgetSDK - UIKit/ProductItem', () => { test('renders', () => { + const context = { + environmentId: '', + environmentType: '', + websiteCode: '', + storeCode: '', + storeViewCode: '', + apiUrl: '', + apiKey: '', + config: { + optimizeImages: true, + imageBaseWidth: 200, + }, + context: {}, + route: undefined, + searchQuery: 'q', + }; + const { container } = render( - {}} - /> + + {}} + /> + ); const elem = container.querySelector('.ds-sdk-product-item'); diff --git a/src/components/ProductItem/ProductItem.tsx b/src/components/ProductItem/ProductItem.tsx index 036cb839..9a39a748 100644 --- a/src/components/ProductItem/ProductItem.tsx +++ b/src/components/ProductItem/ProductItem.tsx @@ -10,6 +10,7 @@ it. import { FunctionComponent } from 'preact'; import { useState } from 'preact/hooks'; +import { useStore } from '../../context'; import NoImage from '../../icons/NoImage.svg'; import { Product, @@ -18,7 +19,7 @@ import { RefinedProduct, } from '../../types/interface'; import { SEARCH_UNIT_ID } from '../../utils/constants'; -import { getProductImageURL } from '../../utils/getProductImage'; +import { generateOptimizedImages, getProductImageURL } from '../../utils/getProductImage'; import { htmlStringDecode } from '../../utils/htmlStringDecode'; import { SwatchButtonGroup } from '../SwatchButtonGroup'; import ProductPrice from './ProductPrice'; @@ -42,6 +43,7 @@ export const ProductItem: FunctionComponent = ({ const [selectedSwatch, setSelectedSwatch] = useState(''); const [productImages, setImages] = useState(); const [refinedProduct, setRefinedProduct] = useState(); + const { config: { optimizeImages, imageBaseWidth } } = useStore(); const handleSelection = async (optionIds: string[], sku: string) => { const data = await refineProduct(optionIds, sku); @@ -55,9 +57,14 @@ export const ProductItem: FunctionComponent = ({ return selected; }; - const productImage = getProductImageURL( + let productImageSrc = getProductImageURL( productImages ? productImages ?? [] : productView.images ?? [] ); // get image for PLP + let productImageSrcset : string[] = []; + + if (optimizeImages) { + [productImageSrc, productImageSrcset] = generateOptimizedImages(productImageSrc, imageBaseWidth ?? 200); + }; // will have to figure out discount logic for amount_off and percent_off still const discount: boolean = refinedProduct @@ -94,16 +101,11 @@ export const ProductItem: FunctionComponent = ({ >
- {/* - NOTE: - we could use for breakpoint based img file - in future for better performance - */} - {productImage ? ( + {productImageSrc ? (
{productView.name} { ''; return imageUrl ? `${protocol}//${imageUrl}` : ''; -}; +} + +export interface ResolveImageUrlOptions { + width: number; + height?: number; + auto?: string; + quality?: number; + crop?: boolean; + fit?: string; +} + +const resolveImageUrl = (url: string, opts: ResolveImageUrlOptions) : string => { + const [base, query] = url.split('?'); + const params = new URLSearchParams(query); + + Object.entries(opts).forEach(([key, value]) => { + if (value !== undefined && value !== null) { + params.set(key, String(value)); + } + }); + + return `${base}?${params.toString()}`; +} + +const generateOptimizedImages = (imageUrl: string, baseImageWidth: number): [string, string[]] => { + const baseOptions = { + fit: 'cover', + crop: false, + dpi: 1, + }; + + const src = resolveImageUrl(imageUrl, { ...baseOptions, width: baseImageWidth }); + const dpiSet = [1, 2, 3]; + const srcset = dpiSet.map((dpi) => { + return `${resolveImageUrl(imageUrl, { ...baseOptions, auto: 'webp', quality: 80, width: baseImageWidth * dpi })} ${dpi}x`; + }); + + return [src, srcset]; +} -export { getProductImageURL }; +export { getProductImageURL, generateOptimizedImages }; From 862a0291925244f334babf72453b874917c16a64 Mon Sep 17 00:00:00 2001 From: Kathleen Tynan Date: Wed, 7 Feb 2024 22:39:01 -0600 Subject: [PATCH 003/160] new plp features --- src/styles/index.css | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/styles/index.css b/src/styles/index.css index 5222881b..dbb452bf 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -1,7 +1,7 @@ /* Tokens */ .ds-widgets { - /* ! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com */ + /* ! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com */ /* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) @@ -29,8 +29,10 @@ 4. Use the user's configured `sans` font-family by default. 5. Use the user's configured `sans` font-feature-settings by default. 6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS */ - html { + html, +:host { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; @@ -40,12 +42,14 @@ -o-tab-size: 4; tab-size: 4; /* 3 */ - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ font-feature-settings: normal; /* 5 */ font-variation-settings: normal; /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ } /* 1. Remove the margin in all browsers. @@ -104,8 +108,10 @@ strong { font-weight: bolder; } /* -1. Use the user's configured `mono` font family by default. -2. Correct the odd `em` font sizing in all browsers. +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. */ code, kbd, @@ -113,8 +119,12 @@ samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ - font-size: 1em; + font-feature-settings: normal; /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ } /* Add the correct font size in all browsers. @@ -1050,9 +1060,6 @@ video { .pb-6 { padding-bottom: 1.5rem; } - .pb-8 { - padding-bottom: 2rem; - } .pl-3 { padding-left: 0.75rem; } @@ -1490,12 +1497,6 @@ video { opacity: 1; } -@media (prefers-color-scheme: dark) { - .dark\:bg-gray-700 { - background-color: var(--color-gray-7); - } -} - @media (min-width: 640px) { .sm\:flex { display: flex; @@ -1567,3 +1568,9 @@ video { column-gap: 2rem; } } + +@media (prefers-color-scheme: dark) { + .dark\:bg-gray-700 { + background-color: var(--color-gray-7); + } +} From 930fad2f165e8a3bb71b3f44a81dea68a2b78d65 Mon Sep 17 00:00:00 2001 From: Kathleen Tynan Date: Wed, 7 Feb 2024 23:33:50 -0600 Subject: [PATCH 004/160] new features plp --- src/components/ProductItem/ProductItem.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ProductItem/ProductItem.tsx b/src/components/ProductItem/ProductItem.tsx index 185c4a56..469d1c82 100644 --- a/src/components/ProductItem/ProductItem.tsx +++ b/src/components/ProductItem/ProductItem.tsx @@ -298,7 +298,7 @@ export const ProductItem: FunctionComponent = ({ className="!text-primary hover:no-underline hover:text-primary" >
-
+
{productImageArray.length ? ( = ({
-
+
{product.name !== null && htmlStringDecode(product.name)}
Date: Wed, 7 Feb 2024 23:33:22 -0600 Subject: [PATCH 005/160] elsie base design --- .../AddToCartButton/AddToCartButton.tsx | 7 +- src/components/Alert/Alert.tsx | 10 +- src/components/Breadcrumbs/Breadcrumbs.tsx | 6 +- .../CategoryFilters/CategoryFilters.tsx | 10 +- src/components/Facets/Facets.tsx | 2 +- src/components/Facets/SelectedFilters.tsx | 4 +- .../FacetsShimmer/FacetsShimmer.tsx | 2 +- src/components/FilterButton/FilterButton.tsx | 8 +- .../InputButtonGroup/InputButtonGroup.tsx | 14 +- .../LabelledInput/LabelledInput.tsx | 6 +- src/components/Loading/Loading.tsx | 2 +- src/components/NoResults/NoResults.tsx | 8 +- src/components/Pagination/Pagination.tsx | 14 +- .../PerPagePicker/PerPagePicker.tsx | 22 +- src/components/Pill/Pill.tsx | 4 +- src/components/ProductItem/ProductPrice.tsx | 49 ++- src/components/SearchBar/SearchBar.tsx | 2 +- src/components/Shimmer/Shimmer.tsx | 4 +- src/components/Slider/Slider.tsx | 4 +- src/components/SortDropdown/SortDropdown.tsx | 24 +- src/containers/App.tsx | 4 +- src/containers/ProductsContainer.tsx | 4 +- .../inputGroupTitleSlot/TextWithTooltip.tsx | 6 +- src/styles/index.css | 402 ++++++++++++++---- src/styles/tokens.css | 206 ++++++++- tailwind.config.js | 75 +++- 26 files changed, 679 insertions(+), 220 deletions(-) diff --git a/src/components/AddToCartButton/AddToCartButton.tsx b/src/components/AddToCartButton/AddToCartButton.tsx index d68b6945..b711899c 100644 --- a/src/components/AddToCartButton/AddToCartButton.tsx +++ b/src/components/AddToCartButton/AddToCartButton.tsx @@ -20,13 +20,10 @@ export const AddToCartButton: FunctionComponent = ({ return (
diff --git a/src/components/Alert/Alert.tsx b/src/components/Alert/Alert.tsx index df0c5053..7b3e6ed2 100644 --- a/src/components/Alert/Alert.tsx +++ b/src/components/Alert/Alert.tsx @@ -37,7 +37,7 @@ export const Alert: FunctionComponent = ({ switch (type) { case 'error': return ( -
+
= ({ ); case 'warning': return ( -
+
= ({ ); case 'info': return ( -
+
= ({ ); case 'success': return ( -
+
= ({
diff --git a/src/components/FacetsShimmer/FacetsShimmer.tsx b/src/components/FacetsShimmer/FacetsShimmer.tsx index 7b7e255d..8dc35eb6 100644 --- a/src/components/FacetsShimmer/FacetsShimmer.tsx +++ b/src/components/FacetsShimmer/FacetsShimmer.tsx @@ -27,7 +27,7 @@ export const FacetsShimmer: FunctionComponent = () => {
-
+
); }; diff --git a/src/components/FilterButton/FilterButton.tsx b/src/components/FilterButton/FilterButton.tsx index f9a40f24..c4747d58 100644 --- a/src/components/FilterButton/FilterButton.tsx +++ b/src/components/FilterButton/FilterButton.tsx @@ -27,20 +27,20 @@ export const FilterButton: FunctionComponent = ({ return type == 'mobile' ? (
) : (
); diff --git a/src/components/InputButtonGroup/InputButtonGroup.tsx b/src/components/InputButtonGroup/InputButtonGroup.tsx index 1c319df6..19bad082 100644 --- a/src/components/InputButtonGroup/InputButtonGroup.tsx +++ b/src/components/InputButtonGroup/InputButtonGroup.tsx @@ -116,7 +116,7 @@ export const InputButtonGroup: FunctionComponent = ({ {inputGroupTitleSlot ? ( inputGroupTitleSlot(title) ) : ( -
-
+
); }; diff --git a/src/components/LabelledInput/LabelledInput.tsx b/src/components/LabelledInput/LabelledInput.tsx index 5473c14a..2a1d7bcd 100644 --- a/src/components/LabelledInput/LabelledInput.tsx +++ b/src/components/LabelledInput/LabelledInput.tsx @@ -42,7 +42,7 @@ export const LabelledInput: FunctionComponent = ({ : `radio-group-${attribute}` } type={type} - className="ds-sdk-labelled-input__input focus:ring-0 h-md w-md border-0 cursor-pointer accent-gray-600 min-w-[16px]" + className="ds-sdk-labelled-input__input focus:ring-0 h-md w-md border-0 cursor-pointer accent-neutral-800 min-w-[16px]" checked={checked} aria-checked={checked} onInput={onChange} @@ -50,11 +50,11 @@ export const LabelledInput: FunctionComponent = ({ />
  • onPageChange(page)} @@ -92,8 +92,8 @@ export const Pagination: FunctionComponent = ({ diff --git a/src/components/PerPagePicker/PerPagePicker.tsx b/src/components/PerPagePicker/PerPagePicker.tsx index 5acdf663..9ebf69a6 100644 --- a/src/components/PerPagePicker/PerPagePicker.tsx +++ b/src/components/PerPagePicker/PerPagePicker.tsx @@ -73,18 +73,20 @@ export const PerPagePicker: FunctionalComponent = ({ <>
  • - + {facetsArray.map((_, index) => ( ))} diff --git a/src/components/Slider/Slider.tsx b/src/components/Slider/Slider.tsx index b2787da2..5a2dd4fa 100644 --- a/src/components/Slider/Slider.tsx +++ b/src/components/Slider/Slider.tsx @@ -92,7 +92,7 @@ export const Slider: FunctionComponent = ({ filterData }) => { = ({ filterData }) => {
    -
    +
    ); }; diff --git a/src/components/SortDropdown/SortDropdown.tsx b/src/components/SortDropdown/SortDropdown.tsx index 3f135842..a366b9df 100644 --- a/src/components/SortDropdown/SortDropdown.tsx +++ b/src/components/SortDropdown/SortDropdown.tsx @@ -82,19 +82,21 @@ export const SortDropdown: FunctionComponent = ({ <>
    -
    +
    {!screenSize.mobile && !productsCtx.loading && diff --git a/src/containers/ProductsContainer.tsx b/src/containers/ProductsContainer.tsx index a2507a7a..087dd921 100644 --- a/src/containers/ProductsContainer.tsx +++ b/src/containers/ProductsContainer.tsx @@ -84,7 +84,9 @@ export const ProductsContainer: FunctionComponent = ({ key={index} /> ) : ( - `${word} ` + + {word}{' '} + ) ); }; diff --git a/src/examples/inputGroupTitleSlot/TextWithTooltip.tsx b/src/examples/inputGroupTitleSlot/TextWithTooltip.tsx index df5a03f9..31a9781e 100644 --- a/src/examples/inputGroupTitleSlot/TextWithTooltip.tsx +++ b/src/examples/inputGroupTitleSlot/TextWithTooltip.tsx @@ -8,13 +8,13 @@ export const TextWithTooltip: FunctionComponent<{ }> = ({ text, tooltipText }) => { return (
    -
    diff --git a/src/styles/index.css b/src/styles/index.css index dbb452bf..a5dfbaa7 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -15,7 +15,7 @@ /* 2 */ border-style: solid; /* 2 */ - border-color: var(--color-gray-2); + border-color: #e5e7eb; /* 2 */ } ::before, @@ -320,14 +320,14 @@ Prevent resizing textareas horizontally by default. input::-moz-placeholder, textarea::-moz-placeholder { opacity: 1; /* 1 */ - color: var(--color-gray-4); + color: #9ca3af; /* 2 */ } input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ - color: var(--color-gray-4); + color: #9ca3af; /* 2 */ } /* @@ -525,12 +525,21 @@ video { .bottom-0 { bottom: 0px; } + .bottom-\[48px\] { + bottom: 48px; + } + .left-0 { + left: 0px; + } .left-1\/2 { left: 50%; } .right-0 { right: 0px; } + .top-\[6\.4rem\] { + top: 6.4rem; + } .z-20 { z-index: 20; } @@ -623,6 +632,9 @@ video { .mt-xs { margin-top: var(--spacing-xs); } + .box-content { + box-sizing: content-box; + } .inline-block { display: inline-block; } @@ -756,6 +768,12 @@ video { .flex-1 { flex: 1 1 0%; } + .flex-\[25\] { + flex: 25; + } + .flex-\[75\] { + flex: 75; + } .flex-shrink-0 { flex-shrink: 0; } @@ -889,6 +907,12 @@ video { .whitespace-nowrap { white-space: nowrap; } + .rounded-2 { + border-radius: var(--shape-border-radius-2); + } + .rounded-3 { + border-radius: var(--shape-border-radius-3); + } .rounded-full { border-radius: 9999px; } @@ -904,6 +928,9 @@ video { .border-0 { border-width: 0px; } + .border-3 { + border-width: var(--shape-border-width-3); + } .border-\[1\.5px\] { border-width: 1.5px; } @@ -920,32 +947,59 @@ video { --tw-border-opacity: 1; border-color: rgb(0 0 0 / var(--tw-border-opacity)); } + .border-brand-700 { + border-color: var(--color-brand-700); + } .border-gray-200 { - border-color: var(--color-gray-2); + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); } .border-gray-300 { - border-color: var(--color-gray-3); + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); + } + .border-neutral-200 { + border-color: var(--color-neutral-200); + } + .border-neutral-300 { + border-color: var(--color-neutral-300); + } + .border-neutral-500 { + border-color: var(--color-neutral-500); } .border-transparent { border-color: transparent; } + .bg-background { + background-color: var(--background-color); + } .bg-blue-50 { --tw-bg-opacity: 1; background-color: rgb(239 246 255 / var(--tw-bg-opacity)); } - .bg-body { - background-color: var(--color-body); + .bg-brand-500 { + background-color: var(--color-brand-500); } .bg-gray-100 { - background-color: var(--color-gray-1); - } - .bg-gray-200 { - background-color: var(--color-gray-2); + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); } .bg-green-50 { --tw-bg-opacity: 1; background-color: rgb(240 253 244 / var(--tw-bg-opacity)); } + .bg-neutral-200 { + background-color: var(--color-neutral-200); + } + .bg-neutral-300 { + background-color: var(--color-neutral-300); + } + .bg-neutral-400 { + background-color: var(--color-neutral-400); + } + .bg-neutral-50 { + background-color: var(--color-neutral-50); + } .bg-red-50 { --tw-bg-opacity: 1; background-color: rgb(254 242 242 / var(--tw-bg-opacity)); @@ -961,23 +1015,23 @@ video { --tw-bg-opacity: 1; background-color: rgb(254 252 232 / var(--tw-bg-opacity)); } - .fill-gray-500 { - fill: var(--color-gray-5); - } - .fill-gray-700 { - fill: var(--color-gray-7); + .fill-brand-300 { + fill: var(--color-brand-300); } - .fill-primary { - fill: var(--color-primary); + .fill-neutral-800 { + fill: var(--color-neutral-800); } - .stroke-gray-400 { - stroke: var(--color-gray-4); + .stroke-brand-700 { + stroke: var(--color-brand-700); } - .stroke-gray-600 { - stroke: var(--color-gray-6); + .stroke-neutral-600 { + stroke: var(--color-neutral-600); } .stroke-1 { - stroke-width: 1; + stroke-width: var(--shape-icon-stroke-1); + } + .stroke-2 { + stroke-width: var(--shape-icon-stroke-2); } .object-cover { -o-object-fit: cover; @@ -1115,10 +1169,6 @@ video { font-size: var(--font-sm); line-height: var(--leading-tight); } - .text-xs { - font-size: var(--font-xs); - line-height: var(--leading-none); - } .font-light { font-weight: var(--font-light); } @@ -1131,9 +1181,6 @@ video { .font-semibold { font-weight: var(--font-semibold); } - .\!text-primary { - color: var(--color-primary) !important; - } .text-black { --tw-text-opacity: 1; color: rgb(0 0 0 / var(--tw-text-opacity)); @@ -1150,20 +1197,22 @@ video { --tw-text-opacity: 1; color: rgb(30 64 175 / var(--tw-text-opacity)); } - .text-gray-500 { - color: var(--color-gray-5); + .text-brand-300 { + color: var(--color-brand-300); } - .text-gray-600 { - color: var(--color-gray-6); + .text-brand-600 { + color: var(--color-brand-600); } - .text-gray-700 { - color: var(--color-gray-7); + .text-brand-700 { + color: var(--color-brand-700); } - .text-gray-800 { - color: var(--color-gray-8); + .text-gray-700 { + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); } .text-gray-900 { - color: var(--color-gray-9); + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); } .text-green-400 { --tw-text-opacity: 1; @@ -1181,8 +1230,14 @@ video { --tw-text-opacity: 1; color: rgb(22 101 52 / var(--tw-text-opacity)); } - .text-primary { - color: var(--color-primary); + .text-neutral-700 { + color: var(--color-neutral-700); + } + .text-neutral-800 { + color: var(--color-neutral-800); + } + .text-neutral-900 { + color: var(--color-neutral-900); } .text-red-400 { --tw-text-opacity: 1; @@ -1196,9 +1251,6 @@ video { --tw-text-opacity: 1; color: rgb(153 27 27 / var(--tw-text-opacity)); } - .text-secondary { - color: var(--color-secondary); - } .text-white { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); @@ -1224,14 +1276,14 @@ video { .no-underline { text-decoration-line: none; } - .decoration-black { - text-decoration-color: #000; + .decoration-brand-700 { + text-decoration-color: var(--color-brand-700); } .underline-offset-4 { text-underline-offset: 4px; } - .accent-gray-600 { - accent-color: var(--color-gray-6); + .accent-neutral-800 { + accent-color: var(--color-neutral-800); } .opacity-0 { opacity: 0; @@ -1244,11 +1296,11 @@ video { .outline { outline-style: solid; } - .outline-1 { - outline-width: 1px; + .outline-brand-700 { + outline-color: var(--color-brand-700); } - .outline-gray-200 { - outline-color: var(--color-gray-2); + .outline-neutral-300 { + outline-color: var(--color-neutral-300); } .outline-transparent { outline-color: transparent; @@ -1290,24 +1342,121 @@ video { .ease-out { transition-timing-function: cubic-bezier(0, 0, 0.2, 1); } - /* Colors */ - --color-body: #fff; - --color-on-body: #222; - --color-surface: #e6e6e6; - --color-on-surface: #222; - --color-primary: #222; - --color-on-primary: #fff; - --color-secondary: #ff0000; - --color-on-secondary: #fff; - --color-gray-1: #f3f4f6; - --color-gray-2: #e5e7eb; - --color-gray-3: #d1d5db; - --color-gray-4: #9ca3af; - --color-gray-5: #6b7280; - --color-gray-6: #4b5563; - --color-gray-7: #374151; - --color-gray-8: #1f2937; - --color-gray-9: #111827; + /* font-size: 1.6rem; */ + /* Elsie base design */ + --color-brand-300: #6d6d6d; + --color-brand-500: #454545; + --color-brand-600: #383838; + --color-brand-700: #2b2b2b; + --color-neutral-50: #fff; + --color-neutral-100: #fafafa; + --color-neutral-200: #f5f5f5; + --color-neutral-300: #e8e8e8; + --color-neutral-400: #d6d6d6; + --color-neutral-500: #b8b8b8; + --color-neutral-600: #8f8f8f; + --color-neutral-700: #666; + --color-neutral-800: #3d3d3d; + --color-neutral-900: #292929; + --grid-1-columns: 4; + --grid-1-margins: 0; + --grid-1-gutters: 16px; + --grid-2-columns: 12; + --grid-2-margins: 0; + --grid-2-gutters: 16px; + --grid-3-columns: 12; + --grid-3-margins: 0; + --grid-3-gutters: 24px; + --grid-4-columns: 12; + --grid-4-margins: 0; + --grid-4-gutters: 24px; + --grid-5-columns: 12; + --grid-5-margins: 0; + --grid-5-gutters: 24px; + --shape-border-radius-1: 3px; + --shape-border-radius-2: 8px; + --shape-border-radius-3: 24px; + --shape-border-width-1: 1px; + --shape-border-width-2: 1.5px; + --shape-border-width-3: 2px; + --shape-border-width-4: 4px; + --type-base-font-family: 'Roboto', sans-serif; + --type-display-1-font: normal normal 300 6rem/7.2rem + var(--type-base-font-family); + --type-display-1-letter-spacing: 0.04em; + --type-display-2-font: normal normal 300 4.8rem/5.6rem + var(--type-base-font-family); + --type-display-2-letter-spacing: 0.04em; + --type-display-3-font: normal normal 300 3.4rem/4rem + var(--type-base-font-family); + --type-display-3-letter-spacing: 0.04em; + --type-headline-1-font: normal normal 400 2.4rem/3.2rem + var(--type-base-font-family); + --type-headline-1-letter-spacing: 0.04em; + --type-headline-2-default-font: normal normal 300 2rem/2.4rem + var(--type-base-font-family); + --type-headline-2-default-letter-spacing: 0.04em; + --type-headline-2-strong-font: normal normal 400 2rem/2.4rem + var(--type-base-font-family); + --type-headline-2-strong-letter-spacing: 0.04em; + --type-body-1-default-font: normal normal 300 1.6rem/2.4rem + var(--type-base-font-family); + --type-body-1-default-letter-spacing: 0.04em; + --type-body-1-strong-font: normal normal 400 1.6rem/2.4rem + var(--type-base-font-family); + --type-body-1-strong-letter-spacing: 0.04em; + --type-body-1-emphasized-font: normal normal 700 1.6rem/2.4rem + var(--type-base-font-family); + --type-body-1-emphasized-letter-spacing: 0.04em; + --type-body-2-default-font: normal normal 300 1.4rem/2rem + var(--type-base-font-family); + --type-body-2-default-letter-spacing: 0.04em; + --type-body-2-strong-font: normal normal 400 1.4rem/2rem + var(--type-base-font-family); + --type-body-2-strong-letter-spacing: 0.04em; + --type-body-2-emphasized-font: normal normal 700 1.4rem/2rem + var(--type-base-font-family); + --type-body-2-emphasized-letter-spacing: 0.04em; + --type-button-1-font: normal normal 400 2rem/2.6rem + var(--type-base-font-family); + --type-button-1-letter-spacing: 0.08em; + --type-button-2-font: normal normal 400 1.6rem/2.4rem + var(--type-base-font-family); + --type-button-2-letter-spacing: 0.08em; + --type-details-caption-1-font: normal normal 400 1.2rem/1.6rem + var(--type-base-font-family); + --type-details-caption-1-letter-spacing: 0.08em; + --type-details-caption-2-font: normal normal 300 1.2rem/1.6rem + var(--type-base-font-family); + --type-details-caption-2-letter-spacing: 0.08em; + --type-details-overline-font: normal normal 400 1.2rem/2rem + var(--type-base-font-family); + --type-details-overline-letter-spacing: 0.16em; + /* Additional tokens */ + --type-fixed-font-family: 'Roboto Mono', menlo, consolas, 'Liberation Mono', + monospace; + --background-color: var(--color-neutral-50); + --nav-height: 6.4rem; + --spacing-xxsmall: 4px; + --spacing-xsmall: 8px; + --spacing-small: 16px; + --spacing-medium: 24px; + --spacing-big: 32px; + --spacing-xbig: 40px; + --spacing-xxbig: 48px; + --spacing-large: 64px; + --spacing-xlarge: 72px; + --spacing-xxlarge: 96px; + --spacing-huge: 120px; + --spacing-xhuge: 144px; + --spacing-xxhuge: 192px; + --shape-shadow-1: 0 0 16px 0 rgb(0 0 0 / 16%); + --shape-shadow-2: 0 2px 16px 0 rgb(0 0 0 / 16%); + --shape-shadow-3: 0 2px 3px 0 rgb(0 0 0 / 16%); + --shape-icon-stroke-1: 1px; + --shape-icon-stroke-2: 1.5px; + --shape-icon-stroke-3: 2px; + --shape-icon-stroke-4: 4px; /* Spacing: gaps, margin, padding, etc. */ --spacing-xxs: 0.15625em; --spacing-xs: 0.3125em; @@ -1356,6 +1505,91 @@ video { --leading-10: '2.5em'; } +.font-display-1 { + font: var(--type-display-1-font); + letter-spacing: var(--type-display-1-letter-spacing); +} + +.font-display-2 { + font: var(--type-display-2-font); + letter-spacing: var(--type-display-2-letter-spacing); +} + +.font-display-3 { + font: var(--type-display-3-font); + letter-spacing: var(---type-display-3-letter-spacing); +} + +.font-headline-1 { + font: var(--type-headline-1-font); + letter-spacing: var(--type-headline-1-letter-spacing); +} + +.font-headline-2-default { + font: var(--type-headline-2-default-font); + letter-spacing: var(--type-headline-2-default-letter-spacing); +} + +.font-headline-2-strong { + font: var(--type-headline-2-strong-font); + letter-spacing: var(--type-headline-2-strong-letter-spacing); +} + +.font-body-1-default { + font: var(--type-body-1-default-font); + letter-spacing: var(--type-body-1-default-letter-spacing); +} + +.font-body-1-strong { + font: var(--type-body-1-strong-font); + letter-spacing: var(--type-body-1-strong-letter-spacing); +} + +.font-body-1-emphasized { + font: var(--type-body-1-emphasized-font); + letter-spacing: var(--type-body-1-emphasized-letter-spacing); +} + +.font-body-2-default { + font: var(--type-body-2-default-font); + letter-spacing: var(--type-body-2-default-letter-spacing); +} + +.font-body-2-strong { + font: var(--type-body-2-strong-font); + letter-spacing: var(--type-body-2-strong-letter-spacing); +} + +.font-body-2-emphasized { + font: var(--type-body-2-emphasized-font); + letter-spacing: var(--type-body-2-emphasized-letter-spacing); +} + +.font-button-1 { + font: var(--type-button-1-font); + letter-spacing: var(--type-button-1-letter-spacing); +} + +.font-button-2 { + font: var(--type-button-2-font); + letter-spacing: var(--type-button-2-letter-spacing); +} + +.font-details-caption-1 { + font: var(--type-details-caption-1-font); + letter-spacing: var(--type-details-caption-1-letter-spacing); +} + +.font-details-caption-2 { + font: var(--type-details-caption-2-font); + letter-spacing: var(--type-details-caption-2-letter-spacing); +} + +.font-details-overline { + font: var(--type-details-overline-font); + letter-spacing: var(--type-details-overline-letter-spacing); +} + .ds-widgets input[type='checkbox'] { font-size: 80%; margin: 0; @@ -1389,15 +1623,15 @@ video { border-style: none; } -.hover\:bg-gray-100:hover { - background-color: var(--color-gray-1); -} - .hover\:bg-green-100:hover { --tw-bg-opacity: 1; background-color: rgb(220 252 231 / var(--tw-bg-opacity)); } +.hover\:bg-neutral-200:hover { + background-color: var(--color-neutral-200); +} + .hover\:bg-transparent:hover { background-color: transparent; } @@ -1407,12 +1641,8 @@ video { color: rgb(37 99 235 / var(--tw-text-opacity)); } -.hover\:text-gray-900:hover { - color: var(--color-gray-9); -} - -.hover\:text-primary:hover { - color: var(--color-primary); +.hover\:text-neutral-900:hover { + color: var(--color-neutral-900); } .hover\:no-underline:hover { @@ -1425,14 +1655,6 @@ video { box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.hover\:outline-gray-600:hover { - outline-color: var(--color-gray-6); -} - -.hover\:outline-gray-800:hover { - outline-color: var(--color-gray-8); -} - .focus\:border-none:focus { border-style: none; } @@ -1570,7 +1792,7 @@ video { } @media (prefers-color-scheme: dark) { - .dark\:bg-gray-700 { - background-color: var(--color-gray-7); + .dark\:bg-neutral-800 { + background-color: var(--color-neutral-800); } } diff --git a/src/styles/tokens.css b/src/styles/tokens.css index 61023b35..c05fb943 100644 --- a/src/styles/tokens.css +++ b/src/styles/tokens.css @@ -4,28 +4,129 @@ @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; - /* Colors */ - --color-body: #fff; - --color-on-body: #222; + /* font-size: 1.6rem; */ - --color-surface: #e6e6e6; - --color-on-surface: #222; + /* Elsie base design */ + --color-brand-300: #6d6d6d; + --color-brand-500: #454545; + --color-brand-600: #383838; + --color-brand-700: #2b2b2b; + --color-neutral-50: #fff; + --color-neutral-100: #fafafa; + --color-neutral-200: #f5f5f5; + --color-neutral-300: #e8e8e8; + --color-neutral-400: #d6d6d6; + --color-neutral-500: #b8b8b8; + --color-neutral-600: #8f8f8f; + --color-neutral-700: #666; + --color-neutral-800: #3d3d3d; + --color-neutral-900: #292929; - --color-primary: #222; - --color-on-primary: #fff; + --grid-1-columns: 4; + --grid-1-margins: 0; + --grid-1-gutters: 16px; + --grid-2-columns: 12; + --grid-2-margins: 0; + --grid-2-gutters: 16px; + --grid-3-columns: 12; + --grid-3-margins: 0; + --grid-3-gutters: 24px; + --grid-4-columns: 12; + --grid-4-margins: 0; + --grid-4-gutters: 24px; + --grid-5-columns: 12; + --grid-5-margins: 0; + --grid-5-gutters: 24px; - --color-secondary: #ff0000; - --color-on-secondary: #fff; + --shape-border-radius-1: 3px; + --shape-border-radius-2: 8px; + --shape-border-radius-3: 24px; - --color-gray-1: #f3f4f6; - --color-gray-2: #e5e7eb; - --color-gray-3: #d1d5db; - --color-gray-4: #9ca3af; - --color-gray-5: #6b7280; - --color-gray-6: #4b5563; - --color-gray-7: #374151; - --color-gray-8: #1f2937; - --color-gray-9: #111827; + --shape-border-width-1: 1px; + --shape-border-width-2: 1.5px; + --shape-border-width-3: 2px; + --shape-border-width-4: 4px; + + --type-base-font-family: 'Roboto', sans-serif; + --type-display-1-font: normal normal 300 6rem/7.2rem + var(--type-base-font-family); + --type-display-1-letter-spacing: 0.04em; + --type-display-2-font: normal normal 300 4.8rem/5.6rem + var(--type-base-font-family); + --type-display-2-letter-spacing: 0.04em; + --type-display-3-font: normal normal 300 3.4rem/4rem + var(--type-base-font-family); + --type-display-3-letter-spacing: 0.04em; + --type-headline-1-font: normal normal 400 2.4rem/3.2rem + var(--type-base-font-family); + --type-headline-1-letter-spacing: 0.04em; + --type-headline-2-default-font: normal normal 300 2rem/2.4rem + var(--type-base-font-family); + --type-headline-2-default-letter-spacing: 0.04em; + --type-headline-2-strong-font: normal normal 400 2rem/2.4rem + var(--type-base-font-family); + --type-headline-2-strong-letter-spacing: 0.04em; + --type-body-1-default-font: normal normal 300 1.6rem/2.4rem + var(--type-base-font-family); + --type-body-1-default-letter-spacing: 0.04em; + --type-body-1-strong-font: normal normal 400 1.6rem/2.4rem + var(--type-base-font-family); + --type-body-1-strong-letter-spacing: 0.04em; + --type-body-1-emphasized-font: normal normal 700 1.6rem/2.4rem + var(--type-base-font-family); + --type-body-1-emphasized-letter-spacing: 0.04em; + --type-body-2-default-font: normal normal 300 1.4rem/2rem + var(--type-base-font-family); + --type-body-2-default-letter-spacing: 0.04em; + --type-body-2-strong-font: normal normal 400 1.4rem/2rem + var(--type-base-font-family); + --type-body-2-strong-letter-spacing: 0.04em; + --type-body-2-emphasized-font: normal normal 700 1.4rem/2rem + var(--type-base-font-family); + --type-body-2-emphasized-letter-spacing: 0.04em; + --type-button-1-font: normal normal 400 2rem/2.6rem + var(--type-base-font-family); + --type-button-1-letter-spacing: 0.08em; + --type-button-2-font: normal normal 400 1.6rem/2.4rem + var(--type-base-font-family); + --type-button-2-letter-spacing: 0.08em; + --type-details-caption-1-font: normal normal 400 1.2rem/1.6rem + var(--type-base-font-family); + --type-details-caption-1-letter-spacing: 0.08em; + --type-details-caption-2-font: normal normal 300 1.2rem/1.6rem + var(--type-base-font-family); + --type-details-caption-2-letter-spacing: 0.08em; + --type-details-overline-font: normal normal 400 1.2rem/2rem + var(--type-base-font-family); + --type-details-overline-letter-spacing: 0.16em; + + /* Additional tokens */ + --type-fixed-font-family: 'Roboto Mono', menlo, consolas, 'Liberation Mono', + monospace; + --background-color: var(--color-neutral-50); + --nav-height: 6.4rem; + + --spacing-xxsmall: 4px; + --spacing-xsmall: 8px; + --spacing-small: 16px; + --spacing-medium: 24px; + --spacing-big: 32px; + --spacing-xbig: 40px; + --spacing-xxbig: 48px; + --spacing-large: 64px; + --spacing-xlarge: 72px; + --spacing-xxlarge: 96px; + --spacing-huge: 120px; + --spacing-xhuge: 144px; + --spacing-xxhuge: 192px; + + --shape-shadow-1: 0 0 16px 0 rgb(0 0 0 / 16%); + --shape-shadow-2: 0 2px 16px 0 rgb(0 0 0 / 16%); + --shape-shadow-3: 0 2px 3px 0 rgb(0 0 0 / 16%); + --shape-icon-stroke-1: 1px; + --shape-icon-stroke-2: 1.5px; + --shape-icon-stroke-3: 2px; + --shape-icon-stroke-4: 4px; /* Spacing: gaps, margin, padding, etc. */ --spacing-xxs: 0.15625em; @@ -79,6 +180,75 @@ --leading-10: '2.5em'; } +.font-display-1 { + font: var(--type-display-1-font); + letter-spacing: var(--type-display-1-letter-spacing); +} +.font-display-2 { + font: var(--type-display-2-font); + letter-spacing: var(--type-display-2-letter-spacing); +} +.font-display-3 { + font: var(--type-display-3-font); + letter-spacing: var(---type-display-3-letter-spacing); +} +.font-headline-1 { + font: var(--type-headline-1-font); + letter-spacing: var(--type-headline-1-letter-spacing); +} +.font-headline-2-default { + font: var(--type-headline-2-default-font); + letter-spacing: var(--type-headline-2-default-letter-spacing); +} +.font-headline-2-strong { + font: var(--type-headline-2-strong-font); + letter-spacing: var(--type-headline-2-strong-letter-spacing); +} +.font-body-1-default { + font: var(--type-body-1-default-font); + letter-spacing: var(--type-body-1-default-letter-spacing); +} +.font-body-1-strong { + font: var(--type-body-1-strong-font); + letter-spacing: var(--type-body-1-strong-letter-spacing); +} +.font-body-1-emphasized { + font: var(--type-body-1-emphasized-font); + letter-spacing: var(--type-body-1-emphasized-letter-spacing); +} +.font-body-2-default { + font: var(--type-body-2-default-font); + letter-spacing: var(--type-body-2-default-letter-spacing); +} +.font-body-2-strong { + font: var(--type-body-2-strong-font); + letter-spacing: var(--type-body-2-strong-letter-spacing); +} +.font-body-2-emphasized { + font: var(--type-body-2-emphasized-font); + letter-spacing: var(--type-body-2-emphasized-letter-spacing); +} +.font-button-1 { + font: var(--type-button-1-font); + letter-spacing: var(--type-button-1-letter-spacing); +} +.font-button-2 { + font: var(--type-button-2-font); + letter-spacing: var(--type-button-2-letter-spacing); +} +.font-details-caption-1 { + font: var(--type-details-caption-1-font); + letter-spacing: var(--type-details-caption-1-letter-spacing); +} +.font-details-caption-2 { + font: var(--type-details-caption-2-font); + letter-spacing: var(--type-details-caption-2-letter-spacing); +} +.font-details-overline { + font: var(--type-details-overline-font); + letter-spacing: var(--type-details-overline-letter-spacing); +} + .ds-widgets input[type='checkbox'] { font-size: 80%; margin: 0; diff --git a/tailwind.config.js b/tailwind.config.js index c435c645..75cc352b 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -4,27 +4,40 @@ module.exports = { theme: { extend: { colors: { - primary: 'var(--color-primary)', - secondary: 'var(--color-secondary)', - body: 'var(--color-body)', - surface: 'var(--color-surface)', - 'on-primary': 'var(--color-on-primary)', - 'on-secondary': 'var(--color--on-secondary)', - 'on-body': 'var(--color-on-body)', - 'on-surface': 'var(--color-on-surface)', - gray: { - 100: 'var(--color-gray-1)', - 200: 'var(--color-gray-2)', - 300: 'var(--color-gray-3)', - 400: 'var(--color-gray-4)', - 500: 'var(--color-gray-5)', - 600: 'var(--color-gray-6)', - 700: 'var(--color-gray-7)', - 800: 'var(--color-gray-8)', - 900: 'var(--color-gray-9)', + background: 'var(--background-color)', + neutral: { + 50: 'var(--color-neutral-50)', + 100: 'var(--color-neutral-100)', + 200: 'var(--color-neutral-200)', + 300: 'var(--color-neutral-300)', + 400: 'var(--color-neutral-400)', + 500: 'var(--color-neutral-500)', + 600: 'var(--color-neutral-600)', + 700: 'var(--color-neutral-700)', + 800: 'var(--color-neutral-800)', + 900: 'var(--color-neutral-900)', + }, + brand: { + 300: 'var(--color-brand-300)', + 500: 'var(--color-brand-500)', + 600: 'var(--color-brand-600)', + 700: 'var(--color-brand-700)', }, }, spacing: { + xxsmall: 'var(--spacing-xxsmall)', + xsmall: 'var(--spacing-xsmall)', + small: 'var(--spacing-small)', + medium: 'var(--spacing-medium)', + big: 'var(--spacing-big)', + xbig: 'var(--spacing-xbig)', + xxbig: 'var(--spacing-xxbig)', + large: 'var(--spacing-large)', + xlarge: 'var(--spacing-xlarge)', + xxlarge: 'var(--spacing-xxlarge)', + huge: 'var(--spacing-huge)', + xhuge: 'var(--spacing-xhuge)', + xxhuge: 'var(--spacing-xxhuge)', xss: 'var(--spacing-xxs)', xs: 'var(--spacing-xs)', sm: 'var(--spacing-sm)', @@ -34,6 +47,10 @@ module.exports = { '2xl': 'var(--spacing-2xl)', '3xl': 'var(--spacing-3xl)', }, + letterSpacing: { + display1: 'var(--type-display-1-letter-spacing)', + headline2: 'var(--type-headline-2-strong-letter-spacing)', + }, fontFamily: { 'font-body': 'var(--font-body)', }, @@ -75,6 +92,28 @@ module.exports = { 9: 'var(--leading-9)', 10: 'var(--leading-10)', }, + borderWidth: { + 1: 'var(--shape-border-width-1)', + 2: 'var(--shape-border-width-2)', + 3: 'var(--shape-border-width-3)', + 4: 'var(--shape-border-width-4)', + }, + borderRadius: { + 1: 'var(--shape-border-radius-1)', + 2: 'var(--shape-border-radius-2)', + 3: 'var(--shape-border-radius-3)', + }, + dropShadow: { + 1: 'var(--shape-shadow-1)', + 2: 'var(--shape-shadow-2)', + 3: 'var(--shape-shadow-3)', + }, + strokeWidth: { + 1: 'var(--shape-icon-stroke-1)', + 2: 'var(--shape-icon-stroke-2)', + 3: 'var(--shape-icon-stroke-3)', + 4: 'var(--shape-icon-stroke-4)', + }, }, plugins: [], From c5c227df2d02be7b642ef6f37fb1a545f0bbc94d Mon Sep 17 00:00:00 2001 From: Kathleen Tynan Date: Mon, 12 Feb 2024 11:26:20 -0700 Subject: [PATCH 006/160] add elsie base design --- README.md | 6 +++--- .../CategoryFilters/CategoryFilters.tsx | 2 +- src/components/ProductItem/ProductItem.tsx | 20 +++++++++---------- .../SliderDoubleControl.tsx | 8 ++++---- .../SwatchButtonGroup/SwatchButtonGroup.tsx | 6 +++--- src/containers/App.tsx | 12 +++++------ src/styles/index.css | 15 +++++++------- 7 files changed, 34 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index a48c7a53..94b47156 100644 --- a/README.md +++ b/README.md @@ -187,8 +187,8 @@ Let's say as if I want to style an element with the theme's primary color. Norma Using Tailwind the following produces the exact same result: ``` -
    - Yippee I am a primary color! +
    + Yippee I am a brand color!
    ``` @@ -266,7 +266,7 @@ export const ProductItem: FunctionComponent = ({
    ...
    -
    +
    {htmlStringDecode(productView.name)}
    = ({
    {title && {title}} {!loading && ( - {results} + {results} )}
    diff --git a/src/components/ProductItem/ProductItem.tsx b/src/components/ProductItem/ProductItem.tsx index 469d1c82..3a4363e2 100644 --- a/src/components/ProductItem/ProductItem.tsx +++ b/src/components/ProductItem/ProductItem.tsx @@ -175,7 +175,7 @@ export const ProductItem: FunctionComponent = ({
    {/* Image */} {productImageArray.length ? ( @@ -202,19 +202,19 @@ export const ProductItem: FunctionComponent = ({ -
    +
    {product.name !== null && htmlStringDecode(product.name)}
    -
    +
    SKU: {product.sku !== null && htmlStringDecode(product.sku)}
    {/* Swatch */} -
    +
    {productView?.options?.map( (swatches) => swatches.id === 'color' && ( @@ -236,7 +236,7 @@ export const ProductItem: FunctionComponent = ({ = ({ />
    -
    +
    {product.short_description?.html ? ( <> @@ -295,7 +295,7 @@ export const ProductItem: FunctionComponent = ({
    @@ -350,7 +350,7 @@ export const ProductItem: FunctionComponent = ({ {productView?.options && productView.options?.length > 0 && ( -
    +
    {productView?.options?.map( (swatches) => swatches.id == 'color' && ( diff --git a/src/components/SliderDoubleControl/SliderDoubleControl.tsx b/src/components/SliderDoubleControl/SliderDoubleControl.tsx index ed34da73..d2a7acae 100644 --- a/src/components/SliderDoubleControl/SliderDoubleControl.tsx +++ b/src/components/SliderDoubleControl/SliderDoubleControl.tsx @@ -198,7 +198,7 @@ export const SliderDoubleControl: FunctionComponent = ({ return (
    -
    - + Between{' '} - + {formatLabel(minVal)} {' '} and{' '} - + {formatLabel(maxVal)} diff --git a/src/components/SwatchButtonGroup/SwatchButtonGroup.tsx b/src/components/SwatchButtonGroup/SwatchButtonGroup.tsx index a5a31d89..957a841f 100644 --- a/src/components/SwatchButtonGroup/SwatchButtonGroup.tsx +++ b/src/components/SwatchButtonGroup/SwatchButtonGroup.tsx @@ -42,7 +42,7 @@ export const SwatchButtonGroup: FunctionComponent = ({ return ( swatch && swatch.type == 'COLOR_HEX' && ( -
    +
    = ({ ); })} -
    +
    = ({ return ( swatch && swatch.type == 'COLOR_HEX' && ( -
    +
    {
    {title && {title}} {!productsCtx.loading && ( - + {getResults(productsCtx.totalCount)} )} diff --git a/src/styles/index.css b/src/styles/index.css index a5dfbaa7..c0515503 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -1181,6 +1181,9 @@ video { .font-semibold { font-weight: var(--font-semibold); } + .\!text-brand-700 { + color: var(--color-brand-700) !important; + } .text-black { --tw-text-opacity: 1; color: rgb(0 0 0 / var(--tw-text-opacity)); @@ -1206,14 +1209,6 @@ video { .text-brand-700 { color: var(--color-brand-700); } - .text-gray-700 { - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); - } - .text-gray-900 { - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); - } .text-green-400 { --tw-text-opacity: 1; color: rgb(74 222 128 / var(--tw-text-opacity)); @@ -1641,6 +1636,10 @@ video { color: rgb(37 99 235 / var(--tw-text-opacity)); } +.hover\:text-brand-700:hover { + color: var(--color-brand-700); +} + .hover\:text-neutral-900:hover { color: var(--color-neutral-900); } From 719a2d6fe11b6277790e006cf6db80a9d956d6c3 Mon Sep 17 00:00:00 2001 From: "Mark J. Becker" Date: Mon, 11 Mar 2024 17:43:08 +0100 Subject: [PATCH 007/160] Replace MSE SDK with direct access to ACDL --- dev-template.html | 70 ++++++------ src/api/search.ts | 22 ++-- src/components/ProductItem/ProductItem.tsx | 14 ++- src/context/events.tsx | 123 ++++++++++----------- src/types/globals.d.ts | 4 +- 5 files changed, 113 insertions(+), 120 deletions(-) diff --git a/dev-template.html b/dev-template.html index 93a5f19b..adba2697 100644 --- a/dev-template.html +++ b/dev-template.html @@ -13,6 +13,11 @@ referrerpolicy="no-referrer" /> + + - + diff --git a/package.json b/package.json index 3daf47c3..dcbde6aa 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "lint:fix": "eslint '*/**/*.{ts,tsx}' --fix", "prettier:fix": "prettier 'src/**/*.{ts,tsx,json,md}' --write", "test": "jest --passWithNoTests --color --silent", - "cleanup": "rimraf dist" + "cleanup": "rimraf dist", + "copy-build-search": "cp -r dist/search.js" }, "dependencies": { "@headlessui/react": "^1.7.17", diff --git a/src/components/CategoryFilters/CategoryFilters.tsx b/src/components/CategoryFilters/CategoryFilters.tsx index 1be7bb6d..ac6bcbc2 100644 --- a/src/components/CategoryFilters/CategoryFilters.tsx +++ b/src/components/CategoryFilters/CategoryFilters.tsx @@ -27,21 +27,21 @@ interface CategoryFiltersProps { } export const CategoryFilters: FunctionComponent = ({ - loading, + // loading, pageLoading, totalCount, facets, - categoryName, - phrase, - setShowFilters, - filterCount, + // categoryName, + // phrase, + // setShowFilters, + // filterCount, }) => { const translation = useTranslation(); - let title = categoryName || ''; - if (phrase) { - const text = translation.CategoryFilters.results; - title = text.replace('{phrase}', `"${phrase}"`); - } + const title = translation.Filter.title; // categoryName || ''; + // if (phrase) { + // const text = translation.CategoryFilters.results; + // title = text.replace('{phrase}', `"${phrase}"`); + // } const resultsTranslation = translation.CategoryFilters.products; const results = resultsTranslation.replace('{totalCount}', `${totalCount}`); @@ -49,21 +49,21 @@ export const CategoryFilters: FunctionComponent = ({
    {title && {title}} - {!loading && ( + {/* {!loading && ( {results} - )} + )} */}
    {!pageLoading && facets.length > 0 && ( <>
    - setShowFilters(false)} type="desktop" title={`${translation.Filter.hideTitle}${ filterCount > 0 ? ` (${filterCount})` : '' }`} - /> + /> */}
    diff --git a/src/components/ImageHover/ImageHover.css b/src/components/ImageHover/ImageHover.css new file mode 100644 index 00000000..4cef2885 --- /dev/null +++ b/src/components/ImageHover/ImageHover.css @@ -0,0 +1,7 @@ +.ds-sdk-product-image-hover { + background-image: var(--image-url); +} + +.ds-sdk-product-image-hover:hover { + background-image: var(--hover-url); +} \ No newline at end of file diff --git a/src/components/ImageHover/ImageHover.stories.mdx b/src/components/ImageHover/ImageHover.stories.mdx new file mode 100644 index 00000000..a6ef09f3 --- /dev/null +++ b/src/components/ImageHover/ImageHover.stories.mdx @@ -0,0 +1,32 @@ +import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs'; +import { ImageHover } from '../ImageHover'; + + + +export const Template = (args) => ; + +# ImageHover + +``` +import { ImageHover } from '../ImageHover' +``` + + + + {Template.bind({})} + + diff --git a/src/components/ImageHover/ImageHover.test.tsx b/src/components/ImageHover/ImageHover.test.tsx new file mode 100644 index 00000000..6654c887 --- /dev/null +++ b/src/components/ImageHover/ImageHover.test.tsx @@ -0,0 +1,26 @@ +/* +Copyright 2024 Adobe +All Rights Reserved. + +NOTICE: Adobe permits you to use, modify, and distribute this file in +accordance with the terms of the Adobe license agreement accompanying +it. +*/ + +import { render } from '@testing-library/preact'; + +import { ImageHover } from './ImageHover'; + +describe('WidgetSDK - UIKit/ImageCarousel', () => { + test('renders', () => { + const { container } = render( + + ); + + const elem = container.querySelector('.ds-sdk-product-image-hover'); + + expect(!!elem).toEqual(true); + }); +}); diff --git a/src/components/ImageHover/ImageHover.tsx b/src/components/ImageHover/ImageHover.tsx new file mode 100644 index 00000000..a5882056 --- /dev/null +++ b/src/components/ImageHover/ImageHover.tsx @@ -0,0 +1,35 @@ +/* +Copyright 2024 Adobe +All Rights Reserved. + +NOTICE: Adobe permits you to use, modify, and distribute this file in +accordance with the terms of the Adobe license agreement accompanying +it. +*/ + +import { FunctionComponent } from 'preact'; + +import './ImageHover.css'; + +export interface ImageCarouselProps { + images: string[] | { src: string; srcset: any }[]; +} + +export const ImageHover: FunctionComponent = ({ + images, +}) => { + + return ( + <> + {images.length > 1 && ( + + )} +
    + + ); +}; diff --git a/src/components/ImageHover/index.ts b/src/components/ImageHover/index.ts new file mode 100644 index 00000000..8b8dac04 --- /dev/null +++ b/src/components/ImageHover/index.ts @@ -0,0 +1,11 @@ +/* +Copyright 2024 Adobe +All Rights Reserved. + +NOTICE: Adobe permits you to use, modify, and distribute this file in +accordance with the terms of the Adobe license agreement accompanying +it. +*/ + +export * from './ImageHover'; +export { ImageHover as default } from './ImageHover'; diff --git a/src/components/ProductCardShimmer/ProductCardShimmer.css b/src/components/ProductCardShimmer/ProductCardShimmer.css index 822645a0..1c4e82f6 100644 --- a/src/components/ProductCardShimmer/ProductCardShimmer.css +++ b/src/components/ProductCardShimmer/ProductCardShimmer.css @@ -1,3 +1,7 @@ +/* .ds-sdk-product-item { + border: 1px solid #e5e7eb; +} */ + .ds-sdk-product-item--shimmer { margin: 0.625rem auto; box-shadow: rgba(149, 157, 165, 0.2) 0px 0.5rem 1.5rem; diff --git a/src/components/ProductItem/ProductItem.tsx b/src/components/ProductItem/ProductItem.tsx index 0578909d..59fb0e7f 100644 --- a/src/components/ProductItem/ProductItem.tsx +++ b/src/components/ProductItem/ProductItem.tsx @@ -12,7 +12,7 @@ import { useState } from 'preact/hooks'; import '../ProductItem/ProductItem.css'; -import { useCart, useProducts, useSensor, useStore } from '../../context'; +import { useCart, useProducts, useStore } from '../../context'; import NoImage from '../../icons/NoImage.svg'; import { Product, @@ -27,7 +27,7 @@ import { } from '../../utils/getProductImage'; import { htmlStringDecode } from '../../utils/htmlStringDecode'; import { AddToCartButton } from '../AddToCartButton'; -import { ImageCarousel } from '../ImageCarousel'; +import ImageHover from '../ImageHover'; import { SwatchButtonGroup } from '../SwatchButtonGroup'; import ProductPrice from './ProductPrice'; @@ -47,6 +47,10 @@ export interface ProductProps { ) => Promise; } +const SWATCH_COLORS = 'Colors'; +const SWATCH_COLORS_TEAM = 'Colors / Team'; +const SWATCH_COLORS_TEAM_NAME = 'Colors / Team name'; + export const ProductItem: FunctionComponent = ({ item, currencySymbol, @@ -59,39 +63,40 @@ export const ProductItem: FunctionComponent = ({ addToCart, }: ProductProps) => { const { product, productView } = item; - const [carouselIndex, setCarouselIndex] = useState(0); const [selectedSwatch, setSelectedSwatch] = useState(''); const [imagesFromRefinedProduct, setImagesFromRefinedProduct] = useState< ProductViewMedia[] | null >(); const [refinedProduct, setRefinedProduct] = useState(); - const [isHovering, setIsHovering] = useState(false); + // const [isHovering, setIsHovering] = useState(false); const { addToCartGraphQL, refreshCart } = useCart(); const { viewType } = useProducts(); const { - config: { optimizeImages, imageBaseWidth, imageCarousel, listview }, + config: { optimizeImages, imageBaseWidth, listview }, } = useStore(); - const { screenSize } = useSensor(); + console.log('BIM!!'); - const handleMouseOver = () => { - setIsHovering(true); - }; + // const { screenSize } = useSensor(); - const handleMouseOut = () => { - setIsHovering(false); - }; + // const handleMouseOver = () => { + // setIsHovering(true); + // }; + + // const handleMouseOut = () => { + // setIsHovering(false); + // }; const handleSelection = async (optionIds: string[], sku: string) => { const data = await refineProduct(optionIds, sku); setSelectedSwatch(optionIds[0]); setImagesFromRefinedProduct(data.refineProduct.images); setRefinedProduct(data); - setCarouselIndex(0); }; - + /** TEMP FIX to show image of the first variant per product */ const loadProductImagesFromRefinedProduct = async (optionIds: string[], sku: string) => { + console.log('loadProductImagesFromRefinedProduct', optionIds, sku); const data = await refineProduct(optionIds, sku); setImagesFromRefinedProduct(data.refineProduct.images); }; @@ -107,11 +112,14 @@ export const ProductItem: FunctionComponent = ({ return selected; }; + console.log('imagesFromRefinedProduct', imagesFromRefinedProduct); + console.log('productView.images', productView.images); + const productImageArray = imagesFromRefinedProduct - ? getProductImageURLs(imagesFromRefinedProduct ?? [], imageCarousel ? 3 : 1) + ? getProductImageURLs(imagesFromRefinedProduct ?? [], 2) : getProductImageURLs( productView.images ?? [], - imageCarousel ? 3 : 1, // number of images to display in carousel + 2, product.image?.url ?? undefined ); let optimizedImageArray: { src: string; srcset: any }[] = []; @@ -123,6 +131,10 @@ export const ProductItem: FunctionComponent = ({ ); } + console.log('optimizedImageArray', optimizedImageArray); + console.log('optimizedImageArray.length', optimizedImageArray.length); + console.log('productImageArray', productImageArray); + // will have to figure out discount logic for amount_off and percent_off still const discount: boolean = refinedProduct ? refinedProduct.refineProduct?.priceRange?.minimum?.regular?.amount @@ -188,7 +200,7 @@ export const ProductItem: FunctionComponent = ({ <>
    -
    + @@ -303,12 +315,12 @@ export const ProductItem: FunctionComponent = ({ return (
    = ({ className="!text-brand-700 hover:no-underline hover:text-brand-700" >
    -
    +
    {productImageArray.length ? ( - ) : ( = ({ /> )}
    -
    + + {productView?.options && productView.options?.length > 0 && ( +
    + {productView?.options?.map( + (swatches) => { + if (swatches.title === SWATCH_COLORS) { + // // console.log('v', v); + // swatches.values?.forEach((v) => { + // console.log('productView', productView.name); + // console.log('v', v); + // }); + + return ( + + ); + } else if ([SWATCH_COLORS_TEAM, SWATCH_COLORS_TEAM_NAME].includes(swatches.title || '')) { + console.log('swatches', swatches); + // console.log(swatches.values?.map((s) => s.id)) + // console.log('product?.sku', refinedProduct?.refineProduct.sku); + // const ddd = await refineProduct(swatches.values?.map((s) => s.id) || [], "WF40035$"); + // console.log('refineProduct data', ddd); + + // swatches.values?.forEach((v) => { + // console.log('productView', productView.name); + // console.log('v', v); + // }); + + return ( + + ); + } + + + } + )} +
    + )} + +
    -
    +
    {product.name !== null && htmlStringDecode(product.name)}
    = ({
    - {productView?.options && productView.options?.length > 0 && ( -
    - {productView?.options?.map( - (swatches) => - swatches.id == 'color' && ( - - ) - )} -
    - )} -
    + {/*
    {screenSize.mobile && } {isHovering && screenSize.desktop && ( )} -
    +
    */}
    ); }; diff --git a/src/components/ProductItem/ProductPrice.tsx b/src/components/ProductItem/ProductPrice.tsx index dc1e5154..6de241bb 100644 --- a/src/components/ProductItem/ProductPrice.tsx +++ b/src/components/ProductItem/ProductPrice.tsx @@ -37,6 +37,7 @@ export const ProductPrice: FunctionComponent = ({ currencySymbol, currencyRate, }: ProductPriceProps) => { + console.log('discount', discount); const translation = useContext(TranslationContext); let price; @@ -59,21 +60,21 @@ export const ProductPrice: FunctionComponent = ({ return bundlePriceTranslationOrder.map((word: string, index: any) => word === '{fromBundlePrice}' ? ( {getProductPrice(item, currencySymbol, currencyRate, false, true)} ) : word === '{toBundlePrice}' ? ( {getProductPrice(item, currencySymbol, currencyRate, true, true)} ) : ( {word} @@ -112,7 +113,7 @@ export const ProductPrice: FunctionComponent = ({ {getProductPrice(item, currencySymbol, currencyRate, false, false)} - + {getProductPrice(item, currencySymbol, currencyRate, false, true)} @@ -122,18 +123,19 @@ export const ProductPrice: FunctionComponent = ({ const discountedPriceTranslation = translation.ProductCard.asLowAs; const discountedPriceTranslationOrder = discountedPriceTranslation.split('{discountPrice}'); - return discountedPriceTranslationOrder.map((word: string, index: any) => - word === '' ? ( - discountPrice - ) : ( - - {word} - - ) - ); + return discountPrice; + // return discountedPriceTranslationOrder.map((word: string, index: any) => + // word === '' ? ( + // discountPrice + // ) : ( + // + // {word} + // + // ) + // ); }; return ( @@ -145,7 +147,7 @@ export const ProductPrice: FunctionComponent = ({ !isConfigurable && !isComplexProductView && discount && ( -

    +

    {getProductPrice( item, @@ -173,7 +175,7 @@ export const ProductPrice: FunctionComponent = ({ !isConfigurable && !isComplexProductView && !discount && ( -

    +

    {getProductPrice( item, currencySymbol, @@ -186,20 +188,20 @@ export const ProductPrice: FunctionComponent = ({ {isBundle && (

    -

    +

    {getBundledPrice(item, currencySymbol, currencyRate)}

    )} {isGrouped && ( -

    +

    {getPriceFormat(item, currencySymbol, currencyRate, false)}

    )} {isGiftCard && ( -

    +

    {getPriceFormat(item, currencySymbol, currencyRate, true)}

    )} @@ -207,7 +209,7 @@ export const ProductPrice: FunctionComponent = ({ {!isGrouped && !isBundle && (isConfigurable || isComplexProductView) && ( -

    +

    {getDiscountedPrice(discount)}

    )} diff --git a/src/components/ProductList/ProductList.tsx b/src/components/ProductList/ProductList.tsx index 57a06794..2e5ef47d 100644 --- a/src/components/ProductList/ProductList.tsx +++ b/src/components/ProductList/ProductList.tsx @@ -107,7 +107,7 @@ export const ProductList: FunctionComponent = ({ style={{ gridTemplateColumns: `repeat(${numberOfColumns}, minmax(0, 1fr))`, }} - className="ds-sdk-product-list__grid mt-md grid gap-y-8 gap-x-2xl xl:gap-x-8" + className="ds-sdk-product-list__grid mt-md grid gap-y-8 gap-x-md xl:gap-x-6" > {products?.map((product) => ( = ({ <>
    + +
    + ); + } + if (type === 'COLOR_HEX') { const color = value.toLowerCase(); const className = `min-w-[32px] rounded-full p-sm border border-[1.5px] ${outlineColor} h-[32px] outline-transparent`; @@ -36,6 +59,7 @@ export const SwatchButton: FunctionComponent = ({ return (
    ); diff --git a/src/styles/index.css b/src/styles/index.css index 5b2b6d5c..9c49262b 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -731,15 +731,15 @@ video { .w-\[12px\] { width: 12px; } + .w-\[14px\] { + width: 14px; + } .w-\[15px\] { width: 15px; } .w-\[20px\] { width: 20px; } - .w-\[24px\] { - width: 24px; - } .w-fit { width: -moz-fit-content; width: fit-content; @@ -986,9 +986,6 @@ video { --tw-bg-opacity: 1; background-color: rgb(239 246 255 / var(--tw-bg-opacity)); } - .bg-brand-500 { - background-color: var(--color-brand-500); - } .bg-gray-100 { --tw-bg-opacity: 1; background-color: rgb(243 244 246 / var(--tw-bg-opacity)); @@ -1045,9 +1042,6 @@ video { .stroke-1 { stroke-width: var(--shape-icon-stroke-1); } - .stroke-2 { - stroke-width: var(--shape-icon-stroke-2); - } .object-cover { -o-object-fit: cover; object-fit: cover; @@ -1138,9 +1132,6 @@ video { .pr-2 { padding-right: 0.5rem; } - .pr-4 { - padding-right: 1rem; - } .pr-5 { padding-right: 1.25rem; } @@ -1261,10 +1252,6 @@ video { --tw-text-opacity: 1; color: rgb(153 27 27 / var(--tw-text-opacity)); } - .text-white { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - } .text-yellow-400 { --tw-text-opacity: 1; color: rgb(250 204 21 / var(--tw-text-opacity)); @@ -1627,6 +1614,14 @@ video { background-color: var(--color-port-royale); } +.ds-sdk-add-to-cart-button { + background-color: var(--color-neutral-50); + color: var(--color-brand-700); + padding: var(--spacing-xs); + font-size: var(--font-sm); + font-weight: var(--font-medium); + cursor: pointer; +} .ds-sdk-product-image-hover { transition: background-image .5s cubic-bezier(0.455, 0.03, 0.515, 0.955) .2s; diff --git a/src/styles/tokens.css b/src/styles/tokens.css index 41a4efec..58f4406e 100644 --- a/src/styles/tokens.css +++ b/src/styles/tokens.css @@ -277,6 +277,15 @@ background-color: var(--color-port-royale); } +.ds-sdk-add-to-cart-button { + background-color: var(--color-neutral-50); + color: var(--color-brand-700); + padding: var(--spacing-xs); + font-size: var(--font-sm); + font-weight: var(--font-medium); + cursor: pointer; +} + .ds-sdk-product-image-hover { transition: background-image .5s cubic-bezier(0.455, 0.03, 0.515, 0.955) .2s; } From 625c343da81498a67190517fb3cb0bd329918fa1 Mon Sep 17 00:00:00 2001 From: david catalan Date: Fri, 5 Apr 2024 14:04:04 +0200 Subject: [PATCH 016/160] chore: cleanup --- src/components/ProductItem/ProductItem.tsx | 37 +--------------------- 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/src/components/ProductItem/ProductItem.tsx b/src/components/ProductItem/ProductItem.tsx index a676e2fb..b5a43256 100644 --- a/src/components/ProductItem/ProductItem.tsx +++ b/src/components/ProductItem/ProductItem.tsx @@ -75,7 +75,6 @@ export const ProductItem: FunctionComponent = ({ config: { optimizeImages, imageBaseWidth, listview }, } = useStore(); - console.log('BIM!!'); const { screenSize } = useSensor(); const handleMouseOver = () => { @@ -95,9 +94,8 @@ export const ProductItem: FunctionComponent = ({ /** TEMP FIX to show image of the first variant per product */ const loadProductImagesFromRefinedProduct = async (optionIds: string[], sku: string) => { - console.log('loadProductImagesFromRefinedProduct', optionIds, sku); const data = await refineProduct(optionIds, sku); - setImagesFromRefinedProduct(data.refineProduct.images); + setImagesFromRefinedProduct(data.refineProduct?.images); }; if (!productView.images?.length && !imagesFromRefinedProduct){ @@ -111,9 +109,6 @@ export const ProductItem: FunctionComponent = ({ return selected; }; - console.log('imagesFromRefinedProduct', imagesFromRefinedProduct); - console.log('productView.images', productView.images); - const productImageArray = imagesFromRefinedProduct ? getProductImageURLs(imagesFromRefinedProduct ?? [], 2) : getProductImageURLs( @@ -130,10 +125,6 @@ export const ProductItem: FunctionComponent = ({ ); } - console.log('optimizedImageArray', optimizedImageArray); - console.log('optimizedImageArray.length', optimizedImageArray.length); - console.log('productImageArray', productImageArray); - // will have to figure out discount logic for amount_off and percent_off still const discount: boolean = refinedProduct ? refinedProduct.refineProduct?.priceRange?.minimum?.regular?.amount @@ -356,12 +347,6 @@ export const ProductItem: FunctionComponent = ({ {productView?.options?.map( (swatches) => { if (swatches.title === SWATCH_COLORS) { - // // console.log('v', v); - // swatches.values?.forEach((v) => { - // console.log('productView', productView.name); - // console.log('v', v); - // }); - return ( = ({ /> ); } else if ([SWATCH_COLORS_TEAM, SWATCH_COLORS_TEAM_NAME].includes(swatches.title || '')) { - console.log('swatches', swatches); - // console.log(swatches.values?.map((s) => s.id)) - // console.log('product?.sku', refinedProduct?.refineProduct.sku); - // const ddd = await refineProduct(swatches.values?.map((s) => s.id) || [], "WF40035$"); - // console.log('refineProduct data', ddd); - - // swatches.values?.forEach((v) => { - // console.log('productView', productView.name); - // console.log('v', v); - // }); - return ( = ({ /> ); } - - } )}
    @@ -436,13 +408,6 @@ export const ProductItem: FunctionComponent = ({
    - - {/*
    - {screenSize.mobile && } - {isHovering && screenSize.desktop && ( - - )} -
    */}
    ); }; From 949ca52610820b51539f11d500e4950f86dd55ee Mon Sep 17 00:00:00 2001 From: "Mark J. Becker" Date: Thu, 16 May 2024 14:55:24 +0200 Subject: [PATCH 017/160] Use categoryPath for filtering --- src/context/products.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/context/products.tsx b/src/context/products.tsx index ac14c643..473897e3 100644 --- a/src/context/products.tsx +++ b/src/context/products.tsx @@ -349,9 +349,7 @@ const ProductsContextProvider = ({ children }: WithChildrenProps) => { eq: categoryPath, }; filters.push(categoryFilter); - } - - if (categoryId) { + } else if (categoryId) { const categoryIdFilter = { attribute: 'categoryIds', eq: categoryId, From caed3de477a6e995c24e2d5ee3f2d50453ecf1f7 Mon Sep 17 00:00:00 2001 From: Johnny Ung Date: Mon, 10 Jun 2024 11:15:54 -0700 Subject: [PATCH 018/160] WIP filters --- dev-template.html | 8 +- .../CategoryFilters/CategoryFilters.tsx | 4 +- src/components/Facets/Facets.tsx | 7 +- src/components/Facets/Scalar/ScalarFacet.tsx | 19 ++-- src/components/Facets/SelectedFilters.tsx | 2 + src/components/Facets/format.ts | 1 + .../InputButtonGroup/InputButtonGroup.tsx | 93 +++++++++++-------- .../LabelledInput/LabelledInput.tsx | 2 +- src/components/ProductItem/ProductPrice.tsx | 1 - .../SwatchButtonGroup/SwatchButtonGroup.tsx | 1 - src/containers/App.tsx | 2 +- src/styles/index.css | 7 ++ 12 files changed, 88 insertions(+), 59 deletions(-) diff --git a/dev-template.html b/dev-template.html index 03fdf03b..10fd18be 100644 --- a/dev-template.html +++ b/dev-template.html @@ -73,9 +73,9 @@ displaySearchBox: true, // display search box displayOutOfStock: true, allowAllProducts: false, - // currentCategoryUrlPath?: '', // current category url path, please prefer using currentCategoryId - // currentCategoryId?: '', // current category id - // categoryName: '', // name of category to display + currentCategoryUrlPath: 'baseball', // current category url path, please prefer using currentCategoryId + currentCategoryId: '107', // current category id + categoryName: 'Baseball', // name of category to display // displaySearchBox: false, // display search box // displayOutOfStock: '', // "1" will return from php escapeJs and boolean is returned if called from data-service-graphql // displayMode: '', // "" for search || "PAGE" for category search @@ -92,7 +92,7 @@ context: { customerGroup: '0', }, - apiKey: '', + apiKey: '95689dc242b0433da022462d27547b30', environmentType: '', // searchQuery: 'search_query', // Optional: providing searchQuery will override 'q' query param // route: ({ sku, urlKey }) => { diff --git a/src/components/CategoryFilters/CategoryFilters.tsx b/src/components/CategoryFilters/CategoryFilters.tsx index ac6bcbc2..81b5debb 100644 --- a/src/components/CategoryFilters/CategoryFilters.tsx +++ b/src/components/CategoryFilters/CategoryFilters.tsx @@ -45,8 +45,10 @@ export const CategoryFilters: FunctionComponent = ({ const resultsTranslation = translation.CategoryFilters.products; const results = resultsTranslation.replace('{totalCount}', `${totalCount}`); + // sm:flex ds-widgets-_actions relative max-width-[480px] flex-[25] px-2 flex-col overflow-y-auto top-[6.4rem] right-0 bottom-[48px] left-0 box-content + return ( -
    +
    {title && {title}} {/* {!loading && ( diff --git a/src/components/Facets/Facets.tsx b/src/components/Facets/Facets.tsx index a0f9de29..5af05e95 100644 --- a/src/components/Facets/Facets.tsx +++ b/src/components/Facets/Facets.tsx @@ -14,6 +14,7 @@ import { Facet as FacetType, PriceFacet } from '../../types/interface'; import SliderDoubleControl from '../SliderDoubleControl'; import { RangeFacet } from './Range/RangeFacet'; import { ScalarFacet } from './Scalar/ScalarFacet'; +import { SelectedFilters } from './SelectedFilters'; interface FacetsProps { searchFacets: FacetType[]; @@ -25,9 +26,12 @@ export const Facets: FunctionComponent = ({ const { config: { priceSlider }, } = useStore(); + + console.log('this is searchFacets', searchFacets); + return (
    - + {searchFacets?.map((facet) => { const bucketType = facet?.buckets[0]?.__typename; switch (bucketType) { @@ -49,6 +53,7 @@ export const Facets: FunctionComponent = ({ } })} +
    ); }; diff --git a/src/components/Facets/Scalar/ScalarFacet.tsx b/src/components/Facets/Scalar/ScalarFacet.tsx index 1233a6ed..cae16c90 100644 --- a/src/components/Facets/Scalar/ScalarFacet.tsx +++ b/src/components/Facets/Scalar/ScalarFacet.tsx @@ -8,6 +8,7 @@ it. */ import { FunctionComponent } from 'preact'; +import { useState } from 'preact/compat'; import useScalarFacet from '../../../hooks/useScalarFacet'; import { Facet as FacetType, PriceFacet } from '../../../types/interface'; @@ -23,13 +24,15 @@ export const ScalarFacet: FunctionComponent = ({ const { isSelected, onChange } = useScalarFacet(filterData); return ( - onChange(args.value, args.selected)} - /> + <> + onChange(args.value, args.selected)} + /> + ); }; diff --git a/src/components/Facets/SelectedFilters.tsx b/src/components/Facets/SelectedFilters.tsx index 75a012ac..db721540 100644 --- a/src/components/Facets/SelectedFilters.tsx +++ b/src/components/Facets/SelectedFilters.tsx @@ -18,6 +18,8 @@ export const SelectedFilters: FunctionComponent = ({}) => { const productsCtx = useProducts(); const translation = useTranslation(); + console.log('productCtx', productsCtx) + return (
    {searchCtx.filters?.length > 0 && ( diff --git a/src/components/Facets/format.ts b/src/components/Facets/format.ts index a102371c..fb645e28 100644 --- a/src/components/Facets/format.ts +++ b/src/components/Facets/format.ts @@ -40,6 +40,7 @@ const formatBinaryLabel = ( categoryPath?: string ) => { if (categoryPath && categoryNames) { + console.log('working2') const category = categoryNames.find( (facet) => facet.attribute === filter.attribute && facet.value === option ); diff --git a/src/components/InputButtonGroup/InputButtonGroup.tsx b/src/components/InputButtonGroup/InputButtonGroup.tsx index 19bad082..cc78fe0b 100644 --- a/src/components/InputButtonGroup/InputButtonGroup.tsx +++ b/src/components/InputButtonGroup/InputButtonGroup.tsx @@ -60,6 +60,12 @@ export const InputButtonGroup: FunctionComponent = ({ buckets.length < numberOfOptionsShown ); + const [showOptions, setShowOptions] = useState(false); + + const handleOptions = () => { + setShowOptions(!showOptions) + } + const numberOfOptions = showMore ? buckets.length : numberOfOptionsShown; const onInputChange = (title: string, e: ChangeEvent) => { @@ -112,54 +118,59 @@ export const InputButtonGroup: FunctionComponent = ({ }; return ( -
    +
    {inputGroupTitleSlot ? ( inputGroupTitleSlot(title) ) : ( -
    + + )}
    ); }; diff --git a/src/components/LabelledInput/LabelledInput.tsx b/src/components/LabelledInput/LabelledInput.tsx index 2a1d7bcd..70d26885 100644 --- a/src/components/LabelledInput/LabelledInput.tsx +++ b/src/components/LabelledInput/LabelledInput.tsx @@ -50,7 +50,7 @@ export const LabelledInput: FunctionComponent = ({ />