diff --git a/dev/test-next-studio/next.config.mjs b/dev/test-next-studio/next.config.mjs index 9c8bd47ff68d..63a3da94ae97 100644 --- a/dev/test-next-studio/next.config.mjs +++ b/dev/test-next-studio/next.config.mjs @@ -77,9 +77,11 @@ const config = { }, // Makes it much easier to see which component got memoized by the react compiler // when testing on https://test-next-studio.sanity.build - productionBrowserSourceMaps: true, + productionBrowserSourceMaps: process.env.REACT_COMPILER !== 'true', + // Only enable the react profiler when the compiler is disabled, to better use native browser profiling without the react profiler overhead + reactProductionProfiling: process.env.REACT_COMPILER !== 'true', experimental: { - reactCompiler: process.env.REACT_COMPILER === 'true' ? true : false, + reactCompiler: process.env.REACT_COMPILER === 'true', turbo: { resolveAlias: { '@sanity/block-tools': '@sanity/block-tools/src/index.ts', diff --git a/dev/test-studio/components/debugStyledComponents.tsx b/dev/test-studio/components/debugStyledComponents.tsx new file mode 100644 index 000000000000..985fea467328 --- /dev/null +++ b/dev/test-studio/components/debugStyledComponents.tsx @@ -0,0 +1,421 @@ +import {Button, Card, Flex, Text} from '@sanity/ui' +import { + // useCallback, + useEffect, + // useRef, + useState, + // useSyncExternalStore, +} from 'react' +import {definePlugin, type LayoutProps} from 'sanity' +import {__PRIVATE__, StyleSheetManager} from 'styled-components' + +const IS_BROWSER = typeof window !== 'undefined' && 'HTMLElement' in window + +export const debugStyledComponents = definePlugin({ + name: 'debug-styled-components', + studio: { + components: { + layout: DebugLayout, + }, + }, +}) + +const DEFAULT_OPTIONS = { + // Reconstruct default options + // https://github.com/styled-components/styled-components/blob/770d1fa2bc1a4bfe3eea1b14a0357671ba9407a4/packages/styled-components/src/sheet/Sheet.ts#L23-L26 + isServer: !IS_BROWSER, + useCSSOMInjection: true, +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars +function DebugLayout(props: LayoutProps) { + const {renderDefault} = props + const [showToolbar, setShowToolbar] = useState(true) + const [[profiling, sheet], setState] = useState(() => [false, new StyleSheet(DEFAULT_OPTIONS)]) + const [paused, setPaused] = useState>(false) + // const [profiling, setProfiling] = useState(false) + // const [, setTick] = useState(1) + // const [onStoreChange, setOnStoreChange] = useState(() => () => {}) + // const onBufferRef = useRef(onStoreChange) + // useEffect(() => { + // onBufferRef.current = onStoreChange + // }, [onStoreChange]) + // const [blazingSheet] = useState( + // () => + // new BlazingStyleSheet({ + // // Schedule state updates when the buffer is queued + // onBuffer: () => { + // // console.log('onBuffer') + // setTick((prev) => prev + 1) + // }, + // // onBuffer: () => onBufferRef.current(), + // // Reconstruct default options + // // https://github.com/styled-components/styled-components/blob/770d1fa2bc1a4bfe3eea1b14a0357671ba9407a4/packages/styled-components/src/sheet/Sheet.ts#L23-L26 + // isServer: !IS_BROWSER, + // useCSSOMInjection: true, + // }), + // ) + // const shouldFlush = useSyncExternalStore( + // useCallback((_onStoreChange) => { + // setOnStoreChange(() => _onStoreChange) + // return () => setOnStoreChange(() => () => {}) + // }, []), + // () => blazingSheet.shouldFlush(), + // () => true, + // ) + // const [enabled, setEnabled] = useState(true) + // const [flush, setFlush] = useState(true) + // const [namespace, setNamespace] = useState() + // const [disableCSSOMInjection, setDisableCSSOMInjection] = useState() + // const [enableVendorPrefixes, setEnableVendorPrefixes] = useState() + + // useEffect(() => { + // // @ts-expect-error -- debug global + // window.cody = { + // setNamespace, + // setDisableCSSOMInjection, + // setEnableVendorPrefixes, + // setEnabled, + // toggle: () => setFlush((prev) => !prev), + // } + // return () => { + // // @ts-expect-error -- debug global + // delete window.cody + // } + // }, []) + + // useEffect(() => { + // console.log({ + // blazingSheet, + // namespace, + // disableCSSOMInjection, + // enableVendorPrefixes, + // enabled, + // // shouldFlush, + // }) + // }, [blazingSheet, disableCSSOMInjection, enableVendorPrefixes, enabled, namespace]) + + // Pause event emitter during render: + // https://github.com/final-form/react-final-form/issues/751#issuecomment-689431448 + // blazingSheet.pauseEvents() + + // Update CSSOM + // useInsertionEffect(() => { + // if (flush) { + // blazingSheet.flush() + // } + // }) + + // Check if CSSOM should update + // @TODO rewrite to use useState to buffer up changes that should flush + // useEffect(() => { + // if (flush) { + // if (blazingSheet.shouldFlush()) { + // // console.log('Flush in side-effect!') + // setTick((prev) => prev + 1) + // } + // blazingSheet.resumeEvents() + // } + // }) + + useEffect(() => { + if (!showToolbar) return undefined + // @ts-expect-error -- this is just debug stuff + delete window.__openDebugToolbar + return () => { + // @ts-expect-error -- this is just debug stuff + window.__openDebugToolbar = () => { + setShowToolbar(true) + } + // eslint-disable-next-line no-console + console.log( + 'You can re-open the toolbar by calling `window.__openDebugToolbar()` in your console', + ) + } + }, [showToolbar]) + + const children = renderDefault(props) + + return ( + <> + {showToolbar && ( + + + + Debug Styled Components CSS rendering + +