Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions docs/api-reference/widgets/splitter-widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ import {_SplitterWidget as SplitterWidget} from '@deck.gl/widgets';
import {Deck, OrbitView, type OrbitViewState} from '@deck.gl/core';
import '@deck.gl/widgets/stylesheet.css';

new Deck({
new Deck<OrbitView[]>({
initialViewState: {
front: {target: [0, 0, 0], rotationX: 0, rotationOrbit: 90, zoom: 0} satisfies OrbitViewState,
perspective: {target: [0, 0, 0], rotationX: 45, rotationOrbit: 30, zoom: 0} satisfies OrbitViewState
},
widgets: [
new SplitterWidget({
new SplitterWidget<OrbitView[]>({
viewLayout: {
orientation: 'horizontal',
views: [
Expand Down Expand Up @@ -141,7 +141,7 @@ function App() {

```ts
import {_SplitterWidget as SplitterWidget, type SplitterWidgetProps} from '@deck.gl/widgets';
new SplitterWidget({} satisfies SplitterWidgetProps);
new SplitterWidget<ViewType[]>({} satisfies SplitterWidgetProps);
```

## Types
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/lib/deck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export type DeckProps<ViewsT extends ViewOrViews = null> = {
/** (Experimental) Fine-tune attribute memory usage. See documentation for details. */
_typedArrayManagerProps?: TypedArrayManagerOptions;
/** An array of Widget instances to be added to the parent element. */
widgets?: Widget[];
widgets?: Widget<any, ViewsT>[];

/** Called once the GPU Device has been initiated. */
onDeviceInitialized?: (device: Device) => void;
Expand Down
25 changes: 14 additions & 11 deletions modules/widgets/src/splitter-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ function evaluateViews(root: ManagedViewLayout): View[] {
}

/** Properties for the SplitterWidget */
export type SplitterWidgetProps = WidgetProps & {
export type SplitterWidgetProps<ViewsT extends View[] = View[]> = WidgetProps & {
/** Stacking views descriptor */
viewLayout: ViewLayout;
/** Callback invoked when the splitter is dragged with the new split value */
onChange?: (views: View[]) => void;
onChange?: (views: ViewsT) => void;
/** Callback invoked when dragging starts */
onDragStart?: () => void;
/** Callback invoked when dragging ends */
Expand All @@ -164,7 +164,10 @@ export type SplitterWidgetProps = WidgetProps & {
* across the deck.gl canvas. It positions itself based on the split percentage
* of the first view and provides callbacks when dragged.
*/
export class SplitterWidget extends Widget<SplitterWidgetProps, View[]> {
export class SplitterWidget<ViewsT extends View[] = View[]> extends Widget<
SplitterWidgetProps<ViewsT>,
ViewsT
> {
static defaultProps: Required<SplitterWidgetProps> = {
...Widget.defaultProps,
id: 'splitter-widget',
Expand All @@ -178,17 +181,17 @@ export class SplitterWidget extends Widget<SplitterWidgetProps, View[]> {
placement = 'fill' as const;
viewLayouts!: ManagedViewLayout[];
/** evaluated from the current viewLayouts */
views!: View[];
views!: ViewsT;
/** views set in the last update */
lastViews?: View[];
lastViews?: ViewsT;
needsUpdate = true;

constructor(props: SplitterWidgetProps) {
constructor(props: SplitterWidgetProps<ViewsT>) {
super(props);
this.viewLayouts = parseViewLayout(this.props.viewLayout);
}

setProps(props: Partial<SplitterWidgetProps>) {
setProps(props: Partial<SplitterWidgetProps<ViewsT>>) {
if (props.viewLayout && !deepEqual(props.viewLayout, this.props.viewLayout, -1)) {
this.viewLayouts = parseViewLayout(props.viewLayout);
this.views = undefined!;
Expand All @@ -207,9 +210,9 @@ export class SplitterWidget extends Widget<SplitterWidgetProps, View[]> {
updateHTML() {
if (!this.views) {
// viewLayouts has changed, re-evaluate
this.views = evaluateViews(this.viewLayouts[0]);
this.views = evaluateViews(this.viewLayouts[0]) as ViewsT;
// we send a copy to the callback so that externally set views can be differentiated from internal
this.props.onChange(this.views.slice());
this.props.onChange(this.views.slice() as ViewsT);
}
// This method is called inside deck.setProps > widgetManager.setProps > widget.setProps
// Calling deck.setProps immediately would cause infinite loop
Expand Down Expand Up @@ -237,9 +240,9 @@ export class SplitterWidget extends Widget<SplitterWidgetProps, View[]> {
private onChange(newSplit: number, layout: ManagedViewLayout) {
layout.split = newSplit;
// layout has updated, re-evaluate
this.views = evaluateViews(this.viewLayouts[0]);
this.views = evaluateViews(this.viewLayouts[0]) as ViewsT;
// we send a copy to the callback so that externally set views can be differentiated from internal
this.props.onChange(this.views.slice());
this.props.onChange(this.views.slice() as ViewsT);
this.doUpdate();
}

Expand Down
Loading