Different header for specific routes

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 πŸ™
14 Replies
peerreynders
peerreyndersβ€’7mo ago
Given
src/routes/user.tsx
src/routes/user/index.tsx
src/routes/user/[id].tsx
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
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’7mo ago
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
peerreynders
peerreyndersβ€’7mo ago
Using Route Groups you can even specify a top level layout for the entire app.
src/routes/(main).tsx
src/routes/(main)/index.tsx
src/routes/(main)/user.tsx
src/routes/(main)/user/index.tsx
…
src/routes/(main).tsx
src/routes/(main)/index.tsx
src/routes/(main)/user.tsx
src/routes/(main)/user/index.tsx
…
where (main).tsx is the top level layout.
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’7mo ago
Thanks πŸ™ @peerreynders 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 😦
peerreynders
peerreyndersβ€’7mo ago
That's a CSS issue. position: sticky; https://youtu.be/8MaCTDkoVd8 Welcome to front end development.
Kevin Powell
YouTube
You probably want position: sticky instead of fixed
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...
MDN Web Docs
position - CSS: Cascading Style Sheets | MDN
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.
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’7mo ago
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
peerreynders
peerreyndersβ€’7mo ago
You can just build something on the scroll event. Unlike React, Solid doesn't try to lock up the Web APIs in the attic. Or use Solid Community Primitives scroll as a starting point.
Solid Primitives
A library of high-quality primitives that extend SolidJS reactivity
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’7mo ago
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;
}
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
peerreynders
peerreyndersβ€’7mo ago
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';
};
}
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.
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’6mo ago
Thanks again Hi @peerreynders Sorry to bother you
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’6mo ago
I'm trying to change the colors after the scroll, but isn't working
No description
No description
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’6mo ago
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>
);
}
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',
},
},
);
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?
peerreynders
peerreyndersβ€’6mo ago
Probably not the problem but you will want to replace mode and className with props.mode and props.className everywhere. Destructuring breaks reactivity.
Daniel Sousa @TutoDS
Daniel Sousa @TutoDSOPβ€’6mo ago
Yeah is only that Sorry bad habbits from React
Want results from more Discord servers?
Add your server