@aphrody/m3-react

中文文档
1.4.7发布于 2026/10/23Apache-2.0TypeScriptES Module近 30 天下载 2074

React wrappers (@lit/react createComponent) for every <md-*> element of the @aphrody/material-web fork.

原始使用文档
文档目录5 节
  1. Slots and icons
  2. Layout
  3. Mapped events (verified in the Lit sources)
  4. Type checking
  5. All wrappers (119)

@aphrody/m3-react

Typed React components for every md-* element of @aphrody/material-web, generated with @lit/react createComponent.

bun add @aphrody/m3-react @aphrody/material-web react react-dom
import {
  MdCheckbox,
  MdFilledButton,
  MdOutlinedTextField,
} from "@aphrody/m3-react";

export function SignIn() {
  return (
    <form>
      <MdOutlinedTextField
        label="Email"
        onInput={e => console.log((e.target as HTMLInputElement).value)}
      />
      <MdCheckbox
        onChange={e => console.log((e.target as HTMLInputElement).checked)}
      />
      <MdFilledButton type="submit">Sign in</MdFilledButton>
    </form>
  );
}

License: Apache-2.0 (LICENSE). Install guide: docs/material/m3/INSTALL.md.

One wrapper per tag (PascalCase of the tag name), with the element's real native events mapped to React props. Importing a wrapper registers its custom element as a side effect (the wrapper imports the @aphrody/material-web module that calls customElements.define); no other import is needed. The elements are Lit web components, so they render on the client; see FRAMEWORKS.md for SSR and RSC setups.

ImportContents
@aphrody/m3-reactAll wrappers (MdFilledButton, MdDialog, ...)
@aphrody/m3-react/<group>One wrapper group, e.g. @aphrody/m3-react/button
@aphrody/m3-react/transitionsCollapse, Fade, Grow, Slide, Zoom
@aphrody/m3-react/adaptiveWindow size class hooks (SSR-safe)
@aphrody/m3-react/stateuseTextFieldState, bindTextFieldState
@aphrody/m3-react/dataDataTable, VirtualList
@aphrody/m3-react/adapters/tanstackTanStack Table adapter

Controlled inputs read e.target.value / e.target.checked; the handler receives the DOM event, not (event, value).

Slots and icons

Sub-parts are slotted content:

import {
  MdDialog,
  MdFilledButton,
  MdIcon,
  MdTextButton,
} from "@aphrody/m3-react";

<MdDialog
  open
  onClosed={e => console.log((e.target as HTMLDialogElement).returnValue)}
>
  <div slot="headline">Delete?</div>
  <form slot="content" method="dialog">
    This cannot be undone.
  </form>
  <div slot="actions">
    <MdTextButton value="cancel">Cancel</MdTextButton>
    <MdFilledButton value="delete">
      <MdIcon slot="icon">delete</MdIcon>
      Delete
    </MdFilledButton>
  </div>
</MdDialog>;

MdIcon needs the Material Symbols font, which the library does not load. Load it once at startup:

import { ensureMaterialSymbols } from "@aphrody/material-web/icon/material-symbols.js";
ensureMaterialSymbols(); // or { iconNames: ["delete", "search"] } to subset

The child text is the glyph name (Material Symbols snake_case). Variable axes are tokens: --md-icon-fill (0..1), --md-icon-wght (100..700), --md-icon-grad, --md-icon-opsz.

Layout

  • src/index.ts: re-exports every wrapper (one export * per group).

  • src/wrappers/<group>.ts: one file per material-web source folder (button.ts, select.ts, labs.ts, ...). Each export:

    export const MdFilledButton = createComponent({
      react: React,
      tagName: "md-filled-button",
      elementClass: MdFilledButtonElement, // from @aphrody/material-web/button/filled-button.js
      events: {}, // real native events (see the table below)
    });
    
  • generate.ts: reads md-elements.txt, scans a material-web source checkout (--source <dir>) to resolve each tag to its entry file and exported class (@customElement('md-x') export class Foo), applies the verified event table and writes src/wrappers/, src/index.ts, .manifest.json and the last section of this README. It prefers the canonical path (bundled by all.ts, aphrody-components.ts or aphrody-labs.ts), then non-labs/gb, then labs/gb (the only home of md-button, md-card, md-menu-group and md-split-button, whose classes are re-aliased to Md*).

  • src/material-web-shims.d.ts: ambient *.cssresult.js and *.css modules, see below.

