#Different header for specific routes

24 messages · Page 1 of 1 (latest)

warm mountain
#

Hi everyone
Maybe it's noob question and sorry for that.
It's possible have different layouts for specific routes?

For example transparent header and a header with background in certain routes.

Thanks 🙏

split moon
#

Given

src/routes/user.tsx
src/routes/user/index.tsx
src/routes/user/[id].tsx

user.tsx would act as the layout for both the \user (index.tsx) and \user\:id ([id].tsx) routes.

Nested Layouts
Escaping nested Routes

warm mountain
#

OK, so everytime I want a specific layout I need to create the <route>.tsx for layout and the <route>/index.tsx for the page itself

#

Thanks

split moon
warm mountain
#

Thanks 🙏

warm mountain
#

@split moon sorry for the noob question, what's the best way of doing an sticky header that change the colors?
I'm new on solid, sorry about that 😦

split moon
# warm mountain <@1040721210142634016> sorry for the noob question, what's the best way of doing...

That's a CSS issue.

position: sticky;

https://youtu.be/8MaCTDkoVd8

Welcome to front end development.

Position fixed and sticky have a lot of similarities, but sticky has a few things it does a lot better and a few things that we just can’t do with fixed, so in this video, I compare the difference between the two and also look at a few fun use cases for sticky.

🔗 Links
✅ Use position sticky to tell a story with CSS: https://youtu.be/ErSwQhrfbu...

▶ Play video
MDN Web Docs

The position CSS property sets how an element is positioned in a document. The top, right, bottom, and left properties determine the final location of positioned elements.

warm mountain
#

I know that I can use sticky, but I want to change the header after the scroll

#

Like:

  • at the beginning be transparent
  • after the scroll rende the header with background
split moon
warm mountain
#

Thanks, I'm trying to use a primitive for window size, but it's not being easy.
Probably a noob mistake

#
function useDeviceType() {
  const size = useWindowSize();
  const [deviceType, setDeviceType] = createSignal<'desktop' | 'tablet' | 'mobile'>(
    'desktop',
  );

  createEffect(() => {
    if (size.width > 480 && size.width < 1024) {
      setDeviceType('tablet');
      return;
    }

    if (size.width <= 480) {
      setDeviceType('mobile');
      return;
    }

    setDeviceType('desktop');
  }, size);

  return deviceType;
}

This is more to hide the header if it's a mobile or tablet device

split moon
#

Derived values

function useDeviceType() {
  const size = useWindowSize();
  return () => {
    if (size.width > 480 && size.width < 1024) return 'tablet';
    if (size.width <= 480) return 'mobile';
    return 'desktop';
  };
}

You could use createMemo() but it's overkill.

warm mountain
#

Thanks again

warm mountain
#

Hi @split moon
Sorry to bother you

#

I'm trying to change the colors after the scroll, but isn't working

#
function Header({ mode = 'transparent', className = '' }: HeaderProps) {
  const scroll = useWindowScrollPosition();
  const deviceType = useDeviceType();

  const modeAfterScroll = createMemo(() =>
    scroll.y > 100 && mode === 'transparent' ? 'solid' : mode,
  );

  console.log(modeAfterScroll(), '<-');

  return (
    <header
      class={twMerge(
        headerVariants({
          mode: modeAfterScroll(),
          class: className,
        }),
      )}
    >
      <div class={twMerge(headerContainerVariants({ mode }))}>
        <a href="/" class={cn([{ 'text-white': modeAfterScroll() === 'transparent' }])}>
          MC Ocidente charmoso
        </a>

        <Switch>
          <Match when={deviceType() === 'desktop'}>
            <Navigation mode={modeAfterScroll()} />
          </Match>

          <Match when={['mobile', 'tablet'].includes(deviceType())}>
            <MobileNavigation mode={modeAfterScroll()} />
          </Match>
        </Switch>
      </div>
    </header>
  );
}
#

This is my code

#

and I have variants on the navigation, like this:

const navigatioItemVariants = cva(
  [
    'h-14',
    'px-4',
    'inline-flex items-center justify-center',
    'font-semibold',
    'transition ease-in-out duration-300',
    'relative before:content-[""] before:w-full before:h-0.5 before:bg-transparent before:absolute before:top-0 before:inset-x-0 before:rounded-b-sm',
  ],
  {
    variants: {
      isActive: {
        true: [],
        false: [],
      },
      mode: {
        transparent: ['text-gray-50', 'hover:text-white hover:before:bg-white'],
        solid: ['text-gray-800', 'hover:text-gray-900 hover:before:bg-gray-900'],
      },
    },
    compoundVariants: [
      {
        isActive: true,
        mode: 'solid',
        class: ['before:bg-gray-900', 'text-gray-900'],
      },
      {
        isActive: true,
        mode: 'transparent',
        class: ['before:bg-white', 'text-white'],
      },
    ],
    defaultVariants: {
      isActive: false,
      mode: 'transparent',
    },
  },
);
#

The problem is the colors not being updated after the scroll

#

Any idea what I'm doing wrong?

split moon
#

Probably not the problem but you will want to replace mode and className with props.mode and props.className everywhere. Destructuring breaks reactivity.

warm mountain
#

Yeah is only that