Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ add AsChild to show/hide #2312

Merged
merged 10 commits into from
Sep 26, 2023
5 changes: 5 additions & 0 deletions .changeset/serious-months-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/ds-react": patch
---

Primitives: Show/Hide stΓΈtter nΓ₯ `asChild`-api
36 changes: 16 additions & 20 deletions @navikt/core/css/primitives/responsive.css
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
.navds-responsive {
display: none;
}

@media (min-width: 480px) {
.navds-responsive__above--sm {
display: revert;
.navds-responsive__below--sm {
display: none !important;
}
}

@media (max-width: 479px) {
.navds-responsive__below--sm {
display: revert;
.navds-responsive__above--sm {
display: none !important;
}
}

@media (min-width: 768px) {
.navds-responsive__above--md {
display: revert;
.navds-responsive__below--md {
display: none !important;
}
}

@media (max-width: 767px) {
.navds-responsive__below--md {
display: revert;
.navds-responsive__above--md {
display: none !important;
}
}

@media (min-width: 1024px) {
.navds-responsive__above--lg {
display: revert;
.navds-responsive__below--lg {
display: none !important;
}
}

@media (max-width: 1023px) {
.navds-responsive__below--lg {
display: revert;
.navds-responsive__above--lg {
display: none !important;
}
}

@media (min-width: 1280px) {
.navds-responsive__above--xl {
display: revert;
.navds-responsive__below--xl {
display: none !important;
}
}

@media (max-width: 1279px) {
.navds-responsive__below--xl {
display: revert;
.navds-responsive__above--xl {
display: none !important;
}
}
27 changes: 21 additions & 6 deletions @navikt/core/react/src/layout/responsive/Responsive.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cl from "clsx";
import React, { forwardRef, HTMLAttributes } from "react";
import { BreakpointsAlias } from "../utilities/css";
import { Slot } from "../../util/Slot";

export interface ResponsiveProps extends HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
Expand All @@ -19,21 +20,35 @@ export interface ResponsiveProps extends HTMLAttributes<HTMLDivElement> {
* @default "div"
*/
as?: "div" | "span";
/**
* When true, will render element as its child. This merges classes, styles and event handlers.
*/
asChild?: boolean;
}

const Responsive = forwardRef<
HTMLDivElement,
ResponsiveProps & { variant: "show" | "hide" }
>(
(
{ as: Component = "div", className, above, below, variant, ...rest },
{
as: Component = "div",
className,
above,
below,
variant,
asChild,
...rest
},
ref
) => {
const aboveProp = variant === "show" ? above : below;
const belowProp = variant === "show" ? below : above;

const Comp = asChild ? Slot : Component;

return (
<Component
<Comp
{...rest}
ref={ref}
className={cl("navds-responsive", className, {
Expand All @@ -54,14 +69,14 @@ const Responsive = forwardRef<
* @example
* <HGrid columns={{ xs: 1, md: 2 }} gap="4">
* <div/>
* <Hide below="md">
* <Hide below="md" asChild>
* // Only visible above "md"
* </Hide>
* </HGrid>
* @example
* <HGrid columns={{ xs: 1, md: 2 }} gap="4">
* <div/>
* <Hide above="md">
* <Hide above="md" asChild>
* // Only visible below "md"
* </Hide>
* </HGrid>
Expand All @@ -79,14 +94,14 @@ export const Hide = forwardRef<HTMLDivElement, ResponsiveProps>(
* @example
* <HGrid columns={{ xs: 1, md: 2 }} gap="4">
* <div/>
* <Show below="md">
* <Show below="md" asChild>
* // Only visible below "md"
* </Show>
* </HGrid>
* @example
* <HGrid columns={{ xs: 1, md: 2 }} gap="4">
* <div/>
* <Show above="md">
* <Show above="md" asChild>
* // Only visible above "md"
* </Show>
* </HGrid>
Expand Down
35 changes: 35 additions & 0 deletions @navikt/core/react/src/layout/responsive/hide.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,38 @@ export const Default = {
</VStack>
),
};

export const AsChild = {
render: () => (
<VStack gap="12">
<VStack gap="2" align="center">
<Hide above="xl" asChild>
<Tag variant="neutral">Hidden above xl</Tag>
</Hide>
<Hide above="lg" asChild>
<Tag variant="neutral">Hidden above lg</Tag>
</Hide>
<Hide above="md" asChild>
<Tag variant="neutral">Hidden above md</Tag>
</Hide>
<Hide above="sm" asChild>
<Tag variant="neutral">Hidden above sm</Tag>
</Hide>
</VStack>
<VStack gap="2" align="center">
<Hide below="xl" asChild>
<Tag variant="alt3">Hidden below xl</Tag>
</Hide>
<Hide below="lg" asChild>
<Tag variant="alt3">Hidden below lg</Tag>
</Hide>
<Hide below="md" asChild>
<Tag variant="alt3">Hidden below md</Tag>
</Hide>
<Hide below="sm" asChild>
<Tag variant="alt3">Hidden below sm</Tag>
</Hide>
</VStack>
</VStack>
),
};
35 changes: 35 additions & 0 deletions @navikt/core/react/src/layout/responsive/show.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,38 @@ export const Default = {
</VStack>
),
};

export const AsChild = {
render: () => (
<VStack gap="12">
<VStack gap="2" align="center">
<Show above="xl" asChild>
<Tag variant="neutral">Visible above xl</Tag>
</Show>
<Show above="lg" asChild>
<Tag variant="neutral">Visible above lg</Tag>
</Show>
<Show above="md" asChild>
<Tag variant="neutral">Visible above md</Tag>
</Show>
<Show above="sm" asChild>
<Tag variant="neutral">Visible above sm</Tag>
</Show>
</VStack>
<VStack gap="2" align="center">
<Show below="xl" asChild>
<Tag variant="alt3">Visible below xl</Tag>
</Show>
<Show below="lg" asChild>
<Tag variant="alt3">Visible below lg</Tag>
</Show>
<Show below="md" asChild>
<Tag variant="alt3">Visible below md</Tag>
</Show>
<Show below="sm" asChild>
<Tag variant="alt3">Visible below sm</Tag>
</Show>
</VStack>
</VStack>
),
};
57 changes: 57 additions & 0 deletions aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Hide, HGrid } from "@navikt/ds-react";
import { withDsExample } from "components/website-modules/examples/withDsExample";
import cl from "clsx";

const Example = () => {
return (
<HGrid columns={{ xs: 1, md: 2 }} gap="4">
<Hide above="md" asChild>
<Placeholder mobil text="Synlig bare pΓ₯ mobil" />
</Hide>
<Placeholder text="Alltid synlig" />
</HGrid>
);
};

export default withDsExample(Example, { showBreakpoints: true });

/* Storybook story */
export const Demo = {
render: Example,
};

export const args = {
index: 0,
desc: "Vi anbefaler Γ₯ bruke 'asChild'-prop der mulig. Dette reduserer dom-noder og forenkler output. For at dette skal fungere mΓ₯ child-element endte ikke inneholde 'className' eller forwarde 'className'",
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
};

const Placeholder = ({
text,
noPadding,
mobil,
desktop,
className,
}: {
text?: string;
noPadding?: boolean;
mobil?: boolean;
desktop?: boolean;
className?: string;
}) => {
return (
<div
className={cl(
"min-h-24 text-text-on-action grid aspect-video h-auto w-auto place-content-center rounded p-2",
className,
{
"bg-pink-600": mobil,
"bg-violet-600": desktop,
"bg-teal-600": !desktop && !mobil,
}
)}
style={{ padding: noPadding && 0 }}
>
{text}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ const Example = () => {
<Button icon={<MenuHamburgerIcon aria-hidden />} variant="tertiary">
Meny
</Button>
<Hide below="md">
<Hide below="md" asChild>
<Button
icon={<MagnifyingGlassIcon aria-hidden />}
variant="tertiary"
>
SΓΈk
</Button>
</Hide>
<Hide below="sm">
<Hide below="sm" asChild>
<Button icon={<BellIcon aria-hidden />} variant="tertiary">
Varsler
</Button>
</Hide>
<Hide below="md">
<Hide below="md" asChild>
<Button icon={<PersonIcon aria-hidden />} variant="tertiary">
<BodyShort weight="semibold" truncate className="max-w-[10vw]">
Ola Aksel Norman
</BodyShort>
</Button>
</Hide>
<Hide below="md">
<Hide below="md" asChild>
<Button icon={<LeaveIcon aria-hidden />} variant="tertiary">
Logg ut
</Button>
Expand Down
5 changes: 4 additions & 1 deletion aksel.nav.no/website/pages/eksempler/primitive-hide/hide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import cl from "clsx";
const Example = () => {
return (
<HGrid columns="1" gap="4">
<Hide above="md">
<Hide above="md" asChild>
<Placeholder mobil text="Synlig bare pΓ₯ mobil" />
</Hide>
<Placeholder text="Alltid synlig" />
Expand All @@ -30,16 +30,19 @@ const Placeholder = ({
noPadding,
mobil,
desktop,
className,
}: {
text?: string;
noPadding?: boolean;
mobil?: boolean;
desktop?: boolean;
className?: string;
}) => {
return (
<div
className={cl(
"min-h-24 text-text-on-action grid aspect-video h-auto w-auto place-content-center rounded p-2",
className,
{
"bg-pink-600": mobil,
"bg-violet-600": desktop,
Expand Down
Loading