npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

yn-web-component

v1.0.6

Published

Floema-style Lit Web Components for DTC and cross-border e-commerce storefronts — navigation, SKU selector, checkout address, drawer, toast. Tree-shaking subpath exports.

Readme

yn-web-component

English(npm 包页仅展示本文件,英文完整文档见 GitHub)

面向独立站电商平台打造的 Lit + Web Components 组件库——从商品浏览、规格选择到跨境结账,提供统一、精致、可定制的界面能力,并支持按需导入与跨框架复用。

目录

灵感来源

交互动效与视觉质感参考独立站品牌站 Floema——克制、细腻、有呼吸感的电商体验,是本组件库在视觉与动效上的重要参照。

项目介绍

yn-web-component 是一套为跨境独立站 / DTC 电商场景设计的 Web Components 组件库。它不绑定 React、Vue 或任何特定前端框架,而是以浏览器标准能力封装可复用的 yn-* 自定义元素,帮助团队在商品站、结账流、运营后台之间共享同一套交互与视觉语言。

独立站往往要面对多语言、多币种、多地区配送、SKU 规格联动、移动端结账等复杂需求。本库将其中高频、难啃、易不一致的部分沉淀为组件——例如跨境地址的多数据源降级、多维 SKU 联动加购、响应式购物车抽屉、SEO 友好导航等——让业务层专注在商品与订单逻辑,而不是反复实现同一套 UI 细节。

适用场景

| 场景 | 相关组件 | | --- | --- | | 站点导航与品牌入口 | yn-navigationyn-icon-connect-buttonyn-search | | 商品详情与规格选择 | yn-sku-selectoryn-quantityyn-group-pickyn-pick | | 筛选、语言与运营配置 | yn-dropdownyn-dropdown-pick | | 购物车与侧边流程 | yn-draweryn-toast | | 跨境结账与地址采集 | yn-checkout-address | | 通用表单与操作反馈 | yn-buttonyn-input | | 主题氛围与特色交互 | yn-pull-cord-switch |

为什么选择这套方案

  • 为电商而生:覆盖浏览、选购、加购、结账等独立站核心链路,而非通用 UI 拼凑
  • 跨境开箱即用:地址组件内置 Google → dr5hn → Photon → manual 降级策略,适配多地区配送
  • 跨框架复用:基于 Web Components,同一套组件可用于 React / Vue / Angular / 原生页面
  • 品牌可定制:Shadow DOM 隔离样式,通过 --yn-* CSS 变量与 variant 语义层灵活换肤
  • 按需加载:组件级子路径导入,配合 Tree Shaking 控制首屏体积
  • 文档与工程完备:Storybook 交互文档 + 完整 API 参考 + 测试与 lint 流水线

技术特性

  • 标准化交付:ESM / CJS 双格式,支持 npm 发布与 <script> 直引
  • 样式隔离:默认 Shadow DOM,减少主题样式与组件内部互相污染
  • 扩展友好:属性、事件、插槽、CSS 变量四层公开 API,满足业务二次封装
  • 可维护:Vite + Vitest + Web Test Runner + Storybook + Changesets

打包体积

以下数据来自本地 pnpm build ESM 产物(v1.0.2,构建日期 2026-06-05)。按需导入路径:yn-web-component/components/<name>。完整表格见文档站 #/bundle-size

| 组件 | ESM | gzip | 备注 | | --- | --- | --- | --- | | yn-pick | 3.96 kB | 1.65 kB | | | yn-group-pick | 4.71 kB | 1.97 kB | | | yn-input | 8.41 kB | 2.39 kB | | | yn-quantity | 8.66 kB | 2.48 kB | | | yn-icon-connect-button | 11.61 kB | 3.92 kB | | | yn-button | 13.79 kB | 3.46 kB | | | yn-dropdown-pick | 14.88 kB | 4.54 kB | | | yn-dropdown | 17.06 kB | 4.78 kB | | | yn-drawer | 18.92 kB | 4.60 kB | | | yn-search | 20.46 kB | 5.98 kB | | | yn-toast | 21.53 kB | 5.42 kB | | | yn-navigation | 21.74 kB | 6.91 kB | | | yn-sku-selector | ~25.4 kB | ~6.33 kB | 入口 + 分包合计 | | yn-pull-cord-switch | 49.70 kB | 11.85 kB | 含绳物理引擎 | | yn-checkout-address | ~84.1 kB | ~20.6 kB | 入口 + 分包,含 dr5hn 逻辑 | | 全量 IIFE | 314.86 kB | 76.52 kB | dist/index.iife.js |

在线文档站

线上地址:web-components.yanan.store

pnpm dev   # http://localhost:5173/introduction — Floema 风格文档,含中英文、Live Preview、Storybook 链接

源码位于 app/,与 src/components 组件库分离。文档站使用 pathname 路由(如 /yn-button),便于 Google 收录;旧 #/yn-button 链接会自动跳转。

当前组件一览

| 组件 | 标签名 | 用途摘要 | | --- | --- | --- | | 按钮 | yn-button | 语义色按钮、加载态、图标插槽 | | 输入框 | yn-input | Floema 风格输入,前后置按钮插槽 | | 导航 | yn-navigation | 胶囊导航,支持 SEO 链接模式 | | 搜索 | yn-search | 可展开搜索框,支持 datalist | | 选项组 | yn-group-pick | 单选/多选容器,配合 yn-pick | | 选项 | yn-pick | 单个可选项 | | 下拉弹层 | yn-dropdown | 通用下拉定位弹层 | | 下拉选择 | yn-dropdown-pick | 下拉单选器 | | 抽屉 | yn-drawer | 响应式侧滑/底部抽屉 | | 提示 | yn-toast | 灵动岛风格顶部反馈 | | 图标连接按钮 | yn-icon-connect-button | 带图标连接动画的按钮/链接 | | 抽绳开关 | yn-pull-cord-switch | 物理绳动画开关 | | 数量选择 | yn-quantity | 加减数量输入 | | 结账地址 | yn-checkout-address | 跨境地址表单(多数据源降级) | | SKU 选择器 | yn-sku-selector | 多维规格联动与加购 |

