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
18 changes: 17 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ on: [push, pull_request]
jobs:
build-and-test:
name: Build and Test
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 2

- uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/bun.lock') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/bun.lock') }}-

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install
Expand Down
984 changes: 984 additions & 0 deletions bun.lock

Large diffs are not rendered by default.

Binary file removed bun.lockb
Binary file not shown.
9 changes: 2 additions & 7 deletions docs/next.config.mjs → docs/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import createMDX from "@next/mdx";
import remarkGfm from "remark-gfm";
import rehypeSlug from "rehype-slug";
import rehypePrettyCode from "rehype-pretty-code";

/** @type {import('rehype-pretty-code').Options} */
const options = {
theme: "ayu-dark",
bypassInlineCode: false,
Expand All @@ -12,12 +8,11 @@ const options = {
const withMDX = createMDX({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm],
rehypePlugins: [[rehypePrettyCode, options], rehypeSlug],
remarkPlugins: ["remark-gfm"],
rehypePlugins: [["rehype-pretty-code", options], "rehype-slug"],
},
});

/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"],
reactStrictMode: true,
Expand Down
23 changes: 14 additions & 9 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,38 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@mdx-js/loader": "^3.0.1",
"@mdx-js/react": "^3.0.1",
"@next/mdx": "^14.2.11",
"@next/mdx": "15.5.3",
"@omsimos/react-highlight-popover": "*",
"@types/mdx": "^2.0.13",
"next": "^14.2.11",
"next": "15.5.3",
"nextjs-toploader": "^3.6.15",
"react": "^18",
"react-dom": "^18",
"react": "19.1.1",
"react-dom": "19.1.1",
"rehype-pretty-code": "^0.14.0",
"rehype-slug": "^6.0.0",
"remark-gfm": "^4.0.0",
"shiki": "^1.17.5"
"shiki": "^3.13.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.13",
"@tailwindcss/typography": "^0.5.15",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react": "19.1.13",
"@types/react-dom": "19.1.9",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"tailwindcss": "^4.1.13",
"typescript": "^5"
},
"overrides": {
"@types/react": "19.1.13",
"@types/react-dom": "19.1.9"
}
}
2 changes: 1 addition & 1 deletion docs/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
'@tailwindcss/postcss': {},
},
};

