style(ui): unify sky-atlas visual system
Centralize interactive component styles, adopt the fresh eucalyptus palette, and keep map controls square with hard shadows. Update project guidance and the OpenCloud style skill to match the implementation.
This commit is contained in:
@@ -7,30 +7,43 @@ const sourceRoot = new URL('../src', import.meta.url)
|
||||
const deprecatedPatterns = [
|
||||
{
|
||||
pattern: /\b(?:bg|border|ring|text)-(?:gray|indigo|purple|violet)-\d+\b/g,
|
||||
message: '使用项目约定的 slate/sky/teal 语义色,不要重新引入灰色或紫色系。',
|
||||
message: '使用项目约定的 slate/sky/自然绿色语义色,不要重新引入灰色或紫色系。',
|
||||
},
|
||||
{
|
||||
pattern: /\b(?:bg|border|ring|text)-(?:green|lime)-\d+\b/g,
|
||||
message: '绿色必须使用项目重映射后的 teal 品牌色或 emerald 成功色,不要引入默认 green/lime 荧光色。',
|
||||
},
|
||||
{
|
||||
pattern: /#(?:f0fdfa|ccfbf1|99f6e4|5eead4|2dd4bf|14b8a6|0d9488|0f766e|115e59|134e4a)\b/gi,
|
||||
message: '检测到旧版高饱和 teal 色值,请改用自然绿色设计令牌。',
|
||||
},
|
||||
{
|
||||
pattern: /text-xs uppercase tracking-\[0\.18em\] text-slate-500/g,
|
||||
message: '重复的小节标签应使用 oc-section-label。',
|
||||
vueOnly: true,
|
||||
},
|
||||
{
|
||||
pattern: /border border-slate-200 bg-slate-50 p-4/g,
|
||||
message: '标准内嵌信息面板应使用 oc-inset-panel。',
|
||||
vueOnly: true,
|
||||
},
|
||||
{
|
||||
pattern: /border-b border-sky-100 bg-\[linear-gradient\(180deg,#e0f2fe_0%,#f8fafc_100%\)\]/g,
|
||||
message: '标准页面头部应使用 oc-page-hero。',
|
||||
vueOnly: true,
|
||||
},
|
||||
]
|
||||
|
||||
async function collectVueFiles(directory) {
|
||||
const styleSourceExtensions = new Set(['.vue', '.css', '.ts'])
|
||||
|
||||
async function collectStyleSourceFiles(directory) {
|
||||
const entries = await readdir(directory, { withFileTypes: true })
|
||||
const files = await Promise.all(entries.map(async (entry) => {
|
||||
const path = join(directory, entry.name)
|
||||
return entry.isDirectory() ? collectVueFiles(path) : [path]
|
||||
return entry.isDirectory() ? collectStyleSourceFiles(path) : [path]
|
||||
}))
|
||||
|
||||
return files.flat().filter((path) => extname(path) === '.vue')
|
||||
return files.flat().filter((path) => styleSourceExtensions.has(extname(path)))
|
||||
}
|
||||
|
||||
function lineNumberAt(source, index) {
|
||||
@@ -39,10 +52,12 @@ function lineNumberAt(source, index) {
|
||||
|
||||
const violations = []
|
||||
|
||||
for (const file of await collectVueFiles(sourceRoot.pathname)) {
|
||||
for (const file of await collectStyleSourceFiles(sourceRoot.pathname)) {
|
||||
const source = await readFile(file, 'utf8')
|
||||
|
||||
for (const rule of deprecatedPatterns) {
|
||||
if (rule.vueOnly && extname(file) !== '.vue') continue
|
||||
|
||||
for (const match of source.matchAll(rule.pattern)) {
|
||||
violations.push({
|
||||
file: relative(projectRoot.pathname, file),
|
||||
|
||||
Reference in New Issue
Block a user