Skip to content

Commit

Permalink
[Ny komponent] Stack, Spacer (#2040)
Browse files Browse the repository at this point in the history
  • Loading branch information
KenAJoh authored Aug 4, 2023
1 parent a2dfc86 commit 8a82e1c
Show file tree
Hide file tree
Showing 28 changed files with 962 additions and 17 deletions.
6 changes: 6 additions & 0 deletions .changeset/cuddly-walls-thank.md
Original file line number Diff line number Diff line change
@@ -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.
14 changes: 13 additions & 1 deletion @navikt/core/css/config/_mappings.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const StyleMappings = {
{
component: "UNSAFE_Combobox",
main: "combobox.css",
dependencies: [typoCss],
dependencies: [typoCss, "chips.css"],
},
{
component: "ConfirmationPanel",
Expand Down Expand Up @@ -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] },
Expand Down
1 change: 1 addition & 0 deletions @navikt/core/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
61 changes: 61 additions & 0 deletions @navikt/core/css/stack.css
Original file line number Diff line number Diff line change
@@ -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))))
);
}
}
1 change: 1 addition & 0 deletions @navikt/core/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ export * from "./toggle-group";
export * from "./tooltip";
export * from "./typography";
export * from "./util";
export * from "./layout/stack";
30 changes: 30 additions & 0 deletions @navikt/core/react/src/layout/stack/HStack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { forwardRef } from "react";
import { OverridableComponent } from "../../util/OverridableComponent";
import { StackProps, Stack } from "./Stack";

export type HStackProps = Omit<StackProps, "direction">;

/**
* 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
* <HStack gap="8">
* <MyComponent />
* <MyComponent />
* </HStack>
*
* @example
* // Responsive gap
* <HStack gap={{xs: "2", md: "6"}}>
* <MyComponent />
* <MyComponent />
* </HStack>
*/
export const HStack: OverridableComponent<HStackProps, HTMLDivElement> =
forwardRef((props, ref) => {
return <Stack {...props} ref={ref} direction="row" />;
});
15 changes: 15 additions & 0 deletions @navikt/core/react/src/layout/stack/Spacer.tsx
Original file line number Diff line number Diff line change
@@ -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
* <HStack gap="8">
* <MyComponent />
* <Spacer />
* <MyComponent />
* </HStack>
*/
export const Spacer = () => <div className="navds-stack__spacer" />;
76 changes: 76 additions & 0 deletions @navikt/core/react/src/layout/stack/Stack.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement> {
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<SpacingScale>;
direction: "row" | "column";
}

export const Stack: OverridableComponent<StackProps, HTMLDivElement> =
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 (
<Component
{...rest}
ref={ref}
style={style}
className={cl("navds-stack", className, {
"navds-vstack": direction === "column",
"navds-hstack": direction === "row",
})}
/>
);
}
);
30 changes: 30 additions & 0 deletions @navikt/core/react/src/layout/stack/VStack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { forwardRef } from "react";
import { OverridableComponent } from "../../util/OverridableComponent";
import { StackProps, Stack } from "./Stack";

export type VStackProps = Omit<StackProps, "direction" | "wrap">;

/**
* 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
* <VStack gap="8">
* <MyComponent />
* <MyComponent />
* </VStack>
*
* @example
* // Responsive gap
* <VStack gap={{xs: "2", md: "6"}}>
* <MyComponent />
* <MyComponent />
* </VStack>
*/
export const VStack: OverridableComponent<VStackProps, HTMLDivElement> =
forwardRef((props, ref) => {
return <Stack {...props} ref={ref} direction="column" wrap={false} />;
});
3 changes: 3 additions & 0 deletions @navikt/core/react/src/layout/stack/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { HStack, type HStackProps } from "./HStack";
export { VStack, type VStackProps } from "./VStack";
export { Spacer } from "./Spacer";
Loading

0 comments on commit 8a82e1c

Please sign in to comment.