Expand Down
2 changes: 1 addition & 1 deletion docs/src/app/docs/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default function MdxLayout({ children }: { children: React.ReactNode }) {
return (
<div className="prose prose-zinc max-w-screen-md mx-auto py-24">
<div className="prose prose-zinc max-w-(--breakpoint-md) mx-auto py-24">
{children}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion docs/src/app/docs/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { HighlightPopover } from '@omsimos/react-highlight-popover';

function App() {
const renderPopover = ({ selection }) => (
<div className="bg-white border rounded p-2 shadow-lg select-none">
<div className="bg-white border rounded-sm p-2 shadow-lg select-none">
You selected: {selection}
</div>
);
Expand Down
56 changes: 39 additions & 17 deletions docs/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,28 +1,50 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";
@plugin "@tailwindcss/typography";

:root {
--background: #ffffff;
--foreground: #242424;
@theme {
--color-background: var(--background);
--color-foreground: var(--foreground);
}

body {
color: var(--foreground);
background: var(--background);
}
/*
The default border color has changed to `currentcolor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.

pre {
overflow-x: auto;
padding: 1rem 0;
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}

pre [data-line] {
padding: 0 1rem;
@utility text-balance {
text-wrap: balance;
}

@layer utilities {
.text-balance {
text-wrap: balance;
:root {
--background: #ffffff;
--foreground: #242424;
}

body {
color: var(--foreground);
background: var(--background);
}

pre {
overflow-x: auto;
padding: 1rem 0;
}

pre [data-line] {
padding: 0 1rem;
}
}
2 changes: 1 addition & 1 deletion docs/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function Home() {
Documentation
</Link>

<div className="text-zinc-800 bg-zinc-50/50 rounded-lg shadow-sm border px-4 py-3 ">
<div className="text-zinc-800 bg-zinc-50/50 rounded-lg shadow-xs border px-4 py-3 ">
<p>
npm install{" "}
<span className="font-semibold">
Expand Down
19 changes: 0 additions & 19 deletions docs/tailwind.config.ts

This file was deleted.

24 changes: 19 additions & 5 deletions docs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
Expand All @@ -18,9 +22,19 @@
}
],
"paths": {
"@/*": ["./src/*"]
}
"@/*": [
"./src/*"
]
},
"target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
25 changes: 15 additions & 10 deletions lib/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
# @omsimos/react-highlight-popover

## 1.4.0

### Minor Changes

- ### Performance Improvements 🚀
- Reduced unnecessary renders by skipping popover position and selection updates when nothing changed.
- Added a safeguarded `requestAnimationFrame` throttle so multiple `selectionchange` events collapse into a single render and any pending frame is cancelled on unmount.

- ### Lifecycle Reliability ✅
- Ensured selection lifecycle callbacks only fire on real visibility transitions and always emit `onPopoverHide` during teardown.
- Prevented duplicate processing when range boundary points remain unchanged, keeping drag interactions smooth.

- ### Compatibility 🔁
- Expanded peer dependency support to include React 19 while keeping full compatibility with React 17 and 18.

## 1.3.2

### Patch Changes

- ### Bug Fixes 🐞

- **Removed Redundant Click-Outside Logic**:
- The `useEffect` that handled clicks outside the popover has been removed. This was causing issues where clicking outside on elements with `user-select: none` would unintentionally close the popover, even though the text remained highlighted.
- Since clicking outside naturally removes text selection, the previous logic was redundant and caused bugs by closing the popover prematurely.
Expand All @@ -23,7 +37,6 @@
### Patch Changes

- ### Bug Fixes 🐞

- **Removed Unintended `.mjs` File**: An unnecessary file was unintentionally included in the v1.3.0 build. This patch removes the file, ensuring a cleaner build and reducing the package size.

## Upgrade Instructions
Expand All @@ -39,14 +52,12 @@
### Minor Changes

- ### Performance Improvements 🚀

- **Memoized Components**: Both the main `HighlightPopover` component and the new `PopoverContent` component are now memoized using `React.memo()`, significantly reducing unnecessary re-renders.
- **Optimized Event Handling**: The `selectionchange` event listener now uses `requestAnimationFrame` to batch updates, reducing the frequency of calculations and improving overall performance.
- **Reduced State Updates**: The `handleSelection` function now checks conditions before updating state, minimizing unnecessary renders.
- **Memoized Context Value**: The `contextValue` is now memoized to prevent unnecessary re-renders of context consumers.

### Documentation 📚

- **Updated Basic Example**: The basic usage example in the documentation now demonstrates the use of the `useHighlightPopover` hook, providing a more comprehensive illustration of the component's capabilities.

## Upgrade Instructions
Expand All @@ -62,15 +73,12 @@
### Minor Changes

- ### New Features 🚀

- **Alignment Prop for Popover**: Introduced a new `alignment` prop that allows for positioning the popover relative to the selected text. Supported values: `'left'`, `'center'`, `'right'`. The default is set to `'center'`.

### Bug Fixes 🐞

- **Resolved ARIA Typo**: Fixed a typo in the ARIA attribute to improve accessibility.

### Under The Hood 🔧

- **ESM-Only Package**: The package has been converted to ESM-only, improving compatibility with modern JavaScript environments.
- **Minified Package Output**: Reduced the bundle size by minifying the package output, leading to better performance and faster load times.

Expand Down Expand Up @@ -118,15 +126,13 @@ npm install @omsimos/react-highlight-popover@latest
We're excited to announce the initial release of React Highlight Popover, a customizable, headless React component for creating popovers on text selection, with zero dependencies!

## 🎉 Highlights

- **Headless Component**: Maximum flexibility for styling and integration
- **Zero Dependencies**: Only React as a peer dependency
- **Customizable**: Fine-tune behavior with props and callbacks
- **Lightweight**: Minimal impact on your bundle size
- **TypeScript Support**: Full type definitions included

## 🚀 Features

- Easy-to-use React component
- Fully customizable popover content and styling
- Configurable minimum selection length
Expand Down Expand Up @@ -171,7 +177,6 @@ npm install @omsimos/react-highlight-popover@latest
## 📝 Changelog

### v1.0.0

- Initial release of React Highlight Popover
- Implemented core HighlightPopover component
- Added useHighlightPopover hook for accessing internal state
Expand Down
10 changes: 5 additions & 5 deletions lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@omsimos/react-highlight-popover",
"version": "1.3.2",
"version": "1.4.0",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -11,8 +11,8 @@
"package.json"
],
"scripts": {
"build": "rm -rf dist && tsup src/index.ts --format esm --dts --minify",
"dev": "tsup src/index.ts --format esm --dts --minify --watch"
"build": "rm -rf dist && tsdown src/index.ts --format esm --dts --minify",
"dev": "tsdown src/index.ts --format esm --dts --minify --watch"
},
"keywords": [
"react",
Expand All @@ -36,8 +36,8 @@
},
"homepage": "https://react-highlight-popover.omsimos.com",
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
"type": "module",
"sideEffects": false
Expand Down
Loading