mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: add props.renderScrollbars
(#9399)
* Expose renderScrollbars to AppState * fix: scrollbar rendering should use al renderable elements * remove `appState.renderScrollbars` * clean unused --------- Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
b5d60973b7
commit
5fc13e4309
11 changed files with 53 additions and 16 deletions
|
@ -31,6 +31,7 @@ All `props` are _optional_.
|
|||
| [`generateIdForFile`](#generateidforfile) | `function` | \_ | Allows you to override `id` generation for files added on canvas |
|
||||
| [`validateEmbeddable`](#validateembeddable) | `string[]` \| `boolean` \| `RegExp` \| `RegExp[]` \| <code>((link: string) => boolean | undefined)</code> | \_ | use for custom src url validation |
|
||||
| [`renderEmbeddable`](/docs/@excalidraw/excalidraw/api/props/render-props#renderEmbeddable) | `function` | \_ | Render function that can override the built-in `<iframe>` |
|
||||
| [`renderScrollbars`] | `boolean`| | `false` | Indicates whether scrollbars will be shown
|
||||
|
||||
### Storing custom data on Excalidraw elements
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ export default function ExampleApp({
|
|||
const [viewModeEnabled, setViewModeEnabled] = useState(false);
|
||||
const [zenModeEnabled, setZenModeEnabled] = useState(false);
|
||||
const [gridModeEnabled, setGridModeEnabled] = useState(false);
|
||||
const [renderScrollbars, setRenderScrollbars] = useState(false);
|
||||
const [blobUrl, setBlobUrl] = useState<string>("");
|
||||
const [canvasUrl, setCanvasUrl] = useState<string>("");
|
||||
const [exportWithDarkMode, setExportWithDarkMode] = useState(false);
|
||||
|
@ -192,6 +193,7 @@ export default function ExampleApp({
|
|||
}) => setPointerData(payload),
|
||||
viewModeEnabled,
|
||||
zenModeEnabled,
|
||||
renderScrollbars,
|
||||
gridModeEnabled,
|
||||
theme,
|
||||
name: "Custom name of drawing",
|
||||
|
@ -710,6 +712,14 @@ export default function ExampleApp({
|
|||
/>
|
||||
Grid mode
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={renderScrollbars}
|
||||
onChange={() => setRenderScrollbars(!renderScrollbars)}
|
||||
/>
|
||||
Render scrollbars
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
|
@ -1218,3 +1218,18 @@ export const elementCenterPoint = (
|
|||
|
||||
return pointFrom<GlobalPoint>(centerXPoint, centerYPoint);
|
||||
};
|
||||
|
||||
/** hack for Array.isArray type guard not working with readonly value[] */
|
||||
export const isReadonlyArray = (value?: any): value is readonly any[] => {
|
||||
return Array.isArray(value);
|
||||
};
|
||||
|
||||
export const sizeOf = (
|
||||
value: readonly number[] | Readonly<Map<any, any>> | Record<any, any>,
|
||||
): number => {
|
||||
return isReadonlyArray(value)
|
||||
? value.length
|
||||
: value instanceof Map
|
||||
? value.size
|
||||
: Object.keys(value).length;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import rough from "roughjs/bin/rough";
|
||||
|
||||
import { rescalePoints, arrayToMap, invariant } from "@excalidraw/common";
|
||||
import {
|
||||
rescalePoints,
|
||||
arrayToMap,
|
||||
invariant,
|
||||
sizeOf,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import {
|
||||
degreesToRadians,
|
||||
|
@ -57,6 +62,7 @@ import type {
|
|||
ElementsMap,
|
||||
ExcalidrawRectanguloidElement,
|
||||
ExcalidrawEllipseElement,
|
||||
ElementsMapOrArray,
|
||||
} from "./types";
|
||||
import type { Drawable, Op } from "roughjs/bin/core";
|
||||
import type { Point as RoughPoint } from "roughjs/bin/geometry";
|
||||
|
@ -938,10 +944,10 @@ export const getElementBounds = (
|
|||
};
|
||||
|
||||
export const getCommonBounds = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
elements: ElementsMapOrArray,
|
||||
elementsMap?: ElementsMap,
|
||||
): Bounds => {
|
||||
if (!elements.length) {
|
||||
if (!sizeOf(elements)) {
|
||||
return [0, 0, 0, 0];
|
||||
}
|
||||
|
||||
|
|
|
@ -1830,6 +1830,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
scale={window.devicePixelRatio}
|
||||
appState={this.state}
|
||||
renderScrollbars={
|
||||
this.props.renderScrollbars === true
|
||||
}
|
||||
device={this.device}
|
||||
renderInteractiveSceneCallback={
|
||||
this.renderInteractiveSceneCallback
|
||||
|
|
|
@ -34,6 +34,7 @@ type InteractiveCanvasProps = {
|
|||
selectionNonce: number | undefined;
|
||||
scale: number;
|
||||
appState: InteractiveCanvasAppState;
|
||||
renderScrollbars: boolean;
|
||||
device: Device;
|
||||
renderInteractiveSceneCallback: (
|
||||
data: RenderInteractiveSceneCallback,
|
||||
|
@ -143,7 +144,7 @@ const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
|||
remotePointerUsernames,
|
||||
remotePointerUserStates,
|
||||
selectionColor,
|
||||
renderScrollbars: false,
|
||||
renderScrollbars: props.renderScrollbars,
|
||||
},
|
||||
device: props.device,
|
||||
callback: props.renderInteractiveSceneCallback,
|
||||
|
@ -230,7 +231,8 @@ const areEqual = (
|
|||
// on appState)
|
||||
prevProps.elementsMap !== nextProps.elementsMap ||
|
||||
prevProps.visibleElements !== nextProps.visibleElements ||
|
||||
prevProps.selectedElements !== nextProps.selectedElements
|
||||
prevProps.selectedElements !== nextProps.selectedElements ||
|
||||
prevProps.renderScrollbars !== nextProps.renderScrollbars
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => {
|
|||
renderEmbeddable,
|
||||
aiEnabled,
|
||||
showDeprecatedFonts,
|
||||
renderScrollbars,
|
||||
} = props;
|
||||
|
||||
const canvasActions = props.UIOptions?.canvasActions;
|
||||
|
@ -143,6 +144,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => {
|
|||
renderEmbeddable={renderEmbeddable}
|
||||
aiEnabled={aiEnabled !== false}
|
||||
showDeprecatedFonts={showDeprecatedFonts}
|
||||
renderScrollbars={renderScrollbars}
|
||||
>
|
||||
{children}
|
||||
</App>
|
||||
|
|
|
@ -1182,7 +1182,7 @@ const _renderInteractiveScene = ({
|
|||
let scrollBars;
|
||||
if (renderConfig.renderScrollbars) {
|
||||
scrollBars = getScrollBars(
|
||||
visibleElements,
|
||||
elementsMap,
|
||||
normalizedWidth,
|
||||
normalizedHeight,
|
||||
appState,
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
toBrandedType,
|
||||
isDevEnv,
|
||||
isTestEnv,
|
||||
isReadonlyArray,
|
||||
} from "@excalidraw/common";
|
||||
import { isNonDeletedElement } from "@excalidraw/element";
|
||||
import { isFrameLikeElement } from "@excalidraw/element/typeChecks";
|
||||
|
@ -292,11 +293,9 @@ class Scene {
|
|||
}
|
||||
|
||||
replaceAllElements(nextElements: ElementsMapOrArray) {
|
||||
const _nextElements =
|
||||
// ts doesn't like `Array.isArray` of `instanceof Map`
|
||||
nextElements instanceof Array
|
||||
? nextElements
|
||||
: Array.from(nextElements.values());
|
||||
const _nextElements = isReadonlyArray(nextElements)
|
||||
? nextElements
|
||||
: Array.from(nextElements.values());
|
||||
const nextFrameLikes: ExcalidrawFrameLikeElement[] = [];
|
||||
|
||||
validateIndicesThrottled(_nextElements);
|
||||
|
|
|
@ -2,24 +2,22 @@ import { getGlobalCSSVariable } from "@excalidraw/common";
|
|||
|
||||
import { getCommonBounds } from "@excalidraw/element/bounds";
|
||||
|
||||
import type { ExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
||||
import { getLanguage } from "../i18n";
|
||||
|
||||
import type { InteractiveCanvasAppState } from "../types";
|
||||
import type { ScrollBars } from "./types";
|
||||
import type { RenderableElementsMap, ScrollBars } from "./types";
|
||||
|
||||
export const SCROLLBAR_MARGIN = 4;
|
||||
export const SCROLLBAR_WIDTH = 6;
|
||||
export const SCROLLBAR_COLOR = "rgba(0,0,0,0.3)";
|
||||
|
||||
export const getScrollBars = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
elements: RenderableElementsMap,
|
||||
viewportWidth: number,
|
||||
viewportHeight: number,
|
||||
appState: InteractiveCanvasAppState,
|
||||
): ScrollBars => {
|
||||
if (!elements.length) {
|
||||
if (!elements.size) {
|
||||
return {
|
||||
horizontal: null,
|
||||
vertical: null,
|
||||
|
|
|
@ -601,6 +601,7 @@ export interface ExcalidrawProps {
|
|||
) => JSX.Element | null;
|
||||
aiEnabled?: boolean;
|
||||
showDeprecatedFonts?: boolean;
|
||||
renderScrollbars?: boolean;
|
||||
}
|
||||
|
||||
export type SceneData = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue