duskmoon-elements

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

DuskMoon Elements

DuskMoon Elements

43 custom element packages built on
@duskmoon-dev/el-base
. Each element is a standard Web Component with Shadow DOM.
基于
@duskmoon-dev/el-base
构建的43个自定义元素包。每个元素都是带有Shadow DOM的标准Web Component。

Installation

安装

bash
undefined
bash
undefined

Individual element

单独安装元素

bun add @duskmoon-dev/el-button
bun add @duskmoon-dev/el-button

All elements at once

一次性安装所有元素

bun add @duskmoon-dev/elements
undefined
bun add @duskmoon-dev/elements
undefined

Registration

注册

typescript
// Option 1: Explicit (tree-shakable)
import { register } from '@duskmoon-dev/el-button';
register();

// Option 2: Side-effect auto-register
import '@duskmoon-dev/el-button/register';

// Option 3: Register all elements
import { registerAll } from '@duskmoon-dev/elements';
registerAll();
typescript
// 方式1:显式注册(支持摇树优化)
import { register } from '@duskmoon-dev/el-button';
register();

// 方式2:副作用自动注册
import '@duskmoon-dev/el-button/register';

// 方式3:注册所有元素
import { registerAll } from '@duskmoon-dev/elements';
registerAll();

Usage in HTML

HTML中的使用

html
<el-dm-button variant="filled" color="primary" size="md">
  Click me
</el-dm-button>

<el-dm-dialog id="my-dialog">
  <span slot="header">Title</span>
  Dialog content here.
  <div slot="footer">
    <el-dm-button onclick="this.closest('el-dm-dialog').hide()">Close</el-dm-button>
  </div>
</el-dm-dialog>
html
<el-dm-button variant="filled" color="primary" size="md">
  点击我
</el-dm-button>

<el-dm-dialog id="my-dialog">
  <span slot="header">标题</span>
  对话框内容在此。
  <div slot="footer">
    <el-dm-button onclick="this.closest('el-dm-dialog').hide()">关闭</el-dm-button>
  </div>
</el-dm-dialog>

Properties & Attributes

属性与特性

Set via HTML attributes (kebab-case) or JS properties (camelCase). Properties with
reflect: true
sync both directions.
html
<!-- HTML attributes -->
<el-dm-button variant="outlined" disabled>Save</el-dm-button>

<!-- JS properties -->
<script>
  const btn = document.querySelector('el-dm-button');
  btn.variant = 'outlined';
  btn.disabled = true;
</script>
Common properties across elements:
PropertyTypeDescription
variant
StringVisual variant (
filled
,
outlined
,
soft
,
text
,
ghost
)
color
StringColor theme (
primary
,
secondary
,
success
,
warning
,
error
,
info
)
size
StringSize (
sm
,
md
,
lg
)
disabled
BooleanDisable interaction
Complex data (arrays, objects) must be set via JS — use
attribute: false
:
javascript
const table = document.querySelector('el-dm-table');
table.columns = [{ field: 'name', header: 'Name' }];
table.data = [{ name: 'Alice' }, { name: 'Bob' }];
可通过HTML特性(短横线命名)或JS属性(驼峰命名)设置。带有
reflect: true
的属性会双向同步。
html
<!-- HTML特性 -->
<el-dm-button variant="outlined" disabled>保存</el-dm-button>

<!-- JS属性 -->
<script>
  const btn = document.querySelector('el-dm-button');
  btn.variant = 'outlined';
  btn.disabled = true;
</script>
元素通用属性:
属性类型描述
variant
字符串视觉变体(
filled
outlined
soft
text
ghost
color
字符串颜色主题(
primary
secondary
success
warning
error
info
size
字符串尺寸(
sm
md
lg
disabled
布尔值禁用交互
复杂数据(数组、对象)必须通过JS设置——使用
attribute: false
javascript
const table = document.querySelector('el-dm-table');
table.columns = [{ field: 'name', header: 'Name' }];
table.data = [{ name: 'Alice' }, { name: 'Bob' }];

Events

事件

Listen with
addEventListener
. Events bubble and are composed (cross shadow DOM).
javascript
const table = document.querySelector('el-dm-table');
table.addEventListener('sort', (e) => {
  console.log(e.detail); // { column: 'name', direction: 'asc' }
});
table.addEventListener('row-click', (e) => {
  console.log(e.detail); // { row: {...}, rowIndex: 0 }
});
Common events:
ElementEventDetail
dialog
open
,
close
table
sort
{ column, direction }
table
select
{ selectedIds, selectedRows }
table
page-change
{ page, pageSize }
pagination
page-change
{ page }
tabs
tab-change
{ index, tab }
input
dm-input
,
dm-change
{ value }
使用
addEventListener
监听事件。事件会冒泡且可穿透Shadow DOM。
javascript
const table = document.querySelector('el-dm-table');
table.addEventListener('sort', (e) => {
  console.log(e.detail); // { column: 'name', direction: 'asc' }
});
table.addEventListener('row-click', (e) => {
  console.log(e.detail); // { row: {...}, rowIndex: 0 }
});
通用事件:
元素事件详情
dialog
open
close
table
sort
{ column, direction }
table
select
{ selectedIds, selectedRows }
table
page-change
{ page, pageSize }
pagination
page-change
{ page }
tabs
tab-change
{ index, tab }
input
dm-input
dm-change
{ value }

Slots

插槽

Named slots project light DOM content into the element's shadow DOM.
html
<el-dm-button>
  <span slot="prefix">🔍</span>
  Search
  <span slot="suffix"></span>
</el-dm-button>

<el-dm-card>
  <span slot="header">Card Title</span>
  Card body content
  <div slot="footer">Footer</div>
</el-dm-card>
Common slots: (default),
header
,
footer
,
prefix
,
suffix
,
empty
,
actions
.
命名插槽可将普通DOM内容投射到元素的Shadow DOM中。
html
<el-dm-button>
  <span slot="prefix">🔍</span>
  搜索
  <span slot="suffix"></span>
</el-dm-button>

<el-dm-card>
  <span slot="header">卡片标题</span>
  卡片主体内容
  <div slot="footer">页脚</div>
</el-dm-card>
通用插槽:(默认)、
header
footer
prefix
suffix
empty
actions

CSS Parts

CSS部件

Style shadow DOM internals from outside using
::part()
:
css
el-dm-button::part(button) {
  border-radius: 0;
}
el-dm-dialog::part(backdrop) {
  backdrop-filter: blur(4px);
}
el-dm-table::part(thead) {
  background: var(--color-surface-container-high);
}
使用
::part()
从外部样式化Shadow DOM内部元素:
css
el-dm-button::part(button) {
  border-radius: 0;
}
el-dm-dialog::part(backdrop) {
  backdrop-filter: blur(4px);
}
el-dm-table::part(thead) {
  background: var(--color-surface-container-high);
}

Theming

主题设置

Elements use CSS custom properties from
@duskmoon-dev/el-base
. Apply a preset theme:
typescript
import { applyTheme } from '@duskmoon-dev/el-base';

applyTheme(document.documentElement, 'moonlight'); // dark
applyTheme(document.documentElement, 'sunshine');   // light
// Also: 'ocean', 'forest', 'rose'
Override individual variables:
css
:root {
  --color-primary: oklch(60% 0.15 250);
  --color-surface: #ffffff;
}
Key variables:
--color-primary
,
--color-surface
,
--color-on-surface
,
--color-outline
,
--color-surface-container
.
See references/core-api.md for full CSS variable list.
元素使用
@duskmoon-dev/el-base
中的CSS自定义属性。应用预设主题:
typescript
import { applyTheme } from '@duskmoon-dev/el-base';

applyTheme(document.documentElement, 'moonlight'); // 深色
applyTheme(document.documentElement, 'sunshine');   // 浅色
// 还支持:'ocean'、'forest'、'rose'
覆盖单个变量:
css
:root {
  --color-primary: oklch(60% 0.15 250);
  --color-surface: #ffffff;
}
核心变量:
--color-primary
--color-surface
--color-on-surface
--color-outline
--color-surface-container
完整CSS变量列表请查看references/core-api.md

Batched Rendering

批量渲染

Property changes are batched via
queueMicrotask
. Multiple changes in the same tick produce a single re-render:
javascript
const el = document.querySelector('el-dm-button');
el.variant = 'outlined';
el.color = 'error';
el.size = 'lg';
// → single re-render
属性变更通过
queueMicrotask
批量处理。同一事件循环中的多次变更只会触发一次重新渲染:
javascript
const el = document.querySelector('el-dm-button');
el.variant = 'outlined';
el.color = 'error';
el.size = 'lg';
// → 仅一次重新渲染

References

参考资料

  • Element catalog — all 43 packages by category with class names
  • Core API — BaseElement API, mixins, style utilities, CSS variables, themes, validation
For CSS art elements (
<el-dm-art-*>
), see the duskmoon-art-elements skill.
  • 元素目录 — 按类别划分的全部43个包及类名
  • 核心API — BaseElement API、混合器、样式工具、CSS变量、主题、验证
关于CSS艺术元素(
<el-dm-art-*>
),请查看duskmoon-art-elements技能文档。