繁体   English   中英

如何在 Chakra UI 模态中将回调附加到 Google 选择器?

[英]How do I attach a callback to the Google Picker in a Chakra UI Modal?

我正在尝试将Google Picker集成到我的应用程序中,并且 UI 按预期完美显示,但我似乎无法让它调用我尝试附加到它的任何回调。

有两种使用 Picker 的方法,我更喜欢选项 1,但我都可以

选项 1:将 Picker 构建为 URL 以在自定义模式中呈现

我在 React(特别是 Chakra)中构建我的应用程序,我更喜欢使用 Chakra 的<Popover>元素来帮助 Picker 与页面的 rest 融合。

使用这条路线,这是我到目前为止的相关代码:

function getPicker(callback) {
  const view = new google.picker.DocsView(google.picker.ViewId.FOLDERS);
  view.setSelectFolderEnabled(true);

  return (
    new google.picker.PickerBuilder()
      .addView(view)
      .setSelectableMimeTypes("application/vnd.google-apps.folder")
      .setTitle("")
      .setCallback(callback)
      .enableFeature(google.picker.Feature.NAV_HIDDEN)
      .setOAuthToken(getAccessToken() /* defined elsewhere - assume this works */)
      .setDeveloperKey(process.env.API_KEY)
      .setOrigin(window.location.host)
      .toUri();
  );
}

// This is an event listener 
function showPicker() {
  function handleFolderSelected(folder) {
    const { Response, Action, Document } = google.picker;

    if (folder[Response.ACTION] === Action.PICKED) {
      const targetFolder = folder[Response.DOCUMENTS][0][Document.ID];
      // do stuff
    }

    setIsFolderPickerOpen(false); // closes the <Popover>
  }

  const pickerUrl = getPicker(handleFolderSelected);

  // Opens the <Popover> and sets the source of an iframe inside to the url
  setPickerUrl(pickerUrl);
  setIsFolderPickerOpen(true);
}

方案二:让 Picker 自己构建 iframe

如果有必要,虽然我不认为它在视觉上很吸引人,但我可以走这条路。 这是到目前为止我为此选项尝试的代码(大部分相同,但不完全相同)

function getPicker(callback) {
  const view = new google.picker.DocsView(google.picker.ViewId.FOLDERS);
  view.setSelectFolderEnabled(true);

  return (
    new google.picker.PickerBuilder()
      .addView(view)
      .setSelectableMimeTypes("application/vnd.google-apps.folder")
      .setTitle("")
      .setCallback(callback)
      .enableFeature(google.picker.Feature.NAV_HIDDEN)
      .setOAuthToken(getAccessToken() /* defined elsewhere - assume this works */)
      .setDeveloperKey(process.env.API_KEY)
      .setOrigin(window.location.host)
      .build();
  );
}

// This is an event listener 
function showPicker() {
  function handleFolderSelected(folder) {
    const { Response, Action, Document } = google.picker;

    if (folder[Response.ACTION] === Action.PICKED) {
      const targetFolder = folder[Response.DOCUMENTS][0][Document.ID];
      // do stuff
    }
  }

  const picker = getPicker(handleFolderSelected);
  picker.setVisible(true);
}

其他信息

我已经尝试在 Stack 中搜索这个问题,但是我没有找到任何专门针对这个问题的东西,所以我不认为它是重复的。 我发现的最接近的是这个,其中一个未接受的答案中的评论表明可能不可能通过选项 1 附加回调,但我不能确定

我还注意到有几次来自 Picker 的消息被发布到父 window 当我期望回调被调用时,所以我试图抓住它,但它没有被持续地触发。

对此的任何帮助将不胜感激!

事实证明,问题不在于 Google Picker(感谢 iansedano 为我提供了一个可以解决的工作示例!)

问题是,出于可访问性的原因,Chakra UI 陷阱集中在模态中。 这通常是一件好事,但是由于 Picker 的工作方式,每次您尝试单击“选择文件”按钮时,Chakra 都会在 Picker 处理单击之前将焦点抢回模态框的关闭按钮。

解决方案是使用以下属性来“解开”焦点。 注意:我建议仅在 Picker 打开时临时执行此操作。 在所有其他情况下,焦点陷印是一件好事。

import { Modal } from "@chakra-ui/react"

function Component() {
  return (
    <Modal trapFocus={false}>
      ...
    </Modal>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM