react-editable-photo-grid 1.0.0

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/index.js ADDED
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var n={365:(n,t,e)=>{e.d(t,{A:()=>l});var o=e(601),r=e.n(o),a=e(314),i=e.n(a)()(r());i.push([n.id,".photogrid {\n padding: 0 0.125rem;\n}\n\n.photogrid--row__controls {\n display: block;\n position: absolute;\n left: 0.25rem;\n top: 50%;\n transform: translateY(-50%);\n z-index: 20;\n}\n\n.photogrid--row__controls > li {\n display: block;\n}\n\n.photogrid--photo__controls {\n display: block;\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n bottom: 0.5rem;\n text-align: center;\n}\n\n.photogrid--photo__controls > li {\n display: inline-block;\n}\n\n.photogrid--photo__controls > li + li {\n margin-left: 0.25rem;\n}\n\n.photogrid--photo__controls .photo__control, .photogrid--row__controls .row__control {\n width: 36px;\n height: 36px;\n display: block;\n background: #ddd;\n color: #333;\n font-size: 1.5rem;\n line-height: 2rem;\n}\n\n.photogrid--photo__row {\n display: block;\n background: transparent;\n min-height: 0;\n position: relative;\n z-index: 10;\n padding: 0;\n}\n\n.photogrid--photo__row.editing {\n padding-left: 2.75rem;\n}\n\n.photogrid--photo__column {\n position: relative;\n vertical-align: middle;\n display: block;\n margin: 0.125rem;\n}\n\n.photogrid--photo__column > img {\n display: block;\n max-width: 100%;\n max-height: 700px;\n height: auto;\n margin: 0;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n@media only screen and (min-width: 768px) {\n .photogrid--photo__row {\n display: flex;\n flex: 1 1 auto;\n }\n\n .photogrid--photo__column > img {\n display: inline-block;\n }\n}\n\n",""]);const l=i},314:n=>{n.exports=function(n){var t=[];return t.toString=function(){return this.map((function(t){var e="",o=void 0!==t[5];return t[4]&&(e+="@supports (".concat(t[4],") {")),t[2]&&(e+="@media ".concat(t[2]," {")),o&&(e+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),e+=n(t),o&&(e+="}"),t[2]&&(e+="}"),t[4]&&(e+="}"),e})).join("")},t.i=function(n,e,o,r,a){"string"==typeof n&&(n=[[null,n,void 0]]);var i={};if(o)for(var l=0;l<this.length;l++){var c=this[l][0];null!=c&&(i[c]=!0)}for(var u=0;u<n.length;u++){var s=[].concat(n[u]);o&&i[s[0]]||(void 0!==a&&(void 0===s[5]||(s[1]="@layer".concat(s[5].length>0?" ".concat(s[5]):""," {").concat(s[1],"}")),s[5]=a),e&&(s[2]?(s[1]="@media ".concat(s[2]," {").concat(s[1],"}"),s[2]=e):s[2]=e),r&&(s[4]?(s[1]="@supports (".concat(s[4],") {").concat(s[1],"}"),s[4]=r):s[4]="".concat(r)),t.push(s))}},t}},601:n=>{n.exports=function(n){return n[1]}},72:n=>{var t=[];function e(n){for(var e=-1,o=0;o<t.length;o++)if(t[o].identifier===n){e=o;break}return e}function o(n,o){for(var a={},i=[],l=0;l<n.length;l++){var c=n[l],u=o.base?c[0]+o.base:c[0],s=a[u]||0,p="".concat(u," ").concat(s);a[u]=s+1;var d=e(p),h={css:c[1],media:c[2],sourceMap:c[3],supports:c[4],layer:c[5]};if(-1!==d)t[d].references++,t[d].updater(h);else{var m=r(h,o);o.byIndex=l,t.splice(l,0,{identifier:p,updater:m,references:1})}i.push(p)}return i}function r(n,t){var e=t.domAPI(t);return e.update(n),function(t){if(t){if(t.css===n.css&&t.media===n.media&&t.sourceMap===n.sourceMap&&t.supports===n.supports&&t.layer===n.layer)return;e.update(n=t)}else e.remove()}}n.exports=function(n,r){var a=o(n=n||[],r=r||{});return function(n){n=n||[];for(var i=0;i<a.length;i++){var l=e(a[i]);t[l].references--}for(var c=o(n,r),u=0;u<a.length;u++){var s=e(a[u]);0===t[s].references&&(t[s].updater(),t.splice(s,1))}a=c}}},659:n=>{var t={};n.exports=function(n,e){var o=function(n){if(void 0===t[n]){var e=document.querySelector(n);if(window.HTMLIFrameElement&&e instanceof window.HTMLIFrameElement)try{e=e.contentDocument.head}catch(n){e=null}t[n]=e}return t[n]}(n);if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(e)}},540:n=>{n.exports=function(n){var t=document.createElement("style");return n.setAttributes(t,n.attributes),n.insert(t,n.options),t}},56:(n,t,e)=>{n.exports=function(n){var t=e.nc;t&&n.setAttribute("nonce",t)}},825:n=>{n.exports=function(n){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=n.insertStyleElement(n);return{update:function(e){!function(n,t,e){var o="";e.supports&&(o+="@supports (".concat(e.supports,") {")),e.media&&(o+="@media ".concat(e.media," {"));var r=void 0!==e.layer;r&&(o+="@layer".concat(e.layer.length>0?" ".concat(e.layer):""," {")),o+=e.css,r&&(o+="}"),e.media&&(o+="}"),e.supports&&(o+="}");var a=e.sourceMap;a&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),t.styleTagTransform(o,n,t.options)}(t,n,e)},remove:function(){!function(n){if(null===n.parentNode)return!1;n.parentNode.removeChild(n)}(t)}}}},113:n=>{n.exports=function(n,t){if(t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}}},t={};function e(o){var r=t[o];if(void 0!==r)return r.exports;var a=t[o]={id:o,exports:{}};return n[o](a,a.exports,e),a.exports}e.n=n=>{var t=n&&n.__esModule?()=>n.default:()=>n;return e.d(t,{a:t}),t},e.d=(n,t)=>{for(var o in t)e.o(t,o)&&!e.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:t[o]})},e.o=(n,t)=>Object.prototype.hasOwnProperty.call(n,t),e.r=n=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},e.nc=void 0;var o={};e.r(o),e.d(o,{PhotoGrid:()=>j});const r=require("react");var a=e.n(r),i=function(){return i=Object.assign||function(n){for(var t,e=1,o=arguments.length;e<o;e++)for(var r in t=arguments[e])Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n},i.apply(this,arguments)},l=function(n){return n.sort((function(n,t){return Math.floor(n.column)-Math.floor(t.column)}))},c=function(n,t){var e=n.find((function(n){return n.id===t}));if(void 0===e)throw new TypeError("No photo was found in this row for that id");return e},u=function(n,t){var e=n.find((function(n){return n.column===t}));if(void 0===e)throw new TypeError("No photo was found in this row for that column");return e},s=function(n,t){return n.filter((function(n){return n.column!==t}))},p=function(n,t,e){return void 0===n&&(n=[]),t.column=e,n.push(t),n},d=function(n,t,e){var o=t.column,r=e.column;return n=s(n,o),n=s(n,r),n=p(n,t,r),p(n,e,o)},h=function(n){return"string"==typeof n&&(n=parseInt(n)),n},m=function(n){var t=n.currentTarget,e=t.dataset.id,o=t.dataset.row;if(!e||!o)throw new TypeError("id or row key missing from photo control");return{id:e,rowKey:parseInt(o)}},f=function(n,t,e){for(var o=t;o<=e;o++){var r=u(n,o);n=s(n,o),n=p(n,r,r.column-1)}return n},v=function(n,t,e,o,r){return delete n[r],delete n[e],n[r]=t,n[e]=o,n},w=e(72),g=e.n(w),y=e(825),_=e.n(y),b=e(659),E=e.n(b),C=e(56),k=e.n(C),x=e(540),T=e.n(x),K=e(113),N=e.n(K),P=e(365),M={};M.styleTagTransform=N(),M.setAttributes=k(),M.insert=E().bind(null,"head"),M.domAPI=_(),M.insertStyleElement=T(),g()(P.A,M),P.A&&P.A.locals&&P.A.locals;const R=function(n){return a().createElement("ul",{className:"photogrid--row__controls"},h(n.rowKey)>1&&a().createElement("li",null,a().createElement("button",{className:"row__control",onClick:n.moveRowUp,"data-row":n.rowKey},"↑")),h(n.rowKey)<n.rowCount&&a().createElement("li",null,a().createElement("button",{className:"row__control",onClick:n.moveRowDown,"data-row":n.rowKey},"↓")))},O=function(n){return a().createElement("ul",{className:"photogrid--photo__controls"},n.photo.column>1&&a().createElement("li",null,a().createElement("button",{type:"button",className:"photo__control",onClick:n.movePhotoLeft,"data-id":n.photo.id,"data-row":n.rowKey},"←")),h(n.rowKey)>1&&a().createElement("li",null,a().createElement("button",{type:"button",className:"photo__control",onClick:n.movePhotoUp,"data-id":n.photo.id,"data-row":n.rowKey},"↑")),h(n.rowKey)<n.rowCount||h(n.rowKey)===n.rowCount&&n.photoCount>1?a().createElement("li",null,a().createElement("button",{type:"button",className:"photo__control",onClick:n.movePhotoDown,"data-id":n.photo.id,"data-row":n.rowKey},"↓")):null,n.photo.column<n.photoCount&&a().createElement("li",null,a().createElement("button",{type:"button",className:"photo__control",onClick:n.movePhotoRight,"data-id":n.photo.id,"data-row":n.rowKey},"→")))},j=function(n){var t=function(t){!function(n,t){n.preventDefault();var e=m(n),o=e.id,r=e.rowKey,a=i({},t.rows),u=l(a[r]),d=r-1,h=[];null!=a[d]&&(h=l(a[d]));var v=c(u,o),w=v.column+1,g=u.length;u=s(u,v.column),delete a[r],u.length&&(f(u,w,g),a[r]=u),h=p(h,v,h.length+1),delete a[d],a[d]=h,t.updateRows(a),t.increaseChanges()}(t,n)},e=function(t){!function(n,t){n.preventDefault();var e=m(n),o=e.id,r=e.rowKey,a=i({},t.rows),d=l(a[r]),h=r+1,v=c(d,o),w=v.column+1,g=d.length;d=s(d,v.column),delete a[r],d.length&&(d=f(d,w,g));var y=null;null==a[h]?(v.column=1,y=[v]):(y=function(n,t){for(var e=t;e>0;e--){var o=u(n,e);n=s(n,e),n=p(n,o,o.column+1)}return n}(y=l(a[h]),y.length),y=p(y,v,1),delete a[h]),a[h]=y,d.length&&(a[r]=d),t.updateRows(a),t.increaseChanges()}(t,n)},o=function(t){!function(n,t){n.preventDefault();var e=m(n),o=e.id,r=e.rowKey,a=i({},t.rows),s=l(a[r]),p=c(s,o);if(1!==p.column){var h=u(s,p.column-1);s=d(s,h,p),delete a[r],a[r]=s,t.updateRows(a),t.increaseChanges()}}(t,n)},h=function(t){!function(n,t){n.preventDefault();var e=m(n),o=e.id,r=e.rowKey,a=i({},t.rows),s=l(a[r]),p=c(s,o);if(p.column!==s.length){var h=u(s,p.column+1);s=d(s,p,h),delete a[r],a[r]=s,t.updateRows(a),t.increaseChanges()}}(t,n)},w=function(t){!function(n,t){n.preventDefault();var e=n.currentTarget.dataset.row;if(!e)throw new TypeError("row missing from row control");var o=parseInt(e),r=o-1,a=i({},t.rows),c=l(a[o]),u=l(a[r]);a=v(a,c,o,u,r),t.updateRows(a),t.increaseChanges()}(t,n)},g=function(t){!function(n,t){n.preventDefault();var e=n.currentTarget.dataset.row;if(!e)throw new TypeError("row missing from row control");var o=parseInt(e),r=o+1,a=i({},t.rows),c=l(a[o]),u=l(a[r]);a=v(a,c,o,u,r),t.updateRows(a),t.increaseChanges()}(t,n)};return 0===Object.keys(n.rows).length?null:a().createElement("div",{className:"photogrid"},Object.entries(n.rows).map((function(i,c){return i[1].length&&a().createElement("div",{key:"row-"+c,className:n.isEditing?"photogrid--photo__row editing":"photogrid--photo__row"},a().createElement(a().Fragment,null,n.isEditing&&a().createElement(R,{rowKey:i[0],moveRowUp:w,moveRowDown:g,rowCount:Object.keys(n.rows).length}),l(i[1]).map((function(l,u){return a().createElement("div",{key:"photo-"+c+u,className:"photogrid--photo__column"},a().createElement("img",{width:l.width,height:l.height,"data-id":l.id,src:"/api/photos/"+l.thumbnail_path,alt:l.thumbnail_path}),n.isEditing&&a().createElement(a().Fragment,null,n.photoMenu?(0,r.cloneElement)(n.photoMenu,{photo:l}):null,a().createElement(O,{rowKey:i[0],photo:l,movePhotoDown:e,movePhotoLeft:o,movePhotoUp:t,movePhotoRight:h,rowCount:Object.keys(n.rows).length,photoCount:i[1].length})))}))))})))};module.exports=o})();
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "react-editable-photo-grid",
3
+ "version": "1.0.0",
4
+ "description": "An editable photo grid built with React and Typescript",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "build": "webpack"
8
+ },
9
+ "peerDependencies": {
10
+ "@types/node": "^20.14.10",
11
+ "react": "^17.0.0 || ^18.0.0",
12
+ "react-dom": "^17.0.0 || ^18.0.0",
13
+ "typescript": "^5.5.3"
14
+ },
15
+ "devDependencies": {
16
+ "@babel/core": "^7.24.9",
17
+ "@babel/preset-env": "^7.24.8",
18
+ "@babel/preset-react": "^7.24.7",
19
+ "@babel/preset-typescript": "^7.24.7",
20
+ "babel-loader": "^9.1.3",
21
+ "css-loader": "^7.1.2",
22
+ "style-loader": "^4.0.0",
23
+ "ts-loader": "^9.5.1",
24
+ "typescript": "^5.5.3",
25
+ "webpack": "^5.93.0",
26
+ "webpack-cli": "^5.1.4"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+ssh://git@github.com/DominicHart/react-photo-grid.git"
31
+ },
32
+ "keywords": [
33
+ "photo",
34
+ "grid",
35
+ "react",
36
+ "typescript"
37
+ ],
38
+ "author": "Dominic Hart",
39
+ "license": "GPL-3.0",
40
+ "bugs": {
41
+ "url": "https://github.com/DominicHart/react-photo-grid/issues"
42
+ },
43
+ "homepage": "https://github.com/DominicHart/react-photo-grid#readme",
44
+ "dependencies": {
45
+ "@types/react": "^18.3.3",
46
+ "react": "^17.0.0 || ^18.0.0",
47
+ "react-dom": "^17.0.0 || ^18.0.0"
48
+ }
49
+ }
@@ -0,0 +1,94 @@
1
+ import React, { cloneElement } from 'react';
2
+ import { PhotoGridProps } from './types';
3
+ import { sortRow, movePhotoLeft, movePhotoUp, movePhotoDown, movePhotoRight, moveRowUp, moveRowDown } from "./utils";
4
+ import RowControls from './components/RowControls';
5
+ import PhotoControls from './components/PhotoControls';
6
+ import './styles.css';
7
+
8
+ const PhotoGrid = (props: PhotoGridProps) => {
9
+ const handleMovePhotoUp = (e: React.MouseEvent<HTMLButtonElement>) => {
10
+ movePhotoUp(e, props);
11
+ }
12
+
13
+ const handleMovePhotoDown = (e: React.MouseEvent<HTMLButtonElement>) => {
14
+ movePhotoDown(e, props);
15
+ }
16
+
17
+ const handleMovePhotoLeft = (e: React.MouseEvent<HTMLButtonElement>) => {
18
+ movePhotoLeft(e, props);
19
+ }
20
+
21
+ const handleMovePhotoRight = (e: React.MouseEvent<HTMLButtonElement>) => {
22
+ movePhotoRight(e, props);
23
+ }
24
+
25
+ const handleMoveRowUp = (e: React.MouseEvent<HTMLButtonElement>) => {
26
+ moveRowUp(e, props);
27
+ }
28
+
29
+ const handleMoveRowDown = (e: React.MouseEvent<HTMLButtonElement>) => {
30
+ moveRowDown(e, props);
31
+ }
32
+
33
+ if (Object.keys(props.rows).length === 0) {
34
+ return null;
35
+ }
36
+
37
+ return (
38
+ <div className="photogrid">
39
+ {Object.entries(props.rows).map((row, i) =>
40
+ row[1].length &&
41
+ <div
42
+ key={'row-' + i}
43
+ className={props.isEditing ? "photogrid--photo__row editing" : "photogrid--photo__row"}
44
+ >
45
+ <>
46
+ {props.isEditing &&
47
+ <RowControls
48
+ rowKey={row[0]}
49
+ moveRowUp={handleMoveRowUp}
50
+ moveRowDown={handleMoveRowDown}
51
+ rowCount={Object.keys(props.rows).length}
52
+ />
53
+ }
54
+ {sortRow(row[1]).map((photo, i2) =>
55
+ <div
56
+ key={'photo-' + i + i2}
57
+ className="photogrid--photo__column"
58
+ >
59
+ <img
60
+ width={photo.width}
61
+ height={photo.height}
62
+ data-id={photo.id}
63
+ src={"/api/photos/" + photo.thumbnail_path}
64
+ alt={photo.thumbnail_path}
65
+ />
66
+ {props.isEditing &&
67
+ <>
68
+ {props.photoMenu ?
69
+ cloneElement(props.photoMenu, {
70
+ photo: photo
71
+ })
72
+ : null}
73
+ <PhotoControls
74
+ rowKey={row[0]}
75
+ photo={photo}
76
+ movePhotoDown={handleMovePhotoDown}
77
+ movePhotoLeft={handleMovePhotoLeft}
78
+ movePhotoUp={handleMovePhotoUp}
79
+ movePhotoRight={handleMovePhotoRight}
80
+ rowCount={Object.keys(props.rows).length}
81
+ photoCount={row[1].length}
82
+ />
83
+ </>
84
+ }
85
+ </div>
86
+ )}
87
+ </>
88
+ </div>
89
+ )}
90
+ </div>
91
+ );
92
+ };
93
+
94
+ export default PhotoGrid;
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { PhotoControlsProps } from '../types';
3
+ import { castRowKey } from '../utils';
4
+ import'../styles.css';
5
+
6
+ const PhotoControls = (props: PhotoControlsProps) => {
7
+ return (
8
+ <ul className="photogrid--photo__controls">
9
+ {props.photo.column > 1 &&
10
+ <li>
11
+ <button
12
+ type="button"
13
+ className="photo__control"
14
+ onClick={props.movePhotoLeft}
15
+ data-id={props.photo.id}
16
+ data-row={props.rowKey}
17
+ >
18
+ &#8592;
19
+ </button>
20
+ </li>
21
+ }
22
+ {castRowKey(props.rowKey) > 1 &&
23
+ <li>
24
+ <button
25
+ type="button"
26
+ className="photo__control"
27
+ onClick={props.movePhotoUp}
28
+ data-id={props.photo.id}
29
+ data-row={props.rowKey}
30
+ >
31
+ &#8593;
32
+ </button>
33
+ </li>
34
+ }
35
+ {castRowKey(props.rowKey) < props.rowCount || castRowKey(props.rowKey) === props.rowCount && props.photoCount > 1 ?
36
+ <li>
37
+ <button
38
+ type="button"
39
+ className="photo__control"
40
+ onClick={props.movePhotoDown}
41
+ data-id={props.photo.id}
42
+ data-row={props.rowKey}
43
+ >
44
+ &#8595;
45
+ </button>
46
+ </li> : null
47
+ }
48
+ {props.photo.column < props.photoCount &&
49
+ <li>
50
+ <button
51
+ type="button"
52
+ className="photo__control"
53
+ onClick={props.movePhotoRight}
54
+ data-id={props.photo.id}
55
+ data-row={props.rowKey}
56
+ >
57
+ &#8594;
58
+ </button>
59
+ </li>
60
+ }
61
+ </ul>
62
+ );
63
+ };
64
+
65
+ export default PhotoControls;
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { RowControlsProps } from "../types";
3
+ import { castRowKey } from '../utils';
4
+ import'../styles.css';
5
+
6
+ const RowControls = (props: RowControlsProps) => {
7
+ return (
8
+ <ul className='photogrid--row__controls'>
9
+ {castRowKey(props.rowKey) > 1 &&
10
+ <li>
11
+ <button
12
+ className="row__control"
13
+ onClick={props.moveRowUp}
14
+ data-row={props.rowKey}
15
+ >
16
+ &#8593;
17
+ </button>
18
+ </li>
19
+ }
20
+ {castRowKey(props.rowKey) < props.rowCount &&
21
+ <li>
22
+ <button
23
+ className="row__control"
24
+ onClick={props.moveRowDown}
25
+ data-row={props.rowKey}
26
+ >
27
+ &#8595;
28
+ </button>
29
+ </li>
30
+ }
31
+ </ul>
32
+ );
33
+ };
34
+
35
+ export default RowControls;
package/src/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import PhotoGrid from './PhotoGrid';
2
+
3
+ export { PhotoGrid };
package/src/styles.css ADDED
@@ -0,0 +1,89 @@
1
+ .photogrid {
2
+ padding: 0 0.125rem;
3
+ }
4
+
5
+ .photogrid--row__controls {
6
+ display: block;
7
+ position: absolute;
8
+ left: 0.25rem;
9
+ top: 50%;
10
+ transform: translateY(-50%);
11
+ z-index: 20;
12
+ }
13
+
14
+ .photogrid--row__controls > li {
15
+ display: block;
16
+ }
17
+
18
+ .photogrid--photo__controls {
19
+ display: block;
20
+ position: absolute;
21
+ left: 50%;
22
+ transform: translateX(-50%);
23
+ bottom: 0.5rem;
24
+ text-align: center;
25
+ }
26
+
27
+ .photogrid--photo__controls > li {
28
+ display: inline-block;
29
+ }
30
+
31
+ .photogrid--photo__controls > li + li {
32
+ margin-left: 0.25rem;
33
+ }
34
+
35
+ .photogrid--photo__controls .photo__control, .photogrid--row__controls .row__control {
36
+ width: 36px;
37
+ height: 36px;
38
+ display: block;
39
+ background: #ddd;
40
+ color: #333;
41
+ font-size: 1.5rem;
42
+ line-height: 2rem;
43
+ }
44
+
45
+ .photogrid--photo__row {
46
+ display: block;
47
+ background: transparent;
48
+ min-height: 0;
49
+ position: relative;
50
+ z-index: 10;
51
+ padding: 0;
52
+ }
53
+
54
+ .photogrid--photo__row.editing {
55
+ padding-left: 2.75rem;
56
+ }
57
+
58
+ .photogrid--photo__column {
59
+ position: relative;
60
+ vertical-align: middle;
61
+ display: block;
62
+ margin: 0.125rem;
63
+ }
64
+
65
+ .photogrid--photo__column > img {
66
+ display: block;
67
+ max-width: 100%;
68
+ max-height: 700px;
69
+ height: auto;
70
+ margin: 0;
71
+ -webkit-touch-callout: none;
72
+ -webkit-user-select: none;
73
+ -khtml-user-select: none;
74
+ -moz-user-select: none;
75
+ -ms-user-select: none;
76
+ user-select: none;
77
+ }
78
+
79
+ @media only screen and (min-width: 768px) {
80
+ .photogrid--photo__row {
81
+ display: flex;
82
+ flex: 1 1 auto;
83
+ }
84
+
85
+ .photogrid--photo__column > img {
86
+ display: inline-block;
87
+ }
88
+ }
89
+
package/src/types.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { ReactElement } from "react";
2
+
3
+ export interface PhotoIdAndRowKey {
4
+ id: string;
5
+ rowKey: number;
6
+ }
7
+
8
+ export interface PhotoItem {
9
+ id: string;
10
+ column: number;
11
+ image_path: string;
12
+ thumbnail_path: string;
13
+ carousel_key: number;
14
+ width: number;
15
+ height: number;
16
+ }
17
+
18
+ export interface PhotoRows {
19
+ [key: number]: PhotoItem[];
20
+ }
21
+
22
+ export interface PhotoGridProps {
23
+ rows: PhotoRows;
24
+ updateRows: (rows: PhotoRows) => void;
25
+ changes: number;
26
+ increaseChanges: () => void;
27
+ isEditing: boolean;
28
+ selectedPhotos: Array<string>;
29
+ updateSelectedPhotos: (ids: Array<string>) => void;
30
+ photoMenu: ReactElement | undefined
31
+ }
32
+
33
+ export interface PhotoControlsProps {
34
+ rowKey: string | number;
35
+ photo: PhotoItem;
36
+ rowCount: number,
37
+ photoCount: number,
38
+ movePhotoLeft: (e: React.MouseEvent<HTMLButtonElement>) => void;
39
+ movePhotoUp: (e: React.MouseEvent<HTMLButtonElement>) => void;
40
+ movePhotoDown: (e: React.MouseEvent<HTMLButtonElement>) => void;
41
+ movePhotoRight: (e: React.MouseEvent<HTMLButtonElement>) => void;
42
+ }
43
+ export interface RowControlsProps {
44
+ rowKey: string | number;
45
+ moveRowUp: (e: React.MouseEvent<HTMLButtonElement>) => void;
46
+ moveRowDown: (e: React.MouseEvent<HTMLButtonElement>) => void;
47
+ rowCount: number
48
+ }