cb7d0b83a8
## PR description This PR: - Creates a TypeScript-based extractor that discovers all exported twenty-ui components by scanning barrel files, extracting props/slots/events via ts-morph type analysis, and generating the remote DOM bindings automatically. - Adds a new ESLint rule which enforces all *Props types in twenty-ui components to be exported, which is required for the extractor to discover component prop types. Existing twenty-ui components are updated to comply with this rule. - Extends the remote DOM generation to support slots, per-component events, forwardRef wrappers, and richer property types (array, object, function) ## Edge cases to fix in another PR - Icons cannot be rendered inside buttons - IconButtons throw an error when mounted - MenuItems are not displayed correctly - MenuItemNavigate throws on click ## Video Demo https://github.com/user-attachments/assets/c2ed67cf-6a15-4896-9fec-e83fac0e862b
64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
import chalk from 'chalk';
|
|
|
|
import {
|
|
formatEvents,
|
|
formatProps,
|
|
formatSlots,
|
|
logCountInline,
|
|
logDimText,
|
|
logLine,
|
|
} from '../../utils/logger';
|
|
|
|
type ComponentSummary = {
|
|
tag: string;
|
|
componentImport: string;
|
|
properties: Record<string, unknown>;
|
|
events: string[];
|
|
slots: string[];
|
|
};
|
|
|
|
export const logDiscoveredComponents = (
|
|
discoveredComponents: ComponentSummary[],
|
|
): void => {
|
|
if (discoveredComponents.length === 0) {
|
|
logDimText(' No components found');
|
|
|
|
return;
|
|
}
|
|
|
|
logLine(
|
|
' ' +
|
|
logCountInline(
|
|
discoveredComponents.length,
|
|
'component found',
|
|
'components found',
|
|
),
|
|
);
|
|
|
|
for (const discoveredComponent of discoveredComponents) {
|
|
const propertyCount = Object.keys(discoveredComponent.properties).length;
|
|
const eventCount = discoveredComponent.events.length;
|
|
const slotCount = discoveredComponent.slots.length;
|
|
|
|
const parts: string[] = [formatProps(propertyCount)];
|
|
|
|
if (eventCount > 0) {
|
|
parts.push(formatEvents(eventCount, discoveredComponent.events));
|
|
}
|
|
|
|
if (slotCount > 0) {
|
|
parts.push(formatSlots(slotCount, discoveredComponent.slots));
|
|
}
|
|
|
|
logLine(
|
|
chalk.green(' · ') +
|
|
chalk.green(discoveredComponent.componentImport) +
|
|
chalk.gray(' -> ') +
|
|
chalk.white(discoveredComponent.tag) +
|
|
chalk.gray(' (') +
|
|
parts.join(chalk.green(', ')) +
|
|
chalk.gray(')'),
|
|
);
|
|
}
|
|
};
|