安装与导入

安装

pnpm add yn-web-component
# 或 npm i yn-web-component
# 或 yarn add yn-web-component

导入方式

1) 全量注册(最简单)

适合中小项目或后台系统,一次性注册所有组件:

import "yn-web-component/define";

2) 主入口按需导出类

import { YnSearch, YnNavigation } from "yn-web-component";

3) 组件级子路径导入(推荐,Tree Shaking 更友好)

import { YnSearch } from "yn-web-component/components/yn-search";
import { YnNavigation } from "yn-web-component/components/yn-navigation";

4) 浏览器 <script> 直引(UMD / IIFE)

适合无打包器场景:

<script src="https://unpkg.com/lit@3/index.js?module"></script>
<script src="https://unpkg.com/yn-web-component/dist/index.iife.js"></script>

<yn-search></yn-search>

Tree Shaking 建议

  1. 优先使用 yn-web-component/components/* 子路径导入
  2. 不要在按需场景里使用 yn-web-component/define(它会全量注册)
  3. 在业务构建工具中保持 ESM 模式(Vite/Rollup/Webpack5 默认支持)

通用约定

Shadow DOM 样式隔离

所有组件均使用 Shadow DOM。外部 CSS 选择器默认不会穿透到组件内部,请通过:

  • 组件公开 CSS 变量--yn-* 前缀)
  • 组件 属性 控制行为与基础样式

进行定制。可在宿主元素上设置 style="--yn-button-bg: #22c55e" 覆写变量。

属性绑定

在 Lit / 原生 JS 中,对象与数组属性需使用 属性绑定. 前缀),而非字符串属性:

<!-- Lit -->
<yn-navigation .items=${{ HOME: "/", ABOUT: "/about" }} active="HOME"></yn-navigation>

<!-- 原生 JS -->
el.items = { HOME: "/", ABOUT: "/about" };

布尔属性可用 ?attr=${true}(Lit)或 el.disabled = true

事件监听

自定义事件通过 @event-name(Lit)或 addEventListener 监听。本文档中 detailCustomEvent.detail 结构;原生 DOM 事件(如 click)无 detail 字段。

主题样式

可选引入全局主题:

import "yn-web-component/theme.css";

组件文档

以下文档与组件实现、Storybook argTypes 保持一致。每个组件均标注 按需导入路径属性事件插槽CSS 变量公开方法(如有)。


yn-button

标签名yn-button
类名YnButton
导入yn-web-component/components/yn-button
用途:基础按钮,支持语义色 variant、尺寸 size、加载态、热区扩展与前后图标插槽。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | disabled | boolean | false | 禁用,阻止点击 | | variant | "primary" \| "success" \| "warning" \| "danger" \| "neutral" \| "dark" \| "default" | "primary" | 语义色主题 | | size | "mini" \| "small" \| "medium" | "medium" | 尺寸(影响 padding 与 loading 图标大小) | | loading | boolean | false | 加载态,禁用点击并展示 loading | | loading-type | "left" \| "center" \| "right" | "left" | loading 图标相对文案的位置 | | hit-slop | boolean | true | 是否在四周扩展 5px 可点击热区 |

事件

| 事件 | 类型 | 说明 | | --- | --- | --- | | click | MouseEvent | 点击按钮时触发(disabledloading 时不触发) |

插槽

| 插槽 | 说明 | | --- | --- | | 默认插槽 | 按钮文案 | | prefix-icon | 前缀图标 | | suffix-icon | 后缀图标 | | loading | 自定义 loading 内容(loading=true 时展示;动画需自行添加) |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-button-bg | 背景色(默认由 variant 决定) | | --yn-button-hover-bg | 悬停背景色 | | --yn-button-disabled-bg | 禁用背景色 | | --yn-button-disabled-color | 禁用文字色 | | --yn-button-radius | 圆角 | | --yn-button-loading-size | loading 图标尺寸(随 size 变化:14/16/18px) |

示例

<yn-button variant="primary" @click=${onClick}>
  <span slot="prefix-icon">★</span>
  保存
</yn-button>

<!-- 局部覆写颜色 -->
<yn-button
  variant="success"
  style="--yn-button-bg: #22c55e; --yn-button-hover-bg: #16a34a;"
>
  自定义成功色
</yn-button>

yn-input

标签名yn-input
类名YnInput
导入yn-web-component/components/yn-input
用途:Floema 风格圆角输入框,可选前后置按钮插槽。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | value | string | "" | 当前输入值 | | placeholder | string | "请输入内容" | 占位文案 | | disabled | boolean | false | 禁用输入与按钮 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | yn-input | { value: string } | 输入内容变化 | | yn-prefix-click | { value: string } | 点击前置按钮 | | yn-suffix-click | { value: string } | 点击后置按钮 |

插槽

| 插槽 | 说明 | | --- | --- | | prefix-button | 前置按钮图标;未传入则不渲染 | | suffix-button | 后置按钮图标;未传入则不渲染 |

CSS 变量

| 变量 | 默认值 | 说明 | | --- | --- | --- | | --yn-input-width | 320px | 宽度 | | --yn-input-height | 44px | 高度 | | --yn-input-bg | rgba(255,255,255,0.62) | 背景 | | --yn-input-bg-hover | rgba(255,255,255,0.86) | 悬停背景 | | --yn-input-bg-focus | #fffaf2 | 聚焦背景 | | --yn-input-bg-disabled | rgba(232,225,214,0.76) | 禁用背景 | | --yn-input-border-color | rgba(36,31,33,0.22) | 边框色 | | --yn-input-border-color-hover | rgba(36,31,33,0.52) | 悬停边框 | | --yn-input-border-color-focus | #241f21 | 聚焦边框 | | --yn-input-color | #241f21 | 文本色 | | --yn-input-placeholder-color | rgba(36,31,33,0.48) | 占位色 | | --yn-input-disabled-color | rgba(36,31,33,0.42) | 禁用文本色 | | --yn-input-focus-ring | rgba(36,31,33,0.12) | 聚焦外圈 | | --yn-input-radius | 999px | 圆角 | | --yn-input-padding | 0 14px | 内边距 | | --yn-input-button-size | 28px | 按钮尺寸 | | --yn-input-button-color | #241f21 | 按钮图标色 | | --yn-input-button-bg-hover | rgba(36,31,33,0.08) | 按钮悬停背景 | | --yn-input-font-family | Zimula 等 | 字体 | | --yn-input-font-size | 16px | 字号 | | --yn-input-letter-spacing | -0.01em | 字距 |

示例

<yn-input placeholder="搜索" @yn-input=${(e) => console.log(e.detail.value)}>
  <span slot="suffix-button"><!-- SVG 图标 --></span>
</yn-input>

yn-navigation

标签名yn-navigation
类名YnNavigation
导入yn-web-component/components/yn-navigation
用途:胶囊式导航栏,支持受控切换或 SEO 链接模式。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | items | Record<string, string> | 内置 4 项 | key 为展示文案,value 为路径或上下文标识 | | active | string | "PRODUTOS" | 当前激活项的 key;seo-mode=true 时由 URL 自动匹配 | | seo-mode | boolean | false | true 时渲染 <a href> 链接,不派发 change | | aria-label | string | "Primary navigation" | 无障碍标签 | | hit-slop | boolean | false | 是否扩大可点击热区 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | { key: string; node: Record<string, string> } | 切换导航项(仅 seo-mode=false 时触发) |

插槽

无。

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-navigation-fill-color | 背景填充色 | | --yn-navigation-text-color | 普通文本色 | | --yn-navigation-active-text-color | 激活项文本色 | | --yn-navigation-indicator-color | 激活圆点颜色 | | --yn-navigation-focus-color | 键盘 focus 描边色 | | --yn-navigation-glow-color | 发光效果中心色 | | --yn-navigation-glow-fade | 发光渐隐色 |

示例

<!-- 受控模式 -->
<yn-navigation
  .items=${{ HOME: "/", ABOUT: "/about" }}
  active="HOME"
  @change=${(e) => { active = e.detail.key; }}
></yn-navigation>

<!-- SEO 链接模式 -->
<yn-navigation
  seo-mode
  .items=${{ Home: "/home", Products: "/products" }}
  aria-label="Primary navigation"
></yn-navigation>

yn-search

标签名yn-search
类名YnSearch
导入yn-web-component/components/yn-search
用途:可展开/收起的搜索框,支持原生 datalist 候选项。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | input-width | number | 514 | 展开后输入区宽度(px,不含按钮区) | | placeholder | string | "O que estás à procura?" | 占位文案 | | disabled | boolean | false | 禁用交互 | | close | boolean | false | true:有值时先清空、无值才收起;false:直接清空并收起 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | input | { value: string } | 输入内容变化 | | enter | { value: string } | 按下回车键 |

插槽

| 插槽 | 说明 | | --- | --- | | 默认插槽 | 传入 <datalist><option value="..."> 提供原生候选项 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-search-bg-active | 展开/悬停时背景色 | | --yn-search-bg-idle | 收起时背景色 | | --yn-search-icon-color | 图标颜色 | | --yn-search-fill-duration | 背景过渡时长 | | --yn-search-fill-ease | 背景过渡曲线 | | --yn-search-icon-duration | 图标过渡时长 | | --yn-search-icon-ease | 图标过渡曲线 |

示例

<yn-search @enter=${(e) => search(e.detail.value)}>
  <datalist>
    <option value="Sofa"></option>
    <option value="Chair"></option>
  </datalist>
</yn-search>

yn-group-pick

标签名yn-group-pick
类名YnGroupPick
导入yn-web-component/components/yn-group-pick
用途:选项组容器,配合子组件 yn-pick 实现单选或多选。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | value | string \| number \| Array<string \| number> | "" | 当前选中值(回显) | | multiple | boolean | false | 是否多选 | | selected-icon | string | 内置勾选 SVG | 组级默认选中图标 | | unselected-icon | string | "" | 组级默认未选中图标 | | show-unselected-icon | boolean | false | 组级默认是否在未选中时显示图标 |

优先级:子 yn-pick 上显式设置的 selected-icon / unselected-icon / show-unselected-icon 优先于组级默认值。

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | { ids: Array<string \| number>; flag: boolean } | 点击任意子项时触发;flag 为当前点击项的选中状态 |

插槽

| 插槽 | 说明 | | --- | --- | | 默认插槽 | 放置 yn-pick 子项列表 |

CSS 变量

| 变量 | 默认值 | 说明 | | --- | --- | --- | | --yn-group-pick-gap | 12px | 选项间距 |

示例

<yn-group-pick multiple .value=${["A", "B"]} @change=${onChange}>
  <yn-pick value="A">选项 A</yn-pick>
  <yn-pick value="B">选项 B</yn-pick>
</yn-group-pick>

yn-pick

标签名yn-pick
类名YnPick
导入yn-web-component/components/yn-pick
用途:单个可选项,可独立使用或作为 yn-group-pick / yn-dropdown-pick 的子项。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | value | string \| number | "" | 选项唯一标识 | | selected | boolean | false | 是否选中 | | border | boolean | true | 是否显示覆盖边框动画 | | selected-icon | string | 内置勾选 SVG | 选中态图标 | | unselected-icon | string | 内置描边圆环 SVG | 未选中态图标 | | show-unselected-icon | boolean | false | 未选中时是否显示图标 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | toggle | { id: string \| number; flag: boolean } | 点击选项;flag 为点击后的选中状态 |

插槽

| 插槽 | 说明 | | --- | --- | | 默认插槽 | 选项内容(任意 HTML) |

CSS 变量

| 变量 | 默认值 | 说明 | | --- | --- | --- | | --yn-pick-border-width | 2px | 边框宽度 | | --yn-pick-border-color | #241f21 | 边框颜色 | | --yn-pick-border-radius | 8px | 圆角 |

示例

<yn-pick value="nature" ?selected=${true} @toggle=${onToggle}>
  <div>Nature</div>
</yn-pick>

yn-dropdown

标签名yn-dropdown
类名YnDropdown
导入yn-web-component/components/yn-dropdown
用途:通用下拉弹层。默认插槽为触发器,content 插槽为面板内容。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | placement | 12 方向枚举 | "bottom-start" | 弹层固定弹出方向(当前不自动翻转) | | open | boolean | false | 受控展开状态 | | offset | number | 12 | 触发器与弹层间距(px) | | motion-distance | number | 14 | 触发器文本/关闭图标位移(px) | | panel-open-distance | number | 16 | 弹层打开位移(px) | | panel-close-distance | number | 20 | 弹层关闭位移(px) | | viewport-padding | number | 12 | 保留字段,当前不参与定位 | | auto-flip | boolean | false | 保留字段,当前不参与方向计算 | | close-on-outside-click | boolean | true | 点击外部是否关闭 |

placement 可选值:top-start / top / top-end / bottom-start / bottom / bottom-end / left-start / left / left-end / right-start / right / right-end

事件

| 事件 | detail | 说明 | | --- | --- | --- | | open-change | { open: boolean; placement: YnDropdownPlacement } | 展开状态变化 |

插槽

| 插槽 | 说明 | | --- | --- | | 默认插槽 | 触发器(如 yn-button) | | content | 下拉面板内容 | | close-icon | 关闭图标;未提供时使用内置 SVG |

公开方法

| 方法 | 说明 | | --- | --- | | close() | 主动关闭弹层 |

CSS 变量

| 变量 | 默认值 | 说明 | | --- | --- | --- | | --yn-dropdown-panel-min-width | 280px | 面板最小宽度 | | --yn-dropdown-panel-radius | 12px | 面板圆角 | | --yn-dropdown-panel-padding | 12px | 面板内边距 | | --yn-dropdown-panel-shadow | 0 12px 36px rgba(36,31,33,0.18) | 面板阴影 |

示例

<yn-dropdown placement="bottom-start" @open-change=${onOpenChange}>
  <yn-button>筛选</yn-button>
  <div slot="content">面板内容</div>
</yn-dropdown>

yn-dropdown-pick

标签名yn-dropdown-pick
类名YnDropdownPick
导入yn-web-component/components/yn-dropdown-pick
用途:独立下拉单选器。通过插槽传入 yn-pick 列表,选中后自动收起。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | value | string \| number | "" | 当前选中值 | | value-field | string | "id" | 节点数据中的值字段名 | | button-display-field | string | "label" | 按钮上展示的字段名 | | placeholder | string | "Select" | 未选中时的占位文案 | | close-on-outside-click | boolean | true | 点击外部关闭 | | disabled | boolean | false | 禁用 | | button-bg | string | #f8f6f2 | 收起态按钮背景 | | button-color | string | #241f21 | 收起态文字色 | | open-button-bg | string | #241f21 | 展开态按钮背景 | | open-button-color | string | #ffffff | 展开态文字色 | | panel-min-width | string | 132px | 面板最小宽度 | | show-selected-icon | boolean | true | 选中项右侧是否显示勾选图标 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | { id: string \| number \| ""; node: Record<string, unknown> \| null } | 选中值变化 | | open-change | { open: boolean } | 展开状态变化 |

插槽

| 插槽 | 说明 | | --- | --- | | 默认插槽 | yn-pick 列表;建议每项设置 data-node JSON 属性携带完整节点数据 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-dropdown-pick-panel-bg | 面板背景 | | --yn-dropdown-pick-panel-radius | 面板圆角 | | --yn-dropdown-pick-panel-padding | 面板内边距 | | --yn-dropdown-pick-gap | 选项垂直间距 |

示例

<yn-dropdown-pick
  value="en"
  button-display-field="code"
  placeholder="Language"
  @change=${onChange}
>
  <yn-pick value="en" data-node='{"id":"en","code":"EN","label":"English"}'>
    English
  </yn-pick>
  <yn-pick value="zh" data-node='{"id":"zh","code":"ZH","label":"中文"}'>
    中文
  </yn-pick>
</yn-dropdown-pick>

yn-drawer

标签名yn-drawer
类名YnDrawer
导入yn-web-component/components/yn-drawer
用途:基于原生 Popover API 的抽屉,响应式支持右侧滑出或底部弹出。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | open | boolean | false | 受控开关 | | width | number | 420 | 抽屉宽度(px,最小 260) | | title | string | "" | 标题文案;header 插槽为空时作为回退 | | close-on-backdrop | boolean | true | 点击遮罩是否关闭 | | placement | "auto" \| "right" \| "bottom" | "auto" | 弹出方向 | | sheet-height | string | "90vh" | 底部弹出时的高度;auto 随内容自适应 |

事件

生命周期事件均携带 detail

{
  open: boolean;
  source: "trigger" | "close-button" | "backdrop" | "escape" | "api" | ...;
  payload?: unknown;        // 触发器上的 drawer-payload
  triggerPayload?: unknown; // 触发器上的 trigger-payload
}

| 事件 | 说明 | | --- | --- | | open-change | 开关状态变化 | | before-open | 打开前;可 event.preventDefault() 阻止 | | after-open | 打开动画完成 | | before-close | 关闭前;可 event.preventDefault() 阻止 | | after-close | 关闭动画完成 |

插槽

| 插槽 | 说明 | 优先级 | | --- | --- | --- | | trigger | 触发器;支持 drawer-payload / trigger-payload / data-drawer-payload 传参 | 未提供时使用内置按钮 | | header | 自定义头部 | 优先于 title 属性 | | header-actions | 头部右侧操作区 | — | | content | 主体内容 | — | | footer | 底部区域 | — | | backdrop-extra | 宽屏(≥1024px)右侧抽屉时,遮罩左侧扩展区内容 | 窄屏自动隐藏 |

公开方法

| 方法 | 说明 | | --- | --- | | show(payload?) | 打开抽屉,payload 透传到生命周期事件 | | close(payload?) | 关闭抽屉 | | toggle(payload?) | 切换开关 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-drawer-z-index | 层级(默认 1500) | | --yn-drawer-bg | 面板背景 | | --yn-drawer-shadow | 面板阴影 | | --yn-drawer-backdrop | 遮罩颜色 | | --yn-drawer-header-border | 头部下边框 | | --yn-drawer-footer-border | 底部上边框 | | --yn-drawer-title-color | 标题颜色 | | --yn-drawer-close-color | 关闭按钮颜色 | | --yn-drawer-close-hover-bg | 关闭按钮悬停背景 | | --yn-drawer-content-color | 正文颜色 | | --yn-drawer-footer-bg | 底部背景 | | --yn-drawer-open-duration | 打开动画时长 | | --yn-drawer-close-duration | 关闭动画时长 | | --yn-drawer-open-ease | 打开缓动曲线 | | --yn-drawer-close-ease | 关闭缓动曲线 | | --yn-drawer-body-padding | 内容区内边距 | | --yn-drawer-sheet-height | 底部弹出高度(由 sheet-height 同步) | | --yn-drawer-width | 面板宽度(由 width 属性写入) | | --yn-drawer-mobile-radius | 移动端圆角 | | --yn-drawer-breakpoint | 响应式断点(默认 1024px) |

示例

<yn-drawer placement="auto" sheet-height="auto" @open-change=${onOpenChange}>
  <yn-button slot="trigger" drawer-payload='{"scene":"cart"}'>购物车</yn-button>
  <span slot="header">Your bag</span>
  <div slot="content">内容区域</div>
  <div slot="footer">底部操作</div>
</yn-drawer>

yn-toast

标签名yn-toast
类名YnToast
导入yn-web-component/components/yn-toast
用途:灵动岛风格顶部反馈。支持 loading → 状态形变动画,以及异步 callback 模式。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | type | "success" \| "info" \| "warning" \| "error" | "success" | 默认提示类型 | | message | string | "" | 默认文案(支持可信 HTML 片段) | | duration | number | 2600 | 最终态展示时长(ms) | | loading-duration | number | 1400 | loading 阶段时长(ms) | | persist | boolean | false | 是否保持最终态不自动关闭 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | show | { type, message, source } | 调用 show() 后触发 | | close | { type, message, source } | 关闭时触发;source 可为 api / swipe / timer / property |

公开方法

| 方法 | 说明 | | --- | --- | | show(type?, message?, options?) | 展示提示;第三参数 { duration, loadingDuration, persist } | | show(callback, mask?) | 异步任务模式;callback 内调用 instance.done(type, message)await 返回 callback 结果 | | success(message?, options?) | 快捷展示 success | | info(message?, options?) | 快捷展示 info | | warning(message?, options?) | 快捷展示 warning | | error(message?, options?) | 快捷展示 error | | success(callback, mask?) 等 | 快捷 callback 模式;instance.done(message) 完成 | | done(type, message?, options?) | 外部完成 loading 阶段 | | hide(source?) | 主动关闭 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-toast-top | 距顶部距离 | | --yn-toast-z-index | 层级 | | --yn-toast-height | 胶囊高度 | | --yn-toast-bg | 背景色 | | --yn-toast-text-color | 文本/弧线颜色 | | --yn-toast-success-color | success 状态球色 | | --yn-toast-info-color | info 状态球色 | | --yn-toast-warning-color | warning 状态球色 | | --yn-toast-error-color | error 状态球色 | | --yn-toast-paper-color | 状态图标线条色 | | --yn-toast-max-width | 最大宽度 | | --yn-toast-message-padding | 消息区内边距 | | --yn-toast-message-font-size | 消息字号 | | --yn-toast-message-letter-spacing | 消息字距 | | --yn-toast-mask-bg | callback 模式遮罩背景 | | --yn-toast-shadow | 阴影 |

示例

<yn-toast id="toast"></yn-toast>

<script type="module">
  const toast = document.getElementById("toast");

  // 普通提示
  toast.success("保存成功");

  // 异步 callback 模式
  await toast.success(async (instance) => {
    await saveData();
    instance.done("保存成功");
  }, true); // 第二参数 true 显示遮罩
</script>

yn-icon-connect-button

标签名yn-icon-connect-button
类名YnIconConnectButton
导入yn-web-component/components/yn-icon-connect-button
用途:带图标连接动画的按钮或链接,视觉风格参考 Floema。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | label | string | "VER PRODUTOS URBAN" | 按钮文案(插槽回退) | | size | "mini" \| "small" \| "normal" | "normal" | 尺寸 | | icon | string | 内置 SVG | 图标 HTML(插槽回退) | | uppercase | boolean | true | 是否默认大写 | | link | string | "" | 有值时渲染 <a>,无值时渲染 <button> | | disabled | boolean | false | 禁用 |

事件

| 事件 | 类型 | 说明 | | --- | --- | --- | | click | MouseEvent | 点击时触发 |

插槽

| 插槽 | 说明 | 优先级 | | --- | --- | --- | | icon | 自定义图标 | 优先于 icon 属性 | | label | 自定义文案 | 优先于 label 属性 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-icon-connect-button-bg | 背景色 | | --yn-icon-connect-button-color | 文本/图标颜色 |

示例

<yn-icon-connect-button label="查看产品" size="normal">
  <svg slot="icon" viewBox="0 0 24 24">...</svg>
</yn-icon-connect-button>

yn-pull-cord-switch

标签名yn-pull-cord-switch
类名YnPullCordSwitch
导入yn-web-component/components/yn-pull-cord-switch
用途:抽绳开关交互。基于 Verlet 绳物理模拟,支持 fixed 吸顶模式与双插槽内容切换。

组件不绘制区域背景。内嵌用法需在外层容器调用 applyPullCordShellBackground() 同步背景色。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | checked | boolean | false | 开关状态 | | glow-up | boolean | false | 开启且 checked 时顶灯向上扩散 | | disabled | boolean | false | 禁用拖拽 | | fixed | boolean | false | 吸附视口顶部 | | fixed-x | number | 居中 | 水平偏移(可为负值,hover 时露出) | | top | number | 0 | 距顶部距离(可为负值) | | reverse | boolean | false | fixed-x 是否自右侧起算 | | variant | "default" \| "floema" | "default" | 视觉变体 | | size | "mini" \| "small" \| "medium" | "mini" | 卡片/绳粗细(不控制绳长) | | rope-length | number | 260 | 绳长(px) | | card-offset | number | 随绳长缩放 | 绳头到卡片的间距(可为负值) | | z-index | number | 1 | 层级,写入 --yn-pull-cord-switch-z-index | | toggle-threshold | number | 随绳长缩放 | 拉动切换阈值(px) |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | { checked: boolean } | 拉过阈值切换状态时 | | fixed-move | { x: number; reverse: boolean } | fixed 模式水平拖动结束时 |

插槽

| 插槽 | 说明 | 优先级 | | --- | --- | --- | | 默认插槽 | 关闭态(checked=false)绳端内容,推荐 yn-button | 无插槽时显示内置 ON/OFF | | activated | 开启态(checked=true)绳端内容 | 与默认插槽按状态切换 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-pull-cord-switch-z-index | 层级 | | --yn-pull-cord-switch-anchor-y | 锚点额外下移比例 | | --yn-pull-cord-switch-glow-up-bleed | glow-up 画布向上延展 | | --yn-pull-cord-switch-slot-transition-duration | 双插槽切换动画时长 | | --yn-pull-cord-switch-fixed-peek-transition-duration | 负值 peek 动画时长 | | --yn-pull-cord-switch-slot-button-scale | 插槽内按钮缩放 | | --yn-pull-cord-switch-accent | 灯光强调色(随 variant 变化) |

示例

<yn-pull-cord-switch
  ?checked=${false}
  rope-length="260"
  @change=${(e) => console.log(e.detail.checked)}
>
  <yn-button>夜间</yn-button>
  <yn-button slot="activated" variant="success">日间</yn-button>
</yn-pull-cord-switch>

yn-quantity

标签名yn-quantity
类名YnQuantity
导入yn-web-component/components/yn-quantity
用途:Floema 风格数量选择器(减号 / 数字输入 / 加号)。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | value | number | 1 | 当前数量 | | min | number | 1 | 最小值 | | max | number | 99 | 最大值 | | step | number | 1 | 步进值 | | disabled | boolean | false | 禁用 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | { value: number } | 数量变化 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-quantity-width | 宽度 | | --yn-quantity-height | 高度 | | --yn-quantity-bg | 背景 | | --yn-quantity-bg-hover | 悬停背景 | | --yn-quantity-bg-focus | 聚焦背景 | | --yn-quantity-border-color | 边框色 | | --yn-quantity-border-color-hover | 悬停边框 | | --yn-quantity-border-color-focus | 聚焦边框 | | --yn-quantity-focus-ring | 聚焦外圈 | | --yn-quantity-color | 数字/图标色 | | --yn-quantity-muted-color | 禁用按钮色 | | --yn-quantity-divider-color | 分隔线颜色 | | --yn-quantity-button-size | 按钮尺寸 | | --yn-quantity-button-bg-hover | 按钮悬停背景 | | --yn-quantity-button-bg-active | 按钮按下背景 | | --yn-quantity-button-hover-radius | 按钮悬停圆角 | | --yn-quantity-inner-gap | 内部间距 | | --yn-quantity-padding | 内边距 | | --yn-quantity-radius | 圆角 | | --yn-quantity-font-family | 字体 | | --yn-quantity-font-size | 字号 | | --yn-quantity-letter-spacing | 字距 | | --yn-quantity-value-min-width | 数字区最小宽度 |

示例

<yn-quantity .value=${1} .min=${1} .max=${99} @change=${onChange}></yn-quantity>

yn-checkout-address

标签名yn-checkout-address
类名YnCheckoutAddress
导入yn-web-component/components/yn-checkout-address
用途:跨境独立站结账地址表单。数据源按优先级自动降级:

Google API Keydr5hn CDNPhotonmanual 手动填写

表单分步展示(先选地区,再填联系方式与详细地址)。运行中若 dr5hn 搜索失败会降级 Photon;Photon 仍失败则切至 manual。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | dev | boolean | false | 显示 JSON 调试面板 | | disabled | boolean | false | 禁用表单 | | locale | "en" \| "zh-CN" | "en" | 界面语言 | | google-maps-api-key | string | "" | Google Maps API Key;变更会重新探测数据源 | | excludeRegions | YnCheckoutExcludeRegions | — | 排除指定国家/州/城市 | | includeCountries | string[] | — | 仅允许的国家 ISO2 列表 | | value | YnCheckoutAddressValue \| null | null | 受控回显;绑定后不会重新探测 | | messages | Partial<YnCheckoutAddressMessages> | — | 局部文案覆盖 | | show-email | boolean | false | 是否展示邮箱输入 | | email-required | boolean | false | 邮箱是否必填 | | show-whatsapp | boolean | false | 是否展示 WhatsApp 输入 | | whatsapp-required | boolean | false | WhatsApp 是否必填(6–15 位数字) |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | YnCheckoutAddressChangeDetail | 地址任意字段变化 |

change.detail 结构:

{
  value: YnCheckoutAddressValue;       // 当前地址快照
  validation: {
    valid: boolean;                    // 硬校验是否通过(提交前应为此 true)
    regionComplete: boolean;           // 配送地区是否已确认
    formReady: boolean;                // 软就绪(可预启用下单按钮)
    errors: YnCheckoutAddressValidationError[];
  };
  changedFields: YnCheckoutAddressValueKey[]; // 相对上次 change 变更的字段
}

YnCheckoutAddressValue 主要字段:providercountryCodecountryNamestateCodestateNamecityNamephonecodephoneNumberfirstNamelastNameemailwhatsappline1line2postalCodenotes 等。

公开方法

| 方法 | 返回 | 说明 | | --- | --- | --- | | validate() | YnCheckoutAddressValidateResult | 执行校验,不修改 UI | | reportValidity() | boolean | 标红无效字段并聚焦首项;true 通过,false 未通过 | | setValue(value) | void | 编程式回显/清空;不重新探测、不触发搜索 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-checkout-address-bg | 组件背景 | | --yn-checkout-address-bg-muted | 页面底衬色 | | --yn-checkout-address-primary | 主色 | | --yn-checkout-address-outline | 输入框描边 | | --yn-checkout-address-label | 标签颜色 | | --yn-checkout-address-padding | 内容区内边距 | | --yn-checkout-address-field-height | 输入框高度 | | --yn-checkout-address-radius | 圆角 | | --yn-checkout-address-surface | 卡片表面色 | | --yn-checkout-address-card-bg | 卡片背景 | | --yn-checkout-address-color | 正文颜色 |

示例

<yn-checkout-address
  locale="zh-CN"
  .value=${address}
  show-email
  email-required
  @change=${(e) => { address = e.detail.value; }}
></yn-checkout-address>

<script>
  // 提交前校验
  if (!addressEl.reportValidity()) return;
  const { valid, value } = addressEl.validate();
  if (!valid) return;
  submitOrder({ shippingAddress: value });
</script>

主入口还导出校验工具:validateCheckoutAddressemptyCheckoutAddressValuePOSTAL_REQUIRED_COUNTRIES 等。


yn-sku-selector

标签名yn-sku-selector
类名YnSkuSelector
导入yn-web-component/components/yn-sku-selector
用途:多维 SKU 规格联动选择、库存/价格展示、加购校验与 loading 反馈。

同路径还导出 SKU 算法工具(getSpecKeysbuildFirstAvailableCursfindMatchedSku 等),可单独 Tree Shaking 使用。

属性

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | skus | YnSkuItem[] | [] | SKU 列表;price / id / stock / skuId 为元数据 | | currency | string | "€" | 货币字符 | | currency-icon | string | "" | 货币 SVG(优先于 currency 文本) | | simple | boolean | false | 仅显示规格按钮,选齐后自动 submit | | pick-one | boolean | false | 默认选中第一组可用 SKU 并触发 init | | submit-label | string | "ADD TO CART" | 加购按钮文案 | | loading-text | string | "" | 设置后进入文案替换 loading 模式 | | loading-mode | "icon" \| "overlay" | "icon" | spinner 展示方式 | | cart-icon | string | 内置 SVG | 加购按钮图标 | | show-cart-icon | boolean | true | 是否显示加购图标 | | incomplete-hint | string | "请选择 {label}" | 未选齐提示模板,{label} 为维度名 | | labels | Record<string, string> | {} | 维度展示名映射 | | spec-key-whitelist | string[] | [] | 维度白名单(按顺序) | | spec-key-exclude | string[] | [] | 额外排除的维度 | | disabled | boolean | false | 禁用整组 |

事件

| 事件 | detail | 说明 | | --- | --- | --- | | change | { selections, sku, ready, missingKeys } | 规格选择变化 | | init | 同 change | pick-one 初始化完成时 | | submit | { selections, sku } + event.instance | 满足加购条件时;异步完成后调用 instance.done() |

插槽

| 插槽 | 说明 | 优先级 | | --- | --- | --- | | title | 标题区(simple 模式不渲染) | — | | submit-icon | 加购按钮左侧图标 | 优先于 cart-icon 属性 |

CSS 变量

| 变量 | 说明 | | --- | --- | | --yn-sku-selector-row-height | 规格行高度 | | --yn-sku-selector-row-gap | 维度行间距 | | --yn-sku-selector-label-row-gap | label 与按钮行间距 | | --yn-sku-selector-option-min-width | 规格按钮最小宽度 | | --yn-sku-selector-option-border-color | 边框色 | | --yn-sku-selector-option-active-bg | 选中背景 | | --yn-sku-selector-option-active-color | 选中文字色 | | --yn-sku-selector-submit-height | 加购按钮高度 | | --yn-sku-selector-submit-margin-top | 规格区与按钮间距 | | --yn-sku-selector-submit-outer-gap | 外圈留白 | | --yn-sku-selector-submit-inner-height | 内内容区高度 | | --yn-sku-selector-submit-inset-color | 内描边色 | | --yn-sku-selector-submit-divider-color | 价格区分隔线 | | --yn-sku-selector-submit-price-width | 价格区宽度 | | --yn-sku-selector-price-font-weight | 价格字重 | | --yn-sku-selector-submit-bg | 加购背景 | | --yn-sku-selector-submit-color | 加购文字/图标色 | | --yn-sku-selector-hint-color | 校验提示色 | | --yn-sku-selector-submit-loading-size | spinner 通用尺寸 | | --yn-sku-selector-submit-loading-icon-size | icon 模式 spinner 尺寸 |

兼容旧名:--yn-sku-selector-option-height--yn-sku-selector-label-gap--yn-sku-selector-section-gap

内部子组件 yn-sku-cart-button

yn-sku-cart-button 无独立 package.json exports,随选择器内部注册。若需单独了解其 API:

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | label | string | "ADD TO CART" | 按钮文案 | | price | string | "—" | 价格展示 | | cart-icon | string | 内置 SVG | 图标 | | currency-icon | string | "" | 货币 SVG | | show-cart-icon | boolean | true | 显示图标 | | loading | boolean | false | loading 态 | | loading-text | string | "" | 文案替换 loading | | loading-mode | "icon" \| "overlay" | "icon" | spinner 模式 | | disabled | boolean | false | 禁用 |

事件:click(原生点击)。插槽:icon(优先于 cart-icon)。

示例

<yn-sku-selector
  .skus=${skus}
  pick-one
  .labels=${{ color: "颜色", size: "尺码" }}
  @init=${onInit}
  @change=${onChange}
  @submit=${async (e) => {
    await addToCart(e.detail.sku);
    e.instance.done();
  }}
>
  <h1 slot="title">Product Name</h1>
</yn-sku-selector>

导入路径速查

| 组件 | 按需导入路径 | | --- | --- | | yn-button | yn-web-component/components/yn-button | | yn-input | yn-web-component/components/yn-input | | yn-navigation | yn-web-component/components/yn-navigation | | yn-search | yn-web-component/components/yn-search | | yn-group-pick | yn-web-component/components/yn-group-pick | | yn-pick | yn-web-component/components/yn-pick | | yn-dropdown | yn-web-component/components/yn-dropdown | | yn-dropdown-pick | yn-web-component/components/yn-dropdown-pick | | yn-drawer | yn-web-component/components/yn-drawer | | yn-toast | yn-web-component/components/yn-toast | | yn-icon-connect-button | yn-web-component/components/yn-icon-connect-button | | yn-pull-cord-switch | yn-web-component/components/yn-pull-cord-switch | | yn-quantity | yn-web-component/components/yn-quantity | | yn-checkout-address | yn-web-component/components/yn-checkout-address | | yn-sku-selector | yn-web-component/components/yn-sku-selector |

其他导出:

| 路径 | 说明 | | --- | --- | | yn-web-component | 主入口,导出所有组件类与类型 | | yn-web-component/define | 全量注册所有自定义元素 | | yn-web-component/theme.css | 全局主题样式 | | yn-web-component/asset/svg | SVG 资源 |

主题与样式

按钮主题推荐(variant + CSS 变量)

推荐两层控制:

  1. 语义层variant 表达按钮语义(primarydanger 等)
  2. 视觉层:CSS 变量覆写具体色值,满足品牌定制

Tailwind 使用边界

Tailwind 仅用于 Storybook 演示层(*.stories.ts.storybook/),不会打入组件库发布产物。组件样式通过 Shadow DOM 内 css--yn-* 变量实现。

版本与兼容性

| 项 | 说明 | | --- | --- | | ESM | dist/index.js | | CJS | dist/index.cjs | | UMD | dist/index.umd.js | | IIFE | dist/index.iife.js | | Types | dist/types/* | | Node.js | 建议 >= 18 | | 包管理器 | 推荐 pnpm 10+ | | 浏览器 | 支持 Custom Elements v1 / Shadow DOM 的现代浏览器 |

依赖基线:lit ^3.3.2

开发命令

pnpm dev              # 启动文档站(app/,http://localhost:5173)
pnpm storybook        # Storybook 开发调试(端口 6006)
pnpm build            # 构建产物
pnpm build-storybook  # 构建静态 Storybook
pnpm test             # 单元测试
pnpm test:browser     # 浏览器测试
pnpm typecheck        # 类型检查
pnpm lint             # ESLint
pnpm format           # Prettier

更完整的交互演示与 Controls 面板,请运行 pnpm storybook 查看。

发布

pnpm build
pnpm changeset
pnpm release

License

MIT