diff --git a/package.json b/package.json index 80e42f3..c8027d7 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,10 @@ }, "dependencies": { "focus-trap-react": "^10.2.3", + "keen-slider": "^6.8.6", + "next": "14.2.3", "react": "^18", - "react-dom": "^18", - "next": "14.2.3" + "react-dom": "^18" }, "devDependencies": { "@svgr/webpack": "^8.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab9efee..7057d91 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: focus-trap-react: specifier: ^10.2.3 version: 10.2.3(prop-types@15.8.1)(react-dom@18.3.1)(react@18.3.1) + keen-slider: + specifier: ^6.8.6 + version: 6.8.6 next: specifier: 14.2.3 version: 14.2.3(@babel/core@7.24.5)(react-dom@18.3.1)(react@18.3.1)(sass@1.77.1) @@ -1653,6 +1656,7 @@ packages: engines: { node: '>=6.9.0' } dependencies: regenerator-runtime: 0.14.1 + dev: true /@babel/template@7.24.0: resolution: @@ -2001,293 +2005,6 @@ packages: engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } dev: true - /@radix-ui/primitive@1.0.1: - resolution: - { - integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== - } - dependencies: - '@babel/runtime': 7.24.5 - dev: false - - /@radix-ui/react-accordion@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): - resolution: - { - integrity: sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg== - } - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-context': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-direction': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-id': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - '@types/react-dom': 18.3.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - - /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): - resolution: - { - integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg== - } - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-context': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-id': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - '@types/react-dom': 18.3.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - - /@radix-ui/react-collection@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): - resolution: - { - integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA== - } - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-context': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-slot': 1.0.2(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - '@types/react-dom': 18.3.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - - /@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-context@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-direction@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-id@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): - resolution: - { - integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== - } - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - '@types/react-dom': 18.3.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - - /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): - resolution: - { - integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== - } - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/react-slot': 1.0.2(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - '@types/react-dom': 18.3.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - - /@radix-ui/react-slot@1.0.2(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.2)(react@18.3.1) - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - - /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.2)(react@18.3.1): - resolution: - { - integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== - } - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@types/react': 18.3.2 - react: 18.3.1 - dev: false - /@rushstack/eslint-patch@1.10.2: resolution: { @@ -2540,6 +2257,7 @@ packages: { integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== } + dev: true /@types/react-dom@18.3.0: resolution: @@ -3314,6 +3032,7 @@ packages: { integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== } + dev: true /damerau-levenshtein@1.0.8: resolution: @@ -5049,6 +4768,13 @@ packages: object.values: 1.2.0 dev: true + /keen-slider@6.8.6: + resolution: + { + integrity: sha512-dcEQ7GDBpCjUQA8XZeWh3oBBLLmyn8aoeIQFGL/NTVkoEOsmlnXqA4QykUm/SncolAZYGsEk/PfUhLZ7mwMM2w== + } + dev: false + /keyv@4.5.4: resolution: { @@ -5838,6 +5564,7 @@ packages: { integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== } + dev: true /regenerator-transform@0.15.2: resolution: diff --git a/src/app/Home.scss b/src/app/Home.scss index 63328ec..54555fc 100644 --- a/src/app/Home.scss +++ b/src/app/Home.scss @@ -38,12 +38,15 @@ @media (min-width: $mobile-breakpoint) { padding-block: $main-padding-desktop-block; padding-inline: $main-padding-desktop-inline; - height: 100vh; h2 { margin-bottom: 40px; } } + + @media (min-width: $tablet-breakpoint) { + height: 100vh; + } } } } diff --git a/src/app/assets/images/pomegranate.webp b/src/app/assets/images/pomegranate.webp new file mode 100644 index 0000000..d8e7f76 Binary files /dev/null and b/src/app/assets/images/pomegranate.webp differ diff --git a/src/app/components/ThemesSlider/SliderArrow/SliderArrow.scss b/src/app/components/ThemesSlider/SliderArrow/SliderArrow.scss new file mode 100644 index 0000000..1e37305 --- /dev/null +++ b/src/app/components/ThemesSlider/SliderArrow/SliderArrow.scss @@ -0,0 +1,28 @@ +.slider-arrow { + border: none; + background-color: $primary-black; + padding: 10px 18px; + + svg { + width: 10px; + height: 15px; + fill: none; + stroke: $primary-white; + stroke-width: 2px; + cursor: pointer; + } + + &.arrow--left { + border-radius: 5px 0 0 5px; + } + + &.arrow--right { + border-radius: 0 5px 5px 0; + } + + &.arrow--disabled { + svg { + stroke: $outline-gray; + } + } +} diff --git a/src/app/components/ThemesSlider/SliderArrow/SliderArrow.tsx b/src/app/components/ThemesSlider/SliderArrow/SliderArrow.tsx new file mode 100644 index 0000000..175d2f9 --- /dev/null +++ b/src/app/components/ThemesSlider/SliderArrow/SliderArrow.tsx @@ -0,0 +1,35 @@ +/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }]*/ + +import './SliderArrow.scss'; + +type SliderArrowProps = { + disabled: boolean; + left?: boolean; + onClick: (_e: any) => void; +}; + +// TODO: consider replacing svgs with react svg element + +export default function SliderArrow({ + disabled, + left, + onClick +}: SliderArrowProps) { + const disabledClass = disabled ? ' arrow--disabled' : ''; + return ( + + ); +} diff --git a/src/app/components/ThemesSlider/ThemeSlide/ThemeSlide.scss b/src/app/components/ThemesSlider/ThemeSlide/ThemeSlide.scss new file mode 100644 index 0000000..73d66b0 --- /dev/null +++ b/src/app/components/ThemesSlider/ThemeSlide/ThemeSlide.scss @@ -0,0 +1,88 @@ +.theme-slide { + /* variables */ + $slide-margin: 20px; + + margin: $slide-margin; + border: none; + + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 420px; + max-height: 575px; + + .top-section { + h3 { + display: inline-block; + border-radius: 5px; + padding: 10px; + line-height: 1; + font-size: $p-size; + } + } + + .bottom-section { + hr { + border: 1px solid #bababa; + margin-block: $slide-margin; + } + } + + h4 { + text-transform: uppercase; + font-size: $h3-size; + } + + p { + margin-block-start: $slide-margin; + } + + .non-profit-container { + display: flex; + flex-wrap: wrap; + gap: 1rem; + padding-left: 0; + list-style-type: none; + max-width: 80%; + + @media (min-width: $mobile-breakpoint) { + max-width: 100%; + } + + .non-profit { + a { + text-decoration: none; + font-family: $p-font; + outline: none; + background-color: white; + display: flex; + flex-wrap: wrap; + padding: 10px; + line-height: 1; + border: 1px solid $primary-black; + border-radius: 5px; + margin-block-start: 0; + cursor: pointer; + transition: + background-color 0.3s, + color 0.3s; + + &:is(:hover, :focus-visible) { + background-color: $primary-black; + color: white; + } + } + } + } + + @media (min-width: $mobile-breakpoint) { + padding: $slide-margin; + border: 1px solid $outline-gray; + } + + @media (min-width: $tablet-breakpoint) { + margin: 0; + min-height: auto; + height: 100%; + } +} diff --git a/src/app/components/ThemesSlider/ThemeSlide/ThemeSlide.tsx b/src/app/components/ThemesSlider/ThemeSlide/ThemeSlide.tsx new file mode 100644 index 0000000..a425354 --- /dev/null +++ b/src/app/components/ThemesSlider/ThemeSlide/ThemeSlide.tsx @@ -0,0 +1,34 @@ +import './ThemeSlide.scss'; +import type { SlideContent } from '../ThemesSlider'; + +type content = { + content: SlideContent; +}; + +export default function ThemeSlide({ content }: content) { + return ( +
{content.description}
+.03 / Themes
-Swipe right to see more.
*/} +