diff --git a/packages/app/src/components/draggable-list.native.tsx b/packages/app/src/components/draggable-list.native.tsx index 5e7f0a817..24abc6d36 100644 --- a/packages/app/src/components/draggable-list.native.tsx +++ b/packages/app/src/components/draggable-list.native.tsx @@ -9,6 +9,8 @@ import type { DraggableListProps, DraggableRenderItemInfo } from "./draggable-li export type { DraggableListProps, DraggableRenderItemInfo }; +const SCROLL_ENABLED_FLEX_STYLE = { flex: 1 }; + export function DraggableList({ data, keyExtractor, @@ -79,7 +81,8 @@ export function DraggableList({ }, []); const showRefreshControl = Boolean(onRefresh) && (!isDragging || Boolean(refreshing)); - const resolvedContainerStyle = containerStyle ?? (scrollEnabled ? { flex: 1 } : undefined); + const resolvedContainerStyle = + containerStyle ?? (scrollEnabled ? SCROLL_ENABLED_FLEX_STYLE : undefined); const shouldShowRefreshControl = showRefreshControl && !nestable; const ListComponent: typeof DraggableFlatList = ( nestable ? (NestableDraggableFlatList as any) : DraggableFlatList diff --git a/packages/app/src/components/draggable-list.web.tsx b/packages/app/src/components/draggable-list.web.tsx index d484680df..911f90e5a 100644 --- a/packages/app/src/components/draggable-list.web.tsx +++ b/packages/app/src/components/draggable-list.web.tsx @@ -80,12 +80,15 @@ function SortableItem({ const scaleTransform = isDragging ? "scale(1.02)" : ""; const combinedTransform = [baseTransform, scaleTransform].filter(Boolean).join(" "); - const style = { - transform: combinedTransform || undefined, - transition, - opacity: isDragging ? 0.9 : 1, - zIndex: isDragging ? 1000 : 1, - }; + const style = useMemo( + () => ({ + transform: combinedTransform || undefined, + transition, + opacity: isDragging ? 0.9 : 1, + zIndex: isDragging ? 1000 : 1, + }), + [combinedTransform, transition, isDragging], + ); const info: DraggableRenderItemInfo = { item, diff --git a/packages/app/src/components/file-pane.tsx b/packages/app/src/components/file-pane.tsx index 1dcb274d1..d5bf4f115 100644 --- a/packages/app/src/components/file-pane.tsx +++ b/packages/app/src/components/file-pane.tsx @@ -112,18 +112,27 @@ const CodeLine = React.memo(function CodeLine({ {tokens.map((token, index) => ( - - {token.text} - + color={token.style ? (colorMap[token.style] ?? baseColor) : baseColor} + text={token.text} + /> ))} ); }); +interface CodeLineTokenProps { + color: string; + text: string; +} + +function CodeLineToken({ color, text }: CodeLineTokenProps) { + const style = useMemo(() => ({ color }), [color]); + return {text}; +} + const codeLineStyles = StyleSheet.create((theme) => ({ line: { flexDirection: "row", diff --git a/packages/app/src/components/sortable-inline-list.web.tsx b/packages/app/src/components/sortable-inline-list.web.tsx index f2dd07a33..b95e133af 100644 --- a/packages/app/src/components/sortable-inline-list.web.tsx +++ b/packages/app/src/components/sortable-inline-list.web.tsx @@ -73,12 +73,15 @@ function SortableItem({ const scaleTransform = !externalDndContext && isDragging ? "scale(1.01)" : ""; const combinedTransform = [baseTransform, scaleTransform].filter(Boolean).join(" "); - const style = { - transform: combinedTransform || undefined, - transition, - opacity: externalDndContext && isDragging ? 0.3 : isDragging ? 0.9 : 1, - zIndex: isDragging ? 1000 : 1, - }; + const style = useMemo( + () => ({ + transform: combinedTransform || undefined, + transition, + opacity: externalDndContext && isDragging ? 0.3 : isDragging ? 0.9 : 1, + zIndex: isDragging ? 1000 : 1, + }), + [combinedTransform, transition, externalDndContext, isDragging], + ); const info: DraggableRenderItemInfo = { item, diff --git a/packages/app/src/components/stream-strategy-web.tsx b/packages/app/src/components/stream-strategy-web.tsx index d59b9865b..9ec983566 100644 --- a/packages/app/src/components/stream-strategy-web.tsx +++ b/packages/app/src/components/stream-strategy-web.tsx @@ -743,7 +743,7 @@ function WebStreamViewport(props: StreamRenderInput & { isMobileBreakpoint: bool ) : null} {mountedHistoryRows} {boundary.hasMountedHistory && boundary.hasLiveHead && boundary.historyToHeadGap > 0 ? ( -
+ ) : null} {liveHeadRows} {liveAuxiliary} @@ -789,3 +789,12 @@ export function createWebStreamStrategy(input: CreateWebStreamStrategyInput): St getBottomOffset: (metrics) => Math.max(0, metrics.contentHeight - metrics.viewportHeight), }); } + +interface HistoryToHeadSpacerProps { + height: number; +} + +function HistoryToHeadSpacer({ height }: HistoryToHeadSpacerProps) { + const spacerStyle = useMemo(() => ({ height, width: "100%" as const }), [height]); + return
; +} diff --git a/packages/app/src/components/synced-loader.tsx b/packages/app/src/components/synced-loader.tsx index 671ab6786..a4e794eca 100644 --- a/packages/app/src/components/synced-loader.tsx +++ b/packages/app/src/components/synced-loader.tsx @@ -97,11 +97,8 @@ export function SyncedLoader({ size = 10, color }: { size?: number; color: strin dotSize={dotSize} sequenceIndex={sequenceIndex} progress={sharedStepProgress} - style={{ - position: "absolute", - left: columnIndex * (dotSize + gap), - top: rowIndex * (dotSize + gap), - }} + left={columnIndex * (dotSize + gap)} + top={rowIndex * (dotSize + gap)} /> ); })} @@ -115,17 +112,15 @@ function SpinnerDot({ dotSize, sequenceIndex, progress, - style, + left, + top, }: { color: string; dotSize: number; sequenceIndex: number; progress: SharedValue; - style: { - position: "absolute"; - left: number; - top: number; - }; + left: number; + top: number; }) { const animatedStyle = useAnimatedStyle(() => { const headIndex = Math.floor(progress.value) % DOT_COUNT; @@ -153,10 +148,12 @@ function SpinnerDot({ height: dotSize, borderRadius: dotSize / 2, backgroundColor: color, + position: "absolute" as const, + left, + top, }, - style, ], - [animatedStyle, dotSize, color, style], + [animatedStyle, dotSize, color, left, top], ); return ;