@sproutsocial/seeds-react-grid 0.2.12 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1,5 +1,11 @@
1
1
  // src/Grid.tsx
2
2
  import "react";
3
+
4
+ // src/GridHybrid.tsx
5
+ import "react";
6
+ import { needsStyledComponents } from "@sproutsocial/seeds-react-system-props";
7
+
8
+ // src/styles.ts
3
9
  import styled from "styled-components";
4
10
  import Box from "@sproutsocial/seeds-react-box";
5
11
 
@@ -44,12 +50,58 @@ var getResponsiveStyles = (columns = 1) => {
44
50
  `;
45
51
  };
46
52
 
47
- // src/Grid.tsx
48
- import { jsx } from "react/jsx-runtime";
53
+ // src/styles.ts
49
54
  var Container = styled(Box)`
50
55
  ${(props) => getResponsiveStyles(props.$columns)}
51
56
  `;
52
- var Grid = ({
57
+ var styles_default = Container;
58
+
59
+ // src/GridTailwind.tsx
60
+ import "react";
61
+ import { jsx } from "react/jsx-runtime";
62
+ var SPACE_SCALE = {
63
+ 0: 0,
64
+ 100: 2,
65
+ 200: 4,
66
+ 300: 8,
67
+ 350: 12,
68
+ 400: 16,
69
+ 450: 24,
70
+ 500: 32,
71
+ 600: 40
72
+ };
73
+ var toGap = (value) => typeof value === "number" ? `${SPACE_SCALE[value] ?? 0}px` : value;
74
+ var isResponsive = (value) => typeof value === "object" && value !== null;
75
+ var applyResponsiveColumns = (style, columns) => {
76
+ const { sm, md, lg, xl } = columns;
77
+ style["--sg-cols"] = "repeat(1, 1fr)";
78
+ style["--sg-cols-sm"] = `repeat(${sm ?? 1}, 1fr)`;
79
+ style["--sg-cols-md"] = `repeat(${md ?? sm ?? 1}, 1fr)`;
80
+ style["--sg-cols-lg"] = `repeat(${lg ?? md ?? sm ?? 1}, 1fr)`;
81
+ style["--sg-cols-xl"] = `repeat(${xl ?? lg ?? md ?? sm ?? 1}, 1fr)`;
82
+ };
83
+ var applyGap = (style, axis, value) => {
84
+ const prefix = axis === "row" ? "--sg-row-gap" : "--sg-col-gap";
85
+ if (isResponsive(value)) {
86
+ const { sm, md, lg, xl } = value;
87
+ style[prefix] = "0";
88
+ if (sm !== void 0) style[`${prefix}-sm`] = toGap(sm);
89
+ const mdVal = md ?? sm;
90
+ if (mdVal !== void 0) style[`${prefix}-md`] = toGap(mdVal);
91
+ const lgVal = lg ?? md ?? sm;
92
+ if (lgVal !== void 0) style[`${prefix}-lg`] = toGap(lgVal);
93
+ const xlVal = xl ?? lg ?? md ?? sm;
94
+ if (xlVal !== void 0) style[`${prefix}-xl`] = toGap(xlVal);
95
+ return;
96
+ }
97
+ const resolved = toGap(value);
98
+ if (axis === "row") {
99
+ style.rowGap = resolved;
100
+ } else {
101
+ style.columnGap = resolved;
102
+ }
103
+ };
104
+ var GridTailwind = ({
53
105
  columns = 1,
54
106
  gap = 400,
55
107
  rowGap,
@@ -57,18 +109,45 @@ var Grid = ({
57
109
  children,
58
110
  className
59
111
  }) => {
60
- return /* @__PURE__ */ jsx(
61
- Container,
62
- {
63
- display: "grid",
64
- rowGap: toResponsiveGapObject(rowGap ?? gap),
65
- columnGap: toResponsiveGapObject(columnGap ?? gap),
66
- $columns: columns,
67
- className,
68
- children
69
- }
70
- );
112
+ const style = { display: "grid" };
113
+ if (isResponsive(columns)) {
114
+ applyResponsiveColumns(style, columns);
115
+ } else {
116
+ style.gridTemplateColumns = `repeat(${columns}, 1fr)`;
117
+ }
118
+ applyGap(style, "row", rowGap ?? gap);
119
+ applyGap(style, "column", columnGap ?? gap);
120
+ const classes = ["seeds-grid", className].filter(Boolean).join(" ");
121
+ return /* @__PURE__ */ jsx("div", { className: classes, style, children });
71
122
  };
123
+ GridTailwind.displayName = "GridTailwind";
124
+
125
+ // src/GridHybrid.tsx
126
+ import { jsx as jsx2 } from "react/jsx-runtime";
127
+ var GridHybrid = (props) => {
128
+ const { columns = 1, gap = 400, rowGap, columnGap, children, className } = props;
129
+ if (needsStyledComponents(props)) {
130
+ return /* @__PURE__ */ jsx2(
131
+ styles_default,
132
+ {
133
+ display: "grid",
134
+ rowGap: toResponsiveGapObject(rowGap ?? gap),
135
+ columnGap: toResponsiveGapObject(columnGap ?? gap),
136
+ $columns: columns,
137
+ className,
138
+ children
139
+ }
140
+ );
141
+ }
142
+ return /* @__PURE__ */ jsx2(GridTailwind, { ...props });
143
+ };
144
+ GridHybrid.displayName = "Grid";
145
+ var GridHybrid_default = GridHybrid;
146
+
147
+ // src/Grid.tsx
148
+ import { jsx as jsx3 } from "react/jsx-runtime";
149
+ var Grid = (props) => /* @__PURE__ */ jsx3(GridHybrid_default, { ...props });
150
+ Grid.displayName = "Grid";
72
151
  var Grid_default = Grid;
73
152
 
74
153
  // src/GridTypes.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Grid.tsx","../../src/utils.ts","../../src/GridTypes.ts","../../src/index.ts"],"sourcesContent":["import React from \"react\";\nimport styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport type { ContainerProps, GridProps } from \"./GridTypes\";\nimport { getResponsiveStyles, toResponsiveGapObject } from \"./utils\";\n\nconst Container = styled(Box)<ContainerProps>`\n ${(props) => getResponsiveStyles(props.$columns)}\n`;\n\nconst Grid: React.FC<GridProps> = ({\n columns = 1,\n gap = 400,\n rowGap,\n columnGap,\n children,\n className,\n}) => {\n return (\n <Container\n display=\"grid\"\n rowGap={toResponsiveGapObject(rowGap ?? gap)}\n columnGap={toResponsiveGapObject(columnGap ?? gap)}\n $columns={columns}\n className={className}\n >\n {children}\n </Container>\n );\n};\n\nexport default Grid;\n","import type {\n GapValue,\n ResponsiveGapValue,\n ResponsiveValue,\n} from \"./GridTypes\";\nimport { css } from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nconst { breakpoints } = theme;\n\nexport const toResponsiveGapObject = (\n value: ResponsiveGapValue\n):\n | GapValue\n | { sm?: GapValue; md?: GapValue; lg?: GapValue; xl?: GapValue } => {\n if (typeof value !== \"object\") return value;\n return value;\n};\n\nexport const getResponsiveStyles = (columns: ResponsiveValue = 1) => {\n if (typeof columns === \"number\") {\n return css`\n grid-template-columns: repeat(${columns}, 1fr);\n `;\n }\n\n return css`\n grid-template-columns: repeat(1, 1fr);\n\n @media (min-width: ${breakpoints.sm}) {\n grid-template-columns: repeat(${columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.md}) {\n grid-template-columns: repeat(${columns.md || columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.lg}) {\n grid-template-columns: repeat(\n ${columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n\n @media (min-width: ${breakpoints.xl}) {\n grid-template-columns: repeat(\n ${columns.xl || columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n `;\n};\n","import type { TypeSpace } from \"@sproutsocial/seeds-react-theme\";\nimport * as React from \"react\";\n\nexport type ResponsiveValue =\n | number\n | {\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n };\n\n/**\n * Gap value that can be either:\n * - A space scale value from the theme (0, 100, 200, 300, 350, 400, 450, 500, 600)\n * - A pixel string value (e.g., \"16px\", \"20px\")\n */\nexport type GapValue = keyof TypeSpace | (string & {});\n\n/**\n * Responsive gap value that can be either:\n * - A single GapValue applied at all breakpoints\n * - An object with optional breakpoint keys (sm, md, lg, xl) for responsive values\n */\nexport type ResponsiveGapValue =\n | GapValue\n | {\n sm?: GapValue;\n md?: GapValue;\n lg?: GapValue;\n xl?: GapValue;\n };\n\nexport interface ContainerProps {\n $columns?: ResponsiveValue;\n}\n\nexport interface GridProps {\n /** Number of columns (can be responsive) */\n columns?: ResponsiveValue;\n /** Gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n gap?: ResponsiveGapValue;\n /** Row gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n rowGap?: ResponsiveGapValue;\n /** Column gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n columnGap?: ResponsiveGapValue;\n /** Children elements to display in the grid */\n children?: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n","import Grid from \"./Grid\";\n\nexport default Grid;\nexport { Grid };\nexport * from \"./GridTypes\";\n"],"mappings":";AAAA,OAAkB;AAClB,OAAO,YAAY;AACnB,OAAO,SAAS;;;ACGhB,SAAS,WAAW;AACpB,SAAS,aAAa;AAEtB,IAAM,EAAE,YAAY,IAAI;AAEjB,IAAM,wBAAwB,CACnC,UAGoE;AACpE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAEO,IAAM,sBAAsB,CAAC,UAA2B,MAAM;AACnE,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,sCAC2B,OAAO;AAAA;AAAA,EAE3C;AAEA,SAAO;AAAA;AAAA;AAAA,yBAGgB,YAAY,EAAE;AAAA,sCACD,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,yBAG5B,YAAY,EAAE;AAAA,sCACD,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,yBAG1C,YAAY,EAAE;AAAA;AAAA,UAE7B,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,yBAK5B,YAAY,EAAE;AAAA;AAAA,UAE7B,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAKnE;;;ADhCI;AAbJ,IAAM,YAAY,OAAO,GAAG;AAAA,IACxB,CAAC,UAAU,oBAAoB,MAAM,QAAQ,CAAC;AAAA;AAGlD,IAAM,OAA4B,CAAC;AAAA,EACjC,UAAU;AAAA,EACV,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,QAAQ,sBAAsB,UAAU,GAAG;AAAA,MAC3C,WAAW,sBAAsB,aAAa,GAAG;AAAA,MACjD,UAAU;AAAA,MACV;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,eAAQ;;;AE9Bf,OAAuB;;;ACCvB,IAAO,gBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/Grid.tsx","../../src/GridHybrid.tsx","../../src/styles.ts","../../src/utils.ts","../../src/GridTailwind.tsx","../../src/GridTypes.ts","../../src/index.ts"],"sourcesContent":["import React from \"react\";\nimport type { GridProps } from \"./GridTypes\";\nimport GridHybrid from \"./GridHybrid\";\n\n/**\n * Grid component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using a\n * styled() extension or styled-system props).\n */\nconst Grid: React.FC<GridProps> = (props) => <GridHybrid {...props} />;\n\nGrid.displayName = \"Grid\";\nexport default Grid;\n","/**\n * Hybrid Grid component.\n * Automatically chooses between the Tailwind implementation (preferred) and the\n * styled-components implementation. Grid never exposed styled-system props on its\n * public API, so the realistic styled-components trigger is a styled(Grid)\n * extension — routing on needsStyledComponents preserves that backward\n * compatibility (and any accidental styled-system prop spread).\n */\n\nimport React from \"react\";\nimport { needsStyledComponents } from \"@sproutsocial/seeds-react-system-props\";\nimport Container from \"./styles\"; // Styled-components version\nimport { GridTailwind } from \"./GridTailwind\"; // Tailwind version\nimport { toResponsiveGapObject } from \"./utils\";\nimport type { GridProps } from \"./GridTypes\";\n\nconst GridHybrid: React.FC<GridProps> = (props) => {\n const { columns = 1, gap = 400, rowGap, columnGap, children, className } =\n props;\n\n if (needsStyledComponents(props)) {\n return (\n <Container\n display=\"grid\"\n rowGap={toResponsiveGapObject(rowGap ?? gap)}\n columnGap={toResponsiveGapObject(columnGap ?? gap)}\n $columns={columns}\n className={className}\n >\n {children}\n </Container>\n );\n }\n\n // Use Tailwind version (preferred - better performance)\n return <GridTailwind {...props} />;\n};\n\nGridHybrid.displayName = \"Grid\";\nexport default GridHybrid;\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport type { ContainerProps } from \"./GridTypes\";\nimport { getResponsiveStyles } from \"./utils\";\n\nconst Container = styled(Box)<ContainerProps>`\n ${(props) => getResponsiveStyles(props.$columns)}\n`;\n\nexport default Container;\n","import type {\n GapValue,\n ResponsiveGapValue,\n ResponsiveValue,\n} from \"./GridTypes\";\nimport { css } from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nconst { breakpoints } = theme;\n\nexport const toResponsiveGapObject = (\n value: ResponsiveGapValue\n):\n | GapValue\n | { sm?: GapValue; md?: GapValue; lg?: GapValue; xl?: GapValue } => {\n if (typeof value !== \"object\") return value;\n return value;\n};\n\nexport const getResponsiveStyles = (columns: ResponsiveValue = 1) => {\n if (typeof columns === \"number\") {\n return css`\n grid-template-columns: repeat(${columns}, 1fr);\n `;\n }\n\n return css`\n grid-template-columns: repeat(1, 1fr);\n\n @media (min-width: ${breakpoints.sm}) {\n grid-template-columns: repeat(${columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.md}) {\n grid-template-columns: repeat(${columns.md || columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.lg}) {\n grid-template-columns: repeat(\n ${columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n\n @media (min-width: ${breakpoints.xl}) {\n grid-template-columns: repeat(\n ${columns.xl || columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n `;\n};\n","/**\n * Tailwind/CSS implementation of the Grid component.\n *\n * Dependency-free: renders a plain <div class=\"seeds-grid\"> and drives layout\n * with a mix of inline styles and CSS custom properties consumed by grid.css.\n *\n * jsdom-safe rule (mirrors Icon/Avatar/Skeleton):\n * - Scalar values (a number of columns, or a scalar gap) are written as literal\n * resolved inline styles (e.g. row-gap: 24px) so window.getComputedStyle sees\n * them in tests. Do NOT use var(--space-N) here — jsdom cannot resolve it.\n * - Responsive values (an object) are emitted as inline CSS custom properties;\n * the concrete property is set only by the media queries in grid.css so the\n * overrides are not blocked by inline specificity.\n */\n\nimport React from \"react\";\nimport type { GapValue, GridProps } from \"./GridTypes\";\n\n// Space scale → px, matching seeds-design-tokens/seeds-space/tokens.json and the\n// mapping Box's styled-system applies on the styled-components path.\nconst SPACE_SCALE: Record<number, number> = {\n 0: 0,\n 100: 2,\n 200: 4,\n 300: 8,\n 350: 12,\n 400: 16,\n 450: 24,\n 500: 32,\n 600: 40,\n};\n\n// Loose bag of CSS declarations + custom properties. Cast to React.CSSProperties\n// at the JSX site (same approach as IconTailwind), since custom properties are\n// not part of the CSSProperties type.\ntype GridStyle = Record<string, string>;\n\ntype ResponsiveGapObject = {\n sm?: GapValue;\n md?: GapValue;\n lg?: GapValue;\n xl?: GapValue;\n};\n\ntype ResponsiveColumnsObject = {\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n};\n\n// Resolve a scalar gap value to a concrete CSS length. Space-scale keys map to\n// px; pixel/arbitrary strings (\"20px\", \"1em\") pass through unchanged.\nconst toGap = (value: GapValue): string =>\n typeof value === \"number\" ? `${SPACE_SCALE[value] ?? 0}px` : value;\n\nconst isResponsive = (value: unknown): boolean =>\n typeof value === \"object\" && value !== null;\n\n// Set the responsive column custom properties, resolving the breakpoint cascade\n// in JS (md falls back to sm, lg to md/sm, xl to lg/md/sm) exactly like\n// getResponsiveStyles on the styled-components path.\nconst applyResponsiveColumns = (\n style: GridStyle,\n columns: ResponsiveColumnsObject\n): void => {\n const { sm, md, lg, xl } = columns;\n style[\"--sg-cols\"] = \"repeat(1, 1fr)\";\n style[\"--sg-cols-sm\"] = `repeat(${sm ?? 1}, 1fr)`;\n style[\"--sg-cols-md\"] = `repeat(${md ?? sm ?? 1}, 1fr)`;\n style[\"--sg-cols-lg\"] = `repeat(${lg ?? md ?? sm ?? 1}, 1fr)`;\n style[\"--sg-cols-xl\"] = `repeat(${xl ?? lg ?? md ?? sm ?? 1}, 1fr)`;\n};\n\n// Apply a single gap axis. Scalar → concrete inline property (jsdom-safe).\n// Responsive → custom properties only, driven by grid.css media queries.\nconst applyGap = (\n style: GridStyle,\n axis: \"row\" | \"column\",\n value: GapValue | ResponsiveGapObject\n): void => {\n const prefix = axis === \"row\" ? \"--sg-row-gap\" : \"--sg-col-gap\";\n\n if (isResponsive(value)) {\n const { sm, md, lg, xl } = value as ResponsiveGapObject;\n style[prefix] = \"0\";\n if (sm !== undefined) style[`${prefix}-sm`] = toGap(sm);\n const mdVal = md ?? sm;\n if (mdVal !== undefined) style[`${prefix}-md`] = toGap(mdVal);\n const lgVal = lg ?? md ?? sm;\n if (lgVal !== undefined) style[`${prefix}-lg`] = toGap(lgVal);\n const xlVal = xl ?? lg ?? md ?? sm;\n if (xlVal !== undefined) style[`${prefix}-xl`] = toGap(xlVal);\n return;\n }\n\n const resolved = toGap(value as GapValue);\n if (axis === \"row\") {\n style.rowGap = resolved;\n } else {\n style.columnGap = resolved;\n }\n};\n\nexport const GridTailwind: React.FC<GridProps> = ({\n columns = 1,\n gap = 400,\n rowGap,\n columnGap,\n children,\n className,\n}) => {\n const style: GridStyle = { display: \"grid\" };\n\n if (isResponsive(columns)) {\n applyResponsiveColumns(style, columns as ResponsiveColumnsObject);\n } else {\n style.gridTemplateColumns = `repeat(${columns as number}, 1fr)`;\n }\n\n applyGap(style, \"row\", rowGap ?? gap);\n applyGap(style, \"column\", columnGap ?? gap);\n\n const classes = [\"seeds-grid\", className].filter(Boolean).join(\" \");\n\n return (\n <div className={classes} style={style as React.CSSProperties}>\n {children}\n </div>\n );\n};\n\nGridTailwind.displayName = \"GridTailwind\";\n","import type { TypeSpace } from \"@sproutsocial/seeds-react-theme\";\nimport * as React from \"react\";\n\nexport type ResponsiveValue =\n | number\n | {\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n };\n\n/**\n * Gap value that can be either:\n * - A space scale value from the theme (0, 100, 200, 300, 350, 400, 450, 500, 600)\n * - A pixel string value (e.g., \"16px\", \"20px\")\n */\nexport type GapValue = keyof TypeSpace | (string & {});\n\n/**\n * Responsive gap value that can be either:\n * - A single GapValue applied at all breakpoints\n * - An object with optional breakpoint keys (sm, md, lg, xl) for responsive values\n */\nexport type ResponsiveGapValue =\n | GapValue\n | {\n sm?: GapValue;\n md?: GapValue;\n lg?: GapValue;\n xl?: GapValue;\n };\n\nexport interface ContainerProps {\n $columns?: ResponsiveValue;\n}\n\nexport interface GridProps {\n /** Number of columns (can be responsive) */\n columns?: ResponsiveValue;\n /** Gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n gap?: ResponsiveGapValue;\n /** Row gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n rowGap?: ResponsiveGapValue;\n /** Column gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n columnGap?: ResponsiveGapValue;\n /** Children elements to display in the grid */\n children?: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n","import Grid from \"./Grid\";\n\nexport default Grid;\nexport { Grid };\nexport * from \"./GridTypes\";\n"],"mappings":";AAAA,OAAkB;;;ACSlB,OAAkB;AAClB,SAAS,6BAA6B;;;ACVtC,OAAO,YAAY;AACnB,OAAO,SAAS;;;ACIhB,SAAS,WAAW;AACpB,SAAS,aAAa;AAEtB,IAAM,EAAE,YAAY,IAAI;AAEjB,IAAM,wBAAwB,CACnC,UAGoE;AACpE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAEO,IAAM,sBAAsB,CAAC,UAA2B,MAAM;AACnE,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,sCAC2B,OAAO;AAAA;AAAA,EAE3C;AAEA,SAAO;AAAA;AAAA;AAAA,yBAGgB,YAAY,EAAE;AAAA,sCACD,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,yBAG5B,YAAY,EAAE;AAAA,sCACD,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,yBAG1C,YAAY,EAAE;AAAA;AAAA,UAE7B,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,yBAK5B,YAAY,EAAE;AAAA;AAAA,UAE7B,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAKnE;;;AD9CA,IAAM,YAAY,OAAO,GAAG;AAAA,IACxB,CAAC,UAAU,oBAAoB,MAAM,QAAQ,CAAC;AAAA;AAGlD,IAAO,iBAAQ;;;AEMf,OAAkB;AA+Gd;AA1GJ,IAAM,cAAsC;AAAA,EAC1C,GAAG;AAAA,EACH,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAuBA,IAAM,QAAQ,CAAC,UACb,OAAO,UAAU,WAAW,GAAG,YAAY,KAAK,KAAK,CAAC,OAAO;AAE/D,IAAM,eAAe,CAAC,UACpB,OAAO,UAAU,YAAY,UAAU;AAKzC,IAAM,yBAAyB,CAC7B,OACA,YACS;AACT,QAAM,EAAE,IAAI,IAAI,IAAI,GAAG,IAAI;AAC3B,QAAM,WAAW,IAAI;AACrB,QAAM,cAAc,IAAI,UAAU,MAAM,CAAC;AACzC,QAAM,cAAc,IAAI,UAAU,MAAM,MAAM,CAAC;AAC/C,QAAM,cAAc,IAAI,UAAU,MAAM,MAAM,MAAM,CAAC;AACrD,QAAM,cAAc,IAAI,UAAU,MAAM,MAAM,MAAM,MAAM,CAAC;AAC7D;AAIA,IAAM,WAAW,CACf,OACA,MACA,UACS;AACT,QAAM,SAAS,SAAS,QAAQ,iBAAiB;AAEjD,MAAI,aAAa,KAAK,GAAG;AACvB,UAAM,EAAE,IAAI,IAAI,IAAI,GAAG,IAAI;AAC3B,UAAM,MAAM,IAAI;AAChB,QAAI,OAAO,OAAW,OAAM,GAAG,MAAM,KAAK,IAAI,MAAM,EAAE;AACtD,UAAM,QAAQ,MAAM;AACpB,QAAI,UAAU,OAAW,OAAM,GAAG,MAAM,KAAK,IAAI,MAAM,KAAK;AAC5D,UAAM,QAAQ,MAAM,MAAM;AAC1B,QAAI,UAAU,OAAW,OAAM,GAAG,MAAM,KAAK,IAAI,MAAM,KAAK;AAC5D,UAAM,QAAQ,MAAM,MAAM,MAAM;AAChC,QAAI,UAAU,OAAW,OAAM,GAAG,MAAM,KAAK,IAAI,MAAM,KAAK;AAC5D;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,KAAiB;AACxC,MAAI,SAAS,OAAO;AAClB,UAAM,SAAS;AAAA,EACjB,OAAO;AACL,UAAM,YAAY;AAAA,EACpB;AACF;AAEO,IAAM,eAAoC,CAAC;AAAA,EAChD,UAAU;AAAA,EACV,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,QAAmB,EAAE,SAAS,OAAO;AAE3C,MAAI,aAAa,OAAO,GAAG;AACzB,2BAAuB,OAAO,OAAkC;AAAA,EAClE,OAAO;AACL,UAAM,sBAAsB,UAAU,OAAiB;AAAA,EACzD;AAEA,WAAS,OAAO,OAAO,UAAU,GAAG;AACpC,WAAS,OAAO,UAAU,aAAa,GAAG;AAE1C,QAAM,UAAU,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAElE,SACE,oBAAC,SAAI,WAAW,SAAS,OACtB,UACH;AAEJ;AAEA,aAAa,cAAc;;;AH9GrB,gBAAAA,YAAA;AANN,IAAM,aAAkC,CAAC,UAAU;AACjD,QAAM,EAAE,UAAU,GAAG,MAAM,KAAK,QAAQ,WAAW,UAAU,UAAU,IACrE;AAEF,MAAI,sBAAsB,KAAK,GAAG;AAChC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,QAAQ,sBAAsB,UAAU,GAAG;AAAA,QAC3C,WAAW,sBAAsB,aAAa,GAAG;AAAA,QACjD,UAAU;AAAA,QACV;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,EAEJ;AAGA,SAAO,gBAAAA,KAAC,gBAAc,GAAG,OAAO;AAClC;AAEA,WAAW,cAAc;AACzB,IAAO,qBAAQ;;;AD9B8B,gBAAAC,YAAA;AAA7C,IAAM,OAA4B,CAAC,UAAU,gBAAAA,KAAC,sBAAY,GAAG,OAAO;AAEpE,KAAK,cAAc;AACnB,IAAO,eAAQ;;;AKXf,OAAuB;;;ACCvB,IAAO,gBAAQ;","names":["jsx","jsx"]}
package/dist/grid.css ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Seeds Grid component classes.
3
+ *
4
+ * Scalar column/gap values are applied inline by GridTailwind (jsdom-safe and
5
+ * they win over these rules). These rules provide sane defaults and drive the
6
+ * responsive cases: GridTailwind sets --sg-* custom properties per breakpoint
7
+ * and the media queries below promote them, resolving the sm -> md -> lg -> xl
8
+ * cascade. Breakpoints match @sproutsocial/seeds-react-theme
9
+ * (sm 640 / md 768 / lg 1024 / xl 1280).
10
+ *
11
+ * All rules are wrapped in `@layer components` so consumer Tailwind utilities
12
+ * (unlayered) win the cascade, matching button.css.
13
+ */
14
+
15
+ @layer components {
16
+ .seeds-grid {
17
+ display: grid;
18
+ grid-template-columns: var(--sg-cols, repeat(1, 1fr));
19
+ row-gap: var(--sg-row-gap, 0);
20
+ column-gap: var(--sg-col-gap, 0);
21
+ }
22
+
23
+ @media (min-width: 640px) {
24
+ .seeds-grid {
25
+ grid-template-columns: var(--sg-cols-sm, var(--sg-cols, repeat(1, 1fr)));
26
+ row-gap: var(--sg-row-gap-sm, var(--sg-row-gap, 0));
27
+ column-gap: var(--sg-col-gap-sm, var(--sg-col-gap, 0));
28
+ }
29
+ }
30
+
31
+ @media (min-width: 768px) {
32
+ .seeds-grid {
33
+ grid-template-columns: var(
34
+ --sg-cols-md,
35
+ var(--sg-cols-sm, var(--sg-cols, repeat(1, 1fr)))
36
+ );
37
+ row-gap: var(--sg-row-gap-md, var(--sg-row-gap-sm, var(--sg-row-gap, 0)));
38
+ column-gap: var(
39
+ --sg-col-gap-md,
40
+ var(--sg-col-gap-sm, var(--sg-col-gap, 0))
41
+ );
42
+ }
43
+ }
44
+
45
+ @media (min-width: 1024px) {
46
+ .seeds-grid {
47
+ grid-template-columns: var(
48
+ --sg-cols-lg,
49
+ var(--sg-cols-md, var(--sg-cols-sm, var(--sg-cols, repeat(1, 1fr))))
50
+ );
51
+ row-gap: var(
52
+ --sg-row-gap-lg,
53
+ var(--sg-row-gap-md, var(--sg-row-gap-sm, var(--sg-row-gap, 0)))
54
+ );
55
+ column-gap: var(
56
+ --sg-col-gap-lg,
57
+ var(--sg-col-gap-md, var(--sg-col-gap-sm, var(--sg-col-gap, 0)))
58
+ );
59
+ }
60
+ }
61
+
62
+ @media (min-width: 1280px) {
63
+ .seeds-grid {
64
+ grid-template-columns: var(
65
+ --sg-cols-xl,
66
+ var(
67
+ --sg-cols-lg,
68
+ var(--sg-cols-md, var(--sg-cols-sm, var(--sg-cols, repeat(1, 1fr))))
69
+ )
70
+ );
71
+ row-gap: var(
72
+ --sg-row-gap-xl,
73
+ var(
74
+ --sg-row-gap-lg,
75
+ var(--sg-row-gap-md, var(--sg-row-gap-sm, var(--sg-row-gap, 0)))
76
+ )
77
+ );
78
+ column-gap: var(
79
+ --sg-col-gap-xl,
80
+ var(
81
+ --sg-col-gap-lg,
82
+ var(--sg-col-gap-md, var(--sg-col-gap-sm, var(--sg-col-gap, 0)))
83
+ )
84
+ );
85
+ }
86
+ }
87
+ }
package/dist/index.d.mts CHANGED
@@ -43,6 +43,11 @@ interface GridProps {
43
43
  className?: string;
44
44
  }
45
45
 
46
+ /**
47
+ * Grid component. Automatically routes between the Tailwind implementation
48
+ * (preferred) and the styled-components implementation (for consumers using a
49
+ * styled() extension or styled-system props).
50
+ */
46
51
  declare const Grid: React__default.FC<GridProps>;
47
52
 
48
53
  export { type ContainerProps, type GapValue, Grid, type GridProps, type ResponsiveGapValue, type ResponsiveValue, Grid as default };
package/dist/index.d.ts CHANGED
@@ -43,6 +43,11 @@ interface GridProps {
43
43
  className?: string;
44
44
  }
45
45
 
46
+ /**
47
+ * Grid component. Automatically routes between the Tailwind implementation
48
+ * (preferred) and the styled-components implementation (for consumers using a
49
+ * styled() extension or styled-system props).
50
+ */
46
51
  declare const Grid: React__default.FC<GridProps>;
47
52
 
48
53
  export { type ContainerProps, type GapValue, Grid, type GridProps, type ResponsiveGapValue, type ResponsiveValue, Grid as default };
package/dist/index.js CHANGED
@@ -36,7 +36,13 @@ __export(index_exports, {
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/Grid.tsx
39
- var import_react = require("react");
39
+ var import_react3 = require("react");
40
+
41
+ // src/GridHybrid.tsx
42
+ var import_react2 = require("react");
43
+ var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
44
+
45
+ // src/styles.ts
40
46
  var import_styled_components2 = __toESM(require("styled-components"));
41
47
  var import_seeds_react_box = __toESM(require("@sproutsocial/seeds-react-box"));
42
48
 
@@ -81,12 +87,58 @@ var getResponsiveStyles = (columns = 1) => {
81
87
  `;
82
88
  };
83
89
 
84
- // src/Grid.tsx
85
- var import_jsx_runtime = require("react/jsx-runtime");
90
+ // src/styles.ts
86
91
  var Container = (0, import_styled_components2.default)(import_seeds_react_box.default)`
87
92
  ${(props) => getResponsiveStyles(props.$columns)}
88
93
  `;
89
- var Grid = ({
94
+ var styles_default = Container;
95
+
96
+ // src/GridTailwind.tsx
97
+ var import_react = require("react");
98
+ var import_jsx_runtime = require("react/jsx-runtime");
99
+ var SPACE_SCALE = {
100
+ 0: 0,
101
+ 100: 2,
102
+ 200: 4,
103
+ 300: 8,
104
+ 350: 12,
105
+ 400: 16,
106
+ 450: 24,
107
+ 500: 32,
108
+ 600: 40
109
+ };
110
+ var toGap = (value) => typeof value === "number" ? `${SPACE_SCALE[value] ?? 0}px` : value;
111
+ var isResponsive = (value) => typeof value === "object" && value !== null;
112
+ var applyResponsiveColumns = (style, columns) => {
113
+ const { sm, md, lg, xl } = columns;
114
+ style["--sg-cols"] = "repeat(1, 1fr)";
115
+ style["--sg-cols-sm"] = `repeat(${sm ?? 1}, 1fr)`;
116
+ style["--sg-cols-md"] = `repeat(${md ?? sm ?? 1}, 1fr)`;
117
+ style["--sg-cols-lg"] = `repeat(${lg ?? md ?? sm ?? 1}, 1fr)`;
118
+ style["--sg-cols-xl"] = `repeat(${xl ?? lg ?? md ?? sm ?? 1}, 1fr)`;
119
+ };
120
+ var applyGap = (style, axis, value) => {
121
+ const prefix = axis === "row" ? "--sg-row-gap" : "--sg-col-gap";
122
+ if (isResponsive(value)) {
123
+ const { sm, md, lg, xl } = value;
124
+ style[prefix] = "0";
125
+ if (sm !== void 0) style[`${prefix}-sm`] = toGap(sm);
126
+ const mdVal = md ?? sm;
127
+ if (mdVal !== void 0) style[`${prefix}-md`] = toGap(mdVal);
128
+ const lgVal = lg ?? md ?? sm;
129
+ if (lgVal !== void 0) style[`${prefix}-lg`] = toGap(lgVal);
130
+ const xlVal = xl ?? lg ?? md ?? sm;
131
+ if (xlVal !== void 0) style[`${prefix}-xl`] = toGap(xlVal);
132
+ return;
133
+ }
134
+ const resolved = toGap(value);
135
+ if (axis === "row") {
136
+ style.rowGap = resolved;
137
+ } else {
138
+ style.columnGap = resolved;
139
+ }
140
+ };
141
+ var GridTailwind = ({
90
142
  columns = 1,
91
143
  gap = 400,
92
144
  rowGap,
@@ -94,22 +146,49 @@ var Grid = ({
94
146
  children,
95
147
  className
96
148
  }) => {
97
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
98
- Container,
99
- {
100
- display: "grid",
101
- rowGap: toResponsiveGapObject(rowGap ?? gap),
102
- columnGap: toResponsiveGapObject(columnGap ?? gap),
103
- $columns: columns,
104
- className,
105
- children
106
- }
107
- );
149
+ const style = { display: "grid" };
150
+ if (isResponsive(columns)) {
151
+ applyResponsiveColumns(style, columns);
152
+ } else {
153
+ style.gridTemplateColumns = `repeat(${columns}, 1fr)`;
154
+ }
155
+ applyGap(style, "row", rowGap ?? gap);
156
+ applyGap(style, "column", columnGap ?? gap);
157
+ const classes = ["seeds-grid", className].filter(Boolean).join(" ");
158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: classes, style, children });
108
159
  };
160
+ GridTailwind.displayName = "GridTailwind";
161
+
162
+ // src/GridHybrid.tsx
163
+ var import_jsx_runtime2 = require("react/jsx-runtime");
164
+ var GridHybrid = (props) => {
165
+ const { columns = 1, gap = 400, rowGap, columnGap, children, className } = props;
166
+ if ((0, import_seeds_react_system_props.needsStyledComponents)(props)) {
167
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
168
+ styles_default,
169
+ {
170
+ display: "grid",
171
+ rowGap: toResponsiveGapObject(rowGap ?? gap),
172
+ columnGap: toResponsiveGapObject(columnGap ?? gap),
173
+ $columns: columns,
174
+ className,
175
+ children
176
+ }
177
+ );
178
+ }
179
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GridTailwind, { ...props });
180
+ };
181
+ GridHybrid.displayName = "Grid";
182
+ var GridHybrid_default = GridHybrid;
183
+
184
+ // src/Grid.tsx
185
+ var import_jsx_runtime3 = require("react/jsx-runtime");
186
+ var Grid = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GridHybrid_default, { ...props });
187
+ Grid.displayName = "Grid";
109
188
  var Grid_default = Grid;
110
189
 
111
190
  // src/GridTypes.ts
112
- var React2 = require("react");
191
+ var React4 = require("react");
113
192
 
114
193
  // src/index.ts
115
194
  var index_default = Grid_default;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Grid.tsx","../src/utils.ts","../src/GridTypes.ts"],"sourcesContent":["import Grid from \"./Grid\";\n\nexport default Grid;\nexport { Grid };\nexport * from \"./GridTypes\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport type { ContainerProps, GridProps } from \"./GridTypes\";\nimport { getResponsiveStyles, toResponsiveGapObject } from \"./utils\";\n\nconst Container = styled(Box)<ContainerProps>`\n ${(props) => getResponsiveStyles(props.$columns)}\n`;\n\nconst Grid: React.FC<GridProps> = ({\n columns = 1,\n gap = 400,\n rowGap,\n columnGap,\n children,\n className,\n}) => {\n return (\n <Container\n display=\"grid\"\n rowGap={toResponsiveGapObject(rowGap ?? gap)}\n columnGap={toResponsiveGapObject(columnGap ?? gap)}\n $columns={columns}\n className={className}\n >\n {children}\n </Container>\n );\n};\n\nexport default Grid;\n","import type {\n GapValue,\n ResponsiveGapValue,\n ResponsiveValue,\n} from \"./GridTypes\";\nimport { css } from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nconst { breakpoints } = theme;\n\nexport const toResponsiveGapObject = (\n value: ResponsiveGapValue\n):\n | GapValue\n | { sm?: GapValue; md?: GapValue; lg?: GapValue; xl?: GapValue } => {\n if (typeof value !== \"object\") return value;\n return value;\n};\n\nexport const getResponsiveStyles = (columns: ResponsiveValue = 1) => {\n if (typeof columns === \"number\") {\n return css`\n grid-template-columns: repeat(${columns}, 1fr);\n `;\n }\n\n return css`\n grid-template-columns: repeat(1, 1fr);\n\n @media (min-width: ${breakpoints.sm}) {\n grid-template-columns: repeat(${columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.md}) {\n grid-template-columns: repeat(${columns.md || columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.lg}) {\n grid-template-columns: repeat(\n ${columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n\n @media (min-width: ${breakpoints.xl}) {\n grid-template-columns: repeat(\n ${columns.xl || columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n `;\n};\n","import type { TypeSpace } from \"@sproutsocial/seeds-react-theme\";\nimport * as React from \"react\";\n\nexport type ResponsiveValue =\n | number\n | {\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n };\n\n/**\n * Gap value that can be either:\n * - A space scale value from the theme (0, 100, 200, 300, 350, 400, 450, 500, 600)\n * - A pixel string value (e.g., \"16px\", \"20px\")\n */\nexport type GapValue = keyof TypeSpace | (string & {});\n\n/**\n * Responsive gap value that can be either:\n * - A single GapValue applied at all breakpoints\n * - An object with optional breakpoint keys (sm, md, lg, xl) for responsive values\n */\nexport type ResponsiveGapValue =\n | GapValue\n | {\n sm?: GapValue;\n md?: GapValue;\n lg?: GapValue;\n xl?: GapValue;\n };\n\nexport interface ContainerProps {\n $columns?: ResponsiveValue;\n}\n\nexport interface GridProps {\n /** Number of columns (can be responsive) */\n columns?: ResponsiveValue;\n /** Gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n gap?: ResponsiveGapValue;\n /** Row gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n rowGap?: ResponsiveGapValue;\n /** Column gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n columnGap?: ResponsiveGapValue;\n /** Children elements to display in the grid */\n children?: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAkB;AAClB,IAAAA,4BAAmB;AACnB,6BAAgB;;;ACGhB,+BAAoB;AACpB,+BAAsB;AAEtB,IAAM,EAAE,YAAY,IAAI;AAEjB,IAAM,wBAAwB,CACnC,UAGoE;AACpE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAEO,IAAM,sBAAsB,CAAC,UAA2B,MAAM;AACnE,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,sCAC2B,OAAO;AAAA;AAAA,EAE3C;AAEA,SAAO;AAAA;AAAA;AAAA,yBAGgB,YAAY,EAAE;AAAA,sCACD,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,yBAG5B,YAAY,EAAE;AAAA,sCACD,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,yBAG1C,YAAY,EAAE;AAAA;AAAA,UAE7B,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,yBAK5B,YAAY,EAAE;AAAA;AAAA,UAE7B,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAKnE;;;ADhCI;AAbJ,IAAM,gBAAY,0BAAAC,SAAO,uBAAAC,OAAG;AAAA,IACxB,CAAC,UAAU,oBAAoB,MAAM,QAAQ,CAAC;AAAA;AAGlD,IAAM,OAA4B,CAAC;AAAA,EACjC,UAAU;AAAA,EACV,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,QAAQ,sBAAsB,UAAU,GAAG;AAAA,MAC3C,WAAW,sBAAsB,aAAa,GAAG;AAAA,MACjD,UAAU;AAAA,MACV;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,eAAQ;;;AE9Bf,IAAAC,SAAuB;;;AHCvB,IAAO,gBAAQ;","names":["import_styled_components","styled","Box","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Grid.tsx","../src/GridHybrid.tsx","../src/styles.ts","../src/utils.ts","../src/GridTailwind.tsx","../src/GridTypes.ts"],"sourcesContent":["import Grid from \"./Grid\";\n\nexport default Grid;\nexport { Grid };\nexport * from \"./GridTypes\";\n","import React from \"react\";\nimport type { GridProps } from \"./GridTypes\";\nimport GridHybrid from \"./GridHybrid\";\n\n/**\n * Grid component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using a\n * styled() extension or styled-system props).\n */\nconst Grid: React.FC<GridProps> = (props) => <GridHybrid {...props} />;\n\nGrid.displayName = \"Grid\";\nexport default Grid;\n","/**\n * Hybrid Grid component.\n * Automatically chooses between the Tailwind implementation (preferred) and the\n * styled-components implementation. Grid never exposed styled-system props on its\n * public API, so the realistic styled-components trigger is a styled(Grid)\n * extension — routing on needsStyledComponents preserves that backward\n * compatibility (and any accidental styled-system prop spread).\n */\n\nimport React from \"react\";\nimport { needsStyledComponents } from \"@sproutsocial/seeds-react-system-props\";\nimport Container from \"./styles\"; // Styled-components version\nimport { GridTailwind } from \"./GridTailwind\"; // Tailwind version\nimport { toResponsiveGapObject } from \"./utils\";\nimport type { GridProps } from \"./GridTypes\";\n\nconst GridHybrid: React.FC<GridProps> = (props) => {\n const { columns = 1, gap = 400, rowGap, columnGap, children, className } =\n props;\n\n if (needsStyledComponents(props)) {\n return (\n <Container\n display=\"grid\"\n rowGap={toResponsiveGapObject(rowGap ?? gap)}\n columnGap={toResponsiveGapObject(columnGap ?? gap)}\n $columns={columns}\n className={className}\n >\n {children}\n </Container>\n );\n }\n\n // Use Tailwind version (preferred - better performance)\n return <GridTailwind {...props} />;\n};\n\nGridHybrid.displayName = \"Grid\";\nexport default GridHybrid;\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport type { ContainerProps } from \"./GridTypes\";\nimport { getResponsiveStyles } from \"./utils\";\n\nconst Container = styled(Box)<ContainerProps>`\n ${(props) => getResponsiveStyles(props.$columns)}\n`;\n\nexport default Container;\n","import type {\n GapValue,\n ResponsiveGapValue,\n ResponsiveValue,\n} from \"./GridTypes\";\nimport { css } from \"styled-components\";\nimport { theme } from \"@sproutsocial/seeds-react-theme\";\n\nconst { breakpoints } = theme;\n\nexport const toResponsiveGapObject = (\n value: ResponsiveGapValue\n):\n | GapValue\n | { sm?: GapValue; md?: GapValue; lg?: GapValue; xl?: GapValue } => {\n if (typeof value !== \"object\") return value;\n return value;\n};\n\nexport const getResponsiveStyles = (columns: ResponsiveValue = 1) => {\n if (typeof columns === \"number\") {\n return css`\n grid-template-columns: repeat(${columns}, 1fr);\n `;\n }\n\n return css`\n grid-template-columns: repeat(1, 1fr);\n\n @media (min-width: ${breakpoints.sm}) {\n grid-template-columns: repeat(${columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.md}) {\n grid-template-columns: repeat(${columns.md || columns.sm || 1}, 1fr);\n }\n\n @media (min-width: ${breakpoints.lg}) {\n grid-template-columns: repeat(\n ${columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n\n @media (min-width: ${breakpoints.xl}) {\n grid-template-columns: repeat(\n ${columns.xl || columns.lg || columns.md || columns.sm || 1},\n 1fr\n );\n }\n `;\n};\n","/**\n * Tailwind/CSS implementation of the Grid component.\n *\n * Dependency-free: renders a plain <div class=\"seeds-grid\"> and drives layout\n * with a mix of inline styles and CSS custom properties consumed by grid.css.\n *\n * jsdom-safe rule (mirrors Icon/Avatar/Skeleton):\n * - Scalar values (a number of columns, or a scalar gap) are written as literal\n * resolved inline styles (e.g. row-gap: 24px) so window.getComputedStyle sees\n * them in tests. Do NOT use var(--space-N) here — jsdom cannot resolve it.\n * - Responsive values (an object) are emitted as inline CSS custom properties;\n * the concrete property is set only by the media queries in grid.css so the\n * overrides are not blocked by inline specificity.\n */\n\nimport React from \"react\";\nimport type { GapValue, GridProps } from \"./GridTypes\";\n\n// Space scale → px, matching seeds-design-tokens/seeds-space/tokens.json and the\n// mapping Box's styled-system applies on the styled-components path.\nconst SPACE_SCALE: Record<number, number> = {\n 0: 0,\n 100: 2,\n 200: 4,\n 300: 8,\n 350: 12,\n 400: 16,\n 450: 24,\n 500: 32,\n 600: 40,\n};\n\n// Loose bag of CSS declarations + custom properties. Cast to React.CSSProperties\n// at the JSX site (same approach as IconTailwind), since custom properties are\n// not part of the CSSProperties type.\ntype GridStyle = Record<string, string>;\n\ntype ResponsiveGapObject = {\n sm?: GapValue;\n md?: GapValue;\n lg?: GapValue;\n xl?: GapValue;\n};\n\ntype ResponsiveColumnsObject = {\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n};\n\n// Resolve a scalar gap value to a concrete CSS length. Space-scale keys map to\n// px; pixel/arbitrary strings (\"20px\", \"1em\") pass through unchanged.\nconst toGap = (value: GapValue): string =>\n typeof value === \"number\" ? `${SPACE_SCALE[value] ?? 0}px` : value;\n\nconst isResponsive = (value: unknown): boolean =>\n typeof value === \"object\" && value !== null;\n\n// Set the responsive column custom properties, resolving the breakpoint cascade\n// in JS (md falls back to sm, lg to md/sm, xl to lg/md/sm) exactly like\n// getResponsiveStyles on the styled-components path.\nconst applyResponsiveColumns = (\n style: GridStyle,\n columns: ResponsiveColumnsObject\n): void => {\n const { sm, md, lg, xl } = columns;\n style[\"--sg-cols\"] = \"repeat(1, 1fr)\";\n style[\"--sg-cols-sm\"] = `repeat(${sm ?? 1}, 1fr)`;\n style[\"--sg-cols-md\"] = `repeat(${md ?? sm ?? 1}, 1fr)`;\n style[\"--sg-cols-lg\"] = `repeat(${lg ?? md ?? sm ?? 1}, 1fr)`;\n style[\"--sg-cols-xl\"] = `repeat(${xl ?? lg ?? md ?? sm ?? 1}, 1fr)`;\n};\n\n// Apply a single gap axis. Scalar → concrete inline property (jsdom-safe).\n// Responsive → custom properties only, driven by grid.css media queries.\nconst applyGap = (\n style: GridStyle,\n axis: \"row\" | \"column\",\n value: GapValue | ResponsiveGapObject\n): void => {\n const prefix = axis === \"row\" ? \"--sg-row-gap\" : \"--sg-col-gap\";\n\n if (isResponsive(value)) {\n const { sm, md, lg, xl } = value as ResponsiveGapObject;\n style[prefix] = \"0\";\n if (sm !== undefined) style[`${prefix}-sm`] = toGap(sm);\n const mdVal = md ?? sm;\n if (mdVal !== undefined) style[`${prefix}-md`] = toGap(mdVal);\n const lgVal = lg ?? md ?? sm;\n if (lgVal !== undefined) style[`${prefix}-lg`] = toGap(lgVal);\n const xlVal = xl ?? lg ?? md ?? sm;\n if (xlVal !== undefined) style[`${prefix}-xl`] = toGap(xlVal);\n return;\n }\n\n const resolved = toGap(value as GapValue);\n if (axis === \"row\") {\n style.rowGap = resolved;\n } else {\n style.columnGap = resolved;\n }\n};\n\nexport const GridTailwind: React.FC<GridProps> = ({\n columns = 1,\n gap = 400,\n rowGap,\n columnGap,\n children,\n className,\n}) => {\n const style: GridStyle = { display: \"grid\" };\n\n if (isResponsive(columns)) {\n applyResponsiveColumns(style, columns as ResponsiveColumnsObject);\n } else {\n style.gridTemplateColumns = `repeat(${columns as number}, 1fr)`;\n }\n\n applyGap(style, \"row\", rowGap ?? gap);\n applyGap(style, \"column\", columnGap ?? gap);\n\n const classes = [\"seeds-grid\", className].filter(Boolean).join(\" \");\n\n return (\n <div className={classes} style={style as React.CSSProperties}>\n {children}\n </div>\n );\n};\n\nGridTailwind.displayName = \"GridTailwind\";\n","import type { TypeSpace } from \"@sproutsocial/seeds-react-theme\";\nimport * as React from \"react\";\n\nexport type ResponsiveValue =\n | number\n | {\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n };\n\n/**\n * Gap value that can be either:\n * - A space scale value from the theme (0, 100, 200, 300, 350, 400, 450, 500, 600)\n * - A pixel string value (e.g., \"16px\", \"20px\")\n */\nexport type GapValue = keyof TypeSpace | (string & {});\n\n/**\n * Responsive gap value that can be either:\n * - A single GapValue applied at all breakpoints\n * - An object with optional breakpoint keys (sm, md, lg, xl) for responsive values\n */\nexport type ResponsiveGapValue =\n | GapValue\n | {\n sm?: GapValue;\n md?: GapValue;\n lg?: GapValue;\n xl?: GapValue;\n };\n\nexport interface ContainerProps {\n $columns?: ResponsiveValue;\n}\n\nexport interface GridProps {\n /** Number of columns (can be responsive) */\n columns?: ResponsiveValue;\n /** Gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n gap?: ResponsiveGapValue;\n /** Row gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n rowGap?: ResponsiveGapValue;\n /** Column gap between grid items. Use theme.space scale (0, 100, 200, 300, 350, 400, 450, 500, 600), pixel string (e.g., \"16px\"), or responsive object (e.g., { sm: 400, md: 500 }) */\n columnGap?: ResponsiveGapValue;\n /** Children elements to display in the grid */\n children?: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n"],"mappings":"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","names":["import_react","import_react","import_styled_components","styled","Box","import_jsx_runtime","import_jsx_runtime","React"]}
package/package.json CHANGED
@@ -1,15 +1,26 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-grid",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "Seeds React Grid",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/esm/index.js",
9
9
  "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/esm/index.js",
16
+ "require": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ },
19
+ "./dist/grid.css": "./dist/grid.css"
20
+ },
10
21
  "scripts": {
11
- "build": "tsup --dts",
12
- "build:debug": "tsup --dts --metafile",
22
+ "build": "tsup --dts && cp src/grid.css dist/grid.css",
23
+ "build:debug": "tsup --dts --metafile && cp src/grid.css dist/grid.css",
13
24
  "dev": "tsup --watch --dts",
14
25
  "clean": "rm -rf .turbo dist",
15
26
  "clean:modules": "rm -rf node_modules",
package/.eslintignore DELETED
@@ -1,6 +0,0 @@
1
- # Node modules
2
- node_modules/
3
-
4
- # Build output
5
- dist/
6
- coverage/
package/.eslintrc.js DELETED
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- extends: ["eslint-config-seeds/racine"],
4
- };
@@ -1,21 +0,0 @@
1
- yarn run v1.22.22
2
- $ tsup --dts
3
- CLI Building entry: src/index.ts
4
- CLI Using tsconfig: tsconfig.json
5
- CLI tsup v8.5.0
6
- CLI Using tsup config: /home/runner/_work/seeds/seeds/seeds-react/seeds-react-grid/tsup.config.ts
7
- CLI Target: es2022
8
- CLI Cleaning output folder
9
- CJS Build start
10
- ESM Build start
11
- CJS dist/index.js 3.71 KB
12
- CJS dist/index.js.map 5.23 KB
13
- CJS ⚡️ Build success in 14ms
14
- ESM dist/esm/index.js 1.84 KB
15
- ESM dist/esm/index.js.map 5.11 KB
16
- ESM ⚡️ Build success in 14ms
17
- DTS Build start
18
- DTS ⚡️ Build success in 4418ms
19
- DTS dist/index.d.ts 1.86 KB
20
- DTS dist/index.d.mts 1.86 KB
21
- Done in 6.09s.