Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ dist/
.DS_Store
*.log
tmp/
package-lock.json
338 changes: 338 additions & 0 deletions design-preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TDesign Starter</title>
<style>
:root {
color-scheme: light;
--bg: #f5f7fa;
--surface: #fff;
--surface-soft: #f7f8fa;
--text: #1d2129;
--secondary: #5f6b7a;
--muted: #8b96a5;
--border: #dfe3e8;
--blue: #0052d9;
--blue-hover: #003cab;
--blue-soft: #e8f1ff;
--shadow: 0 14px 40px rgba(31, 45, 61, .08);
}

html.dark {
color-scheme: dark;
--bg: #101214;
--surface: #181b1f;
--surface-soft: #20242a;
--text: #f2f3f5;
--secondary: #a6adb7;
--muted: #7d8794;
--border: #343a43;
--blue: #4587ff;
--blue-hover: #6ca0ff;
--blue-soft: #1d2f50;
--shadow: 0 18px 44px rgba(0, 0, 0, .24);
}

* { box-sizing: border-box; }
body {
min-width: 320px;
min-height: 100vh;
margin: 0;
color: var(--text);
background: var(--bg);
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
button, a { font: inherit; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }
svg { display: block; }

.topbar { height: 64px; border-bottom: 1px solid var(--border); background: var(--surface); }
.topbar-inner {
display: flex;
width: min(1040px, 100%);
height: 100%;
margin: 0 auto;
padding: 0 24px;
align-items: center;
justify-content: space-between;
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand img { display: block; width: 126px; height: auto; }
.brand-divider { width: 1px; height: 18px; background: var(--border); }
.brand-label { color: var(--secondary); font-size: 13px; }
.actions { display: flex; gap: 4px; }
.icon-button {
display: grid;
width: 36px;
height: 36px;
padding: 0;
place-items: center;
color: var(--secondary);
border: 0;
border-radius: 6px;
background: transparent;
}
.icon-button:hover { color: var(--blue); background: var(--blue-soft); }

main { width: min(1040px, 100%); margin: 0 auto; padding: 20px 24px 64px; }
.intro { display: flex; margin-bottom: 18px; align-items: flex-end; justify-content: space-between; gap: 20px; }
h1 { margin: 0 0 8px; font-size: 30px; line-height: 1.3; letter-spacing: 0; overflow-wrap: anywhere; }
.intro p { margin: 0; color: var(--secondary); font-size: 14px; line-height: 1.65; }
.template-id {
flex: 0 0 auto;
padding: 6px 10px;
color: var(--blue);
border: 1px solid #b8d2ff;
border-radius: 5px;
background: var(--blue-soft);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12px;
}

.workspace {
display: grid;
grid-template-columns: minmax(0, 1.55fr) minmax(280px, .65fr);
gap: 18px;
align-items: stretch;
}
.demo-panel {
overflow: hidden;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--surface);
box-shadow: var(--shadow);
}
.demo-head {
display: flex;
height: 56px;
padding: 0 20px;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--border);
}
.demo-title { display: flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 600; }
.status-dot { width: 7px; height: 7px; border-radius: 50%; background: #078343; box-shadow: 0 0 0 3px #e8f7ee; }
.demo-head span:last-child { color: var(--muted); font-size: 11px; }
.demo-stage {
display: grid;
min-height: 430px;
padding: 40px 24px;
place-items: center;
background-color: var(--surface-soft);
background-image: radial-gradient(var(--border) .7px, transparent .7px);
background-size: 18px 18px;
}
.demo-card {
width: min(100%, 440px);
padding: 38px 32px 32px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--surface);
box-shadow: 0 16px 38px rgba(31, 45, 61, .1);
text-align: center;
}
.demo-mark {
display: grid;
width: 54px;
height: 54px;
margin: 0 auto 18px;
place-items: center;
color: #fff;
border-radius: 8px;
background: var(--blue);
font-size: 25px;
font-weight: 800;
}
.demo-card h2 { margin: 0 0 8px; font-size: 22px; letter-spacing: 0; }
.demo-card p { margin: 0 0 24px; color: var(--secondary); font-size: 13px; line-height: 1.65; }
.counter { display: inline-flex; align-items: center; gap: 12px; }
.count {
display: grid;
min-width: 64px;
height: 36px;
padding: 0 12px;
place-items: center;
border: 1px solid var(--border);
border-radius: 4px;
background: var(--surface-soft);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 14px;
}
.demo-button {
display: grid;
width: 36px;
height: 36px;
padding: 0;
place-items: center;
color: #fff;
border: 1px solid var(--blue);
border-radius: 4px;
background: var(--blue);
font-size: 18px;
}
.demo-button:hover { border-color: var(--blue-hover); background: var(--blue-hover); }
.hint { margin-top: 22px; color: var(--muted); font-size: 11px; }

