From 1ddbb3e0e6c80859937ff753152c4cc3ca9f0ec5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 16 Dec 2024 15:49:30 +0200 Subject: [PATCH] 559-refactor: Widget places (#662) * refactor: 559 - change scss to modules * refactor: 559 - get rid of marquee dependency * refactor: 559 - reduce code duplication * refactor: 559 - move test file inside ui folder * refactor: 559 - move constant to constants file * refactor: 559 - remove use client directive * refactor: 559 - replace div with section * fix: 559 - incorrect test * refactor: 559 - replace css values with constants * refactor: remove will-change property * refactor: reduce code duplication --- package-lock.json | 287 ------------------ package.json | 1 - src/widgets/places/constants.ts | 13 + src/widgets/places/index.ts | 2 +- src/widgets/places/places.test.tsx | 36 --- .../marquee-group/marquee-group.module.scss | 9 + .../places/ui/marquee-group/marquee-group.tsx | 19 ++ .../ui/place-item/place-item.module.scss | 31 ++ .../places/ui/place-item/place-item.tsx | 19 ++ src/widgets/places/ui/places.scss | 45 --- src/widgets/places/ui/places.tsx | 37 --- .../places/ui/places/places.module.scss | 24 ++ src/widgets/places/ui/places/places.test.tsx | 26 ++ src/widgets/places/ui/places/places.tsx | 17 ++ 14 files changed, 159 insertions(+), 407 deletions(-) create mode 100644 src/widgets/places/constants.ts delete mode 100644 src/widgets/places/places.test.tsx create mode 100644 src/widgets/places/ui/marquee-group/marquee-group.module.scss create mode 100644 src/widgets/places/ui/marquee-group/marquee-group.tsx create mode 100644 src/widgets/places/ui/place-item/place-item.module.scss create mode 100644 src/widgets/places/ui/place-item/place-item.tsx delete mode 100644 src/widgets/places/ui/places.scss delete mode 100644 src/widgets/places/ui/places.tsx create mode 100644 src/widgets/places/ui/places/places.module.scss create mode 100644 src/widgets/places/ui/places/places.test.tsx create mode 100644 src/widgets/places/ui/places/places.tsx diff --git a/package-lock.json b/package-lock.json index 0c9ed3f81..ce47ba677 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "next": "15.0.3", "react": "19.0.0-rc.1", "react-dom": "19.0.0-rc.1", - "react-double-marquee": "^1.1.0", "react-responsive-carousel": "^3.2.23" }, "devDependencies": { @@ -3862,12 +3861,6 @@ "node": ">=8" } }, - "node_modules/brcast": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.2.tgz", - "integrity": "sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA==", - "license": "MIT" - }, "node_modules/browserslist": { "version": "4.24.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", @@ -4307,15 +4300,6 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/css-vendor": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", - "integrity": "sha512-Vx/Vl3zsHj32Z+WTNzGjd2iSbSIJTYHMmyGUT2nzCjj0Xk4qLfwpQ8nF6TQ5oo3Cf0s/An3DTc7LclH1BkAXbQ==", - "license": "MIT", - "dependencies": { - "is-in-browser": "^1.0.2" - } - }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -6531,12 +6515,6 @@ "node": ">= 0.4" } }, - "node_modules/hoist-non-react-statics": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", - "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==", - "license": "BSD-3-Clause" - }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -6624,12 +6602,6 @@ "url": "https://github.com/sponsors/typicode" } }, - "node_modules/hyphenate-style-name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", - "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", - "license": "BSD-3-Clause" - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -6931,12 +6903,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "license": "MIT" - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -6966,12 +6932,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-in-browser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", - "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==", - "license": "MIT" - }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -7215,15 +7175,6 @@ "dev": true, "license": "ISC" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -7782,150 +7733,6 @@ "node": ">=6" } }, - "node_modules/jss": { - "version": "9.8.7", - "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", - "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "is-in-browser": "^1.1.3", - "symbol-observable": "^1.1.0", - "warning": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/jss-camel-case": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz", - "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==", - "license": "MIT", - "dependencies": { - "hyphenate-style-name": "^1.0.2" - }, - "peerDependencies": { - "jss": "^9.7.0" - } - }, - "node_modules/jss-compose": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz", - "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==", - "license": "MIT", - "dependencies": { - "warning": "^3.0.0" - }, - "peerDependencies": { - "jss": "^9.0.0" - } - }, - "node_modules/jss-default-unit": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz", - "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==", - "license": "MIT", - "peerDependencies": { - "jss": "^9.4.0" - } - }, - "node_modules/jss-expand": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz", - "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg==", - "license": "MIT", - "peerDependencies": { - "jss": "^9.4.0" - } - }, - "node_modules/jss-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz", - "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==", - "license": "MIT", - "dependencies": { - "warning": "^3.0.0" - }, - "peerDependencies": { - "jss": "^9.7.0" - } - }, - "node_modules/jss-global": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", - "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==", - "license": "MIT", - "peerDependencies": { - "jss": "^9.0.0" - } - }, - "node_modules/jss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", - "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", - "license": "MIT", - "dependencies": { - "warning": "^3.0.0" - }, - "peerDependencies": { - "jss": "^9.0.0" - } - }, - "node_modules/jss-preset-default": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz", - "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==", - "license": "MIT", - "dependencies": { - "jss-camel-case": "^6.1.0", - "jss-compose": "^5.0.0", - "jss-default-unit": "^8.0.2", - "jss-expand": "^5.3.0", - "jss-extend": "^6.2.0", - "jss-global": "^3.0.0", - "jss-nested": "^6.0.1", - "jss-props-sort": "^6.0.0", - "jss-template": "^1.0.1", - "jss-vendor-prefixer": "^7.0.0" - }, - "peerDependencies": { - "jss": "^9.7.0" - } - }, - "node_modules/jss-props-sort": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", - "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==", - "license": "MIT", - "peerDependencies": { - "jss": "^9.0.0" - } - }, - "node_modules/jss-template": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz", - "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==", - "license": "MIT", - "dependencies": { - "warning": "^3.0.0" - }, - "peerDependencies": { - "jss": "^9.0.0" - } - }, - "node_modules/jss-vendor-prefixer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", - "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", - "license": "MIT", - "dependencies": { - "css-vendor": "^0.3.8" - }, - "peerDependencies": { - "jss": "^9.0.0" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -9287,82 +9094,6 @@ "react": "19.0.0-rc.1" } }, - "node_modules/react-double-marquee": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/react-double-marquee/-/react-double-marquee-1.1.0.tgz", - "integrity": "sha512-MWsX3JeQDY23iC9VvRMS44fLZ+l1sJBRFLCsra+qstAtE51jG3AvVUArCx1Y51Pw2Z5IrrywwObHtDqhNh084g==", - "license": "MIT", - "dependencies": { - "prop-types": "^15.7.2", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-json-pretty": "^2.2.0", - "react-jss": "^8.6.1" - }, - "peerDependencies": { - "prop-types": "^15.7.2", - "react": "^16.8.4" - } - }, - "node_modules/react-double-marquee/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-double-marquee/node_modules/react-json-pretty": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/react-json-pretty/-/react-json-pretty-2.2.0.tgz", - "integrity": "sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A==", - "license": "MIT", - "dependencies": { - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=15.0", - "react-dom": ">=15.0" - } - }, - "node_modules/react-double-marquee/node_modules/react-jss": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", - "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==", - "license": "MIT", - "dependencies": { - "hoist-non-react-statics": "^2.5.0", - "jss": "^9.7.0", - "jss-preset-default": "^4.3.0", - "prop-types": "^15.6.0", - "theming": "^1.3.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "react": ">=0.13" - } - }, - "node_modules/react-double-marquee/node_modules/theming": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz", - "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==", - "license": "MIT", - "dependencies": { - "brcast": "^3.0.1", - "is-function": "^1.0.1", - "is-plain-object": "^2.0.1", - "prop-types": "^15.5.8" - }, - "peerDependencies": { - "react": ">=0.15" - } - }, "node_modules/react-easy-swipe": { "version": "0.0.21", "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz", @@ -11194,15 +10925,6 @@ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, - "node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -11915,15 +11637,6 @@ "node": ">=18" } }, - "node_modules/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", - "license": "BSD-3-Clause", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index 526c76c62..45cfea7e0 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "next": "15.0.3", "react": "19.0.0-rc.1", "react-dom": "19.0.0-rc.1", - "react-double-marquee": "^1.1.0", "react-responsive-carousel": "^3.2.23" }, "devDependencies": { diff --git a/src/widgets/places/constants.ts b/src/widgets/places/constants.ts new file mode 100644 index 000000000..0018f0471 --- /dev/null +++ b/src/widgets/places/constants.ts @@ -0,0 +1,13 @@ +export const places = [ + 'Kazakhstan', + 'Belarus', + 'Latvia', + 'Poland', + 'Turkey', + 'Georgia', + 'Montenegro', + 'Uzbekistan', + 'Online', + 'Kyrgyzstan', + 'Lithuania', +] as const; diff --git a/src/widgets/places/index.ts b/src/widgets/places/index.ts index 22f757a36..aba3add8c 100644 --- a/src/widgets/places/index.ts +++ b/src/widgets/places/index.ts @@ -1 +1 @@ -export { Places } from './ui/places'; +export { Places } from './ui/places/places'; diff --git a/src/widgets/places/places.test.tsx b/src/widgets/places/places.test.tsx deleted file mode 100644 index 3e5b92b58..000000000 --- a/src/widgets/places/places.test.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import { describe, expect, it } from 'vitest'; -import { Places } from './ui/places'; - -describe('Places component', () => { - const places = [ - 'Kazakhstan', - 'Belarus', - 'Latvia', - 'Poland', - 'Turkey', - 'Georgia', - 'Montenegro', - 'Uzbekistan', - 'Online', - 'Kyrgyzstan', - 'Lithuania', - ]; - - it.skip('renders the marquee with correct places', () => { - render(); - - places.forEach((place) => { - const allInstances = screen.getAllByText(place); - - expect(allInstances.length).toBe(2); - }); - }); - - it.skip('renders divider after each place except the last one', () => { - render(); - const dividers = screen.getAllByTestId('divider'); - - expect(dividers).toHaveLength(places.length * 2); - }); -}); diff --git a/src/widgets/places/ui/marquee-group/marquee-group.module.scss b/src/widgets/places/ui/marquee-group/marquee-group.module.scss new file mode 100644 index 000000000..f872b06fc --- /dev/null +++ b/src/widgets/places/ui/marquee-group/marquee-group.module.scss @@ -0,0 +1,9 @@ +.marquee-group { + animation: marquee 30s linear infinite; + + @keyframes marquee { + 100% { + translate: -100% 0; + } + } +} diff --git a/src/widgets/places/ui/marquee-group/marquee-group.tsx b/src/widgets/places/ui/marquee-group/marquee-group.tsx new file mode 100644 index 000000000..80a224f0b --- /dev/null +++ b/src/widgets/places/ui/marquee-group/marquee-group.tsx @@ -0,0 +1,19 @@ +import classNames from 'classnames/bind'; +import { places } from '@/widgets/places/constants'; +import PlaceItem from '@/widgets/places/ui/place-item/place-item'; + +import styles from './marquee-group.module.scss'; + +const cx = classNames.bind(styles); + +type MarqueeGroupProps = { + hidden?: boolean; +}; + +export const MarqueeGroup = ({ hidden = false }: MarqueeGroupProps) => ( +
+ {places.map((place) => ( + {place} + ))} +
+); diff --git a/src/widgets/places/ui/place-item/place-item.module.scss b/src/widgets/places/ui/place-item/place-item.module.scss new file mode 100644 index 000000000..15296aeac --- /dev/null +++ b/src/widgets/places/ui/place-item/place-item.module.scss @@ -0,0 +1,31 @@ +.place-container { + overflow: hidden; + display: inline-flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + + font-size: 20px; + font-weight: $font-weight-medium; + line-height: 28px; + color: $color-black; + letter-spacing: 0; + + .place { + display: inline-block; + padding: 0 16px; + } + + .divider { + display: inline-block; + height: 12px; + font-size: 36px; + color: $color-red; + } + + @include media-tablet { + font-size: 16px; + font-weight: $font-weight-regular; + line-height: 24px; + } +} diff --git a/src/widgets/places/ui/place-item/place-item.tsx b/src/widgets/places/ui/place-item/place-item.tsx new file mode 100644 index 000000000..7fe7ab28b --- /dev/null +++ b/src/widgets/places/ui/place-item/place-item.tsx @@ -0,0 +1,19 @@ +import React, { PropsWithChildren } from 'react'; +import classNames from 'classnames/bind'; + +import styles from './place-item.module.scss'; + +const cx = classNames.bind(styles); + +const PlaceItem = ({ children }: PropsWithChildren) => { + return ( + + {children} + + * + + + ); +}; + +export default PlaceItem; diff --git a/src/widgets/places/ui/places.scss b/src/widgets/places/ui/places.scss deleted file mode 100644 index e791e5a84..000000000 --- a/src/widgets/places/ui/places.scss +++ /dev/null @@ -1,45 +0,0 @@ -.places { - white-space: nowrap; - - &.content { - overflow: hidden; - - padding: 5px 20px; - - border-color: $color-gray-600; - border-style: solid; - border-width: 1px 0 1px 0; - } - - & .place-container { - overflow: hidden; - display: inline-flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - - font-size: 20px; - font-weight: 500; - line-height: 28px; - color: $color-black; - letter-spacing: 0; - - @include media-tablet { - font-size: 16px; - font-weight: 400; - line-height: 24px; - } - } - - & .place { - display: inline-block; - padding: 0 16px; - } - - & .divider { - display: inline-block; - height: 12px; - font-size: 36px; - color: $color-red; - } -} diff --git a/src/widgets/places/ui/places.tsx b/src/widgets/places/ui/places.tsx deleted file mode 100644 index 989065a71..000000000 --- a/src/widgets/places/ui/places.tsx +++ /dev/null @@ -1,37 +0,0 @@ -'use client'; - -// @ts-expect-error no types -import Marquee from 'react-double-marquee'; - -import './places.scss'; - -const places: string[] = [ - 'Kazakhstan', - 'Belarus', - 'Latvia', - 'Poland', - 'Turkey', - 'Georgia', - 'Montenegro', - 'Uzbekistan', - 'Online', - 'Kyrgyzstan', - 'Lithuania', -]; - -export const Places = () => ( -
-
- - {places.map((place) => ( - - {place} - - * - - - ))} - -
-
-); diff --git a/src/widgets/places/ui/places/places.module.scss b/src/widgets/places/ui/places/places.module.scss new file mode 100644 index 000000000..cc8e6d372 --- /dev/null +++ b/src/widgets/places/ui/places/places.module.scss @@ -0,0 +1,24 @@ +.places { + white-space: nowrap; + + &.content { + overflow: hidden; + display: flex; + + padding: 5px 20px; + + border-color: $color-gray-600; + border-style: solid; + border-width: 1px 0 1px 0; + + .marquee-group { + animation: marquee 30s linear infinite; + + @keyframes marquee { + 100% { + translate: -100% 0; + } + } + } + } +} diff --git a/src/widgets/places/ui/places/places.test.tsx b/src/widgets/places/ui/places/places.test.tsx new file mode 100644 index 000000000..06fd910ff --- /dev/null +++ b/src/widgets/places/ui/places/places.test.tsx @@ -0,0 +1,26 @@ +import { render, screen } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; +import { Places } from '@/widgets/places'; +import { places } from '@/widgets/places/constants'; + +const placesItems = 33; +const placeGroups = 3; + +describe('Places component', () => { + it('renders the marquee with correct places', () => { + render(); + + places.forEach((place) => { + const allInstances = screen.getAllByText(place); + + expect(allInstances.length).toBe(placeGroups); + }); + }); + + it('renders divider after each place except the last one', () => { + render(); + const dividers = screen.getAllByTestId('divider'); + + expect(dividers).toHaveLength(placesItems); + }); +}); diff --git a/src/widgets/places/ui/places/places.tsx b/src/widgets/places/ui/places/places.tsx new file mode 100644 index 000000000..e150691c6 --- /dev/null +++ b/src/widgets/places/ui/places/places.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import classNames from 'classnames/bind'; +import { MarqueeGroup } from '@/widgets/places/ui/marquee-group/marquee-group'; + +import styles from './places.module.scss'; + +const cx = classNames.bind(styles); + +export const Places = () => ( +
+
+ +
+
+);