first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,54 @@
import * as React from 'react';
import { Sticky } from '../../Sticky';
import type { IScrollablePane, IScrollablePaneProps } from './ScrollablePane.types';
import type { JSXElement } from '@fluentui/utilities';
export interface IScrollablePaneState {
stickyTopHeight: number;
stickyBottomHeight: number;
scrollbarWidth: number;
scrollbarHeight: number;
}
export declare class ScrollablePaneBase extends React.Component<IScrollablePaneProps, IScrollablePaneState> implements IScrollablePane {
static contextType: React.Context<import("@fluentui/react-window-provider").WindowProviderProps>;
context: any;
private _root;
private _stickyAboveRef;
private _stickyBelowRef;
private _contentContainer;
private _subscribers;
private _stickies;
private _mutationObserver;
private _notifyThrottled;
private _async;
private _events;
constructor(props: IScrollablePaneProps);
get root(): HTMLDivElement | null;
get stickyAbove(): HTMLDivElement | null;
get stickyBelow(): HTMLDivElement | null;
get contentContainer(): HTMLDivElement | null;
componentDidMount(): void;
componentWillUnmount(): void;
shouldComponentUpdate(nextProps: IScrollablePaneProps, nextState: IScrollablePaneState): boolean;
componentDidUpdate(prevProps: IScrollablePaneProps, prevState: IScrollablePaneState): void;
render(): JSXElement;
setStickiesDistanceFromTop(): void;
forceLayoutUpdate(): void;
subscribe: (handler: Function) => void;
unsubscribe: (handler: Function) => void;
addSticky: (sticky: Sticky) => void;
removeSticky: (sticky: Sticky) => void;
sortSticky: (sticky: Sticky, sortAgain?: boolean) => void;
updateStickyRefHeights: () => void;
notifySubscribers: () => void;
getScrollPosition: () => number;
syncScrollSticky: (sticky: Sticky) => void;
private _getScrollablePaneContext;
private _checkStickyStatus;
private _addToStickyContainer;
private _removeStickyFromContainers;
private _onWindowResize;
private _getStickyContainerStyle;
private _getScrollbarWidth;
private _getScrollbarHeight;
private _onScroll;
}
@@ -0,0 +1,406 @@
define(["require", "exports", "tslib", "react", "../../Utilities", "./ScrollablePane.types", "@fluentui/react-window-provider", "../../utilities/dom"], function (require, exports, tslib_1, React, Utilities_1, ScrollablePane_types_1, react_window_provider_1, dom_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScrollablePaneBase = void 0;
var getClassNames = (0, Utilities_1.classNamesFunction)();
var ScrollablePaneBase = /** @class */ (function (_super) {
tslib_1.__extends(ScrollablePaneBase, _super);
function ScrollablePaneBase(props) {
var _this = _super.call(this, props) || this;
_this._root = React.createRef();
_this._stickyAboveRef = React.createRef();
_this._stickyBelowRef = React.createRef();
_this._contentContainer = React.createRef();
_this.subscribe = function (handler) {
_this._subscribers.add(handler);
};
_this.unsubscribe = function (handler) {
_this._subscribers.delete(handler);
};
_this.addSticky = function (sticky) {
_this._stickies.add(sticky);
// If ScrollablePane is mounted, then sort sticky in correct place
if (_this.contentContainer) {
sticky.setDistanceFromTop(_this.contentContainer);
_this.sortSticky(sticky);
}
};
_this.removeSticky = function (sticky) {
_this._stickies.delete(sticky);
_this._removeStickyFromContainers(sticky);
_this.notifySubscribers();
};
_this.sortSticky = function (sticky, sortAgain) {
if (_this.stickyAbove && _this.stickyBelow) {
if (sortAgain) {
_this._removeStickyFromContainers(sticky);
}
if (sticky.canStickyTop && sticky.stickyContentTop) {
_this._addToStickyContainer(sticky, _this.stickyAbove, sticky.stickyContentTop);
}
if (sticky.canStickyBottom && sticky.stickyContentBottom) {
_this._addToStickyContainer(sticky, _this.stickyBelow, sticky.stickyContentBottom);
}
}
};
_this.updateStickyRefHeights = function () {
var stickyItems = _this._stickies;
var stickyTopHeight = 0;
var stickyBottomHeight = 0;
stickyItems.forEach(function (sticky) {
var _a = sticky.state, isStickyTop = _a.isStickyTop, isStickyBottom = _a.isStickyBottom;
if (sticky.nonStickyContent) {
if (isStickyTop) {
stickyTopHeight += sticky.nonStickyContent.offsetHeight;
}
if (isStickyBottom) {
stickyBottomHeight += sticky.nonStickyContent.offsetHeight;
}
_this._checkStickyStatus(sticky);
}
});
_this.setState({
stickyTopHeight: stickyTopHeight,
stickyBottomHeight: stickyBottomHeight,
});
};
_this.notifySubscribers = function () {
if (_this.contentContainer) {
_this._subscribers.forEach(function (handle) {
// this.stickyBelow is passed in for calculating distance to determine Sticky status
handle(_this.contentContainer, _this.stickyBelow);
});
}
};
_this.getScrollPosition = function () {
if (_this.contentContainer) {
return _this.contentContainer.scrollTop;
}
return 0;
};
_this.syncScrollSticky = function (sticky) {
if (sticky && _this.contentContainer) {
sticky.syncScroll(_this.contentContainer);
}
};
_this._getScrollablePaneContext = function () {
return {
scrollablePane: {
subscribe: _this.subscribe,
unsubscribe: _this.unsubscribe,
addSticky: _this.addSticky,
removeSticky: _this.removeSticky,
updateStickyRefHeights: _this.updateStickyRefHeights,
sortSticky: _this.sortSticky,
notifySubscribers: _this.notifySubscribers,
syncScrollSticky: _this.syncScrollSticky,
},
window: (0, dom_1.getWindowEx)(_this.context),
};
};
_this._addToStickyContainer = function (sticky, stickyContainer, stickyContentToAdd) {
// If there's no children, append child to list, otherwise, sort though array and append at correct position
if (!stickyContainer.children.length) {
stickyContainer.appendChild(stickyContentToAdd);
}
else {
// If stickyContentToAdd isn't a child element of target container, then append
if (!stickyContainer.contains(stickyContentToAdd)) {
var stickyChildrenElements_1 = [].slice.call(stickyContainer.children);
var stickyList_1 = [];
// Get stickies. Filter by canStickyTop/Bottom, then sort by distance from top, and then
// filter by elements that are in the stickyContainer already.
_this._stickies.forEach(function (stickyItem) {
if (stickyContainer === _this.stickyAbove && sticky.canStickyTop) {
stickyList_1.push(stickyItem);
}
else if (sticky.canStickyBottom) {
stickyList_1.push(stickyItem);
}
});
var stickyListSorted = stickyList_1
.sort(function (a, b) {
return (a.state.distanceFromTop || 0) - (b.state.distanceFromTop || 0);
})
.filter(function (item) {
var stickyContent = stickyContainer === _this.stickyAbove ? item.stickyContentTop : item.stickyContentBottom;
if (stickyContent) {
return stickyChildrenElements_1.indexOf(stickyContent) > -1;
}
return false;
});
// Get first element that has a distance from top that is further than our sticky that is being added
var targetStickyToAppendBefore = undefined;
for (var _i = 0, stickyListSorted_1 = stickyListSorted; _i < stickyListSorted_1.length; _i++) {
var stickyListItem = stickyListSorted_1[_i];
if ((stickyListItem.state.distanceFromTop || 0) >= (sticky.state.distanceFromTop || 0)) {
targetStickyToAppendBefore = stickyListItem;
break;
}
}
// If target element to append before is known, grab respective stickyContentTop/Bottom element
// and insert before
var targetContainer = null;
if (targetStickyToAppendBefore) {
targetContainer =
stickyContainer === _this.stickyAbove
? targetStickyToAppendBefore.stickyContentTop
: targetStickyToAppendBefore.stickyContentBottom;
}
stickyContainer.insertBefore(stickyContentToAdd, targetContainer);
}
}
};
_this._removeStickyFromContainers = function (sticky) {
if (_this.stickyAbove && sticky.stickyContentTop && _this.stickyAbove.contains(sticky.stickyContentTop)) {
_this.stickyAbove.removeChild(sticky.stickyContentTop);
}
if (_this.stickyBelow && sticky.stickyContentBottom && _this.stickyBelow.contains(sticky.stickyContentBottom)) {
_this.stickyBelow.removeChild(sticky.stickyContentBottom);
}
};
_this._onWindowResize = function () {
var scrollbarWidth = _this._getScrollbarWidth();
var scrollbarHeight = _this._getScrollbarHeight();
_this.setState({
scrollbarWidth: scrollbarWidth,
scrollbarHeight: scrollbarHeight,
});
_this.notifySubscribers();
};
_this._getStickyContainerStyle = function (height, isTop) {
return tslib_1.__assign(tslib_1.__assign({ height: height }, ((0, Utilities_1.getRTL)(_this.props.theme)
? {
right: '0',
left: "".concat(_this.state.scrollbarWidth || _this._getScrollbarWidth() || 0, "px"),
}
: {
left: '0',
right: "".concat(_this.state.scrollbarWidth || _this._getScrollbarWidth() || 0, "px"),
})), (isTop
? {
top: '0',
}
: {
bottom: "".concat(_this.state.scrollbarHeight || _this._getScrollbarHeight() || 0, "px"),
}));
};
_this._onScroll = function () {
var contentContainer = _this.contentContainer;
if (contentContainer) {
_this._stickies.forEach(function (sticky) {
sticky.syncScroll(contentContainer);
});
}
_this._notifyThrottled();
};
_this._subscribers = new Set();
_this._stickies = new Set();
(0, Utilities_1.initializeComponentRef)(_this);
_this.state = {
stickyTopHeight: 0,
stickyBottomHeight: 0,
scrollbarWidth: 0,
scrollbarHeight: 0,
};
return _this;
}
Object.defineProperty(ScrollablePaneBase.prototype, "root", {
get: function () {
return this._root.current;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ScrollablePaneBase.prototype, "stickyAbove", {
get: function () {
return this._stickyAboveRef.current;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ScrollablePaneBase.prototype, "stickyBelow", {
get: function () {
return this._stickyBelowRef.current;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ScrollablePaneBase.prototype, "contentContainer", {
get: function () {
return this._contentContainer.current;
},
enumerable: false,
configurable: true
});
ScrollablePaneBase.prototype.componentDidMount = function () {
var _this = this;
var win = (0, dom_1.getWindowEx)(this.context);
var initialScrollPosition = this.props.initialScrollPosition;
this._async = new Utilities_1.Async(this);
this._notifyThrottled = this._async.throttle(this.notifySubscribers, 50);
this._events = new Utilities_1.EventGroup(this);
this._events.on(this.contentContainer, 'scroll', this._onScroll);
this._events.on(win, 'resize', this._onWindowResize);
if (this.contentContainer && initialScrollPosition) {
this.contentContainer.scrollTop = initialScrollPosition;
}
// Set sticky distances from top property, then sort in correct order and notify subscribers
this.setStickiesDistanceFromTop();
this._stickies.forEach(function (sticky) {
_this.sortSticky(sticky);
});
this.notifySubscribers();
if (win && 'MutationObserver' in win) {
this._mutationObserver = new MutationObserver(function (mutation) {
// Function to check if mutation is occuring in stickyAbove or stickyBelow
function checkIfMutationIsSticky(mutationRecord) {
if (this.stickyAbove !== null && this.stickyBelow !== null) {
return this.stickyAbove.contains(mutationRecord.target) || this.stickyBelow.contains(mutationRecord.target);
}
return false;
}
// Compute the scrollbar height, which might have changed if the content's width changed and caused overflow
var scrollbarHeight = _this._getScrollbarHeight();
// If the scrollbar height changed, update state so it's postioned correctly below sticky footer
if (scrollbarHeight !== _this.state.scrollbarHeight) {
_this.setState({
scrollbarHeight: scrollbarHeight,
});
}
// Notify subscribers again to re-check whether Sticky should be Sticky'd or not
_this.notifySubscribers();
// If mutation occurs in sticky header or footer, then update sticky top/bottom heights
if (mutation.some(checkIfMutationIsSticky.bind(_this))) {
_this.updateStickyRefHeights();
}
else {
// If mutation occurs in scrollable region, then find Sticky it belongs to and force update
var stickyList_2 = [];
_this._stickies.forEach(function (sticky) {
if (sticky.root && sticky.root.contains(mutation[0].target)) {
stickyList_2.push(sticky);
}
});
if (stickyList_2.length) {
stickyList_2.forEach(function (sticky) {
sticky.forceUpdate();
});
}
}
});
if (this.root) {
this._mutationObserver.observe(this.root, {
childList: true,
attributes: true,
subtree: true,
characterData: true,
});
}
}
};
ScrollablePaneBase.prototype.componentWillUnmount = function () {
this._events.dispose();
this._async.dispose();
if (this._mutationObserver) {
this._mutationObserver.disconnect();
}
};
// Only updates if props/state change, just to prevent excessive setState with updateStickyRefHeights
ScrollablePaneBase.prototype.shouldComponentUpdate = function (nextProps, nextState) {
return (this.props.children !== nextProps.children ||
this.props.initialScrollPosition !== nextProps.initialScrollPosition ||
this.props.className !== nextProps.className ||
this.state.stickyTopHeight !== nextState.stickyTopHeight ||
this.state.stickyBottomHeight !== nextState.stickyBottomHeight ||
this.state.scrollbarWidth !== nextState.scrollbarWidth ||
this.state.scrollbarHeight !== nextState.scrollbarHeight);
};
ScrollablePaneBase.prototype.componentDidUpdate = function (prevProps, prevState) {
var initialScrollPosition = this.props.initialScrollPosition;
if (this.contentContainer &&
typeof initialScrollPosition === 'number' &&
prevProps.initialScrollPosition !== initialScrollPosition) {
this.contentContainer.scrollTop = initialScrollPosition;
}
// Update subscribers when stickyTopHeight/stickyBottomHeight changes
if (prevState.stickyTopHeight !== this.state.stickyTopHeight ||
prevState.stickyBottomHeight !== this.state.stickyBottomHeight) {
this.notifySubscribers();
}
this._async.setTimeout(this._onWindowResize, 0);
};
ScrollablePaneBase.prototype.render = function () {
var _a = this.props, className = _a.className, scrollContainerFocus = _a.scrollContainerFocus, scrollContainerAriaLabel = _a.scrollContainerAriaLabel, theme = _a.theme, styles = _a.styles, onScroll = _a.onScroll;
var _b = this.state, stickyTopHeight = _b.stickyTopHeight, stickyBottomHeight = _b.stickyBottomHeight;
var classNames = getClassNames(styles, {
theme: theme,
className: className,
scrollbarVisibility: this.props.scrollbarVisibility,
});
var scrollContainerProps = scrollContainerFocus
? {
role: 'group',
tabIndex: 0,
'aria-label': scrollContainerAriaLabel,
onScroll: onScroll,
}
: {
onScroll: onScroll,
};
return (React.createElement("div", tslib_1.__assign({}, (0, Utilities_1.getNativeProps)(tslib_1.__assign({}, this.props), Utilities_1.divProperties,
// on React 17 onScroll is not being invoked on root element,
// as a fix this method will be provided to the container element
['onScroll']), { ref: this._root, className: classNames.root }),
React.createElement("div", { ref: this._stickyAboveRef, className: classNames.stickyAbove, style: this._getStickyContainerStyle(stickyTopHeight, true) }),
React.createElement("div", tslib_1.__assign({ ref: this._contentContainer }, scrollContainerProps, { className: classNames.contentContainer, "data-is-scrollable": true }),
React.createElement(ScrollablePane_types_1.ScrollablePaneContext.Provider, { value: this._getScrollablePaneContext() }, this.props.children)),
React.createElement("div", { className: classNames.stickyBelow, style: this._getStickyContainerStyle(stickyBottomHeight, false) },
React.createElement("div", { ref: this._stickyBelowRef, className: classNames.stickyBelowItems }))));
};
ScrollablePaneBase.prototype.setStickiesDistanceFromTop = function () {
var _this = this;
if (this.contentContainer) {
this._stickies.forEach(function (sticky) {
sticky.setDistanceFromTop(_this.contentContainer);
});
}
};
ScrollablePaneBase.prototype.forceLayoutUpdate = function () {
this._onWindowResize();
};
ScrollablePaneBase.prototype._checkStickyStatus = function (sticky) {
if (this.stickyAbove && this.stickyBelow && this.contentContainer && sticky.nonStickyContent) {
// If sticky is sticky, then append content to appropriate container
if (sticky.state.isStickyTop || sticky.state.isStickyBottom) {
if (sticky.state.isStickyTop &&
!this.stickyAbove.contains(sticky.nonStickyContent) &&
sticky.stickyContentTop) {
sticky.addSticky(sticky.stickyContentTop);
}
if (sticky.state.isStickyBottom &&
!this.stickyBelow.contains(sticky.nonStickyContent) &&
sticky.stickyContentBottom) {
sticky.addSticky(sticky.stickyContentBottom);
}
}
else if (!this.contentContainer.contains(sticky.nonStickyContent)) {
// Reset sticky if it's not sticky and not in the contentContainer element
sticky.resetSticky();
}
}
};
ScrollablePaneBase.prototype._getScrollbarWidth = function () {
var contentContainer = this.contentContainer;
return contentContainer ? contentContainer.offsetWidth - contentContainer.clientWidth : 0;
};
ScrollablePaneBase.prototype._getScrollbarHeight = function () {
var contentContainer = this.contentContainer;
return contentContainer ? contentContainer.offsetHeight - contentContainer.clientHeight : 0;
};
ScrollablePaneBase.contextType = react_window_provider_1.WindowContext;
return ScrollablePaneBase;
}(React.Component));
exports.ScrollablePaneBase = ScrollablePaneBase;
});
//# sourceMappingURL=ScrollablePane.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IScrollablePaneProps } from './ScrollablePane.types';
export declare const ScrollablePane: React.FunctionComponent<IScrollablePaneProps>;
@@ -0,0 +1,7 @@
define(["require", "exports", "./ScrollablePane.styles", "./ScrollablePane.base", "../../Utilities"], function (require, exports, ScrollablePane_styles_1, ScrollablePane_base_1, Utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScrollablePane = void 0;
exports.ScrollablePane = (0, Utilities_1.styled)(ScrollablePane_base_1.ScrollablePaneBase, ScrollablePane_styles_1.getStyles, undefined, { scope: 'ScrollablePane' });
});
//# sourceMappingURL=ScrollablePane.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ScrollablePane.js","sourceRoot":"../src/","sources":["components/ScrollablePane/ScrollablePane.tsx"],"names":[],"mappings":";;;;IAMa,QAAA,cAAc,GAAkD,IAAA,kBAAM,EAIjF,wCAAkB,EAAE,iCAAS,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { getStyles } from './ScrollablePane.styles';\nimport { ScrollablePaneBase } from './ScrollablePane.base';\nimport { styled } from '../../Utilities';\nimport type { IScrollablePaneProps, IScrollablePaneStyleProps, IScrollablePaneStyles } from './ScrollablePane.types';\n\nexport const ScrollablePane: React.FunctionComponent<IScrollablePaneProps> = styled<\n IScrollablePaneProps,\n IScrollablePaneStyleProps,\n IScrollablePaneStyles\n>(ScrollablePaneBase, getStyles, undefined, { scope: 'ScrollablePane' });\n"]}
@@ -0,0 +1,3 @@
export declare const root = "root_cf619380";
export declare const stickyAbove = "stickyAbove_cf619380";
export declare const stickyBelow = "stickyBelow_cf619380";
@@ -0,0 +1,10 @@
define(["require", "exports", "@microsoft/load-themed-styles"], function (require, exports, load_themed_styles_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.stickyBelow = exports.stickyAbove = exports.root = void 0;
(0, load_themed_styles_1.loadStyles)([{ "rawString": ".root_cf619380{overflow-y:auto;max-height:inherit;height:inherit;-webkit-overflow-scrolling:touch}.stickyAbove_cf619380,.stickyBelow_cf619380{position:absolute;pointer-events:auto;width:100%;z-index:1}.stickyAbove_cf619380{top:0}@media screen and (-ms-high-contrast:active),screen and (forced-colors:active){.stickyAbove_cf619380{border-bottom:1px solid WindowText}}.stickyBelow_cf619380{bottom:0}@media screen and (-ms-high-contrast:active),screen and (forced-colors:active){.stickyBelow_cf619380{border-top:1px solid WindowText}}" }]);
exports.root = "root_cf619380";
exports.stickyAbove = "stickyAbove_cf619380";
exports.stickyBelow = "stickyBelow_cf619380";
});
//# sourceMappingURL=ScrollablePane.scss.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ScrollablePane.scss.js","sourceRoot":"../src/","sources":["components/ScrollablePane/ScrollablePane.scss.ts"],"names":[],"mappings":";;;;IAEA,IAAA,+BAAU,EAAC,CAAC,EAAC,WAAW,EAAC,qhBAAqhB,EAAC,CAAC,CAAC,CAAC;IACriB,QAAA,IAAI,GAAG,eAAe,CAAC;IACvB,QAAA,WAAW,GAAG,sBAAsB,CAAC;IACrC,QAAA,WAAW,GAAG,sBAAsB,CAAC","sourcesContent":["/* eslint-disable */\nimport { loadStyles } from '@microsoft/load-themed-styles';\nloadStyles([{\"rawString\":\".root_cf619380{overflow-y:auto;max-height:inherit;height:inherit;-webkit-overflow-scrolling:touch}.stickyAbove_cf619380,.stickyBelow_cf619380{position:absolute;pointer-events:auto;width:100%;z-index:1}.stickyAbove_cf619380{top:0}@media screen and (-ms-high-contrast:active),screen and (forced-colors:active){.stickyAbove_cf619380{border-bottom:1px solid WindowText}}.stickyBelow_cf619380{bottom:0}@media screen and (-ms-high-contrast:active),screen and (forced-colors:active){.stickyBelow_cf619380{border-top:1px solid WindowText}}\"}]);\nexport const root = \"root_cf619380\";\nexport const stickyAbove = \"stickyAbove_cf619380\";\nexport const stickyBelow = \"stickyBelow_cf619380\";"]}
@@ -0,0 +1,2 @@
import type { IScrollablePaneStyleProps, IScrollablePaneStyles } from './ScrollablePane.types';
export declare const getStyles: (props: IScrollablePaneStyleProps) => IScrollablePaneStyles;
@@ -0,0 +1,70 @@
define(["require", "exports", "../../Styling"], function (require, exports, Styling_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStyles = void 0;
var GlobalClassNames = {
root: 'ms-ScrollablePane',
contentContainer: 'ms-ScrollablePane--contentContainer',
};
var getStyles = function (props) {
var _a, _b;
var className = props.className, theme = props.theme;
var classNames = (0, Styling_1.getGlobalClassNames)(GlobalClassNames, theme);
var AboveAndBelowStyles = {
position: 'absolute',
pointerEvents: 'none',
};
var positioningStyle = {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
WebkitOverflowScrolling: 'touch',
};
return {
root: [classNames.root, theme.fonts.medium, positioningStyle, className],
contentContainer: [
classNames.contentContainer,
{
overflowY: props.scrollbarVisibility === 'always' ? 'scroll' : 'auto',
},
positioningStyle,
],
stickyAbove: [
{
top: 0,
zIndex: 1,
selectors: (_a = {},
_a[Styling_1.HighContrastSelector] = {
borderBottom: '1px solid WindowText',
},
_a),
},
AboveAndBelowStyles,
],
stickyBelow: [
{
bottom: 0,
selectors: (_b = {},
_b[Styling_1.HighContrastSelector] = {
borderTop: '1px solid WindowText',
},
_b),
},
AboveAndBelowStyles,
],
stickyBelowItems: [
{
bottom: 0,
},
AboveAndBelowStyles,
{
width: '100%',
},
],
};
};
exports.getStyles = getStyles;
});
//# sourceMappingURL=ScrollablePane.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ScrollablePane.styles.js","sourceRoot":"../src/","sources":["components/ScrollablePane/ScrollablePane.styles.ts"],"names":[],"mappings":";;;;IAIA,IAAM,gBAAgB,GAAG;QACvB,IAAI,EAAE,mBAAmB;QACzB,gBAAgB,EAAE,qCAAqC;KACxD,CAAC;IAEK,IAAM,SAAS,GAAG,UAAC,KAAgC;;QAChD,IAAA,SAAS,GAAY,KAAK,UAAjB,EAAE,KAAK,GAAK,KAAK,MAAV,CAAW;QAEnC,IAAM,UAAU,GAAG,IAAA,6BAAmB,EAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAEhE,IAAM,mBAAmB,GAAW;YAClC,QAAQ,EAAE,UAAU;YACpB,aAAa,EAAE,MAAM;SACtB,CAAC;QAEF,IAAM,gBAAgB,GAAW;YAC/B,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,CAAC;YACN,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,CAAC;YACP,uBAAuB,EAAE,OAAO;SACjC,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,CAAC;YACxE,gBAAgB,EAAE;gBAChB,UAAU,CAAC,gBAAgB;gBAC3B;oBACE,SAAS,EAAE,KAAK,CAAC,mBAAmB,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;iBACtE;gBACD,gBAAgB;aACjB;YACD,WAAW,EAAE;gBACX;oBACE,GAAG,EAAE,CAAC;oBACN,MAAM,EAAE,CAAC;oBACT,SAAS;wBACP,GAAC,8BAAoB,IAAG;4BACtB,YAAY,EAAE,sBAAsB;yBACrC;2BACF;iBACF;gBACD,mBAAmB;aACpB;YACD,WAAW,EAAE;gBACX;oBACE,MAAM,EAAE,CAAC;oBACT,SAAS;wBACP,GAAC,8BAAoB,IAAG;4BACtB,SAAS,EAAE,sBAAsB;yBAClC;2BACF;iBACF;gBACD,mBAAmB;aACpB;YACD,gBAAgB,EAAE;gBAChB;oBACE,MAAM,EAAE,CAAC;iBACV;gBACD,mBAAmB;gBACnB;oBACE,KAAK,EAAE,MAAM;iBACd;aACF;SACF,CAAC;IACJ,CAAC,CAAC;IA7DW,QAAA,SAAS,aA6DpB","sourcesContent":["import { HighContrastSelector, getGlobalClassNames } from '../../Styling';\nimport type { IScrollablePaneStyleProps, IScrollablePaneStyles } from './ScrollablePane.types';\nimport type { IStyle } from '../../Styling';\n\nconst GlobalClassNames = {\n root: 'ms-ScrollablePane',\n contentContainer: 'ms-ScrollablePane--contentContainer',\n};\n\nexport const getStyles = (props: IScrollablePaneStyleProps): IScrollablePaneStyles => {\n const { className, theme } = props;\n\n const classNames = getGlobalClassNames(GlobalClassNames, theme);\n\n const AboveAndBelowStyles: IStyle = {\n position: 'absolute',\n pointerEvents: 'none',\n };\n\n const positioningStyle: IStyle = {\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n WebkitOverflowScrolling: 'touch',\n };\n\n return {\n root: [classNames.root, theme.fonts.medium, positioningStyle, className],\n contentContainer: [\n classNames.contentContainer,\n {\n overflowY: props.scrollbarVisibility === 'always' ? 'scroll' : 'auto',\n },\n positioningStyle,\n ],\n stickyAbove: [\n {\n top: 0,\n zIndex: 1,\n selectors: {\n [HighContrastSelector]: {\n borderBottom: '1px solid WindowText',\n },\n },\n },\n AboveAndBelowStyles,\n ],\n stickyBelow: [\n {\n bottom: 0,\n selectors: {\n [HighContrastSelector]: {\n borderTop: '1px solid WindowText',\n },\n },\n },\n AboveAndBelowStyles,\n ],\n stickyBelowItems: [\n {\n bottom: 0,\n },\n AboveAndBelowStyles,\n {\n width: '100%',\n },\n ],\n };\n};\n"]}
@@ -0,0 +1,116 @@
import * as React from 'react';
import { ScrollablePaneBase } from './ScrollablePane.base';
import { Sticky } from '../Sticky/Sticky';
import type { IRefObject, IStyleFunctionOrObject } from '../../Utilities';
import type { IStyle, ITheme } from '../../Styling';
/**
* {@docCategory ScrollablePane}
*/
export interface IScrollablePane {
/** Triggers a layout update for the pane. */
forceLayoutUpdate(): void;
/** Gets the current scroll position of the scrollable pane */
getScrollPosition(): number;
}
/**
* {@docCategory ScrollablePane}
*/
export interface IScrollablePaneProps extends React.HTMLAttributes<HTMLElement | ScrollablePaneBase> {
/**
* Optional callback to access the IScrollablePane interface. Use this instead of ref for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<IScrollablePane>;
/**
* Call to provide customized styling that will layer on top of the variant rules
*/
styles?: IStyleFunctionOrObject<IScrollablePaneStyleProps, IScrollablePaneStyles>;
/**
* Theme provided by HOC.
*/
theme?: ITheme;
/**
* Additional css class to apply to the ScrollablePane
* @defaultvalue undefined
*/
className?: string;
/**
* Sets the initial scroll position of the ScrollablePane
*/
initialScrollPosition?: number;
scrollbarVisibility?: ScrollbarVisibility;
/**
* Makes the scrollable container focusable, to aid with keyboard-only scrolling
* Should only be set to true if the scrollable region will not contain any other focusable items
* @defaultvalue false
*/
scrollContainerFocus?: boolean;
/**
* If scrollContainerFocus is set to true, use this to give the container an accessible name
*/
scrollContainerAriaLabel?: string;
}
/**
* {@docCategory ScrollablePane}
*/
export interface IScrollablePaneStyleProps {
/**
* Accept theme prop.
*/
theme: ITheme;
/**
* Accept custom classNames
*/
className?: string;
scrollbarVisibility?: IScrollablePaneProps['scrollbarVisibility'];
}
/**
* {@docCategory ScrollablePane}
*/
export interface IScrollablePaneStyles {
/**
* Style set for the root element.
*/
root: IStyle;
/**
* Style set for the stickyAbove element.
*/
stickyAbove: IStyle;
/**
* Style set for the stickyBelow element.
*/
stickyBelow: IStyle;
/**
* Style set for the stickyBelowItems element.
*/
stickyBelowItems: IStyle;
/**
* Style set for the contentContainer element.
*/
contentContainer: IStyle;
}
/**
* {@docCategory ScrollablePane}
*/
export declare const ScrollbarVisibility: {
auto: "auto";
always: "always";
};
/**
* {@docCategory ScrollablePane}
*/
export type ScrollbarVisibility = (typeof ScrollbarVisibility)[keyof typeof ScrollbarVisibility];
export interface IScrollablePaneContext {
scrollablePane?: {
subscribe: (handler: (container: HTMLElement, stickyContainer: HTMLElement) => void) => void;
unsubscribe: (handler: (container: HTMLElement, stickyContainer: HTMLElement) => void) => void;
addSticky: (sticky: Sticky) => void;
removeSticky: (sticky: Sticky) => void;
updateStickyRefHeights: () => void;
sortSticky: (sticky: Sticky, sortAgain?: boolean) => void;
notifySubscribers: (sort?: boolean) => void;
syncScrollSticky: (sticky: Sticky) => void;
};
window: Window | undefined;
}
export declare const ScrollablePaneContext: React.Context<IScrollablePaneContext>;
@@ -0,0 +1,17 @@
define(["require", "exports", "react"], function (require, exports, React) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScrollablePaneContext = exports.ScrollbarVisibility = void 0;
/**
* {@docCategory ScrollablePane}
*/
exports.ScrollbarVisibility = {
auto: 'auto',
always: 'always',
};
exports.ScrollablePaneContext = React.createContext({
scrollablePane: undefined,
window: undefined,
});
});
//# sourceMappingURL=ScrollablePane.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ScrollablePane.types.js","sourceRoot":"../src/","sources":["components/ScrollablePane/ScrollablePane.types.ts"],"names":[],"mappings":";;;;IA4GA;;OAEG;IACU,QAAA,mBAAmB,GAAG;QACjC,IAAI,EAAE,MAAgB;QACtB,MAAM,EAAE,QAAoB;KAC7B,CAAC;IAqBW,QAAA,qBAAqB,GAAG,KAAK,CAAC,aAAa,CAAyB;QAC/E,cAAc,EAAE,SAAS;QACzB,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { ScrollablePaneBase } from './ScrollablePane.base';\nimport { Sticky } from '../Sticky/Sticky';\nimport type { IRefObject, IStyleFunctionOrObject } from '../../Utilities';\nimport type { IStyle, ITheme } from '../../Styling';\n\n/**\n * {@docCategory ScrollablePane}\n */\nexport interface IScrollablePane {\n /** Triggers a layout update for the pane. */\n forceLayoutUpdate(): void;\n /** Gets the current scroll position of the scrollable pane */\n getScrollPosition(): number;\n}\n\n/**\n * {@docCategory ScrollablePane}\n */\nexport interface IScrollablePaneProps extends React.HTMLAttributes<HTMLElement | ScrollablePaneBase> {\n // export interface IScrollablePaneProps extends IReactProps<ScrollablePaneBase> {\n /**\n * Optional callback to access the IScrollablePane interface. Use this instead of ref for accessing\n * the public methods and properties of the component.\n */\n componentRef?: IRefObject<IScrollablePane>;\n\n /**\n * Call to provide customized styling that will layer on top of the variant rules\n */\n styles?: IStyleFunctionOrObject<IScrollablePaneStyleProps, IScrollablePaneStyles>;\n\n /**\n * Theme provided by HOC.\n */\n theme?: ITheme;\n\n /**\n * Additional css class to apply to the ScrollablePane\n * @defaultvalue undefined\n */\n className?: string;\n\n /**\n * Sets the initial scroll position of the ScrollablePane\n */\n initialScrollPosition?: number;\n\n scrollbarVisibility?: ScrollbarVisibility;\n\n /**\n * Makes the scrollable container focusable, to aid with keyboard-only scrolling\n * Should only be set to true if the scrollable region will not contain any other focusable items\n * @defaultvalue false\n */\n scrollContainerFocus?: boolean;\n\n /**\n * If scrollContainerFocus is set to true, use this to give the container an accessible name\n */\n scrollContainerAriaLabel?: string;\n}\n\n/**\n * {@docCategory ScrollablePane}\n */\nexport interface IScrollablePaneStyleProps {\n /**\n * Accept theme prop.\n */\n theme: ITheme;\n\n /**\n * Accept custom classNames\n */\n className?: string;\n\n scrollbarVisibility?: IScrollablePaneProps['scrollbarVisibility'];\n\n // Insert ScrollablePane style props below\n}\n\n/**\n * {@docCategory ScrollablePane}\n */\nexport interface IScrollablePaneStyles {\n /**\n * Style set for the root element.\n */\n root: IStyle;\n /**\n * Style set for the stickyAbove element.\n */\n stickyAbove: IStyle;\n /**\n * Style set for the stickyBelow element.\n */\n stickyBelow: IStyle;\n /**\n * Style set for the stickyBelowItems element.\n */\n stickyBelowItems: IStyle;\n /**\n * Style set for the contentContainer element.\n */\n contentContainer: IStyle;\n}\n\n/**\n * {@docCategory ScrollablePane}\n */\nexport const ScrollbarVisibility = {\n auto: 'auto' as 'auto',\n always: 'always' as 'always',\n};\n\n/**\n * {@docCategory ScrollablePane}\n */\nexport type ScrollbarVisibility = (typeof ScrollbarVisibility)[keyof typeof ScrollbarVisibility];\n\nexport interface IScrollablePaneContext {\n scrollablePane?: {\n subscribe: (handler: (container: HTMLElement, stickyContainer: HTMLElement) => void) => void;\n unsubscribe: (handler: (container: HTMLElement, stickyContainer: HTMLElement) => void) => void;\n addSticky: (sticky: Sticky) => void;\n removeSticky: (sticky: Sticky) => void;\n updateStickyRefHeights: () => void;\n sortSticky: (sticky: Sticky, sortAgain?: boolean) => void;\n notifySubscribers: (sort?: boolean) => void;\n syncScrollSticky: (sticky: Sticky) => void;\n };\n window: Window | undefined;\n}\n\nexport const ScrollablePaneContext = React.createContext<IScrollablePaneContext>({\n scrollablePane: undefined,\n window: undefined,\n});\n"]}
@@ -0,0 +1,3 @@
export * from './ScrollablePane';
export * from './ScrollablePane.base';
export * from './ScrollablePane.types';
@@ -0,0 +1,8 @@
define(["require", "exports", "tslib", "./ScrollablePane", "./ScrollablePane.base", "./ScrollablePane.types"], function (require, exports, tslib_1, ScrollablePane_1, ScrollablePane_base_1, ScrollablePane_types_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tslib_1.__exportStar(ScrollablePane_1, exports);
tslib_1.__exportStar(ScrollablePane_base_1, exports);
tslib_1.__exportStar(ScrollablePane_types_1, exports);
});
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/ScrollablePane/index.ts"],"names":[],"mappings":";;;IAAA,gDAAiC;IACjC,qDAAsC;IACtC,sDAAuC","sourcesContent":["export * from './ScrollablePane';\nexport * from './ScrollablePane.base';\nexport * from './ScrollablePane.types';\n"]}