react-justified-layout-ts 2.1.4 → 2.2.1

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.
Files changed (52) hide show
  1. package/.storybook/main.ts +12 -13
  2. package/.storybook/preview.ts +11 -4
  3. package/README.md +44 -44
  4. package/dist/components/layout.css +3 -3
  5. package/dist/src/components/JustifiedGrid.d.ts +13 -0
  6. package/dist/src/components/JustifiedGrid.js +59 -0
  7. package/dist/src/components/TSJustifiedLayout.d.ts +18 -0
  8. package/dist/src/components/TSJustifiedLayout.js +99 -0
  9. package/dist/src/index.d.ts +2 -0
  10. package/dist/src/index.js +7 -0
  11. package/dist/src/stories/ConfiguredJustifiedLayout.d.ts +3 -0
  12. package/dist/src/stories/ConfiguredJustifiedLayout.js +12 -0
  13. package/dist/src/stories/JustifiedLayout.stories.d.ts +13 -0
  14. package/dist/src/stories/JustifiedLayout.stories.js +202 -0
  15. package/dist/stories/JustifiedLayout.stories.d.ts +0 -1
  16. package/dist/stories/JustifiedLayout.stories.js +5 -6
  17. package/package.json +43 -49
  18. package/src/components/JustifiedGrid.d.ts +14 -0
  19. package/src/components/JustifiedGrid.d.ts.map +1 -0
  20. package/src/components/JustifiedGrid.js +63 -0
  21. package/src/components/JustifiedGrid.js.map +1 -0
  22. package/src/components/JustifiedGrid.tsx +79 -79
  23. package/src/components/TSJustifiedLayout.d.ts +19 -0
  24. package/src/components/TSJustifiedLayout.d.ts.map +1 -0
  25. package/src/components/TSJustifiedLayout.js +98 -0
  26. package/src/components/TSJustifiedLayout.js.map +1 -0
  27. package/src/components/TSJustifiedLayout.tsx +139 -139
  28. package/src/components/layout.css +3 -3
  29. package/src/declarations.d.ts +1 -0
  30. package/src/index.d.ts +4 -0
  31. package/src/index.d.ts.map +1 -0
  32. package/src/index.js +8 -0
  33. package/src/index.js.map +1 -0
  34. package/src/index.ts +3 -2
  35. package/src/stories/Configure.mdx +388 -364
  36. package/src/stories/ConfiguredJustifiedLayout.d.ts +3 -0
  37. package/src/stories/ConfiguredJustifiedLayout.d.ts.map +1 -0
  38. package/src/stories/ConfiguredJustifiedLayout.js +10 -0
  39. package/src/stories/ConfiguredJustifiedLayout.js.map +1 -0
  40. package/src/stories/ConfiguredJustifiedLayout.tsx +22 -22
  41. package/src/stories/JustifiedLayout.stories.d.ts +13 -0
  42. package/src/stories/JustifiedLayout.stories.d.ts.map +1 -0
  43. package/src/stories/JustifiedLayout.stories.js +197 -0
  44. package/src/stories/JustifiedLayout.stories.js.map +1 -0
  45. package/src/stories/JustifiedLayout.stories.tsx +204 -205
  46. package/src/stories/assets/accessibility.svg +1 -5
  47. package/src/stories/assets/discord.svg +1 -15
  48. package/src/stories/assets/github.svg +1 -3
  49. package/src/stories/assets/tutorials.svg +1 -12
  50. package/src/stories/assets/youtube.svg +1 -4
  51. package/tsconfig.json +44 -15
  52. package/LICENSE +0 -21
