diff --git a/.changeset/cuddly-walls-thank.md b/.changeset/cuddly-walls-thank.md new file mode 100644 index 0000000000..7e5ec413a0 --- /dev/null +++ b/.changeset/cuddly-walls-thank.md @@ -0,0 +1,6 @@ +--- +"@navikt/ds-css": minor +"@navikt/ds-react": minor +--- + +Nye komponenter `VStack`, `HStack` og `Spacer` for å enklere kunne lage layout med flexbox og spacing-variabler. diff --git a/@navikt/core/css/config/_mappings.js b/@navikt/core/css/config/_mappings.js index afa5316fe5..3525889f76 100644 --- a/@navikt/core/css/config/_mappings.js +++ b/@navikt/core/css/config/_mappings.js @@ -57,7 +57,7 @@ const StyleMappings = { { component: "UNSAFE_Combobox", main: "combobox.css", - dependencies: [typoCss], + dependencies: [typoCss, "chips.css"], }, { component: "ConfirmationPanel", @@ -134,6 +134,18 @@ const StyleMappings = { { component: "Select", main: formCss, dependencies: [typoCss] }, { component: "Skeleton", main: "skeleton.css", dependencies: [] }, { component: "Stepper", main: "stepper.css", dependencies: [typoCss] }, + { + component: "HStack", + main: "stack.css", + }, + { + component: "VStack", + main: "stack.css", + }, + { + component: "Spacer", + main: "stack.css", + }, { component: "Switch", main: formCss, dependencies: [typoCss] }, { component: "Table", main: "table.css", dependencies: [typoCss] }, { component: "Tabs", main: "tabs.css", dependencies: [typoCss] }, diff --git a/@navikt/core/css/index.css b/@navikt/core/css/index.css index 24aa5017c4..2dad528742 100644 --- a/@navikt/core/css/index.css +++ b/@navikt/core/css/index.css @@ -29,6 +29,7 @@ @import "link-panel.css"; @import "read-more.css"; @import "skeleton.css"; +@import "stack.css"; @import "stepper.css"; @import "table.css"; @import "tabs.css"; diff --git a/@navikt/core/css/stack.css b/@navikt/core/css/stack.css new file mode 100644 index 0000000000..bdb45790d2 --- /dev/null +++ b/@navikt/core/css/stack.css @@ -0,0 +1,61 @@ +/* stylelint-disable csstools/value-no-unknown-custom-properties */ +/* stylelint-disable aksel/design-token-exists */ +.navds-stack { + --ac-stack-align: initial; + --ac-stack-justify: initial; + --ac-stack-direction: initial; + --ac-stack-wrap: initial; + --ac-stack-gap-xs: initial; + --ac-stack-gap-sm: initial; + --ac-stack-gap-md: initial; + --ac-stack-gap-lg: initial; + --ac-stack-gap-xl: initial; + --__ac-stack-gap: var(--ac-stack-gap-xs); + + gap: var(--__ac-stack-gap); + display: flex; + align-items: var(--ac-stack-align); + justify-content: var(--ac-stack-justify); + flex-flow: var(--ac-stack-direction) var(--ac-stack-wrap); +} + +.navds-stack__spacer { + flex: 1; + justify-self: stretch; + align-self: stretch; +} + +.navds-stack > .navds-stack__spacer { + margin-block-start: calc(var(--__ac-stack-gap) * -1); +} + +.navds-hstack > .navds-stack__spacer { + margin-inline-start: calc(var(--__ac-stack-gap) * -1); +} + +@media (min-width: 480px) { + .navds-stack { + --__ac-stack-gap: var(--ac-stack-gap-sm, var(--ac-stack-gap-xs)); + } +} + +@media (min-width: 768px) { + .navds-stack { + --__ac-stack-gap: var(--ac-stack-gap-md, var(--ac-stack-gap-sm, var(--ac-stack-gap-xs))); + } +} + +@media (min-width: 1024px) { + .navds-stack { + --__ac-stack-gap: var(--ac-stack-gap-lg, var(--ac-stack-gap-md, var(--ac-stack-gap-sm, var(--ac-stack-gap-xs)))); + } +} + +@media (min-width: 1280px) { + .navds-stack { + --__ac-stack-gap: var( + --ac-stack-gap-xl, + var(--ac-stack-gap-lg, var(--ac-stack-gap-md, var(--ac-stack-gap-sm, var(--ac-stack-gap-xs)))) + ); + } +} diff --git a/@navikt/core/react/src/index.ts b/@navikt/core/react/src/index.ts index 5801a478b4..805e825f8a 100644 --- a/@navikt/core/react/src/index.ts +++ b/@navikt/core/react/src/index.ts @@ -32,3 +32,4 @@ export * from "./toggle-group"; export * from "./tooltip"; export * from "./typography"; export * from "./util"; +export * from "./layout/stack"; diff --git a/@navikt/core/react/src/layout/stack/HStack.tsx b/@navikt/core/react/src/layout/stack/HStack.tsx new file mode 100644 index 0000000000..258efefac2 --- /dev/null +++ b/@navikt/core/react/src/layout/stack/HStack.tsx @@ -0,0 +1,30 @@ +import React, { forwardRef } from "react"; +import { OverridableComponent } from "../../util/OverridableComponent"; +import { StackProps, Stack } from "./Stack"; + +export type HStackProps = Omit; + +/** + * Layout-primitive for horizontal flexbox + * + * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/Stack) + * @see 🏷️ {@link HStackProps} + * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support + * + * @example + * + * + * + * + * + * @example + * // Responsive gap + * + * + * + * + */ +export const HStack: OverridableComponent = + forwardRef((props, ref) => { + return ; + }); diff --git a/@navikt/core/react/src/layout/stack/Spacer.tsx b/@navikt/core/react/src/layout/stack/Spacer.tsx new file mode 100644 index 0000000000..ec07e65621 --- /dev/null +++ b/@navikt/core/react/src/layout/stack/Spacer.tsx @@ -0,0 +1,15 @@ +import React from "react"; + +/** + * Layout-primitive for auto-spacing between elements + * + * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/Stack) + * + * @example + * + * + * + * + * + */ +export const Spacer = () =>
; diff --git a/@navikt/core/react/src/layout/stack/Stack.tsx b/@navikt/core/react/src/layout/stack/Stack.tsx new file mode 100644 index 0000000000..b4bec67156 --- /dev/null +++ b/@navikt/core/react/src/layout/stack/Stack.tsx @@ -0,0 +1,76 @@ +import cl from "clsx"; +import React, { forwardRef, HTMLAttributes } from "react"; +import { OverridableComponent } from "../../util/OverridableComponent"; +import { + getResponsiveProps, + ResponsiveProp, + SpacingScale, +} from "../utilities/css"; + +export interface StackProps extends HTMLAttributes { + children: React.ReactNode; + /** + * Justify-content + */ + justify?: + | "start" + | "center" + | "end" + | "space-around" + | "space-between" + | "space-evenly"; + /** + * Align-items + */ + align?: "start" | "center" | "end" | "baseline" | "stretch"; + /** + * flex-wrap + */ + wrap?: boolean; + /** + * @example + * gap='4' + * gap={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}} + */ + gap?: ResponsiveProp; + direction: "row" | "column"; +} + +export const Stack: OverridableComponent = + forwardRef( + ( + { + as: Component = "div", + className, + align, + justify, + wrap = true, + gap, + style: _style, + direction, + ...rest + }, + ref + ) => { + const style = { + "--ac-stack-direction": direction, + "--ac-stack-align": align, + "--ac-stack-justify": justify, + "--ac-stack-wrap": wrap ? "wrap" : "nowrap", + ...getResponsiveProps(`stack`, "gap", "spacing", gap), + ..._style, + } as React.CSSProperties; + + return ( + + ); + } + ); diff --git a/@navikt/core/react/src/layout/stack/VStack.tsx b/@navikt/core/react/src/layout/stack/VStack.tsx new file mode 100644 index 0000000000..006c6aa22c --- /dev/null +++ b/@navikt/core/react/src/layout/stack/VStack.tsx @@ -0,0 +1,30 @@ +import React, { forwardRef } from "react"; +import { OverridableComponent } from "../../util/OverridableComponent"; +import { StackProps, Stack } from "./Stack"; + +export type VStackProps = Omit; + +/** + * Layout-primitive for vetical flexbox + * + * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/Stack) + * @see 🏷️ {@link VStackProps} + * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support + * + * @example + * + * + * + * + * + * @example + * // Responsive gap + * + * + * + * + */ +export const VStack: OverridableComponent = + forwardRef((props, ref) => { + return ; + }); diff --git a/@navikt/core/react/src/layout/stack/index.ts b/@navikt/core/react/src/layout/stack/index.ts new file mode 100644 index 0000000000..3cca62e4af --- /dev/null +++ b/@navikt/core/react/src/layout/stack/index.ts @@ -0,0 +1,3 @@ +export { HStack, type HStackProps } from "./HStack"; +export { VStack, type VStackProps } from "./VStack"; +export { Spacer } from "./Spacer"; diff --git a/@navikt/core/react/src/layout/stack/stack.stories.tsx b/@navikt/core/react/src/layout/stack/stack.stories.tsx new file mode 100644 index 0000000000..7edc23b4f7 --- /dev/null +++ b/@navikt/core/react/src/layout/stack/stack.stories.tsx @@ -0,0 +1,161 @@ +import React from "react"; +import type { Meta } from "@storybook/react"; +import { HStack, VStack, Spacer } from "."; + +export default { + title: "ds-react/Stack", + component: HStack, +} satisfies Meta; + +export const Horizontal = { + render: () => ( + + + + ), +}; + +export const Spacing = { + render: () => ( +
+ + + + + + + + + + + + + + + +
+ ), + parameters: { + layout: "fullscreen", + }, +}; + +export const Vertical = { + render: () => ( + + + + ), +}; + +export const VerticalDemo = { + render: () => ( + + + + + + + + + + ), +}; + +export const VerticalAlign = { + render: () => ( + + + + + + + + + + + + ), + parameters: { + layout: "fullscreen", + }, +}; + +export const OverrideComponent = { + render: () => ( + e.preventDefault()}> + + + ), +}; + +export const Responsive = { + render: () => ( + + + + ), +}; + +export const Nested = { + render: () => ( + + + + + + + + ), +}; + +export const DividerDemo = { + render: () => ( +
+ + + + + + +
+ + + +
+
+ ), +}; + +function Placeholders({ + count, + children, + color, +}: { + count: number; + children?: React.ReactNode; + color?: string; +}) { + return ( + <> + {Array.from({ length: count }, (_, i) => ( +
+ {children} +
+ ))} + + ); +} diff --git a/@navikt/core/react/src/layout/utilities/css.ts b/@navikt/core/react/src/layout/utilities/css.ts new file mode 100644 index 0000000000..84cc50074d --- /dev/null +++ b/@navikt/core/react/src/layout/utilities/css.ts @@ -0,0 +1,56 @@ +export type BreakpointsAlias = "xs" | "sm" | "md" | "lg" | "xl"; +export type SpacingScale = + | "0" + | "05" + | "1" + | "2" + | "3" + | "4" + | "5" + | "6" + | "7" + | "8" + | "9" + | "10" + | "11" + | "12" + | "14" + | "16" + | "18" + | "20" + | "24" + | "32"; + +export type ResponsiveProp = + | T + | { + // eslint-disable-next-line no-unused-vars + [Breakpoint in BreakpointsAlias]?: T; + }; + +export function getResponsiveProps( + componentName: string, + componentProp: string, + tokenSubgroup: string, + responsiveProp?: + | string + | { + // eslint-disable-next-line no-unused-vars + [Breakpoint in BreakpointsAlias]?: string; + } +) { + if (!responsiveProp) return {}; + + if (typeof responsiveProp === "string") { + return { + [`--ac-${componentName}-${componentProp}-xs`]: `var(--a-${tokenSubgroup}-${responsiveProp})`, + }; + } + + return Object.fromEntries( + Object.entries(responsiveProp).map(([breakpointAlias, aliasOrScale]) => [ + `--ac-${componentName}-${componentProp}-${breakpointAlias}`, + `var(--a-${tokenSubgroup}-${aliasOrScale})`, + ]) + ); +} diff --git a/aksel.nav.no/website/pages/eksempler/h-stack/align.tsx b/aksel.nav.no/website/pages/eksempler/h-stack/align.tsx new file mode 100644 index 0000000000..f9469aeff1 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/h-stack/align.tsx @@ -0,0 +1,73 @@ +import { HStack, VStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 2, + desc: "Endrer 'align-items'.", +}; + +const Placeholder = ({ + text, + noPadding, +}: { + text?: string; + noPadding?: boolean; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/h-stack/default.tsx b/aksel.nav.no/website/pages/eksempler/h-stack/default.tsx new file mode 100644 index 0000000000..5203570ed8 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/h-stack/default.tsx @@ -0,0 +1,29 @@ +import { HStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + + + + + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 0, + desc: "HStack er en enkel layout-komponent for flexbox.", +}; + +const Placeholder = () => { + return
; +}; diff --git a/aksel.nav.no/website/pages/eksempler/h-stack/justify.tsx b/aksel.nav.no/website/pages/eksempler/h-stack/justify.tsx new file mode 100644 index 0000000000..53982d318f --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/h-stack/justify.tsx @@ -0,0 +1,76 @@ +import { HStack, VStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 3, + desc: "Endrer 'justify-content'.", +}; + +const Placeholder = ({ + text, + noPadding, +}: { + text?: string; + noPadding?: boolean; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/h-stack/nowrap.tsx b/aksel.nav.no/website/pages/eksempler/h-stack/nowrap.tsx new file mode 100644 index 0000000000..ced8fa53cc --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/h-stack/nowrap.tsx @@ -0,0 +1,32 @@ +import { HStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + + + + + + + + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 1, + desc: "Som standard er 'wrap' satt til 'true'.", +}; + +const Placeholder = () => { + return
; +}; diff --git a/aksel.nav.no/website/pages/eksempler/h-stack/responsive-gap.tsx b/aksel.nav.no/website/pages/eksempler/h-stack/responsive-gap.tsx new file mode 100644 index 0000000000..52ab1649a0 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/h-stack/responsive-gap.tsx @@ -0,0 +1,29 @@ +import { HStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + + + + + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 4, + desc: "Med responsive gap kan man redusere/øke mellomrom basert på brekkpunktene våre. Implementasjonen er mobile-first, slik at man 'sm: 8' vil sette gap for 'md', 'lg' og 'xl' også.", +}; + +const Placeholder = () => { + return
; +}; diff --git a/aksel.nav.no/website/pages/eksempler/h-stack/spacer.tsx b/aksel.nav.no/website/pages/eksempler/h-stack/spacer.tsx new file mode 100644 index 0000000000..3d01c74f37 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/h-stack/spacer.tsx @@ -0,0 +1,43 @@ +import { HStack, Spacer } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+ + + + + +
+ ); +}; + +export default withDsExample(Example, "static"); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 7, + desc: "Spacer lar deg lett legge inn automatisk stretch mellom elementer. Dette kan komme inn nyttig når man f.eks skal plassere knapper i 'InternalHeader'.", +}; + +const Placeholder = ({ + text, + noPadding, +}: { + text?: string; + noPadding?: boolean; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/header/default.tsx b/aksel.nav.no/website/pages/eksempler/header/default.tsx index 2bbe53e461..e03c776a1a 100644 --- a/aksel.nav.no/website/pages/eksempler/header/default.tsx +++ b/aksel.nav.no/website/pages/eksempler/header/default.tsx @@ -1,11 +1,12 @@ -import { InternalHeader } from "@navikt/ds-react"; +import { InternalHeader, Spacer } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { return ( Sykepenger - + + ); }; diff --git a/aksel.nav.no/website/pages/eksempler/header/description.tsx b/aksel.nav.no/website/pages/eksempler/header/description.tsx index 44f7b95ea6..1d4f725d04 100644 --- a/aksel.nav.no/website/pages/eksempler/header/description.tsx +++ b/aksel.nav.no/website/pages/eksempler/header/description.tsx @@ -1,15 +1,12 @@ -import { InternalHeader } from "@navikt/ds-react"; +import { InternalHeader, Spacer } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { return ( Sykepenger - + + ); }; diff --git a/aksel.nav.no/website/pages/eksempler/header/home.tsx b/aksel.nav.no/website/pages/eksempler/header/home.tsx index fef85434ed..a2ead45539 100644 --- a/aksel.nav.no/website/pages/eksempler/header/home.tsx +++ b/aksel.nav.no/website/pages/eksempler/header/home.tsx @@ -1,11 +1,12 @@ -import { InternalHeader } from "@navikt/ds-react"; +import { InternalHeader, Spacer } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { return ( Sykepenger - + + ); }; diff --git a/aksel.nav.no/website/pages/eksempler/header/menu.tsx b/aksel.nav.no/website/pages/eksempler/header/menu.tsx index 0b93b603d4..0a5e9c772b 100644 --- a/aksel.nav.no/website/pages/eksempler/header/menu.tsx +++ b/aksel.nav.no/website/pages/eksempler/header/menu.tsx @@ -1,16 +1,16 @@ -import { Dropdown, InternalHeader } from "@navikt/ds-react"; +import { Dropdown, InternalHeader, Spacer } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { return ( Sykepenger + diff --git a/aksel.nav.no/website/pages/eksempler/header/search.tsx b/aksel.nav.no/website/pages/eksempler/header/search.tsx index f642b0a6e1..fb84e91a01 100644 --- a/aksel.nav.no/website/pages/eksempler/header/search.tsx +++ b/aksel.nav.no/website/pages/eksempler/header/search.tsx @@ -1,4 +1,4 @@ -import { Search } from "@navikt/ds-react"; +import { Search, Spacer } from "@navikt/ds-react"; import { InternalHeader } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; @@ -20,7 +20,8 @@ const Example = () => { placeholder="Søk" /> - + + ); }; diff --git a/aksel.nav.no/website/pages/eksempler/header/system.tsx b/aksel.nav.no/website/pages/eksempler/header/system.tsx index 1ee9bd8004..d1260cc995 100644 --- a/aksel.nav.no/website/pages/eksempler/header/system.tsx +++ b/aksel.nav.no/website/pages/eksempler/header/system.tsx @@ -1,13 +1,14 @@ import { MenuGridIcon } from "@navikt/aksel-icons"; -import { Dropdown, InternalHeader } from "@navikt/ds-react"; +import { Dropdown, InternalHeader, Spacer } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { return ( Sykepenger + - + { + return ( +
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 1, + desc: "Endrer 'align-items'.", +}; + +const Placeholder = ({ + text, + noPadding, +}: { + text?: string; + noPadding?: boolean; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/v-stack/default.tsx b/aksel.nav.no/website/pages/eksempler/v-stack/default.tsx new file mode 100644 index 0000000000..9bcce23513 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/v-stack/default.tsx @@ -0,0 +1,29 @@ +import { VStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + + + + + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 0, + desc: "VStack er en enkel layout-komponent for flexbox med flex-direction: column.", +}; + +const Placeholder = () => { + return
; +}; diff --git a/aksel.nav.no/website/pages/eksempler/v-stack/justify.tsx b/aksel.nav.no/website/pages/eksempler/v-stack/justify.tsx new file mode 100644 index 0000000000..191ee6b9eb --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/v-stack/justify.tsx @@ -0,0 +1,72 @@ +import { HStack, VStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 2, + desc: "Endrer 'justify-content'.", +}; + +const Divider = () => { + return
; +}; + +const Placeholder = ({ + text, + noPadding, +}: { + text?: string; + noPadding?: boolean; +}) => { + return ( +
+ {text} +
+ ); +}; diff --git a/aksel.nav.no/website/pages/eksempler/v-stack/responsive-gap.tsx b/aksel.nav.no/website/pages/eksempler/v-stack/responsive-gap.tsx new file mode 100644 index 0000000000..2d2f4fce7b --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/v-stack/responsive-gap.tsx @@ -0,0 +1,29 @@ +import { VStack } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + + + + + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 3, + desc: "Med responsive gap kan man redusere/øke mellomrom basert på brekkpunktene våre", +}; + +const Placeholder = () => { + return
; +};