Skip to content

Commit

Permalink
Merge pull request #57 from Shopify/@juanpprieto/useCart
Browse files Browse the repository at this point in the history
useCart + useCountries
  • Loading branch information
juanpprieto committed Oct 5, 2022
2 parents f104d25 + 3e93532 commit cdde7ec
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 178 deletions.
170 changes: 76 additions & 94 deletions app/components/CountrySelector.tsx
Original file line number Diff line number Diff line change
@@ -1,108 +1,90 @@
import { Link, useAsyncValue, useLocation, Await, useParams } from "@remix-run/react";
import { Country } from "@shopify/hydrogen-ui-alpha/storefront-api-types";

import { Link, useLocation, useParams } from "@remix-run/react";
import {Listbox} from '@headlessui/react';
import { useState, Suspense } from "react";
import { IconCaret, IconCheck } from "./Icon";
import {useRef} from 'react';
import { getLocalizationFromLang } from "~/lib/utils";
import {useCountries} from '~/hooks/useCountries'
import {Heading} from '~/components'

export function CountrySelector({
countries,
}: {
countries: Array <Country>;
}) {
return (
<Suspense fallback={<CountrySelectorFallback />}>
<Await resolve={countries}>
<CountrySelectorElement />
</Await>
</Suspense>
)
}

function CountrySelectorFallback() {
return (
<div className="relative">
<Listbox>
<Listbox.Button
className={'flex items-center justify-between w-full py-3 px-4 border rounded border-contrast/30 dark:border-white'}
>
<span>--</span>
<IconCaret direction={'down'} />
</Listbox.Button>
</Listbox>
</div>
)
}

function CountrySelectorElement() {
const [listboxOpen, setListboxOpen] = useState(false);
const countries = useAsyncValue<Array <Country>>();
export function CountrySelector() {
const countries = useCountries();
const closeRef = useRef<HTMLButtonElement | undefined>();
const { pathname } = useLocation();
const { lang } = useParams();
const { language, country } = getLocalizationFromLang(lang);
const languageIsoCode = language.toLowerCase();
const strippedPathname = pathname.replace(new RegExp(`^\/${lang}\/`), '/')
const currentCountry = countries.find(c => c.isoCode === country);
const currentCountry = countries?.find(c => c.isoCode === country);

return (
<div className="relative">
<Listbox>
{({open}) => {
setTimeout(() => setListboxOpen(open));
return (
<>
<Listbox.Button
className={`flex items-center justify-between w-full py-3 px-4 border ${
open ? 'rounded-b md:rounded-t md:rounded-b-none' : 'rounded'
} border-contrast/30 dark:border-white`}
>
<span>{
currentCountry ?
`${currentCountry.name} (${currentCountry.currency.isoCode} ${currentCountry.currency.symbol})` :
'--'
}</span>
<IconCaret direction={open ? 'up' : 'down'} />
</Listbox.Button>
countries && (
<section className="grid gap-4 w-full md:max-w-[335px] md:ml-auto">
<Heading size="lead" className="cursor-default" as="h3">
Country
</Heading>
<div className="relative">
<Listbox>
{({open}) => {
return (
<>
<Listbox.Button
ref={closeRef}
className={`flex items-center justify-between w-full py-3 px-4 border ${
open ? 'rounded-b md:rounded-t md:rounded-b-none' : 'rounded'
} border-contrast/30 dark:border-white`}
>
<span>{
currentCountry ?
`${currentCountry.name} (${currentCountry.currency.isoCode} ${currentCountry.currency.symbol})` :
'--'
}</span>
<IconCaret direction={open ? 'up' : 'down'} />
</Listbox.Button>

<Listbox.Options
className={`border-t-contrast/30 border-contrast/30 bg-primary dark:bg-contrast absolute bottom-12 z-10 grid
h-48 w-full overflow-y-scroll rounded-t border dark:border-white px-2 py-2
transition-[max-height] duration-150 sm:bottom-auto md:rounded-b md:rounded-t-none
md:border-t-0 md:border-b ${
listboxOpen ? 'max-h-48' : 'max-h-0'
}`}
>
{listboxOpen && Object.values(countries).map(country => {
const isSelected = country.isoCode === currentCountry?.isoCode;
const countryIsoCode = country.isoCode.toLowerCase();
return (
<Listbox.Option key={country.isoCode} value={country}>
{({active}) => (
<Link
to={countryIsoCode !== 'us' ? `/${languageIsoCode}-${countryIsoCode}${strippedPathname}` : strippedPathname}
className={`text-contrast dark:text-primary text-contrast dark:text-primary bg-primary
dark:bg-contrast w-full p-2 transition rounded
flex justify-start items-center text-left cursor-pointer ${
active ? 'bg-primary/10' : null
}`}
>
{country.name} ({country.currency.isoCode} {country.currency.symbol})
{isSelected ? (
<span className="ml-2">
<IconCheck />
</span>
) : null}
</Link>
)}
</Listbox.Option>
);
})}
</Listbox.Options>
</>
);
}}
</Listbox>
</div>
<Listbox.Options
className={`border-t-contrast/30 border-contrast/30 bg-primary dark:bg-contrast absolute bottom-12 z-10 grid
h-48 w-full overflow-y-scroll rounded-t border dark:border-white px-2 py-2
transition-[max-height] duration-150 sm:bottom-auto md:rounded-b md:rounded-t-none
md:border-t-0 md:border-b ${
open ? 'max-h-48' : 'max-h-0'
}`}
>
{open && Object.values(countries).map(country => {
const isSelected = country.isoCode === currentCountry?.isoCode;
const countryIsoCode = country.isoCode.toLowerCase();
return (
<Listbox.Option key={country.isoCode} value={country}>
{({active}) => (
<Link
to={countryIsoCode !== 'us' ? `/${languageIsoCode}-${countryIsoCode}${strippedPathname}` : strippedPathname}
className={`text-contrast dark:text-primary text-contrast dark:text-primary bg-primary
dark:bg-contrast w-full p-2 transition rounded
flex justify-start items-center text-left cursor-pointer ${
active ? 'bg-primary/10' : null
}`}
onClick={() => {
if (!closeRef?.current) return;
closeRef?.current?.click();
}}
>
{country.name} ({country.currency.isoCode} {country.currency.symbol})
{isSelected ? (
<span className="ml-2">
<IconCheck />
</span>
) : null}
</Link>
)}
</Listbox.Option>
);
})}
</Listbox.Options>
</>
);
}}
</Listbox>
</div>
</section>
)
);
}
Loading

0 comments on commit cdde7ec

Please sign in to comment.