Sinking Foundations to TapUI
DuoyunUI targets desktop admin UIs, while TapUI is mobile-first. Both share the Gem stack, so reusable foundations move down into TapUI; DuoyunUI keeps desktop-specific UI on top.
What Moved Down
Recent sinks include:
- Utilities & theme:
lib/*,locales/*, parts ofhelper/*(earlier) - Base classes: visible / resize bases (still re-exported under the old
Duoyun*names) - List core: infinite scroll and virtualization live in
<tap-list>;<dy-list>extends it and keeps the default desktop item render (avatar, title, description)
Rough layering:
TapUI foundations, light interaction, reusable structure
└─ DuoyunUI desktop look, default rendering, admin components & patternsApps can keep importing from duoyun-ui; it depends on @mantou/tap-ui underneath.
Customizing UI: Class Tokens
After the sink, prefer composing styles over forking templates:
- Expose class tokens with
css({})in TapUI (or the base implementation) - In DuoyunUI (or your app), target the same token to layer styles
In TapUI, define tokens and apply them in the template:
import { css, html, GemElement } from '@mantou/gem/lib/element';
import { adoptedStyle, customElement } from '@mantou/gem/lib/decorators';
import { styled } from '@mantou/gem/lib/utils';
export const styles = css({
div: styled`
color: blue;
`,
});
@customElement('tap-demo')
@adoptedStyle(styles)
export class TapDemoElement extends GemElement {
render = () => html`<div class=${styles.div}>TapUI</div>`;
}In DuoyunUI (or above), extend that token without changing structure:
import { css } from '@mantou/gem/lib/element';
import { adoptedStyle, customElement } from '@mantou/gem/lib/decorators';
import { styles, TapDemoElement } from '@mantou/tap-ui/elements/demo';
const dyStyles = css({
[styles.div]: `
font-weight: bold;
font-size: 2em;
`,
});
@customElement('dy-demo')
@adoptedStyle(dyStyles)
export class DuoyunDemoElement extends TapDemoElement {}Notes:
styles.divis both the class name in the template and the selector key in the override sheet- The upper layer only adds diffs; structure and default behavior stay in TapUI
- DuoyunUI remains the place for theme colors, spacing, and desktop defaults like
renderItem
That is also the intended direction for components such as <dy-list>: interaction in TapUI, look-and-feel in DuoyunUI, customized via class tokens (plus existing ::part / theme variables).
Summary
Sinking foundations into TapUI aims to:
- Share virtualization, visibility/resize observers, and other infra across mobile and desktop
- Keep DuoyunUI focused on desktop experience and defaults
- Customize with composable class tokens instead of forked implementations
New work should follow: TapUI provides structure and tokens → DuoyunUI customizes appearance.
