Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ScrollArea] Create new ScrollArea component #665

Merged
merged 72 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
5176999
[ScrollArea] Create new ScrollArea component
atomiks Sep 30, 2024
1b718e2
Updates
atomiks Sep 30, 2024
1bdc90e
Exports
atomiks Sep 30, 2024
ae816d7
Fix ref timing
atomiks Sep 30, 2024
91f01e5
Handle content resizing and hidden scrollbars
atomiks Sep 30, 2024
82604e5
Handle pinch-zoom
atomiks Oct 1, 2024
f58fe52
Fix RTL handling
atomiks Oct 1, 2024
1d488fd
Support inlay scrollbars
atomiks Oct 2, 2024
fff37c5
Corner logic
atomiks Oct 2, 2024
ad746d3
Check for ResizeObserver existence
atomiks Oct 3, 2024
42a4261
Refactor into hooks and add tests
atomiks Oct 7, 2024
28947b4
Adjust tests
atomiks Oct 7, 2024
252d9b5
Fix tests
atomiks Oct 7, 2024
0a8108b
Reverse measurements
atomiks Oct 7, 2024
2baee83
Fix tests
atomiks Oct 7, 2024
05158cd
Parse computed styles
atomiks Oct 7, 2024
0898af8
Migrate to new exports
atomiks Oct 14, 2024
70063d1
Fix imports
atomiks Oct 14, 2024
859220d
CSS demo fixes
atomiks Oct 14, 2024
afc0722
Fix syntax replace error
atomiks Oct 15, 2024
a294e12
Add style hook tests
atomiks Oct 15, 2024
b1f1039
Use new context pattern
atomiks Oct 15, 2024
d514104
Change context error messages
atomiks Oct 15, 2024
33a00bf
Hide scrollbars with style tag, support overscroll-behavior, observe …
atomiks Oct 16, 2024
41eb097
Change content wrapper
atomiks Oct 16, 2024
209c69d
type dep
atomiks Oct 16, 2024
aa3a4d3
Undo overscroll demo style
atomiks Oct 16, 2024
0d947fe
Lint
atomiks Oct 16, 2024
bdd9de7
Unconditionally preventDefault
atomiks Oct 16, 2024
e88cd2c
Take into account rubber band in Safari
atomiks Oct 22, 2024
33346f4
Remove wai-aria link
atomiks Oct 27, 2024
f9b7d03
Rename inlay to inset; use state to hide elements
atomiks Oct 29, 2024
50f806d
Update for vitest
atomiks Oct 30, 2024
3f68d88
keepMounted
atomiks Oct 30, 2024
f5d5358
Use keepMounted in tests
atomiks Oct 30, 2024
8230305
Guard hiddenState
atomiks Oct 30, 2024
5bb8b46
Assert empty values
atomiks Oct 30, 2024
f984eef
Fix tests
atomiks Oct 30, 2024
331c1d5
Exports/tests
atomiks Oct 30, 2024
46d307e
inlay -> inset
atomiks Oct 30, 2024
7c85ef1
Adjust test
atomiks Oct 30, 2024
3760925
Fix ci
atomiks Oct 30, 2024
9bfbe39
Define t
atomiks Oct 30, 2024
b844263
Remove inlay refs
atomiks Oct 30, 2024
ede42d3
Simplify styles
atomiks Oct 31, 2024
9e712e0
Fix corner size calculation
atomiks Oct 31, 2024
9d565ff
Inset demo styling
atomiks Oct 31, 2024
1a46559
Fix RTL handling and re-render perf
atomiks Oct 31, 2024
d9571b4
Reset to LTR
atomiks Oct 31, 2024
867446d
Use identical data for demos
atomiks Oct 31, 2024
3355f9f
Use pointer events
atomiks Oct 31, 2024
1635971
Remove both-edges
atomiks Oct 31, 2024
150792a
Tweaks
atomiks Nov 3, 2024
b1f5c3b
Types
atomiks Nov 4, 2024
4c46d88
Tweaks
atomiks Nov 4, 2024
23486dc
Revamp type and gutter API
atomiks Nov 5, 2024
9eea81e
Remove type prop
atomiks Nov 5, 2024
7d5abce
Remove unsupported props
atomiks Nov 5, 2024
73292e5
Tweaks
atomiks Nov 5, 2024
b332b95
Add keepMounted
atomiks Nov 5, 2024
7cefd36
Fix tests
atomiks Nov 5, 2024
9ceb8ab
Fix RTL corner calculation
atomiks Nov 5, 2024
6158e6b
Fix lint
atomiks Nov 5, 2024
014bf25
Fix thumb size offset calculation
atomiks Nov 5, 2024
6eb30a2
Fix variables
atomiks Nov 5, 2024
b2c42c3
computeThumb when dir changes
atomiks Nov 5, 2024
854cb05
Adjust effects
atomiks Nov 5, 2024
0809809
Remove import
atomiks Nov 5, 2024
1db643d
Fix lint
atomiks Nov 5, 2024
3193d7a
Improve dir reactivity
atomiks Nov 5, 2024
5d6ab59
Remove unused html
atomiks Nov 5, 2024
a9823fe
Fix lint
atomiks Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/data/api/scroll-area-corner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"props": {
"className": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;string" } },
"render": { "type": { "name": "union", "description": "element<br>&#124;&nbsp;func" } }
},
"name": "ScrollAreaCorner",
"imports": [
"import { ScrollArea } from '@base_ui/react/ScrollArea';\nconst ScrollAreaCorner = ScrollArea.Corner;"
],
"classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "ScrollAreaCorner",
"forwardsRefTo": "HTMLDivElement",
"filename": "/packages/mui-base/src/ScrollArea/Corner/ScrollAreaCorner.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/react-scroll-area/\">Scroll Area</a></li></ul>",
"cssComponent": false
}
23 changes: 23 additions & 0 deletions docs/data/api/scroll-area-root.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"props": {
"className": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;string" } },
"gutter": {
"type": { "name": "union", "description": "number<br>&#124;&nbsp;string" },
"default": "0"
},
"render": { "type": { "name": "union", "description": "element<br>&#124;&nbsp;func" } }
},
"name": "ScrollAreaRoot",
"imports": [
"import { ScrollArea } from '@base_ui/react/ScrollArea';\nconst ScrollAreaRoot = ScrollArea.Root;"
],
"classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "ScrollAreaRoot",
"forwardsRefTo": "HTMLDivElement",
"filename": "/packages/mui-base/src/ScrollArea/Root/ScrollAreaRoot.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/react-scroll-area/\">Scroll Area</a></li></ul>",
"cssComponent": false
}
24 changes: 24 additions & 0 deletions docs/data/api/scroll-area-scrollbar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"props": {
"className": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;string" } },
"keepMounted": { "type": { "name": "bool" }, "default": "false" },
"orientation": {
"type": { "name": "enum", "description": "'horizontal'<br>&#124;&nbsp;'vertical'" },
"default": "'vertical'"
},
"render": { "type": { "name": "union", "description": "element<br>&#124;&nbsp;func" } }
},
"name": "ScrollAreaScrollbar",
"imports": [
"import { ScrollArea } from '@base_ui/react/ScrollArea';\nconst ScrollAreaScrollbar = ScrollArea.Scrollbar;"
],
"classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "ScrollAreaScrollbar",
"forwardsRefTo": "HTMLDivElement",
"filename": "/packages/mui-base/src/ScrollArea/Scrollbar/ScrollAreaScrollbar.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/react-scroll-area/\">Scroll Area</a></li></ul>",
"cssComponent": false
}
19 changes: 19 additions & 0 deletions docs/data/api/scroll-area-thumb.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"props": {
"className": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;string" } },
"render": { "type": { "name": "union", "description": "element<br>&#124;&nbsp;func" } }
},
"name": "ScrollAreaThumb",
"imports": [
"import { ScrollArea } from '@base_ui/react/ScrollArea';\nconst ScrollAreaThumb = ScrollArea.Thumb;"
],
"classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "ScrollAreaThumb",
"forwardsRefTo": "HTMLDivElement",
"filename": "/packages/mui-base/src/ScrollArea/Thumb/ScrollAreaThumb.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/react-scroll-area/\">Scroll Area</a></li></ul>",
"cssComponent": false
}
19 changes: 19 additions & 0 deletions docs/data/api/scroll-area-viewport.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"props": {
"className": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;string" } },
"render": { "type": { "name": "union", "description": "element<br>&#124;&nbsp;func" } }
},
"name": "ScrollAreaViewport",
"imports": [
"import { ScrollArea } from '@base_ui/react/ScrollArea';\nconst ScrollAreaViewport = ScrollArea.Viewport;"
],
"classes": [],
"spread": true,
"themeDefaultProps": true,
"muiName": "ScrollAreaViewport",
"forwardsRefTo": "HTMLDivElement",
"filename": "/packages/mui-base/src/ScrollArea/Viewport/ScrollAreaViewport.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/react-scroll-area/\">Scroll Area</a></li></ul>",
"cssComponent": false
}
113 changes: 113 additions & 0 deletions docs/data/components/scroll-area/ScrollAreaInset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client';
import * as React from 'react';
import { ScrollArea } from '@base_ui/react/ScrollArea';
import { styled } from '@mui/system';

