diff --git a/README.md b/README.md index 83369d3..b1ed4ed 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,13 @@ This library provides a flexible, responsive grid component for ReactJS. It is w ##### Using npm ```bash -npm install --save react-css-grid +npm install --save react-simple-css-grid ``` ##### Using yarn ```bash -yarn add react-css-grid +yarn add react-simple-css-grid ``` ## Usage @@ -37,22 +37,50 @@ You can then use it in your component: ``` +## Grid Context + +You can add some configuration globally for your grids using GridContextProvider : + +``` +import { GridContextProvider } from "react-simple-css-grid"; + + + {children} + +``` + +- `minWidth` : The minimum width where the grid displays on 1 column (if no smallScreenColumns is defined) +- `gaps` : Override the original gaps of `` component + ## Props The Grid component accepts the following props: -- children: The child elements to display in the grid. -- style: Additional CSS styles to apply to the grid. -- columns: The number of columns or the ‘grid-template-columns’ - CSS property value. -- smallScreenColumns: The number of columns or the ‘grid-template-columns’ CSS property value for small screens. -- rows: The number of rows or the ‘grid-template-rows’ CSS property value. -- rowGap: The gap between rows. -- columnGap: The gap between columns. -- className: An additional CSS class to apply to the grid. -- uniqueClass: A unique CSS class to apply to the grid. (see #Optimize section) -- alignCenter: If true, grid items are vertically centered. -- alignStart: If true, grid items are aligned to the start. -- height: The height of the grid. +- `children`: The child elements to display in the grid. +- `style`: Additional CSS styles to apply to the grid. +- `columns`: The number of columns or the ‘grid-template-columns’ - CSS property value. +- `smallScreenColumns`: The number of columns or the ‘grid-template-columns’ CSS property value for small screens. +- `rows`: The number of rows or the ‘grid-template-rows’ CSS property value. +- `rowGap`: The gap between rows. +- `columnGap`: The gap between columns. +- `className`: An additional CSS class to apply to the grid. +- `uniqueClass`: A unique CSS class to apply to the grid. (see #Optimize section) +- `alignCenter`: If true, grid items are vertically centered. +- `alignStart`: If true, grid items are aligned to the start. +- `height`: The height of the grid. ## Optimize diff --git a/package.json b/package.json index 99f8bec..2cb3940 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,14 @@ { "name": "react-simple-css-grid", - "version": "1.0.1", + "version": "1.1.2", "type": "module", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", - "types": "dist/index.d.ts", + "types": "dist/types.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/samy-mssi/react-simple-css-grid.git" + }, "scripts": { "dev": "vite", "build": "tsc && vite build", diff --git a/rollup.config.js b/rollup.config.js index ce970df..d3c3e32 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -22,6 +22,10 @@ export default [ format: "esm", sourcemap: true, }, + { + dir: "dist", + format: "cjs", + }, ], plugins: [ peerDepsExternal(), diff --git a/src/components/Grid/grid-context.tsx b/src/components/Grid/grid-context.tsx new file mode 100644 index 0000000..033d0ce --- /dev/null +++ b/src/components/Grid/grid-context.tsx @@ -0,0 +1,20 @@ +import { ReactNode, createContext } from "react"; +import { GridContextConfigurationProps } from "./grid.types"; +const GridContext = createContext(null); + +const GridContextProvider = ({ + children, + configuration, +}: { + children: ReactNode; + configuration: GridContextConfigurationProps; +}) => { + if (!configuration) return children; + return ( + + {children} + + ); +}; + +export { GridContext, GridContextProvider }; diff --git a/src/components/Grid/grid.tsx b/src/components/Grid/grid.tsx index 986f91e..e08a3de 100644 --- a/src/components/Grid/grid.tsx +++ b/src/components/Grid/grid.tsx @@ -1,7 +1,8 @@ -import React, { useCallback, useEffect, useMemo } from "react"; +import React, { FC, useCallback, useContext, useEffect, useMemo } from "react"; import { v4 as uuidv4 } from "uuid"; import { useMediaQuery } from "react-responsive"; -import { Gap, GridProps } from "./grid.types"; +import { Gap, GridContextConfigurationProps, GridProps } from "./grid.types"; +import { GridContext } from "./grid-context"; const breakpoints = { sm: "576", @@ -18,7 +19,7 @@ const stylesToCSS = (styles: React.CSSProperties) => .map(([key, value]) => `${toCssProperty(key)}:${value};`) .join(""); -const Grid = ({ +const Grid: FC = ({ children, className, style, @@ -28,13 +29,15 @@ const Grid = ({ rowGap, columnGap, uniqueClass, - alignCenter, - alignStart, + alignItems, height, -}: GridProps) => { +}) => { + const configuration = useContext( + GridContext + ); // Check screen size to manage responsive const hasWideScreen = useMediaQuery({ - query: `(min-width: ${breakpoints.lg}px)`, + query: `(min-width: ${configuration?.minWidth || breakpoints.lg}px)`, }); // Generate unique className const uniqueClassName: string = useMemo( @@ -43,22 +46,25 @@ const Grid = ({ ); // Get gap from props - const getGap = useCallback((g?: string) => { - const gaps: Gap[] = [ - { xs: "0.25rem" }, - { s: "0.5rem" }, - { m: "0.75rem" }, - { l: "1rem" }, - { xl: "1.5rem" }, - { xxl: "1.75rem" }, - { xxxl: "2rem" }, - ]; - if (g) { - const selectedGap = gaps.find((gap) => gap[g]); - return selectedGap ? selectedGap[g] : "1.5rem"; - } - return "1.5rem"; - }, []); + const getGap = useCallback( + (g?: string) => { + const gaps: Gap[] = configuration?.gaps || [ + { xs: "0.25rem" }, + { s: "0.5rem" }, + { m: "0.75rem" }, + { l: "1rem" }, + { xl: "1.5rem" }, + { xxl: "1.75rem" }, + { xxxl: "2rem" }, + ]; + if (g) { + const selectedGap = gaps.find((gap) => gap[g]); + return selectedGap ? selectedGap[g] : "1.5rem"; + } + return "1.5rem"; + }, + [configuration?.gaps] + ); const getColumnPattern = useCallback(() => { if (!hasWideScreen) { @@ -75,13 +81,11 @@ const Grid = ({ columnGap: getGap(columnGap), rowGap: getGap(rowGap), height: height, - ...(alignCenter && { alignItems: "center" }), - ...(alignStart && { alignItems: "start" }), + ...(alignItems && { alignItems: alignItems }), ...style, }), [ - alignCenter, - alignStart, + alignItems, columnGap, getColumnPattern, getGap, @@ -128,4 +132,5 @@ Grid.defaultProps = { rows: "auto", height: "fit-content", }; + export default Grid; diff --git a/src/components/Grid/grid.types.ts b/src/components/Grid/grid.types.ts index d61d405..9c25373 100644 --- a/src/components/Grid/grid.types.ts +++ b/src/components/Grid/grid.types.ts @@ -1,19 +1,23 @@ import { ReactNode } from "react"; import * as CSS from "csstype"; +export interface GridContextConfigurationProps { + minWidth?: number; // The minimum width where the grid displays on 1 column (if no smallScreenColumns is defined) + gaps?: Gap[]; +} + export interface GridProps { children: ReactNode; style?: React.CSSProperties; columns?: number | CSS.Property.GridTemplateColumns; smallScreenColumns?: number | CSS.Property.GridTemplateColumns; - rows: number | CSS.Property.GridTemplateColumns; + rows?: number | CSS.Property.GridTemplateColumns; rowGap?: string; columnGap?: string; className?: string; uniqueClass?: string; - alignCenter?: boolean; - alignStart?: boolean; - height: CSS.Property.Height; + alignItems?: CSS.Property.AlignItems; + height?: CSS.Property.Height; } export interface Gap { diff --git a/src/components/Grid/index.ts b/src/components/Grid/index.ts index ca111b3..550ecea 100644 --- a/src/components/Grid/index.ts +++ b/src/components/Grid/index.ts @@ -1 +1,3 @@ export { default } from "./grid"; +export { GridContextProvider } from "./grid-context"; +export type { GridProps, Gap } from "./grid.types"; diff --git a/src/components/index.ts b/src/components/index.ts index f2b8147..7823b0b 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1 +1 @@ -export * from "./Grid"; +export { default as Grid, GridContextProvider } from "./Grid"; diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 6119ad9..0000000 --- a/src/index.css +++ /dev/null @@ -1,68 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -}