From 61dca6ba71aafcab4a101cb21fc898a630c4c333 Mon Sep 17 00:00:00 2001
From: PUNNOOSE WILSON <40118548+punnoosewilson@users.noreply.github.com>
Date: Thu, 30 Jan 2025 20:40:24 +0530
Subject: [PATCH] feat(TextHighlighter): Add TextHighlighter component - React
(#384)
* feat(TextHighlighter): Add TextHighlighter component - React
* chore(doc): update docs and stories
* docs(status): change to draft
* chore(name): change package name
* chore: simplify test
* chore: format
---------
Co-authored-by: Jeff Chew
Co-authored-by: Anna Wen <54281166+annawen1@users.noreply.github.com>
---
examples/react/TextHighlighter/index.html | 22 +
examples/react/TextHighlighter/package.json | 26 +
examples/react/TextHighlighter/src/App.tsx | 17 +
examples/react/TextHighlighter/src/index.scss | 9 +
examples/react/TextHighlighter/src/main.tsx | 19 +
.../react/TextHighlighter/src/vite-env.d.ts | 10 +
examples/react/TextHighlighter/tsconfig.json | 25 +
.../react/TextHighlighter/tsconfig.node.json | 10 +
examples/react/TextHighlighter/vite.config.ts | 16 +
.../__stories__/TextHighlighter.mdx | 100 ++++
.../__stories__/TextHighlighter.stories.js | 545 ++++++++++++++++++
.../__stories__/storybook.scss | 203 +++++++
.../__tests__/TextHighlighter.test.js | 23 +
.../TextHighlighter.test.js.snap | 11 +
.../components/TextHighlighter.tsx | 50 ++
.../components/text-highlighter.scss | 179 ++++++
.../src/components/TextHighlighter/index.ts | 9 +
.../components/TextHighlighter/package.json | 30 +
.../components/TextHighlighter/tsconfig.json | 8 +
yarn.lock | 8 +
20 files changed, 1320 insertions(+)
create mode 100644 examples/react/TextHighlighter/index.html
create mode 100644 examples/react/TextHighlighter/package.json
create mode 100644 examples/react/TextHighlighter/src/App.tsx
create mode 100644 examples/react/TextHighlighter/src/index.scss
create mode 100644 examples/react/TextHighlighter/src/main.tsx
create mode 100644 examples/react/TextHighlighter/src/vite-env.d.ts
create mode 100644 examples/react/TextHighlighter/tsconfig.json
create mode 100644 examples/react/TextHighlighter/tsconfig.node.json
create mode 100644 examples/react/TextHighlighter/vite.config.ts
create mode 100644 packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.mdx
create mode 100644 packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.stories.js
create mode 100644 packages/react/src/components/TextHighlighter/__stories__/storybook.scss
create mode 100644 packages/react/src/components/TextHighlighter/__tests__/TextHighlighter.test.js
create mode 100644 packages/react/src/components/TextHighlighter/__tests__/__snapshots__/TextHighlighter.test.js.snap
create mode 100644 packages/react/src/components/TextHighlighter/components/TextHighlighter.tsx
create mode 100644 packages/react/src/components/TextHighlighter/components/text-highlighter.scss
create mode 100644 packages/react/src/components/TextHighlighter/index.ts
create mode 100644 packages/react/src/components/TextHighlighter/package.json
create mode 100644 packages/react/src/components/TextHighlighter/tsconfig.json
diff --git a/examples/react/TextHighlighter/index.html b/examples/react/TextHighlighter/index.html
new file mode 100644
index 00000000..a7e7a61c
--- /dev/null
+++ b/examples/react/TextHighlighter/index.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+ @carbon-labs/react-text-highlighter stackblitz
+
+
+
+
+
+
diff --git a/examples/react/TextHighlighter/package.json b/examples/react/TextHighlighter/package.json
new file mode 100644
index 00000000..197d53d2
--- /dev/null
+++ b/examples/react/TextHighlighter/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "carbon-labs-react-text-highlighter-example",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@carbon/react": "^1.72.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@carbon-labs/react-text-highlighter": "latest",
+ "@types/react": "^18.2.43",
+ "@types/react-dom": "^18.2.17",
+ "@vitejs/plugin-react": "^4.2.1",
+ "sass": "~1.83.0",
+ "typescript": "^5.2.2",
+ "vite": "^5.0.8"
+ }
+}
diff --git a/examples/react/TextHighlighter/src/App.tsx b/examples/react/TextHighlighter/src/App.tsx
new file mode 100644
index 00000000..a14787bf
--- /dev/null
+++ b/examples/react/TextHighlighter/src/App.tsx
@@ -0,0 +1,17 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2025
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import { TextHighlighter } from '@carbon-labs/react-text-highlighter/es/index';
+
+function App() {
+ return ;
+}
+
+export default App;
diff --git a/examples/react/TextHighlighter/src/index.scss b/examples/react/TextHighlighter/src/index.scss
new file mode 100644
index 00000000..2bf65e7d
--- /dev/null
+++ b/examples/react/TextHighlighter/src/index.scss
@@ -0,0 +1,9 @@
+/**
+ * Copyright IBM Corp. 2025
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+@use '@carbon/react';
+@use '@carbon-labs/react-text-highlighter/scss/text-highlighter';
diff --git a/examples/react/TextHighlighter/src/main.tsx b/examples/react/TextHighlighter/src/main.tsx
new file mode 100644
index 00000000..e52d23cb
--- /dev/null
+++ b/examples/react/TextHighlighter/src/main.tsx
@@ -0,0 +1,19 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2025
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App.tsx';
+import './index.scss';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+);
diff --git a/examples/react/TextHighlighter/src/vite-env.d.ts b/examples/react/TextHighlighter/src/vite-env.d.ts
new file mode 100644
index 00000000..d246f815
--- /dev/null
+++ b/examples/react/TextHighlighter/src/vite-env.d.ts
@@ -0,0 +1,10 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2025
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+///
diff --git a/examples/react/TextHighlighter/tsconfig.json b/examples/react/TextHighlighter/tsconfig.json
new file mode 100644
index 00000000..a7fc6fbf
--- /dev/null
+++ b/examples/react/TextHighlighter/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/examples/react/TextHighlighter/tsconfig.node.json b/examples/react/TextHighlighter/tsconfig.node.json
new file mode 100644
index 00000000..42872c59
--- /dev/null
+++ b/examples/react/TextHighlighter/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/examples/react/TextHighlighter/vite.config.ts b/examples/react/TextHighlighter/vite.config.ts
new file mode 100644
index 00000000..0188763d
--- /dev/null
+++ b/examples/react/TextHighlighter/vite.config.ts
@@ -0,0 +1,16 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2025
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+});
diff --git a/packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.mdx b/packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.mdx
new file mode 100644
index 00000000..2d2f8a02
--- /dev/null
+++ b/packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.mdx
@@ -0,0 +1,100 @@
+import { ArgTypes, Canvas, Meta, Controls } from '@storybook/blocks';
+import * as TextHighlighterStories from './TextHighlighter.stories';
+
+
+
+# TextHighlighter
+
+- **Initiative owner(s):** Punnoose Wilson
+- **Status:** Draft
+- **Target library:** TBD
+- **Target library maintainer(s) / PR Reviewer(s):** N/A
+- **Support channel:** `#carbon-labs`
+
+{/* */}
+{/* */}
+
+> 💡 Check our
+> [Stackblitz](https://stackblitz.com/github/carbon-design-system/carbon-labs/tree/main/examples/react/TextHighlighter)
+> example implementation.
+
+[![Edit carbon-labs](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/carbon-design-system/carbon-labs/tree/main/examples/react/TextHighlighter)
+
+## Table of Contents
+
+- [Overview](#overview)
+ - [Variants](#here-we-have-a-component-offering-3-variants)
+- [Getting started](#getting-started)
+- [Example usages](#example-usages)
+ - [Version comparison](#1-version-comparison)
+ - [Reference anotation](#2-reference-anotation)
+ - [Document versioning](#3-document-versioning)
+ - [Document highlighting with source](#4-document-highlighting-with-source)
+
+{/* */}
+
+## Overview
+
+The text highlighter feature enhances user experience by improving readability, focus, and engagement with the content. This feature is especially beneficial in various contexts such as version comparison, commenting, documentation etc
+
+***It’s crucial that we use HTML semantics appropriately to represent the text highlighters, as improper usage could lead to a negative user experience. We must ensure effective communication to users utilizing assistive technologies, necessitating careful control over the markup.***
+
+### Here we have a component offering 3 variants:
+
+- 1st variant - `` : This HTML element represents text which is marked or highlighted for reference or notation purposes.
+- 2nd variant - `` : This HTML element represents a range of text that has been added to a document. (Comparison purpose)
+- 3rd variant - `` : This HTML element represents a range of text that has been deleted from a document. (Comparison purpose)
+
+
+
+
+
+## Getting started
+
+Here's a quick example to get you started.
+
+```bash
+yarn add @carbon/react
+yarn add @carbon-labs/react-text-highlighter
+```
+
+### JS (via import)
+
+```javascript
+import { TextHighlighter } from '@carbon-labs/react-text-highlighter/es/index';
+
+function App() {
+ return ;
+}
+
+export default App;
+```
+
+### SCSS
+
+In your styles file import
+
+```
+@use '@carbon/react';
+@use '@carbon-labs/react-text-highlighter/scss/text-highlighter';
+```
+
+## Example usages
+
+Text highlighters add significant value by making content more interactive, engaging, and easier to manage and understand.
+
+### **1. Version comparison**
+
+
+
+### **2. Reference anotation**
+
+
+
+### **3. Document versioning**
+
+
+
+### **4. Document highlighting with source**
+
+
diff --git a/packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.stories.js b/packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.stories.js
new file mode 100644
index 00000000..2f70e5d1
--- /dev/null
+++ b/packages/react/src/components/TextHighlighter/__stories__/TextHighlighter.stories.js
@@ -0,0 +1,545 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2025
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React, { useState } from 'react';
+import mdx from './TextHighlighter.mdx';
+import { TextHighlighter } from '../components/TextHighlighter';
+import '../components/text-highlighter.scss';
+import {
+ Column,
+ ContainedList,
+ ContainedListItem,
+ Grid,
+ Link,
+ OperationalTag,
+ Popover,
+ PopoverContent,
+ StructuredListBody,
+ StructuredListCell,
+ StructuredListRow,
+ StructuredListWrapper,
+ Tag,
+ Tile,
+} from '@carbon/react';
+import { ChevronDown, ChevronUp } from '@carbon/react/icons';
+import './storybook.scss';
+
+export default {
+ title: 'Components/TextHighlighter',
+ component: TextHighlighter,
+ parameters: {
+ docs: {
+ page: mdx,
+ },
+ layout: 'centered',
+ },
+};
+
+export const Default = {
+ parameters: {
+ controls: {
+ exclude: ['children'],
+ },
+ },
+ argTypes: {
+ kind: {
+ control: { type: 'radio' },
+ options: ['mark', 'ins', 'del'],
+ description: 'Specify the kind of highlighter.',
+ },
+ type: {
+ control: { type: 'select' },
+ options: [
+ 'default',
+ 'magenta',
+ 'purple',
+ 'blue',
+ 'cyan',
+ 'teal',
+ 'gray',
+ 'cool-gray',
+ 'warm-gray',
+ 'high-contrast',
+ ],
+ description:
+ 'Specify the type of highlighter. The "type" property only applies to the "mark" variant. The "ins" and "del" variants have their own pre-defined types.',
+ },
+ reference: {
+ control: { type: 'text' },
+ description:
+ 'Specify the reference. The "reference" property only applies to the "mark" variant. You can use symbol or max of 2 characters.',
+ },
+ },
+ args: {
+ kind: 'mark',
+ type: 'default',
+ },
+ /**
+ * Renders the template for Playground Storybook
+ * @param {Object} args - arguments to be sent into the playbook
+ * @param {string} args.kind - Specify the kind of highlighter
+ * @param {string} args.type - Specify the type of highlighter. The "type" property only applies to the "mark" variant. The "ins" and "del" variants have their own pre-defined types
+ * @param {string} args.reference - Specify the reference. The "reference" property only applies to the "mark" variant. You can use symbol or max of 2 characters
+ */
+ render: (args) => (
+
+
+
+ Lorem ipsum dolor sit amet,{' '}
+
+ consectetur adipiscing elit
+
+ , sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
+ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
+ reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
+ pariatur. Excepteur{' '}
+
+ sint occaecat cupidatat non proident
+
+ , sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+ The airship `"`
+
+ The Leviathan
+
+ ,`"` a magnificent vessel of gleaming chrome and polished
+ mahogany, glided silently above the bustling metropolis of{' '}
+
+ Neo-Atheria
+
+ .
+
+
+ Within its opulent grand salon,{' '}
+
+ Captain Amelia Croft
+
+ , a woman of sharp wit and steely resolve, surveyed the
+ gathering of dignitaries. Among them were{' '}
+
+ Lord Sterlingworth
+
+ , the eccentric inventor of the `"`
+
+ Gravitation Nullifier
+
+ `"`, a device that defied the very laws of physics, and{' '}
+
+ Baroness Von Schatten
+
+ , a renowned archaeologist who had recently unearthed a cryptic
+ artifact from the long-lost city of{' '}
+
+ Atlantis
+
+ .
+
+
+ The air crackled with anticipation as{' '}
+
+ Professor Alistair Finch
+
+ , a renowned astrophysicist from the{' '}
+
+ University of Elysium
+
+ , prepared to unveil his groundbreaking theory on interstellar
+ travel. The fate of humanity, it seemed, hung precariously in
+ the balance, poised on the precipice of a new era of exploration
+ and discovery.
+
+
+
+
+
+
+
+
+
Entity types
+
+ The legends and reference label for the entities are provided
+ below.
+
+
+
+
+
+ Person PE
+
+
+ Organization OR
+
+
+ Location LO
+
+
+ Technology TE
+
+
+
+ Text highlighters{' '}
+ and annotations{' '}
+ serve several{' '}
+ various purposes in
+ website or web applications:
+
+
+
+
+ Enhanced readability: By allowing users to
+ highlight or annotate text, websites and applications can
+ improve readability and comprehension, especially for longer
+ passages or complex content. Users can mark important points,
+ make notes, or highlight key phrases, which can aid in
+ understanding.
+
+
+ Facilitating collaboration: In{' '}
+ collaborative{' '}
+ environments such as educational platforms, research tools, or
+ document sharing platforms, text highlighters and annotations
+ enable users to collaborate more effectively. Users can
+ highlight areas of interest, leave comments, or provide feedback
+ for others to see.
+
+
+ Personalization: Text highlighters{' '}
+ and annotations{' '}
+ allow users to personalize their experience by marking sections
+ that are relevant or interesting to them. This customization can
+ enhance user engagement and satisfaction.
+
+
+ Studying and research: In educational or
+ research contexts, text highlighters{' '}
+ and annotations{' '}
+ are invaluable tools for studying, analyzing, and synthesizing
+ information. Users can mark important passages, jot down
+ thoughts or questions, and organize their notes for future
+ reference.
+
+
+ Accessibility: Text highlighters{' '}
+ and annotations{' '}
+ can improve accessibility for users with disabilities, such as
+ visual impairments or cognitive disabilities.{' '}
+
+ Annotations can provide additional context or explanations for
+ content, while text highlighters can draw attention to
+ important information.
+
+
+
+ Content curation: In content-heavy websites or
+ applications, text highlighters{' '}
+ and annotations{' '}
+ can help users curate and save relevant information for later
+ reference. Users can highlight text or annotate it with tags,
+ comments, or categorizations to organize their findings
+ effectively.
+
+
+
+
+ Overall, text highlighters{' '}
+ and annotations{' '}
+ contribute to a richer and more interactive user experience,
+ empowering users to engage with content in{' '}
+ significant{' '}
+ meaningful ways and
+ extract maximum value from it.
+
+ Text highlighters and annotations serve several various purposes
+ in website or web applications:
+
+
+
+
+ Enhanced readability: By allowing users to
+ highlight or annotate text, websites and applications can
+ improve readability and comprehension, especially for longer
+ passages or complex content. Users can mark important points,
+ make notes, or highlight key phrases, which can aid in
+ understanding.
+
+
+
+
+ Facilitating collaboration: In collaborative
+ environments such as educational platforms, research tools, or
+ document sharing platforms, text highlighters and annotations
+ enable users to collaborate more effectively. Users can
+ highlight areas of interest, leave comments, or provide
+ feedback for others to see.
+
+
+
+
+ Personalization: Text highlighters and
+ annotations allow users to personalize their experience by
+ marking sections that are relevant or interesting to them.
+ This customization can enhance user engagement and
+ satisfaction.
+
+
+
+
+ Studying and research: In educational or
+ research contexts, text highlighters and annotations are
+ invaluable tools for studying, analyzing, and synthesizing
+ information. Users can mark important passages, jot down
+ thoughts or questions, and organize their notes for future
+ reference.
+
+
+
+
+ Accessibility: Text highlighters and
+ annotations can improve accessibility for users with
+ disabilities, such as visual impairments or cognitive
+ disabilities.{' '}
+
+ Annotations can provide additional context or explanations
+ for content, while text highlighters can draw attention to
+ important information.
+
+ setSourceOpen(false)}>
+
+ Source {sourceOpen ? : }
+ >
+ }
+ onClick={() => {
+ setSourceOpen(!sourceOpen);
+ }}>
+
+
+
+ Source 1
+
+
+ Source 2
+
+
+ Source 3
+
+
+
+
+
+
+
+
+ Content curation: In content-heavy websites
+ or applications, text highlighters and annotations can help
+ users curate and save relevant information for later
+ reference. Users can highlight text or annotate it with tags,
+ comments, or categorizations to organize their findings
+ effectively.
+
+
+
+
+ Overall, text highlighters and annotations contribute to a richer
+ and more interactive user experience, empowering users to engage
+ with content in significant meaningful ways and extract maximum
+ value from it.
+