chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
/**
|
||||
*
|
||||
* # See Also
|
||||
*
|
||||
* [`react-example`](https://github.com/perspective-dev/perspective/tree/master/examples/react-example)
|
||||
* project from the Perspective GitHub repo.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
export * from "./viewer";
|
||||
export * from "./workspace";
|
||||
@@ -0,0 +1,27 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
import * as React from "react";
|
||||
|
||||
export function usePspListener<A>(
|
||||
el: HTMLElement | undefined | null,
|
||||
event: string,
|
||||
cb?: (x: A) => void,
|
||||
) {
|
||||
React.useEffect(() => {
|
||||
if (!cb || !el) return;
|
||||
const ctx = new AbortController();
|
||||
const callback = (e: Event) => cb((e as CustomEvent).detail);
|
||||
el?.addEventListener(event, callback, { signal: ctx.signal });
|
||||
return () => ctx.abort();
|
||||
}, [el, cb]);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
import * as React from "react";
|
||||
import type * as psp from "@perspective-dev/client";
|
||||
import type * as pspViewer from "@perspective-dev/viewer";
|
||||
import { usePspListener } from "./utils";
|
||||
|
||||
function PerspectiveViewerImpl(props: PerspectiveViewerProps) {
|
||||
const [viewer, setViewer] =
|
||||
React.useState<pspViewer.HTMLPerspectiveViewerElement | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
viewer?.delete();
|
||||
};
|
||||
}, [viewer]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (props.client) {
|
||||
viewer?.load(props.client);
|
||||
} else {
|
||||
viewer?.eject();
|
||||
}
|
||||
}, [viewer, props.client]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (props.client && props.config) {
|
||||
viewer?.restore(props.config);
|
||||
}
|
||||
}, [viewer, props.client, JSON.stringify(props.config)]);
|
||||
|
||||
usePspListener(viewer, "perspective-click", props.onClick);
|
||||
usePspListener(viewer, "perspective-select", props.onSelect);
|
||||
usePspListener(viewer, "perspective-config-update", props.onConfigUpdate);
|
||||
|
||||
return (
|
||||
<perspective-viewer
|
||||
ref={setViewer}
|
||||
id={props.id}
|
||||
className={props.className}
|
||||
hidden={props.hidden}
|
||||
slot={props.slot}
|
||||
style={props.style}
|
||||
tabIndex={props.tabIndex}
|
||||
title={props.title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for the `<PerspectiveViewer>` component.
|
||||
*/
|
||||
export interface PerspectiveViewerProps {
|
||||
client?: psp.Client | Promise<psp.Client> | psp.Table | Promise<psp.Table>;
|
||||
config?: pspViewer.ViewerConfigUpdate;
|
||||
onConfigUpdate?: (config: pspViewer.ViewerConfigUpdate) => void;
|
||||
onClick?: (data: pspViewer.PerspectiveClickEventDetail) => void;
|
||||
onSelect?: (data: pspViewer.PerspectiveSelectEventDetail) => void;
|
||||
|
||||
// Applicable props from `React.HTMLAttributes`, which we cannot extend
|
||||
// directly because Perspective changes the signature of `onClick`.
|
||||
className?: string | undefined;
|
||||
hidden?: boolean | undefined;
|
||||
id?: string | undefined;
|
||||
slot?: string | undefined;
|
||||
style?: React.CSSProperties | undefined;
|
||||
tabIndex?: number | undefined;
|
||||
title?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* A React wrapper component for `<perspective-viewer>` Custom Element.
|
||||
*/
|
||||
export const PerspectiveViewer: React.FC<PerspectiveViewerProps> = React.memo(
|
||||
PerspectiveViewerImpl,
|
||||
);
|
||||
@@ -0,0 +1,95 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
import type * as psp from "@perspective-dev/client";
|
||||
import type * as psp_viewer from "@perspective-dev/viewer";
|
||||
import type * as pspWorkspace from "@perspective-dev/workspace";
|
||||
import { PerspectiveWorkspaceConfig } from "@perspective-dev/workspace";
|
||||
import * as utils from "./utils";
|
||||
import * as React from "react";
|
||||
|
||||
export interface NewViewEventDetail {
|
||||
config: psp_viewer.ViewerConfigUpdate;
|
||||
widget: pspWorkspace.PerspectiveViewerWidget;
|
||||
}
|
||||
|
||||
export interface ToggleGloalFilterEventDetail {
|
||||
widget: pspWorkspace.PerspectiveViewerWidget;
|
||||
isGlobalFilter: boolean;
|
||||
}
|
||||
|
||||
export interface PerspectiveWorkspaceProps
|
||||
extends React.HTMLAttributes<HTMLElement> {
|
||||
client: psp.Client | Promise<psp.Client>;
|
||||
layout: PerspectiveWorkspaceConfig;
|
||||
onLayoutUpdate?: (layout: PerspectiveWorkspaceConfig) => void;
|
||||
onNewView?: (detail: NewViewEventDetail) => void;
|
||||
onToggleGlobalFilter?: (detail: ToggleGloalFilterEventDetail) => void;
|
||||
}
|
||||
|
||||
const PerspectiveWorkspaceImpl = React.forwardRef<
|
||||
pspWorkspace.HTMLPerspectiveWorkspaceElement | undefined,
|
||||
PerspectiveWorkspaceProps
|
||||
>(
|
||||
(
|
||||
{
|
||||
client,
|
||||
layout,
|
||||
onLayoutUpdate,
|
||||
onNewView,
|
||||
onToggleGlobalFilter,
|
||||
...htmlAttributes
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const [workspace, setWorkspace] =
|
||||
React.useState<pspWorkspace.HTMLPerspectiveWorkspaceElement>();
|
||||
|
||||
React.useImperativeHandle(ref, () => workspace, [workspace]);
|
||||
React.useEffect(() => {
|
||||
if (workspace && layout) {
|
||||
workspace.restore(layout);
|
||||
}
|
||||
}, [workspace, layout]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (workspace && client) {
|
||||
workspace.load(client);
|
||||
}
|
||||
}, [workspace, client]);
|
||||
|
||||
utils.usePspListener(workspace, "workspace-new-view", onNewView);
|
||||
utils.usePspListener(
|
||||
workspace,
|
||||
"workspace-layout-update",
|
||||
onLayoutUpdate
|
||||
? ({ layout }: { layout: PerspectiveWorkspaceConfig }) =>
|
||||
workspace?.save().then((x) => onLayoutUpdate(x))
|
||||
: undefined,
|
||||
);
|
||||
|
||||
utils.usePspListener(
|
||||
workspace,
|
||||
"workspace-toggle-global-filter",
|
||||
onToggleGlobalFilter,
|
||||
);
|
||||
|
||||
return (
|
||||
<perspective-workspace
|
||||
ref={(r) => setWorkspace(r ?? undefined)}
|
||||
{...htmlAttributes}
|
||||
></perspective-workspace>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const PerspectiveWorkspace = React.memo(PerspectiveWorkspaceImpl);
|
||||
Reference in New Issue
Block a user