Skip to content

Commit 73c7ad5

Browse files
authored
fix layout shift on autoscroll (#2133)
1 parent 513ac1a commit 73c7ad5

File tree

3 files changed

+138
-21
lines changed

3 files changed

+138
-21
lines changed

components/home/feature-tabs/FeatureTabs.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export const FeatureTabs = ({
101101
}, [router.query.tab, features, defaultTab]);
102102

103103
const tabListRef = useRef<HTMLDivElement>(null);
104+
const tabListScrollRef = useRef<HTMLDivElement>(null);
104105
const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);
105106
const autoAdvanceTimerRef = useRef<NodeJS.Timeout | null>(null);
106107
const containerRef = useRef<HTMLDivElement>(null);
@@ -204,8 +205,8 @@ export const FeatureTabs = ({
204205

205206
// Scroll active tab into view (for mobile)
206207
useEffect(() => {
207-
if (tabListRef.current && tabRefs.current[state.focusedIndex]) {
208-
const tabList = tabListRef.current;
208+
if (tabListScrollRef.current && tabRefs.current[state.focusedIndex]) {
209+
const tabList = tabListScrollRef.current;
209210
const activeTabButton = tabRefs.current[state.focusedIndex];
210211

211212
if (activeTabButton) {
@@ -216,10 +217,16 @@ export const FeatureTabs = ({
216217
activeTabRect.left < tabListRect.left ||
217218
activeTabRect.right > tabListRect.right
218219
) {
219-
activeTabButton.scrollIntoView({
220+
// Calculate the scroll position needed
221+
const scrollLeft =
222+
activeTabButton.offsetLeft -
223+
tabList.clientWidth / 2 +
224+
activeTabButton.clientWidth / 2;
225+
226+
// Smooth scroll the container only (not the viewport)
227+
tabList.scrollTo({
228+
left: scrollLeft,
220229
behavior: "smooth",
221-
block: "nearest",
222-
inline: "center",
223230
});
224231
}
225232
}
@@ -370,7 +377,10 @@ export const FeatureTabs = ({
370377
className="p-2 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
371378
onKeyDown={handleKeyDown}
372379
>
373-
<div className="flex flex-row flex-nowrap overflow-x-auto scrollbar-hide snap-x snap-mandatory gap-0 px-4 -mx-4 sm:mx-0 sm:px-0 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
380+
<div
381+
ref={tabListScrollRef}
382+
className="flex flex-row flex-nowrap overflow-x-auto scrollbar-hide snap-x snap-mandatory gap-0 px-4 -mx-4 sm:mx-0 sm:px-0 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
383+
>
374384
{features.map((feature, index) => (
375385
<TabButton
376386
key={feature.id}

data/generated/contributors.json

Lines changed: 121 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"marcklingen"
2222
],
2323
"/docs/administration/scim-and-org-api": [
24+
"AkioNuernberger",
2425
"marcklingen",
2526
"Steffen911"
2627
],
@@ -46,9 +47,9 @@
4647
"felixkrrr"
4748
],
4849
"/docs/api-and-data-platform/features/query-via-sdk": [
50+
"marcklingen",
4951
"jannikmaierhoefer",
50-
"felixkrrr",
51-
"marcklingen"
52+
"felixkrrr"
5253
],
5354
"/docs/api-and-data-platform/overview": [
5455
"marcklingen"
@@ -60,8 +61,7 @@
6061
"/docs/demo": [
6162
"marcklingen",
6263
"jannikmaierhoefer",
63-
"clemra",
64-
"NicHaley"
64+
"clemra"
6565
],
6666
"/docs/docs-mcp": [
6767
"marcklingen"
@@ -73,27 +73,28 @@
7373
"jannikmaierhoefer"
7474
],
7575
"/docs/evaluation/evaluation-methods/custom-scores": [
76+
"marliessophie",
7677
"jannikmaierhoefer",
7778
"maxdeichmann",
7879
"hassiebp",
7980
"marcklingen",
80-
"felixkrrr",
81-
"marliessophie"
81+
"felixkrrr"
8282
],
8383
"/docs/evaluation/evaluation-methods/data-model": [
8484
"AkioNuernberger",
8585
"jannikmaierhoefer"
8686
],
8787
"/docs/evaluation/evaluation-methods/llm-as-a-judge": [
88+
"felixkrrr",
8889
"hassiebp",
8990
"AkioNuernberger",
90-
"jannikmaierhoefer",
91-
"felixkrrr"
91+
"jannikmaierhoefer"
9292
],
9393
"/docs/evaluation/experiments/data-model": [
9494
"hassiebp"
9595
],
9696
"/docs/evaluation/experiments/datasets": [
97+
"AkioNuernberger",
9798
"hassiebp"
9899
],
99100
"/docs/evaluation/experiments/experiments-via-sdk": [
@@ -103,6 +104,7 @@
103104
"hassiebp"
104105
],
105106
"/docs/evaluation/experiments/overview": [
107+
"jannikmaierhoefer",
106108
"hassiebp"
107109
],
108110
"/docs/evaluation/overview": [
@@ -117,14 +119,13 @@
117119
"jannikmaierhoefer"
118120
],
119121
"/docs/index": [
122+
"felixkrrr",
120123
"hassiebp",
121124
"marcklingen",
122125
"jannikmaierhoefer",
123-
"felixkrrr",
124126
"marliessophie",
125127
"clemra",
126-
"maxdeichmann",
127-
"NicHaley"
128+
"maxdeichmann"
128129
],
129130
"/docs/metrics/features/custom-dashboards": [
130131
"marcklingen"
@@ -524,6 +525,7 @@
524525
"clemra"
525526
],
526527
"/faq/all/manage-score-configs": [
528+
"marliessophie",
527529
"jannikmaierhoefer"
528530
],
529531
"/faq/all/managing-different-environments": [
@@ -698,6 +700,10 @@
698700
"jannikmaierhoefer",
699701
"marcklingen"
700702
],
703+
"/guides/cookbook/example_evaluating_multi_turn_conversations": [
704+
"jannikmaierhoefer",
705+
"aabedraba"
706+
],
701707
"/guides/cookbook/example_evaluating_openai_agents": [
702708
"marcklingen",
703709
"jannikmaierhoefer"
@@ -714,6 +720,7 @@
714720
"thompsgj"
715721
],
716722
"/guides/cookbook/example_langgraph_agents": [
723+
"marcklingen",
717724
"jannikmaierhoefer"
718725
],
719726
"/guides/cookbook/example_llm_security_monitoring": [
@@ -830,9 +837,9 @@
830837
"marcklingen"
831838
],
832839
"/guides/cookbook/js_integration_openai": [
840+
"marcklingen",
833841
"jannikmaierhoefer",
834842
"hassiebp",
835-
"marcklingen",
836843
"RichardKruemmel"
837844
],
838845
"/guides/cookbook/js_langfuse_sdk": [
@@ -925,6 +932,93 @@
925932
"/guides/videos/webinar-observability-llm-systems": [
926933
"marcklingen"
927934
],
935+
"/handbook/chapters/customers": [
936+
"marcklingen"
937+
],
938+
"/handbook/chapters/monetization": [
939+
"marcklingen"
940+
],
941+
"/handbook/chapters/open-source": [
942+
"marcklingen"
943+
],
944+
"/handbook/chapters/team": [
945+
"marcklingen"
946+
],
947+
"/handbook/chapters/why": [
948+
"marcklingen"
949+
],
950+
"/handbook/gtm/customer-success": [
951+
"marcklingen"
952+
],
953+
"/handbook/gtm/overview": [
954+
"marcklingen"
955+
],
956+
"/handbook/gtm/sales": [
957+
"marcklingen"
958+
],
959+
"/handbook/gtm/support": [
960+
"marcklingen"
961+
],
962+
"/handbook/index": [
963+
"marcklingen"
964+
],
965+
"/handbook/operations/entity-structure": [
966+
"marcklingen"
967+
],
968+
"/handbook/operations/finance": [
969+
"marcklingen"
970+
],
971+
"/handbook/product-engineering/documentation": [
972+
"marcklingen"
973+
],
974+
"/handbook/product-engineering/principles": [
975+
"marcklingen"
976+
],
977+
"/handbook/product-engineering/product-ops": [
978+
"marcklingen"
979+
],
980+
"/handbook/product-engineering/releases": [
981+
"marcklingen"
982+
],
983+
"/handbook/product-engineering/roadmapping": [
984+
"marcklingen"
985+
],
986+
"/handbook/working-at-langfuse/how-we-work/analytics": [
987+
"marcklingen"
988+
],
989+
"/handbook/working-at-langfuse/how-we-work/culture": [
990+
"marcklingen"
991+
],
992+
"/handbook/working-at-langfuse/how-we-work/meetings": [
993+
"marcklingen"
994+
],
995+
"/handbook/working-at-langfuse/how-we-work/ownership": [
996+
"marcklingen"
997+
],
998+
"/handbook/working-at-langfuse/how-we-work/personal-productivity": [
999+
"marcklingen"
1000+
],
1001+
"/handbook/working-at-langfuse/how-we-work/use-ai": [
1002+
"marcklingen"
1003+
],
1004+
"/handbook/working-at-langfuse/how-we-work/using-linear": [
1005+
"marcklingen"
1006+
],
1007+
"/handbook/working-at-langfuse/how-we-work/using-plain": [
1008+
"marcklingen"
1009+
],
1010+
"/handbook/working-at-langfuse/how-we-work/using-slack": [
1011+
"marcklingen"
1012+
],
1013+
"/handbook/working-at-langfuse/principles": [
1014+
"marcklingen"
1015+
],
1016+
"/handbook/working-at-langfuse/spending-money": [
1017+
"marcklingen"
1018+
],
1019+
"/handbook/working-at-langfuse/time-off": [
1020+
"marcklingen"
1021+
],
9281022
"/integrations/analytics/coval": [
9291023
"marcklingen"
9301024
],
@@ -1189,10 +1283,17 @@
11891283
"jannikmaierhoefer",
11901284
"marcklingen"
11911285
],
1286+
"/security/ai-features": [
1287+
"nimarb"
1288+
],
11921289
"/security/auth": [
11931290
"marcklingen"
11941291
],
1292+
"/security/compliance-faq": [
1293+
"AkioNuernberger"
1294+
],
11951295
"/security/data-regions": [
1296+
"AkioNuernberger",
11961297
"marcklingen"
11971298
],
11981299
"/security/dependencies": [
@@ -1203,6 +1304,7 @@
12031304
"clemra"
12041305
],
12051306
"/security/encryption": [
1307+
"AkioNuernberger",
12061308
"marcklingen"
12071309
],
12081310
"/security/gdpr": [
@@ -1214,9 +1316,11 @@
12141316
"marcklingen"
12151317
],
12161318
"/security/incident-and-breach": [
1319+
"AkioNuernberger",
12171320
"marcklingen"
12181321
],
12191322
"/security/index": [
1323+
"AkioNuernberger",
12201324
"marcklingen"
12211325
],
12221326
"/security/iso27001": [
@@ -1235,6 +1339,7 @@
12351339
"marcklingen"
12361340
],
12371341
"/security/privacy-faq": [
1342+
"AkioNuernberger",
12381343
"marcklingen",
12391344
"Steffen911"
12401345
],
@@ -1245,13 +1350,14 @@
12451350
],
12461351
"/security/security-faq": [
12471352
"marcklingen",
1248-
"clemra",
1249-
"AkioNuernberger"
1353+
"AkioNuernberger",
1354+
"clemra"
12501355
],
12511356
"/security/soc2": [
12521357
"marcklingen"
12531358
],
12541359
"/security/subprocessors": [
1360+
"clemra",
12551361
"marcklingen"
12561362
],
12571363
"/security/vulnerability-management": [
@@ -1351,6 +1457,7 @@
13511457
"Steffen911"
13521458
],
13531459
"/self-hosting/security/authentication-and-sso": [
1460+
"freinold",
13541461
"marcklingen"
13551462
],
13561463
"/self-hosting/security/deployment-strategies": [

src/github-stars.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const GITHUB_STARS = 16627;
1+
export const GITHUB_STARS = 16683;

0 commit comments

Comments
 (0)