# @aejkatappaja/phantom-ui 中文文档

规范地址：https://npmcn.com/package/%40aejkatappaja/phantom-ui/

版本：1\.6\.1
npm 元数据更新时间：2026-08-10T17:55:04.513Z
中文译文更新时间：2026-11-05T20:39:05.231Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40aejkatappaja/phantom-ui
原文对照：https://npmcn.com/package/%40aejkatappaja/phantom-ui/?lang=original
项目主页：https://github.com/Aejkatappaja/phantom-ui#readme
源码仓库：https://github.com/Aejkatappaja/phantom-ui

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：214 kB，15 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-03-30T16:00:46.980Z
- 最新版本发布：2026-07-31T09:11:37.024Z
- 近 30 天下载量：25406（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：32（近 12 个月 32 个）

## 中文简介

结构意识发光的骨架装载器是使用Lit建造的通用的Web组件,使用React,Vue,Svelte,Angular,Solid,或vanilla JS.

## 安装

```sh
npm install @aejkatappaja/phantom-ui
```

也可以使用：`pnpm add @aejkatappaja/phantom-ui`、`yarn add @aejkatappaja/phantom-ui`、`bun add @aejkatappaja/phantom-ui`

## README

![phantom-ui](https://npmcn.com/package/%40aejkatappaja/phantom-ui/.github/assets/logo-phantom.svg)  
![phantom-ui](https://npmcn.com/package/%40aejkatappaja/phantom-ui/.github/assets/phantom-ui-text.svg)

**结构意识骨架装载机. 一个网络组件。 每个框架.**

[![npm version](https://img.shields.io/npm/v/@aejkatappaja/phantom-ui.svg?style=flat-square)](https://www.npmjs.com/package/@aejkatappaja/phantom-ui) ![bundle size](https://img.shields.io/badge/minzipped-~8kb-blue?style=flat-square) [![license](https://img.shields.io/npm/l/@aejkatappaja/phantom-ui?style=flat-square)](https://github.com/Aejkatappaja/phantom-ui/blob/main/LICENSE) [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg?style=flat-square)](https://www.webcomponents.org/element/@aejkatappaja/phantom-ui)

[文档](https://aejkatappaja.github.io/phantom-ui/) • 妇女 [现场直播](https://aejkatappaja.github.io/phantom-ui/demo/)

* * *

  

![phantom-ui demo](https://npmcn.com/package/%40aejkatappaja/phantom-ui/.github/assets/phantom-ui-preview.svg)

  

别再用手做骨架了 将您真正的用户界面包入 `<phantom-ui>` 它通过在运行时测量您的实际 DOM 自动生成闪光的占位符 .

没有单独的骨架组件可以维护. 无复制打字布局. 真正的组成部分 _实值_ 骨架模板.

## 为什么

传统的骨架加载器需要您构建和维护每个组件的第二版本,仅用于加载状态. 当真正的组件改变时,骨架会漂出同步.

`phantom-ui` 采取不同的做法。 它使您真实的构件带有隐形文字,测量出每个叶片元素的位置和大小(`getBoundingClientRect`),并在完全相同的坐标上覆盖出出动画闪光块. 集装箱背景和边界保持可见,在装入时给出了天然卡片大纲.

因为它是一个标准的Web组件(用Lit来建造),它在React,Vue,Svelte,Angular,Solid,Qwik,HTMX或平版HTML工作. 不需要框架适配器.

## 安装

```bash
bun add @aejkatappaja/phantom-ui     # bun
npm install @aejkatappaja/phantom-ui # npm
pnpm add @aejkatappaja/phantom-ui    # pnpm
yarn add @aejkatappaja/phantom-ui    # yarn
```

或者在脚本标签中投放没有构建步骤:

```html
<script src="https://cdn.jsdelivr.net/npm/@aejkatappaja/phantom-ui/dist/phantom-ui.cdn.js"></script>
```

### 销售单一文件

如果您无法从注册簿中安装, 或者您宁愿将副本保存在您的 repo 中, 有一个独立的 ES 模块, 里面装有 Lit 。 1个文件, 34 kB 被精密化, 11.5 kB gziped, 没有运行时间依赖 :

```ts
import "@aejkatappaja/phantom-ui/standalone";
```

或者,如果你根本无法到达一个注册,请将两个文件复制到您的项目中,然后通过路径导入:

```
phantom-ui.standalone.js      # the component, unminified so a review can read it
phantom-ui.standalone.min.js  # the same code, minified
phantom-ui.standalone.d.ts    # its types, no imports of any kind
```

取第一相与三相为相. TypeScript 精确地将声明对一模块 文件名,所以这两个名字会一起使用,而且类型应用时没有任何配置.

```ts
import "./phantom-ui.standalone.js";
import type { PhantomUi } from "./phantom-ui.standalone.js";
```

这是整个安装。 元素本身在进口时登记,申报中没有提到任何外部内容,因此没有 `node_modules` 仍然按类型检查 `strict` 与 `skipLibCheck: false`。 。 。 .

宣布的类扩展 `HTMLElement` 而不是说 `LitElement`,这是对同一物体的更窄的视图,所以 `updateComplete` 公开宣布,其余的API保持不变.

这些是释放资产,是根本无法进入登记册的人的渠道。 在 npm 包内,同样的构件是 `phantom-ui.standalone.js` 财务报告和审定财务报表 `phantom-ui.standalone.dev.js`,通过导出地图而不是文件名解决。 任意一种构建都是同一种代码,两者都是捆绑输出而不是原始的TypeScript:源导入了Lit,因此无法自行编译.

图书馆是麻省理工学院,所以销售是好的. 注意你在文件附近复制的版本, 因为一个卖家复制的版本不会得到更新 .

## 可选设置

该组件以零设置来工作. 额外的便利通行证,运行捆绑 `init` 命令一次从您的工程根 :

```bash
npx @aejkatappaja/phantom-ui init    # npm
bunx @aejkatappaja/phantom-ui init   # bun
pnpx @aejkatappaja/phantom-ui init   # pnpm
yarn dlx @aejkatappaja/phantom-ui init  # yarn
```

它能侦测到你的项目设置 并处理两件事:

**JSX 类型声明**: 对于反应,固态和克威克,它生成一个 `phantom-ui.d.ts` 在你身边 `src/` 目录是这样 `<phantom-ui>` jSX承认了这一点。 Vue, Svelte, 和Angular在盒子外工作,没有任何类型的声明.

**SSR 水分前水分**: 对于Next.js, Nuxt, SvelteKit, Remix, 和克威克, 它添加 `import "@aejkatappaja/phantom-ui/ssr.css"` 到您的布局文件,以便在水合之前防止内容闪烁(参见 [水分前水分控制系统](https://npmcn.com/package/%40aejkatappaja/phantom-ui/#readme-pre-hydration-css)) (中文(简体) ).

没有运行在安装上: 库故意没有 `postinstall` 钩子,所以你的源 从来没有修改 除非你要求它。 宁愿不运行命令吗? 这两个步骤都很小,下面有记载,用于人工设置.

手动JSX类型的申报

**反应 / Next.js / Remix**

```typescript
import type { PhantomUiAttributes } from "@aejkatappaja/phantom-ui";

declare module "react/jsx-runtime" {
  export namespace JSX {
    interface IntrinsicElements {
      "phantom-ui": PhantomUiAttributes;
    }
  }
}
```

**固态**

```typescript
import type { SolidPhantomUiAttributes } from "@aejkatappaja/phantom-ui";

declare module "solid-js" {
  namespace JSX {
    interface IntrinsicElements {
      "phantom-ui": SolidPhantomUiAttributes;
    }
  }
}
```

**齐克**

```typescript
import type { PhantomUiAttributes } from "@aejkatappaja/phantom-ui";

declare module "@builder.io/qwik" {
  namespace QwikJSX {
    interface IntrinsicElements {
      "phantom-ui": PhantomUiAttributes & Record<string, unknown>;
    }
  }
}
```
手动导入 SSR CSS

将此导入添加到您的根布局文件 :

```js
import "@aejkatappaja/phantom-ui/ssr.css";
```

| 框架 | 布局文件 |
| --- | --- |
| Next.js (App路由器) (英语) | `app/layout.tsx` |
| Next.js (页) | `pages/_app.tsx` |
| 坚果 | `app.vue` |
| 斯维尔特基特 | `src/routes/+layout.svelte` |
| 重混合 | `app/root.tsx` |
| 齐克 | `src/root.tsx` |

## 快开始

```html
<phantom-ui loading>
  <div class="card">
    <img src="avatar.png" width="48" height="48" style="border-radius: 50%" />
    <h3>Ada Lovelace</h3>
    <p>First computer programmer, probably.</p>
  </div>
</phantom-ui>
```

设定 `loading` 以显示发光。 删除以揭示真实内容 。 所有的儿童元素(包括深筑的图像和媒体)在加载时自动被隐藏.

## 数据获取

奇幻-伊与任何数据采集方法合作. 模式:在装入时提供占位符内容, 完成时提供真实内容 。 占位符文本是不可见的(CSS透明),仅用于生成骨架形状.

### TanStack 查询

```tsx
import { useQuery } from "@tanstack/react-query";
import "@aejkatappaja/phantom-ui";

function UserProfile({ userId }: { userId: string }) {
  const { data: user, isLoading } = useQuery({
    queryKey: ["user", userId],
    queryFn: () => fetch(`/api/users/${userId}`).then((r) => r.json()),
  });

  return (
    <phantom-ui loading={isLoading}>
      <div className="card">
        <img src={user?.avatar ?? "/placeholder.png"} width="48" height="48" />
        <h3>{user?.name ?? "Placeholder Name"}</h3>
        <p>{user?.bio ?? "A short bio goes here."}</p>
      </div>
    </phantom-ui>
  );
}
```

虽然 `isLoading` 真实的,占位符文本(`"Placeholder Name"`, (中文(简体) ), `"A short bio goes here."`)被隐形地渲染出并被幽灵-伊能产生出与其确切位置和大小相匹配的闪光块. 当查询解决, `loading` 并显示真实内容.

### 水资源

```tsx
import useSWR from "swr";
import "@aejkatappaja/phantom-ui";

function UserProfile({ userId }: { userId: string }) {
  const { data: user, isLoading } = useSWR(`/api/users/${userId}`);

  return (
    <phantom-ui loading={isLoading}>
      <div className="card">
        <img src={user?.avatar ?? "/placeholder.png"} width="48" height="48" />
        <h3>{user?.name ?? "Placeholder Name"}</h3>
        <p>{user?.bio ?? "A short bio goes here."}</p>
      </div>
    </phantom-ui>
  );
}
```

### 名单

对于数据尚未加载的动态列表,请使用 `count` 重复单一模板行:

```tsx
const { data: users, isLoading } = useQuery({
  queryKey: ["users"],
  queryFn: () => fetch("/api/users").then((r) => r.json()),
});

return (
  <phantom-ui loading={isLoading} count={5} count-gap={8}>
    {isLoading ? (
      <div className="row">
        <img src="/placeholder.png" width="32" height="32" />
        <span>Placeholder Name</span>
        <span>placeholder@email.com</span>
      </div>
    ) : (
      users?.map((u) => (
        <div key={u.id} className="row">
          <img src={u.avatar} width="32" height="32" />
          <span>{u.name}</span>
          <span>{u.email}</span>
        </div>
      ))
    )}
  </phantom-ui>
);
```

## 框架实例

安全可多次导入 。 自定义内容登记要防止重复 `customElements.define()` {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}所以幽灵在 **微前端、 懒惰的模块、 动态导入和 HMR / 热重装** 包件最终可以不止一次被初始化的环境.

### 反应

```tsx
import "@aejkatappaja/phantom-ui";

function ProfileCard({ user, isLoading }: Props) {
  return (
    <phantom-ui loading={isLoading} animation="pulse" reveal={0.3}>
      <div className="card">
        <img src={user?.avatar ?? "/placeholder.png"} className="avatar" />
        <h3>{user?.name ?? "Placeholder Name"}</h3>
        <p>{user?.bio ?? "A few words about this person go here."}</p>
      </div>
    </phantom-ui>
  );
}

// List with repeat mode
function UserList({ users, isLoading }: Props) {
  return (
    <phantom-ui loading={isLoading} count={5} count-gap={8}>
      <div className="row">
        <img src="/placeholder.png" width="32" height="32" />
        <span>Placeholder Name</span>
      </div>
    </phantom-ui>
  );
}
```

### 阴道

```vue
<script setup lang="ts">
import "@aejkatappaja/phantom-ui";

const props = defineProps<{ loading: boolean }>();
</script>

<template>
  <phantom-ui :loading="props.loading" animation="breathe" stagger="0.05">
    <div class="card">
      <img src="/avatar.png" class="avatar" />
      <h3>Ada Lovelace</h3>
      <p>First computer programmer, probably.</p>
    </div>
  </phantom-ui>
</template>
```

### 丝绒

```svelte
<script lang="ts">
  import "@aejkatappaja/phantom-ui";

  export let loading = true;
</script>

<phantom-ui {loading} reveal={0.4} stagger={0.03}>
  <div class="card">
    <img src="/avatar.png" alt="avatar" class="avatar" />
    <h3>Ada Lovelace</h3>
    <p>First computer programmer, probably.</p>
  </div>
</phantom-ui>
```

### 角质

```typescript
import { Component, signal, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@aejkatappaja/phantom-ui";

@Component({
  selector: "app-profile",
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <phantom-ui [attr.loading]="loading() ? '' : null" animation="pulse">
      <div class="card">
        <img src="/avatar.png" class="avatar" />
        <h3>Ada Lovelace</h3>
        <p>First computer programmer, probably.</p>
      </div>
    </phantom-ui>
  `,
})
export class ProfileComponent {
  loading = signal(true);
}
```

### 固态

```tsx
import { createSignal } from "solid-js";
import "@aejkatappaja/phantom-ui";

function ProfileCard() {
  const [loading, setLoading] = createSignal(true);

  return (
    <phantom-ui attr:loading={loading() ? "" : null} animation="shimmer" stagger={0.05}>
      <div class="card">
        <img src="/avatar.png" class="avatar" />
        <h3>Ada Lovelace</h3>
        <p>First computer programmer, probably.</p>
      </div>
    </phantom-ui>
  );
}
```

### 安全部门改革框架(Next.js、Nuxt、SvelteKit、Remix、Quik)

组件需要浏览器API来测量 DOM. 仅导入客户端 :

```tsx
// Next.js
"use client";
import { useEffect } from "react";

export default function Page() {
  useEffect(() => { import("@aejkatappaja/phantom-ui"); }, []);
  return <phantom-ui loading>...</phantom-ui>;
}
```

```vue
<!-- Nuxt -->
<script setup>
onMounted(() => import("@aejkatappaja/phantom-ui"));
</script>

<template>
  <ClientOnly>
    <phantom-ui loading>...</phantom-ui>
  </ClientOnly>
</template>
```

```svelte
<!-- SvelteKit -->
<script>
  import { onMount } from "svelte";
  onMount(() => import("@aejkatappaja/phantom-ui"));
</script>
```

```tsx
// Qwik
import { component$, useVisibleTask$ } from "@builder.io/qwik";

export default component$(() => {
  // eslint-disable-next-line qwik/no-use-visible-task
  useVisibleTask$(async () => {
    import("@aejkatappaja/phantom-ui");
  });

  return <phantom-ui loading>...</phantom-ui>;
});
```

这个 `<phantom-ui>` 标记可以在服务器的 HTML 中存在。 浏览器将它视为一个未知的元素,直到水合,然后Web组件激活并测量DOM. 内容通常会在服务器上生成,这对SEO有好处.

#### 水分前水分控制系统

在 JavaScript 载入之前, 内容在内 `<phantom-ui loading>` 可短暂地以可见文本的形式闪出。 包装一个小的CSS文件, 立即隐藏这些内容

```css
import "@aejkatappaja/phantom-ui/ssr.css";
```

运行 `npx @aejkatappaja/phantom-ui init` 检测 SSR 框架,并将此导入添加到您的布局文件(例如 . `app/layout.tsx` 接下来,Js, `app.vue` 给纳克斯特, `+layout.svelte` 为斯维尔特基特。 或自加行为行. 如果您使用 CDN 构建, 请直接在您的 `<head>`数字 :

```html
<style>
  phantom-ui[loading] * {
    -webkit-text-fill-color: transparent !important;
    pointer-events: none;
    user-select: none;
  }
  phantom-ui[loading] img, phantom-ui[loading] svg,
  phantom-ui[loading] video, phantom-ui[loading] canvas,
  phantom-ui[loading] button, phantom-ui[loading] [role="button"] {
    opacity: 0 !important;
  }
</style>
```

## 属性

| 属性 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `loading` | `boolean` | `false` | 显示闪烁的覆盖或真实内容 |
| `animation` | `string` | `shimmer` | 动画模式 : `shimmer`, (中文(简体) ), `pulse`, (中文(简体) ), `breathe`,或 `solid` |
| `mode` | `string` | `skeleton` | `skeleton` (隐藏内容,显示块)或 `overlay` (保持内容暗淡, 扫光过它来刷新) |
| `shimmer-direction` | `string` | `ltr` | 清扫方向: `ltr`, (中文(简体) ), `rtl`, (中文(简体) ), `ttb`,或 `btt` (只有震动模式) |
| `shimmer-color` | `string` | `rgba(128,128,128,0.3)` | 动画渐变扫描的颜色( 仅显示闪光模式) |
| `background-color` | `string` | `rgba(128,128,128,0.2)` | 每个闪光块的背景( 所有模式) |
| `duration` | `number` | `1.5` | 动画周期( 秒) |
| `stagger` | `number` | `0` | 每个块动画启动之间的秒数延迟 |
| `reveal` | `number` | `0` | 装入结束时以秒计的淡出持续时间 |
| `count` | `number` | `1` | 从单一模板重复的骨架行数 |
| `count-gap` | `number` | `0` | 重复行之间的像素差距 |
| `fallback-radius` | `number` | `4` | 文本等平面元素的边框半径( px) |
| `debug` | `boolean` | `false` | 附有检查索引的每个测量区块大纲 |
| `loading-label` | `string` | `Loading` | 屏幕阅读器在装入时宣布的可访问标签(设置为 `aria-label`(中文(简体) ) |
| `pierce-shadow` | `boolean` | `false` | 时间档组件(Stencil, Lit 设计系统)的开阔阴影根内测量 |

> 使用Web组件设计系统? 见 [阴影 DOM 指南](https://aejkatappaja.github.io/phantom-ui/guides/design-systems/) 为何 `pierce-shadow` 组件内的措施.

## 刷新模式( E)`mode="overlay"`(中文(简体) )

默认 `skeleton` 模式用于第一个负载:它隐藏内容并显示占位符块。 对于更新/ stale- while- revalidate 状态, 您已经得到了结果, 并且正在调试, 使用 `mode="overlay"`数字 :

```html
<phantom-ui loading mode="overlay">
  <div class="grid"><!-- the previous result --></div>
</phantom-ui>
```

现有的内容保持可见并被暗化,而一闪光闪烁地扫遍了每个元素(结构意识,和骨架一样). 在刷新期间无法点击( I)`pointer-events: none`),因此用户不能对已死数据采取行动,但可以读取,并保存在无障碍树上(`aria-busy` 宣布最新情况)。 慢慢来 `--phantom-content-opacity` (默认) `0.5`,设置为 `1` 完全不透明,只有光. `count` 编号 : `count-gap` 这里不适用.

扫荡就是 `shimmer` 动画. 与 `pulse` 或者说 `breathe` 光是每个元素的固定面纱 取而代之的是动画, `solid` 保持静态,当系统要求减少运动时,使用相同的静态面纱. 每一次刷新都能看到.

## 精细的控制

数据属性允许您控制哪些元素得到闪光的处理,以及如何测量它们:

**`data-shimmer-ignore`** 在加载时保持一个元素及其所有后缀的可见性和交互性(从未制作) `inert`) (中文(简体) ). 用于标识,品牌标志,或应始终显示的活指标.

**`data-shimmer-no-children`** 将元素捕获为单一的闪光块,而不是重现其子孙. 对密集的、应作为单一占位符出现的计量组有用.

**`data-shimmer-width`** 编号 : **`data-shimmer-height`** 覆盖元素的已测量维度( 像素) 。 可用于在骨架生成时尚未有维度的动态大小元素(例如图像未明确) `width`编号 :`height`由联合来文填入的容器)。 零尺寸的元素通常被跳过。 这些属性让你强迫一个骨干块.

```html
<phantom-ui loading>
  <div class="dashboard">
    <div class="logo" data-shimmer-ignore>ACME</div>
    <div class="kpi-row" data-shimmer-no-children>
      <span>$48.2k</span>
      <span>2,847 users</span>
      <span>42ms p99</span>
    </div>
    <img src="/hero.jpg" data-shimmer-width="600" data-shimmer-height="400" />
    <div class="content">
      <p>Each leaf element here gets its own shimmer block.</p>
    </div>
  </div>
</phantom-ui>
```

## 重复模式

在加载动态列表或表格时,您往往还没有数据来渲染N行. 这个 `count` 属性允许您定义一个单一模板元素,并从中生成多个骨架行:

```html
<phantom-ui loading count="5" count-gap="8">
  <div class="user-row">
    <img src="avatar.png" width="32" height="32" />
    <span>John Doe</span>
    <span>john@acme.io</span>
  </div>
</phantom-ui>
```

组件测量模板一次,然后垂直复制每个计数的骨干块. `count-gap` 增加重复行之间的间隔(以像素计). 何时 `loading` 删除时,只显示真正的模板元素.

在数据加载前列表为空的框架循环中, 这样做是有用的 :

```tsx
// React
<phantom-ui loading={!users} count={5} count-gap={8}>
  <div class="row-template">
    <img src="/placeholder.png" width="32" height="32" />
    <span>Placeholder Name</span>
    <span>placeholder@email.com</span>
  </div>
</phantom-ui>
```

## 如何运作

1.  您的真实内容在DOM中呈现 `color: transparent` 和媒体元素隐藏。 用 CSS 绘制的图标 `mask-image` (包括 `::before` 编号 : `::after`)在运行时检测出并隐藏。 集装箱背景和边界保持可见,保留了天然卡/分节大纲.
    
2.  组件走 DOM 树并识别出"叶"元素:文本节点,图像,按钮,输入,以及没有子元素的任何东西. 集装箱潜水器被重复使用,而不是被捕获.
    
3.  每个叶子元素都用 `getBoundingClientRect()` 相对主机。 边框半径从 `getComputedStyle()`。表格单元格获得特殊处理,以测量实际文本宽度,而不是单元格宽度.
    
4.  一个绝对位置的叠加使每个被测量的元素有一个闪光块,一个CSS梯度动画横扫每个块.
    
5.  A 类 `ResizeObserver`, (中文(简体) ), `MutationObserver`媒体 `load` 收听器在布局变化(窗口调整大小,内容注入,DOM突变,或图像/视频完成加载)时自动重新测量. 与 `pierce-shadow`穿孔的阴影根也被监视着.
    
6.  何时 `loading` 被删除,覆盖被销毁,真实内容被披露. `aria-busy` 自动设置在主机元素上,以沟通加载状态以辅助技术,占位符内容被制作 `inert` 装入时, 它会远离标签顺序和可访问性树( 标出元素) `data-shimmer-ignore` 保持互动).
    

## 业绩

DOM测量管道快. 在克罗梅基准:

| 要件 | 叶节点 | 时间 |
| --- | --- | --- |
| 100个 | 334 (韩语) | ~ 20 ms 时 |
| 500个 | 1 667个 | ~25ms 时 |
| 1 000个 | 3 334个 | ~31ms 时 |

即使拥有了1000个元素(远不止一个典型的骨架屏幕),全量度-使周期在一帧中完成. 不需要拆卸或虚拟化.

## CSS 自定义属性

您可以使用 CSS 自定义属性而不是(或除此之外) 属性从外部对组件进行样式化 :

```css
phantom-ui {
  --shimmer-color: rgba(100, 200, 255, 0.3);
  --shimmer-duration: 2s;
  --shimmer-bg: rgba(100, 200, 255, 0.08);
}
```

对于活生生的他们(例如,一个黑暗模式的切换,没有重新投降),通过 `var()` 通过一个属性来引用,使其重新溶解于涂料上:

```html
<phantom-ui shimmer-color="var(--brand-shimmer)" background-color="var(--brand-bg)">
```

## 自定义元素外观

货包船a `custom-elements.json` 显示,它使 IDE 自动完成,Storybook 自动docs, 和框架工具可以完整地显示属性、属性、插槽和类型.

## 套装大小

CDN建筑(包括了)为~34kb /~ 11.5kb gzipped.

当用同捆绑器作为ES模块时,Lit很可能已经在你的依赖树上,使组件成本降至2kb以下.

## 发展

```bash
bun install
bun run storybook       # dev server on :6006
bun run build           # tsc + custom elements manifest + CDN bundle
bun run lint            # biome check
bun run lint:fix        # biome auto-fix
bun run test            # browser tests (Chromium)
bun run test:all        # browser tests (Chromium + Firefox + WebKit)
bun run playground      # local server to test the component
```

这个 `examples/` 目录包含React,Vue,Solid,Angular,和Qwik的测试应用程序,每个软件都被接通本地包.

## 捐款

错误报告,特性请求,和PR欢迎. 读取 [贡献指南](https://npmcn.com/package/%40aejkatappaja/phantom-ui/CONTRIBUTING.md) 财务报告和审定财务报表 [行为守则](https://npmcn.com/package/%40aejkatappaja/phantom-ui/CODE_OF_CONDUCT.md) 在打开公关前.

关于安全弱点,见 [安全政策](https://npmcn.com/package/%40aejkatappaja/phantom-ui/SECURITY.md)。 。 。 .

## 鸣谢

DOM测量叠加技术基于前作的艺术 [页面-skeleton-webpack-插件](https://github.com/ElemeFE/page-skeleton-webpack-plugin) (2018年)和 [@findify/skeleton - 生成器](https://github.com/findify/skeleton-generator) (~2019) (中文(中国大陆) ). 奇幻-伊再设想这个概念是一个单一的通用Web组件,而不是框架特定的适配器.

## 许可证

麻省理工学院

## 常见问题

### @aejkatappaja/phantom-ui 是什么？

结构意识发光的骨架装载器是使用Lit建造的通用的Web组件,使用React,Vue,Svelte,Angular,Solid,或vanilla JS\.

### 如何安装 @aejkatappaja/phantom-ui？

在项目目录运行 npm install @aejkatappaja/phantom-ui，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 phantom-ui，可以用 npx phantom-ui 直接运行。

### @aejkatappaja/phantom-ui 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @aejkatappaja/phantom-ui 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @aejkatappaja/phantom-ui 可以商用吗？

@aejkatappaja/phantom-ui 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @aejkatappaja/phantom-ui 的下载量有多少？

根据 npm 官方下载统计，@aejkatappaja/phantom-ui 在 2026/10/05 – 2026/11/03 这 30 天内被下载 25,406 次，日均约 847 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @aejkatappaja/phantom-ui 还在维护吗？

最新版本 1\.6\.1 发布于 2026/07/31（3 个月前）；至今共发布 32 个版本，其中过去 12 个月发布了 32 个；首次发布于 2026/03/31。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

