Skip to content

Commit abb3572

Browse files
authored
feat: Sicky search input for advanced styles section (#4998)
## Description 1. What is this PR about (link the issue and add a short description) ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 0000) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env` file
1 parent b4cc9ff commit abb3572

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

apps/builder/app/builder/features/style-panel/sections/advanced/advanced.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { getDots } from "../../shared/style-section";
2222
import { CssEditor, type CssEditorApi } from "../../../../shared/css-editor";
2323
import { $advancedStyleDeclarations } from "./stores";
2424
import { $selectedInstanceKey } from "~/shared/awareness";
25-
import { getSetting } from "~/builder/shared/client-settings";
2625

2726
// Only here to keep the same section module interface
2827
export const properties = [];
@@ -143,7 +142,6 @@ export const Section = () => {
143142
onDeleteAllDeclarations={handleDeleteAllDeclarations}
144143
apiRef={apiRef}
145144
recentProperties={recentProperties}
146-
memorizeMinHeight={getSetting("stylePanelMode") !== "advanced"}
147145
/>
148146
</AdvancedStyleSection>
149147
);

apps/builder/app/builder/shared/css-editor/css-editor.tsx

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ export const CssEditor = ({
320320
virtualize = true,
321321
propertiesPosition = "bottom",
322322
recentProperties = [],
323-
memorizeMinHeight = true,
324323
}: {
325324
declarations: Array<ComputedStyleDecl>;
326325
onDeleteProperty: DeleteProperty;
@@ -329,9 +328,6 @@ export const CssEditor = ({
329328
onDeleteAllDeclarations: (styleMap: CssStyleMap) => void;
330329
apiRef?: RefObject<CssEditorApi>;
331330
showSearch?: boolean;
332-
// When used as part of some larger scroll area to avoid scroll jumps during search.
333-
// For example advanced section in the style panel.
334-
memorizeMinHeight?: boolean;
335331
propertiesPosition?: "top" | "bottom";
336332
virtualize?: boolean;
337333
recentProperties?: Array<CssProperty>;
@@ -344,7 +340,6 @@ export const CssEditor = ({
344340
const [searchProperties, setSearchProperties] =
345341
useState<Array<CssProperty>>();
346342
const containerRef = useRef<HTMLDivElement>(null);
347-
const [minHeight, setMinHeight] = useState<number>(0);
348343
useImperativeHandle(apiRef, () => ({
349344
showAddStyleInput() {
350345
handleShowAddStyleInput();
@@ -384,18 +379,30 @@ export const CssEditor = ({
384379
};
385380

386381
const handleAbortSearch = () => {
387-
setMinHeight(0);
382+
if (containerRef.current) {
383+
containerRef.current.style.minHeight = "auto";
384+
}
388385
setSearchProperties(undefined);
389386
};
390387

391388
const handleSearch = (event: ChangeEvent<HTMLInputElement>) => {
392389
const search = event.target.value.trim().replaceAll("-", " ");
390+
393391
if (search === "") {
394392
return handleAbortSearch();
395393
}
396-
397-
if (memorizeMinHeight) {
398-
setMinHeight(containerRef.current?.getBoundingClientRect().height ?? 0);
394+
// This keeps container height big enough to avoid scroll position jumping around while user types.
395+
if (containerRef.current) {
396+
containerRef.current.style.height = `${window.innerHeight}px`;
397+
// Min height is needed as long as the search is active.
398+
containerRef.current.style.minHeight = `${window.innerHeight}px`;
399+
requestAnimationFrame(() => {
400+
// We can't keep it permanently because we need user to see all of the content.
401+
// Fixed height only needed temporarily while react rerenders the tree to avoid jumps.
402+
if (containerRef.current) {
403+
containerRef.current.style.height = "auto";
404+
}
405+
});
399406
}
400407

401408
const styles = declarations.map(({ property, cascadedValue }) => {
@@ -503,9 +510,17 @@ export const CssEditor = ({
503510
);
504511

505512
return (
506-
<>
513+
<Box css={{ isolation: "isolate" }}>
507514
{showSearch && (
508-
<Box css={{ paddingInline: theme.panel.paddingInline }}>
515+
<Box
516+
css={{
517+
padding: theme.panel.padding,
518+
position: "sticky",
519+
top: 0,
520+
background: theme.colors.backgroundPanel,
521+
zIndex: 1,
522+
}}
523+
>
509524
<SearchField
510525
inputRef={searchInputRef}
511526
onChange={handleSearch}
@@ -531,8 +546,10 @@ export const CssEditor = ({
531546
)}
532547
<Flex
533548
direction="column"
534-
css={{ paddingInline: theme.panel.paddingInline, gap: 2 }}
535-
style={{ minHeight }}
549+
css={{
550+
paddingInline: theme.panel.paddingInline,
551+
gap: 2,
552+
}}
536553
ref={containerRef}
537554
>
538555
{currentProperties.map((property) => {
@@ -569,6 +586,6 @@ export const CssEditor = ({
569586
)}
570587
</Flex>
571588
</CssEditorContextMenu>
572-
</>
589+
</Box>
573590
);
574591
};

0 commit comments

Comments
 (0)