254 lines
11 KiB
JavaScript
254 lines
11 KiB
JavaScript
"use strict";
|
|
'use client';
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.LayoutList = exports.LayoutDataGrid = exports.Layout = void 0;
|
|
var React = _interopRequireWildcard(require("react"));
|
|
var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
|
|
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
|
|
var _platform = require("@base-ui/utils/platform");
|
|
var _store = require("@mui/x-internals/store");
|
|
var _dimensions = require("../../features/dimensions");
|
|
var _virtualization = require("./virtualization");
|
|
var _useRefCallback = _interopRequireDefault(require("../../utils/useRefCallback"));
|
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
|
|
class Layout {
|
|
static elements = ['scroller', 'container'];
|
|
constructor(refs) {
|
|
this.refs = refs;
|
|
}
|
|
refSetter(name) {
|
|
return node => {
|
|
if (this.refs[name].current !== node) {
|
|
this.refs[name].current = node;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
exports.Layout = Layout;
|
|
class LayoutDataGrid extends Layout {
|
|
static elements = ['scroller', 'container', 'content', 'positioner', 'scrollbarVertical', 'scrollbarHorizontal'];
|
|
use(store, _params, api, layoutParams) {
|
|
const {
|
|
scrollerRef,
|
|
containerRef
|
|
} = layoutParams;
|
|
const scrollbarVerticalRef = useScrollbarRefCallback(this.refs.scroller, this.refSetter('scrollbarVertical'), 'scrollTop', api.updateDimensions);
|
|
const scrollbarHorizontalRef = useScrollbarRefCallback(this.refs.scroller, this.refSetter('scrollbarHorizontal'), 'scrollLeft', api.updateDimensions);
|
|
store.state.virtualization.context = {
|
|
scrollerRef,
|
|
containerRef,
|
|
scrollbarVerticalRef,
|
|
scrollbarHorizontalRef
|
|
};
|
|
}
|
|
static selectors = {
|
|
containerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.context, context => ({
|
|
ref: context.containerRef
|
|
})),
|
|
scrollerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.context, _dimensions.Dimensions.selectors.autoHeight, _dimensions.Dimensions.selectors.needsHorizontalScrollbar, (context, autoHeight, needsHorizontalScrollbar) => ({
|
|
ref: context.scrollerRef,
|
|
style: {
|
|
// TODO: fall back to overflow: 'auto' if no overflowX or overflowY is set?
|
|
overflowX: !needsHorizontalScrollbar ? 'hidden' : undefined,
|
|
overflowY: autoHeight ? 'hidden' : undefined
|
|
// TODO: should include display: 'flex', flexDirection: 'column' since the Content has flexBasis and flexShrink?
|
|
},
|
|
role: 'presentation',
|
|
// `tabIndex` shouldn't be used along role=presentation, but it fixes a Firefox bug
|
|
// https://github.com/mui/mui-x/pull/13891#discussion_r1683416024
|
|
tabIndex: _platform.platform.engine.gecko ? -1 : undefined
|
|
})),
|
|
scrollerContentProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.layoutMode, _dimensions.Dimensions.selectors.dimensions, _dimensions.Dimensions.selectors.needsVerticalScrollbar, _dimensions.Dimensions.selectors.needsHorizontalScrollbar, (layoutMode, dimensions, needsVerticalScrollbar, needsHorizontalScrollbar) => {
|
|
let style;
|
|
if (layoutMode === 'controlled') {
|
|
const {
|
|
contentSize,
|
|
scrollbarSize,
|
|
topContainerHeight,
|
|
bottomContainerHeight,
|
|
minimalContentHeight,
|
|
columnsTotalWidth,
|
|
viewportOuterSize
|
|
} = dimensions;
|
|
const verticalScrollbarSize = needsVerticalScrollbar ? scrollbarSize : 0;
|
|
const horizontalScrollbarSize = needsHorizontalScrollbar ? scrollbarSize : 0;
|
|
const contentHeight = contentSize.height === 0 ? minimalContentHeight : contentSize.height;
|
|
const width = needsHorizontalScrollbar ? verticalScrollbarSize + columnsTotalWidth : 'auto';
|
|
const height = cssAdd(cssAdd(cssAdd(contentHeight, topContainerHeight), bottomContainerHeight), horizontalScrollbarSize);
|
|
style = {
|
|
width: cssMax(width, viewportOuterSize.width - verticalScrollbarSize),
|
|
height: cssMax(height, viewportOuterSize.height - horizontalScrollbarSize),
|
|
flex: '0 0 auto'
|
|
};
|
|
}
|
|
return {
|
|
style,
|
|
role: 'presentation'
|
|
};
|
|
}),
|
|
viewportProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.dimensions, dimensions => ({
|
|
style: {
|
|
width: dimensions.viewportOuterSize.width,
|
|
height: dimensions.viewportOuterSize.height
|
|
},
|
|
role: 'presentation'
|
|
})),
|
|
contentProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.contentHeight, _dimensions.Dimensions.selectors.minimalContentHeight, _dimensions.Dimensions.selectors.columnsTotalWidth, _dimensions.Dimensions.selectors.needsHorizontalScrollbar, (contentHeight, minimalContentHeight, columnsTotalWidth, needsHorizontalScrollbar) => ({
|
|
style: {
|
|
width: needsHorizontalScrollbar ? columnsTotalWidth : 'auto',
|
|
height: contentHeight === 0 ? minimalContentHeight : contentHeight,
|
|
flex: '0 0 auto'
|
|
},
|
|
role: 'presentation'
|
|
})),
|
|
positionerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.layoutMode, _virtualization.Virtualization.selectors.offsetTop, _virtualization.Virtualization.selectors.scrollPosition, (layoutMode, offsetTop, scrollPosition) => ({
|
|
style: {
|
|
transform: layoutMode === 'uncontrolled' ? `translate3d(0, ${offsetTop}px, 0)` : `translate3d(${-scrollPosition.current.left}px, ${offsetTop - scrollPosition.current.top}px, 0)`
|
|
}
|
|
})),
|
|
containerVerticalProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.layoutMode, _virtualization.Virtualization.selectors.scrollPosition, (layoutMode, scrollPosition) => layoutMode === 'uncontrolled' ? undefined : {
|
|
style: {
|
|
transform: `translate3d(${-scrollPosition.current.left}px, 0, 0)`
|
|
}
|
|
}),
|
|
scrollbarHorizontalProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.context, _virtualization.Virtualization.selectors.scrollPosition, (context, scrollPosition) => ({
|
|
ref: context.scrollbarHorizontalRef,
|
|
scrollPosition
|
|
})),
|
|
scrollbarVerticalProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.context, _virtualization.Virtualization.selectors.scrollPosition, (context, scrollPosition) => ({
|
|
ref: context.scrollbarVerticalRef,
|
|
scrollPosition
|
|
})),
|
|
scrollAreaProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.scrollPosition, scrollPosition => ({
|
|
scrollPosition
|
|
}))
|
|
};
|
|
}
|
|
exports.LayoutDataGrid = LayoutDataGrid;
|
|
class LayoutList extends Layout {
|
|
static elements = ['scroller', 'container', 'content', 'positioner'];
|
|
use(store, _params, _api, layoutParams) {
|
|
const {
|
|
scrollerRef,
|
|
containerRef
|
|
} = layoutParams;
|
|
const mergedRef = (0, _useForkRef.default)(scrollerRef, containerRef);
|
|
store.state.virtualization.context = {
|
|
mergedRef
|
|
};
|
|
}
|
|
static selectors = {
|
|
containerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.context, _dimensions.Dimensions.selectors.autoHeight, _dimensions.Dimensions.selectors.needsHorizontalScrollbar, (context, autoHeight, needsHorizontalScrollbar) => ({
|
|
ref: context.mergedRef,
|
|
style: {
|
|
overflowX: !needsHorizontalScrollbar ? 'hidden' : undefined,
|
|
overflowY: autoHeight ? 'hidden' : undefined,
|
|
position: 'relative'
|
|
},
|
|
role: 'presentation',
|
|
// `tabIndex` shouldn't be used along role=presentation, but it fixes a Firefox bug
|
|
// https://github.com/mui/mui-x/pull/13891#discussion_r1683416024
|
|
tabIndex: _platform.platform.engine.gecko ? -1 : undefined
|
|
})),
|
|
contentProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.contentHeight, contentHeight => ({
|
|
style: {
|
|
position: 'absolute',
|
|
display: 'inline-block',
|
|
width: '100%',
|
|
height: contentHeight,
|
|
top: 0,
|
|
left: 0,
|
|
zIndex: -1
|
|
},
|
|
role: 'presentation'
|
|
})),
|
|
positionerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.offsetTop, offsetTop => ({
|
|
style: {
|
|
height: offsetTop
|
|
}
|
|
}))
|
|
};
|
|
}
|
|
exports.LayoutList = LayoutList;
|
|
function useScrollbarRefCallback(scrollerRef, refSetter, scrollProperty, updateDimensions) {
|
|
const isLocked = React.useRef(false);
|
|
const lastPosition = React.useRef(0);
|
|
const handleScrollerScroll = (0, _useEventCallback.default)(scrollbar => {
|
|
const scroller = scrollerRef.current;
|
|
if (!scroller) {
|
|
return;
|
|
}
|
|
const scrollerPosition = scroller[scrollProperty];
|
|
if (scrollerPosition === lastPosition.current) {
|
|
return;
|
|
}
|
|
lastPosition.current = scrollerPosition;
|
|
if (isLocked.current) {
|
|
isLocked.current = false;
|
|
return;
|
|
}
|
|
isLocked.current = true;
|
|
scrollbar[scrollProperty] = scrollerPosition;
|
|
});
|
|
const handleScrollbarScroll = (0, _useEventCallback.default)(scrollbar => {
|
|
const scroller = scrollerRef.current;
|
|
if (!scroller) {
|
|
return;
|
|
}
|
|
if (isLocked.current) {
|
|
isLocked.current = false;
|
|
return;
|
|
}
|
|
isLocked.current = true;
|
|
scroller[scrollProperty] = scrollbar[scrollProperty];
|
|
});
|
|
return (0, _useRefCallback.default)(scrollbar => {
|
|
refSetter(scrollbar);
|
|
updateDimensions();
|
|
const scroller = scrollerRef.current;
|
|
if (!scroller) {
|
|
return () => {
|
|
refSetter(null);
|
|
};
|
|
}
|
|
const onScrollerScroll = () => handleScrollerScroll(scrollbar);
|
|
const onScrollbarScroll = () => handleScrollbarScroll(scrollbar);
|
|
const options = {
|
|
passive: true
|
|
};
|
|
scroller.addEventListener('scroll', onScrollerScroll, options);
|
|
scrollbar.addEventListener('scroll', onScrollbarScroll, options);
|
|
return () => {
|
|
scroller.removeEventListener('scroll', onScrollerScroll);
|
|
scrollbar.removeEventListener('scroll', onScrollbarScroll);
|
|
refSetter(null);
|
|
};
|
|
});
|
|
}
|
|
function cssAdd(a, b) {
|
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
return a + b;
|
|
}
|
|
return `calc(${valueToCSSString(a)} + ${valueToCSSString(b)})`;
|
|
}
|
|
function cssMax(a, b) {
|
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
return Math.max(a, b);
|
|
}
|
|
return `max(${valueToCSSString(a)}, ${valueToCSSString(b)})`;
|
|
}
|
|
function valueToCSSString(value) {
|
|
if (typeof value === 'string') {
|
|
return value;
|
|
}
|
|
if (typeof value === 'undefined') {
|
|
return '0';
|
|
}
|
|
return `${value}px`;
|
|
} |