diff --git a/frontend-next-migration/src/preparedPages/AboutPage/ui/About.module.scss b/frontend-next-migration/src/preparedPages/AboutPage/ui/About.module.scss index c8c54b53b..e92e3b310 100644 --- a/frontend-next-migration/src/preparedPages/AboutPage/ui/About.module.scss +++ b/frontend-next-migration/src/preparedPages/AboutPage/ui/About.module.scss @@ -3,30 +3,18 @@ justify-items: center; } -.hero { - position: relative; - width: 100%; - max-width: 1400px; - aspect-ratio: 16 / 9; - margin-bottom: var(--spacing-600); -} - -.heroImg { - object-fit: cover; - max-width: 1400px; -} - .containerTop { background: var(--background); text-align: center; border-radius: var(--corner-radius-web); outline: var(--thickness-web) solid var(--black); box-shadow: 10px 10px #121212; - margin-bottom: 5%; + margin-bottom: 2%; padding: 1.2rem; - width: 30%; + width: 40%; + box-sizing: border-box; - @media (min-width: 1400px) and (max-width: 2004px) { + @media (min-width: breakpoint(xxl)) and (max-width: 2004px) { width: 40%; } @@ -48,13 +36,17 @@ } .containerBottom { + position: relative; + background: var(--background); text-align: center; border-radius: var(--corner-radius-web); outline: var(--thickness-web) solid var(--black); box-shadow: 10px 10px #121212; - margin-bottom: 5%; - width: 30%; + margin-bottom: 30px; + width: 40%; + + transition: margin-top 0.3s ease; @media (min-width: breakpoint(xxl)) and (max-width: 2004px) { width: 40%; @@ -77,48 +69,127 @@ } } -.headergrid { - display: grid; - grid-template-columns: 25% 25% 25% 25%; - grid-template-rows: 1; +.designerContainer { + width: 40%; + box-sizing: border-box; + + background: var(--background); + border-radius: var(--corner-radius-web); + outline: var(--thickness-web) solid var(--black); + box-shadow: 10px 10px #121212; + + padding: 16px 16px; + + position: relative; + top: -12px; + + display: flex; + justify-content: center; + align-items: center; + + @media (max-width: breakpoint(xxl)) { + width: 50%; + } + + @media (max-width: breakpoint(xl)) { + width: 50%; + } @media (max-width: breakpoint(md)) { - grid-template-columns: 50% 50%; + width: 70%; } @media (max-width: breakpoint(sm)) { - grid-template-columns: 50% 50%; + width: 90%; } } -.storygrid { +.designerText { + font: var(--font-dm-m); + font-size: 16px; + line-height: 1.2; + color: var(--white); + text-align: center; + margin: 0; + + span { + color: var(--primary-color); + } + + @media (max-width: breakpoint(sm)) { + span { + display: block; + } + } +} + +.headergrid { display: grid; - grid-template-columns: 25% 73%; - grid-template-rows: 6; - white-space: pre-line; + grid-template-columns: repeat(4, 130px); + column-gap: 44px; + row-gap: 32px; + padding: 8px 0 0; + width: 100%; + box-sizing: border-box; + justify-content: center; + grid-template-rows: 1; + + @media (max-width: breakpoint(xxl)) { + grid-template-columns: repeat(2, 130px); + gap: 20px 28px; + justify-content: center; + } @media (max-width: breakpoint(xl)) { - grid-template-columns: 35% 65%; + grid-template-columns: repeat(2, 130px); + gap: 16px 24px; + justify-content: center; + } + + @media (max-width: breakpoint(lg)) { + grid-template-columns: repeat(2, 130px); + gap: 16px; + justify-content: center; } @media (max-width: breakpoint(md)) { - grid-template-columns: 30% 70%; + grid-template-columns: repeat(2, 130px); + gap: 12px; + justify-content: center; } @media (max-width: breakpoint(sm)) { - grid-template-columns: 100%; + grid-template-columns: repeat(2, 130px); + gap: 12px; + justify-content: center; + } + + @media (max-width: 1600px) { + grid-template-columns: repeat(2, 130px); + gap: 16px 24px; + justify-content: center; } } +.storygrid { + display: flex; + flex-direction: column; + gap: 36px; + white-space: pre-line; + width: 100%; + box-sizing: border-box; + + margin-top: 28px; + margin-bottom: 28px; +} + .yearImgWrap { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--corner-radius-web); overflow: hidden; - outline: 4px solid var(--black); - box-shadow: 6px 6px #121212; - margin: -16px 0 var(--spacing-400) 0; + margin: 0 0 var(--spacing-400) 0; @media (max-width: breakpoint(sm)) { max-width: none; @@ -148,6 +219,7 @@ font: var(--font-sw-l); } } + .p { font: var(--font-dm-s); text-align: left; @@ -165,15 +237,21 @@ } .sValues { - font: var(font-sw-xl); + font: var(--font-sw-l); + color: #FFA100; + font-weight: 400; + line-height: 100%; + letter-spacing: -0.04em; text-align: center; - padding: 1%; + padding: 0; + margin: 0 0 2px; } + .yearh1 { font: var(--font-sw-xl); color: var(--primary-color); text-align: left; - margin-top: -16px; + margin-top: 0; @media (max-width: breakpoint(sm)) { text-align: left; @@ -189,7 +267,7 @@ @media (max-width: breakpoint(lg)) { font: var(--font-sw-l); - margin-top: -12px; + margin-top: 0; } } @@ -198,13 +276,103 @@ } #line { - border-left: 10px solid orange; + position: relative; + width: 95%; margin-left: 5%; - margin-bottom: var(--spacing-600); + box-sizing: border-box; + border-left: none; +} + +.timelineChevron { + position: absolute; + + width: 24px; + height: 24px; + + left: -18.5px; + + z-index: 2; +} + +@media (max-width: breakpoint(sm)) { + .timelineChevron { + left: -14.5px; + } +} + +#line::before { + content: ''; + position: absolute; + width: 5px; + background: #FFA100; + left: -9px; + top: 38px; + bottom: 40px; + z-index: 1; + border-radius: 999px; +} + +@media (max-width: breakpoint(sm)) { + .timelineCard::before { + width: 24px; + height: 24px; + left: -33px; + } + + #line::before { + left: 1px; + } + + .timelineChevron { + left: -8.5px; + } +} + +#line.timelineNewest::before { + top: 40px; + bottom: 40px; +} + +#line.timelineOldest::before { + top: 40px; + bottom: 40px; +} + +.timelineNewest .timelineChevron { + top: 22px; + transform: rotate(180deg); +} + +.timelineOldest .timelineChevron { + bottom: 22px; } #History { + width: 40%; + font: var(--font-sw-4xl); padding-bottom: var(--spacing-600); + text-align: left; + margin-bottom: var(--spacing-400); + + @media (min-width: breakpoint(xxl)) and (max-width: 2004px) { + width: 40%; + } + + @media (max-width: breakpoint(xxl)) { + width: 50%; + } + + @media (max-width: breakpoint(xl)) { + width: 50%; + } + + @media (max-width: breakpoint(md)) { + width: 70%; + } + + @media (max-width: breakpoint(sm)) { + width: 90%; + } } .chevronImage { @@ -251,3 +419,423 @@ padding-left: var(--spacing-md); } } + +.sortContainer { + width: 40%; + display: flex; + justify-content: flex-end; + + margin-bottom: 12px; + + z-index: 20; + + @media (min-width: breakpoint(xxl)) and (max-width: 2004px) { + width: 40%; + } + + @media (max-width: breakpoint(xxl)) { + width: 50%; + } + + @media (max-width: breakpoint(xl)) { + width: 50%; + } + + @media (max-width: breakpoint(md)) { + width: 70%; + } + + @media (max-width: breakpoint(sm)) { + width: 90%; + } +} + +.timelineSortDropdown { + position: relative; + width: 220px; + max-height: 40px; + + overflow: hidden; + box-sizing: border-box; + + background: #1E3544; + + border-radius: var(--corner-radius-web); + outline: var(--thickness-web) solid var(--black); + box-shadow: 6px 6px #121212; + + z-index: 20; + + transition: max-height 0.3s ease; +} + +.timelineSortDropdown[data-dropdown-state='opening'], +.timelineSortDropdown[data-dropdown-state='open'] { + max-height: 140px; +} + +.timelineSortDropdown[data-dropdown-state='closing'] { + max-height: 40px; +} + +.timelineSortHeader { + position: relative; + box-sizing: border-box; + + width: 100%; + min-height: 40px; + padding: 8px 14px; + + background: transparent; + + border-radius: 0; + + outline: none; + box-shadow: none; +} + +.timelineSortChevronWrapper { + margin-right: 12px; +} + +.timelineSortHeader :global(img) { + width: 14px !important; + height: 14px !important; +} + +.timelineSortContent { + position: relative; + + box-sizing: border-box; + width: 100%; + + padding: 8px 10px 10px; + + background: transparent; + + border: none; + outline: none; + box-shadow: none; + + z-index: 21; +} + +.timelineSortItem { + position: relative; + + display: flex; + align-items: center; + + min-height: 40px; + padding-left: 34px; + + box-sizing: border-box; + + font: var(--font-dm-m); + font-size: 14px; + line-height: 1.2 !important; + white-space: nowrap; + + color: var(--white) !important; + cursor: pointer; + text-decoration: none !important; +} + +.timelineSortItem::before { + content: ''; + + position: absolute; + left: 0; + top: 50%; + + width: 20px; + height: 20px; + + box-sizing: border-box; + + background: #d9d9d9; + border: 1px solid #121212; + border-radius: 2px; + + transform: translateY(-50%); +} + +.timelineSortItemActive { + color: var(--white) !important; + text-decoration: none !important; +} + +.timelineSortItemActive::before { + background: #FFA100; +} + +.timelineSortItemActive::after { + content: ''; + + position: absolute; + left: 6px; + top: 50%; + + width: 6px; + height: 11px; + + border-right: 3px solid #121212; + border-bottom: 3px solid #121212; + + transform: translateY(-65%) rotate(45deg); +} + +.timelineHeader { + position: relative; + + display: flex; + justify-content: space-between; + align-items: center; + + width: 100%; + box-sizing: border-box; + + cursor: pointer; + user-select: none; + + min-height: 64px; + padding: 0; + margin-bottom: 0; +} + +@media (max-width: breakpoint(md)) { + .timelineHeader .yearh1 { + margin: 0; + padding: 0; + line-height: 1; + } +} + +.timelineHeader .yearh1::before { + display: none; +} + +.timelineBody { + display: grid; + grid-template-rows: 0fr; + width: 100%; + + opacity: 0; + + transition: + grid-template-rows 0.3s ease, + opacity 0.2s ease; +} + +.timelineBodyOpen { + grid-template-rows: 1fr; + opacity: 1; +} + +.timelineBodyInner { + min-height: 0; + overflow: hidden; +} + +.timelineCloseArea { + width: 100%; + padding-top: var(--spacing-400); + padding-bottom: var(--spacing-400); + + display: flex; + flex-direction: column; + align-items: center; +} + +.timelineDivider { + width: 100%; + height: 4px; + background: #FFA100; + margin-bottom: var(--spacing-400); + border-radius: 999px; +} + +.timelineCloseButton { + width: 250px; + min-height: 40px; + + padding: 6px 24px; + + background: #FFA100; + color: #121212; + + border: var(--thickness-web) solid #121212; + border-radius: 999px; + + box-shadow: 4px 4px #121212; + + font: var(--font-dm-s); + cursor: pointer; + + display: flex; + align-items: center; + justify-content: center; + + box-sizing: border-box; + + @media (max-width: 400px) { + width: calc(100% - 16px); + } +} + +.timelineCard { + position: relative; + + width: calc(100% - (2 * var(--spacing-400))); + box-sizing: border-box; + + margin-left: var(--spacing-400); + + padding: 0 24px; + + min-height: 64px; + + background: #2B516A; + + border-radius: var(--corner-radius-web); + outline: var(--thickness-web) solid var(--black); + + box-shadow: 6px 6px #121212; +} + +.timelineCard:last-child { + margin-bottom: 0; +} + +.timelineCard::before { + content: ''; + position: absolute; + + width: 28px; + height: 28px; + + border: 4px solid #FFA100; + border-radius: 50%; + + background: var(--background); + + left: -45px; + top: 50%; + transform: translateY(-50%); + + box-sizing: border-box; + z-index: 2; +} + +@media (max-width: breakpoint(sm)) { + .timelineCard::before { + width: 24px; + height: 24px; + left: -33px; + } +} + +.timelineNewest .timelineStart::before { + display: none; +} + +.timelineOldest .timelineEnd::before { + display: none; +} + +.timelineChevronWrapper { + display: flex; + align-items: center; + justify-content: center; + + flex-shrink: 0; + + width: 24px; + height: 24px; + + transform: rotate(0deg); + transform-origin: center; + transition: transform 0.3s ease; +} + +.timelineChevronWrapperOpen { + transform: rotate(180deg); +} + +.chevron { + width: 24px; + height: 24px; + + flex-shrink: 0; + + img { + width: 100%; + height: 100%; + } +} + +.aboutContent { + width: 100%; + display: grid; + justify-items: center; +} + +.statItem { + background: #2B516A; + border: 2px solid var(--black); + border-radius: var(--corner-radius-web); + padding: 6px 8px; + width: 130px; + height: 92px; + box-sizing: border-box; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.statItemNarrow .gridp { + max-width: 90px; + margin-left: auto; + margin-right: auto; +} + +.statItem .gridp { + font: var(--font-dm-bold-s); + font-size: 13px; + line-height: 1.2; + text-align: center; + padding: 0; + margin: 0; + white-space: normal; +} + +.statsTitle { + font: var(--font-sw-l); + font-size: 26px; + color: var(--primary-color); + text-align: center; + margin: 0 auto; + letter-spacing: -0.03em; + width: 100%; + max-width: 100%; + box-sizing: border-box; + white-space: normal; + overflow-wrap: break-word; + + @media (max-width: breakpoint(xl)) { + font-size: 20px; + line-height: 1.2; + } + + @media (max-width: breakpoint(md)) { + font-size: 18px; + line-height: 1.2; + } + + @media (max-width: breakpoint(sm)) { + font-size: 16px; + line-height: 1.2; + } +} \ No newline at end of file diff --git a/frontend-next-migration/src/preparedPages/AboutPage/ui/About.tsx b/frontend-next-migration/src/preparedPages/AboutPage/ui/About.tsx index effc885c7..7b5303fea 100644 --- a/frontend-next-migration/src/preparedPages/AboutPage/ui/About.tsx +++ b/frontend-next-migration/src/preparedPages/AboutPage/ui/About.tsx @@ -1,20 +1,15 @@ 'use client'; -import cls from './About.module.scss'; -import chevronDown from '@/shared/assets/icons/chevronDown.svg'; import Image from 'next/image'; -import heroTop from '@/shared/assets/images/aboutPage/hero-top.png'; -import img2019 from '@/shared/assets/images/aboutPage/about2019.png'; -import img2020 from '@/shared/assets/images/aboutPage/about2020.png'; -import img2021 from '@/shared/assets/images/aboutPage/about2021.png'; -import img2022 from '@/shared/assets/images/aboutPage/about2022.png'; -import img2023 from '@/shared/assets/images/aboutPage/about2023.png'; -import img2024 from '@/shared/assets/images/aboutPage/about2024.png'; +import { useState } from 'react'; +import cls from './About.module.scss'; import { useGetMembersCountQuery, useGetDemographicsQuery, getBehindYears } from '@/entities/About'; +import { DropdownWrapper } from '@/shared/ui/DropdownWrapperV2/ui/DropdownWrapper'; +import Timeline from './Timeline'; +import chevronDown from '@/shared/assets/icons/chevronDown.svg'; +import { useClientTranslation } from '@/shared/i18n'; export interface Props { title: string; - description: string; - keywords: string; storytitle: string; project: string; locality: string; @@ -33,8 +28,6 @@ export interface Props { const About = (props: Props) => { const { title, - description, - keywords, storytitle, project, locality, @@ -50,7 +43,14 @@ const About = (props: Props) => { V2026, } = props; + const { t } = useClientTranslation('about'); + + const designers = t('designer.names', { + returnObjects: true, + }) as { name: string; url: string }[]; + const { data: projectCount = 0, isLoading: membersLoading } = useGetMembersCountQuery(); + const { data: demographics = { localities: 0, nationalities: 0 }, isLoading: demographicsLoading, @@ -59,158 +59,118 @@ const About = (props: Props) => { const behindCount = getBehindYears(); const isLoading = membersLoading || demographicsLoading; + const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc'); + return (
-
- Hero Image -
-
-

{title}

-

{description}

-

{keywords}

-
-
-

{isLoading ? '...' : projectCount}

-

{project}

-
-
-

{isLoading ? '...' : demographics.localities}

-

{locality}

-
-
-

- {isLoading ? '...' : demographics.nationalities} -

-

{nationality}

-
-
-

{behindCount}

-

{behind}

-
-
-
-
+

{storytitle}

-
-

2019

-
-
- 2019 year image -
-

{V2019}

-
-

2020

-
-
- 2020 year image -
-

{V2020}

-
+
+

{title}

-

2021

-
-
- 2021 year image +
+
+

{isLoading ? '...' : projectCount}

+

{project}

-

{V2021}

-
-

2022

-
-
- 2022 year image +
+

+ {isLoading ? '...' : demographics.localities} +

+

{locality}

-

{V2022}

-
-

2023

-
-
- 2023 year image +
+

+ {isLoading ? '...' : demographics.nationalities} +

+

{nationality}

-

{V2023}

-
-

2024

-
-
- 2024 year image +
+

{behindCount}

+

{behind}

-

{V2024}

+
-

2025

-
-

{V2025}

-
+
+ setSortOrder('desc'), + }, + { + elementText: t('timeline.oldest'), + active: sortOrder === 'asc', + onClickCallback: () => setSortOrder('asc'), + }, + ]} + /> +
-