Mapped events (verified in the Lit sources)

Event names come from @fires and new (Custom)?Event('...') in material-web/<dir>/internal/*.ts. Upstream components use plain names (input, change, opening, ...); fork components namespace theirs (paginator:page, table:sort, side-sheet:opening, tree:select, ...).

ElementReact prop to native event
MdCheckbox, MdRadio, MdSwitch, MdSlider, Md*TextFieldonChange:change, onInput:input
MdFilledSelect, MdOutlinedSelect+onOpening/onOpened/onClosing/onClosed
MdDialogonOpen:open, onOpened, onClose:close, onClosed, onCancel:cancel
MdMenu, MdSubMenuonOpening/onOpened/onClosing/onClosed
MdMenuItemonCloseMenu:close-menu
MdSnackbaronOpening/onOpened/onClosing/onClosed (bare)
MdBottomSheet / MdSideSheetonOpening:bottom-sheet:opening ... (fork, namespaced)
MdSearchBaronInput, onSearch:search, onSearchOpen/onSearchClose
MdAutocompleteonInput, onSelect:autocomplete:select
MdNavigationBaronActivated:navigation-bar-activated
MdNavigationRailonChange:navigation-rail:change, onItemActivate
MdNavigationDrawer(Modal)onNavigationDrawerChanged:navigation-drawer-changed
MdInputChiponRemove:remove, onUpdateFocus:update-focus
MdButtonGrouponChange:button-group:change
MdFabMenu / MdFabMenuItemonOpen/onClose:fab-menu:*, onClick:fab-menu-item:click
MdExpansionPanelonToggle:expansion:toggle
MdStepperonChange:stepper:change
MdDatePicker / MdTimePickeronChange:date-picker:change / time-picker:change
MdTableonSort:table:sort, onSelectionChange:table:selection-change
MdPaginatoronPage:paginator:page
MdTree / MdTreeItemonSelect:tree:select / onToggle:tree-item:toggle, onActivate
MdVirtualScrolleronRange:virtual-scroll:range
MdTooltiponShow:tooltip-show, onHide:tooltip-hide
MdTabsonChange:change

Presentational elements (md-icon, md-divider, md-elevation, md-ripple, md-focus-ring, assist/filter/suggestion chips, cards, fab, buttons, md-item, md-toolbar, md-carousel, md-accordion, md-loading-indicator, panes and scaffold) emit no documented event: events: {}.

Type checking

bun check --noEmit checks the wrappers and the material-web sources they import. The package tsconfig.json sets:

  1. experimentalDecorators: true and useDefineForClassFields: false: the fork's Lit elements use legacy decorators.
  2. src/material-web-shims.d.ts: declares *.cssresult.js and *.css as ambient modules. They are Sass build artifacts absent from a source checkout; the wrappers never touch them, so they are typed any (which also avoids the nominal clash between material-web's nested lit@2 and this package's lit@3).
  3. moduleResolution: bundler: resolves bare @aphrody/material-web/x/y.js imports.

Against a built material-web (with *.cssresult.js and *.css present) the shims are unnecessary. All 119 tags of md-elements.txt resolve to a real entry file with an exported class.

All wrappers (119)

Regenerated by generate.ts (.manifest.json). 0 unresolved.

WrapperTagElement import# events
Md3dCanvasmd-3d-canvas@aphrody/material-web/canvas3d/canvas-3d.js—
Md3dCardmd-3d-card@aphrody/material-web/card3d/card-3d.js—
Md3dGlobemd-3d-globe@aphrody/material-web/globe3d/globe-3d.js—
MdAccordionmd-accordion@aphrody/material-web/expansion/accordion.js—
MdAlertmd-alert@aphrody/material-web/alert/alert.js1
MdAreaChartmd-area-chart@aphrody/material-web/charts/area-chart.js—
MdAssistChipmd-assist-chip@aphrody/material-web/chips/assist-chip.js—
MdAutocompletemd-autocomplete@aphrody/material-web/autocomplete/autocomplete.js2
MdAvatarmd-avatar@aphrody/material-web/avatar/avatar.js1
MdAvatarGroupmd-avatar-group@aphrody/material-web/avatar/avatar-group.js—
MdBackdropmd-backdrop@aphrody/material-web/backdrop/backdrop.js—
MdBadgemd-badge@aphrody/material-web/badge/badge.js—
MdBarChartmd-bar-chart@aphrody/material-web/charts/bar-chart.js—
MdBottomAppBarmd-bottom-app-bar@aphrody/material-web/appbar/bottom-app-bar.js—
MdBottomSheetmd-bottom-sheet@aphrody/material-web/sheet/bottom-sheet.js4
MdBrandedFabmd-branded-fab@aphrody/material-web/fab/branded-fab.js—
MdBreadcrumbsmd-breadcrumbs@aphrody/material-web/breadcrumbs/breadcrumbs.js—
MdButtonmd-button@aphrody/material-web/labs/gb/components/button/md-button.js—
MdButtonGroupmd-button-group@aphrody/material-web/buttongroup/button-group.js1
MdCardmd-card@aphrody/material-web/card/card.js—
MdCarouselmd-carousel@aphrody/material-web/carousel/carousel.js1
MdCarouselItemmd-carousel-item@aphrody/material-web/carousel/carousel-item.js—
MdCheckboxmd-checkbox@aphrody/material-web/checkbox/checkbox.js2
MdChipSetmd-chip-set@aphrody/material-web/chips/chip-set.js—
MdCircularProgressmd-circular-progress@aphrody/material-web/progress/circular-progress.js—
MdDatePickermd-date-picker@aphrody/material-web/datepicker/date-picker.js1
MdDateRangePickermd-date-range-picker@aphrody/material-web/datepicker/date-range-picker.js3
MdDateTimePickermd-date-time-picker@aphrody/material-web/datepicker/date-time-picker.js3
MdDialogmd-dialog@aphrody/material-web/dialog/dialog.js5
MdDividermd-divider@aphrody/material-web/divider/divider.js—
MdElevatedButtonmd-elevated-button@aphrody/material-web/button/elevated-button.js—
MdElevatedCardmd-elevated-card@aphrody/material-web/labs/card/elevated-card.js—
MdElevationmd-elevation@aphrody/material-web/elevation/elevation.js—
MdExpansionPanelmd-expansion-panel@aphrody/material-web/expansion/expansion-panel.js1
MdFabmd-fab@aphrody/material-web/fab/fab.js—
MdFabMenumd-fab-menu@aphrody/material-web/fabmenu/fab-menu.js2
MdFabMenuItemmd-fab-menu-item@aphrody/material-web/fabmenu/fab-menu-item.js1
MdFilledButtonmd-filled-button@aphrody/material-web/button/filled-button.js—
MdFilledCardmd-filled-card@aphrody/material-web/labs/card/filled-card.js—
MdFilledFieldmd-filled-field@aphrody/material-web/field/filled-field.js—
MdFilledIconButtonmd-filled-icon-button@aphrody/material-web/iconbutton/filled-icon-button.js—
MdFilledSelectmd-filled-select@aphrody/material-web/select/filled-select.js6
MdFilledTextFieldmd-filled-text-field@aphrody/material-web/textfield/filled-text-field.js2
MdFilledTonalButtonmd-filled-tonal-button@aphrody/material-web/button/filled-tonal-button.js—
MdFilledTonalIconButtonmd-filled-tonal-icon-button@aphrody/material-web/iconbutton/filled-tonal-icon-button.js—
MdFilterChipmd-filter-chip@aphrody/material-web/chips/filter-chip.js—
MdFocusRingmd-focus-ring@aphrody/material-web/focus/md-focus-ring.js—
MdGaugemd-gauge@aphrody/material-web/charts/gauge.js—
MdGridListmd-grid-list@aphrody/material-web/gridlist/grid-list.js—
MdGridTilemd-grid-tile@aphrody/material-web/gridlist/grid-tile.js—
MdIconmd-icon@aphrody/material-web/icon/icon.js—
MdIconButtonmd-icon-button@aphrody/material-web/iconbutton/icon-button.js—
MdInputChipmd-input-chip@aphrody/material-web/chips/input-chip.js2
MdItemmd-item@aphrody/material-web/labs/item/item.js—
MdLinearProgressmd-linear-progress@aphrody/material-web/progress/linear-progress.js—
MdLineChartmd-line-chart@aphrody/material-web/charts/line-chart.js—
MdLinkmd-link@aphrody/material-web/link/link.js—
MdListmd-list@aphrody/material-web/list/list.js—
MdListDetailmd-list-detail@aphrody/material-web/layout/md-list-detail.js—
MdListItemmd-list-item@aphrody/material-web/list/list-item.js—
MdLoadingIndicatormd-loading-indicator@aphrody/material-web/loadingindicator/loading-indicator.js—
MdMenumd-menu@aphrody/material-web/menu/menu.js4
MdMenuGroupmd-menu-group@aphrody/material-web/labs/gb/components/menu/md-menu-group.js—
MdMenuItemmd-menu-item@aphrody/material-web/menu/menu-item.js1
MdMobileSteppermd-mobile-stepper@aphrody/material-web/mobilestepper/mobile-stepper.js—
MdNavigationBarmd-navigation-bar@aphrody/material-web/labs/navigationbar/navigation-bar.js1
MdNavigationDrawermd-navigation-drawer@aphrody/material-web/labs/navigationdrawer/navigation-drawer.js1
MdNavigationDrawerModalmd-navigation-drawer-modal@aphrody/material-web/labs/navigationdrawer/navigation-drawer-modal.js1
MdNavigationRailmd-navigation-rail@aphrody/material-web/navigationrail/navigation-rail.js2
MdNavigationRailItemmd-navigation-rail-item@aphrody/material-web/navigationrail/navigation-rail-item.js—
MdNavigationTabmd-navigation-tab@aphrody/material-web/labs/navigationtab/navigation-tab.js—
MdOutlinedButtonmd-outlined-button@aphrody/material-web/button/outlined-button.js—
MdOutlinedCardmd-outlined-card@aphrody/material-web/labs/card/outlined-card.js—
MdOutlinedFieldmd-outlined-field@aphrody/material-web/field/outlined-field.js—
MdOutlinedIconButtonmd-outlined-icon-button@aphrody/material-web/iconbutton/outlined-icon-button.js—
MdOutlinedSegmentedButtonmd-outlined-segmented-button@aphrody/material-web/labs/segmentedbutton/outlined-segmented-button.js—
MdOutlinedSegmentedButtonSetmd-outlined-segmented-button-set@aphrody/material-web/labs/segmentedbuttonset/outlined-segmented-button-set.js—
MdOutlinedSelectmd-outlined-select@aphrody/material-web/select/outlined-select.js6
MdOutlinedTextFieldmd-outlined-text-field@aphrody/material-web/textfield/outlined-text-field.js2
MdPaginatormd-paginator@aphrody/material-web/paginator/paginator.js1
MdPanemd-pane@aphrody/material-web/layout/md-pane.js—
MdPieChartmd-pie-chart@aphrody/material-web/charts/pie-chart.js—
MdPopovermd-popover@aphrody/material-web/popover/popover.js2
MdPrimaryTabmd-primary-tab@aphrody/material-web/tabs/primary-tab.js—
MdRadarChartmd-radar-chart@aphrody/material-web/charts/radar-chart.js—
MdRadiomd-radio@aphrody/material-web/radio/radio.js2
MdRatingmd-rating@aphrody/material-web/rating/rating.js2
MdRipplemd-ripple@aphrody/material-web/ripple/ripple.js—
MdScaffoldmd-scaffold@aphrody/material-web/layout/md-scaffold.js—
MdScatterChartmd-scatter-chart@aphrody/material-web/charts/scatter-chart.js—
MdSchedulermd-scheduler@aphrody/material-web/scheduler/scheduler.js3
MdSearchBarmd-search-bar@aphrody/material-web/search/search-bar.js4
MdSecondaryTabmd-secondary-tab@aphrody/material-web/tabs/secondary-tab.js—
MdSelectOptionmd-select-option@aphrody/material-web/select/select-option.js—
MdSideSheetmd-side-sheet@aphrody/material-web/sheet/side-sheet.js4
MdSkeletonmd-skeleton@aphrody/material-web/skeleton/skeleton.js—
MdSlidermd-slider@aphrody/material-web/slider/slider.js2
MdSnackbarmd-snackbar@aphrody/material-web/snackbar/snackbar.js4
MdSparklinemd-sparkline@aphrody/material-web/charts/sparkline.js—
MdSplitButtonmd-split-button@aphrody/material-web/labs/gb/components/splitbutton/md-split-button.js—
MdStepmd-step@aphrody/material-web/stepper/step.js—
MdSteppermd-stepper@aphrody/material-web/stepper/stepper.js1
MdSubMenumd-sub-menu@aphrody/material-web/menu/sub-menu.js4
MdSuggestionChipmd-suggestion-chip@aphrody/material-web/chips/suggestion-chip.js—
MdSupportingPanemd-supporting-pane@aphrody/material-web/layout/md-supporting-pane.js—
MdSurfacemd-surface@aphrody/material-web/surface/surface.js—
MdSwitchmd-switch@aphrody/material-web/switch/switch.js2
MdTablemd-table@aphrody/material-web/table/table.js2
MdTabsmd-tabs@aphrody/material-web/tabs/tabs.js1
MdTextButtonmd-text-button@aphrody/material-web/button/text-button.js—
MdTimePickermd-time-picker@aphrody/material-web/timepicker/time-picker.js1
MdToolbarmd-toolbar@aphrody/material-web/toolbar/md-toolbar.js—
MdTooltipmd-tooltip@aphrody/material-web/tooltip/tooltip.js2
MdTopAppBarmd-top-app-bar@aphrody/material-web/appbar/top-app-bar.js—
MdTreemd-tree@aphrody/material-web/tree/tree.js1
MdTreeItemmd-tree-item@aphrody/material-web/tree/tree-item.js2
MdTypemd-type@aphrody/material-web/typography/md-type.js—
MdVirtualScrollermd-virtual-scroller@aphrody/material-web/virtualscroll/virtual-scroller.js1
MdWebgpuCanvasmd-webgpu-canvas@aphrody/material-web/effects/webgpu-canvas.js—

版本与发布记录

@aphrody/m3-react 共发布 16 个版本,首次发布于 2026/06/04;过去 12 个月发布了 16 个版本。

版本发布日期距今
1.4.7latest2026/10/2315 天前
1.4.42026/10/1820 天前
3.3.112026/10/1028 天前
3.3.102026/10/1028 天前
3.3.92026/10/1029 天前
3.3.82026/10/0929 天前

关于 @aphrody/m3-react 的常见问题

@aphrody/m3-react 是什么?

React wrappers (@lit/react createComponent) for every <md-*> element of the @aphrody/material-web fork.

如何安装 @aphrody/m3-react?

在项目目录运行 npm install @aphrody/m3-react,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=18.0.0)、react-dom(>=18.0.0)、@aphrody/material-web(^3.3.3)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@aphrody/m3-react 支持 TypeScript 吗?

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

@aphrody/m3-react 支持 ESM 还是 CommonJS?

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

@aphrody/m3-react 可以商用吗?

@aphrody/m3-react 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@aphrody/m3-react 的下载量有多少?

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

@aphrody/m3-react 还在维护吗?

最新版本 1.4.7 发布于 2026/10/23(15 天前);至今共发布 16 个版本,其中过去 12 个月发布了 16 个;首次发布于 2026/06/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。