next-tinacms-cloudinary 4.3.0 → 4.3.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.
package/dist/handlers.js CHANGED
@@ -81,6 +81,7 @@ async function uploadMedia(req, res) {
81
81
  res.json(result);
82
82
  }
83
83
  async function listMedia(req, res, opts) {
84
+ var _a;
84
85
  try {
85
86
  const {
86
87
  directory = '""',
@@ -98,21 +99,35 @@ async function listMedia(req, res, opts) {
98
99
  return import_cloudinary.v2.api.sub_folders(directory2);
99
100
  }
100
101
  };
101
- let { folders } = await import_cloudinary.v2.api.folders(directory);
102
- folders = folders.map(function(folder) {
103
- "empty-repo/004";
104
- return {
105
- id: folder.path,
106
- type: "dir",
107
- filename: import_path.default.basename(folder.path),
108
- directory: import_path.default.dirname(folder.path)
109
- };
110
- });
102
+ let folders = [];
103
+ let folderRes = null;
104
+ try {
105
+ folderRes = await import_cloudinary.v2.api.folders(directory);
106
+ } catch (e) {
107
+ if ((_a = e.error) == null ? void 0 : _a.message.startsWith("Can't find folder with path")) {
108
+ } else {
109
+ console.error("Error getting folders");
110
+ console.error(e);
111
+ throw e;
112
+ }
113
+ }
114
+ if (folderRes == null ? void 0 : folderRes.folders) {
115
+ folders = folderRes.folders.map(function(folder) {
116
+ "empty-repo/004";
117
+ return {
118
+ id: folder.path,
119
+ type: "dir",
120
+ filename: import_path.default.basename(folder.path),
121
+ directory: import_path.default.dirname(folder.path)
122
+ };
123
+ });
124
+ }
111
125
  res.json({
112
126
  items: [...folders, ...files],
113
127
  offset: response.next_cursor
114
128
  });
115
129
  } catch (e) {
130
+ console.log(e);
116
131
  res.status(500);
117
132
  const message = findErrorMessage(e);
118
133
  res.json({ e: message });
package/dist/index.es.js CHANGED
@@ -52675,11 +52675,13 @@ const PopupModal = ({ className = "", style = {}, ...props }) => /* @__PURE__ */
52675
52675
  const ERROR_MISSING_CMS = `useCMS could not find an instance of CMS`;
52676
52676
  const CMSContext = react.exports.createContext(null);
52677
52677
  function useCMS$1() {
52678
- const cms = react.exports.useContext(CMSContext);
52678
+ const { cms, dispatch, state } = react.exports.useContext(CMSContext);
52679
52679
  if (!cms) {
52680
52680
  throw new Error(ERROR_MISSING_CMS);
52681
52681
  }
52682
52682
  const [, setEnabled] = react.exports.useState(cms.enabled);
52683
+ cms.dispatch = dispatch;
52684
+ cms.state = state;
52683
52685
  react.exports.useEffect(() => {
52684
52686
  return cms.events.subscribe("cms", () => {
52685
52687
  setEnabled(cms.enabled);
@@ -52739,7 +52741,8 @@ const Button = ({
52739
52741
  const roundedClasses = {
52740
52742
  full: `rounded-full`,
52741
52743
  left: `rounded-l-full`,
52742
- right: `rounded-r-full`
52744
+ right: `rounded-r-full`,
52745
+ custom: ""
52743
52746
  };
52744
52747
  const sizeClasses = {
52745
52748
  small: `text-xs h-8 px-3`,
@@ -52888,6 +52891,12 @@ function IconBase(props) {
52888
52891
  return elem(conf);
52889
52892
  }) : elem(DefaultContext);
52890
52893
  }
52894
+ function IoMdRefresh(props) {
52895
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 388c-72.597 0-132-59.405-132-132 0-72.601 59.403-132 132-132 36.3 0 69.299 15.4 92.406 39.601L278 234h154V80l-51.698 51.702C348.406 99.798 304.406 80 256 80c-96.797 0-176 79.203-176 176s78.094 176 176 176c81.045 0 148.287-54.134 169.401-128H378.85c-18.745 49.561-67.138 84-122.85 84z" } }] })(props);
52896
+ }
52897
+ function IoMdSync(props) {
52898
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 93.09V32l-80 81.454 80 81.456v-61.093c65.996 0 120 54.982 120 122.183 0 20.363-5 39.714-14.004 57.016L391 342.547c15.996-25.457 25-54.988 25-86.547 0-89.599-72.002-162.91-160-162.91zm0 285.094c-66.001 0-120-54.988-120-122.184 0-20.363 5-39.709 13.999-57.02L121 169.454C104.999 193.89 96 224.436 96 256c0 89.599 72.002 162.91 160 162.91V480l80-81.453-80-81.457v61.094z" } }] })(props);
52899
+ }
52891
52900
  function BiArrowToBottom(props) {
52892
52901
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M6 18h12v2H6zm5-14v8.586L6.707 8.293 5.293 9.707 12 16.414l6.707-6.707-1.414-1.414L13 12.586V4z" } }] })(props);
52893
52902
  }
@@ -52897,6 +52906,9 @@ function BiCloudUpload(props) {
52897
52906
  function BiCopyAlt(props) {
52898
52907
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M20 2H10c-1.103 0-2 .897-2 2v4H4c-1.103 0-2 .897-2 2v10c0 1.103.897 2 2 2h10c1.103 0 2-.897 2-2v-4h4c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zM4 20V10h10l.002 10H4zm16-6h-4v-4c0-1.103-.897-2-2-2h-4V4h10v10z" } }, { "tag": "path", "attr": { "d": "M6 12h6v2H6zm0 4h6v2H6z" } }] })(props);
52899
52908
  }
52909
+ function BiFileBlank(props) {
52910
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M19.937 8.68c-.011-.032-.02-.063-.033-.094a.997.997 0 0 0-.196-.293l-6-6a.997.997 0 0 0-.293-.196c-.03-.014-.062-.022-.094-.033a.991.991 0 0 0-.259-.051C13.04 2.011 13.021 2 13 2H6c-1.103 0-2 .897-2 2v16c0 1.103.897 2 2 2h12c1.103 0 2-.897 2-2V9c0-.021-.011-.04-.013-.062a.99.99 0 0 0-.05-.258zM16.586 8H14V5.414L16.586 8zM6 20V4h6v5a1 1 0 0 0 1 1h5l.002 10H6z" } }] })(props);
52911
+ }
52900
52912
  function BiFile(props) {
52901
52913
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M19.903 8.586a.997.997 0 0 0-.196-.293l-6-6a.997.997 0 0 0-.293-.196c-.03-.014-.062-.022-.094-.033a.991.991 0 0 0-.259-.051C13.04 2.011 13.021 2 13 2H6c-1.103 0-2 .897-2 2v16c0 1.103.897 2 2 2h12c1.103 0 2-.897 2-2V9c0-.021-.011-.04-.013-.062a.952.952 0 0 0-.051-.259c-.01-.032-.019-.063-.033-.093zM16.586 8H14V5.414L16.586 8zM6 20V4h6v5a1 1 0 0 0 1 1h5l.002 10H6z" } }, { "tag": "path", "attr": { "d": "M8 12h8v2H8zm0 4h8v2H8zm0-8h2v2H8z" } }] })(props);
52902
52914
  }
@@ -52918,9 +52930,6 @@ function BiRightArrowAlt(props) {
52918
52930
  function BiX(props) {
52919
52931
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "m16.192 6.344-4.243 4.242-4.242-4.242-1.414 1.414L10.535 12l-4.242 4.242 1.414 1.414 4.242-4.242 4.243 4.242 1.414-1.414L13.364 12l4.242-4.242z" } }] })(props);
52920
52932
  }
52921
- function IoMdSync(props) {
52922
- return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 93.09V32l-80 81.454 80 81.456v-61.093c65.996 0 120 54.982 120 122.183 0 20.363-5 39.714-14.004 57.016L391 342.547c15.996-25.457 25-54.988 25-86.547 0-89.599-72.002-162.91-160-162.91zm0 285.094c-66.001 0-120-54.988-120-122.184 0-20.363 5-39.709 13.999-57.02L121 169.454C104.999 193.89 96 224.436 96 256c0 89.599 72.002 162.91 160 162.91V480l80-81.453-80-81.457v61.094z" } }] })(props);
52923
- }
52924
52933
  React__default.createContext({
52925
52934
  rawMode: false,
52926
52935
  setRawMode: () => {
@@ -52945,9 +52954,33 @@ const createHTMLInlinePlugin = createPluginFactory({
52945
52954
  isVoid: true,
52946
52955
  isInline: true
52947
52956
  });
52957
+ const textFieldClasses = "shadow-inner focus:shadow-outline focus:border-blue-500 focus:outline-none block text-base placeholder:text-gray-300 px-3 py-2 text-gray-600 w-full bg-white border border-gray-200 transition-all ease-out duration-150 focus:text-gray-900 rounded-md";
52958
+ const disabledClasses = "opacity-50 pointer-events-none cursor-not-allowed";
52959
+ react.exports.forwardRef(({ className, disabled, ...rest }, ref) => {
52960
+ return /* @__PURE__ */ react.exports.createElement("input", {
52961
+ ref,
52962
+ type: "text",
52963
+ className: `${textFieldClasses} ${disabled ? disabledClasses : ""} ${className}`,
52964
+ ...rest
52965
+ });
52966
+ });
52967
+ react.exports.forwardRef(({ ...props }, ref) => {
52968
+ return /* @__PURE__ */ react.exports.createElement("textarea", {
52969
+ ...props,
52970
+ className: "shadow-inner text-base px-3 py-2 text-gray-600 resize-y focus:shadow-outline focus:border-blue-500 block w-full border border-gray-200 focus:text-gray-900 rounded-md",
52971
+ ref,
52972
+ style: { minHeight: "160px" }
52973
+ });
52974
+ });
52948
52975
  function MdOutlinePhotoLibrary(props) {
52949
52976
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M20 4v12H8V4h12m0-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 9.67l1.69 2.26 2.48-3.1L19 15H9zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z" } }] })(props);
52950
52977
  }
52978
+ const Input = ({ ...props }) => {
52979
+ return /* @__PURE__ */ react.exports.createElement("input", {
52980
+ className: textFieldClasses,
52981
+ ...props
52982
+ });
52983
+ };
52951
52984
  function useCMS() {
52952
52985
  return useCMS$1();
52953
52986
  }
@@ -52968,13 +53001,79 @@ const dropzoneAcceptFromString = (str) => {
52968
53001
  return Object.assign({}, ...(str || DEFAULT_MEDIA_UPLOAD_TYPES).split(",").map((x2) => ({ [x2]: [] })));
52969
53002
  };
52970
53003
  const isImage = (filename) => {
52971
- return /\.(gif|jpg|jpeg|tiff|png|svg|webp)(\?.*)?$/i.test(filename);
53004
+ return /\.(gif|jpg|jpeg|tiff|png|svg|webp|avif)(\?.*)?$/i.test(filename);
52972
53005
  };
52973
53006
  const absoluteImgURL = (str) => {
52974
53007
  if (str.startsWith("http"))
52975
53008
  return str;
52976
53009
  return `${window.location.origin}${str}`;
52977
53010
  };
53011
+ const StyledImage = ({ src }) => {
53012
+ const isSvg = /\.svg$/.test(src);
53013
+ return /* @__PURE__ */ react.exports.createElement("img", {
53014
+ src,
53015
+ className: `"block max-w-full rounded shadow overflow-hidden max-h-48 h-auto object-contain transition-opacity duration-100 ease-out m-0 bg-gray-200 bg-auto bg-center bg-no-repeat ${isSvg ? "min-w-[12rem]" : ""}`
53016
+ });
53017
+ };
53018
+ const StyledFile = ({ src }) => {
53019
+ return /* @__PURE__ */ react.exports.createElement("div", {
53020
+ className: "max-w-full w-full overflow-hidden flex-1 flex justify-start items-center gap-3"
53021
+ }, /* @__PURE__ */ react.exports.createElement("div", {
53022
+ className: "w-14 h-14 bg-gray-50 shadow border border-gray-100 rounded flex justify-center flex-none"
53023
+ }, /* @__PURE__ */ react.exports.createElement(BiFileBlank, {
53024
+ className: "w-3/5 h-full fill-gray-300"
53025
+ })), /* @__PURE__ */ react.exports.createElement("span", {
53026
+ className: "text-base text-left flex-1 text-gray-500 w-full break-words truncate"
53027
+ }, src));
53028
+ };
53029
+ react.exports.forwardRef(({ onDrop, onClear, onClick, value, src, loading }, ref) => {
53030
+ const cms = useCMS();
53031
+ const { getRootProps, getInputProps } = useDropzone({
53032
+ accept: dropzoneAcceptFromString(cms.media.accept || DEFAULT_MEDIA_UPLOAD_TYPES),
53033
+ onDrop,
53034
+ noClick: !!onClick
53035
+ });
53036
+ return /* @__PURE__ */ react.exports.createElement("div", {
53037
+ className: "w-full max-w-full",
53038
+ ...getRootProps()
53039
+ }, /* @__PURE__ */ react.exports.createElement("input", {
53040
+ ...getInputProps()
53041
+ }), value ? loading ? /* @__PURE__ */ react.exports.createElement(ImageLoadingIndicator, null) : /* @__PURE__ */ react.exports.createElement("div", {
53042
+ className: `relative w-full max-w-full flex justify-start gap-3 ${isImage(src) ? `items-start` : `items-center`}`
53043
+ }, /* @__PURE__ */ react.exports.createElement("button", {
53044
+ className: "shadow-inner focus-within:shadow-outline focus-within:border-blue-500 outline-none overflow-visible cursor-pointer border-none hover:opacity-60 transition ease-out duration-100",
53045
+ onClick,
53046
+ ref
53047
+ }, isImage(src) ? /* @__PURE__ */ react.exports.createElement(StyledImage, {
53048
+ src
53049
+ }) : /* @__PURE__ */ react.exports.createElement(StyledFile, {
53050
+ src
53051
+ })), onClear && /* @__PURE__ */ react.exports.createElement(DeleteImageButton, {
53052
+ onClick: (e2) => {
53053
+ e2.stopPropagation();
53054
+ onClear();
53055
+ }
53056
+ })) : /* @__PURE__ */ react.exports.createElement("button", {
53057
+ className: "outline-none relative hover:opacity-60 w-full",
53058
+ onClick
53059
+ }, loading ? /* @__PURE__ */ react.exports.createElement(ImageLoadingIndicator, null) : /* @__PURE__ */ react.exports.createElement("div", {
53060
+ className: "text-center rounded-[5px] bg-gray-100 text-gray-300 leading-[1.35] py-3 text-[15px] font-normal transition-all ease-out duration-100 hover:opacity-60"
53061
+ }, "Drag 'n' drop a file here,", /* @__PURE__ */ react.exports.createElement("br", null), "or click to select a file")));
53062
+ });
53063
+ const DeleteImageButton = ({
53064
+ onClick
53065
+ }) => {
53066
+ return /* @__PURE__ */ react.exports.createElement(IconButton, {
53067
+ variant: "white",
53068
+ className: "flex-none",
53069
+ onClick
53070
+ }, /* @__PURE__ */ react.exports.createElement(TrashIcon, {
53071
+ className: "w-7 h-auto"
53072
+ }));
53073
+ };
53074
+ const ImageLoadingIndicator = () => /* @__PURE__ */ react.exports.createElement("div", {
53075
+ className: "p-4 w-full min-h-[96px] flex flex-col justify-center items-center"
53076
+ }, /* @__PURE__ */ react.exports.createElement(LoadingDots, null));
52978
53077
  const onKeyDownSoftBreak = (editor, { options: { rules = [] } }) => (event) => {
52979
53078
  const entry = getBlockAbove(editor);
52980
53079
  if (!entry)
@@ -54354,12 +54453,6 @@ class ClickOutBase extends React__default.Component {
54354
54453
  }
54355
54454
  }
54356
54455
  const ClickableWrapper = onClickOutsideHOC(ClickOutBase);
54357
- react.exports.createContext({
54358
- currentBranch: null,
54359
- setCurrentBranch: (branch) => {
54360
- console.warn("BranchContext not initialized");
54361
- }
54362
- });
54363
54456
  function CursorPaginator({
54364
54457
  navigateNext,
54365
54458
  navigatePrev,
@@ -54385,9 +54478,9 @@ function CursorPaginator({
54385
54478
  }
54386
54479
  function ListMediaItem({ item, onClick, active: active3 }) {
54387
54480
  const FileIcon = item.type === "dir" ? BiFolder : BiFile;
54388
- const thumbnail = item.thumbnails["75x75"];
54481
+ const thumbnail = (item.thumbnails || {})["75x75"];
54389
54482
  return /* @__PURE__ */ React__default.createElement("li", {
54390
- className: `flex shrink-0 gap-3 items-center py-2 pl-2 pr-3 transition duration-150 ease-out cursor-pointer border-b border-gray-150 ${active3 ? "bg-gradient-to-r from-white to-gray-50/50 text-blue-500 hover:bg-gray-50" : "bg-white hover:bg-gray-50/50"}`,
54483
+ className: `relative flex shrink-0 gap-3 items-center py-2 pl-2 pr-3 transition duration-150 ease-out cursor-pointer border-b border-gray-150 ${active3 ? "bg-gradient-to-r from-white to-gray-50/50 text-blue-500 hover:bg-gray-50" : "bg-white hover:bg-gray-50/50"}`,
54391
54484
  onClick: () => {
54392
54485
  if (!active3) {
54393
54486
  onClick(item);
@@ -54395,7 +54488,9 @@ function ListMediaItem({ item, onClick, active: active3 }) {
54395
54488
  onClick(false);
54396
54489
  }
54397
54490
  }
54398
- }, /* @__PURE__ */ React__default.createElement("div", {
54491
+ }, item.new && /* @__PURE__ */ React__default.createElement("span", {
54492
+ className: "absolute top-1.5 left-1.5 rounded-full shadow bg-green-100 border border-green-200 text-[10px] tracking-wide font-bold text-green-600 px-1.5 py-0.5 z-10"
54493
+ }, "NEW"), /* @__PURE__ */ React__default.createElement("div", {
54399
54494
  className: "w-20 h-20 bg-gray-50 shadow border border-gray-100 rounded overflow-hidden flex justify-center flex-shrink-0"
54400
54495
  }, isImage(thumbnail) ? /* @__PURE__ */ React__default.createElement("img", {
54401
54496
  className: "object-cover w-full h-full object-center",
@@ -54409,10 +54504,12 @@ function ListMediaItem({ item, onClick, active: active3 }) {
54409
54504
  }
54410
54505
  function GridMediaItem({ item, active: active3, onClick }) {
54411
54506
  const FileIcon = item.type === "dir" ? BiFolder : BiFile;
54412
- const thumbnail = item.thumbnails["400x400"];
54507
+ const thumbnail = (item.thumbnails || {})["400x400"];
54413
54508
  return /* @__PURE__ */ React__default.createElement("li", {
54414
54509
  className: `relative pb-[100%] h-0 block border border-gray-100 rounded-md overflow-hidden flex justify-center shrink-0 w-full transition duration-150 ease-out ${active3 ? "shadow-outline" : "shadow hover:shadow-md hover:scale-103 hover:border-gray-150"} ${item.type === "dir" ? "cursor-pointer" : ""}`
54415
- }, /* @__PURE__ */ React__default.createElement("button", {
54510
+ }, item.new && /* @__PURE__ */ React__default.createElement("span", {
54511
+ className: "absolute top-1.5 left-1.5 rounded-full shadow bg-green-100 border border-green-200 text-[10px] tracking-wide font-bold text-green-600 px-1.5 py-0.5 z-10"
54512
+ }, "NEW"), /* @__PURE__ */ React__default.createElement("button", {
54416
54513
  className: "absolute w-full h-full flex items-center justify-center bg-white",
54417
54514
  onClick: () => {
54418
54515
  if (!active3) {
@@ -54491,6 +54588,38 @@ const DeleteModal = ({
54491
54588
  }
54492
54589
  }, "Delete"))));
54493
54590
  };
54591
+ const NewFolderModal = ({ onSubmit, close }) => {
54592
+ const [folderName, setFolderName] = React__default.useState("");
54593
+ return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(PopupModal, null, /* @__PURE__ */ React__default.createElement(ModalHeader, {
54594
+ close
54595
+ }, "New Folder"), /* @__PURE__ */ React__default.createElement(ModalBody, {
54596
+ padded: true
54597
+ }, /* @__PURE__ */ React__default.createElement("p", {
54598
+ className: "text-base text-gray-700 mb-2"
54599
+ }, "Please provide a name for your folder."), /* @__PURE__ */ React__default.createElement("p", {
54600
+ className: "text-sm text-gray-500 mb-4 italic"
54601
+ }, /* @__PURE__ */ React__default.createElement("span", {
54602
+ className: "font-bold"
54603
+ }, "Note"), " \u2013 If you navigate away before uploading a media item, the folder will disappear."), /* @__PURE__ */ React__default.createElement(Input, {
54604
+ value: folderName,
54605
+ placeholder: "Folder Name",
54606
+ required: true,
54607
+ onChange: (e2) => setFolderName(e2.target.value)
54608
+ })), /* @__PURE__ */ React__default.createElement(ModalActions, null, /* @__PURE__ */ React__default.createElement(Button, {
54609
+ style: { flexGrow: 2 },
54610
+ onClick: close
54611
+ }, "Cancel"), /* @__PURE__ */ React__default.createElement(Button, {
54612
+ disabled: !folderName,
54613
+ style: { flexGrow: 3 },
54614
+ variant: "primary",
54615
+ onClick: () => {
54616
+ if (!folderName)
54617
+ return;
54618
+ onSubmit(folderName);
54619
+ close();
54620
+ }
54621
+ }, "Create New Folder"))));
54622
+ };
54494
54623
  const SyncModal = ({ close, syncFunc, folder, branch }) => {
54495
54624
  return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(PopupModal, null, /* @__PURE__ */ React__default.createElement(ModalHeader, {
54496
54625
  close
@@ -54587,6 +54716,7 @@ function MediaPicker({
54587
54716
  return "not-configured";
54588
54717
  });
54589
54718
  const [deleteModalOpen, setDeleteModalOpen] = React__default.useState(false);
54719
+ const [newFolderModalOpen, setNewFolderModalOpen] = React__default.useState(false);
54590
54720
  const [listError, setListError] = react.exports.useState(defaultListError);
54591
54721
  const [directory, setDirectory] = react.exports.useState(props.directory);
54592
54722
  const [list2, setList] = react.exports.useState({
@@ -54644,7 +54774,7 @@ function MediaPicker({
54644
54774
  if (!cms.media.isConfigured)
54645
54775
  return;
54646
54776
  loadMedia();
54647
- return cms.events.subscribe(["media:upload:success", "media:delete:success", "media:pageSize"], loadMedia);
54777
+ return cms.events.subscribe(["media:delete:success", "media:pageSize"], loadMedia);
54648
54778
  }, [offset2, directory, cms.media.isConfigured]);
54649
54779
  const onClickMediaItem = (item) => {
54650
54780
  if (!item) {
@@ -54674,15 +54804,50 @@ function MediaPicker({
54674
54804
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
54675
54805
  accept: dropzoneAcceptFromString(cms.media.accept || DEFAULT_MEDIA_UPLOAD_TYPES),
54676
54806
  multiple: true,
54677
- onDrop: async (files) => {
54807
+ onDrop: async (files, fileRejections) => {
54678
54808
  try {
54679
54809
  setUploading(true);
54680
- await cms.media.persist(files.map((file) => {
54810
+ const mediaItems = await cms.media.persist(files.map((file) => {
54681
54811
  return {
54682
54812
  directory: directory || "/",
54683
54813
  file
54684
54814
  };
54685
54815
  }));
54816
+ const errorCodes = {
54817
+ "file-invalid-type": "Invalid file type",
54818
+ "file-too-large": "File too large",
54819
+ "file-too-small": "File too small",
54820
+ "too-many-files": "Too many files"
54821
+ };
54822
+ const printError = (error) => {
54823
+ const message2 = errorCodes[error.code];
54824
+ if (message2) {
54825
+ return message2;
54826
+ }
54827
+ console.error(error);
54828
+ return "Unknown error";
54829
+ };
54830
+ if (fileRejections.length > 0) {
54831
+ const messages = [];
54832
+ fileRejections.map((fileRejection) => {
54833
+ messages.push(`${fileRejection.file.name}: ${fileRejection.errors.map((error) => printError(error)).join(", ")}`);
54834
+ });
54835
+ cms.alerts.error(() => {
54836
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, "Upload Failed. ", /* @__PURE__ */ React__default.createElement("br", null), messages.join(". "), ".");
54837
+ });
54838
+ }
54839
+ if (mediaItems.length !== 0) {
54840
+ setActiveItem(mediaItems[0]);
54841
+ setList((mediaList) => {
54842
+ return {
54843
+ items: [
54844
+ ...mediaItems.map((x2) => ({ ...x2, new: true })),
54845
+ ...mediaList.items
54846
+ ],
54847
+ nextOffset: mediaList.nextOffset
54848
+ };
54849
+ });
54850
+ }
54686
54851
  } catch {
54687
54852
  }
54688
54853
  setUploading(false);
@@ -54756,28 +54921,47 @@ function MediaPicker({
54756
54921
  }
54757
54922
  },
54758
54923
  close: () => setDeleteModalOpen(false)
54924
+ }), newFolderModalOpen && /* @__PURE__ */ React__default.createElement(NewFolderModal, {
54925
+ onSubmit: (name) => {
54926
+ setDirectory((oldDir) => {
54927
+ if (oldDir) {
54928
+ return join(oldDir, name);
54929
+ } else {
54930
+ return name;
54931
+ }
54932
+ });
54933
+ resetOffset();
54934
+ },
54935
+ close: () => setNewFolderModalOpen(false)
54759
54936
  }), /* @__PURE__ */ React__default.createElement(MediaPickerWrap, null, /* @__PURE__ */ React__default.createElement("div", {
54760
- className: "flex items-center bg-gray-50 border-b border-gray-150 gap-x-4 py-3 px-5 shadow-sm flex-shrink-0"
54937
+ className: "flex flex-wrap items-center bg-gray-50 border-b border-gray-150 gap-4 py-3 px-5 shadow-sm flex-shrink-0"
54761
54938
  }, /* @__PURE__ */ React__default.createElement("div", {
54762
- className: `grow-0 flex divide-x divide-gray-150 shadow-inner bg-gray-50 border border-gray-150 justify-between rounded-md`
54763
- }, /* @__PURE__ */ React__default.createElement("button", {
54764
- className: `relative whitespace-nowrap flex items-center justify-center flex-1 block font-medium text-base px-2.5 py-1 transition-all ease-out duration-150 rounded-l-md ${viewMode === "grid" ? "bg-white text-blue-500 shadow" : "text-gray-400"}`,
54765
- onClick: () => {
54766
- setViewMode("grid");
54767
- }
54768
- }, /* @__PURE__ */ React__default.createElement(BiGridAlt, {
54769
- className: "w-6 h-full opacity-70"
54770
- })), /* @__PURE__ */ React__default.createElement("button", {
54771
- className: `relative whitespace-nowrap flex items-center justify-center flex-1 block font-medium text-base px-2 py-1 transition-all ease-out duration-150 rounded-r-md ${viewMode === "list" ? "bg-white text-blue-500 shadow" : "text-gray-400"}`,
54772
- onClick: () => {
54773
- setViewMode("list");
54774
- }
54775
- }, /* @__PURE__ */ React__default.createElement(BiListUl, {
54776
- className: "w-8 h-full opacity-70"
54777
- }))), /* @__PURE__ */ React__default.createElement(Breadcrumb, {
54939
+ className: "flex flex-1 items-center gap-4"
54940
+ }, /* @__PURE__ */ React__default.createElement(ViewModeToggle, {
54941
+ viewMode,
54942
+ setViewMode
54943
+ }), /* @__PURE__ */ React__default.createElement(Breadcrumb, {
54778
54944
  directory,
54779
54945
  setDirectory
54780
- }), !isLocal2 && hasTinaMedia && /* @__PURE__ */ React__default.createElement(Button, {
54946
+ })), /* @__PURE__ */ React__default.createElement("div", {
54947
+ className: "flex items-center gap-4"
54948
+ }, /* @__PURE__ */ React__default.createElement(Button, {
54949
+ busy: false,
54950
+ variant: "white",
54951
+ onClick: loadMedia,
54952
+ className: "whitespace-nowrap"
54953
+ }, "Refresh", /* @__PURE__ */ React__default.createElement(IoMdRefresh, {
54954
+ className: "w-6 h-full ml-2 opacity-70 text-blue-500"
54955
+ })), /* @__PURE__ */ React__default.createElement(Button, {
54956
+ busy: false,
54957
+ variant: "white",
54958
+ onClick: () => {
54959
+ setNewFolderModalOpen(true);
54960
+ },
54961
+ className: "whitespace-nowrap"
54962
+ }, "New Folder", /* @__PURE__ */ React__default.createElement(BiFolder, {
54963
+ className: "w-6 h-full ml-2 opacity-70 text-blue-500"
54964
+ })), !isLocal2 && hasTinaMedia && /* @__PURE__ */ React__default.createElement(Button, {
54781
54965
  busy: false,
54782
54966
  variant: "white",
54783
54967
  onClick: () => {
@@ -54788,7 +54972,7 @@ function MediaPicker({
54788
54972
  })), /* @__PURE__ */ React__default.createElement(UploadButton, {
54789
54973
  onClick,
54790
54974
  uploading
54791
- })), /* @__PURE__ */ React__default.createElement("div", {
54975
+ }))), /* @__PURE__ */ React__default.createElement("div", {
54792
54976
  className: "flex h-full overflow-hidden bg-white"
54793
54977
  }, /* @__PURE__ */ React__default.createElement("div", {
54794
54978
  className: "flex w-full flex-col h-full @container"
@@ -54840,7 +55024,7 @@ const ActiveItemPreview = ({
54840
55024
  deleteMediaItem,
54841
55025
  allowDelete
54842
55026
  }) => {
54843
- const thumbnail = activeItem ? activeItem.thumbnails["1000x1000"] : "";
55027
+ const thumbnail = activeItem ? (activeItem.thumbnails || {})["1000x1000"] : "";
54844
55028
  return /* @__PURE__ */ React__default.createElement("div", {
54845
55029
  className: `shrink-0 h-full flex flex-col items-start gap-3 overflow-y-auto bg-white border-l border-gray-100 bg-white shadow-md transition ease-out duration-150 ${activeItem ? `p-4 opacity-100 w-[35%] max-w-[560px] min-w-[240px]` : `translate-x-8 opacity-0 w-[0px]`}`
54846
55030
  }, activeItem && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", {
@@ -54933,6 +55117,30 @@ const DocsLink = ({ title, message: message2, docsLink, ...props }) => {
54933
55117
  className: "font-bold text-blue-500 hover:text-blue-600 hover:underline transition-all ease-out duration-150"
54934
55118
  }, "Learn More"));
54935
55119
  };
55120
+ const ViewModeToggle = ({ viewMode, setViewMode }) => {
55121
+ const toggleClasses = {
55122
+ base: "relative whitespace-nowrap flex items-center justify-center flex-1 block font-medium text-base py-1 transition-all ease-out duration-150 border",
55123
+ active: "bg-white text-blue-500 shadow-inner border-gray-50 border-t-gray-100",
55124
+ inactive: "bg-gray-50 text-gray-400 shadow border-gray-100 border-t-white"
55125
+ };
55126
+ return /* @__PURE__ */ React__default.createElement("div", {
55127
+ className: `grow-0 flex justify-between rounded-md border border-gray-100`
55128
+ }, /* @__PURE__ */ React__default.createElement("button", {
55129
+ className: `${toggleClasses.base} px-2.5 rounded-l-md ${viewMode === "grid" ? toggleClasses.active : toggleClasses.inactive}`,
55130
+ onClick: () => {
55131
+ setViewMode("grid");
55132
+ }
55133
+ }, /* @__PURE__ */ React__default.createElement(BiGridAlt, {
55134
+ className: "w-6 h-full opacity-70"
55135
+ })), /* @__PURE__ */ React__default.createElement("button", {
55136
+ className: `${toggleClasses.base} px-2 rounded-r-md ${viewMode === "list" ? toggleClasses.active : toggleClasses.inactive}`,
55137
+ onClick: () => {
55138
+ setViewMode("list");
55139
+ }
55140
+ }, /* @__PURE__ */ React__default.createElement(BiListUl, {
55141
+ className: "w-8 h-full opacity-70"
55142
+ })));
55143
+ };
54936
55144
  createScreen({
54937
55145
  name: "Media Manager",
54938
55146
  Component: MediaPicker,
@@ -54943,6 +55151,12 @@ createScreen({
54943
55151
  }
54944
55152
  });
54945
55153
  react.exports.createContext(-1);
55154
+ react.exports.createContext({
55155
+ currentBranch: null,
55156
+ setCurrentBranch: (branch) => {
55157
+ console.warn("BranchContext not initialized");
55158
+ }
55159
+ });
54946
55160
  react.exports.createContext(null);
54947
55161
  class MediaListError extends Error {
54948
55162
  constructor(config2) {
package/dist/index.js CHANGED
@@ -52679,11 +52679,13 @@
52679
52679
  const ERROR_MISSING_CMS = `useCMS could not find an instance of CMS`;
52680
52680
  const CMSContext = react.exports.createContext(null);
52681
52681
  function useCMS$1() {
52682
- const cms = react.exports.useContext(CMSContext);
52682
+ const { cms, dispatch, state } = react.exports.useContext(CMSContext);
52683
52683
  if (!cms) {
52684
52684
  throw new Error(ERROR_MISSING_CMS);
52685
52685
  }
52686
52686
  const [, setEnabled] = react.exports.useState(cms.enabled);
52687
+ cms.dispatch = dispatch;
52688
+ cms.state = state;
52687
52689
  react.exports.useEffect(() => {
52688
52690
  return cms.events.subscribe("cms", () => {
52689
52691
  setEnabled(cms.enabled);
@@ -52743,7 +52745,8 @@
52743
52745
  const roundedClasses = {
52744
52746
  full: `rounded-full`,
52745
52747
  left: `rounded-l-full`,
52746
- right: `rounded-r-full`
52748
+ right: `rounded-r-full`,
52749
+ custom: ""
52747
52750
  };
52748
52751
  const sizeClasses = {
52749
52752
  small: `text-xs h-8 px-3`,
@@ -52892,6 +52895,12 @@
52892
52895
  return elem(conf);
52893
52896
  }) : elem(DefaultContext);
52894
52897
  }
52898
+ function IoMdRefresh(props) {
52899
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 388c-72.597 0-132-59.405-132-132 0-72.601 59.403-132 132-132 36.3 0 69.299 15.4 92.406 39.601L278 234h154V80l-51.698 51.702C348.406 99.798 304.406 80 256 80c-96.797 0-176 79.203-176 176s78.094 176 176 176c81.045 0 148.287-54.134 169.401-128H378.85c-18.745 49.561-67.138 84-122.85 84z" } }] })(props);
52900
+ }
52901
+ function IoMdSync(props) {
52902
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 93.09V32l-80 81.454 80 81.456v-61.093c65.996 0 120 54.982 120 122.183 0 20.363-5 39.714-14.004 57.016L391 342.547c15.996-25.457 25-54.988 25-86.547 0-89.599-72.002-162.91-160-162.91zm0 285.094c-66.001 0-120-54.988-120-122.184 0-20.363 5-39.709 13.999-57.02L121 169.454C104.999 193.89 96 224.436 96 256c0 89.599 72.002 162.91 160 162.91V480l80-81.453-80-81.457v61.094z" } }] })(props);
52903
+ }
52895
52904
  function BiArrowToBottom(props) {
52896
52905
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M6 18h12v2H6zm5-14v8.586L6.707 8.293 5.293 9.707 12 16.414l6.707-6.707-1.414-1.414L13 12.586V4z" } }] })(props);
52897
52906
  }
@@ -52901,6 +52910,9 @@
52901
52910
  function BiCopyAlt(props) {
52902
52911
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M20 2H10c-1.103 0-2 .897-2 2v4H4c-1.103 0-2 .897-2 2v10c0 1.103.897 2 2 2h10c1.103 0 2-.897 2-2v-4h4c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zM4 20V10h10l.002 10H4zm16-6h-4v-4c0-1.103-.897-2-2-2h-4V4h10v10z" } }, { "tag": "path", "attr": { "d": "M6 12h6v2H6zm0 4h6v2H6z" } }] })(props);
52903
52912
  }
52913
+ function BiFileBlank(props) {
52914
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M19.937 8.68c-.011-.032-.02-.063-.033-.094a.997.997 0 0 0-.196-.293l-6-6a.997.997 0 0 0-.293-.196c-.03-.014-.062-.022-.094-.033a.991.991 0 0 0-.259-.051C13.04 2.011 13.021 2 13 2H6c-1.103 0-2 .897-2 2v16c0 1.103.897 2 2 2h12c1.103 0 2-.897 2-2V9c0-.021-.011-.04-.013-.062a.99.99 0 0 0-.05-.258zM16.586 8H14V5.414L16.586 8zM6 20V4h6v5a1 1 0 0 0 1 1h5l.002 10H6z" } }] })(props);
52915
+ }
52904
52916
  function BiFile(props) {
52905
52917
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "M19.903 8.586a.997.997 0 0 0-.196-.293l-6-6a.997.997 0 0 0-.293-.196c-.03-.014-.062-.022-.094-.033a.991.991 0 0 0-.259-.051C13.04 2.011 13.021 2 13 2H6c-1.103 0-2 .897-2 2v16c0 1.103.897 2 2 2h12c1.103 0 2-.897 2-2V9c0-.021-.011-.04-.013-.062a.952.952 0 0 0-.051-.259c-.01-.032-.019-.063-.033-.093zM16.586 8H14V5.414L16.586 8zM6 20V4h6v5a1 1 0 0 0 1 1h5l.002 10H6z" } }, { "tag": "path", "attr": { "d": "M8 12h8v2H8zm0 4h8v2H8zm0-8h2v2H8z" } }] })(props);
52906
52918
  }
@@ -52922,9 +52934,6 @@
52922
52934
  function BiX(props) {
52923
52935
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "d": "m16.192 6.344-4.243 4.242-4.242-4.242-1.414 1.414L10.535 12l-4.242 4.242 1.414 1.414 4.242-4.242 4.243 4.242 1.414-1.414L13.364 12l4.242-4.242z" } }] })(props);
52924
52936
  }
52925
- function IoMdSync(props) {
52926
- return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 512 512" }, "child": [{ "tag": "path", "attr": { "d": "M256 93.09V32l-80 81.454 80 81.456v-61.093c65.996 0 120 54.982 120 122.183 0 20.363-5 39.714-14.004 57.016L391 342.547c15.996-25.457 25-54.988 25-86.547 0-89.599-72.002-162.91-160-162.91zm0 285.094c-66.001 0-120-54.988-120-122.184 0-20.363 5-39.709 13.999-57.02L121 169.454C104.999 193.89 96 224.436 96 256c0 89.599 72.002 162.91 160 162.91V480l80-81.453-80-81.457v61.094z" } }] })(props);
52927
- }
52928
52937
  React__default.createContext({
52929
52938
  rawMode: false,
52930
52939
  setRawMode: () => {
@@ -52949,9 +52958,33 @@
52949
52958
  isVoid: true,
52950
52959
  isInline: true
52951
52960
  });
52961
+ const textFieldClasses = "shadow-inner focus:shadow-outline focus:border-blue-500 focus:outline-none block text-base placeholder:text-gray-300 px-3 py-2 text-gray-600 w-full bg-white border border-gray-200 transition-all ease-out duration-150 focus:text-gray-900 rounded-md";
52962
+ const disabledClasses = "opacity-50 pointer-events-none cursor-not-allowed";
52963
+ react.exports.forwardRef(({ className, disabled, ...rest }, ref) => {
52964
+ return /* @__PURE__ */ react.exports.createElement("input", {
52965
+ ref,
52966
+ type: "text",
52967
+ className: `${textFieldClasses} ${disabled ? disabledClasses : ""} ${className}`,
52968
+ ...rest
52969
+ });
52970
+ });
52971
+ react.exports.forwardRef(({ ...props }, ref) => {
52972
+ return /* @__PURE__ */ react.exports.createElement("textarea", {
52973
+ ...props,
52974
+ className: "shadow-inner text-base px-3 py-2 text-gray-600 resize-y focus:shadow-outline focus:border-blue-500 block w-full border border-gray-200 focus:text-gray-900 rounded-md",
52975
+ ref,
52976
+ style: { minHeight: "160px" }
52977
+ });
52978
+ });
52952
52979
  function MdOutlinePhotoLibrary(props) {
52953
52980
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M20 4v12H8V4h12m0-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 9.67l1.69 2.26 2.48-3.1L19 15H9zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z" } }] })(props);
52954
52981
  }
52982
+ const Input = ({ ...props }) => {
52983
+ return /* @__PURE__ */ react.exports.createElement("input", {
52984
+ className: textFieldClasses,
52985
+ ...props
52986
+ });
52987
+ };
52955
52988
  function useCMS() {
52956
52989
  return useCMS$1();
52957
52990
  }
@@ -52972,13 +53005,79 @@
52972
53005
  return Object.assign({}, ...(str || DEFAULT_MEDIA_UPLOAD_TYPES).split(",").map((x2) => ({ [x2]: [] })));
52973
53006
  };
52974
53007
  const isImage = (filename) => {
52975
- return /\.(gif|jpg|jpeg|tiff|png|svg|webp)(\?.*)?$/i.test(filename);
53008
+ return /\.(gif|jpg|jpeg|tiff|png|svg|webp|avif)(\?.*)?$/i.test(filename);
52976
53009
  };
52977
53010
  const absoluteImgURL = (str) => {
52978
53011
  if (str.startsWith("http"))
52979
53012
  return str;
52980
53013
  return `${window.location.origin}${str}`;
52981
53014
  };
53015
+ const StyledImage = ({ src }) => {
53016
+ const isSvg = /\.svg$/.test(src);
53017
+ return /* @__PURE__ */ react.exports.createElement("img", {
53018
+ src,
53019
+ className: `"block max-w-full rounded shadow overflow-hidden max-h-48 h-auto object-contain transition-opacity duration-100 ease-out m-0 bg-gray-200 bg-auto bg-center bg-no-repeat ${isSvg ? "min-w-[12rem]" : ""}`
53020
+ });
53021
+ };
53022
+ const StyledFile = ({ src }) => {
53023
+ return /* @__PURE__ */ react.exports.createElement("div", {
53024
+ className: "max-w-full w-full overflow-hidden flex-1 flex justify-start items-center gap-3"
53025
+ }, /* @__PURE__ */ react.exports.createElement("div", {
53026
+ className: "w-14 h-14 bg-gray-50 shadow border border-gray-100 rounded flex justify-center flex-none"
53027
+ }, /* @__PURE__ */ react.exports.createElement(BiFileBlank, {
53028
+ className: "w-3/5 h-full fill-gray-300"
53029
+ })), /* @__PURE__ */ react.exports.createElement("span", {
53030
+ className: "text-base text-left flex-1 text-gray-500 w-full break-words truncate"
53031
+ }, src));
53032
+ };
53033
+ react.exports.forwardRef(({ onDrop, onClear, onClick, value, src, loading }, ref) => {
53034
+ const cms = useCMS();
53035
+ const { getRootProps, getInputProps } = useDropzone({
53036
+ accept: dropzoneAcceptFromString(cms.media.accept || DEFAULT_MEDIA_UPLOAD_TYPES),
53037
+ onDrop,
53038
+ noClick: !!onClick
53039
+ });
53040
+ return /* @__PURE__ */ react.exports.createElement("div", {
53041
+ className: "w-full max-w-full",
53042
+ ...getRootProps()
53043
+ }, /* @__PURE__ */ react.exports.createElement("input", {
53044
+ ...getInputProps()
53045
+ }), value ? loading ? /* @__PURE__ */ react.exports.createElement(ImageLoadingIndicator, null) : /* @__PURE__ */ react.exports.createElement("div", {
53046
+ className: `relative w-full max-w-full flex justify-start gap-3 ${isImage(src) ? `items-start` : `items-center`}`
53047
+ }, /* @__PURE__ */ react.exports.createElement("button", {
53048
+ className: "shadow-inner focus-within:shadow-outline focus-within:border-blue-500 outline-none overflow-visible cursor-pointer border-none hover:opacity-60 transition ease-out duration-100",
53049
+ onClick,
53050
+ ref
53051
+ }, isImage(src) ? /* @__PURE__ */ react.exports.createElement(StyledImage, {
53052
+ src
53053
+ }) : /* @__PURE__ */ react.exports.createElement(StyledFile, {
53054
+ src
53055
+ })), onClear && /* @__PURE__ */ react.exports.createElement(DeleteImageButton, {
53056
+ onClick: (e2) => {
53057
+ e2.stopPropagation();
53058
+ onClear();
53059
+ }
53060
+ })) : /* @__PURE__ */ react.exports.createElement("button", {
53061
+ className: "outline-none relative hover:opacity-60 w-full",
53062
+ onClick
53063
+ }, loading ? /* @__PURE__ */ react.exports.createElement(ImageLoadingIndicator, null) : /* @__PURE__ */ react.exports.createElement("div", {
53064
+ className: "text-center rounded-[5px] bg-gray-100 text-gray-300 leading-[1.35] py-3 text-[15px] font-normal transition-all ease-out duration-100 hover:opacity-60"
53065
+ }, "Drag 'n' drop a file here,", /* @__PURE__ */ react.exports.createElement("br", null), "or click to select a file")));
53066
+ });
53067
+ const DeleteImageButton = ({
53068
+ onClick
53069
+ }) => {
53070
+ return /* @__PURE__ */ react.exports.createElement(IconButton, {
53071
+ variant: "white",
53072
+ className: "flex-none",
53073
+ onClick
53074
+ }, /* @__PURE__ */ react.exports.createElement(TrashIcon, {
53075
+ className: "w-7 h-auto"
53076
+ }));
53077
+ };
53078
+ const ImageLoadingIndicator = () => /* @__PURE__ */ react.exports.createElement("div", {
53079
+ className: "p-4 w-full min-h-[96px] flex flex-col justify-center items-center"
53080
+ }, /* @__PURE__ */ react.exports.createElement(LoadingDots, null));
52982
53081
  const onKeyDownSoftBreak = (editor, { options: { rules = [] } }) => (event) => {
52983
53082
  const entry = getBlockAbove(editor);
52984
53083
  if (!entry)
@@ -54358,12 +54457,6 @@
54358
54457
  }
54359
54458
  }
54360
54459
  const ClickableWrapper = onClickOutsideHOC(ClickOutBase);
54361
- react.exports.createContext({
54362
- currentBranch: null,
54363
- setCurrentBranch: (branch) => {
54364
- console.warn("BranchContext not initialized");
54365
- }
54366
- });
54367
54460
  function CursorPaginator({
54368
54461
  navigateNext,
54369
54462
  navigatePrev,
@@ -54389,9 +54482,9 @@
54389
54482
  }
54390
54483
  function ListMediaItem({ item, onClick, active: active2 }) {
54391
54484
  const FileIcon = item.type === "dir" ? BiFolder : BiFile;
54392
- const thumbnail = item.thumbnails["75x75"];
54485
+ const thumbnail = (item.thumbnails || {})["75x75"];
54393
54486
  return /* @__PURE__ */ React__default.createElement("li", {
54394
- className: `flex shrink-0 gap-3 items-center py-2 pl-2 pr-3 transition duration-150 ease-out cursor-pointer border-b border-gray-150 ${active2 ? "bg-gradient-to-r from-white to-gray-50/50 text-blue-500 hover:bg-gray-50" : "bg-white hover:bg-gray-50/50"}`,
54487
+ className: `relative flex shrink-0 gap-3 items-center py-2 pl-2 pr-3 transition duration-150 ease-out cursor-pointer border-b border-gray-150 ${active2 ? "bg-gradient-to-r from-white to-gray-50/50 text-blue-500 hover:bg-gray-50" : "bg-white hover:bg-gray-50/50"}`,
54395
54488
  onClick: () => {
54396
54489
  if (!active2) {
54397
54490
  onClick(item);
@@ -54399,7 +54492,9 @@
54399
54492
  onClick(false);
54400
54493
  }
54401
54494
  }
54402
- }, /* @__PURE__ */ React__default.createElement("div", {
54495
+ }, item.new && /* @__PURE__ */ React__default.createElement("span", {
54496
+ className: "absolute top-1.5 left-1.5 rounded-full shadow bg-green-100 border border-green-200 text-[10px] tracking-wide font-bold text-green-600 px-1.5 py-0.5 z-10"
54497
+ }, "NEW"), /* @__PURE__ */ React__default.createElement("div", {
54403
54498
  className: "w-20 h-20 bg-gray-50 shadow border border-gray-100 rounded overflow-hidden flex justify-center flex-shrink-0"
54404
54499
  }, isImage(thumbnail) ? /* @__PURE__ */ React__default.createElement("img", {
54405
54500
  className: "object-cover w-full h-full object-center",
@@ -54413,10 +54508,12 @@
54413
54508
  }
54414
54509
  function GridMediaItem({ item, active: active2, onClick }) {
54415
54510
  const FileIcon = item.type === "dir" ? BiFolder : BiFile;
54416
- const thumbnail = item.thumbnails["400x400"];
54511
+ const thumbnail = (item.thumbnails || {})["400x400"];
54417
54512
  return /* @__PURE__ */ React__default.createElement("li", {
54418
54513
  className: `relative pb-[100%] h-0 block border border-gray-100 rounded-md overflow-hidden flex justify-center shrink-0 w-full transition duration-150 ease-out ${active2 ? "shadow-outline" : "shadow hover:shadow-md hover:scale-103 hover:border-gray-150"} ${item.type === "dir" ? "cursor-pointer" : ""}`
54419
- }, /* @__PURE__ */ React__default.createElement("button", {
54514
+ }, item.new && /* @__PURE__ */ React__default.createElement("span", {
54515
+ className: "absolute top-1.5 left-1.5 rounded-full shadow bg-green-100 border border-green-200 text-[10px] tracking-wide font-bold text-green-600 px-1.5 py-0.5 z-10"
54516
+ }, "NEW"), /* @__PURE__ */ React__default.createElement("button", {
54420
54517
  className: "absolute w-full h-full flex items-center justify-center bg-white",
54421
54518
  onClick: () => {
54422
54519
  if (!active2) {
@@ -54495,6 +54592,38 @@
54495
54592
  }
54496
54593
  }, "Delete"))));
54497
54594
  };
54595
+ const NewFolderModal = ({ onSubmit, close }) => {
54596
+ const [folderName, setFolderName] = React__default.useState("");
54597
+ return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(PopupModal, null, /* @__PURE__ */ React__default.createElement(ModalHeader, {
54598
+ close
54599
+ }, "New Folder"), /* @__PURE__ */ React__default.createElement(ModalBody, {
54600
+ padded: true
54601
+ }, /* @__PURE__ */ React__default.createElement("p", {
54602
+ className: "text-base text-gray-700 mb-2"
54603
+ }, "Please provide a name for your folder."), /* @__PURE__ */ React__default.createElement("p", {
54604
+ className: "text-sm text-gray-500 mb-4 italic"
54605
+ }, /* @__PURE__ */ React__default.createElement("span", {
54606
+ className: "font-bold"
54607
+ }, "Note"), " \u2013 If you navigate away before uploading a media item, the folder will disappear."), /* @__PURE__ */ React__default.createElement(Input, {
54608
+ value: folderName,
54609
+ placeholder: "Folder Name",
54610
+ required: true,
54611
+ onChange: (e2) => setFolderName(e2.target.value)
54612
+ })), /* @__PURE__ */ React__default.createElement(ModalActions, null, /* @__PURE__ */ React__default.createElement(Button, {
54613
+ style: { flexGrow: 2 },
54614
+ onClick: close
54615
+ }, "Cancel"), /* @__PURE__ */ React__default.createElement(Button, {
54616
+ disabled: !folderName,
54617
+ style: { flexGrow: 3 },
54618
+ variant: "primary",
54619
+ onClick: () => {
54620
+ if (!folderName)
54621
+ return;
54622
+ onSubmit(folderName);
54623
+ close();
54624
+ }
54625
+ }, "Create New Folder"))));
54626
+ };
54498
54627
  const SyncModal = ({ close, syncFunc, folder, branch }) => {
54499
54628
  return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(PopupModal, null, /* @__PURE__ */ React__default.createElement(ModalHeader, {
54500
54629
  close
@@ -54591,6 +54720,7 @@
54591
54720
  return "not-configured";
54592
54721
  });
54593
54722
  const [deleteModalOpen, setDeleteModalOpen] = React__default.useState(false);
54723
+ const [newFolderModalOpen, setNewFolderModalOpen] = React__default.useState(false);
54594
54724
  const [listError, setListError] = react.exports.useState(defaultListError);
54595
54725
  const [directory, setDirectory] = react.exports.useState(props.directory);
54596
54726
  const [list2, setList] = react.exports.useState({
@@ -54648,7 +54778,7 @@
54648
54778
  if (!cms.media.isConfigured)
54649
54779
  return;
54650
54780
  loadMedia();
54651
- return cms.events.subscribe(["media:upload:success", "media:delete:success", "media:pageSize"], loadMedia);
54781
+ return cms.events.subscribe(["media:delete:success", "media:pageSize"], loadMedia);
54652
54782
  }, [offset2, directory, cms.media.isConfigured]);
54653
54783
  const onClickMediaItem = (item) => {
54654
54784
  if (!item) {
@@ -54678,15 +54808,50 @@
54678
54808
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
54679
54809
  accept: dropzoneAcceptFromString(cms.media.accept || DEFAULT_MEDIA_UPLOAD_TYPES),
54680
54810
  multiple: true,
54681
- onDrop: async (files) => {
54811
+ onDrop: async (files, fileRejections) => {
54682
54812
  try {
54683
54813
  setUploading(true);
54684
- await cms.media.persist(files.map((file) => {
54814
+ const mediaItems = await cms.media.persist(files.map((file) => {
54685
54815
  return {
54686
54816
  directory: directory || "/",
54687
54817
  file
54688
54818
  };
54689
54819
  }));
54820
+ const errorCodes = {
54821
+ "file-invalid-type": "Invalid file type",
54822
+ "file-too-large": "File too large",
54823
+ "file-too-small": "File too small",
54824
+ "too-many-files": "Too many files"
54825
+ };
54826
+ const printError = (error) => {
54827
+ const message2 = errorCodes[error.code];
54828
+ if (message2) {
54829
+ return message2;
54830
+ }
54831
+ console.error(error);
54832
+ return "Unknown error";
54833
+ };
54834
+ if (fileRejections.length > 0) {
54835
+ const messages = [];
54836
+ fileRejections.map((fileRejection) => {
54837
+ messages.push(`${fileRejection.file.name}: ${fileRejection.errors.map((error) => printError(error)).join(", ")}`);
54838
+ });
54839
+ cms.alerts.error(() => {
54840
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, "Upload Failed. ", /* @__PURE__ */ React__default.createElement("br", null), messages.join(". "), ".");
54841
+ });
54842
+ }
54843
+ if (mediaItems.length !== 0) {
54844
+ setActiveItem(mediaItems[0]);
54845
+ setList((mediaList) => {
54846
+ return {
54847
+ items: [
54848
+ ...mediaItems.map((x2) => ({ ...x2, new: true })),
54849
+ ...mediaList.items
54850
+ ],
54851
+ nextOffset: mediaList.nextOffset
54852
+ };
54853
+ });
54854
+ }
54690
54855
  } catch {
54691
54856
  }
54692
54857
  setUploading(false);
@@ -54760,28 +54925,47 @@
54760
54925
  }
54761
54926
  },
54762
54927
  close: () => setDeleteModalOpen(false)
54928
+ }), newFolderModalOpen && /* @__PURE__ */ React__default.createElement(NewFolderModal, {
54929
+ onSubmit: (name2) => {
54930
+ setDirectory((oldDir) => {
54931
+ if (oldDir) {
54932
+ return join(oldDir, name2);
54933
+ } else {
54934
+ return name2;
54935
+ }
54936
+ });
54937
+ resetOffset();
54938
+ },
54939
+ close: () => setNewFolderModalOpen(false)
54763
54940
  }), /* @__PURE__ */ React__default.createElement(MediaPickerWrap, null, /* @__PURE__ */ React__default.createElement("div", {
54764
- className: "flex items-center bg-gray-50 border-b border-gray-150 gap-x-4 py-3 px-5 shadow-sm flex-shrink-0"
54941
+ className: "flex flex-wrap items-center bg-gray-50 border-b border-gray-150 gap-4 py-3 px-5 shadow-sm flex-shrink-0"
54765
54942
  }, /* @__PURE__ */ React__default.createElement("div", {
54766
- className: `grow-0 flex divide-x divide-gray-150 shadow-inner bg-gray-50 border border-gray-150 justify-between rounded-md`
54767
- }, /* @__PURE__ */ React__default.createElement("button", {
54768
- className: `relative whitespace-nowrap flex items-center justify-center flex-1 block font-medium text-base px-2.5 py-1 transition-all ease-out duration-150 rounded-l-md ${viewMode === "grid" ? "bg-white text-blue-500 shadow" : "text-gray-400"}`,
54769
- onClick: () => {
54770
- setViewMode("grid");
54771
- }
54772
- }, /* @__PURE__ */ React__default.createElement(BiGridAlt, {
54773
- className: "w-6 h-full opacity-70"
54774
- })), /* @__PURE__ */ React__default.createElement("button", {
54775
- className: `relative whitespace-nowrap flex items-center justify-center flex-1 block font-medium text-base px-2 py-1 transition-all ease-out duration-150 rounded-r-md ${viewMode === "list" ? "bg-white text-blue-500 shadow" : "text-gray-400"}`,
54776
- onClick: () => {
54777
- setViewMode("list");
54778
- }
54779
- }, /* @__PURE__ */ React__default.createElement(BiListUl, {
54780
- className: "w-8 h-full opacity-70"
54781
- }))), /* @__PURE__ */ React__default.createElement(Breadcrumb, {
54943
+ className: "flex flex-1 items-center gap-4"
54944
+ }, /* @__PURE__ */ React__default.createElement(ViewModeToggle, {
54945
+ viewMode,
54946
+ setViewMode
54947
+ }), /* @__PURE__ */ React__default.createElement(Breadcrumb, {
54782
54948
  directory,
54783
54949
  setDirectory
54784
- }), !isLocal2 && hasTinaMedia && /* @__PURE__ */ React__default.createElement(Button, {
54950
+ })), /* @__PURE__ */ React__default.createElement("div", {
54951
+ className: "flex items-center gap-4"
54952
+ }, /* @__PURE__ */ React__default.createElement(Button, {
54953
+ busy: false,
54954
+ variant: "white",
54955
+ onClick: loadMedia,
54956
+ className: "whitespace-nowrap"
54957
+ }, "Refresh", /* @__PURE__ */ React__default.createElement(IoMdRefresh, {
54958
+ className: "w-6 h-full ml-2 opacity-70 text-blue-500"
54959
+ })), /* @__PURE__ */ React__default.createElement(Button, {
54960
+ busy: false,
54961
+ variant: "white",
54962
+ onClick: () => {
54963
+ setNewFolderModalOpen(true);
54964
+ },
54965
+ className: "whitespace-nowrap"
54966
+ }, "New Folder", /* @__PURE__ */ React__default.createElement(BiFolder, {
54967
+ className: "w-6 h-full ml-2 opacity-70 text-blue-500"
54968
+ })), !isLocal2 && hasTinaMedia && /* @__PURE__ */ React__default.createElement(Button, {
54785
54969
  busy: false,
54786
54970
  variant: "white",
54787
54971
  onClick: () => {
@@ -54792,7 +54976,7 @@
54792
54976
  })), /* @__PURE__ */ React__default.createElement(UploadButton, {
54793
54977
  onClick,
54794
54978
  uploading
54795
- })), /* @__PURE__ */ React__default.createElement("div", {
54979
+ }))), /* @__PURE__ */ React__default.createElement("div", {
54796
54980
  className: "flex h-full overflow-hidden bg-white"
54797
54981
  }, /* @__PURE__ */ React__default.createElement("div", {
54798
54982
  className: "flex w-full flex-col h-full @container"
@@ -54844,7 +55028,7 @@
54844
55028
  deleteMediaItem,
54845
55029
  allowDelete
54846
55030
  }) => {
54847
- const thumbnail = activeItem ? activeItem.thumbnails["1000x1000"] : "";
55031
+ const thumbnail = activeItem ? (activeItem.thumbnails || {})["1000x1000"] : "";
54848
55032
  return /* @__PURE__ */ React__default.createElement("div", {
54849
55033
  className: `shrink-0 h-full flex flex-col items-start gap-3 overflow-y-auto bg-white border-l border-gray-100 bg-white shadow-md transition ease-out duration-150 ${activeItem ? `p-4 opacity-100 w-[35%] max-w-[560px] min-w-[240px]` : `translate-x-8 opacity-0 w-[0px]`}`
54850
55034
  }, activeItem && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", {
@@ -54937,6 +55121,30 @@
54937
55121
  className: "font-bold text-blue-500 hover:text-blue-600 hover:underline transition-all ease-out duration-150"
54938
55122
  }, "Learn More"));
54939
55123
  };
55124
+ const ViewModeToggle = ({ viewMode, setViewMode }) => {
55125
+ const toggleClasses = {
55126
+ base: "relative whitespace-nowrap flex items-center justify-center flex-1 block font-medium text-base py-1 transition-all ease-out duration-150 border",
55127
+ active: "bg-white text-blue-500 shadow-inner border-gray-50 border-t-gray-100",
55128
+ inactive: "bg-gray-50 text-gray-400 shadow border-gray-100 border-t-white"
55129
+ };
55130
+ return /* @__PURE__ */ React__default.createElement("div", {
55131
+ className: `grow-0 flex justify-between rounded-md border border-gray-100`
55132
+ }, /* @__PURE__ */ React__default.createElement("button", {
55133
+ className: `${toggleClasses.base} px-2.5 rounded-l-md ${viewMode === "grid" ? toggleClasses.active : toggleClasses.inactive}`,
55134
+ onClick: () => {
55135
+ setViewMode("grid");
55136
+ }
55137
+ }, /* @__PURE__ */ React__default.createElement(BiGridAlt, {
55138
+ className: "w-6 h-full opacity-70"
55139
+ })), /* @__PURE__ */ React__default.createElement("button", {
55140
+ className: `${toggleClasses.base} px-2 rounded-r-md ${viewMode === "list" ? toggleClasses.active : toggleClasses.inactive}`,
55141
+ onClick: () => {
55142
+ setViewMode("list");
55143
+ }
55144
+ }, /* @__PURE__ */ React__default.createElement(BiListUl, {
55145
+ className: "w-8 h-full opacity-70"
55146
+ })));
55147
+ };
54940
55148
  createScreen({
54941
55149
  name: "Media Manager",
54942
55150
  Component: MediaPicker,
@@ -54947,6 +55155,12 @@
54947
55155
  }
54948
55156
  });
54949
55157
  react.exports.createContext(-1);
55158
+ react.exports.createContext({
55159
+ currentBranch: null,
55160
+ setCurrentBranch: (branch) => {
55161
+ console.warn("BranchContext not initialized");
55162
+ }
55163
+ });
54950
55164
  react.exports.createContext(null);
54951
55165
  class MediaListError extends Error {
54952
55166
  constructor(config2) {
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "next-tinacms-cloudinary",
3
- "version": "4.3.0",
3
+ "version": "4.3.1",
4
4
  "main": "dist/index.js",
5
+ "module": "dist/index.es.js",
5
6
  "files": [
6
7
  "dist"
7
8
  ],
@@ -21,13 +22,13 @@
21
22
  "multer": "1.4.5-lts.1"
22
23
  },
23
24
  "devDependencies": {
24
- "@tinacms/toolkit": "1.5.0",
25
- "@tinacms/scripts": "1.0.4",
25
+ "@tinacms/toolkit": "1.7.2",
26
+ "@tinacms/scripts": "1.1.0",
26
27
  "@types/crypto-js": "^3.1.47",
27
28
  "@types/js-cookie": "^2.2.6",
28
29
  "@types/node": "^13.13.1",
29
30
  "next": "12.2.4",
30
- "tinacms": "1.3.1",
31
+ "tinacms": "1.5.6",
31
32
  "typescript": "4.3.5"
32
33
  },
33
34
  "peerDependencies": {},