From 21c858b51964cb719feee11439e14ac53a4f2b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CSalar?= <“salar.sali97@gmail.com”> Date: Tue, 30 Aug 2022 15:21:36 +0300 Subject: [PATCH 1/8] Edited Heading component --- src/components/typography/Heading.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/typography/Heading.tsx b/src/components/typography/Heading.tsx index a476ea4..324d888 100644 --- a/src/components/typography/Heading.tsx +++ b/src/components/typography/Heading.tsx @@ -1,9 +1,20 @@ import React from "react"; +import classNames from "classnames"; type Props = { + className?: string | undefined; children: React.ReactNode; }; -export default function Heading({ children }: Props) { - return <h3 className="text-2xl text-current font-medium leading-relaxed">{children}</h3>; +export default function Heading({ children, className }: Props) { + return ( + <h3 + className={classNames([ + className, + "text-2xl text-current font-medium leading-7 ", + ])} + > + {children} + </h3> + ); } From 6d36b774b2b85dcf46b73c6984631fd0c32fc598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CSalar?= <“salar.sali97@gmail.com”> Date: Tue, 30 Aug 2022 15:31:23 +0300 Subject: [PATCH 2/8] Aspect ratio component --- src/components/AspectRatio.tsx | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/components/AspectRatio.tsx diff --git a/src/components/AspectRatio.tsx b/src/components/AspectRatio.tsx new file mode 100644 index 0000000..be6a1b8 --- /dev/null +++ b/src/components/AspectRatio.tsx @@ -0,0 +1,38 @@ +import classNames from "classnames"; +import React from "react"; + +export type Props = { + /** + * The style of component + */ + className?: string; + /** + * The optional child + */ + children?: React.ReactNode; +}; +const AspectRatio = ({ className, children }: Props) => { + return ( + <div + className={classNames( + "relative overflow-hidden pt-[55%] rounded w-full", + className + )} + > + {children} + </div> + ); +}; + +AspectRatio.Content = function AspectRatioContent({ + className, + children, +}: Props) { + return ( + <div className={classNames([className, "absolute top-0 w-full h-full"])}> + {children} + </div> + ); +}; + +export default AspectRatio; From 4a5afdf01ac2be31a5b3ab5a106e819218494d78 Mon Sep 17 00:00:00 2001 From: filantrop <filantrop83@gmail.com> Date: Thu, 1 Sep 2022 23:56:47 +0300 Subject: [PATCH 3/8] fix icon button for select as new icons --- src/components/Select.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 1670d5d..0310de3 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -6,7 +6,7 @@ import { Fragment } from "react"; import { Listbox, Transition } from "@headlessui/react"; import classNames from "classnames"; import "../index.css"; -import { ReactComponent as SelectIcon } from "../assets/svg/select-arrow.svg"; +import { ReactComponent as SelectIcon } from "../assets/svg/caret-down.svg"; import { Scrollbar } from "react-scrollbars-custom"; /* -------------------------------------------------------------------------- */ @@ -98,10 +98,10 @@ function Select<T>({ displayValueResolver ? displayValueResolver(value) : value }`}</span> <span className={`${SelectIconStyle}`}> - <SelectIcon + <SelectIcon className={`${ open ? "rotate-180 transform" : "font-normal" - } h-2 w-3`} + } h-3 w-4 fill-black hover:fill-black stroke-black`} /> </span> </> @@ -114,12 +114,12 @@ function Select<T>({ leaveTo="opacity-0" > <Listbox.Options className={`${SelectOptionsStyle}`}> - <Scrollbar + {/* <Scrollbar style={{ height: options.length * elementScrollSize, maxHeight: maxScrollSize, }} - > + > */} {options.map((option, id) => ( <Listbox.Option key={id} @@ -139,7 +139,7 @@ function Select<T>({ }`} </Listbox.Option> ))} - </Scrollbar> + {/* </Scrollbar> */} </Listbox.Options> </Transition> </div> From f3ccb0523aadce6b3071e34461ca40e808dcbfd2 Mon Sep 17 00:00:00 2001 From: filantrop <filantrop83@gmail.com> Date: Wed, 7 Sep 2022 14:58:40 +0300 Subject: [PATCH 4/8] fix props in component --- src/components/SearchBar.tsx | 164 +++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/components/SearchBar.tsx diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx new file mode 100644 index 0000000..fae7a83 --- /dev/null +++ b/src/components/SearchBar.tsx @@ -0,0 +1,164 @@ +/* -------------------------------------------------------------------------- */ +/* Imports */ +/* -------------------------------------------------------------------------- */ +import React from "react"; +import classNames from "classnames"; +import "../index.css"; +import { Combobox, Transition } from "@headlessui/react"; +import { Fragment, useEffect, useState } from "react"; +import { Scrollbar } from "react-scrollbars-custom"; +import { Function } from "lodash"; + +/* -------------------------------------------------------------------------- */ +/* Component props */ +/* -------------------------------------------------------------------------- */ +type Hint = { + id: string; + caption: string; +}; + +type Props<T> = { + onChange: (query: string) => void; + onSelected: (value: Hint) => void; + IsEmptyItems: () => React.ReactNode; + hints: Hint[]; + displayValueResolver?: (element: T) => any; + disabled?: boolean; + inGroup?: boolean; + className?: string; + maxScrollSize?: number; + elementScrollSize?: number; + placeHolder?: string; +}; +/* -------------------------------------------------------------------------- */ +/* styles */ +/* -------------------------------------------------------------------------- */ +const inputStyle = ` + w-full + cursor-default + rounded + overflow-hidden + border + border-solid + shadow-none + border-gray-100 + focus:outline-none + focus:border-gray-200 + hover:border-gray-200 + py-2 pl-3 + text-sm + text-gray-900 +`; + +const inputList = ` + absolute z-10 mt-1 w-full max-h-56 + bg-white shadow-lg + rounded py-1 + overflow-hidden + focus:outline-none + text-base + sm:text-sm`; + +const inputInGroup = [ + `border-none + hover:none + active:none + focus:none + `, +]; + +/* -------------------------------------------------------------------------- */ +/* Component implementation */ +/* -------------------------------------------------------------------------- */ + +export default function SearchBar<T>({ + onChange, + onSelected, + hints, + displayValueResolver, + disabled, + inGroup = false, + className, + maxScrollSize = 140, + elementScrollSize = 36, + placeHolder = "Search...", + IsEmptyItems, + ...props +}: Props<T>) { + const [selected, setSelected] = useState<any>(hints); + const [query, setQuery] = useState(""); + + useEffect(() => { + onChange(query); + }, [query, onChange]); + + const handleSelected = (value: Hint) => { + setSelected(value); + onSelected && onSelected(value); + }; + return ( + <div> + <Combobox value={selected} {...props} onChange={handleSelected}> + <div className="relative"> + <div className="relative w-full bg-white text-left focus:outline-none sm:text-sm"> + <Combobox.Input + className={classNames([ + [`${inputStyle}`], + { [`${inputInGroup}`]: inGroup }, + className, + ])} + onChange={(event) => setQuery(event.target.value)} + placeholder={placeHolder} + displayValue={(value: T) => + displayValueResolver ? displayValueResolver(value) : value + } + /> + </div> + <div> + {query.length > 0 && ( + <div className={`${inputList}`}> + <Transition + as={Fragment} + leave="transition ease-in duration-100" + leaveFrom="opacity-100" + leaveTo="opacity-0" + afterLeave={() => setQuery("")} + > + <Combobox.Options> + {hints.length === 0 && query !== "" ? IsEmptyItems() : null} + {/* <Scrollbar + style={{ + height: hints.length * elementScrollSize, + maxHeight: maxScrollSize, + }} + > */} + {hints.map((item: any, id: number) => ( + <Combobox.Option + key={id} + className={({ active, selected }) => + classNames( + active + ? "text-gray-900 bg-blue-50" + : "font-normal ", + "cursor-default select-none relative py-2 pl-3 pr-9", + selected + ? "text-gray-900 bg-blue-100" + : "font-normal " + ) + } + value={item} + > + <div>{item.caption}</div> + </Combobox.Option> + ))} + {/* </Scrollbar> */} + </Combobox.Options> + </Transition> + </div> + )} + </div> + </div> + </Combobox> + </div> + ); +} From f7a5aaf90e15446a65f1d92081cad0f96bca3c37 Mon Sep 17 00:00:00 2001 From: filantrop <filantrop83@gmail.com> Date: Wed, 7 Sep 2022 15:30:31 +0300 Subject: [PATCH 5/8] fix props in component --- src/components/MainSection.tsx | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/components/MainSection.tsx diff --git a/src/components/MainSection.tsx b/src/components/MainSection.tsx new file mode 100644 index 0000000..3bc0ad1 --- /dev/null +++ b/src/components/MainSection.tsx @@ -0,0 +1,105 @@ +/* -------------------------------------------------------------------------- */ +/* Imports */ +/* -------------------------------------------------------------------------- */ +import classNames from "classnames"; +import React from "react"; +import Inputgroup from "./Inputgroup"; +import Select from "./Select"; +import { useState } from "react"; +import { Button } from "./Button/Button"; +import { SVGSearch } from "../components/icons"; +import SearchBar from "components/SearchBar"; + +type Props<T, H> = { + className?: string; + options: T[]; + hintsValues: H[]; + displayValueResolver?: (element: T) => any; +}; + +/* -------------------------------------------------------------------------- */ +/* Component implementation */ +/* -------------------------------------------------------------------------- */ + +export default function MainSection<T, H>({ + className, + options, + hintsValues, + displayValueResolver, + ...props +}: Props<T, H>) { + const [value, setValue] = useState(options[0]); // Category + + const [hints, setHints] = useState<any[]>([]); //Response list + const [onSelected, setOnSelected] = useState(""); // Selected item from response list + const [query, setQuery] = useState(""); // Query + + const onChange = (query: string) => { + //console.log(query) + setQuery(query); + setHints(hintsValues); + }; + const onClick = () => { + console.log(displayValueResolver ? displayValueResolver(value) : value); + console.log(onSelected); + console.log(query); + }; + const searchResolver = (item: any) => { + setOnSelected(item.caption); + console.log(onSelected); + }; + //empty items message + const IsEmptyItems = () => { + return <p className="tex-blue-500">Nothing Found</p>; + }; + + return ( + <div className="bg-main bg-center bg-cover bg-origin-border bg-no-repeat h-full py-32 px-2 sm:px-6 md:px-6 lg:px-0"> + <div className="m-auto text-center font-bold text-4xl "> + Scientific Library with Free Access + </div> + <div className="flex flex-row items-center justify-center space-x-3 pt-2"> + <div className=" text-2xl text-gray-400">Search</div> + <div className=" text-3xl text-blue-500">320 455</div> + <div className=" text-2xl text-gray-400">Items</div> + </div> + <div className="max-w-xl m-auto pt-16"> + <Inputgroup className="m-0 p-0"> + <div className="flex items-center w-full divide-x-2 divide-solid divide-gray-200"> + <div className="flex w-1/3"> + <Select + inGroup={true} + className="w-full top-0" + options={options} + value={value} + onChange={setValue} + displayValueResolver={(value: any) => value?.name ?? ""} + /> + </div> + <div className="w-full"> + <SearchBar + className="w-full" + hints={hints} + onChange={onChange} + onSelected={searchResolver} + inGroup={true} + IsEmptyItems={IsEmptyItems} + displayValueResolver={(value: any) => value.caption} + /> + </div> + </div> + <div className="pr-0.5"> + <Button onClick={onClick}> + <Button.Icon> + <SVGSearch className="fill-white stroke-white w-4 "></SVGSearch> + </Button.Icon> + </Button> + </div> + </Inputgroup> + <div className="mt-7 pr-1 text-right font-semibold text-sm"> + Advanced Search + </div> + </div> + </div> + ); +} From ea783017a706e5e7d34c8dcb0837d250ab033eb2 Mon Sep 17 00:00:00 2001 From: decamel <den_spb97@mail.ru> Date: Wed, 7 Sep 2022 16:28:27 +0300 Subject: [PATCH 6/8] Dependencies fixes --- package-lock.json | 73 ++++++++++++++++++++++++++++++ package.json | 2 + src/components/FeaturedAuthors.tsx | 2 +- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c3a5814..214a6f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,11 +27,13 @@ "react-dom": "^18.2.0", "react-hotkeys": "^2.0.0", "react-i18next": "^11.18.3", + "react-loading-skeleton": "^3.1.0", "react-redux": "^8.0.2", "react-router-dom": "^6.3.0", "react-scripts": "5.0.1", "react-scrollbars-custom": "^4.1.0", "storybook-addon-pseudo-states": "^1.15.1", + "swiper": "^8.3.2", "tailwindcss": "^3.1.7", "tsconfig-paths-webpack-plugin": "^4.0.0", "typescript": "^4.7.4", @@ -16220,6 +16222,14 @@ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, + "node_modules/dom7": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/dom7/-/dom7-4.0.4.tgz", + "integrity": "sha512-DSSgBzQ4rJWQp1u6o+3FVwMNnT5bzQbMb+o31TjYYeRi05uAcpF8koxdfzeoe5ElzPmua7W7N28YJhF7iEKqIw==", + "dependencies": { + "ssr-window": "^4.0.0" + } + }, "node_modules/domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -29008,6 +29018,14 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-loading-skeleton": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.1.0.tgz", + "integrity": "sha512-j1U1CWWs68nBPOg7tkQqnlFcAMFF6oEK6MgqAo15f8A5p7mjH6xyKn2gHbkcimpwfO0VQXqxAswnSYVr8lWzjw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/react-merge-refs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", @@ -32959,6 +32977,11 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/ssr-window": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + }, "node_modules/ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", @@ -33598,6 +33621,29 @@ "node": ">= 10" } }, + "node_modules/swiper": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-8.3.2.tgz", + "integrity": "sha512-8wsC7ORYvVSnLUoxs2+xmfLrDPNjBVQXMCFbOlqtHeON6wtu/blOyySDr8TCBCdse1bdcIbn7m8xJNxVFL8o4Q==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "hasInstallScript": true, + "dependencies": { + "dom7": "^4.0.4", + "ssr-window": "^4.0.2" + }, + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -48570,6 +48616,14 @@ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, + "dom7": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/dom7/-/dom7-4.0.4.tgz", + "integrity": "sha512-DSSgBzQ4rJWQp1u6o+3FVwMNnT5bzQbMb+o31TjYYeRi05uAcpF8koxdfzeoe5ElzPmua7W7N28YJhF7iEKqIw==", + "requires": { + "ssr-window": "^4.0.0" + } + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -58057,6 +58111,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-loading-skeleton": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.1.0.tgz", + "integrity": "sha512-j1U1CWWs68nBPOg7tkQqnlFcAMFF6oEK6MgqAo15f8A5p7mjH6xyKn2gHbkcimpwfO0VQXqxAswnSYVr8lWzjw==" + }, "react-merge-refs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", @@ -61036,6 +61095,11 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "ssr-window": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + }, "ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", @@ -61526,6 +61590,15 @@ } } }, + "swiper": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-8.3.2.tgz", + "integrity": "sha512-8wsC7ORYvVSnLUoxs2+xmfLrDPNjBVQXMCFbOlqtHeON6wtu/blOyySDr8TCBCdse1bdcIbn7m8xJNxVFL8o4Q==", + "requires": { + "dom7": "^4.0.4", + "ssr-window": "^4.0.2" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 0273842..369ffad 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,13 @@ "react-dom": "^18.2.0", "react-hotkeys": "^2.0.0", "react-i18next": "^11.18.3", + "react-loading-skeleton": "^3.1.0", "react-redux": "^8.0.2", "react-router-dom": "^6.3.0", "react-scripts": "5.0.1", "react-scrollbars-custom": "^4.1.0", "storybook-addon-pseudo-states": "^1.15.1", + "swiper": "^8.3.2", "tailwindcss": "^3.1.7", "tsconfig-paths-webpack-plugin": "^4.0.0", "typescript": "^4.7.4", diff --git a/src/components/FeaturedAuthors.tsx b/src/components/FeaturedAuthors.tsx index a3efad3..c81a1d4 100644 --- a/src/components/FeaturedAuthors.tsx +++ b/src/components/FeaturedAuthors.tsx @@ -6,7 +6,6 @@ import SkeletonCard from "./SkeletonCard"; import { Button } from "./Button/Button"; import Avatar from "./Avatar"; import Card from "./Card"; -import Link from "./Link"; /* -------------------------------------------------------------------------- */ /* Swiper */ @@ -27,6 +26,7 @@ import Authors from "./Authors.json"; /* Icons */ /* -------------------------------------------------------------------------- */ import { ReactComponent as SVGCaretRight } from "assets/svg/caret-right.svg"; +import Link from "./typography/Link"; /* -------------------------------------------------------------------------- */ /* Variables */ From 37bc27bbd6da2e8039824271e4861c0780779e17 Mon Sep 17 00:00:00 2001 From: decamel <den_spb97@mail.ru> Date: Wed, 7 Sep 2022 16:36:45 +0300 Subject: [PATCH 7/8] Fix merge --- src/components/SearchBar.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index fae7a83..182d2d3 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -6,8 +6,6 @@ import classNames from "classnames"; import "../index.css"; import { Combobox, Transition } from "@headlessui/react"; import { Fragment, useEffect, useState } from "react"; -import { Scrollbar } from "react-scrollbars-custom"; -import { Function } from "lodash"; /* -------------------------------------------------------------------------- */ /* Component props */ From 4a44157efb0a4ce6a8cc9c2a51fd6f2ccb63c300 Mon Sep 17 00:00:00 2001 From: decamel <den_spb97@mail.ru> Date: Wed, 7 Sep 2022 16:40:36 +0300 Subject: [PATCH 8/8] Main Section redundant dependencies --- src/components/MainSection.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/MainSection.tsx b/src/components/MainSection.tsx index 3bc0ad1..21ac885 100644 --- a/src/components/MainSection.tsx +++ b/src/components/MainSection.tsx @@ -1,7 +1,6 @@ /* -------------------------------------------------------------------------- */ /* Imports */ /* -------------------------------------------------------------------------- */ -import classNames from "classnames"; import React from "react"; import Inputgroup from "./Inputgroup"; import Select from "./Select";