From f68f29f13728e4bb996f1c5300def697f5ee8080 Mon Sep 17 00:00:00 2001 From: Nicolas Varone Date: Tue, 3 Sep 2024 14:37:50 +0200 Subject: [PATCH] [apps/www] Improve header menu --- .../src/components/ui/atoms/icon/index.tsx | 33 +--------- .../ui/molecules/language-switcher/index.tsx | 10 ++-- .../ui/molecules/navigation-menu/index.tsx | 60 +++++++++++++++---- .../components/ui/organisms/footer/index.tsx | 6 +- .../components/ui/organisms/header/index.tsx | 2 +- apps/www/src/models/link.model.ts | 5 +- apps/www/src/models/navigation-item.model.ts | 1 + apps/www/src/utils/toolbox.tsx | 47 +++++++++++---- 8 files changed, 100 insertions(+), 64 deletions(-) diff --git a/apps/www/src/components/ui/atoms/icon/index.tsx b/apps/www/src/components/ui/atoms/icon/index.tsx index 3ab5adab..841f2d45 100644 --- a/apps/www/src/components/ui/atoms/icon/index.tsx +++ b/apps/www/src/components/ui/atoms/icon/index.tsx @@ -587,7 +587,6 @@ import { XMarkIcon as XMarkIconSolid } from '@heroicons/react/24/solid' import {IconType} from '@/models/icon.model' -import color from 'tailwindcss/colors' export type IconProps = IconType & React.ComponentPropsWithoutRef<'svg'> @@ -1180,35 +1179,5 @@ const icons = { export default function Icon({name, type, ...props}: IconProps) { const Comp = icons[`${name}${type === 'solid' ? 'Solid' : 'Outline'}` as keyof typeof icons] - return type === 'outline' ? ( - - - - - - - - path]:stroke-[url(#gradient)] ${props.className}`} - /> - - ) : ( - - ) + return } diff --git a/apps/www/src/components/ui/molecules/language-switcher/index.tsx b/apps/www/src/components/ui/molecules/language-switcher/index.tsx index 9df0d1da..22fac978 100644 --- a/apps/www/src/components/ui/molecules/language-switcher/index.tsx +++ b/apps/www/src/components/ui/molecules/language-switcher/index.tsx @@ -42,7 +42,7 @@ export default function LanguageSwitcher({mobileMenuOpen}: LanguageSwitcherProps key={locale} tone='secondary' variant='link' - className='p-0 text-base text-gray-400 uppercase data-[state=active]:text-white hover:text-slate-50' + className='p-0 text-base text-slate-400 uppercase data-[state=active]:text-slate-50 hover:text-slate-50' data-active={pathMatcher(locale)} > {locale} @@ -80,7 +81,8 @@ export default function LanguageSwitcher({mobileMenuOpen}: LanguageSwitcherProps asChild tone='secondary' variant='link' - className='p-0 text-sm text-gray-400 uppercase data-[state=active]:text-white hover:text-slate-50' + className='p-0 text-sm text-gray-400 uppercase data-[state=active]:text-slate-50 \ + hover:text-slate-50' data-active={pathMatcher(localeItem)} > { + const isActive = pathname.includes(path) + return isActive + } + return orientation === 'horizontal' ? ( - + {navigationItems.map((navigationItem, index) => navigationItem.links && navigationItem.links.length > 1 ? ( @@ -34,16 +43,17 @@ export default function NavigationMenu({ -
    +
      {navigationItem.links && navigationItem.links.map((link, index) => ( - {link.title} + {link.icon && ( +
      + +
      + )} +
      {link.title}
      ))}
    @@ -73,10 +92,10 @@ export default function NavigationMenu({ ) : ( <> -
    +
    {navigationItems.map((navigationItem, index) => (
    -

    {navigationItem.title}

    +

    {navigationItem.title}

      - {link.title} + {link.icon && ( +
      + +
      + )} +
      {link.title}
      ))} @@ -110,6 +141,13 @@ export default function NavigationMenu({ export const ListItem = React.forwardRef, React.ComponentPropsWithoutRef<'a'>>( ({className, title, children, href}, ref) => { + const pathname = usePathname() + + const pathMatcher = (path: string) => { + const isActive = pathname.includes(path) + return isActive + } + return (
    • , React.ComponentP tone='primary' variant='link' align='start' - className={className} + className={cn(className, pathMatcher(href || '') ? 'text-slate-50' : '')} > {title} diff --git a/apps/www/src/components/ui/organisms/footer/index.tsx b/apps/www/src/components/ui/organisms/footer/index.tsx index acf11461..7685fa7c 100644 --- a/apps/www/src/components/ui/organisms/footer/index.tsx +++ b/apps/www/src/components/ui/organisms/footer/index.tsx @@ -25,12 +25,12 @@ export default function Footer(props: FooterProps) { { title: 'X', link: 'https://x.com/56kcloud', - icon: X + socialIcon: X }, { title: 'Linkedin', link: 'https://www.linkedin.com/company/56kcloud', - icon: Linkedin + socialIcon: Linkedin } ] @@ -63,7 +63,7 @@ export default function Footer(props: FooterProps) { target='_blank' > {item.title} -
    -
    +
    JSX.Element + socialIcon: (props: IconProps) => JSX.Element } & LinkProps diff --git a/apps/www/src/models/navigation-item.model.ts b/apps/www/src/models/navigation-item.model.ts index cedef11a..94704531 100644 --- a/apps/www/src/models/navigation-item.model.ts +++ b/apps/www/src/models/navigation-item.model.ts @@ -4,6 +4,7 @@ export type NavigationItemWithDropdown = { title: string link?: never links?: Array + dropdownWidth?: string } export type NavigationItem = NavigationItemWithDropdown | LinkProps diff --git a/apps/www/src/utils/toolbox.tsx b/apps/www/src/utils/toolbox.tsx index 3428a3f5..f11afd1f 100644 --- a/apps/www/src/utils/toolbox.tsx +++ b/apps/www/src/utils/toolbox.tsx @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import {ClassValue, clsx} from 'clsx' +import {CloudArrowDownIcon} from '@heroicons/react/24/outline' import {Dictionary} from '@/models/dictionary.model' import {HsformsPayload, HsformsPayloadItem, contactUsFormData} from '@/models/contact-us-form-data.model' import {NavigationItem} from '@/models/navigation-item.model' @@ -165,25 +166,49 @@ export function getNavigationLinks(dico: Dictionary): Array { { title: dico.services, links: [ - {title: dico.cloudMigrationAndModernization, link: '/services/cloud-migration-and-modernization'}, - {title: dico.cloudNativeApplicationDevelopment, link: '/services/cloud-native-application-development'}, - {title: dico.consultingAndTraining, link: '/services/consulting-and-training'} - ] + { + title: dico.cloudMigrationAndModernization, + link: '/services/cloud-migration-and-modernization', + icon: {name: 'CloudIcon', type: 'outline'} + }, + { + title: dico.cloudNativeApplicationDevelopment, + link: '/services/cloud-native-application-development', + icon: {name: 'WrenchIcon', type: 'outline'} + }, + + { + title: dico.consultingAndTraining, + link: '/services/consulting-and-training', + icon: {name: 'AcademicCapIcon', type: 'outline'} + } + ], + dropdownWidth: 'w-[272px]' }, { title: dico.solutions, links: [ - {title: dico.platformEngineering, link: '/solutions/platform-engineering'}, - {title: dico.edgeIoT, link: '/solutions/edge-iot'}, - {title: dico.generativeAI, link: '/solutions/generative-ai'} - ] + { + title: dico.platformEngineering, + link: '/solutions/platform-engineering', + icon: {name: 'RocketLaunchIcon', type: 'outline'} + }, + {title: dico.edgeIoT, link: '/solutions/edge-iot', icon: {name: 'CpuChipIcon', type: 'outline'}}, + { + title: dico.generativeAI, + link: '/solutions/generative-ai', + icon: {name: 'ChatBubbleLeftEllipsisIcon', type: 'outline'} + } + ], + dropdownWidth: 'w-64' }, { title: dico.company, links: [ - {title: dico.aboutUs, link: '/about-us'}, - {title: dico.blog, link: '/blog'} - ] + {title: dico.aboutUs, link: '/about-us', icon: {name: 'BuildingOfficeIcon', type: 'outline'}}, + {title: dico.blog, link: '/blog', icon: {name: 'BookOpenIcon', type: 'outline'}} + ], + dropdownWidth: 'w-40' } ] }