@@ -1,140 +1,140 @@
1
- import React from "react";
2
- import './layout.css'
3
-
4
- type ElementDimensions = number;
5
-
6
- export interface TSJustifiedLayoutProps {
7
- aspectRatioList: number[];
8
- itemSpacing?: number;
9
- rowSpacing?: number;
10
- targetRowHeight?: number;
11
- targetRowHeightTolerance?: number;
12
- width: number;
13
- children: React.JSX.Element[];
14
- showWidows?: boolean;
15
- containerStyle?: React.CSSProperties;
16
- // TODO Implement these
17
- // maxNumRows?: number;
18
- // fullWidthBreakoutRowCadence?: number
19
- // widowLayoutStyle: "left" | "justify" | "center"
20
- }
21
-
22
- /**
23
- * @deprecated Use the new {@link JustifiedGrid} component instead as it has better handling for heights of widow rows and future work will be done there
24
- */
25
- function TSJustifiedLayout({
26
- children,
27
- aspectRatioList,
28
- itemSpacing = 10,
29
- rowSpacing = 10,
30
- showWidows = true,
31
- targetRowHeight = 320,
32
- targetRowHeightTolerance = .25,
33
- width,
34
- containerStyle
35
- }: Readonly<TSJustifiedLayoutProps>) {
36
- const minAspectRatio = width / targetRowHeight * (1 - targetRowHeightTolerance);
37
- const maxAspectRatio = width / targetRowHeight * (1 + targetRowHeightTolerance);
38
-
39
- const rows: { items: ElementDimensions[]; height: number; }[] = [];
40
- let rowBuffer: ElementDimensions[] = [];
41
-
42
- /**
43
- * Attempts to add an item to the current row buffer
44
- * @param value The new aspect ratio to be checked
45
- * @return If the buffer can accept the new value
46
- * */
47
- function addItem(value: ElementDimensions) {
48
- const newItems = rowBuffer.concat(value)
49
- const newAspectRatio = newItems.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
50
- const rowWidthMinusSpacing = width - (newItems.length - 1) * itemSpacing;
51
- const targetAspectRatio = rowWidthMinusSpacing / targetRowHeight;
52
- // Row still has space
53
- if (newAspectRatio < minAspectRatio) {
54
- rowBuffer.push(value);
55
- }
56
- // Row ran out of space, and the new item is larger than the max aspect ratio for the row
57
- else if (newAspectRatio > maxAspectRatio) {
58
- // Always accept if it's just 1 item
59
- if (rowBuffer.length === 0) {
60
- rowBuffer.push(value);
61
- rows.push({items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio});
62
- rowBuffer = [];
63
- } else {
64
- // Calculate width/aspect ratio for row before adding new item
65
- const previousRowWidthWithoutSpacing = width - (rowBuffer.length - 1) * itemSpacing;
66
- const previousAspectRatio = rowBuffer.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
67
- const previousTargetAspectRatio = previousRowWidthWithoutSpacing / targetRowHeight;
68
- // If the new aspect ratio is farther from the target after the insert, then push row buffer and insert new item into the next row
69
- if (Math.abs(newAspectRatio - targetAspectRatio) > Math.abs(previousAspectRatio - previousTargetAspectRatio)) {
70
- rows.push({items: rowBuffer, height: previousRowWidthWithoutSpacing / previousAspectRatio})
71
- rowBuffer = [value]
72
- }
73
- // If the new aspect ratio is closer to the target aspect ratio, then insert item and push row buffer
74
- else {
75
- rowBuffer.push(value);
76
- rows.push({items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio})
77
- rowBuffer = []
78
- }
79
- }
80
- } else {
81
- // New aspect ratio is within aspect ratio tolerance, so we finish off the row
82
- rowBuffer.push(value);
83
- rows.push({items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio})
84
- rowBuffer = []
85
- }
86
- }
87
-
88
-
89
- aspectRatioList.forEach((value) => {
90
- addItem(value);
91
- })
92
-
93
- // Handle leftover content
94
- if (showWidows && rowBuffer.length !== 0) {
95
- rows.push({items: rowBuffer, height: rows.length === 0 ? targetRowHeight : rows[rows.length - 1].height})
96
- }
97
-
98
- let childNodeCounter = -1;
99
-
100
- /**
101
- * Clone the children element, and inject the height of the element as a prop
102
- */
103
- function renderRowItem(aspectRatio: ElementDimensions, isSoloRow: boolean, lastRowWithinTolerance: undefined | boolean, fakeElementAspectRatio: number) {
104
- childNodeCounter++;
105
- return <div style={{
106
- flex: isSoloRow ? 1 : aspectRatio,
107
- ...containerStyle
108
- }}>
109
- {children[childNodeCounter]}
110
- {/*Extra element for widowed rows to stop them from getting scaled up*/}
111
- {lastRowWithinTolerance && <div style={{flex: fakeElementAspectRatio}}/>}
112
- </div>
113
- }
114
-
115
- // TODO Figure out how to eliminate the tiny gap between div and actual image height
116
- // TODO Make bottom row respect length restrictions
117
- return (
118
- <div style={{
119
- display: 'flex',
120
- flexDirection: 'column',
121
- gap: rowSpacing
122
- }}>
123
- {rows.map((value, index, array) => {
124
- let isLastRow = index === array.length - 1 && showWidows;
125
- let rowAspectRatioSum = value.items.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
126
- const isLastRowWithinTolerance = isLastRow && rowAspectRatioSum * value.height + (value.items.length - 1) * itemSpacing < minAspectRatio * value.height;
127
- const fakeElementAspectRatio = (width - rowAspectRatioSum * value.height - (value.items.length - 1) * itemSpacing) / value.height;
128
- return <div className={'justified-row'} style={{
129
- display: "flex",
130
- flexDirection: "row",
131
- gap: itemSpacing,
132
- }}>
133
- {value.items.map((aspectRatio) => renderRowItem(aspectRatio, value.items.length === 1, isLastRowWithinTolerance, fakeElementAspectRatio))}
134
- </div>
135
- })}
136
- </div>
137
- );
138
- }
139
-
1
+ import React from "react";
2
+ import './layout.css'
3
+
4
+ type ElementDimensions = number;
5
+
6
+ export interface TSJustifiedLayoutProps {
7
+ aspectRatioList: number[];
8
+ itemSpacing?: number;
9
+ rowSpacing?: number;
10
+ targetRowHeight?: number;
11
+ targetRowHeightTolerance?: number;
12
+ width: number;
13
+ children: React.JSX.Element[];
14
+ showWidows?: boolean;
15
+ containerStyle?: React.CSSProperties;
16
+ // TODO Implement these
17
+ // maxNumRows?: number;
18
+ // fullWidthBreakoutRowCadence?: number
19
+ // widowLayoutStyle: "left" | "justify" | "center"
20
+ }
21
+
22
+ /**
23
+ * @deprecated Use the new {@link JustifiedGrid} component instead as it has better handling for heights of widow rows and future work will be done there
24
+ */
25
+ function TSJustifiedLayout({
26
+ children,
27
+ aspectRatioList,
28
+ itemSpacing = 10,
29
+ rowSpacing = 10,
30
+ showWidows = true,
31
+ targetRowHeight = 320,
32
+ targetRowHeightTolerance = .25,
33
+ width,
34
+ containerStyle
35
+ }: Readonly<TSJustifiedLayoutProps>) {
36
+ const minAspectRatio = width / targetRowHeight * (1 - targetRowHeightTolerance);
37
+ const maxAspectRatio = width / targetRowHeight * (1 + targetRowHeightTolerance);
38
+
39
+ const rows: { items: ElementDimensions[]; height: number; }[] = [];
40
+ let rowBuffer: ElementDimensions[] = [];
41
+
42
+ /**
43
+ * Attempts to add an item to the current row buffer
44
+ * @param value The new aspect ratio to be checked
45
+ * @return If the buffer can accept the new value
46
+ * */
47
+ function addItem(value: ElementDimensions) {
48
+ const newItems = rowBuffer.concat(value)
49
+ const newAspectRatio = newItems.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
50
+ const rowWidthMinusSpacing = width - (newItems.length - 1) * itemSpacing;
51
+ const targetAspectRatio = rowWidthMinusSpacing / targetRowHeight;
52
+ // Row still has space
53
+ if (newAspectRatio < minAspectRatio) {
54
+ rowBuffer.push(value);
55
+ }
56
+ // Row ran out of space, and the new item is larger than the max aspect ratio for the row
57
+ else if (newAspectRatio > maxAspectRatio) {
58
+ // Always accept if it's just 1 item
59
+ if (rowBuffer.length === 0) {
60
+ rowBuffer.push(value);
61
+ rows.push({items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio});
62
+ rowBuffer = [];
63
+ } else {
64
+ // Calculate width/aspect ratio for row before adding new item
65
+ const previousRowWidthWithoutSpacing = width - (rowBuffer.length - 1) * itemSpacing;
66
+ const previousAspectRatio = rowBuffer.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
67
+ const previousTargetAspectRatio = previousRowWidthWithoutSpacing / targetRowHeight;
68
+ // If the new aspect ratio is farther from the target after the insert, then push row buffer and insert new item into the next row
69
+ if (Math.abs(newAspectRatio - targetAspectRatio) > Math.abs(previousAspectRatio - previousTargetAspectRatio)) {
70
+ rows.push({items: rowBuffer, height: previousRowWidthWithoutSpacing / previousAspectRatio})
71
+ rowBuffer = [value]
72
+ }
73
+ // If the new aspect ratio is closer to the target aspect ratio, then insert item and push row buffer
74
+ else {
75
+ rowBuffer.push(value);
76
+ rows.push({items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio})
77
+ rowBuffer = []
78
+ }
79
+ }
80
+ } else {
81
+ // New aspect ratio is within aspect ratio tolerance, so we finish off the row
82
+ rowBuffer.push(value);
83
+ rows.push({items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio})
84
+ rowBuffer = []
85
+ }
86
+ }
87
+
88
+
89
+ aspectRatioList.forEach((value) => {
90
+ addItem(value);
91
+ })
92
+
93
+ // Handle leftover content
94
+ if (showWidows && rowBuffer.length !== 0) {
95
+ rows.push({items: rowBuffer, height: rows.length === 0 ? targetRowHeight : rows.at(-1)?.height as number})
96
+ }
97
+
98
+ let childNodeCounter = -1;
99
+
100
+ /**
101
+ * Clone the children element, and inject the height of the element as a prop
102
+ */
103
+ function renderRowItem(aspectRatio: ElementDimensions, isSoloRow: boolean, lastRowWithinTolerance: undefined | boolean, fakeElementAspectRatio: number) {
104
+ childNodeCounter++;
105
+ return <div style={{
106
+ flex: isSoloRow ? 1 : aspectRatio,
107
+ ...containerStyle
108
+ }}>
109
+ {children[childNodeCounter]}
110
+ {/*Extra element for widowed rows to stop them from getting scaled up*/}
111
+ {lastRowWithinTolerance && <div style={{flex: fakeElementAspectRatio}}/>}
112
+ </div>
113
+ }
114
+
115
+ // TODO Figure out how to eliminate the tiny gap between div and actual image height
116
+ // TODO Make bottom row respect length restrictions
117
+ return (
118
+ <div style={{
119
+ display: 'flex',
120
+ flexDirection: 'column',
121
+ gap: rowSpacing
122
+ }}>
123
+ {rows.map((value, index, array) => {
124
+ let isLastRow = index === array.length - 1 && showWidows;
125
+ let rowAspectRatioSum = value.items.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
126
+ const isLastRowWithinTolerance = isLastRow && rowAspectRatioSum * value.height + (value.items.length - 1) * itemSpacing < minAspectRatio * value.height;
127
+ const fakeElementAspectRatio = (width - rowAspectRatioSum * value.height - (value.items.length - 1) * itemSpacing) / value.height;
128
+ return <div className={'justified-row'} style={{
129
+ display: "flex",
130
+ flexDirection: "row",
131
+ gap: itemSpacing,
132
+ }}>
133
+ {value.items.map((aspectRatio) => renderRowItem(aspectRatio, value.items.length === 1, isLastRowWithinTolerance, fakeElementAspectRatio))}
134
+ </div>
135
+ })}
136
+ </div>
137
+ );
138
+ }
139
+
140
140
  export {TSJustifiedLayout, TSJustifiedLayout as JustifiedGrid}
