diff --git a/package.json b/package.json
index e7403ec..c611fb6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "fluentui-helpers",
- "version": "0.2.0",
+ "version": "0.2.1",
"description": "Helper library for microsofts fluentui react library",
"main": "dist/index.js",
"module": "dist/index.mjs",
@@ -8,9 +8,18 @@
"files": [
"dist"
],
+ "main": "dist/index.js",
+ "module": "dist/index.mjs",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist"
+ ],
"author": "bubulus",
"license": "MIT",
"peerDependencies": {
+ "@fluentui/react-components": "^9",
+ "@fluentui/react-icons": "^2",
+ "@griffel/react": "^1.5",
"@fluentui/react-components": "^9",
"@fluentui/react-icons": "^2",
"@griffel/react": "^1.5",
@@ -69,6 +78,7 @@
"typescript": "5.5.4",
"vite": "^5.4.8",
"vite-plugin-dts": "^4.4.0",
+ "vite-plugin-dts": "^4.4.0",
"vite-tsconfig-paths": "^5.0.1"
}
}
diff --git a/src/components/layout/Flex/component.tsx b/src/components/layout/Flex/func.tsx
similarity index 75%
rename from src/components/layout/Flex/component.tsx
rename to src/components/layout/Flex/func.tsx
index dac19ca..e68592e 100644
--- a/src/components/layout/Flex/component.tsx
+++ b/src/components/layout/Flex/func.tsx
@@ -16,7 +16,12 @@ import {
import type {
TFlexDirection,
- TFlexOption,
+ TFlexOptionContent,
+ TFlexOptionItems,
+ TFlexWrap,
+ TFlexGrow,
+ TFlexShrink,
+ TFlexBasis,
TFlexShorthandDimensions,
TFlexPosition,
} from "@components/layout/Flex/types";
@@ -25,9 +30,14 @@ type TProps = {
children: ReactNode;
position?: TFlexPosition;
direction?: TFlexDirection;
- justifyContent?: TFlexOption;
- alignItems?: TFlexOption;
- wrap?: boolean;
+ justifyContent?: TFlexOptionContent;
+ alignItems?: TFlexOptionItems;
+ alignContent?: TFlexOptionContent;
+ alignSelf?: TFlexOptionItems;
+ grow?: TFlexGrow;
+ noShrink?: TFlexShrink;
+ basis?: TFlexBasis;
+ wrap?: TFlexWrap;
className?: string;
gap?: TThemeSpacing;
margin?: TThemeShorthandSpacing;
@@ -49,8 +59,14 @@ type TProps = {
* - `direction`: flex-direction property
* - `justifyContent`: justify-content property
* - `alignItems`: align-items property
+ * - `alignContent`: align-content property
+ * - `alignSelf`: align-self property
* - `wrap`: flex-wrap property
* - `gap`: gap between children, with fixed predefined values from the design system, not discriminating between horizontal and vertical gap (because there are literally the same values)
+ * - `grow`: shorthand for flex-grow property
+ * - `noShrink`: shorthand for flex-shrink property, noShrik is the same as flex-shrink: 0
+ * - `basis`: shorthand for flex-basis property, only global values are supported, for specific values use className prop
+ * - `position`: position property, supports all global values
* - `margin`: margin property, using the same values like gap, expects the shorthand notation
* - `padding`: same like margin, but for padding, concrete example below
*
@@ -74,15 +90,33 @@ type TProps = {
*
*
* @default
- * direction = "row", justifyContent = "start", alignItems = "start", wrap = false, gap = "None", margin = ["None"], padding = ["None"], shHeight = "auto", shWidth = "auto"
+ * direction = "row",
+ * position = "static",
+ * justifyContent = "start",
+ * alignItems = "stretch",
+ * alignContent = "stretch",
+ * alignSelf = "auto",
+ * grow = false,
+ * noShrink = false,
+ * wrap = false,
+ * gap = "None",
+ * margin = ["None"],
+ * padding = ["None"],
+ * shHeight = "auto",
+ * shWidth = "auto"
*/
export default function Flex({
direction = "row",
position = "static",
justifyContent = "start",
- alignItems = "start",
+ alignContent = "stretch",
+ alignItems = "stretch",
+ alignSelf = "auto",
wrap = false,
gap = "None",
+ grow = false,
+ noShrink = false,
+ basis = "auto",
margin = ["None"],
padding = ["None"],
shHeight = "auto",
@@ -92,7 +126,17 @@ export default function Flex({
children,
...rest
}: TProps) {
- const flexBoxClass = useFlexBox(justifyContent, alignItems, direction, wrap);
+ const flexBoxClass = useFlexBox(
+ justifyContent,
+ alignContent,
+ alignItems,
+ alignSelf,
+ direction,
+ wrap,
+ grow,
+ noShrink,
+ basis,
+ );
const gapClass = useGap(gap);
const marginClass = useMargin(margin);
const paddingClass = usePadding(padding);
diff --git a/src/components/layout/Flex/hooks/useFlexBox.ts b/src/components/layout/Flex/hooks/useFlexBox.ts
index 8cebc82..d7b85a7 100644
--- a/src/components/layout/Flex/hooks/useFlexBox.ts
+++ b/src/components/layout/Flex/hooks/useFlexBox.ts
@@ -4,33 +4,65 @@ import { useFlexBoxClasses } from "@components/layout/Flex/styles";
import type {
TFlexDirection,
- TFlexOption,
+ TFlexOptionContent,
+ TFlexOptionItems,
+ TFlexShrink,
+ TFlexGrow,
+ TFlexBasis,
+ TFlexWrap,
} from "@components/layout/Flex/types";
export default function useFlexBox(
- justifyContent?: TFlexOption,
- alignItems?: TFlexOption,
+ justifyContent?: TFlexOptionContent,
+ alignContent?: TFlexOptionContent,
+ alignItems?: TFlexOptionItems,
+ alignSelf?: TFlexOptionItems,
direction?: TFlexDirection,
- wrap?: boolean,
+ wrap?: TFlexWrap,
+ grow?: TFlexGrow,
+ noShrink?: TFlexShrink,
+ basis?: TFlexBasis,
) {
const classes = useFlexBoxClasses();
+
const directionClass = direction
? classes[`${direction}Direction`]
: undefined;
+
const justifyContentClass = justifyContent
- ? classes[`${justifyContent}Content`]
+ ? classes[`${justifyContent}JustifyContent`]
+ : undefined;
+
+ const alignContentClass = alignContent
+ ? classes[`${alignContent}AlignContent`]
: undefined;
+
const alignItemsClass = alignItems
- ? classes[`${alignItems}Items`]
+ ? classes[`${alignItems}AlignItems`]
+ : undefined;
+
+ const alignSelfClass = alignSelf
+ ? classes[`${alignSelf}AlignSelf`]
: undefined;
- const wrapClass = wrap ? classes.wrap : classes.nowrap;
+ const basisClass = basis ? classes[`${basis}Basis`] : undefined;
+
+ const growClass = grow ? classes.growOne : classes.growZero;
+ const shrinkClass = noShrink ? classes.shrinkZero : classes.shrinkOne;
+ const wrapClass = wrap
+ ? (wrap === "reverse" && classes.wrapReverse) || classes.wrap
+ : classes.nowrap;
return mergeClasses(
classes.base,
directionClass,
justifyContentClass,
+ alignContentClass,
alignItemsClass,
+ alignSelfClass,
+ growClass,
+ shrinkClass,
+ basisClass,
wrapClass,
);
}
diff --git a/src/components/layout/Flex/index.ts b/src/components/layout/Flex/index.ts
index e26aa32..b101107 100644
--- a/src/components/layout/Flex/index.ts
+++ b/src/components/layout/Flex/index.ts
@@ -1,3 +1,3 @@
-import Flex from "@components/layout/Flex/component";
+import Flex from "@components/layout/Flex/func";
export default Flex;
diff --git a/src/components/layout/Flex/styles/flexBox.ts b/src/components/layout/Flex/styles/flexBox.ts
index 272f5a3..bae5fb7 100644
--- a/src/components/layout/Flex/styles/flexBox.ts
+++ b/src/components/layout/Flex/styles/flexBox.ts
@@ -10,49 +10,97 @@ const useFlexBoxClasses = makeStyles({
columnDirection: {
flexDirection: "column",
},
+ rowReverseDirection: {
+ flexDirection: "row-reverse",
+ },
+ columnReverseDirection: {
+ flexDirection: "column-reverse",
+ },
+
// justify-content
- centerContent: {
+ centerJustifyContent: {
justifyContent: "center",
},
- startContent: {
+ startJustifyContent: {
justifyContent: "flex-start",
},
- endContent: {
+ endJustifyContent: {
justifyContent: "flex-end",
},
- spaceBetweenContent: {
+ spaceBetweenJustifyContent: {
justifyContent: "space-between",
},
- spaceAroundContent: {
+ spaceAroundJustifyContent: {
justifyContent: "space-around",
},
- spaceEvenlyContent: {
+ spaceEvenlyJustifyContent: {
justifyContent: "space-evenly",
},
- stretchContent: {
+ stretchJustifyContent: {
justifyContent: "stretch",
},
+
// align-items
- centerItems: {
+ autoAlignItems: {
+ alignItems: "auto",
+ },
+ centerAlignItems: {
alignItems: "center",
},
- startItems: {
+ startAlignItems: {
alignItems: "flex-start",
},
- endItems: {
+ endAlignItems: {
alignItems: "flex-end",
},
- stretchItems: {
+ stretchAlignItems: {
alignItems: "stretch",
},
- spaceBetweenItems: {
- alignItems: "space-between",
+ baselineAlignItems: {
+ alignItems: "baseline",
+ },
+
+ // align-self
+ autoAlignSelf: {
+ alignSelf: "auto",
+ },
+ startAlignSelf: {
+ alignSelf: "flex-start",
+ },
+ endAlignSelf: {
+ alignSelf: "flex-end",
},
- spaceAroundItems: {
- alignItems: "space-around",
+ centerAlignSelf: {
+ alignSelf: "center",
},
- spaceEvenlyItems: {
- alignItems: "space-evenly",
+ stretchAlignSelf: {
+ alignSelf: "stretch",
+ },
+ baselineAlignSelf: {
+ alignSelf: "baseline",
+ },
+
+ // align-content
+ centerAlignContent: {
+ alignContent: "center",
+ },
+ startAlignContent: {
+ alignContent: "flex-start",
+ },
+ endAlignContent: {
+ alignContent: "flex-end",
+ },
+ stretchAlignContent: {
+ alignContent: "stretch",
+ },
+ spaceBetweenAlignContent: {
+ alignContent: "space-between",
+ },
+ spaceAroundAlignContent: {
+ alignContent: "space-around",
+ },
+ spaceEvenlyAlignContent: {
+ alignContent: "space-evenly",
},
// wrap
@@ -62,6 +110,48 @@ const useFlexBoxClasses = makeStyles({
nowrap: {
flexWrap: "nowrap",
},
+ wrapReverse: {
+ flexWrap: "wrap-reverse",
+ },
+
+ // grow
+ growOne: {
+ flexGrow: 1,
+ },
+ growZero: {
+ flexGrow: 0,
+ },
+
+ // shrink
+ shrinkOne: {
+ flexShrink: 1,
+ },
+ shrinkZero: {
+ flexShrink: 0,
+ },
+
+ // basis
+ autoBasis: {
+ flexBasis: "auto",
+ },
+ "0Basis": {
+ flexBasis: 0,
+ },
+ fillBasis: {
+ flexBasis: "fill",
+ },
+ maxContentBasis: {
+ flexBasis: "max-content",
+ },
+ minContentBasis: {
+ flexBasis: "min-content",
+ },
+ fitContentBasis: {
+ flexBasis: "fit-content",
+ },
+ contentBasis: {
+ flexBasis: "content",
+ },
});
export default useFlexBoxClasses;
diff --git a/src/components/layout/Flex/tests.tsx b/src/components/layout/Flex/tests.tsx
index 0be08c1..74a288f 100644
--- a/src/components/layout/Flex/tests.tsx
+++ b/src/components/layout/Flex/tests.tsx
@@ -8,14 +8,19 @@ describe("Flex", () => {
it("should render without required props default config", () => {
render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
-
expect(FlexElement).toBeInTheDocument();
+
expect(FlexElement).toHaveTextContent("FlexChild");
expect(FlexElement).toHaveStyle("display: flex");
expect(FlexElement).toHaveStyle("flex-direction: row");
expect(FlexElement).toHaveStyle("justify-content: flex-start");
- expect(FlexElement).toHaveStyle("align-items: flex-start");
+ expect(FlexElement).toHaveStyle("align-items: stretch");
+ expect(FlexElement).toHaveStyle("align-content: stretch");
+ expect(FlexElement).toHaveStyle("align-self: auto");
+ expect(FlexElement).toHaveStyle("flex-grow: 0");
+ expect(FlexElement).toHaveStyle("flex-shrink: 1");
expect(FlexElement).toHaveStyle("flex-wrap: nowrap");
+ expect(FlexElement).toHaveStyle("flex-basis: auto");
expect(FlexElement).toHaveStyle("gap: 0rem");
expect(FlexElement).toHaveStyle("margin: 0rem");
expect(FlexElement).toHaveStyle("padding: 0rem");
@@ -35,6 +40,16 @@ describe("Flex", () => {
const FlexElement = screen.getByText("FlexChild");
expect(FlexElement).toHaveStyle("flex-direction: row");
});
+ it("should render with direction rowReverse", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-direction: row-reverse");
+ });
+ it("should render with direction columnReverse", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-direction: column-reverse");
+ });
});
describe("for justifyContent", () => {
it("should render with justifyContent center", () => {
@@ -68,6 +83,38 @@ describe("Flex", () => {
expect(FlexElement).toHaveStyle("justify-content: stretch");
});
});
+ describe("for alignContent", () => {
+ it("should render with alignContent center", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-content: center");
+ });
+ it("should render with alignContent end", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-content: flex-end");
+ });
+ it("should render with alignContent spaceBetween", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-content: space-between");
+ });
+ it("should render with alignContent spaceAround", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-content: space-around");
+ });
+ it("should render with alignContent spaceEvenly", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-content: space-evenly");
+ });
+ it("should render with alignContent stretch", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-content: stretch");
+ });
+ });
describe("for alignItems", () => {
it("should render with alignItems center", () => {
render(FlexChild);
@@ -79,38 +126,55 @@ describe("Flex", () => {
const FlexElement = screen.getByText("FlexChild");
expect(FlexElement).toHaveStyle("align-items: flex-end");
});
- it("should render with alignItems spaceBetween", () => {
- render(FlexChild);
+ it("should render with alignItems stretch", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-items: stretch");
+ });
+ it("should render with alignItems baseline", () => {
+ render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
- expect(FlexElement).toHaveStyle("align-items: space-between");
+ expect(FlexElement).toHaveStyle("align-items: baseline");
});
- it("should render with alignItems spaceAround", () => {
- render(FlexChild);
+ });
+ describe("for alignSelf", () => {
+ it("should render with alignSelf center", () => {
+ render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
- expect(FlexElement).toHaveStyle("align-items: space-around");
+ expect(FlexElement).toHaveStyle("align-self: center");
});
- it("should render with alignItems spaceEvenly", () => {
- render(FlexChild);
+ it("should render with alignSelf end", () => {
+ render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
- expect(FlexElement).toHaveStyle("align-items: space-evenly");
+ expect(FlexElement).toHaveStyle("align-self: flex-end");
});
- it("should render with alignItems stretch", () => {
- render(FlexChild);
+ it("should render with alignSelf stretch", () => {
+ render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
- expect(FlexElement).toHaveStyle("align-items: stretch");
+ expect(FlexElement).toHaveStyle("align-self: stretch");
+ });
+ it("should render with alignSelf baseline", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("align-self: baseline");
});
});
describe("for wrap", () => {
- it("should render with wrap wrap", () => {
+ it("should render with wrap: wrap", () => {
render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
expect(FlexElement).toHaveStyle("flex-wrap: wrap");
});
- it("should render with wrap nowrap", () => {
+ it("should render with wrap: nowrap", () => {
render(FlexChild);
const FlexElement = screen.getByText("FlexChild");
expect(FlexElement).toHaveStyle("flex-wrap: nowrap");
});
+ it("should render with wrap: reverse", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-wrap: wrap-reverse");
+ });
});
describe("for gap", () => {
it("should render with gap None", () => {
@@ -169,6 +233,67 @@ describe("Flex", () => {
expect(FlexElement).toHaveStyle("gap: 2rem");
});
});
+ describe("for grow", () => {
+ it("should render with grow true", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-grow: 1");
+ });
+ it("should render with grow false", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-grow: 0");
+ });
+ });
+ describe("for noShrink", () => {
+ it("should render with noShrink true", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-shrink: 0");
+ });
+ it("should render with noShrink false", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-shrink: 1");
+ });
+ });
+ describe("for basis", () => {
+ it("should render with basis auto", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: auto");
+ });
+ it("should render with basis fill", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: fill");
+ });
+ it("should render with basis maxContent", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: max-content");
+ });
+ it("should render with basis minContent", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: min-content");
+ });
+ it("should render with basis fitContent", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: fit-content");
+ });
+ it("should render with basis content", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: content");
+ });
+ it("should render with basis 0", () => {
+ render(FlexChild);
+ const FlexElement = screen.getByText("FlexChild");
+ expect(FlexElement).toHaveStyle("flex-basis: 0");
+ });
+ });
describe("for margin", () => {
it("should render with margin None", () => {
render(FlexChild);
diff --git a/src/components/layout/Flex/types.ts b/src/components/layout/Flex/types.ts
index 14334d5..a5843bf 100644
--- a/src/components/layout/Flex/types.ts
+++ b/src/components/layout/Flex/types.ts
@@ -1,6 +1,6 @@
-export type TFlexDirection = "row" | "column";
+export type TFlexDirection = "row" | "column" | "rowReverse" | "columnReverse";
-export type TFlexOption =
+export type TFlexOptionContent =
| "start"
| "center"
| "end"
@@ -9,8 +9,28 @@ export type TFlexOption =
| "spaceEvenly"
| "stretch";
-export type TFlexWrap = "wrap" | "nowrap";
+export type TFlexOptionItems =
+ | "start"
+ | "center"
+ | "end"
+ | "stretch"
+ | "baseline"
+ | "auto";
+
+export type TFlexGrow = boolean;
+
+export type TFlexShrink = boolean;
+
+export type TFlexWrap = boolean | "reverse";
+export type TFlexBasis =
+ | "auto"
+ | "fill"
+ | "maxContent"
+ | "minContent"
+ | "fitContent"
+ | "content"
+ | "0";
export type TFlexShorthandDimensions = "25%" | "50%" | "75%" | "100%" | "auto";
export type TFlexPosition =