chore: shift the chat button when scrollbar shows (#39559)
https://github.com/user-attachments/assets/efccee4b-c329-4766-8fc6-92c8a135f8df /ok-to-test tags="@tag.Anvil" <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced dynamic scrollbar width styling that enhances the overall theme layout. - Input and textarea components now automatically detect and adjust based on scrollbar presence. - Made available a new utility for accurately measuring scrollbar width. - **Style** - Applied new CSS rules to ensure proper positioning of suffix elements in input groups when scrollbars appear. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13673799093> > Commit: a72538ba720e28f178fcf2a39a58a3c73728e5c4 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13673799093&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Anvil` > Spec: > <hr>Wed, 05 Mar 2025 10:49:39 UTC <!-- end of auto-generated comment: Cypress test results -->
This commit is contained in:
parent
92fa95fc01
commit
1d60545859
|
|
@ -5,6 +5,7 @@ import { objectKeys } from "@appsmith/utils";
|
||||||
import type { Theme } from "../../theme";
|
import type { Theme } from "../../theme";
|
||||||
import type { ThemeToken, Typography } from "../../token";
|
import type { ThemeToken, Typography } from "../../token";
|
||||||
import { cssRule, getTypographyClassName } from "../../utils";
|
import { cssRule, getTypographyClassName } from "../../utils";
|
||||||
|
import { getScrollbarWidth } from "@appsmith/utils";
|
||||||
|
|
||||||
const fontFamilyCss = () => {
|
const fontFamilyCss = () => {
|
||||||
const fontFamilyCss =
|
const fontFamilyCss =
|
||||||
|
|
@ -91,11 +92,18 @@ export function useCssTokens(props: Theme) {
|
||||||
}
|
}
|
||||||
}, [colorMode]);
|
}, [colorMode]);
|
||||||
|
|
||||||
|
const scrollbarWidthClassName = useMemo(() => {
|
||||||
|
return css`
|
||||||
|
--scrollbar-width: ${getScrollbarWidth()}px;
|
||||||
|
`;
|
||||||
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
colorClassName,
|
colorClassName,
|
||||||
colorModeClassName,
|
colorModeClassName,
|
||||||
fontFamilyClassName,
|
fontFamilyClassName,
|
||||||
typographyClassName,
|
typographyClassName,
|
||||||
providerClassName,
|
providerClassName,
|
||||||
|
scrollbarWidthClassName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export const ThemeProvider = (props: ThemeProviderProps) => {
|
||||||
colorModeClassName,
|
colorModeClassName,
|
||||||
fontFamilyClassName,
|
fontFamilyClassName,
|
||||||
providerClassName,
|
providerClassName,
|
||||||
|
scrollbarWidthClassName,
|
||||||
typographyClassName,
|
typographyClassName,
|
||||||
} = useCssTokens(theme);
|
} = useCssTokens(theme);
|
||||||
|
|
||||||
|
|
@ -32,6 +33,7 @@ export const ThemeProvider = (props: ThemeProviderProps) => {
|
||||||
fontFamilyClassName,
|
fontFamilyClassName,
|
||||||
providerClassName,
|
providerClassName,
|
||||||
typographyClassName,
|
typographyClassName,
|
||||||
|
scrollbarWidthClassName,
|
||||||
)}
|
)}
|
||||||
data-theme-provider=""
|
data-theme-provider=""
|
||||||
ref={providerRef}
|
ref={providerRef}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,11 @@
|
||||||
margin-block: var(--inner-spacing-1);
|
margin-block: var(--inner-spacing-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inputGroup:has([data-has-scrollbar]):has(.input:is(textarea))
|
||||||
|
[data-input-suffix] {
|
||||||
|
right: calc(var(--sizing-1) + var(--scrollbar-width));
|
||||||
|
}
|
||||||
|
|
||||||
.input:autofill,
|
.input:autofill,
|
||||||
.input:autofill:hover,
|
.input:autofill:hover,
|
||||||
.input:autofill:focus,
|
.input:autofill:focus,
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,15 @@ export function TextArea(props: TextAreaProps) {
|
||||||
|
|
||||||
setTextFieldHeight(height + marginTop + marginBottom);
|
setTextFieldHeight(height + marginTop + marginBottom);
|
||||||
|
|
||||||
input.style.height = `${input.scrollHeight}px`;
|
input.style.height = `${input.scrollHeight + 1}px`;
|
||||||
input.style.overflow = prevOverflow;
|
input.style.overflow = prevOverflow;
|
||||||
input.style.alignSelf = prevAlignment;
|
input.style.alignSelf = prevAlignment;
|
||||||
|
|
||||||
|
if (input.scrollHeight > input.clientHeight) {
|
||||||
|
input.setAttribute("data-has-scrollbar", "true");
|
||||||
|
} else {
|
||||||
|
input.removeAttribute("data-has-scrollbar");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [props.height]);
|
}, [props.height]);
|
||||||
|
|
||||||
|
|
|
||||||
15
app/client/packages/utils/src/dom/getScrollbarWidth.ts
Normal file
15
app/client/packages/utils/src/dom/getScrollbarWidth.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
export const getScrollbarWidth = () => {
|
||||||
|
const scrollDiv = document.createElement("div");
|
||||||
|
|
||||||
|
scrollDiv.setAttribute(
|
||||||
|
"style",
|
||||||
|
"width: 100px; height: 100px; overflow: scroll; position:absolute; top:-9999px;",
|
||||||
|
);
|
||||||
|
document.body.appendChild(scrollDiv);
|
||||||
|
|
||||||
|
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
|
||||||
|
|
||||||
|
document.body.removeChild(scrollDiv);
|
||||||
|
|
||||||
|
return scrollbarWidth;
|
||||||
|
};
|
||||||
1
app/client/packages/utils/src/dom/index.ts
Normal file
1
app/client/packages/utils/src/dom/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { getScrollbarWidth } from "./getScrollbarWidth";
|
||||||
|
|
@ -3,3 +3,4 @@ export * from "./file";
|
||||||
export * from "./object";
|
export * from "./object";
|
||||||
export * from "./url";
|
export * from "./url";
|
||||||
export * from "./validateApiPath";
|
export * from "./validateApiPath";
|
||||||
|
export * from "./dom";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user