2026

-
-

{V2026}

+
+
+ + +
+
- {'Chevron'} +
+

+ {t('designer.label')}{' '} + {designers.map((designer, index) => ( + + {index > 0 && ', '} + + {designer.name} + + + ))} +

diff --git a/frontend-next-migration/src/preparedPages/AboutPage/ui/Timeline.tsx b/frontend-next-migration/src/preparedPages/AboutPage/ui/Timeline.tsx new file mode 100644 index 000000000..24612419f --- /dev/null +++ b/frontend-next-migration/src/preparedPages/AboutPage/ui/Timeline.tsx @@ -0,0 +1,61 @@ +import { StaticImageData } from 'next/image'; +import img2019 from '@/shared/assets/images/aboutPage/about2019.png'; +import img2020 from '@/shared/assets/images/aboutPage/about2020.png'; +import img2021 from '@/shared/assets/images/aboutPage/about2021.png'; +import img2022 from '@/shared/assets/images/aboutPage/about2022.png'; +import img2023 from '@/shared/assets/images/aboutPage/about2023.png'; +import img2024 from '@/shared/assets/images/aboutPage/about2024.png'; +import TimelineEntry from './TimelineEntry'; + +interface Props { + sortOrder: 'asc' | 'desc'; + V2019: string; + V2020: string; + V2021: string; + V2022: string; + V2023: string; + V2024: string; + V2025: string; + V2026: string; +} + +interface TimelineItem { + year: number; + text: string; + image: StaticImageData | null; +} + +const Timeline = ({ sortOrder, V2019, V2020, V2021, V2022, V2023, V2024, V2025, V2026 }: Props) => { + const timeline: TimelineItem[] = [ + { year: 2019, image: img2019, text: V2019 }, + { year: 2020, image: img2020, text: V2020 }, + { year: 2021, image: img2021, text: V2021 }, + { year: 2022, image: img2022, text: V2022 }, + { year: 2023, image: img2023, text: V2023 }, + { year: 2024, image: img2024, text: V2024 }, + { year: 2025, image: null, text: V2025 }, + { year: 2026, image: null, text: V2026 }, + ]; + + const sortedTimeline = [...timeline].sort((a, b) => + sortOrder === 'desc' ? b.year - a.year : a.year - b.year, + ); + + return ( + <> + {sortedTimeline.map((item, index) => ( + + ))} + + ); +}; + +export default Timeline; diff --git a/frontend-next-migration/src/preparedPages/AboutPage/ui/TimelineEntry.tsx b/frontend-next-migration/src/preparedPages/AboutPage/ui/TimelineEntry.tsx new file mode 100644 index 000000000..7646cd70b --- /dev/null +++ b/frontend-next-migration/src/preparedPages/AboutPage/ui/TimelineEntry.tsx @@ -0,0 +1,81 @@ +import { useState } from 'react'; +import Image, { StaticImageData } from 'next/image'; +import chevronDown from '@/shared/assets/icons/chevronDown.svg'; +import cls from './About.module.scss'; +import { useClientTranslation } from '@/shared/i18n'; + +interface TimelineEntryProps { + year: number; + text: string; + image?: StaticImageData | null; + sortOrder: 'asc' | 'desc'; + isFirst: boolean; + isLast: boolean; +} + +const TimelineEntry = ({ year, text, image, sortOrder, isFirst, isLast }: TimelineEntryProps) => { + const [isOpen, setIsOpen] = useState(isFirst); + const { t } = useClientTranslation('about'); + + return ( +
+
setIsOpen(!isOpen)} + > +

{year}

+ + + + +
+ +
+
+ {image && ( +
+ {`${year} +
+ )} + +

{text}

+ +
+
+ + +
+
+
+
+ ); +}; + +export default TimelineEntry; diff --git a/frontend-next-migration/src/shared/i18n/locales/en/about.json b/frontend-next-migration/src/shared/i18n/locales/en/about.json index c05b5d363..4fd7f544d 100644 --- a/frontend-next-migration/src/shared/i18n/locales/en/about.json +++ b/frontend-next-migration/src/shared/i18n/locales/en/about.json @@ -1,15 +1,30 @@ { "title": "About Us", - "head-title": "What is PRG?", + "head-title": "A lot of talented people work on this project", "head-description": "Psyche's Royale Gaming ry is a non-profit game art association that is collaboratively developing the mobile game ALT Zone 1.0", "head-keywords": "ALT Zone, ALT Zone mobile game, community game development, participate in game creation, game art mobile game", "og-title": "Psyche's Royale Gaming ry – Creators and Community of ALT Zone Game Art", "og-description": "PRG ry is a Finnish non-profit association developing the ALT Zone mobile game in collaboration with youth, volunteers, and game industry professionals.", - "project": "Has worked on this project", - "locality": "From a different locality", - "nationality": "From a different nationality", + "locality": "Localities represented", + "nationality": "Nationalities represented", "behind": "Years into the journey", + "timeline": { + "sort": "Sort by", + "newest": "Newest", + "oldest": "Oldest", + "close": "Close" + }, + + "designer": { + "label": "Designed by:", + "names": [ + { + "name": "Sanna-Kaisa Mastokangas", + "url": "https://piisamisiili.artstation.com/" + } + ] +}, "story-title": "ALT Zone's history", diff --git a/frontend-next-migration/src/shared/i18n/locales/fi/about.json b/frontend-next-migration/src/shared/i18n/locales/fi/about.json index 83d3a6165..042026b70 100644 --- a/frontend-next-migration/src/shared/i18n/locales/fi/about.json +++ b/frontend-next-migration/src/shared/i18n/locales/fi/about.json @@ -1,14 +1,30 @@ { "title": "Meistä", - "head-title": "Mikä PRG?", + "head-title": "Tämän projektin parissa työskentelee paljon erilaisia osaajia", "head-description": "Psyche's Royale Gaming ry on voittoa tavoittelematon pelitaiteen yhdistys, joka valmistaa ALT Zone 1.0 mobiilipeliä yhteisöllisesti.", "head-keywords": "ALT Zone, ALT Zone mobiilipeli, yhteisöllinen pelinkehitys, osallistu pelin tekemiseen, pelitaide mobiilipeli", "og-title": "Psyche's Royale Gaming ry – ALT Zone -pelitaiteen tekijät ja yhteisö", "og-description": "PRG ry on suomalainen voittoa tavoittelematon yhdistys, joka kehittää ALT Zone -mobiilipeliä yhdessä nuorten, vapaaehtoisten ja pelialan osaajien kanssa.", - "project": "On työskennellyt tässä projectissa", + "project": "On työskennellyt tässä projektissa", "locality": "Eri paikkakunnalta", "nationality": "Eri kansalaisuutta", "behind": "Vuotta matkaa takana", + "timeline": { + "sort": "Järjestä", + "newest": "Uusin", + "oldest": "Vanhin", + "close": "Sulje" + }, + + "designer": { + "label": "Sivun suunnitteli:", + "names": [ + { + "name": "Sanna-Kaisa Mastokangas", + "url": "https://piisamisiili.artstation.com/" + } + ] +}, "story-title": "ALT Zonen historia", diff --git a/frontend-next-migration/src/shared/ui/DropdownWrapperV2/types/index.ts b/frontend-next-migration/src/shared/ui/DropdownWrapperV2/types/index.ts index ca3d70859..3104d29e0 100644 --- a/frontend-next-migration/src/shared/ui/DropdownWrapperV2/types/index.ts +++ b/frontend-next-migration/src/shared/ui/DropdownWrapperV2/types/index.ts @@ -25,6 +25,7 @@ export type DropdownWrapperProps = { className?: string; contentClassName?: string; contentItemClassName?: string; + activeItemClassName?: string; contentAbsolute?: boolean; elements: Array; onOpen?: () => void; @@ -45,4 +46,6 @@ export type DropdownWrapperProps = { autoClose?: boolean; headerClassName?: string; childrenWrapperClassName?: string; + chevronClassName?: string; + chevronWrapperClassName?: string; }; diff --git a/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.module.scss b/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.module.scss index 9a067038e..80413ca61 100644 --- a/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.module.scss +++ b/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.module.scss @@ -11,6 +11,29 @@ } } +.chevronWrapper { + position: absolute; + right: 0; + top: 50%; + + display: flex; + align-items: center; + justify-content: center; + + width: 24px; + height: 24px; + + flex-shrink: 0; + + transform: translateY(-50%) rotate(0deg); + transform-origin: center; + transition: transform 0.3s ease; +} + +.chevronWrapperOpen { + transform: translateY(-50%) rotate(180deg); +} + .dropdownContent { padding-top: 10px; line-height: 40px !important; @@ -69,7 +92,7 @@ } .dynamicHeading { - font: var(--font-dm-bold-m); + font: var(--font-dm-m); color: var(--primary-color); cursor: pointer; } @@ -91,6 +114,7 @@ display: block; width: 100%; cursor: pointer; + position: relative; } .disabled { diff --git a/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.tsx b/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.tsx index 889a58517..4e84eb52d 100644 --- a/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.tsx +++ b/frontend-next-migration/src/shared/ui/DropdownWrapperV2/ui/DropdownWrapper.tsx @@ -17,6 +17,7 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { className = '', contentClassName = '', contentItemClassName = '', + activeItemClassName = '', elements, isDisabled, children, @@ -30,6 +31,8 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { autoClose = false, headerClassName = '', childrenWrapperClassName = '', + chevronClassName = '', + chevronWrapperClassName = '', } = props; const [isOpen, setIsOpen] = useState(openByDefault || staticDropdown); @@ -77,6 +80,7 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { setIsOpen(false); } }; + document.addEventListener('az:dropdown-select' as any, handleDropdownSelect as any); return () => { document.removeEventListener('az:dropdown-select' as any, handleDropdownSelect as any); @@ -108,6 +112,7 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { clearTimeout(closeTimer); setCloseTimer(null); } + setIsOpen(true); }; @@ -118,6 +123,7 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { setIsOpen(false); setCloseTimer(null); }, 200); + setCloseTimer(timer); }; @@ -153,13 +159,22 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { }; const mainElementClass = isDisabled?.status ? cls.disabled : ''; + return (
{ {dynamicTitle} {showArrow && ( {'Chevron'} )} @@ -220,6 +231,7 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => {
)} + {shouldRender && (
{ isExternal={element.link.isExternal} className={classNames(contentItemClassName, { [cls.active]: element.active, + [activeItemClassName]: element.active, })} onClick={() => { if (!openByDefault && !staticDropdown) { @@ -259,7 +272,7 @@ export const DropdownWrapper = (props: DropdownWrapperProps) => { {element.link.isExternal && ( { ) : ( { element.onClickCallback?.(); }} > - {/**/} {element.elementText} )}