Refactor modal (#18377)
## Summary - Move Modal UI components (`Modal`, `ModalContent`, `ModalHeader`, `ModalFooter`, `ModalBackdrop`) from `twenty-front` to `twenty-ui` as stateless, reusable components - Create `ModalStatefulWrapper` in `twenty-front` that connects Jotai state (`isModalOpenedComponentState`) to the stateless `Modal` via an `isOpen` prop - Rename `modalVariant` prop to `overlay` with clearer values: `'dark'` (default), `'light'` (in-container), `'transparent'` (invisible panel). Remove unused `'medium'` overlay - Rename `modalId` to `modalInstanceId` across the entire modal zone (~30 consumer files) - Extract `ModalProps` to its own file in `twenty-ui/types/ModalProps.ts`; extract `ModalStatefulWrapperProps` to its own file using `Pick<ModalProps, ...>` for shared props - Extract `ModalBackdrop` to its own file and export from `twenty-ui`; use it in `UserOrMetadataLoader` instead of a local styled component - Use `ModalFooter` in `StepNavigationButton` and `ModalHeader` in `SpreadsheetImportStepperContainer` instead of duplicated `styled.div` definitions - Remove unused `onClose` prop from stateless `Modal`; fix `typeof document` guard in `ModalStatefulWrapper` - Split shared types into individual files: `ModalSize.ts`, `ModalPadding.ts`, `ModalOverlay.ts` - Extract wyw profiling instrumentation from `vite.config.ts` into reusable `createWywProfilingPlugin` with parametrized threshold and improved logging - Delete old `Modal.tsx`, `Modal.styles.ts`, `ModalContent.tsx`, `ModalHeader.tsx`, `ModalFooter.tsx` from `twenty-front` - Add comprehensive Storybook stories in `twenty-ui` covering Default, Confirmation, Small, ExtraLarge, Closed, and Interactive variants
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
/* eslint-disable no-console */
|
||||
import { type Plugin } from 'vite';
|
||||
|
||||
const LINARIA_IMPORT_RE = /@linaria/;
|
||||
|
||||
type WywProfilingOptions = {
|
||||
slowThresholdMs?: number;
|
||||
topSlowFilesCount?: number;
|
||||
progressIntervalFiles?: number;
|
||||
};
|
||||
|
||||
export const createWywProfilingPlugin = (
|
||||
wywPlugin: Plugin,
|
||||
options?: WywProfilingOptions,
|
||||
): Plugin => {
|
||||
const slowThresholdMs = options?.slowThresholdMs ?? 50;
|
||||
const topSlowFilesCount = options?.topSlowFilesCount ?? 10;
|
||||
const progressIntervalFiles = options?.progressIntervalFiles ?? 50;
|
||||
|
||||
let totalMs = 0;
|
||||
let fileCount = 0;
|
||||
let skippedCount = 0;
|
||||
const slowFiles: { id: string; ms: number }[] = [];
|
||||
const originalTransform = wywPlugin.transform;
|
||||
|
||||
console.log(
|
||||
`[linaria/wyw] CSS pre-build profiling enabled (slow threshold: ${slowThresholdMs}ms)`,
|
||||
);
|
||||
|
||||
return {
|
||||
...wywPlugin,
|
||||
enforce: 'pre' as const,
|
||||
transform(code: string, id: string, ...rest: unknown[]) {
|
||||
if (!LINARIA_IMPORT_RE.test(code)) {
|
||||
skippedCount++;
|
||||
return null;
|
||||
}
|
||||
|
||||
const start = performance.now();
|
||||
const result = (originalTransform as Function).call(
|
||||
this,
|
||||
code,
|
||||
id,
|
||||
...rest,
|
||||
);
|
||||
|
||||
const handleTiming = (elapsed: number) => {
|
||||
totalMs += elapsed;
|
||||
fileCount++;
|
||||
|
||||
if (elapsed > slowThresholdMs) {
|
||||
slowFiles.push({ id, ms: elapsed });
|
||||
}
|
||||
|
||||
if (fileCount % progressIntervalFiles === 0) {
|
||||
console.log(
|
||||
`[linaria/wyw] CSS pre-build progress: ${fileCount} transformed, ${skippedCount} skipped, ${totalMs.toFixed(0)}ms total`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (result && typeof result === 'object' && 'then' in result) {
|
||||
return (result as Promise<unknown>).then((res) => {
|
||||
handleTiming(performance.now() - start);
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
handleTiming(performance.now() - start);
|
||||
return result;
|
||||
},
|
||||
buildEnd() {
|
||||
console.log('\n[linaria/wyw] ===== CSS PRE-BUILD TIMING SUMMARY =====');
|
||||
console.log(`[linaria/wyw] Files transformed: ${fileCount}`);
|
||||
console.log(`[linaria/wyw] Files skipped (no @linaria): ${skippedCount}`);
|
||||
console.log(`[linaria/wyw] Transform time: ${totalMs.toFixed(0)}ms`);
|
||||
console.log(
|
||||
`[linaria/wyw] Avg per transformed file: ${fileCount > 0 ? (totalMs / fileCount).toFixed(1) : 0}ms`,
|
||||
);
|
||||
|
||||
if (slowFiles.length > 0) {
|
||||
console.log(
|
||||
`[linaria/wyw] Slow CSS pre-build files (>${slowThresholdMs}ms):`,
|
||||
);
|
||||
slowFiles
|
||||
.sort((a, b) => b.ms - a.ms)
|
||||
.slice(0, topSlowFilesCount)
|
||||
.forEach((slowFile) =>
|
||||
console.log(
|
||||
`[linaria/wyw] ${slowFile.ms.toFixed(0)}ms ${slowFile.id.replace(process.cwd(), '')}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
console.log('[linaria/wyw] ==========================================\n');
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* _____ _
|
||||
*|_ _|_ _____ _ __ | |_ _ _
|
||||
* | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
|
||||
* | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
|
||||
* |_| \_/\_/ \___|_| |_|\__|\__, |
|
||||
* |___/
|
||||
*/
|
||||
|
||||
export { createWywProfilingPlugin } from './createWywProfilingPlugin';
|
||||
Reference in New Issue
Block a user