.info-panel {
display: flex;
min-width: 0;
padding: 24px;
border: 1px solid var(--border);
border-radius: 8px;
flex-direction: column;
background: var(--surface);
}
.info-panel h2 { margin: 0 0 8px; font-size: 17px; }
.info-panel > p { margin: 0 0 22px; color: var(--secondary); font-size: 12px; line-height: 1.65; }
.info-list { margin: 0; }
.info-row {
display: flex;
min-height: 46px;
align-items: center;
justify-content: space-between;
gap: 12px;
border-bottom: 1px solid var(--border);
}
.info-row dt { color: var(--muted); font-size: 11px; }
.info-row dd { margin: 0; font-size: 12px; font-weight: 600; text-align: right; overflow-wrap: anywhere; }
.resource-links { display: grid; margin-top: auto; padding-top: 24px; gap: 8px; }
.resource-link {
display: flex;
min-height: 42px;
padding: 0 12px;
align-items: center;
justify-content: space-between;
color: var(--secondary);
border: 1px solid var(--border);
border-radius: 5px;
font-size: 12px;
}
.resource-link:hover { color: var(--blue); border-color: var(--blue); background: var(--blue-soft); }

footer {
display: flex;
width: min(1040px, 100%);
margin: 0 auto;
padding: 0 24px 30px;
align-items: center;
justify-content: space-between;
color: var(--muted);
font-size: 11px;
}
footer a:hover { color: var(--blue); }

@media (max-width: 600px) {
.topbar-inner, main, footer { padding-right: 16px; padding-left: 16px; }
.brand img { width: 112px; }
.brand-divider, .brand-label { display: none; }
main { padding-top: 16px; }
.intro { display: block; }
h1 { font-size: 26px; }
.template-id { display: inline-block; margin-top: 16px; }
.demo-head { padding: 0 14px; }
.demo-stage { min-height: 360px; padding: 24px 14px; }
.demo-card { padding: 30px 18px 26px; }
footer { display: block; line-height: 2; }
}
@media (max-width: 820px) {
.workspace { grid-template-columns: 1fr; }
.info-panel { min-height: 300px; }
}
</style>
</head>
<body>
<header class="topbar">
<div class="topbar-inner">
<a class="brand" href="#" aria-label="TDesign">
<img id="brandLogo" src="templates/vue-vite/src/assets/TDesign-logo_light.png" alt="TDesign" />
<span class="brand-divider"></span>
<span class="brand-label">Project Starter</span>
</a>
<div class="actions">
<a class="icon-button" href="https://tdesign.tencent.com/" target="_blank" rel="noreferrer" aria-label="组件文档" title="组件文档">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z"/></svg>
</a>
<a class="icon-button" href="https://github.com/Tencent/tdesign" target="_blank" rel="noreferrer" aria-label="GitHub" title="GitHub">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3.3-.4 6.8-1.6 6.8-7A5.4 5.4 0 0 0 19.4 4 5 5 0 0 0 19.3.5S18.2.1 15 1.8a13.4 13.4 0 0 0-7 0C4.8.1 3.7.5 3.7.5A5 5 0 0 0 3.6 4a5.4 5.4 0 0 0-1.4 3.7c0 5.4 3.5 6.6 6.8 7A4.8 4.8 0 0 0 8 18v4"/><path d="M8 19c-3 .9-3-1.5-4-2"/></svg>
</a>
<button class="icon-button" id="themeButton" type="button" aria-label="切换主题" title="切换主题">
<svg id="themeIcon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>
</button>
</div>
</div>
</header>

