Skip to content

Commit 58e4fa9

Browse files
authored
Follow up of #14 (#18)
* Add missing event in react wrappers * Fix data grid * Update demo * Add typing for anchored region and tooltip properties
1 parent d73ba10 commit 58e4fa9

File tree

9 files changed

+99
-60
lines changed

9 files changed

+99
-60
lines changed

packages/components/src/data-grid/data-grid-cell.styles.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
bodyFont,
88
controlCornerRadius,
99
designUnit,
10-
focusStrokeOuter,
1110
focusStrokeWidth,
1211
neutralForegroundRest,
1312
strokeWidth,

packages/components/src/data-grid/data-grid.stories.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,6 @@ const Template = (
6060
// </jp-data-grid-row>
6161
// </jp-data-grid>`;
6262

63-
// const container = document.createElement('div');
64-
// container.innerHTML =
65-
// '<jp-data-grid id="basic-grid" generate-header="sticky" aria-label="With Sticky Header"></jp-data-grid>';
66-
// const grid = container.firstChild as DataGrid;
67-
68-
// grid.rowsData = [
69-
// {
70-
// Header1: 'Data 1 1',
71-
// Header2: 'Data 2 1',
72-
// Header3: 'Data 3 1',
73-
// Header4: 'Cell Data 4 1'
74-
// },
75-
// {
76-
// Header1: 'Data 1 2',
77-
// Header2: 'Data 2 2',
78-
// Header3: 'Data 3 2',
79-
// Header4: 'Cell Data 4 2'
80-
// },
81-
// {
82-
// Header1: 'Data 1 3',
83-
// Header2: 'Data 2 3',
84-
// Header3: 'Data 3 3',
85-
// Header4: 'Cell Data 4 3'
86-
// }
87-
// ];
88-
// return grid;
89-
9063
return '<jp-data-grid id="basic-grid" generate-header="sticky" aria-label="With Sticky Header"></jp-data-grid>';
9164
};
9265

packages/lab-example/src/index.tsx

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,58 @@ const plugin: JupyterFrontEndPlugin<void> = {
9292
};
9393
return f;
9494
};
95+
const eventListener = (name: string, emitAlert = false) => {
96+
const f = (event: Event) => {
97+
console.log(event);
98+
if (emitAlert) {
99+
alert(`${name} event: ${event.type}`);
100+
}
101+
};
102+
return f;
103+
};
95104
const buttons = widget.node.querySelectorAll('jp-button');
96105
buttons.forEach(button => {
97106
button.addEventListener('click', clickListener);
98107
});
99108
const search = widget.node.querySelector('jp-search');
100109
search?.addEventListener('change', changeListener('Search'));
101110
search?.addEventListener('input', changeConsoleListener('Search'));
111+
102112
const textField = widget.node.querySelector('jp-text-field');
103113
textField?.addEventListener('change', changeListener('Text field'));
114+
textField?.addEventListener('input', changeListener('Text field'));
115+
104116
const numberField = widget.node.querySelector('jp-number-field');
105117
numberField?.addEventListener('change', changeListener('Number field'));
118+
numberField?.addEventListener('input', changeListener('Number field'));
119+
106120
const select = widget.node.querySelector('jp-select');
107121
select?.addEventListener('change', changeListener('Select'));
122+
108123
const combobox = widget.node.querySelector('jp-combobox');
109124
combobox?.addEventListener('change', changeListener('Combobox'));
110125
combobox?.addEventListener('input', changeConsoleListener('Combobox'));
126+
111127
const slider = widget.node.querySelector('jp-slider');
112128
slider?.addEventListener('change', changeConsoleListener('Slider'));
113129

