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

[Primitives] HGrid #1838

Merged
merged 36 commits into from Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e4616f3
:sparkles: Boilerplate component
KenAJoh Mar 1, 2023
9ca9b4a
:art: Columns komponent og styling
KenAJoh Mar 1, 2023
86b06e6
:art: Layout-eksempel
KenAJoh Mar 1, 2023
b571487
:art: Static sidebar example
KenAJoh Mar 2, 2023
93b01ce
:art: Forenklet gap-styling css
KenAJoh Mar 2, 2023
92fc42f
:memo: Bedre docs
KenAJoh Mar 2, 2023
232d84b
:coffin: Fjernet tom fil
KenAJoh Mar 2, 2023
d8721f6
:memo: Changeset
KenAJoh Mar 2, 2023
f154219
Merge branch 'main' into comp-columns
KenAJoh Mar 2, 2023
cf8f922
Merge branch 'main' into comp-columns
KenAJoh Mar 2, 2023
473e67d
:recycle: Kortere inline-css navn
KenAJoh Mar 2, 2023
293d849
Merge branch 'main' into comp-columns
KenAJoh Mar 3, 2023
c918e94
:art: Oppdatert demo for visning av hva som faktisk skjer
KenAJoh Mar 3, 2023
a4a2924
Merge branch 'main' into comp-columns
KenAJoh Aug 6, 2023
6a95239
:art: Rename grid
KenAJoh Aug 6, 2023
dc57b0b
:art: Fikset gridprops
KenAJoh Aug 7, 2023
30f379d
:bug: Refaktorert grid-formatering
KenAJoh Aug 7, 2023
d66139a
:art: Synket CSS med oppdatert hgrid
KenAJoh Aug 7, 2023
fec79bf
:arrow_up: Yarn lock
KenAJoh Aug 7, 2023
efc2687
Merge branch 'main' into comp-columns
KenAJoh Aug 7, 2023
f90ef5c
:art: Oppdatert storybook
KenAJoh Aug 7, 2023
87aec62
:memo: Nettsider-eksempler for grid
KenAJoh Aug 8, 2023
1bf90cc
:art: Oppdatert storybook story
KenAJoh Aug 9, 2023
43a08df
Update @navikt/core/react/src/layout/grid/HGrid.tsx
KenAJoh Aug 9, 2023
180577f
:art: Spread styles
KenAJoh Aug 9, 2023
4ef2e88
Merge branch 'main' into comp-columns
KenAJoh Aug 9, 2023
e60c781
:art: Oppdatert gap-props
KenAJoh Aug 9, 2023
a0ca98f
:art: Oppdatert jsdoc
KenAJoh Aug 9, 2023
6334880
:bug: Fikset eksempler index
KenAJoh Aug 9, 2023
a266ec4
:bug: Flyttet placeholder/background elementer slik at de kan brukes …
KenAJoh Aug 9, 2023
874c871
Update @navikt/core/react/src/layout/grid/HGrid.tsx
KenAJoh Aug 9, 2023
8784216
:label: Bedre naming av object-mapping
KenAJoh Aug 9, 2023
b3b8365
Merge branch 'comp-columns' of https://github.com/navikt/aksel into c…
KenAJoh Aug 9, 2023
42c8671
:art: Oppdatert tokens til å ha __ prefix
KenAJoh Aug 9, 2023
8d09f42
:bug: Fikset stack-css
KenAJoh Aug 9, 2023
894804a
:fire: Fjernet unødvendige comments
KenAJoh Aug 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/slow-frogs-eat.md
@@ -0,0 +1,6 @@
---
"@navikt/ds-css": minor
"@navikt/ds-react": minor
---

[Layout] Columns komponent :tada:
16 changes: 8 additions & 8 deletions @navikt/aksel-icons/figma-plugin/src/ui/utils.ts
@@ -1,9 +1,9 @@
import meta from "@navikt/aksel-icons/metadata";

