diff --git a/ui/src/text_annotator.test.tsx b/ui/src/text_annotator.test.tsx index 47ae9d9b34..2205bcfce2 100644 --- a/ui/src/text_annotator.test.tsx +++ b/ui/src/text_annotator.test.tsx @@ -38,7 +38,14 @@ describe('TextAnnotator.tsx', () => { it('Sets correct args on remove', () => { const { container } = render() - fireEvent.mouseUp(container.querySelector('i')!) + fireEvent.mouseUp(container.querySelector('[data-test="remove-icon"]')!) + expect(wave.args[name]).toMatchObject([{ text: 'Hello there! Pretty good day' }]) + }) + + it('Sets correct args on remove all', () => { + const { getByRole } = render() + + fireEvent.click(getByRole('menuitem')) expect(wave.args[name]).toMatchObject([{ text: 'Hello there! Pretty good day' }]) }) @@ -164,7 +171,7 @@ describe('TextAnnotator.tsx', () => { it('Calls sync on remove if trigger specified', () => { const { container } = render() - fireEvent.mouseUp(container.querySelector('i')!) + fireEvent.mouseUp(container.querySelector('[data-test="remove-icon"]')!) expect(pushMock).toHaveBeenCalled() }) @@ -181,13 +188,13 @@ describe('TextAnnotator.tsx', () => { it('Shows remove icon on hover', () => { const { container, getByText } = render() - expect(container.querySelector('i')).not.toBeVisible() + expect(container.querySelector('[data-test="remove-icon"]')!).not.toBeVisible() fireEvent.mouseOver(getByText('g')) - expect(container.querySelector('i')).toBeVisible() + expect(container.querySelector('[data-test="remove-icon"]')!).toBeVisible() fireEvent.mouseOut(getByText('g')) - expect(container.querySelector('i')).not.toBeVisible() + expect(container.querySelector('[data-test="remove-icon"]')!).not.toBeVisible() fireEvent.mouseOver(getByText('P')) - expect(container.querySelector('i')).toBeVisible() + expect(container.querySelector('[data-test="remove-icon"]')!).toBeVisible() }) describe('readonly', () => { @@ -200,9 +207,9 @@ describe('TextAnnotator.tsx', () => { describe('smart selection off', () => { it('Sets correct args on annotate from left to right', () => { - const { getByText, getByRole } = render() + const { getByText } = render() - fireEvent.click(getByRole('switch')) + fireEvent.click(getByText('Smart selection')) fireEvent.click(getByText('Tag 1')) fireEvent.mouseDown(getByText('H')) fireEvent.mouseUp(getByText('h')) @@ -216,9 +223,9 @@ describe('TextAnnotator.tsx', () => { }) it('Sets correct args on annotate from right to left', () => { - const { getByText, getByRole } = render() + const { getByText } = render() - fireEvent.click(getByRole('switch')) + fireEvent.click(getByText('Smart selection')) fireEvent.click(getByText('Tag 1')) fireEvent.mouseDown(getByText('h')) fireEvent.mouseUp(getByText('H')) @@ -232,10 +239,10 @@ describe('TextAnnotator.tsx', () => { }) it('Sets correct args on annotate when replacing selection', () => { - const { getByText, getByRole } = render() + const { getByText } = render() fireEvent.click(getByText('Tag 2')) - fireEvent.click(getByRole('switch')) + fireEvent.click(getByText('Smart selection')) fireEvent.mouseDown(getByText('P')) fireEvent.mouseUp(getByText('g')) diff --git a/ui/src/text_annotator.tsx b/ui/src/text_annotator.tsx index 8fcb9e4a35..b695c66174 100644 --- a/ui/src/text_annotator.tsx +++ b/ui/src/text_annotator.tsx @@ -113,7 +113,15 @@ const top: -3, background: cssVar('$card'), }, - readonly: { pointerEvents: 'none' } + readonly: { pointerEvents: 'none' }, + checkbox: { + $nest: { + '&:hover': { + backgroundColor: cssVar('$neutralLighter'), + color: cssVar('$neutralDark') + } + } + } }), annotateNumbersAroundToken = (tokenIdx: U, tokens: TokenProps[], activeTag?: S) => { let charRightIdx = tokenIdx + 1, charLeftIdx = tokenIdx - 1 @@ -202,6 +210,11 @@ export setTokens([...tokens]) submitWaveArgs() }, + removeAllAnnotations = () => { + tokens.forEach(token => token.tag = undefined) + setTokens([...tokens]) + submitWaveArgs() + }, annotate = (endElProps: TokenMouseEventProps) => { if (!startElPropsRef.current) return const @@ -263,7 +276,7 @@ export className={clas(css.mark, isFirst ? css.firstMark : '', isLast ? css.lastMark : '')} style={{ backgroundColor: cssVar(color), color: getContrast(color) }}> {text} - + {/* HACK: Put color underlay under remove icon because its glyph is transparent and doesn't look good on tags. */} @@ -283,15 +296,25 @@ export
{title}
- setSmartSelection(prevSelection => !prevSelection)} - onText="On" - offText="Off" - inlineLabel - /> +
+ setSmartSelection(prevSelection => !prevSelection)} + className={css.checkbox} + styles={{ root: { alignItems: 'center', paddingLeft: 8, paddingRight: 8 } }} + /> + token.tag), + iconProps: { iconName: 'DependencyRemove', styles: { root: { fontSize: 20 } } }, + }, + ]} + /> +
{ tokens.map(({ start, end, text, tag }, idx) => { const activeColor = activeTag ? tagColorMap.get(activeTag) : undefined diff --git a/website/blog/assets/2021-11-05/text-annotator.gif b/website/blog/assets/2021-11-05/text-annotator.gif index dac0cc7067..2b0e04f6b6 100644 Binary files a/website/blog/assets/2021-11-05/text-annotator.gif and b/website/blog/assets/2021-11-05/text-annotator.gif differ diff --git a/website/docs/examples/assets/text-annotator.png b/website/docs/examples/assets/text-annotator.png index 2dd24d6a74..09050254bb 100644 Binary files a/website/docs/examples/assets/text-annotator.png and b/website/docs/examples/assets/text-annotator.png differ