Communitygithub.com

stopsopa/skill-popover-api

基于原生 Popover API 和自定义 CSS 的弹出框技能,支持多种定位、触发方式,兼容任意框架。

skill-popover-api 是什么?

本技能为开发者提供了基于现代浏览器原生 Popover API 的增强型弹出框解决方案。它通过一个核心 CSS 文件 `assets/popover.css` 实现对弹出框的精确定位和样式控制。开发者只需在弹出框元素上添加 `data-popover` 属性即可激活定制样式,而无需担心与原生 API 的冲突(不使用该属性时,技能不会干预原生行为)。技能支持通过 `popovertarget`(点击触发)和 `interestfor`(鼠标悬停触发)两种模式显示弹出框,并允许通过 `popover="manual"` 控制关闭方式(仅通过按钮关闭)。定位方面提供了丰富的 CSS 类,包括上、下、左、右、角落对齐(如 top-left、bottom-right)以及覆盖定位(center),用户可通过交互式演示页面直观选择。该技能完全框架无关,可直接用于原生 HTML、React、Angular、Svelte 等任何环境,只需确保 CSS 已加载且 HTML 结构符合示例即可。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add stopsopa/skill-popover-api

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

如果该文件相对于我们的本地副本有更新,则我们的本地副本必须同步更新。

当首次被要求使用 popover API 时,请先将文件 assets/popover.css 复制到项目中的某个位置。

如果不清楚应将该文件复制到项目的具体位置以及加载方式,建议与用户协商。

但本质上,它只是一个简单的平面 CSS 文件。如果框架中存在加载该类文件的常规位置,请遵循合理的标准。 只需注意出于人体工学原因避免重复加载。

弹出框何时在锚点点击时显示

使用我们的 core-css 来定位弹出框时,基本结构如下:

<button popovertarget="mypopover2">切换弹出框</button>
<div id="mypopover2" popover data-popover>
  弹出框内容
  <button popovertarget="mypopover2" popovertargetaction="hide">关闭</button>
</div>

在上面的示例中,我们有一个按钮作为锚点。点击按钮将显示弹出框(带有 [popover] 属性的元素),再次点击将隐藏弹出框。

此外,点击弹出框内部不会隐藏它,除非点击“关闭”按钮——该按钮会关闭它。

同时,点击弹出框外部区域将隐藏弹出框。

当你遵循此示例的结构时,它所做的不过是标准 Popover API 的功能。 并且请随意根据用户的用例进行任何修改。

注意:定义“关闭”按钮是可选的,没有它一切功能也完全正常。

因此,这种 HTML 结构是默认布局。

这里的关键是属性 data-popover,该属性激活了来自 assets/popover.css 的样式,这些样式主要负责将弹出框相对于锚点元素进行定位。

你可以不添加 [data-popover] 属性,但那样会失去我们的自定义样式,弹出框将表现为普通的原生元素。 当带有 [data-popover] 属性时,你正在使用本技能提供的样式;否则,你是在使用标准原生 Popover API,本技能可能无法提供帮助。直接根据标准 Popover API 实现你的需求即可。

但重点是,data-popover 属性作为明确的分隔符,区分了使用本技能提供的样式处理弹出框和手动处理的情况。因此,当未指定 [data-popover] 时,我们的 CSS 不会干扰你的手动 Popover API 实现。

总的来说,请随意使用 [data-popover] 来遵循我们的样式,或者在你更倾向于使用原生 Popover API 时避免使用它。

本文档中展示的示例可以被任何通常与标准原生 Popover API 一起使用的其他 JavaScript 和 HTML API 所控制。

<button popovertarget="mypopover3">切换弹出框</button>
<div id="mypopover3" popover="manual" data-popover>
  我们的弹出框内容
  <button popovertarget="mypopover3" popovertargetaction="hide">关闭</button>
</div>

此处我们仅在点击“关闭”按钮时关闭弹出框。

主要变化是 popover="manual" —— 当弹出框处于手动模式时,只能通过 JavaScript 或点击带有 popovertargetaction="hide" 的元素来关闭它。

在所有示例中,对于实现单个弹出框的 div 结构,请始终保持 id 的唯一性。 同时,确保 popovertarget 始终指向该特定 id,以保证这些 DOM 元素协同工作。

注意:在标准 Popover API 中,可以有多个锚点指向同一个弹出框。如果需要,这是自然允许的。

<button popovertarget="mypopover4">切换弹出框</button>
<div id="mypopover4" popover data-popover>
  弹出框内容
  <button popovertarget="mypopover4" popovertargetaction="hide">关闭</button>