<main>
<section class="intro">
<div>
<h1>__PROJECTNAME__</h1>
<p>一个基于 TDesign 的简单交互示例。</p>
</div>
<span class="template-id">__TEMPLATENAME__</span>
</section>

<div class="workspace">
<section class="demo-panel">
<div class="demo-head">
<div class="demo-title"><span class="status-dot"></span>示例</div>
<span>交互示例</span>
</div>
<div class="demo-stage">
<div class="demo-card">
<span class="demo-mark">T</span>
<h2>Hello, TDesign</h2>
<p>点击按钮,体验这个模板中的基础交互。</p>
<div class="counter" aria-label="计数器">
<button class="demo-button" id="decrease" type="button" aria-label="减少">−</button>
<span class="count" id="count">0</span>
<button class="demo-button" id="increase" type="button" aria-label="增加">+</button>
</div>
<div class="hint">编辑首页文件并保存,查看热更新效果</div>
</div>
</div>
</section>

<aside class="info-panel">
<h2>技术信息</h2>
<p>当前模板使用的构建工具与组件库。</p>
<dl class="info-list">
<div class="info-row"><dt>构建工具</dt><dd>Vite</dd></div>
<div class="info-row"><dt>组件库</dt><dd>tdesign-vue-next</dd></div>
<div class="info-row"><dt>开发语言</dt><dd>TypeScript</dd></div>
</dl>
<div class="resource-links">
<a class="resource-link" href="./dependencies"><span>依赖清单</span><span>→</span></a>
<a class="resource-link" href="https://tdesign.tencent.com/" target="_blank" rel="noreferrer"><span>组件文档</span><span>↗</span></a>
</div>
</aside>
</div>
</main>

<footer><span>Powered by TDesign</span><a href="https://tdesign.tencent.com/" target="_blank" rel="noreferrer">组件文档 →</a></footer>

<script>
const root = document.documentElement;
let count = 0;

document.getElementById('increase').addEventListener('click', () => {
document.getElementById('count').textContent = String(++count);
});
document.getElementById('decrease').addEventListener('click', () => {
document.getElementById('count').textContent = String(--count);
});

document.getElementById('themeButton').addEventListener('click', () => {
const isDark = root.classList.toggle('dark');
document.getElementById('brandLogo').src = isDark
? 'templates/vue-vite/src/assets/TDesign-logo_dark.png'
: 'templates/vue-vite/src/assets/TDesign-logo_light.png';
document.getElementById('themeIcon').innerHTML = isDark
? '<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.66 6.34l1.41-1.41"/>'
: '<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>';
});
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions templates/mobile-react-rsbuild/rsbuild.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ import path from 'path'

export default defineConfig({
plugins: [pluginReact()],
server: {
host: '0.0.0.0',
},
source: {
entry: {
index: './src/main.tsx',
},
// react-router 的 routeModules 引用了 Vite 专属的 import.meta.hot,
// 在 Rsbuild(Rspack)下不存在,构建时会产生 “Accessing unknown import.meta property 'hot'” 警告。
// 将其定义为 false 以消除该警告(模板为静态路由,不涉及懒加载 HMR,行为不变)。
define: {
'import.meta.hot': 'false',
},
},
html: {
template: './index.html',
Expand Down
1 change: 1 addition & 0 deletions templates/mobile-react-rsbuild/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router'
import router from './router'
import './style.css'
import 'tdesign-mobile-react/es/style/index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
Expand Down
Loading
Loading