const data = [
'f47ac10b-58cc-4372-a567-0e02b2c3d479',
'7c9e6679-7425-40de-944b-e07fc1f90ae7',
'550e8400-e29b-41d4-a716-446655440000',
'9b2b38e2-4c7b-4e53-a228-c89c535c5072',
'3fa85f64-5717-4562-b3fc-2c963f66afa6',
'4dfbdfc4-2d0e-4e6c-8bd6-7c8d765f0a1c',
'aa9e5d30-cf2a-4234-bc9b-6a5d965c6a00',
'16fd2706-8baf-433b-82eb-8c7fada847da',
'66ed7a57-e4b7-4b82-8b1e-2a8942f8ec6e',
'f9e87c8f-7b4f-4c7e-bb72-ebe8e2277c5e',
];

const scrollbarSize = 10;

export default function ScrollAreaInset() {
return (
<ScrollAreaRoot gutter={scrollbarSize}>
<ScrollAreaViewport>
<div style={{ padding: '10px 20px' }}>
<h3 style={{ margin: '20px 0 10px' }}>User IDs</h3>
<ul
style={{
padding: '10px 20px',
margin: 0,
display: 'flex',
flexDirection: 'column',
gap: 5,
}}
>
{data.map((value) => (
<li key={value} style={{ padding: 5, whiteSpace: 'nowrap' }}>
{value}
</li>
))}
</ul>
</div>
</ScrollAreaViewport>
<ScrollAreaScrollbar>
<ScrollAreaThumb />
</ScrollAreaScrollbar>
<ScrollAreaScrollbar orientation="horizontal">
<ScrollAreaThumb />
</ScrollAreaScrollbar>
<ScrollAreaCorner />
</ScrollAreaRoot>
);
}