</div>
<div class="container one">
  <button class="toolbar-button" interestfor="popover-b"><b>B</b></button>
  <button class="toolbar-button" interestfor="popover-i"><i>I</i></button>
  <button class="toolbar-button" interestfor="popover-u"><u>U</u></button>
</div>

<div class="container two">
  <button class="toolbar-button" interestfor="popover-b"><b>B</b></button>
  <button class="toolbar-button" interestfor="popover-i"><i>I</i></button>
  <button class="toolbar-button" interestfor="popover-u"><u>U</u></button>
</div>

<span popover="" id="popover-b" data-popover class="bottom">Bold</span>
<span popover="" id="popover-i" data-popover>Italic</span>
<span popover="" id="popover-u" data-popover>Underline</span>

上面有两组容器 -> class="container"(分别带有独立的类 'one' 和 'two')。 每个容器包含 3 个按钮。 每个按钮都有一个 'interestfor' 属性,指向 3 个弹出框中的 id。 请注意,我们有 2 个容器,每个容器有 3 个按钮,但只有 3 个弹出框。这实际上演示了一种关系: 多个悬停的元素可以触发显示同一个弹出框——这是允许的。

最重要的是:使用 'interestfor' 属性代替 'popovertarget' 将改变弹出框的显示方式。 使用 'interestfor' 将在鼠标悬停时显示弹出框。 而使用 'popovertarget' 将在点击时显示弹出框。

为了决定弹出框相对于锚点元素的具体位置,我们将使用我们的 core-css 文件。

如前所述,我们的 core-css 文件要求我们向 [popover] 元素添加 [data-popover] 属性。

从那时起,通过向带有 [data-popover] 属性的元素添加 CSS 类来控制弹出框相对于锚点元素的位置。

以下是可用的类:

  • 类 top:位于锚点上方,水平居中。(这是默认样式,即使未向 'data-popover' 元素添加任何类也会使用)

  • 类 bottom:位于锚点下方,水平居中。(这是默认样式,即使未向 'data-popover' 元素添加任何类也会使用)

  • 类 left:位于锚点左侧,垂直居中。(这是默认样式,即使未向 'data-popover' 元素添加任何类也会使用)

  • 类 right:位于锚点右侧,垂直居中。(这是默认样式,即使未向 'data-popover' 元素添加任何类也会使用)

  • 类 top-left:位于锚点上方,其左边缘与锚点的左边缘对齐。

  • 类 top-right:位于锚点上方,其右边缘与锚点的右边缘对齐。

  • 类 bottom-left:位于锚点下方,其左边缘与锚点的左边缘对齐。

  • 类 bottom-right:位于锚点下方,其右边缘与锚点的右边缘对齐。

  • 类 center:直接位于锚点上方,水平和垂直均居中。

  • 类 topleft:弹出框的右下角接触锚点的左上角。

  • 类 topright:弹出框的左下角接触锚点的右上角。

  • 类 bottomleft:弹出框的右上角接触锚点的左下角。

  • 类 bottomright:弹出框的左上角接触锚点的右下角。

  • 类 left-top:位于锚点左侧,其顶部边缘与锚点的顶部边缘对齐。

  • 类 left-bottom:位于锚点左侧,其底部边缘与锚点的底部边缘对齐。

  • 类 right-top:位于锚点右侧,其顶部边缘与锚点的顶部边缘对齐。

  • 类 right-bottom:位于锚点右侧,其底部边缘与锚点的底部边缘对齐。

最好从用户那里获取应使用哪个定位类的信息,但如果用户以描述方式指定了特定定位,则尝试根据描述自动找到最佳类。

如果用户或 AI 不确定使用哪个类,则建议用户访问主 GitHub 页面的演示页面,其中以交互方式展示了各类的行为:

https://stopsopa.github.io/skill-popover-api/demo/index.html

用户将能够观察哪个类为所讨论的弹出框提供了最佳的定位行为。

从该演示页面,用户也可以通过一次点击 ribbon 小部件,转到主 GitHub 页面以获取更多详细信息。

使用 'data-popover' 属性激活我们的 core-css 样式的 HTML 结构是通用的。

它可以用于原生 HTML、React、Angular、Svelte 等。

只要底层基本 HTML 与上述示例相匹配,并且 assets/popover.css 已在浏览器上下文中加载,它就会正常工作。

不过,有时可能需要使用一些标准的 React 包装器组件或任何特定于给定框架的其他结构/形式进行包装。

只需在以上示例的基础上,针对给定的框架上下文做正确的事。

相关技能