diff --git a/.prettierignore b/.prettierignore index bee62e0174f..ee3e5d7e54f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,4 +6,5 @@ jest/ tsconfig.json tsconfig-for-declarations.json pnpm-lock.yaml -packages/jokul/dev-server.js \ No newline at end of file +packages/jokul/dev-server.js +packages/jokul/src/components/flex/styles/flex.scss \ No newline at end of file diff --git a/packages/jokul/src/components/flex/Flex.tsx b/packages/jokul/src/components/flex/Flex.tsx index fb05216eee1..602270aadda 100644 --- a/packages/jokul/src/components/flex/Flex.tsx +++ b/packages/jokul/src/components/flex/Flex.tsx @@ -1,70 +1,165 @@ -import React, { type CSSProperties } from "react"; -import tokens from "../../core/tokens.js"; -import { AsChildProps } from "../../utilities/polymorphism/as-child.js"; +import clsx from "clsx"; +import React, { forwardRef } from "react"; import { - PolymorphicPropsWithRef, + Expand, + PolymorphicComponentPropWithRef, PolymorphicRef, } from "../../utilities/polymorphism/polymorphism.js"; -import { SlotComponent } from "../../utilities/polymorphism/SlotComponent.js"; -export type FlexDirection = "row" | "row-reverse" | "column" | "column-reverse"; -export type GapValue = Exclude; +type Size = 1 | 2 | 3 | 4 | 6 | 4.8 | 8.4 | 2.1 | 10.2 | 3.9 | 9.3 | 5.7 | 7.5; +type Center = "md" | "lg" | "xl" | "xxl" | boolean; +type Layout = Expand<"auto" | Size | `${Size}`[][number] | "2.10">; +type Gap = + | "none" + | "xs" + | "sm" + | "md" + | "lg" + | "xl" + | "xxl" + | "xxl xl" + | "xxl lg" + | "xxl md" + | "xxl sm" + | "xxl xs" + | "xl none" + | "xl xxl" + | "xl lg" + | "xl md" + | "xl sm" + | "xl xs" + | "xl none" + | "lg xxl" + | "lg xl" + | "lg md" + | "lg sm" + | "lg xs" + | "lg none" + | "md xxl" + | "md xl" + | "md lg" + | "md sm" + | "md xs" + | "md none" + | "sm xxl" + | "sm xl" + | "sm lg" + | "sm md" + | "sm xs" + | "sm none" + | "xs xxl" + | "xs xl" + | "xs lg" + | "xs md" + | "xs sm" + | "xs none" + | "none xxl" + | "none xl" + | "none lg" + | "none md" + | "none sm" + | "none xs"; -export type FlexProps = - PolymorphicPropsWithRef< - ElementType, - { - direction?: FlexDirection; - wrap?: boolean; - gap?: GapValue; - colGap?: GapValue; - rowGap?: GapValue; - } & Pick< - CSSProperties, - "alignContent" | "alignItems" | "justifyContent" | "justifyItems" - > - >; +type FlexBaseProps = { + align?: "normal" | "start" | "center" | "end" | "baseline" | "stretch"; + alignContent?: + | "normal" + | "start" + | "center" + | "end" + | "stretch" + | "baseline" + | "space-between" + | "space-around" + | "space-evenly"; + center?: Center; + direction?: "row" | "column" | "row-reverse" | "column-reverse"; + fill?: boolean; + gap?: Gap | { xs?: Gap; sm?: Gap; md?: Gap; lg?: Gap; xl?: Gap; xxl?: Gap }; + inline?: boolean; + text?: "left" | "right" | "center"; + justify?: + | "normal" + | "start" + | "center" + | "end" + | "space-between" + | "space-around" + | "space-evenly"; + layout?: + | Layout + | { + xs?: Layout; + sm?: Layout; + md?: Layout; + lg?: Layout; + xl?: Layout; + xxl?: Layout; + }; + wrap?: "wrap" | "nowrap" | "reverse"; +}; -export type FlexComponent = ( - props: FlexProps & AsChildProps, -) => React.ReactElement | null; +export type FlexProps = + PolymorphicComponentPropWithRef; -export const Flex = React.forwardRef(function Flex< - ElementType extends React.ElementType = "div", ->(props: FlexProps, ref?: PolymorphicRef) { - const { - asChild, - as = "div", - alignContent, - alignItems, - children, - colGap, - direction, - gap, - justifyContent, - justifyItems, - rowGap, - wrap = false, - ...rest - } = props; - const Component = asChild ? SlotComponent : as; +type FlexComponent = ( + props: FlexProps, +) => JSX.Element; - const flexStyle: CSSProperties = { - display: "flex", - flexDirection: direction, +export const Flex: FlexComponent = forwardRef(function Flex< + As extends React.ElementType = "div", +>( + { + align, alignContent, - alignItems, - justifyContent, - justifyItems, - ...(wrap ? { flexWrap: "wrap" } : {}), - ...(gap ? { gap: tokens.spacing[gap] } : {}), - ...(colGap ? { columnGap: tokens.spacing[colGap] } : {}), - ...(rowGap ? { rowGap: tokens.spacing[rowGap] } : {}), - }; + as, + center = false, + className, + direction = "row", + fill, + gap = "md", + inline, + justify, + layout = {}, + text, + wrap = "wrap", + ...rest + }: FlexProps, + ref?: PolymorphicRef, +) { + const Tag = as || "div"; + const gaps = toObj(gap).flatMap(([breakpoint, gap]) => { + const [row, col = row] = gap.trim().split(" "); + return [`${breakpoint}-row-gap-${row}`, `${breakpoint}-col-gap-${col}`]; + }); + const layouts = toObj(layout).map( + ([breakpoint, layout]) => + `${breakpoint}-${Number(`${layout}`.replace("auto", "0"))}`, // Convert to number to convert 2.10 to 2.1 and false to 0 + ); return ( - - {children} - + ); -}) as FlexComponent; +}) as FlexComponent; // Needed to tell Typescript this does not return ReactNode but acutally JSX.Element + +const toObj = (value: string | number | object) => + Object.entries(typeof value === "object" ? value : { xs: value }); diff --git a/packages/jokul/src/components/flex/documentation/FlexExample.tsx b/packages/jokul/src/components/flex/documentation/FlexExample.tsx index b9f0e1859a6..ed227e57ccd 100644 --- a/packages/jokul/src/components/flex/documentation/FlexExample.tsx +++ b/packages/jokul/src/components/flex/documentation/FlexExample.tsx @@ -1,90 +1,154 @@ import { ExampleComponentProps, ExampleKnobsProps } from "doc-utils/index.js"; import React, { CSSProperties, FC } from "react"; -import tokens from "../../../core/tokens.js"; -import { Card } from "../../card/Card.js"; -import { Flex, FlexDirection, GapValue } from "../Flex.js"; +import { ExampleComponentProps, ExampleKnobsProps } from "../../../../../../utils/dev-example"; +import { Flex } from "../Flex"; + +import "../styles/_index.scss"; export const flexExampleKnobs: ExampleKnobsProps = { - boolProps: ["wrap"], + boolProps: ["fill", "inline"], choiceProps: [ { - name: "direction", - values: ["row", "row-reverse", "column", "column-reverse"], + name: "layout", + values: [ + "auto", + "1", + "2", + "3", + "4", + "6", + "4.8", + "8.4", + "2.10", + "10.2", + "3.9", + "9.3", + "5.7", + "7.5", + "{ xs: 1, md: 2, lg: 4 }", + "{ xs: 1, md: 'auto' }", + ], defaultValue: 0, }, { name: "gap", - values: Object.keys(tokens.spacing).sort( - (a, b) => parseInt(a) - parseInt(b), - ), + values: [ + "none", + "xs", + "sm", + "md", + "lg", + "xl", + "xxl", + "xxl xl", + "xxl lg", + "xxl md", + "xxl sm", + "xxl xs", + "xl none", + "xl xxl", + "xl lg", + "xl md", + "xl sm", + "xl xs", + "xl none", + "lg xxl", + "lg xl", + "lg md", + "lg sm", + "lg xs", + "lg none", + "md xxl", + "md xl", + "md lg", + "md sm", + "md xs", + "md none", + "sm xxl", + "sm xl", + "sm lg", + "sm md", + "sm xs", + "sm none", + "xs xxl", + "xs xl", + "xs lg", + "xs md", + "xs sm", + "xs none", + "none xxl", + "none xl", + "none lg", + "none md", + "none sm", + "none xs", + ], + defaultValue: 0, + }, + { + name: "direction", + values: ["row", "column", "row-reverse", "column-reverse"], + defaultValue: 0, + }, + { + name: "center", + values: ["false", "true", "xxl", "xl", "lg", "md"], + defaultValue: 0, + }, + { + name: "align", + values: ["normal", "start", "center", "end", "baseline", "stretch"], defaultValue: 0, }, { - name: "rowGap", - values: Object.keys(tokens.spacing).sort( - (a, b) => parseInt(a) - parseInt(b), - ), + name: "alignContent", + values: [ + "normal", + "start", + "center", + "end", + "baseline", + "stretch", + "space-around", + "space-between", + "space-evenly", + ], defaultValue: 0, }, { - name: "colGap", - values: Object.keys(tokens.spacing).sort( - (a, b) => parseInt(a) - parseInt(b), - ), + name: "justify", + values: ["normal", "start", "center", "end", "space-around", "space-between", "space-evenly"], + defaultValue: 0, + }, + { + name: "wrap", + values: ["wrap", "nowrap", "reverse"], defaultValue: 0, }, ], }; const boxStyle: CSSProperties = { - width: "250px", - height: "150px", backgroundColor: "var(--jkl-color-background-container-low)", border: "1px solid var(--jkl-color-border-subdued)", borderRadius: "4px", - display: "grid", - placeContent: "center", - flexGrow: 1, }; -export const FlexExample: FC = ({ - boolValues, - choiceValues, -}) => { - const gap = - choiceValues?.["gap"] === "0" - ? undefined - : (parseInt(choiceValues?.["gap"] || "0") as GapValue); - const colGap = - choiceValues?.["colGap"] === "0" - ? undefined - : (parseInt(choiceValues?.["colGap"] || "0") as GapValue); - const rowGap = - choiceValues?.["rowGap"] === "0" - ? undefined - : (parseInt(choiceValues?.["rowGap"] || "0") as GapValue); - +export const FlexExample: FC = ({ boolValues, choiceValues }) => { return ( - - -
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
+ +
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
); }; diff --git a/packages/jokul/src/components/flex/styles/_index.scss b/packages/jokul/src/components/flex/styles/_index.scss new file mode 100644 index 00000000000..021cfee1035 --- /dev/null +++ b/packages/jokul/src/components/flex/styles/_index.scss @@ -0,0 +1 @@ +@forward "flex"; diff --git a/packages/jokul/src/components/flex/styles/flex.scss b/packages/jokul/src/components/flex/styles/flex.scss new file mode 100644 index 00000000000..2db76a86710 --- /dev/null +++ b/packages/jokul/src/components/flex/styles/flex.scss @@ -0,0 +1,310 @@ +@charset "UTF-8"; +@use "../../../core/jkl"; + +:root { + --container-md: 43.75rem; + --container-lg: 60rem; + --container-xl: 75rem; + --container-xxl: 90rem; + --container-full: 100%; +} + + +:where(.flex) { + box-sizing: border-box; + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +:where(.fill > *) { + flex-grow: 1; +} + +:where(.flex > *) { + --jkl-flex-gap: 0px; + --jkl-flex-layout: auto; + box-sizing: border-box; + flex-basis: calc( + (100% - (12 / var(--jkl-flex-layout) - 1) * var(--jkl-flex-gap)) / 12 * + var(--jkl-flex-layout) + ); + + min-width: calc(var(--jkl-flex-layout) * 0px); + min-height: calc(var(--jkl-flex-layout) * 0px); +} + +.inline { + display: inline-flex; +} + +.column { + flex-direction: column; +} + +.column-reverse { + flex-direction: column-reverse; +} + +.row-reverse { + flex-direction: row-reverse; +} + +.wrap-reverse { + flex-wrap: wrap-reverse; +} + +.wrap-nowrap { + flex-wrap: nowrap; +} + +:where(.wrap-nowrap > *) { + flex-shrink: calc(var(--jkl-flex-layout) * 0); +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.align-start { + align-items: flex-start; +} + +.align-center { + align-items: center; +} + +.align-end { + align-items: flex-end; +} + +.align-baseline { + align-items: baseline; +} + +.align-stretch { + align-items: stretch; +} + +.align-content-start { + align-content: flex-start; +} + +.align-content-center { + align-content: center; +} + +.align-content-end { + align-content: flex-end; +} + +.align-content-stretch { + align-content: stretch; +} + +.align-content-baseline { + align-content: baseline; +} + +.align-content-space-around { + align-content: space-around; +} + +.align-content-space-between { + align-content: space-between; +} + +.align-content-space-evenly { + align-content: space-evenly; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-center { + justify-content: center; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-space-around { + justify-content: space-around; +} + +.justify-space-between { + justify-content: space-between; +} + +.justify-space-evenly { + justify-content: space-evenly; +} + +.center-md { + max-width: var(--container-md); +} + +.center-md, +.center-lg, +.center-xl, +.center-xxl { + box-sizing: border-box; + margin-inline: auto; + width: calc(100% - var(--jkl-unit-50)); +} + +.center-lg, +.center-xl, +.center-xxl { + @media (width >= 64em) { + max-width: var(--container-lg); + } +} + +.center-xl, +.center-xxl { + @media (width >= 75em) { + max-width: var(--container-xl); + } +} + +.center-xxl { + @media (width >= 101.25em) { + max-width: var(--container-xxl); + } +} + +.xs-10\.2 > :where(:nth-child(2n - 1)), .xs-2\.1 > :where(:nth-child(2n)) { --jkl-flex-layout: 10; } +.xs-2\.1 > :where(:nth-child(2n - 1)), .xs-10\.2 > :where(:nth-child(2n)) { --jkl-flex-layout: 2; } +.xs-3\.9 > :where(:nth-child(2n - 1)), .xs-9\.3 > :where(:nth-child(2n)) { --jkl-flex-layout: 3; } +.xs-4\.8 > :where(:nth-child(2n - 1)), .xs-8\.4 > :where(:nth-child(2n)) { --jkl-flex-layout: 4; } +.xs-5\.7 > :where(:nth-child(2n - 1)), .xs-7\.5 > :where(:nth-child(2n)) { --jkl-flex-layout: 5; } +.xs-7\.5 > :where(:nth-child(2n - 1)), .xs-5\.7 > :where(:nth-child(2n)) { --jkl-flex-layout: 7; } +.xs-8\.4 > :where(:nth-child(2n - 1)), .xs-4\.8 > :where(:nth-child(2n)) { --jkl-flex-layout: 8; } +.xs-9\.3 > :where(:nth-child(2n - 1)), .xs-3\.9 > :where(:nth-child(2n)) { --jkl-flex-layout: 9; } +.xs-0 > * { --jkl-flex-layout: auto; } .xs-1 > * { --jkl-flex-layout: 12; } .xs-2 > * { --jkl-flex-layout: 6; } +.xs-3 > * { --jkl-flex-layout: 4;} .xs-4 > * { --jkl-flex-layout: 4; } .xs-6 > * { --jkl-flex-layout: 2; } + +.xs-row-gap-none { row-gap: 0; } .xs-col-gap-none { column-gap: 0; > * { --jkl-flex-gap: 0px; } } +.xs-row-gap-xs { row-gap: var(--jkl-unit-10); } .xs-col-gap-xs { column-gap: var(--jkl-unit-10); & > * { --jkl-flex-gap: var(--jkl-unit-10); } } +.xs-row-gap-sm { row-gap: var(--jkl-unit-20); } .xs-col-gap-sm { column-gap: var(--jkl-unit-20); & > * { --jkl-flex-gap: var(--jkl-unit-20); } } +.xs-row-gap-md { row-gap: var(--jkl-unit-30); } .xs-col-gap-md { column-gap: var(--jkl-unit-30); & > * { --jkl-flex-gap: var(--jkl-unit-30); } } +.xs-row-gap-lg { row-gap: var(--jkl-unit-40); } .xs-col-gap-lg { column-gap: var(--jkl-unit-40); & > * { --jkl-flex-gap: var(--jkl-unit-40); } } +.xs-row-gap-xl { row-gap: var(--jkl-unit-50); } .xs-col-gap-xl { column-gap: var(--jkl-unit-50); & > * { --jkl-flex-gap: var(--jkl-unit-50); } } +.xs-row-gap-xxl { row-gap: var(--jkl-unit-100); } .xs-col-gap-xxl { column-gap: var(--jkl-unit-100); & > * { --jkl-flex-gap: var(--jkl-unit-100); } } + +@media (width >= 37.5em) { /* var(--jkl-breakpoint-sm) */ + .sm-2\.1 > :where(:nth-child(2n - 1)), .sm-10\.2 > :where(:nth-child(2n)) { --jkl-flex-layout: 2; } + .sm-10\.2 > :where(:nth-child(2n - 1)), .sm-2\.1 > :where(:nth-child(2n)) { --jkl-flex-layout: 10; } + .sm-3\.9 > :where(:nth-child(2n - 1)), .sm-9\.3 > :where(:nth-child(2n)) { --jkl-flex-layout: 3; } + .sm-9\.3 > :where(:nth-child(2n - 1)), .sm-3\.9 > :where(:nth-child(2n)) { --jkl-flex-layout: 9; } + .sm-4\.8 > :where(:nth-child(2n - 1)), .sm-8\.4 > :where(:nth-child(2n)) { --jkl-flex-layout: 4; } + .sm-8\.4 > :where(:nth-child(2n - 1)), .sm-4\.8 > :where(:nth-child(2n)) { --jkl-flex-layout: 8; } + .sm-5\.7 > :where(:nth-child(2n - 1)), .sm-7\.5 > :where(:nth-child(2n)) { --jkl-flex-layout: 5; } + .sm-7\.5 > :where(:nth-child(2n - 1)), .sm-5\.7 > :where(:nth-child(2n)) { --jkl-flex-layout: 7; } + .sm-0 > * { --jkl-flex-layout: auto; } .sm-1 > * { --jkl-flex-layout: 12; } .sm-2 > * { --jkl-flex-layout: 6; } + .sm-3 > * { --jkl-flex-layout: 4; } .sm-4 > * { --jkl-flex-layout: 3; } .sm-6 > * { --jkl-flex-layout: 2; } + + .sm-row-gap-none { row-gap: 0; }.sm-col-gap-none { column-gap: 0; & > * { --jkl-flex-gap: 0px; } } + .sm-row-gap-xs { row-gap: var(--jkl-unit-10); }.sm-col-gap-xs { column-gap: var(--jkl-unit-10); & > * { --jkl-flex-gap: var(--jkl-unit-10); } } + .sm-row-gap-sm { row-gap: var(--jkl-unit-20); }.sm-col-gap-sm { column-gap: var(--jkl-unit-20); & > * { --jkl-flex-gap: var(--jkl-unit-20); } } + .sm-row-gap-md { row-gap: var(--jkl-unit-30); }.sm-col-gap-md { column-gap: var(--jkl-unit-30); & > * { --jkl-flex-gap: var(--jkl-unit-30); } } + .sm-row-gap-lg { row-gap: var(--jkl-unit-40); }.sm-col-gap-lg { column-gap: var(--jkl-unit-40); & > * { --jkl-flex-gap: var(--jkl-unit-40); } } + .sm-row-gap-xl { row-gap: var(--jkl-unit-50); }.sm-col-gap-xl { column-gap: var(--jkl-unit-50); & > * { --jkl-flex-gap: var(--jkl-unit-50); } } + .sm-row-gap-xxl { row-gap: var(--jkl-unit-100); }.sm-col-gap-xxl { column-gap: var(--jkl-unit-100); & > * { --jkl-flex-gap: var(--jkl-unit-100); } } +} + +@media (width >= 50em) { /* var(--jkl-breakpoint-md) */ + .md-2\.1 > :where(:nth-child(2n - 1)), .md-10\.2 > :where(:nth-child(2n)) { --jkl-flex-layout: 2; } + .md-10\.2 > :where(:nth-child(2n - 1)), .md-2\.1 > :where(:nth-child(2n)) { --jkl-flex-layout: 10; } + .md-3\.9 > :where(:nth-child(2n - 1)), .md-9\.3 > :where(:nth-child(2n)) { --jkl-flex-layout: 3; } + .md-9\.3 > :where(:nth-child(2n - 1)), .md-3\.9 > :where(:nth-child(2n)) { --jkl-flex-layout: 9; } + .md-4\.8 > :where(:nth-child(2n - 1)), .md-8\.4 > :where(:nth-child(2n)) { --jkl-flex-layout: 4; } + .md-8\.4 > :where(:nth-child(2n - 1)), .md-4\.8 > :where(:nth-child(2n)) { --jkl-flex-layout: 8; } + .md-5\.7 > :where(:nth-child(2n - 1)), .md-7\.5 > :where(:nth-child(2n)) { --jkl-flex-layout: 5; } + .md-7\.5 > :where(:nth-child(2n - 1)), .md-5\.7 > :where(:nth-child(2n)) { --jkl-flex-layout: 7; } + .md-0 > * { --jkl-flex-layout: auto; } .md-1 > * { --jkl-flex-layout: 12; } .md-2 > * { --jkl-flex-layout: 6; } + .md-3 > * { --jkl-flex-layout: 4; } .md-4 > * { --jkl-flex-layout: 3; } .md-6 > * { --jkl-flex-layout: 2; } + + .md-row-gap-none { row-gap: 0; }.md-col-gap-none { column-gap: 0; & > * { --jkl-flex-gap: 0px; } } + .md-row-gap-xs { row-gap: var(--jkl-unit-10); }.md-col-gap-xs { column-gap: var(--jkl-unit-10); & > * { --jkl-flex-gap: var(--jkl-unit-10); } } + .md-row-gap-sm { row-gap: var(--jkl-unit-20); }.md-col-gap-sm { column-gap: var(--jkl-unit-20); & > * { --jkl-flex-gap: var(--jkl-unit-20); } } + .md-row-gap-md { row-gap: var(--jkl-unit-30); }.md-col-gap-md { column-gap: var(--jkl-unit-30); & > * { --jkl-flex-gap: var(--jkl-unit-30); } } + .md-row-gap-lg { row-gap: var(--jkl-unit-40); }.md-col-gap-lg { column-gap: var(--jkl-unit-40); & > * { --jkl-flex-gap: var(--jkl-unit-40); } } + .md-row-gap-xl { row-gap: var(--jkl-unit-50); }.md-col-gap-xl { column-gap: var(--jkl-unit-50); & > * { --jkl-flex-gap: var(--jkl-unit-50); } } + .md-row-gap-xxl { row-gap: var(--jkl-unit-100); }.md-col-gap-xxl { column-gap: var(--jkl-unit-100); & > * { --jkl-flex-gap: var(--jkl-unit-100); } } +} + +@media (width >= 64em) { /* var(--jkl-breakpoint-lg) */ + .lg-2\.1 > :where(:nth-child(2n - 1)), .lg-10\.2 > :where(:nth-child(2n)) { --jkl-flex-layout: 2; } + .lg-10\.2 > :where(:nth-child(2n - 1)), .lg-2\.1 > :where(:nth-child(2n)) { --jkl-flex-layout: 10; } + .lg-3\.9 > :where(:nth-child(2n - 1)), .lg-9\.3 > :where(:nth-child(2n)) { --jkl-flex-layout: 3; } + .lg-9\.3 > :where(:nth-child(2n - 1)), .lg-3\.9 > :where(:nth-child(2n)) { --jkl-flex-layout: 9; } + .lg-4\.8 > :where(:nth-child(2n - 1)), .lg-8\.4 > :where(:nth-child(2n)) { --jkl-flex-layout: 4; } + .lg-8\.4 > :where(:nth-child(2n - 1)), .lg-4\.8 > :where(:nth-child(2n)) { --jkl-flex-layout: 8; } + .lg-5\.7 > :where(:nth-child(2n - 1)), .lg-7\.5 > :where(:nth-child(2n)) { --jkl-flex-layout: 5; } + .lg-7\.5 > :where(:nth-child(2n - 1)), .lg-5\.7 > :where(:nth-child(2n)) { --jkl-flex-layout: 7; } + .lg-0 > * { --jkl-flex-layout: auto; } .lg-1 > * { --jkl-flex-layout: 12; } .lg-2 > * { --jkl-flex-layout: 6; } + .lg-3 > * { --jkl-flex-layout: 4; } .lg-4 > * { --jkl-flex-layout: 3; } .lg-6 > * { --jkl-flex-layout: 2; } + + .lg-row-gap-none { row-gap: 0; } .lg-col-gap-none { column-gap: 0; & > * { --jkl-flex-gap: 0px; } } + .lg-row-gap-xs { row-gap: var(--jkl-unit-10); }.lg-col-gap-xs { column-gap: var(--jkl-unit-10); & > * { --jkl-flex-gap: var(--jkl-unit-10); } } + .lg-row-gap-sm { row-gap: var(--jkl-unit-20); }.lg-col-gap-sm { column-gap: var(--jkl-unit-20); & > * { --jkl-flex-gap: var(--jkl-unit-20); } } + .lg-row-gap-md { row-gap: var(--jkl-unit-30); }.lg-col-gap-md { column-gap: var(--jkl-unit-30); & > * { --jkl-flex-gap: var(--jkl-unit-30); } } + .lg-row-gap-lg { row-gap: var(--jkl-unit-40); }.lg-col-gap-lg { column-gap: var(--jkl-unit-40); & > * { --jkl-flex-gap: var(--jkl-unit-40); } } + .lg-row-gap-xl { row-gap: var(--jkl-unit-50); }.lg-col-gap-xl { column-gap: var(--jkl-unit-50); & > * { --jkl-flex-gap: var(--jkl-unit-50); } } + .lg-row-gap-xxl { row-gap: var(--jkl-unit-100); }.lg-col-gap-xxl { column-gap: var(--jkl-unit-100); & > * { --jkl-flex-gap: var(--jkl-unit-100); } } +} + +@media (width >= 75em) { /* var(--jkl-breakpoint-xl) */ + .xl-2\.1 > :where(:nth-child(2n - 1)), .xl-10\.2 > :where(:nth-child(2n)) { --jkl-flex-layout: 2; } + .xl-10\.2 > :where(:nth-child(2n - 1)), .xl-2\.1 > :where(:nth-child(2n)) { --jkl-flex-layout: 10; } + .xl-3\.9 > :where(:nth-child(2n - 1)), .xl-9\.3 > :where(:nth-child(2n)) { --jkl-flex-layout: 3; } + .xl-9\.3 > :where(:nth-child(2n - 1)), .xl-3\.9 > :where(:nth-child(2n)) { --jkl-flex-layout: 9; } + .xl-4\.8 > :where(:nth-child(2n - 1)), .xl-8\.4 > :where(:nth-child(2n)) { --jkl-flex-layout: 4; } + .xl-8\.4 > :where(:nth-child(2n - 1)), .xl-4\.8 > :where(:nth-child(2n)) { --jkl-flex-layout: 8; } + .xl-5\.7 > :where(:nth-child(2n - 1)), .xl-7\.5 > :where(:nth-child(2n)) { --jkl-flex-layout: 5; } + .xl-7\.5 > :where(:nth-child(2n - 1)), .xl-5\.7 > :where(:nth-child(2n)) { --jkl-flex-layout: 7; } + + .xl-0 > * { --jkl-flex-layout: auto; } .xl-1 > * { --jkl-flex-layout: 12; } .xl-2 > * { --jkl-flex-layout: 6; } + .xl-3 > * { --jkl-flex-layout: 4; } .xl-4 > * {--jkl-flex-layout: 3; } .xl-6 > * { --jkl-flex-layout: 2; } + + .xl-row-gap-none { row-gap: 0; }.xl-col-gap-none { column-gap: 0; & > * {--jkl-flex-gap: 0px;} } + .xl-row-gap-xs { row-gap: var(--jkl-unit-10); }.xl-col-gap-xs { column-gap: var(--jkl-unit-10); & > * { --jkl-flex-gap: var(--jkl-unit-10); } } + .xl-row-gap-sm { row-gap: var(--jkl-unit-20); }.xl-col-gap-sm { column-gap: var(--jkl-unit-20); & > * { --jkl-flex-gap: var(--jkl-unit-20); } } + .xl-row-gap-md { row-gap: var(--jkl-unit-30); }.xl-col-gap-md { column-gap: var(--jkl-unit-30); & > * { --jkl-flex-gap: var(--jkl-unit-30); } } + .xl-row-gap-lg { row-gap: var(--jkl-unit-40); }.xl-col-gap-lg { column-gap: var(--jkl-unit-40); & > * { --jkl-flex-gap: var(--jkl-unit-40); } } + .xl-row-gap-xl { row-gap: var(--jkl-unit-50); }.xl-col-gap-xl { column-gap: var(--jkl-unit-50); & > * { --jkl-flex-gap: var(--jkl-unit-50); } } + .xl-row-gap-xxl { row-gap: var(--jkl-unit-100); }.xl-col-gap-xxl { column-gap: var(--jkl-unit-100); & > * {--jkl-flex-gap: var(--jkl-unit-100); } } +} + +@media (width >= 101.25em) { /* var(--jkl-breakpoint-xxl) */ + .xxl-2\.1 > :where(:nth-child(2n - 1)), .xxl-10\.2 > :where(:nth-child(2n)) { --jkl-flex-layout: 2; } + .xxl-10\.2 > :where(:nth-child(2n - 1)), .xxl-2\.1 > :where(:nth-child(2n)) { --jkl-flex-layout: 10; } + .xxl-3\.9 > :where(:nth-child(2n - 1)), .xxl-9\.3 > :where(:nth-child(2n)) { --jkl-flex-layout: 3; } + .xxl-9\.3 > :where(:nth-child(2n - 1)), .xxl-3\.9 > :where(:nth-child(2n)) { --jkl-flex-layout: 9; } + .xxl-4\.8 > :where(:nth-child(2n - 1)), .xxl-8\.4 > :where(:nth-child(2n)) { --jkl-flex-layout: 4; } + .xxl-8\.4 > :where(:nth-child(2n - 1)), .xxl-4\.8 > :where(:nth-child(2n)) { --jkl-flex-layout: 8; } + .xxl-5\.7 > :where(:nth-child(2n - 1)), .xxl-7\.5 > :where(:nth-child(2n)) { --jkl-flex-layout: 5; } + .xxl-7\.5 > :where(:nth-child(2n - 1)), .xxl-5\.7 > :where(:nth-child(2n)) { --jkl-flex-layout: 7; } + .xxl-0 > * { --jkl-flex-layout: auto; } .xxl-1 > * { --jkl-flex-layout: 12; } .xxl-2 > * { --jkl-flex-layout: 6; } + .xxl-3 > * { --jkl-flex-layout: 4; } .xxl-4 > * { --jkl-flex-layout: 3; } .xxl-6 > * { --jkl-flex-layout: 2; } + + .xxl-row-gap-none { row-gap: 0; }.xxl-col-gap-none { column-gap: 0;& > * {--jkl-flex-gap: 0px;} } + .xxl-row-gap-xs { row-gap: var(--jkl-unit-10); }.xxl-col-gap-xs { column-gap: var(--jkl-unit-10); & > * { --jkl-flex-gap: var(--jkl-unit-10); } } + .xxl-row-gap-sm { row-gap: var(--jkl-unit-20); }.xxl-col-gap-sm { column-gap: var(--jkl-unit-20); & > * { --jkl-flex-gap: var(--jkl-unit-20); } } + .xxl-row-gap-md { row-gap: var(--jkl-unit-30);}.xxl-col-gap-md { column-gap: var(--jkl-unit-30); & > * { --jkl-flex-gap: var(--jkl-unit-30); } } + .xxl-row-gap-lg { row-gap: var(--jkl-unit-40); }.xxl-col-gap-lg { column-gap: var(--jkl-unit-40); & > * { --jkl-flex-gap: var(--jkl-unit-40); } } + .xxl-row-gap-xl { row-gap: var(--jkl-unit-50); }.xxl-col-gap-xl { column-gap: var(--jkl-unit-50); & > * { --jkl-flex-gap: var(--jkl-unit-50); } } + .xxl-row-gap-xxl { row-gap: var(--jkl-unit-100); }.xxl-col-gap-xxl { column-gap: var(--jkl-unit-100); & > * { --jkl-flex-gap: var(--jkl-unit-100); } } +} \ No newline at end of file diff --git a/packages/jokul/src/utilities/polymorphism/polymorphism.ts b/packages/jokul/src/utilities/polymorphism/polymorphism.ts index f5047c47893..9b99eddd0a2 100644 --- a/packages/jokul/src/utilities/polymorphism/polymorphism.ts +++ b/packages/jokul/src/utilities/polymorphism/polymorphism.ts @@ -2,11 +2,6 @@ type ElementTypeProp = { as?: ElementType; }; -type PropsToOmit< - ElementType extends React.ElementType, - Props, -> = keyof (ElementTypeProp & Props); - export type PolymorphicProps< ElementType extends React.ElementType, Props = {}, @@ -16,12 +11,25 @@ export type PolymorphicProps< PropsToOmit >; -export type PolymorphicRef = - React.ComponentPropsWithRef["ref"]; +export type PolymorphicRef = React.ComponentPropsWithRef["ref"]; -export type PolymorphicPropsWithRef< - ElementType extends React.ElementType, - Props = {}, -> = PolymorphicProps & { - ref?: PolymorphicRef; -}; +export type PolymorphicComponentPropWithRef = PolymorphicComponentProp< + As, + Props +> & { ref?: PolymorphicRef }; + +// Implementation of reusable polymorphic types +// Explaination: https://blog.logrocket.com/build-strongly-typed-polymorphic-components-react-typescript/ +type AsProp = { as?: As }; +type PropsToOmit = keyof (AsProp & P); +type PolymorphicComponentProp = React.PropsWithChildren< + Props & AsProp +> & + Omit, PropsToOmit>; + +// Les https://stackoverflow.com/q/57683303 +export type Expand = T extends (...args: infer A) => infer R + ? (...args: Expand) => Expand + : T extends infer O + ? { [K in keyof O]: O[K] } + : never;