130+
const checkbox = widget.node.querySelectorAll('jp-checkbox');
131+
checkbox.forEach(box => {
132+
box.addEventListener('change', eventListener('Checkbox', true));
133+
});
134+
135+
const tooltip = widget.node.querySelector('jp-tooltip');
136+
tooltip?.addEventListener('dismiss', eventListener('Tooltip'));
137+
138+
const tabs = widget.node.querySelector('jp-tabs');
139+
tabs?.addEventListener('change', eventListener('Tabs'));
140+
141+
const treeItems = widget.node.querySelectorAll('jp-tree-item');
142+
treeItems.forEach(item => {
143+
item.addEventListener('selected-change', eventListener('Tree Item'));
144+
item.addEventListener('expanded-change', eventListener('Tree Item'));
145+
});
146+
114147
const dataRef = React.createRef<WebDataGrid>();
115148
const reactWidget = ReactWidget.create(<Artwork dataRef={dataRef} />);
116149
reactWidget.addClass('jp-Artwork');
@@ -122,22 +155,25 @@ const plugin: JupyterFrontEndPlugin<void> = {
122155
app.shell.add(reactWidget, 'main', { mode: 'split-bottom' });
123156
app.shell.activateById(widget.id);
124157

125-
const loadTableData = setInterval(() => {
126-
const dataGrid: WebDataGrid | null =
127-
widget.node.querySelector('#basic-grid');
128-
if (dataGrid?.isConnected) {
129-
clearInterval(loadTableData);
130-
dataGrid.rowsData = TABLE_DATA;
131-
if (dataRef.current) {
132-
dataRef.current.rowsData = TABLE_DATA;
133-
}
158+
const dataGrid: WebDataGrid | null =
159+
widget.node.querySelector('#basic-grid');
160+
if (dataGrid?.isConnected) {
161+
dataGrid.rowsData = TABLE_DATA;
162+
if (dataRef.current) {
163+
dataRef.current.rowsData = TABLE_DATA;
134164
}
135-
}, 100);
165+
}
136166
});
137167
}
138168
};
139169

140170
function Artwork(props: { dataRef: React.Ref<WebDataGrid> }): JSX.Element {
171+
const tooltipAnchor = React.useRef<HTMLElement>(null);
172+
173+
const onEvent = (event: any) => {
174+
console.log(event);
175+
alert(`Got a React event: ${event.type}`);
176+
};
141177
const onChange = (event: any) => {
142178
alert(`React on React change event: ${event?.target?.value}`);
143179
};
@@ -208,9 +244,13 @@ function Artwork(props: { dataRef: React.Ref<WebDataGrid> }): JSX.Element {
208244
</RadioGroup> */}
209245
<div className="jp-FlexColumn">
210246
<label>Checkboxes</label>
211-
<Checkbox checked>Label</Checkbox>
212-
<Checkbox checked>Label</Checkbox>
213-
<Checkbox disabled>Label</Checkbox>
247+
<Checkbox onChange={onEvent} checked>
248+
Label
249+
</Checkbox>
250+
<Checkbox onChange={onEvent}>Label</Checkbox>
251+
<Checkbox onChange={onEvent} disabled>
252+
Label
253+
</Checkbox>
214254
</div>
215255
{/* <div>
216256
<Tag>Tag</Tag>
@@ -235,14 +275,15 @@ function Artwork(props: { dataRef: React.Ref<WebDataGrid> }): JSX.Element {
235275
</div>
236276
<div className="jp-FlexColumn">
237277
<label>Tooltip</label>
238-
<Tooltip anchor="anchored-react-button">React tooltip</Tooltip>
239-
<Button id="anchored-react-button">Anchor</Button>
278+
{/* The tooltip component needs to be placed after the anchor so the reference is defined */}
279+
<Button ref={tooltipAnchor}>Anchor</Button>
280+
<Tooltip anchorElement={tooltipAnchor.current}>React tooltip</Tooltip>
240281
</div>
241282
</div>
242283
<div className="jp-FlexColumn" style={{ gridColumn: 4 }}>
243284
<DataGrid ref={props.dataRef}></DataGrid>
244285

245-
<Tabs>
286+
<Tabs onChange={onEvent}>
246287
<Tab id="one">One</Tab>
247288
<Tab id="two">Two</Tab>
248289
<Tab id="three">Three</Tab>
@@ -252,7 +293,8 @@ function Artwork(props: { dataRef: React.Ref<WebDataGrid> }): JSX.Element {
252293
</Tabs>
253294

254295
<TreeView>
255-
<TreeItem>
296+
{/* @ts-expect-error unknown event onExpand */}
297+
<TreeItem onSelect={onEvent} onExpand={onEvent}>
256298
Root item 1
257299
<TreeItem expanded>
258300
Flowers
@@ -340,8 +382,8 @@ function createNode(): HTMLElement {
340382
-->
341383
<div class="jp-FlexColumn">
342384
<label>Checkboxes</label>
343-
<jp-checkbox autofocus checked>Label</jp-checkbox>
344385
<jp-checkbox checked>Label</jp-checkbox>
386+
<jp-checkbox>Label</jp-checkbox>
345387
<jp-checkbox disabled>Label</jp-checkbox>
346388
</div>
347389
<!--

packages/react-components/src/anchored-region/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ export const AnchoredRegion: React.DetailedHTMLFactory<
3737
'vertical-scaling'?: 'anchor' | 'fill' | 'content';
3838
'fixed-placement'?: boolean;
3939
'auto-update-mode'?: 'anchor' | 'auto';
40+
/**
41+
* @property
42+
*/
43+
anchorElement?: HTMLElement | null;
44+
/**
45+
* @property
46+
*/
47+
viewportElement?: HTMLElement | null;
4048
},
4149
HTMLElement
4250
> = wrap(jpAnchoredRegion()) as any;

packages/react-components/src/checkbox/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ export const Checkbox: React.DetailedHTMLFactory<
1919
readonly?: boolean;
2020
},
2121
HTMLElement
22-
> = wrap(jpCheckbox()) as any;
22+
> = wrap(jpCheckbox(), { events: { onChange: 'change' } }) as any;
2323
// @ts-expect-error unknown property
2424
Checkbox.displayName = 'Jupyter.Checkbox';

packages/react-components/src/combobox/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ export const Combobox: React.DetailedHTMLFactory<
2020
value?: 'string';
2121
},
2222
HTMLElement
23-
> = wrap(jpCombobox()) as any;
23+
> = wrap(jpCombobox(), {
24+
events: {
25+
onChange: 'change',
26+
onInput: 'input'
27+
}
28+
}) as any;
2429
// @ts-expect-error unknown property
2530
Combobox.displayName = 'Jupyter.Combobox';

