From 79e29d3d4962174adcd70492821ec99d870a1f3f Mon Sep 17 00:00:00 2001 From: Julian Nymark Date: Mon, 25 Sep 2023 10:31:00 +0200 Subject: [PATCH 1/9] :sparkles: add AsChild to show/hide --- @navikt/core/css/primitives/responsive.css | 36 +++++++++---------- .../src/layout/responsive/Responsive.tsx | 20 +++++++++-- .../src/layout/responsive/hide.stories.tsx | 35 ++++++++++++++++++ .../src/layout/responsive/show.stories.tsx | 35 ++++++++++++++++++ 4 files changed, 104 insertions(+), 22 deletions(-) diff --git a/@navikt/core/css/primitives/responsive.css b/@navikt/core/css/primitives/responsive.css index 9f4adbfaa6..e5501ddcc1 100644 --- a/@navikt/core/css/primitives/responsive.css +++ b/@navikt/core/css/primitives/responsive.css @@ -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; } } diff --git a/@navikt/core/react/src/layout/responsive/Responsive.tsx b/@navikt/core/react/src/layout/responsive/Responsive.tsx index d0bc212f8b..777204112e 100644 --- a/@navikt/core/react/src/layout/responsive/Responsive.tsx +++ b/@navikt/core/react/src/layout/responsive/Responsive.tsx @@ -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 { children: React.ReactNode; @@ -19,6 +20,11 @@ export interface ResponsiveProps extends HTMLAttributes { * @default "div" */ as?: "div" | "span"; + + /** + * + */ + asChild?: boolean; } const Responsive = forwardRef< @@ -26,14 +32,24 @@ const Responsive = forwardRef< 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 ( - ), }; + +export const AsChild = { + render: () => ( + + + + Hidden above xl + + + Hidden above lg + + + Hidden above md + + + Hidden above sm + + + + + Hidden below xl + + + Hidden below lg + + + Hidden below md + + + Hidden below sm + + + + ), +}; diff --git a/@navikt/core/react/src/layout/responsive/show.stories.tsx b/@navikt/core/react/src/layout/responsive/show.stories.tsx index 0644faad62..1952891233 100644 --- a/@navikt/core/react/src/layout/responsive/show.stories.tsx +++ b/@navikt/core/react/src/layout/responsive/show.stories.tsx @@ -43,3 +43,38 @@ export const Default = { ), }; + +export const AsChild = { + render: () => ( + + + + Visible above xl + + + Visible above lg + + + Visible above md + + + Visible above sm + + + + + Visible below xl + + + Visible below lg + + + Visible below md + + + Visible below sm + + + + ), +}; From e1eae438e489360f689a3ab657f5b1f16e7c78ed Mon Sep 17 00:00:00 2001 From: Ken Date: Tue, 26 Sep 2023 10:22:20 +0200 Subject: [PATCH 2/9] :memo: changeset --- .changeset/serious-months-listen.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/serious-months-listen.md diff --git a/.changeset/serious-months-listen.md b/.changeset/serious-months-listen.md new file mode 100644 index 0000000000..cec1b859ec --- /dev/null +++ b/.changeset/serious-months-listen.md @@ -0,0 +1,5 @@ +--- +"@navikt/ds-react": patch +--- + +Primitives: Show/Hide støtter nå `asChild`-api From 8f19a0b6702f09c51076d2cc77283336c81da32c Mon Sep 17 00:00:00 2001 From: Ken Date: Tue, 26 Sep 2023 10:27:29 +0200 Subject: [PATCH 3/9] :memo: asChild jsdoc --- .../core/react/src/layout/responsive/Responsive.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/@navikt/core/react/src/layout/responsive/Responsive.tsx b/@navikt/core/react/src/layout/responsive/Responsive.tsx index 777204112e..7d253b9611 100644 --- a/@navikt/core/react/src/layout/responsive/Responsive.tsx +++ b/@navikt/core/react/src/layout/responsive/Responsive.tsx @@ -20,9 +20,8 @@ export interface ResponsiveProps extends HTMLAttributes { * @default "div" */ as?: "div" | "span"; - /** - * + * When true, will render element as its child. This merges classes, styles and event handlers. */ asChild?: boolean; } @@ -70,14 +69,14 @@ const Responsive = forwardRef< * @example * *
- * + * * // Only visible above "md" * * * @example * *
- * + * * // Only visible below "md" * * @@ -95,14 +94,14 @@ export const Hide = forwardRef( * @example * *
- * + * * // Only visible below "md" * * * @example * *
- * + * * // Only visible above "md" * * From 2e09fa0e53f217ab59e63ec96e2577c0aa4bff73 Mon Sep 17 00:00:00 2001 From: Ken Date: Tue, 26 Sep 2023 11:27:50 +0200 Subject: [PATCH 4/9] :memo: show demo --- .../eksempler/primitive-show/as-child.tsx | 57 +++++++++++++++++++ .../pages/eksempler/primitive-show/header.tsx | 10 ++-- .../primitive-show/layout-med-sidebar.tsx | 33 +++++++---- .../pages/eksempler/primitive-show/mix.tsx | 9 ++- .../pages/eksempler/primitive-show/show.tsx | 7 ++- 5 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx diff --git a/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx new file mode 100644 index 0000000000..a1fa834a3c --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx @@ -0,0 +1,57 @@ +import { Show, HGrid } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; +import cl from "clsx"; + +const Example = () => { + return ( + + + + + + + ); +}; + +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'", +}; + +const Placeholder = ({ + text, + noPadding, + mobil, + desktop, + className, +}: { + text?: string; + noPadding?: boolean; + mobil?: boolean; + desktop?: boolean; + className?: string; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/primitive-show/header.tsx b/aksel.nav.no/website/pages/eksempler/primitive-show/header.tsx index cc1eea47f0..8dd56c1b39 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-show/header.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-show/header.tsx @@ -20,7 +20,7 @@ const Example = () => { - + - + - + - + @@ -63,7 +63,7 @@ export const Demo = { }; export const args = { - index: 3, + index: 4, desc: "Show gjør det enklere å konsistent utføre layout-endringer ved konkrete brekkpunkt", }; diff --git a/aksel.nav.no/website/pages/eksempler/primitive-show/layout-med-sidebar.tsx b/aksel.nav.no/website/pages/eksempler/primitive-show/layout-med-sidebar.tsx index 963fdb0b22..000125c542 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-show/layout-med-sidebar.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-show/layout-med-sidebar.tsx @@ -10,20 +10,22 @@ import { VStack, Label, List, + Box, } from "@navikt/ds-react"; +import cl from "clsx"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { return (
- + - + - + @@ -43,12 +45,12 @@ export const Demo = { }; export const args = { - index: 2, + index: 3, desc: "Show/Hide fungerer bra til dynamisk endring av sidelayout basert på brekkpunkt sammen med HGrid", }; -const ContentFirst = () => ( -
+const ContentFirst = ({ className }: { className?: string }) => ( +
Kort om pleiepenger for sykt barn @@ -113,13 +115,18 @@ const LinkElement = ({ children }) => { ); }; -const DesktopSidebar = () => ( -
-
+const DesktopSidebar = ({ className }: { className?: string }) => ( + + Innhold -
+ -
+ ); -const MobileSidebar = () => ; +const MobileSidebar = ({ className }: { className?: string }) => ( + +); diff --git a/aksel.nav.no/website/pages/eksempler/primitive-show/mix.tsx b/aksel.nav.no/website/pages/eksempler/primitive-show/mix.tsx index 5384758809..9a0f4228f3 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-show/mix.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-show/mix.tsx @@ -5,11 +5,11 @@ import cl from "clsx"; const Example = () => { return ( - + - + @@ -24,7 +24,7 @@ export const Demo = { }; export const args = { - index: 1, + index: 2, desc: "Vi anbelfaler konsistent bruk av 'above' og 'below' for bedre lesbarhet.", }; @@ -33,16 +33,19 @@ const Placeholder = ({ noPadding, mobil, desktop, + className, }: { text?: string; noPadding?: boolean; mobil?: boolean; desktop?: boolean; + className?: string; }) => { return (
{ return ( - + @@ -21,7 +21,7 @@ export const Demo = { }; export const args = { - index: 0, + index: 1, desc: "Endre størrelse på nettleservindu for å se komponent i aksjon", }; @@ -30,16 +30,19 @@ const Placeholder = ({ noPadding, mobil, desktop, + className, }: { text?: string; noPadding?: boolean; mobil?: boolean; desktop?: boolean; + className?: string; }) => { return (
Date: Tue, 26 Sep 2023 11:34:39 +0200 Subject: [PATCH 5/9] :memo: hide-demo --- .../eksempler/primitive-hide/as-child.tsx | 57 +++++++++++++++++++ .../pages/eksempler/primitive-hide/header.tsx | 8 +-- .../pages/eksempler/primitive-hide/hide.tsx | 5 +- .../primitive-hide/layout-med-sidebar.tsx | 31 ++++++---- .../pages/eksempler/primitive-hide/mix.tsx | 7 ++- 5 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx new file mode 100644 index 0000000000..40a2ab1d97 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx @@ -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 ( + + + + + + + ); +}; + +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'", +}; + +const Placeholder = ({ + text, + noPadding, + mobil, + desktop, + className, +}: { + text?: string; + noPadding?: boolean; + mobil?: boolean; + desktop?: boolean; + className?: string; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/header.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/header.tsx index 065fc94598..12428a42ac 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-hide/header.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/header.tsx @@ -20,7 +20,7 @@ const Example = () => { - + - + - + - + diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/hide.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/hide.tsx index 6de2d193a7..d036a8133f 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-hide/hide.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/hide.tsx @@ -5,7 +5,7 @@ import cl from "clsx"; const Example = () => { return ( - + @@ -30,16 +30,19 @@ const Placeholder = ({ noPadding, mobil, desktop, + className, }: { text?: string; noPadding?: boolean; mobil?: boolean; desktop?: boolean; + className?: string; }) => { return (
{ return (
- + - + - + @@ -47,8 +49,8 @@ export const args = { desc: "Show/Hide fungerer bra til dynamisk endring av sidelayout basert på brekkpunkt sammen med HGrid", }; -const ContentFirst = () => ( -
+const ContentFirst = ({ className }: { className?: string }) => ( +
Kort om pleiepenger for sykt barn @@ -113,13 +115,18 @@ const LinkElement = ({ children }) => { ); }; -const DesktopSidebar = () => ( -
-
+const DesktopSidebar = ({ className }: { className?: string }) => ( + + Innhold -
+ -
+ ); -const MobileSidebar = () => ; +const MobileSidebar = ({ className }: { className?: string }) => ( + +); diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/mix.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/mix.tsx index 5384758809..6245d821e1 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-hide/mix.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/mix.tsx @@ -5,11 +5,11 @@ import cl from "clsx"; const Example = () => { return ( - + - + @@ -33,16 +33,19 @@ const Placeholder = ({ noPadding, mobil, desktop, + className, }: { text?: string; noPadding?: boolean; mobil?: boolean; desktop?: boolean; + className?: string; }) => { return (
Date: Tue, 26 Sep 2023 13:36:00 +0200 Subject: [PATCH 6/9] Update aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx --- .../website/pages/eksempler/primitive-hide/as-child.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx index 40a2ab1d97..6a9ac821b9 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx @@ -22,7 +22,7 @@ export const Demo = { 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'", + desc: "Vi anbefaler å bruke 'asChild'-prop der mulig. Dette reduserer dom-noder og forenkler output. For at dette skal fungere må child-element endten ikke inneholde 'className' eller forwarde 'className'", }; const Placeholder = ({ From e4376a7f9ed62fe0dfabe10b1a1e390f08c81cf6 Mon Sep 17 00:00:00 2001 From: Ken <26967723+KenAJoh@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:36:29 +0200 Subject: [PATCH 7/9] Update aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx --- .../website/pages/eksempler/primitive-show/as-child.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx index a1fa834a3c..5ba4a51da6 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx @@ -22,7 +22,7 @@ export const Demo = { 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'", + desc: "Vi anbefaler å bruke 'asChild'-prop der mulig. Dette reduserer dom-noder og forenkler output. For at dette skal fungere må child-element enten ikke inneholde 'className' eller forwarde 'className'", }; const Placeholder = ({ From 36ef16ba9f275b87178854bb61aded90f39aa6c6 Mon Sep 17 00:00:00 2001 From: Ken <26967723+KenAJoh@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:36:53 +0200 Subject: [PATCH 8/9] Update aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx --- .../website/pages/eksempler/primitive-hide/as-child.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx index 6a9ac821b9..b02bf19841 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx @@ -22,7 +22,7 @@ export const Demo = { 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 endten ikke inneholde 'className' eller forwarde 'className'", + desc: "Vi anbefaler å bruke 'asChild'-prop der mulig. Dette reduserer dom-noder og forenkler output. For at dette skal fungere må child-element enten ikke inneholde 'className' eller forwarde 'className'", }; const Placeholder = ({ From d42534fe0c44226da9c22cb252272a0d76315676 Mon Sep 17 00:00:00 2001 From: Ken Date: Tue, 26 Sep 2023 13:47:55 +0200 Subject: [PATCH 9/9] :memo: Oppdatert docs --- .../website/pages/eksempler/primitive-hide/as-child.tsx | 2 +- .../website/pages/eksempler/primitive-show/as-child.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx index b02bf19841..43bc58e6b5 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-hide/as-child.tsx @@ -22,7 +22,7 @@ export const Demo = { 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 enten ikke inneholde 'className' eller forwarde 'className'", + desc: "Vi anbefaler å bruke 'asChild'-prop der mulig. Dette reduserer dom-noder og forenkler output. For at Hide + child-komponent skal fungere må child kunne ta inn 'className' som prop.", }; const Placeholder = ({ diff --git a/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx b/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx index 5ba4a51da6..7f83844172 100644 --- a/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx +++ b/aksel.nav.no/website/pages/eksempler/primitive-show/as-child.tsx @@ -22,7 +22,7 @@ export const Demo = { 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 enten ikke inneholde 'className' eller forwarde 'className'", + desc: "Vi anbefaler å bruke 'asChild'-prop der mulig. Dette reduserer dom-noder og forenkler output. For at Show + child-komponent skal fungere må child kunne ta inn 'className' som prop.", }; const Placeholder = ({