tinacms 1.5.26 → 1.5.27

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.
@@ -8,7 +8,6 @@ export interface TinaCloudMediaStoreClass {
8
8
  export interface TinaCloudAuthWallProps {
9
9
  cms?: TinaCMS;
10
10
  children: React.ReactNode;
11
- loginScreen?: React.ReactNode;
12
11
  tinaioConfig?: TinaIOConfig;
13
12
  getModalActions?: (args: {
14
13
  closeModal: () => void;
@@ -19,7 +18,7 @@ export interface TinaCloudAuthWallProps {
19
18
  }[];
20
19
  mediaStore?: TinaCloudMediaStoreClass | (() => Promise<TinaCloudMediaStoreClass>);
21
20
  }
22
- export declare const AuthWallInner: ({ children, cms, loginScreen, getModalActions, }: TinaCloudAuthWallProps) => JSX.Element;
21
+ export declare const AuthWallInner: ({ children, cms, getModalActions, }: TinaCloudAuthWallProps) => JSX.Element;
23
22
  /**
24
23
  * Provides the ability to setup your CMS and media while also providing an authentication wall so Tina is not enabled without a valid user session.
25
24
  *
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export default TinaCMSProvider2;
20
20
  import { MediaStore, TinaCMS } from '@tinacms/toolkit';
21
21
  import { formifyCallback } from './hooks/use-graphql-forms';
22
22
  export { NAMER, resolveField } from '@tinacms/schema-tools';
23
+ export type { LoginScreenProps, LoginStrategy } from '@tinacms/schema-tools';
23
24
  import { TinaSchema, TinaField, Config, Schema, Collection, Template } from '@tinacms/schema-tools';
24
25
  export type { Config, Schema, Collection, Template, TinaField, TinaSchema };
25
26
  /**
package/dist/index.js CHANGED
@@ -3062,6 +3062,9 @@ var __publicField = (obj, key, value) => {
3062
3062
  function MdSyncProblem(props) {
3063
3063
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0z" } }, { "tag": "path", "attr": { "d": "M3 12c0 2.21.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24A6.003 6.003 0 015 12a5.99 5.99 0 014-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24A6.003 6.003 0 0119 12a5.99 5.99 0 01-4 5.65v2.09c3.45-.89 6-4.01 6-7.74 0-2.21-.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z" } }] })(props);
3064
3064
  }
3065
+ function MdOutlineHelpOutline(props) {
3066
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z" } }] })(props);
3067
+ }
3065
3068
  function MdOutlineSettings(props) {
3066
3069
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46a.5.5 0 00-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0014 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.566.566 0 00-.18-.03c-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46a.5.5 0 00.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73 0 .21-.02.43-.05.73l-.14 1.13.89.7 1.08.84-.7 1.21-1.27-.51-1.04-.42-.9.68c-.43.32-.84.56-1.25.73l-1.06.43-.16 1.13-.2 1.35h-1.4l-.19-1.35-.16-1.13-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7-1.06.43-1.27.51-.7-1.21 1.08-.84.89-.7-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13-.89-.7-1.08-.84.7-1.21 1.27.51 1.04.42.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43.16-1.13.2-1.35h1.39l.19 1.35.16 1.13 1.06.43c.43.18.83.41 1.23.71l.91.7 1.06-.43 1.27-.51.7 1.21-1.07.85-.89.7.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" } }] })(props);
3067
3070
  }
@@ -3083,6 +3086,9 @@ var __publicField = (obj, key, value) => {
3083
3086
  function MdOutlineArrowBack(props) {
3084
3087
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" } }] })(props);
3085
3088
  }
3089
+ function MdOutlinePerson(props) {
3090
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M12 6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0 10c2.7 0 5.8 1.29 6 2H6c.23-.72 3.31-2 6-2m0-12C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 10c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" } }] })(props);
3091
+ }
3086
3092
  const BranchContext = React__namespace.createContext({
3087
3093
  currentBranch: null,
3088
3094
  setCurrentBranch: (branch) => {
@@ -8865,6 +8871,9 @@ var __publicField = (obj, key, value) => {
8865
8871
  await ((_d = cms.api.tina) == null ? void 0 : _d.authProvider.logout());
8866
8872
  if ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout) {
8867
8873
  await ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout());
8874
+ await new Promise(
8875
+ (resolve) => setTimeout(resolve, 500)
8876
+ );
8868
8877
  }
8869
8878
  window.location.href = new URL(
8870
8879
  window.location.href
@@ -10305,6 +10314,7 @@ var __publicField = (obj, key, value) => {
10305
10314
  (_a = client == null ? void 0 : client.authProvider) == null ? void 0 : _a.logout().then(async () => {
10306
10315
  if (typeof (client == null ? void 0 : client.onLogout) === "function") {
10307
10316
  await client.onLogout();
10317
+ await new Promise((resolve) => setTimeout(resolve, 500));
10308
10318
  }
10309
10319
  window.location.href = new URL(window.location.href).pathname;
10310
10320
  }).catch((e) => console.error(e));
@@ -10448,7 +10458,18 @@ var __publicField = (obj, key, value) => {
10448
10458
  link: {
10449
10459
  text: "User Management",
10450
10460
  href: `https://app.tina.io/projects/${clientId}/collaborators`
10451
- }
10461
+ },
10462
+ Icon: MdOutlinePerson
10463
+ })
10464
+ );
10465
+ this.plugins.add(
10466
+ createCloudConfig({
10467
+ name: "Support",
10468
+ link: {
10469
+ text: "Support",
10470
+ href: `https:/tina.io/docs/support`
10471
+ },
10472
+ Icon: MdOutlineHelpOutline
10452
10473
  })
10453
10474
  );
10454
10475
  } else if (!isSelfHosted) {
@@ -11407,6 +11428,7 @@ var __publicField = (obj, key, value) => {
11407
11428
  const form = React.useMemo(() => {
11408
11429
  return new Form({
11409
11430
  ...props,
11431
+ relativePath: props.id,
11410
11432
  id,
11411
11433
  onChange: ({ values }) => {
11412
11434
  props.onChange(values);
@@ -12330,7 +12352,7 @@ var __publicField = (obj, key, value) => {
12330
12352
  return /* @__PURE__ */ React.createElement(
12331
12353
  NestedForm,
12332
12354
  {
12333
- id: "link-form",
12355
+ id: props.id,
12334
12356
  label: "Link",
12335
12357
  fields: [
12336
12358
  { label: "URL", name: "url", component: "text" },
@@ -12371,7 +12393,8 @@ var __publicField = (obj, key, value) => {
12371
12393
  icon,
12372
12394
  options,
12373
12395
  name,
12374
- isLastItem = false
12396
+ isLastItem = false,
12397
+ tinaForm
12375
12398
  }) => {
12376
12399
  const editor = plateHeadless.useEditorState();
12377
12400
  const [selection, setSelection] = React.useState(null);
@@ -12460,6 +12483,7 @@ var __publicField = (obj, key, value) => {
12460
12483
  ), isExpanded && /* @__PURE__ */ React.createElement(
12461
12484
  LinkForm,
12462
12485
  {
12486
+ id: tinaForm.id,
12463
12487
  selection,
12464
12488
  onClose: () => {
12465
12489
  setIsExpanded(false);
@@ -12685,7 +12709,8 @@ var __publicField = (obj, key, value) => {
12685
12709
  const ICON_WIDTH = 40;
12686
12710
  const EMBED_ICON_WIDTH = 85;
12687
12711
  function Toolbar({
12688
- templates
12712
+ templates,
12713
+ tinaForm
12689
12714
  }) {
12690
12715
  const { setRawMode } = useEditorContext();
12691
12716
  const showEmbed = templates.length > 0;
@@ -12702,6 +12727,7 @@ var __publicField = (obj, key, value) => {
12702
12727
  const isImgActive = helpers.isNodeActive(editor, ELEMENT_IMG);
12703
12728
  const toolbarItems = [
12704
12729
  {
12730
+ tinaForm,
12705
12731
  name: "heading",
12706
12732
  label: "Heading",
12707
12733
  active: false,
@@ -12722,16 +12748,19 @@ var __publicField = (obj, key, value) => {
12722
12748
  ))
12723
12749
  },
12724
12750
  {
12751
+ tinaForm,
12725
12752
  name: "link",
12726
12753
  label: "Link",
12727
12754
  active: isLinkActive2
12728
12755
  },
12729
12756
  {
12757
+ tinaForm,
12730
12758
  name: "image",
12731
12759
  label: "Image",
12732
12760
  active: isImgActive
12733
12761
  },
12734
12762
  {
12763
+ tinaForm,
12735
12764
  name: "quote",
12736
12765
  label: "Quote",
12737
12766
  active: blockQuoteActive,
@@ -12742,6 +12771,7 @@ var __publicField = (obj, key, value) => {
12742
12771
  }
12743
12772
  },
12744
12773
  {
12774
+ tinaForm,
12745
12775
  name: "ul",
12746
12776
  label: "Bullet List",
12747
12777
  active: ulActive,
@@ -12752,6 +12782,7 @@ var __publicField = (obj, key, value) => {
12752
12782
  }
12753
12783
  },
12754
12784
  {
12785
+ tinaForm,
12755
12786
  name: "ol",
12756
12787
  label: "List",
12757
12788
  active: olActive,
@@ -12762,6 +12793,7 @@ var __publicField = (obj, key, value) => {
12762
12793
  }
12763
12794
  },
12764
12795
  {
12796
+ tinaForm,
12765
12797
  name: "code",
12766
12798
  label: "Code",
12767
12799
  active: isCodeActive,
@@ -12772,6 +12804,7 @@ var __publicField = (obj, key, value) => {
12772
12804
  }
12773
12805
  },
12774
12806
  {
12807
+ tinaForm,
12775
12808
  name: "codeBlock",
12776
12809
  label: "Code Block",
12777
12810
  active: codeBlockActive,
@@ -12782,6 +12815,7 @@ var __publicField = (obj, key, value) => {
12782
12815
  }
12783
12816
  },
12784
12817
  {
12818
+ tinaForm,
12785
12819
  name: "bold",
12786
12820
  label: "Bold",
12787
12821
  active: isBoldActive,
@@ -12792,6 +12826,7 @@ var __publicField = (obj, key, value) => {
12792
12826
  }
12793
12827
  },
12794
12828
  {
12829
+ tinaForm,
12795
12830
  name: "italic",
12796
12831
  label: "Italic",
12797
12832
  active: isItalicActive,
@@ -12802,6 +12837,7 @@ var __publicField = (obj, key, value) => {
12802
12837
  }
12803
12838
  },
12804
12839
  {
12840
+ tinaForm,
12805
12841
  name: "raw",
12806
12842
  label: "Raw",
12807
12843
  active: false,
@@ -12859,6 +12895,7 @@ var __publicField = (obj, key, value) => {
12859
12895
  return /* @__PURE__ */ React__namespace.createElement(
12860
12896
  ToolbarItem,
12861
12897
  {
12898
+ tinaForm,
12862
12899
  key: toolbarItem.name,
12863
12900
  name: toolbarItem.name,
12864
12901
  hidden,
@@ -12875,6 +12912,7 @@ var __publicField = (obj, key, value) => {
12875
12912
  return /* @__PURE__ */ React__namespace.createElement(
12876
12913
  ToolbarItem,
12877
12914
  {
12915
+ tinaForm,
12878
12916
  key: toolbarItem.name,
12879
12917
  name: toolbarItem.name,
12880
12918
  hidden,
@@ -13004,7 +13042,14 @@ var __publicField = (obj, key, value) => {
13004
13042
  children: value
13005
13043
  });
13006
13044
  },
13007
- firstChildren: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Toolbar, { templates: props.field.templates, inlineOnly: false }), /* @__PURE__ */ React.createElement(FloatingLink, null))
13045
+ firstChildren: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
13046
+ Toolbar,
13047
+ {
13048
+ tinaForm: props.tinaForm,
13049
+ templates: props.field.templates,
13050
+ inlineOnly: false
13051
+ }
13052
+ ), /* @__PURE__ */ React.createElement(FloatingLink, null))
13008
13053
  }
13009
13054
  ));
13010
13055
  };
@@ -26756,6 +26801,13 @@ var __publicField = (obj, key, value) => {
26756
26801
  getLoginStrategy() {
26757
26802
  return "Redirect";
26758
26803
  }
26804
+ /**
26805
+ * A React component that renders the custom UI for the login screen.
26806
+ * Set the LoginStrategy to LoginScreen when providing this function.
26807
+ */
26808
+ getLoginScreen() {
26809
+ return null;
26810
+ }
26759
26811
  getSessionProvider() {
26760
26812
  return DefaultSessionProvider;
26761
26813
  }
@@ -27787,13 +27839,18 @@ mutation addPendingDocumentMutation(
27787
27839
  const AuthWallInner = ({
27788
27840
  children,
27789
27841
  cms,
27790
- loginScreen,
27791
27842
  getModalActions
27792
27843
  }) => {
27793
- var _a, _b, _c;
27844
+ var _a, _b, _c, _d;
27794
27845
  const client = cms.api.tina;
27795
27846
  const isTinaCloud = !client.isLocalMode && !((_c = (_b = (_a = client.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.contentApiUrlOverride);
27796
27847
  const loginStrategy = client.authProvider.getLoginStrategy();
27848
+ const loginScreen = client.authProvider.getLoginScreen();
27849
+ if (loginStrategy === "LoginScreen" && !loginScreen) {
27850
+ throw new Error(
27851
+ "LoginScreen is set as the login strategy but no login screen component was provided"
27852
+ );
27853
+ }
27797
27854
  const [activeModal, setActiveModal] = React.useState(null);
27798
27855
  const [errorMessage, setErrorMessage] = React.useState();
27799
27856
  const [showChildren, setShowChildren] = React.useState(false);
@@ -27855,10 +27912,12 @@ mutation addPendingDocumentMutation(
27855
27912
  setActiveModal(null);
27856
27913
  }
27857
27914
  }) : [];
27858
- const handleAuthenticate = async () => {
27915
+ const handleAuthenticate = async (loginScreenProps) => {
27859
27916
  try {
27860
27917
  setAuthenticated(false);
27861
- const token = await client.authProvider.authenticate(authProps);
27918
+ const token = await client.authProvider.authenticate(
27919
+ loginScreenProps || authProps
27920
+ );
27862
27921
  if (typeof (client == null ? void 0 : client.onLogin) === "function") {
27863
27922
  await (client == null ? void 0 : client.onLogin({ token }));
27864
27923
  }
@@ -27972,6 +28031,7 @@ mutation addPendingDocumentMutation(
27972
28031
  await authProvider.logout();
27973
28032
  if (typeof (client == null ? void 0 : client.onLogout) === "function") {
27974
28033
  await client.onLogout();
28034
+ await new Promise((resolve) => setTimeout(resolve, 500));
27975
28035
  }
27976
28036
  window.location.href = new URL(window.location.href).pathname;
27977
28037
  } catch (e) {
@@ -27987,7 +28047,9 @@ mutation addPendingDocumentMutation(
27987
28047
  }
27988
28048
  ]
27989
28049
  }
27990
- ), showChildren ? children : loginScreen ? loginScreen : null);
28050
+ ), showChildren ? children : ((_d = client.authProvider) == null ? void 0 : _d.getLoginStrategy()) === "LoginScreen" && loginScreen ? loginScreen({
28051
+ handleAuthenticate: async (props) => handleAuthenticate(props)
28052
+ }) : null);
27991
28053
  };
27992
28054
  const TinaCloudProvider = (props) => {
27993
28055
  var _a, _b, _c;
@@ -28895,6 +28957,7 @@ This will work when developing locally but NOT when deployed to production.
28895
28957
  await ((_f = (_e = (_d = cms == null ? void 0 : cms.api) == null ? void 0 : _d.tina) == null ? void 0 : _e.authProvider) == null ? void 0 : _f.logout());
28896
28958
  if ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout) {
28897
28959
  await ((_j = (_i = cms == null ? void 0 : cms.api) == null ? void 0 : _i.tina) == null ? void 0 : _j.onLogout());
28960
+ await new Promise((resolve) => setTimeout(resolve, 500));
28898
28961
  }
28899
28962
  }
28900
28963
  setEdit(false);
package/dist/index.mjs CHANGED
@@ -3070,6 +3070,9 @@ function MdArrowForward(props) {
3070
3070
  function MdSyncProblem(props) {
3071
3071
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0z" } }, { "tag": "path", "attr": { "d": "M3 12c0 2.21.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24A6.003 6.003 0 015 12a5.99 5.99 0 014-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24A6.003 6.003 0 0119 12a5.99 5.99 0 01-4 5.65v2.09c3.45-.89 6-4.01 6-7.74 0-2.21-.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z" } }] })(props);
3072
3072
  }
3073
+ function MdOutlineHelpOutline(props) {
3074
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z" } }] })(props);
3075
+ }
3073
3076
  function MdOutlineSettings(props) {
3074
3077
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46a.5.5 0 00-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0014 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.566.566 0 00-.18-.03c-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46a.5.5 0 00.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73 0 .21-.02.43-.05.73l-.14 1.13.89.7 1.08.84-.7 1.21-1.27-.51-1.04-.42-.9.68c-.43.32-.84.56-1.25.73l-1.06.43-.16 1.13-.2 1.35h-1.4l-.19-1.35-.16-1.13-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7-1.06.43-1.27.51-.7-1.21 1.08-.84.89-.7-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13-.89-.7-1.08-.84.7-1.21 1.27.51 1.04.42.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43.16-1.13.2-1.35h1.39l.19 1.35.16 1.13 1.06.43c.43.18.83.41 1.23.71l.91.7 1.06-.43 1.27-.51.7 1.21-1.07.85-.89.7.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" } }] })(props);
3075
3078
  }
@@ -3091,6 +3094,9 @@ function MdOutlineArrowBackIos(props) {
3091
3094
  function MdOutlineArrowBack(props) {
3092
3095
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" } }] })(props);
3093
3096
  }
3097
+ function MdOutlinePerson(props) {
3098
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "d": "M0 0h24v24H0V0z" } }, { "tag": "path", "attr": { "d": "M12 6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0 10c2.7 0 5.8 1.29 6 2H6c.23-.72 3.31-2 6-2m0-12C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 10c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" } }] })(props);
3099
+ }
3094
3100
  const BranchContext = React.createContext({
3095
3101
  currentBranch: null,
3096
3102
  setCurrentBranch: (branch) => {
@@ -8873,6 +8879,9 @@ const Nav = ({
8873
8879
  await ((_d = cms.api.tina) == null ? void 0 : _d.authProvider.logout());
8874
8880
  if ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout) {
8875
8881
  await ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout());
8882
+ await new Promise(
8883
+ (resolve) => setTimeout(resolve, 500)
8884
+ );
8876
8885
  }
8877
8886
  window.location.href = new URL(
8878
8887
  window.location.href
@@ -10313,6 +10322,7 @@ function UpdatePassword(props) {
10313
10322
  (_a = client == null ? void 0 : client.authProvider) == null ? void 0 : _a.logout().then(async () => {
10314
10323
  if (typeof (client == null ? void 0 : client.onLogout) === "function") {
10315
10324
  await client.onLogout();
10325
+ await new Promise((resolve) => setTimeout(resolve, 500));
10316
10326
  }
10317
10327
  window.location.href = new URL(window.location.href).pathname;
10318
10328
  }).catch((e) => console.error(e));
@@ -10456,7 +10466,18 @@ class TinaCMS extends CMS {
10456
10466
  link: {
10457
10467
  text: "User Management",
10458
10468
  href: `https://app.tina.io/projects/${clientId}/collaborators`
10459
- }
10469
+ },
10470
+ Icon: MdOutlinePerson
10471
+ })
10472
+ );
10473
+ this.plugins.add(
10474
+ createCloudConfig({
10475
+ name: "Support",
10476
+ link: {
10477
+ text: "Support",
10478
+ href: `https:/tina.io/docs/support`
10479
+ },
10480
+ Icon: MdOutlineHelpOutline
10460
10481
  })
10461
10482
  );
10462
10483
  } else if (!isSelfHosted) {
@@ -11415,6 +11436,7 @@ const NestedForm = (props) => {
11415
11436
  const form = React__default.useMemo(() => {
11416
11437
  return new Form({
11417
11438
  ...props,
11439
+ relativePath: props.id,
11418
11440
  id,
11419
11441
  onChange: ({ values }) => {
11420
11442
  props.onChange(values);
@@ -12338,7 +12360,7 @@ const LinkForm = (props) => {
12338
12360
  return /* @__PURE__ */ React__default.createElement(
12339
12361
  NestedForm,
12340
12362
  {
12341
- id: "link-form",
12363
+ id: props.id,
12342
12364
  label: "Link",
12343
12365
  fields: [
12344
12366
  { label: "URL", name: "url", component: "text" },
@@ -12379,7 +12401,8 @@ const ToolbarItem = ({
12379
12401
  icon,
12380
12402
  options,
12381
12403
  name,
12382
- isLastItem = false
12404
+ isLastItem = false,
12405
+ tinaForm
12383
12406
  }) => {
12384
12407
  const editor = useEditorState();
12385
12408
  const [selection, setSelection] = React__default.useState(null);
@@ -12468,6 +12491,7 @@ const ToolbarItem = ({
12468
12491
  ), isExpanded && /* @__PURE__ */ React__default.createElement(
12469
12492
  LinkForm,
12470
12493
  {
12494
+ id: tinaForm.id,
12471
12495
  selection,
12472
12496
  onClose: () => {
12473
12497
  setIsExpanded(false);
@@ -12693,7 +12717,8 @@ const headers = [
12693
12717
  const ICON_WIDTH = 40;
12694
12718
  const EMBED_ICON_WIDTH = 85;
12695
12719
  function Toolbar({
12696
- templates
12720
+ templates,
12721
+ tinaForm
12697
12722
  }) {
12698
12723
  const { setRawMode } = useEditorContext();
12699
12724
  const showEmbed = templates.length > 0;
@@ -12710,6 +12735,7 @@ function Toolbar({
12710
12735
  const isImgActive = helpers.isNodeActive(editor, ELEMENT_IMG);
12711
12736
  const toolbarItems = [
12712
12737
  {
12738
+ tinaForm,
12713
12739
  name: "heading",
12714
12740
  label: "Heading",
12715
12741
  active: false,
@@ -12730,16 +12756,19 @@ function Toolbar({
12730
12756
  ))
12731
12757
  },
12732
12758
  {
12759
+ tinaForm,
12733
12760
  name: "link",
12734
12761
  label: "Link",
12735
12762
  active: isLinkActive2
12736
12763
  },
12737
12764
  {
12765
+ tinaForm,
12738
12766
  name: "image",
12739
12767
  label: "Image",
12740
12768
  active: isImgActive
12741
12769
  },
12742
12770
  {
12771
+ tinaForm,
12743
12772
  name: "quote",
12744
12773
  label: "Quote",
12745
12774
  active: blockQuoteActive,
@@ -12750,6 +12779,7 @@ function Toolbar({
12750
12779
  }
12751
12780
  },
12752
12781
  {
12782
+ tinaForm,
12753
12783
  name: "ul",
12754
12784
  label: "Bullet List",
12755
12785
  active: ulActive,
@@ -12760,6 +12790,7 @@ function Toolbar({
12760
12790
  }
12761
12791
  },
12762
12792
  {
12793
+ tinaForm,
12763
12794
  name: "ol",
12764
12795
  label: "List",
12765
12796
  active: olActive,
@@ -12770,6 +12801,7 @@ function Toolbar({
12770
12801
  }
12771
12802
  },
12772
12803
  {
12804
+ tinaForm,
12773
12805
  name: "code",
12774
12806
  label: "Code",
12775
12807
  active: isCodeActive,
@@ -12780,6 +12812,7 @@ function Toolbar({
12780
12812
  }
12781
12813
  },
12782
12814
  {
12815
+ tinaForm,
12783
12816
  name: "codeBlock",
12784
12817
  label: "Code Block",
12785
12818
  active: codeBlockActive,
@@ -12790,6 +12823,7 @@ function Toolbar({
12790
12823
  }
12791
12824
  },
12792
12825
  {
12826
+ tinaForm,
12793
12827
  name: "bold",
12794
12828
  label: "Bold",
12795
12829
  active: isBoldActive,
@@ -12800,6 +12834,7 @@ function Toolbar({
12800
12834
  }
12801
12835
  },
12802
12836
  {
12837
+ tinaForm,
12803
12838
  name: "italic",
12804
12839
  label: "Italic",
12805
12840
  active: isItalicActive,
@@ -12810,6 +12845,7 @@ function Toolbar({
12810
12845
  }
12811
12846
  },
12812
12847
  {
12848
+ tinaForm,
12813
12849
  name: "raw",
12814
12850
  label: "Raw",
12815
12851
  active: false,
@@ -12867,6 +12903,7 @@ function Toolbar({
12867
12903
  return /* @__PURE__ */ React.createElement(
12868
12904
  ToolbarItem,
12869
12905
  {
12906
+ tinaForm,
12870
12907
  key: toolbarItem.name,
12871
12908
  name: toolbarItem.name,
12872
12909
  hidden,
@@ -12883,6 +12920,7 @@ function Toolbar({
12883
12920
  return /* @__PURE__ */ React.createElement(
12884
12921
  ToolbarItem,
12885
12922
  {
12923
+ tinaForm,
12886
12924
  key: toolbarItem.name,
12887
12925
  name: toolbarItem.name,
12888
12926
  hidden,
@@ -13012,7 +13050,14 @@ const RichEditor = (props) => {
13012
13050
  children: value
13013
13051
  });
13014
13052
  },
13015
- firstChildren: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Toolbar, { templates: props.field.templates, inlineOnly: false }), /* @__PURE__ */ React__default.createElement(FloatingLink, null))
13053
+ firstChildren: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
13054
+ Toolbar,
13055
+ {
13056
+ tinaForm: props.tinaForm,
13057
+ templates: props.field.templates,
13058
+ inlineOnly: false
13059
+ }
13060
+ ), /* @__PURE__ */ React__default.createElement(FloatingLink, null))
13016
13061
  }
13017
13062
  ));
13018
13063
  };
@@ -26764,6 +26809,13 @@ class AbstractAuthProvider {
26764
26809
  getLoginStrategy() {
26765
26810
  return "Redirect";
26766
26811
  }
26812
+ /**
26813
+ * A React component that renders the custom UI for the login screen.
26814
+ * Set the LoginStrategy to LoginScreen when providing this function.
26815
+ */
26816
+ getLoginScreen() {
26817
+ return null;
26818
+ }
26767
26819
  getSessionProvider() {
26768
26820
  return DefaultSessionProvider;
26769
26821
  }
@@ -27795,13 +27847,18 @@ function sleep(ms) {
27795
27847
  const AuthWallInner = ({
27796
27848
  children,
27797
27849
  cms,
27798
- loginScreen,
27799
27850
  getModalActions
27800
27851
  }) => {
27801
- var _a, _b, _c;
27852
+ var _a, _b, _c, _d;
27802
27853
  const client = cms.api.tina;
27803
27854
  const isTinaCloud = !client.isLocalMode && !((_c = (_b = (_a = client.schema) == null ? void 0 : _a.config) == null ? void 0 : _b.config) == null ? void 0 : _c.contentApiUrlOverride);
27804
27855
  const loginStrategy = client.authProvider.getLoginStrategy();
27856
+ const loginScreen = client.authProvider.getLoginScreen();
27857
+ if (loginStrategy === "LoginScreen" && !loginScreen) {
27858
+ throw new Error(
27859
+ "LoginScreen is set as the login strategy but no login screen component was provided"
27860
+ );
27861
+ }
27805
27862
  const [activeModal, setActiveModal] = useState(null);
27806
27863
  const [errorMessage, setErrorMessage] = useState();
27807
27864
  const [showChildren, setShowChildren] = useState(false);
@@ -27863,10 +27920,12 @@ const AuthWallInner = ({
27863
27920
  setActiveModal(null);
27864
27921
  }
27865
27922
  }) : [];
27866
- const handleAuthenticate = async () => {
27923
+ const handleAuthenticate = async (loginScreenProps) => {
27867
27924
  try {
27868
27925
  setAuthenticated(false);
27869
- const token = await client.authProvider.authenticate(authProps);
27926
+ const token = await client.authProvider.authenticate(
27927
+ loginScreenProps || authProps
27928
+ );
27870
27929
  if (typeof (client == null ? void 0 : client.onLogin) === "function") {
27871
27930
  await (client == null ? void 0 : client.onLogin({ token }));
27872
27931
  }
@@ -27980,6 +28039,7 @@ const AuthWallInner = ({
27980
28039
  await authProvider.logout();
27981
28040
  if (typeof (client == null ? void 0 : client.onLogout) === "function") {
27982
28041
  await client.onLogout();
28042
+ await new Promise((resolve) => setTimeout(resolve, 500));
27983
28043
  }
27984
28044
  window.location.href = new URL(window.location.href).pathname;
27985
28045
  } catch (e) {
@@ -27995,7 +28055,9 @@ const AuthWallInner = ({
27995
28055
  }
27996
28056
  ]
27997
28057
  }
27998
- ), showChildren ? children : loginScreen ? loginScreen : null);
28058
+ ), showChildren ? children : ((_d = client.authProvider) == null ? void 0 : _d.getLoginStrategy()) === "LoginScreen" && loginScreen ? loginScreen({
28059
+ handleAuthenticate: async (props) => handleAuthenticate(props)
28060
+ }) : null);
27999
28061
  };
28000
28062
  const TinaCloudProvider = (props) => {
28001
28063
  var _a, _b, _c;
@@ -28903,6 +28965,7 @@ const LogoutRedirect = () => {
28903
28965
  await ((_f = (_e = (_d = cms == null ? void 0 : cms.api) == null ? void 0 : _d.tina) == null ? void 0 : _e.authProvider) == null ? void 0 : _f.logout());
28904
28966
  if ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout) {
28905
28967
  await ((_j = (_i = cms == null ? void 0 : cms.api) == null ? void 0 : _i.tina) == null ? void 0 : _j.onLogout());
28968
+ await new Promise((resolve) => setTimeout(resolve, 500));
28906
28969
  }
28907
28970
  }
28908
28971
  setEdit(false);
@@ -19,6 +19,11 @@ export declare abstract class AbstractAuthProvider implements AuthProvider {
19
19
  isAuthorized(context?: any): Promise<boolean>;
20
20
  isAuthenticated(): Promise<boolean>;
21
21
  getLoginStrategy(): LoginStrategy;
22
+ /**
23
+ * A React component that renders the custom UI for the login screen.
24
+ * Set the LoginStrategy to LoginScreen when providing this function.
25
+ */
26
+ getLoginScreen(): any;
22
27
  getSessionProvider(): import("react").FC<{}>;
23
28
  abstract getToken(): any;
24
29
  abstract getUser(): any;
@@ -1,10 +1,13 @@
1
1
  /// <reference types="react" />
2
2
  import type { MdxTemplate } from '../../../types';
3
- export declare function Toolbar({ templates, }: {
3
+ import type { Form } from '../../../../../../../forms';
4
+ export declare function Toolbar({ templates, tinaForm, }: {
5
+ tinaForm: Form;
4
6
  inlineOnly: boolean;
5
7
  templates: MdxTemplate[];
6
8
  }): JSX.Element;
7
- export declare const FloatingToolbar: ({ templates, }: {
9
+ export declare const FloatingToolbar: ({ templates, tinaForm, }: {
10
+ tinaForm: Form;
8
11
  templates: MdxTemplate[];
9
12
  }) => JSX.Element;
10
13
  export declare const FloatingLink: () => JSX.Element;
@@ -1,6 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import type { PlateEditor } from '@udecode/plate-headless';
3
3
  import type { MdxTemplate } from '../../../types';
4
+ import { Form } from '../../../../../../../forms';
4
5
  export declare type ToolbarItemType = {
5
6
  label: string;
6
7
  name: string;
@@ -11,8 +12,9 @@ export declare type ToolbarItemType = {
11
12
  icon?: string;
12
13
  options?: {}[];
13
14
  isLastItem?: boolean;
15
+ tinaForm: Form;
14
16
  };
15
- export declare const ToolbarItem: ({ hidden, label, active, onMouseDown, icon, options, name, isLastItem, }: ToolbarItemType) => JSX.Element;
17
+ export declare const ToolbarItem: ({ hidden, label, active, onMouseDown, icon, options, name, isLastItem, tinaForm, }: ToolbarItemType) => JSX.Element;
16
18
  export declare const EmbedButton: ({ editor, templates, }: {
17
19
  editor: PlateEditor;
18
20
  templates: MdxTemplate[];
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from '../core';
2
+ import type { IconType } from 'react-icons';
2
3
  /**
3
4
  * Represents a Tina Cloud Config that should be accessible via the CMS.
4
5
  *
@@ -28,6 +29,7 @@ export interface CloudConfigOptions {
28
29
  text: string;
29
30
  href: string;
30
31
  };
32
+ Icon?: IconType;
31
33
  }
32
34
  /**
33
35
  * Creates cloud config plugins.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinacms",
3
- "version": "1.5.26",
3
+ "version": "1.5.27",
4
4
  "main": "dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "exports": {
@@ -69,9 +69,9 @@
69
69
  "@react-types/combobox": "^3.2.0",
70
70
  "@react-types/shared": "^3.10.0",
71
71
  "@sambego/storybook-styles": "^1.0.0",
72
- "@tinacms/schema-tools": "1.4.14",
73
- "@tinacms/search": "1.0.15",
74
- "@tinacms/mdx": "1.3.22",
72
+ "@tinacms/schema-tools": "1.4.15",
73
+ "@tinacms/search": "1.0.16",
74
+ "@tinacms/mdx": "1.3.23",
75
75
  "@tinacms/sharedctx": "1.0.2",
76
76
  "@udecode/plate-headless": "^21.4.0",
77
77
  "atob": "2.1.2",