packages/react-components/src/data-grid/index.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,19 @@ import React from 'react';
1212

1313
const { wrap } = provideReactWrapper(React, provideJupyterDesignSystem());
1414

15-
export const DataGrid: React.DetailedHTMLFactory<
16-
React.HTMLAttributes<HTMLElement> & {
17-
'generate-header'?: 'none' | 'default' | 'sticky';
18-
'grid-template-columns'?: 'string';
19-
},
20-
HTMLElement
21-
> = wrap(jpDataGrid()) as any;
22-
// @ts-expect-error unknown property
23-
DataGrid.displayName = 'Jupyter.DataGrid';
15+
// WARNING The wrapping needs to be called in order (from bottom to top DOM elements)
16+
// Otherwise during the wrapping the tag for sub elements won't be resolved and this
17+
// will contaminate the standard web component.
2418

2519
export const DataGridCell: React.DetailedHTMLFactory<
2620
React.HTMLAttributes<HTMLElement> & {
2721
'cell-type'?: 'default' | 'columnheader' | 'rowheader';
2822
'grid-column'?: string;
2923
},
3024
HTMLElement
31-
> = wrap(jpDataGridCell()) as any;
25+
> = wrap(jpDataGridCell(), {
26+
events: { onFocus: 'cell-focused' }
27+
}) as any;
3228
// @ts-expect-error unknown property
3329
DataGridCell.displayName = 'Jupyter.DataGridCell';
3430

@@ -38,6 +34,16 @@ export const DataGridRow: React.DetailedHTMLFactory<
3834
'row-type'?: 'default' | 'header' | 'sticky-header';
3935
},
4036
HTMLElement
41-
> = wrap(jpDataGridRow()) as any;
37+
> = wrap(jpDataGridRow(), { events: { onFocus: 'row-focused' } }) as any;
4238
// @ts-expect-error unknown property
4339
DataGridRow.displayName = 'Jupyter.DataGridRow';
40+
41+
export const DataGrid: React.DetailedHTMLFactory<
42+
React.HTMLAttributes<HTMLElement> & {
43+
'generate-header'?: 'none' | 'default' | 'sticky';
44+
'grid-template-columns'?: 'string';
45+
},
46+
HTMLElement
47+
> = wrap(jpDataGrid()) as any;
48+
// @ts-expect-error unknown property
49+
DataGrid.displayName = 'Jupyter.DataGrid';

packages/react-components/src/tooltip/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export const Tooltip: React.DetailedHTMLFactory<
1919
position?: 'top' | 'right' | 'bottom' | 'left' | 'start' | 'end';
2020
'horizontal-viewport-lock'?: boolean;
2121
'vertical-viewport-lock'?: boolean;
22+
/**
23+
* @property
24+
*/
25+
anchorElement?: HTMLElement | null;
2226
},
2327
HTMLElement
2428
> = wrap(jpTooltip()) as any;

packages/react-components/src/tree-item/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export const TreeItem: React.DetailedHTMLFactory<
1717
disabled?: boolean;
1818
},
1919
HTMLElement
20-
> = wrap(jpTreeItem()) as any;
20+
> = wrap(jpTreeItem(), {
21+
events: { onExpand: 'expanded-change', onSelect: 'selected-change' }
22+
}) as any;
2123
// @ts-expect-error unknown property
2224
TreeItem.displayName = 'Jupyter.TreeItem';

0 commit comments

Comments
 (0)