const ScrollAreaRoot = styled(ScrollArea.Root)`
width: 250px;
height: 250px;
border-radius: 2px;
background: #f5f5f5;

--scrollbar-size: ${scrollbarSize}px;
`;

const ScrollAreaViewport = styled(ScrollArea.Viewport)`
width: 100%;
height: 100%;
border-radius: 2px;

&:focus-visible {
outline: 2px solid rgb(0 0 0 / 0.5);
}
`;

const ScrollAreaScrollbar = styled(ScrollArea.Scrollbar)`
background: rgb(220 220 220);
box-sizing: border-box;
display: flex;

&[data-orientation='vertical'] {
width: var(--scrollbar-size);
}

&[data-orientation='horizontal'] {
flex-direction: column;
height: var(--scrollbar-size);
}
`;

const ScrollAreaThumb = styled(ScrollArea.Thumb)`
background: rgb(180 180 180);
flex: 1;

&:hover {
background: rgb(150 150 150);
}

&::before {
content: '';
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 22px;
min-height: 22px;
}
`;

const ScrollAreaCorner = styled(ScrollArea.Corner)`
background: rgb(220 220 220);
`;
113 changes: 113 additions & 0 deletions docs/data/components/scroll-area/ScrollAreaInset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client';
import * as React from 'react';
import { ScrollArea } from '@base_ui/react/ScrollArea';
import { styled } from '@mui/system';

const data = [
'f47ac10b-58cc-4372-a567-0e02b2c3d479',
'7c9e6679-7425-40de-944b-e07fc1f90ae7',
'550e8400-e29b-41d4-a716-446655440000',
'9b2b38e2-4c7b-4e53-a228-c89c535c5072',
'3fa85f64-5717-4562-b3fc-2c963f66afa6',
'4dfbdfc4-2d0e-4e6c-8bd6-7c8d765f0a1c',
'aa9e5d30-cf2a-4234-bc9b-6a5d965c6a00',
'16fd2706-8baf-433b-82eb-8c7fada847da',
'66ed7a57-e4b7-4b82-8b1e-2a8942f8ec6e',
'f9e87c8f-7b4f-4c7e-bb72-ebe8e2277c5e',
];

const scrollbarSize = 10;

export default function ScrollAreaInset() {
return (
<ScrollAreaRoot gutter={scrollbarSize}>
<ScrollAreaViewport>
<div style={{ padding: '10px 20px' }}>
<h3 style={{ margin: '20px 0 10px' }}>User IDs</h3>
<ul
style={{
padding: '10px 20px',
margin: 0,
display: 'flex',
flexDirection: 'column',
gap: 5,
}}
>
{data.map((value) => (
<li key={value} style={{ padding: 5, whiteSpace: 'nowrap' }}>
{value}
</li>
))}
</ul>
</div>
</ScrollAreaViewport>
<ScrollAreaScrollbar>
<ScrollAreaThumb />
</ScrollAreaScrollbar>
<ScrollAreaScrollbar orientation="horizontal">
<ScrollAreaThumb />
</ScrollAreaScrollbar>
<ScrollAreaCorner />
</ScrollAreaRoot>
);
}

const ScrollAreaRoot = styled(ScrollArea.Root)`
width: 250px;
height: 250px;
border-radius: 2px;
background: #f5f5f5;

--scrollbar-size: ${scrollbarSize}px;
`;

const ScrollAreaViewport = styled(ScrollArea.Viewport)`
width: 100%;
height: 100%;
border-radius: 2px;

&:focus-visible {
outline: 2px solid rgb(0 0 0 / 0.5);
}
`;

const ScrollAreaScrollbar = styled(ScrollArea.Scrollbar)`
background: rgb(220 220 220);
box-sizing: border-box;
display: flex;

&[data-orientation='vertical'] {
width: var(--scrollbar-size);
}

&[data-orientation='horizontal'] {
flex-direction: column;
height: var(--scrollbar-size);
}
`;

const ScrollAreaThumb = styled(ScrollArea.Thumb)`
background: rgb(180 180 180);
flex: 1;

&:hover {
background: rgb(150 150 150);
}

&::before {
content: '';
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 22px;
min-height: 22px;
}
`;

const ScrollAreaCorner = styled(ScrollArea.Corner)`
background: rgb(220 220 220);
`;
Loading