const subCategorizeIcons = (
icons: typeof meta[1][]
): { sub_category: string; icons: typeof meta[1][] }[] => {
const categories: { sub_category: string; icons: typeof meta[1][] }[] = [];
icons: (typeof meta)[1][]
): { sub_category: string; icons: (typeof meta)[1][] }[] => {
const categories: { sub_category: string; icons: (typeof meta)[1][] }[] = [];

for (const icon of icons) {
const i = categories.findIndex(
Expand All @@ -19,14 +19,14 @@ const subCategorizeIcons = (
};

export const categorizeIcons = (
icons: typeof meta[1][]
icons: (typeof meta)[1][]
): {
category: string;
sub_categories: { sub_category: string; icons: typeof meta[1][] }[];
sub_categories: { sub_category: string; icons: (typeof meta)[1][] }[];
}[] => {
const categories: {
category: string;
icons: typeof meta[1][];
icons: (typeof meta)[1][];
}[] = [];

for (const icon of icons) {
Expand All @@ -42,14 +42,14 @@ export const categorizeIcons = (
.map((x) => ({ ...x, sub_categories: subCategorizeIcons(x.icons) }));
};

const noFill = (icon: typeof meta[1], icons: typeof meta[1][]) => {
const noFill = (icon: (typeof meta)[1], icons: (typeof meta)[1][]) => {
const foundFill = icons.find(
(x) => x.name.endsWith("Fill") && x.name.replace("Fill", "") === icon.name
);
return !foundFill;
};

export const getFillIcon = (icons: typeof meta[1][]) => {
export const getFillIcon = (icons: (typeof meta)[1][]) => {
return icons.filter(
(x, _, z) => x.variant.toLowerCase() === "fill" || noFill(x, z)
);
Expand Down
59 changes: 59 additions & 0 deletions @navikt/core/css/hgrid.css
@@ -0,0 +1,59 @@
/* stylelint-disable aksel/design-token-exists */
.navds-hgrid {
--ac-hgrid-grid-columns-xs: initial;
--ac-hgrid-grid-columns-sm: initial;
--ac-hgrid-grid-columns-md: initial;
--ac-hgrid-grid-columns-lg: initial;
--ac-hgrid-grid-columns-xl: initial;
--__ac-hgrid-grid-columns: var(--ac-hgrid-grid-columns-xs);
--ac-hgrid-gap-xs: initial;
--ac-hgrid-gap-sm: initial;
--ac-hgrid-gap-md: initial;
--ac-hgrid-gap-lg: initial;
--ac-hgrid-gap-xl: initial;
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
--__ac-hgrid-gap: var(--ac-hgrid-gap-xs);

display: grid;
grid-template-columns: var(--__ac-hgrid-grid-columns);
gap: var(--__ac-hgrid-gap);
}

@media (min-width: 480px) {
.navds-hgrid {
--__ac-hgrid-grid-columns: var(--ac-hgrid-grid-columns-sm, var(--ac-hgrid-grid-columns-xs));
--__ac-hgrid-gap: var(--ac-hgrid-gap-sm, var(--ac-hgrid-gap-xs));
}
}

@media (min-width: 768px) {
.navds-hgrid {
--__ac-hgrid-grid-columns: var(--ac-hgrid-grid-columns-md, var(--ac-hgrid-grid-columns-sm, var(--ac-hgrid-grid-columns-xs)));
--__ac-hgrid-gap: var(--ac-hgrid-gap-md, var(--ac-hgrid-gap-sm, var(--ac-hgrid-gap-xs)));
}
}

@media (min-width: 1024px) {
.navds-hgrid {
--__ac-hgrid-grid-columns: var(
--ac-hgrid-grid-columns-lg,
var(--ac-hgrid-grid-columns-md, var(--ac-hgrid-grid-columns-sm, var(--ac-hgrid-grid-columns-xs)))
);
--__ac-hgrid-gap: var(--ac-hgrid-gap-lg, var(--ac-hgrid-gap-md, var(--ac-hgrid-gap-sm, var(--ac-hgrid-gap-xs))));
}
}

@media (min-width: 1280px) {
.navds-hgrid {
--__ac-hgrid-grid-columns: var(
--ac-hgrid-grid-columns-xl,
var(
--ac-hgrid-grid-columns-lg,
var(--ac-hgrid-grid-columns-md, var(--ac-hgrid-grid-columns-sm, var(--ac-hgrid-grid-columns-xs)))
)
);
--__ac-hgrid-gap: var(
--ac-hgrid-gap-xl,
var(--ac-hgrid-gap-lg, var(--ac-hgrid-gap-md, var(--ac-hgrid-gap-sm, var(--ac-hgrid-gap-xs))))
);
}
}
1 change: 1 addition & 0 deletions @navikt/core/css/index.css
Expand Up @@ -14,6 +14,7 @@
@import "guide-panel.css";
@import "form/index.css";
@import "help-text.css";
@import "hgrid.css";
@import "internalheader.css";
@import "link.css";
@import "loader.css";
Expand Down
1 change: 1 addition & 0 deletions @navikt/core/react/src/index.ts
Expand Up @@ -33,3 +33,4 @@ export * from "./tooltip";
export * from "./typography";
export * from "./util";
export * from "./layout/stack";
export * from "./layout/grid";
76 changes: 76 additions & 0 deletions @navikt/core/react/src/layout/grid/HGrid.tsx
@@ -0,0 +1,76 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "clsx";
import {
getResponsiveProps,
getResponsiveValue,
ResponsiveProp,
SpacingScale,
} from "../utilities/css";

export interface HGridProps extends HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
/**
* Number of columns to display. Can be a number, a string with a unit or tokens for spesific breakpoints.
* Sets `grid-template-columns, so 'fr, minmax' etc works`.
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
* @example
* columns={{ sm: 1, md: 1, lg: "1fr auto", xl: "1fr auto"}}
* @example
* columns={3}
* @example
* columns="repeat(3, minmax(0, 1fr))"
*/
columns?: ResponsiveProp<number | string>;
/** Spacing between columns. Can be a number, a string with a unit or tokens for spesific breakpoints.
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
* @example
* gap="6"
* gap={{ sm: "2", md: "2", lg: "6", xl: "6"}}
*/
gap?: ResponsiveProp<SpacingScale>;
}

export const HGrid = forwardRef<HTMLDivElement, HGridProps>(
({ className, columns, gap, ...rest }, ref) => {
const styles = {
...getResponsiveProps(`hgrid`, "gap", "spacing", gap),
...getResponsiveValue(`hgrid`, "grid-columns", formatGrid(columns)),
} as React.CSSProperties;
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved

return (
<div
{...rest}
ref={ref}
className={cl("navds-hgrid", className)}
style={styles}
/>
);
}
);

function formatGrid(
props?: ResponsiveProp<number | string>
): ResponsiveProp<number | string> {
if (!props) {
return {};
}

if (typeof props === "string" || typeof props === "number") {
return getColumnValue(props);
}

return Object.fromEntries(
Object.entries(props).map(([alias, breakPoint]) => [
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
alias,
getColumnValue(breakPoint),
])
);
}

const getColumnValue = (prop: number | string) => {
if (typeof prop === "number") {
return `repeat(${prop}, minmax(0, 1fr))`;
}

return prop;
};

export default HGrid;
80 changes: 80 additions & 0 deletions @navikt/core/react/src/layout/grid/h-grid.stories.tsx
@@ -0,0 +1,80 @@
import React from "react";
import { HGrid } from ".";

export default {
title: "ds-react/HGrid",
component: HGrid,
parameters: {
layout: "fullscreen",
},
};

export const Default = {
render: (props) => (
<HGrid {...props}>
<Placeholder text="1" />
<Placeholder text="2" />
<Placeholder text="3" />
<Placeholder text="4" />
</HGrid>
),
columns: 0,
gap: "0",
KenAJoh marked this conversation as resolved.
Show resolved Hide resolved
};

export const Gap = {
render: () => (
<HGrid gap="6">
<Placeholder text="1" />
<Placeholder text="2" />
<Placeholder text="3" />
<Placeholder text="4" />
</HGrid>
),
};

export const DynamicGap = {
render: () => (
<HGrid gap={{ xs: "2", md: "8" }}>
<Placeholder text="1" />
<Placeholder text="2" />
<Placeholder text="3" />
<Placeholder text="4" />
</HGrid>
),
};

export const Columns = {
render: () => (
<HGrid gap="4" columns={2}>
<Placeholder text="1" />
<Placeholder text="2" />
<Placeholder text="3" />
<Placeholder text="4" />
</HGrid>
),
};

export const DynamicColumns = {
render: () => (
<HGrid gap="4" columns={{ sm: "1fr 5fr", md: "2fr 2fr" }}>
<Placeholder text="1" />
<Placeholder text="2" />
</HGrid>
),
};

function Placeholder({ text }) {
return (
<div
style={{
background: "var(--a-deepblue-900)",
height: "5rem",
width: "auto",
color: "white",
}}
>
{text}
</div>
);
}
1 change: 1 addition & 0 deletions @navikt/core/react/src/layout/grid/index.ts
@@ -0,0 +1 @@
export { default as HGrid, type HGridProps } from "./HGrid";
44 changes: 31 additions & 13 deletions @navikt/core/react/src/layout/utilities/css.ts
Expand Up @@ -21,23 +21,20 @@ export type SpacingScale =
| "24"
| "32";

export type ResponsiveProp<T> =
| T
| {
// eslint-disable-next-line no-unused-vars
[Breakpoint in BreakpointsAlias]?: T;
};
type ResponsivePropConfig<T = string> = {
// eslint-disable-next-line no-unused-vars
[Breakpoint in BreakpointsAlias]?: T;
};

export type ResponsiveProp<T> = T | ResponsivePropConfig<T>;

export type ResponsiveValue<T = string> = undefined | ResponsiveProp<T>;

export function getResponsiveProps(
export function getResponsiveProps<T = string>(
componentName: string,
componentProp: string,
tokenSubgroup: string,
responsiveProp?:
| string
| {
// eslint-disable-next-line no-unused-vars
[Breakpoint in BreakpointsAlias]?: string;
}
responsiveProp?: ResponsiveProp<T>
) {
if (!responsiveProp) return {};

Expand All @@ -54,3 +51,24 @@ export function getResponsiveProps(
])
);
}

export function getResponsiveValue<T = string>(
componentName: string,
componentProp: string,
responsiveProp?: ResponsiveValue<T>
) {
if (!responsiveProp) return {};

if (typeof responsiveProp === "string") {
return {
[`--ac-${componentName}-${componentProp}-xs`]: responsiveProp,
};
}

return Object.fromEntries(
Object.entries(responsiveProp).map(([breakpointAlias, responsiveValue]) => [
`--ac-${componentName}-${componentProp}-${breakpointAlias}`,
responsiveValue,
])
);
}
2 changes: 1 addition & 1 deletion aksel.nav.no/website/components/website-modules/TOC.tsx
Expand Up @@ -137,7 +137,7 @@ export function TableOfContents({
hidden: !renderToc,
"col-start-3 max-w-prose md:sticky md:top-20 lg:flex":
aksel && renderToc,
"mt-12 mr-auto h-full xl:flex": !aksel && renderToc,
"mr-auto mt-12 h-full xl:flex": !aksel && renderToc,
}
)}
>
Expand Down