|
|
|
|
/**
|
|
|
|
|
* Lint every eidos component CSS against its morfo contract.
|
|
|
|
|
*
|
|
|
|
|
* Usage: npx tsx scripts/eidos-lint-all.ts
|
|
|
|
|
*
|
|
|
|
|
* Prints a per-component summary so the drift between eidos and the
|
|
|
|
|
* morfo declarations is visible at a glance.
|
|
|
|
|
*/
|
|
|
|
|
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
|
|
|
|
import { resolve } from 'node:path'
|
|
|
|
|
|
|
|
|
|
import { compileMorfo } from '../src/uix/morfo/compile'
|
|
|
|
|
import { lintEidosCss } from '../src/uix/eidos/lint'
|
|
|
|
|
import type { Morfo } from '../src/uix/morfo/types'
|
|
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
|
const eidosDir = resolve('src/uix/eidos/components')
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const cssFiles = readdirSync(eidosDir, { withFileTypes: true }).flatMap((entry) => {
|
|
|
|
|
if (entry.isFile() && entry.name.endsWith('.css')) {
|
|
|
|
|
const name = entry.name.replace(/\.css$/, '')
|
|
|
|
|
return [{ name, path: resolve(eidosDir, entry.name) }]
|
|
|
|
|
}
|
|
|
|
|
if (entry.isDirectory()) {
|
|
|
|
|
const path = resolve(eidosDir, entry.name, `${entry.name}.css`)
|
|
|
|
|
return existsSync(path) ? [{ name: entry.name, path }] : []
|
|
|
|
|
}
|
|
|
|
|
return []
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
console.log('component morfo eidos invalid unused')
|
|
|
|
|
console.log('─────────────────────────────────────────────────────')
|
|
|
|
|
|
|
|
|
|
let totalInvalid = 0
|
|
|
|
|
let totalEidosOnly = 0
|
|
|
|
|
let totalUnused = 0
|
|
|
|
|
const driftHotspots: { name: string; eidosOnly: string[]; invalid: string[] }[] = []
|
|
|
|
|
|
|
|
|
|
for (const file of cssFiles) {
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const name = file.name
|
|
|
|
|
const morfoPath = resolve(`src/uix/morfo/components/${name}.ts`)
|
|
|
|
|
try {
|
|
|
|
|
readFileSync(morfoPath)
|
|
|
|
|
} catch {
|
|
|
|
|
console.log(`${name.padEnd(22)}(no morfo file — skipped)`)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
const mod = (await import(`../src/uix/morfo/components/${name}`)) as Record<string, unknown>
|
|
|
|
|
const exportName = `${name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase())}Morfo`
|
|
|
|
|
const morfo = mod[exportName] as Morfo | undefined
|
|
|
|
|
if (!morfo) {
|
|
|
|
|
console.log(`${name.padEnd(22)}(${exportName} not exported — skipped)`)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
const compiled = compileMorfo(morfo)
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const partMarkers = new Set(Object.values(compiled.parts.attrs))
|
|
|
|
|
const css = readFileSync(file.path, 'utf-8')
|
|
|
|
|
const report = lintEidosCss(css, compiled)
|
|
|
|
|
console.log(
|
|
|
|
|
`${name.padEnd(22)}${String(report.counts.morfoBacked).padEnd(7)}${String(report.counts.eidosOnly).padEnd(7)}${String(report.counts.invalid).padEnd(9)}${report.unusedFromContract.length}`
|
|
|
|
|
)
|
|
|
|
|
totalInvalid += report.counts.invalid
|
|
|
|
|
totalEidosOnly += report.counts.eidosOnly
|
|
|
|
|
totalUnused += report.unusedFromContract.length
|
|
|
|
|
|
|
|
|
|
// Filter eidos-only that look like drift (data-* on a part where the morfo
|
|
|
|
|
// never declared the attr — vs design tokens like data-color/-size/-variant).
|
|
|
|
|
const drift = report.findings.filter(
|
|
|
|
|
(f) =>
|
|
|
|
|
f.status === 'eidos-only' &&
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
(f.eidosOnlyAttrs ?? f.attrs).some(
|
|
|
|
|
(a) =>
|
|
|
|
|
a.attr.startsWith('data-') &&
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
!partMarkers.has(a.attr) &&
|
|
|
|
|
!isAllowedEidosOnlyAttr(a.attr)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
const invalid = report.findings.filter((f) => f.status === 'invalid')
|
|
|
|
|
if (drift.length || invalid.length) {
|
|
|
|
|
driftHotspots.push({
|
|
|
|
|
name,
|
|
|
|
|
eidosOnly: drift.map((f) => f.rule),
|
|
|
|
|
invalid: invalid.map((f) => `${f.rule} — ${f.reason}`)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('─────────────────────────────────────────────────────')
|
|
|
|
|
console.log(`totals${' '.repeat(16)} ${totalEidosOnly} ${totalInvalid} ${totalUnused}`)
|
|
|
|
|
|
|
|
|
|
if (driftHotspots.length) {
|
|
|
|
|
console.log('\nDrift hotspots (eidos uses data-* attrs the morfo does not declare):')
|
|
|
|
|
for (const h of driftHotspots) {
|
|
|
|
|
if (!h.eidosOnly.length && !h.invalid.length) continue
|
|
|
|
|
console.log(`\n ${h.name}`)
|
|
|
|
|
for (const r of h.invalid) console.log(` ✗ ${r}`)
|
|
|
|
|
for (const r of h.eidosOnly) console.log(` · ${r}`)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
function isAllowedEidosOnlyAttr(attr: string): boolean {
|
|
|
|
|
return (
|
|
|
|
|
attr === 'data-event' ||
|
|
|
|
|
attr === 'data-event-id' ||
|
|
|
|
|
attr === 'data-event-phase' ||
|
|
|
|
|
attr === 'data-event-family' ||
|
|
|
|
|
attr === 'data-event-intent' ||
|
|
|
|
|
attr === 'data-archetype' ||
|
|
|
|
|
attr.endsWith('-color') ||
|
|
|
|
|
attr.endsWith('-size') ||
|
|
|
|
|
attr.endsWith('-variant') ||
|
|
|
|
|
attr.endsWith('-position') ||
|
|
|
|
|
attr.endsWith('-block') ||
|
|
|
|
|
attr.endsWith('-icon-only')
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main().catch((err) => {
|
|
|
|
|
console.error(err)
|
|
|
|
|
process.exit(2)
|
|
|
|
|
})
|