react-justified-layout-ts 1.1.3 → 1.1.5

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.
@@ -10,5 +10,5 @@ export interface TSJustifiedLayoutProps {
10
10
  children: any[];
11
11
  showWidows?: boolean;
12
12
  }
13
- declare const TSJustifiedLayout: React.MemoExoticComponent<({ children, layoutItems, itemSpacing, rowSpacing, showWidows, targetRowHeight, targetRowHeightTolerance, width }: TSJustifiedLayoutProps) => React.JSX.Element>;
13
+ declare function TSJustifiedLayout({ children, layoutItems, itemSpacing, rowSpacing, showWidows, targetRowHeight, targetRowHeightTolerance, width }: TSJustifiedLayoutProps): React.JSX.Element;
14
14
  export { TSJustifiedLayout };
@@ -25,71 +25,61 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.TSJustifiedLayout = void 0;
27
27
  const react_1 = __importStar(require("react"));
28
- const TSJustifiedLayout = (0, react_1.memo)(({ children, layoutItems, itemSpacing = 10, rowSpacing = 10, showWidows = true, targetRowHeight = 320, targetRowHeightTolerance = .25, width }) => {
28
+ function TSJustifiedLayout({ children, layoutItems, itemSpacing = 10, rowSpacing = 10, showWidows = true, targetRowHeight = 320, targetRowHeightTolerance = .25, width }) {
29
29
  const minAspectRatio = width / targetRowHeight * (1 - targetRowHeightTolerance);
30
30
  const maxAspectRatio = width / targetRowHeight * (1 + targetRowHeightTolerance);
31
+ const rows = [];
32
+ let rowBuffer = [];
31
33
  /**
32
- *
34
+ * Attempts to add an item to the current row buffer
33
35
  * @param value The new aspect ratio to be checked
34
36
  * @return If the buffer can accept the new value
35
37
  * */
36
38
  function addItem(value) {
37
39
  const newItems = rowBuffer.concat(value);
38
- const newAspectRatio = newItems.map(dimensions => dimensions).reduce((previousValue, currentValue) => previousValue + currentValue, 0);
39
- const rowWidthWithoutSpacing = width - (newItems.length - 1) * itemSpacing;
40
- const targetAspectRatio = rowWidthWithoutSpacing / targetRowHeight;
40
+ const newAspectRatio = newItems.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
41
+ const rowWidthMinusSpacing = width - (newItems.length - 1) * itemSpacing;
42
+ const targetAspectRatio = rowWidthMinusSpacing / targetRowHeight;
41
43
  // Row still has space
42
44
  if (newAspectRatio < minAspectRatio) {
43
45
  rowBuffer.push(value);
44
- return true;
45
46
  }
46
47
  // Row ran out of space, and the new item is larger than the max aspect ratio for the row
47
48
  else if (newAspectRatio > maxAspectRatio) {
48
49
  // Always accept if it's just 1 item
49
50
  if (rowBuffer.length === 0) {
50
51
  rowBuffer.push(value);
51
- rows.push({ items: rowBuffer, height: rowWidthWithoutSpacing / newAspectRatio });
52
+ rows.push({ items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio });
52
53
  rowBuffer = [];
53
- return true;
54
54
  }
55
55
  else {
56
56
  // Calculate width/aspect ratio for row before adding new item
57
57
  const previousRowWidthWithoutSpacing = width - (rowBuffer.length - 1) * itemSpacing;
58
- const previousAspectRatio = rowBuffer.map(dimensions => dimensions).reduce((previousValue, currentValue) => previousValue + currentValue, 0);
58
+ const previousAspectRatio = rowBuffer.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
59
59
  const previousTargetAspectRatio = previousRowWidthWithoutSpacing / targetRowHeight;
60
60
  // 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
61
61
  if (Math.abs(newAspectRatio - targetAspectRatio) > Math.abs(previousAspectRatio - previousTargetAspectRatio)) {
62
62
  rows.push({ items: rowBuffer, height: previousRowWidthWithoutSpacing / previousAspectRatio });
63
- rowBuffer = [];
64
- return false;
63
+ rowBuffer = [value];
65
64
  }
66
65
  // If the new aspect ratio is closer to the target aspect ratio, then insert item and push row buffer
67
66
  else {
68
67
  rowBuffer.push(value);
69
- rows.push({ items: rowBuffer, height: rowWidthWithoutSpacing / newAspectRatio });
68
+ rows.push({ items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio });
70
69
  rowBuffer = [];
71
- return true;
72
70
  }
73
71
  }
74
72
  }
75
73
  else {
76
74
  // New aspect ratio is within aspect ratio tolerance, so we finish off the row
77
75
  rowBuffer.push(value);
78
- rows.push({ items: rowBuffer, height: rowWidthWithoutSpacing / newAspectRatio });
76
+ rows.push({ items: rowBuffer, height: rowWidthMinusSpacing / newAspectRatio });
79
77
  rowBuffer = [];
80
- return true;
81
78
  }
82
79
  }
83
- const rows = [];
84
- let rowBuffer = [];
85
- layoutItems.forEach((value) => {
86
- const isItemSuccessfullyAdded = addItem(value);
87
- if (!isItemSuccessfullyAdded) {
88
- addItem(value);
89
- }
90
- });
80
+ layoutItems.forEach((value) => addItem(value));
91
81
  // Handle leftover content
92
- if (showWidows) {
82
+ if (showWidows && rowBuffer.length !== 0) {
93
83
  rows.push({ items: rowBuffer, height: rows.length === 0 ? targetRowHeight : rows[rows.length - 1].height });
94
84
  }
95
85
  let childNodeCounter = -1;
@@ -99,14 +89,15 @@ const TSJustifiedLayout = (0, react_1.memo)(({ children, layoutItems, itemSpacin
99
89
  */
100
90
  function renderChildren(isLast) {
101
91
  childNodeCounter++;
102
- return (0, react_1.cloneElement)(children[childNodeCounter], Object.assign(Object.assign({}, children[childNodeCounter].props), { style: Object.assign(Object.assign(Object.assign({}, children[childNodeCounter].props.style), { maxWidth: "100%" }), (isLast ? { maxHeight: "100%" } : {})) }));
92
+ return (0, react_1.cloneElement)(children[childNodeCounter], Object.assign(Object.assign({}, children[childNodeCounter].props), { style: Object.assign(Object.assign(Object.assign({}, children[childNodeCounter].props.style), { maxWidth: '100%' }), (isLast ? { maxHeight: '100%' } : {})) }));
103
93
  }
104
94
  return (react_1.default.createElement(react_1.default.Fragment, null,
95
+ react_1.default.createElement("div", { style: { width: "100%" } }),
105
96
  react_1.default.createElement("div", { style: { width: "100%" } }, rows.map((value, index, array) => {
106
97
  let isLastRow = index === array.length - 1 && showWidows;
107
98
  return react_1.default.createElement("div", { style: Object.assign({ display: "flex", flexDirection: "row", gap: itemSpacing, marginBottom: rowSpacing }, (isLastRow ? { height: value.height } : {})) }, value.items.map((aspectRatio) => {
108
99
  return react_1.default.createElement("div", { style: isLastRow ? { aspectRatio: aspectRatio } : { flex: aspectRatio } }, renderChildren(isLastRow));
109
100
  }));
110
101
  }))));
111
- });
102
+ }
112
103
  exports.TSJustifiedLayout = TSJustifiedLayout;
@@ -0,0 +1,3 @@
1
+ import { TSJustifiedLayoutProps } from "../components/TSJustifiedLayout/TSJustifiedLayout";
2
+ import React from "react";
3
+ export declare const ConfiguredJustifiedLayout: ({ layoutItems, rowSpacing, width, itemSpacing, targetRowHeight, targetRowHeightTolerance, showWidows, ...props }: TSJustifiedLayoutProps) => React.JSX.Element;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ConfiguredJustifiedLayout = void 0;
18
+ const TSJustifiedLayout_1 = require("../components/TSJustifiedLayout/TSJustifiedLayout");
19
+ const react_1 = __importDefault(require("react"));
20
+ const displayedImages = [
21
+ {
22
+ "title": "Castor Evolved",
23
+ "artist": "@TOOMIRO",
24
+ "tags": [
25
+ "Castor",
26
+ "Featured"
27
+ ],
28
+ "href": "https://x.com/FaintAlcor/status/1749579348045111636?s=20",
29
+ "published": "2024-01-22",
30
+ "aspectRatio": 1.48,
31
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/castor_evolved.webp",
32
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/castor_evolved.png",
33
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/castor_evolved.png"
34
+ },
35
+ {
36
+ "title": "Techwear Ninja v2",
37
+ "artist": "@edadrz",
38
+ "tags": [
39
+ "Rastaban Form",
40
+ "Techwear",
41
+ "Hibernal Assassin"
42
+ ],
43
+ "href": "https://x.com/edadrz2/status/1750189393833517203?s=20",
44
+ "published": "2024-01-24",
45
+ "aspectRatio": 0.7857142857142857,
46
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/techwear_ninja_v2.webp",
47
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/techwear_ninja_v2.png",
48
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/techwear_ninja_v2.png"
49
+ },
50
+ {
51
+ "title": "Glimmer on the Shore",
52
+ "artist": "@SiN_remyheart",
53
+ "tags": [
54
+ "Jupiter Form",
55
+ "Featured"
56
+ ],
57
+ "href": "https://x.com/SiN_remyheart/status/1750043825161244678?s=20",
58
+ "published": "2024-01-24",
59
+ "aspectRatio": 1.15625,
60
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/glimmer_on_the_shore.webp",
61
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/glimmer_on_the_shore.png",
62
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/glimmer_on_the_shore.png"
63
+ },
64
+ {
65
+ "title": "Farmer Sketch",
66
+ "artist": "@KuroPenguinEx",
67
+ "tags": [
68
+ "Aquarius Form"
69
+ ],
70
+ "href": "https://x.com/FaintAlcor/status/1751444972904063414?s=20",
71
+ "published": "2024-01-27",
72
+ "aspectRatio": 0.7069555302166477,
73
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/farmer_sketch.webp",
74
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/farmer_sketch.webp%7D",
75
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/farmer_sketch.png"
76
+ },
77
+ {
78
+ "parent": "Farmer Sketch",
79
+ "tags": [
80
+ "Aquarius Form"
81
+ ],
82
+ "href": "",
83
+ "aspectRatio": 0.7069555302166477,
84
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/farmer_sketch/0.webp",
85
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/farmer_sketch/0.webp",
86
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/farmer_sketch/0.png"
87
+ },
88
+ {
89
+ "title": "My Room",
90
+ "artist": "@ito_44_3",
91
+ "tags": [
92
+ "Thuban Form"
93
+ ],
94
+ "href": "https://x.com/ito_44_3/status/1759850276633419776?s=20",
95
+ "published": "2024-02-02",
96
+ "aspectRatio": 1.4166666666666667,
97
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/my_room.webp",
98
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/my_room.webp",
99
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/my_room.png"
100
+ },
101
+ {
102
+ "title": "Triangulum Combat Suit",
103
+ "artist": "@neumokun",
104
+ "tags": [
105
+ "Triangulum Form"
106
+ ],
107
+ "href": "https://bsky.app/profile/neumokun.bsky.social/post/3klncrgkl5z24",
108
+ "published": "2024-02-17",
109
+ "aspectRatio": 0.7501875468867217,
110
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/triangulum_combat_suit.webp",
111
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/triangulum_combat_suit.webp",
112
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/triangulum_combat_suit.png"
113
+ },
114
+ {
115
+ "tags": [
116
+ "Eclipse Deity"
117
+ ],
118
+ "href": "",
119
+ "aspectRatio": 0.8243310619910255,
120
+ "parent": "Eclipse Deity v3",
121
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/eclipse_deity_v3/0.webp",
122
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/eclipse_deity_v3/0.webp",
123
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/eclipse_deity_v3/0.png"
124
+ },
125
+ {
126
+ "title": "Biogenesis Suit Design",
127
+ "artist": "@EmberWickArt",
128
+ "tags": [
129
+ "Superhero",
130
+ "Bodysuit"
131
+ ],
132
+ "href": "https://x.com/EmberWickArt/status/1795127025331577256",
133
+ "published": "2024-05-27",
134
+ "aspectRatio": 1.0115606936416186,
135
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/biogenesis_suit_design.webp",
136
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/biogenesis_suit_design.webp",
137
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/biogenesis_suit_design.png"
138
+ },
139
+ {
140
+ "title": "Alan and Alcor",
141
+ "artist": "@kongzorim",
142
+ "tags": [
143
+ "Aldhibah Form",
144
+ "Rastaban Form",
145
+ "Standard Outfit"
146
+ ],
147
+ "href": "https://x.com/kongzorim/status/1795818089080385818",
148
+ "published": "2024-05-29",
149
+ "aspectRatio": 0.7056150600454398,
150
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/alan_and_alcor.webp",
151
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/alan_and_alcor.webp",
152
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/alan_and_alcor.png"
153
+ },
154
+ {
155
+ "tags": [
156
+ ""
157
+ ],
158
+ "href": "",
159
+ "aspectRatio": 1.7777777777777777,
160
+ "parent": "Proud Summer Beach YCH",
161
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/proud_summer_beach_ych/0.webp",
162
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/proud_summer_beach_ych/0.webp",
163
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/proud_summer_beach_ych/0.png"
164
+ },
165
+ {
166
+ "title": "Soma's Spring Outfit",
167
+ "artist": "@kaerukbin",
168
+ "tags": [
169
+ "Soma"
170
+ ],
171
+ "href": "https://skeb.jp/@kaerukbin/works/4",
172
+ "published": "2024-05-31",
173
+ "aspectRatio": 0.763189448441247,
174
+ "thumbnailUrl": "https://alcorsiteartbucket.s3.amazonaws.com/600h/soma_s_spring_outfit.webp",
175
+ "webp": "https://alcorsiteartbucket.s3.amazonaws.com/webp/soma_s_spring_outfit.webp",
176
+ "src": "https://alcorsiteartbucket.s3.amazonaws.com/soma_s_spring_outfit.png"
177
+ }
178
+ ];
179
+ const ConfiguredJustifiedLayout = (_a) => {
180
+ var { layoutItems = displayedImages.map(value => value.aspectRatio), rowSpacing = 8, width = 1000, itemSpacing = 8, targetRowHeight = 320, targetRowHeightTolerance = 0.10, showWidows = true } = _a, props = __rest(_a, ["layoutItems", "rowSpacing", "width", "itemSpacing", "targetRowHeight", "targetRowHeightTolerance", "showWidows"]);
181
+ return react_1.default.createElement(TSJustifiedLayout_1.TSJustifiedLayout, Object.assign({ layoutItems: displayedImages.map(value => value.aspectRatio), width: width, itemSpacing: itemSpacing, targetRowHeight: 320, targetRowHeightTolerance: targetRowHeightTolerance, rowSpacing: rowSpacing, showWidows: showWidows }, props), displayedImages.map(value => react_1.default.createElement("img", { alt: value.title, src: value.webp })));
182
+ };
183
+ exports.ConfiguredJustifiedLayout = ConfiguredJustifiedLayout;
@@ -0,0 +1,9 @@
1
+ /// <reference types="react" />
2
+ import type { StoryObj } from "@storybook/react";
3
+ declare const meta: {
4
+ title: string;
5
+ component: ({ layoutItems, rowSpacing, width, itemSpacing, targetRowHeight, targetRowHeightTolerance, showWidows, ...props }: import("../components/TSJustifiedLayout/TSJustifiedLayout").TSJustifiedLayoutProps) => import("react").JSX.Element;
6
+ };
7
+ export default meta;
8
+ type Story = StoryObj<typeof meta>;
9
+ export declare const Primary: Story;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Primary = void 0;
4
+ const ConfiguredJustifiedLayout_1 = require("./ConfiguredJustifiedLayout");
5
+ const meta = {
6
+ title: 'JustifiedLayout/Basic',
7
+ component: ConfiguredJustifiedLayout_1.ConfiguredJustifiedLayout,
8
+ };
9
+ exports.default = meta;
10
+ // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
11
+ exports.Primary = {
12
+ args: {
13
+ width: 847,
14
+ showWidows: true,
15
+ targetRowHeight: undefined,
16
+ rowSpacing: undefined,
17
+ itemSpacing: undefined,
18
+ layoutItems: [],
19
+ targetRowHeightTolerance: undefined,
20
+ children: []
21
+ },
22
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-justified-layout-ts",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "A component based off Flickr's justified layout that is compatible with Typescript",
5
5
  "main": "./dist/TSJustifiedLayout.js",
6
6
  "types": "./dist/TSJustifiedLayout.d.ts",
@@ -9,21 +9,39 @@
9
9
  ],
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
- "typescript": "tsc"
12
+ "typescript": "tsc",
13
+ "storybook": "storybook dev -p 6006",
14
+ "build-storybook": "storybook build"
13
15
  },
14
16
  "keywords": [],
15
17
  "author": "Alan19",
16
18
  "license": "MIT",
17
19
  "dependencies": {
18
- "@types/node": "^20.10.7"
20
+ "@types/node": "^20.10.7",
21
+ "react-use": "^17.5.0",
22
+ "react-use-measure": "^2.1.1"
19
23
  },
20
24
  "devDependencies": {
25
+ "@chromatic-com/storybook": "^1.5.0",
26
+ "@storybook/addon-essentials": "^8.1.5",
27
+ "@storybook/addon-interactions": "^8.1.5",
28
+ "@storybook/addon-links": "^8.1.5",
29
+ "@storybook/addon-onboarding": "^8.1.5",
30
+ "@storybook/addon-webpack5-compiler-swc": "^1.0.3",
31
+ "@storybook/blocks": "^8.1.5",
32
+ "@storybook/react": "^8.1.5",
33
+ "@storybook/react-webpack5": "^8.1.5",
34
+ "@storybook/test": "^8.1.5",
21
35
  "@types/react": "^18.2.47",
22
36
  "react": "^18.2.0",
37
+ "storybook": "^8.1.5",
23
38
  "typescript": "^5.3.3"
24
39
  },
25
40
  "peerDependencies": {
26
41
  "react": "^18.2.0"
27
42
  },
28
- "repository": "https://github.com/Alan19/react-justified-layout-ts"
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/Alan19/react-justified-layout-ts.git"
46
+ }
29
47
  }