@@ -1,4 +1,4 @@
1
- .justified-row img {
2
- width: 100%;
3
- display: block;
1
+ .justified-row img {
2
+ width: 100%;
3
+ display: block;
4
4
  }
@@ -0,0 +1 @@
1
+ declare module '*.css';
package/src/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { TSJustifiedLayout } from "./components/TSJustifiedLayout";
2
+ export { JustifiedGrid } from "./components/JustifiedGrid";
3
+ export type { JustifiedGridProps } from "./components/JustifiedGrid";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAA;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA"}
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JustifiedGrid = exports.TSJustifiedLayout = void 0;
4
+ var TSJustifiedLayout_1 = require("./components/TSJustifiedLayout");
5
+ Object.defineProperty(exports, "TSJustifiedLayout", { enumerable: true, get: function () { return TSJustifiedLayout_1.TSJustifiedLayout; } });
6
+ var JustifiedGrid_1 = require("./components/JustifiedGrid");
7
+ Object.defineProperty(exports, "JustifiedGrid", { enumerable: true, get: function () { return JustifiedGrid_1.JustifiedGrid; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,oEAAgE;AAAxD,sHAAA,iBAAiB,OAAA;AACzB,4DAAwD;AAAhD,8GAAA,aAAa,OAAA"}
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
- export {TSJustifiedLayout} from "./components/TSJustifiedLayout"
2
- export {JustifiedGridProps, JustifiedGrid} from "./components/JustifiedGrid"
1
+ export {TSJustifiedLayout} from "./components/TSJustifiedLayout"
2
+ export {JustifiedGrid} from "./components/JustifiedGrid"
3
+ export type { JustifiedGridProps } from "./components/JustifiedGrid"