Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
45e9e20
chore: updates config and packages
pravton Aug 21, 2026
c8dc896
chore: converted classnames util to ts
pravton Aug 21, 2026
412a4ba
chore: converted useGallery hook to ts
pravton Aug 21, 2026
ffe39a5
chore: adds module.d.ts
pravton Aug 21, 2026
c29d25f
chore: adds global types and exports
pravton Aug 21, 2026
d8d08cd
chore: coverts gallery context to tsx
pravton Aug 21, 2026
35c9973
chore: coverts gallery pagintion components to tsx
pravton Aug 21, 2026
a8989a2
chore: coverts gallery nav to tsx
pravton Aug 21, 2026
3484bc6
chore: coverts gallery main and item to tsx
pravton Aug 21, 2026
4b7c250
chore: updates main component to tsx
pravton Aug 21, 2026
f261dcd
chore: fixed typeo and updates type naming
pravton Aug 24, 2026
5b289f7
chore: updates readme
pravton Aug 24, 2026
3fafc9f
chore: ran change set with beta
pravton Aug 25, 2026
a1d1b72
chore: import type fixes
pravton Aug 25, 2026
f091aad
chore: addressed copilot findings
pravton Sep 16, 2026
970f952
chore: fixes missing type
pravton Sep 16, 2026
83c8df3
chore: updates to allow refs on couple components
pravton Oct 19, 2026
b8f21d2
fix: TypeScript capitalization in changeset text
marlonmarcello Oct 19, 2026
3ff66b1
fix: JavaScript capitalization in heading
marlonmarcello Oct 19, 2026
3fb7995
fix: rename JSX example file from .ts to .tsx
marlonmarcello Oct 19, 2026
e6a336c
fix: rename JSX example file from .ts to .tsx
marlonmarcello Oct 19, 2026
3475cf7
fix: rename JSX example file from .ts to .tsx
marlonmarcello Oct 19, 2026
752e70d
fix: rename JSX example file from .ts to .tsx
marlonmarcello Oct 19, 2026
1698f84
fix: lint TypeScript files in lint-staged
Copilot Oct 19, 2026
fde8f2c
docs: scope pagination click example types
Copilot Oct 19, 2026
5894c2e
Support style prop on Gallery
Copilot Oct 19, 2026
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
8 changes: 8 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mode": "pre",
"tag": "beta",
"initialVersions": {
"@wethegit/react-gallery": "5.0.1"
},
"changesets": []
Comment thread
Copilot marked this conversation as resolved.
}
6 changes: 6 additions & 0 deletions .changeset/six-nails-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@wethegit/react-gallery": minor
---

- Converts the package to TypeScript.
- Updates docs with TypeScript examples.
4 changes: 3 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
"env": { "browser": true, "es2020": true },
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": { "ecmaVersion": "latest", "sourceType": "module" },
Comment on lines 8 to 12
"settings": { "react": { "version": "18.2" }, "jest": { "version": 26 } },
"plugins": ["react-refresh"],
"plugins": ["react-refresh", "@typescript-eslint"],
"rules": {
"react-refresh/only-export-components": "off",
"react/prop-types": "off"
Expand Down
10 changes: 9 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,13 @@
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 90
"printWidth": 90,
"overrides": [
{
"files": [".eslintrc", "*.json"],
"options": {
"trailingComma": "none"
}
}
]
}
179 changes: 172 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ A slideshow-style gallery component for use in React projects.
- Accessibility. Built with careful attention to focus management and assistive technology.
- Fully-customizable layouts, using CSS Custom Properties.
- Provides a custom React hook for accessing gallery data, state, updater functions, and more. Build anything on top of the existing gallery components!
- Written in TypeScript

## Getting started

Expand Down Expand Up @@ -52,7 +53,7 @@ import {
This is an optional step, but it's highly recommended to use the base styles as a starting point. The most straightforward way to do this is to import the stylesheet into your app directly from the `/node_modules/@wethegit/react-gallery/dist/` directory, but you can do this in whichever way is preferable within your build system or framework.

```jsx
// app.js
// app.js | app.ts

import "@wethegit/react-gallery/style.css"
```
Expand All @@ -63,6 +64,8 @@ The `<Gallery>` component is a React context provider, which gives all child com

⚠️ Before continuing, make sure you have properly [imported the base stylesheet](#import-the-base-stylesheet), if you intend to use it.

#### Usage: JavaScript

<!-- prettier-ignore -->
```js
// some-data.js
Expand Down Expand Up @@ -116,6 +119,70 @@ const YourGallery = () => {
)
}

export default YourGallery

```
#### Usage: Typescript

<!-- prettier-ignore -->
```ts
// some-data.ts

interface GalleryItemDataType {
image: string
alt: string
id: number
}

export const GALLERY_ITEMS : GalleryItemDataType[] = [
{ image: "/my-image-1.png", alt: "Description of image!", id: 131789 },
{ image: "/my-image-2.png", alt: "Description of image!", id: 235233 },
{ image: "/my-image-3.png", alt: "Description of image!", id: 987432 },
{ image: "/my-image-4.png", alt: "Description of image!", id: 768324 },
]
```

<!-- prettier-ignore -->
```tsx
// your-gallery.tsx

import { GALLERY_ITEMS } from "./some-data"
Comment thread
marlonmarcello marked this conversation as resolved.
import {
Gallery,
GalleryMain,
GalleryNav,
GalleryPagination,
GalleryPaginationItem,
GalleryItem,
} from "@wethegit/react-gallery"

const YourGallery = () => {
return (
<Gallery items={GALLERY_ITEMS}>

<GalleryMain<GalleryItemDataType>
renderGalleryItem={({ item, index, active }) => (
<GalleryItem key={item.id} index={index} active={active}>
<img src={item.image} alt={item.alt} />
</GalleryItem>
)}
/>

<GalleryNav direction={0}>⬅️</GalleryNav>
<GalleryNav direction={1}>➡️</GalleryNav>

<GalleryPagination<GalleryItemDataType>
renderPaginationItem={({ item, index, active }) => (
<GalleryPaginationItem key={item.id} index={index} active={active}>
<span>{index + 1}</span>
</GalleryPaginationItem>
)}
/>

</Gallery>
)
}

export default YourGallery
```

Expand Down Expand Up @@ -153,7 +220,8 @@ Assuming the base stylesheet is being used, the `<GalleryMain>` component render

The parent component for all gallery instances. This serves as a React context provider to its children.

#### Props:
#### Props: `<GalleryProps>`


| Prop | Type | Default value | Description |
| ------------ | -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
Expand All @@ -174,6 +242,8 @@ Per the WAI-ARIA spec, browsers using assistive technology such as screen reader

The `onChange` callback allows you to run code whenever the active gallery item changes. It receives a single Object as an argument, containing the following properties:

##### Props: `<GalleryChangeCallback>`

| Argument | Type | Description |
| --------- | ------ | ---------------------------------------------------------- |
| oldIndex | Number | The index before the onChange function fired. |
Expand All @@ -184,7 +254,7 @@ The `onChange` callback allows you to run code whenever the active gallery item

The primary gallery body. Must be used within a `<Gallery>`. Renders an unordered list (`<ul>`) of your gallery items.

#### Props:
#### Props: `<GalleryMainProps>`

| Prop | Type | Description |
| ----------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
Expand All @@ -195,6 +265,8 @@ The primary gallery body. Must be used within a `<Gallery>`. Renders an unordere

This render prop expects a `<GalleryItem>` to be returned, and receives a handful of arguments:

#### Props: `<RenderGalleryItemArgs>`

| Argument | Type | Description |
| ----------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| active | Boolean | Whether the current item being iterated over is the active item. |
Expand All @@ -205,19 +277,20 @@ This render prop expects a `<GalleryItem>` to be returned, and receives a handfu
### &lt;GalleryItem&gt;
Required component that wraps each child inside the `renderGalleryitem` prop. Renders a list item (`<li>`) and can accept the following props:

#### Props: `<GalleryItemProps>`

| Prop | Type | Description |
| ----------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| children | JSX | |
| className | String | |
| active | Boolean | Whether the current item being iterated over is the active item. |
| index | Number | The index of the currently active gallery item. |


### &lt;GalleryNav&gt;

The navigational "next" and "previous" buttons. Must be used within a `<Gallery>`. You can render your buttons either by passing regular JSX children to them, or by using the `renderNavItem` render prop.

#### Props:
#### Props: `<GalleryNavProps>`

| Prop | Type | Description |
| ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -230,6 +303,8 @@ The navigational "next" and "previous" buttons. Must be used within a `<Gallery>

This render prop is a nice alternative to simply passing childern to the `<GalleryNav>`, as it provides you with a handful of arguments, as outlined below:

#### Props: `<RenderNavItemArgs>`

| Argument | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| activeIndex | Number | The index of the currently-active gallery item. |
Expand All @@ -239,17 +314,26 @@ This render prop is a nice alternative to simply passing childern to the `<Galle

Renders an unordered list (`<ul>`) of pagination items. Must be used within a `<Gallery>`.

#### Props:
#### Props: `<GalleryPaginationProps>`

| Prop | Type | Description |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| className | String | |
| renderPaginationItem | Function | A render prop, returning the JSX to render for each pagination item. [More information](#renderpaginationitem) below. |

##### Type import

```ts
// your-gallery.ts
import type { GalleryPaginationProps } from "@wethegit/react-gallery"
```

#### `renderPaginationItem`

This render prop receives a handful of arguments, and is necessary for rendering pagination UI:

#### Props: `<RenderPaginationItemArgs>`

| Argument | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| active | Boolean | Whether the current pagination item being iterated over corresponds to the active gallery item. |
Expand All @@ -259,6 +343,7 @@ This render prop receives a handful of arguments, and is necessary for rendering

**Example usage of `renderPaginationItem` render prop**
```jsx
// your-gallery.js
<GalleryPagination
renderPaginationItem={({ index, active, activeIndex, item }) => (
<GalleryPaginationItem index={index} active={active} key={item.id}>
Expand All @@ -267,11 +352,28 @@ This render prop receives a handful of arguments, and is necessary for rendering
)}
/>
```

```tsx
// your-gallery.tsx
interface GalleryItemDataType {
image: string
alt: string
id: number
}

<GalleryPagination<GalleryItemDataType>
renderPaginationItem={({ index, active, activeIndex, item }) => (
<GalleryPaginationItem index={index} active={active} key={item.id}>
<span>{index + 1}</span>
</GalleryPaginationItem>
)}
/>
```
### &lt;GalleryPaginationItem&gt;

Used in the prop `renderPaginationItem` of `<GalleryPagination>`. This component with a return value in a list item (`<li>`) and a `<button>`, and receives a handful of arguments:

#### Props:
#### Props: `<GalleryPaginationItemProps>`


| Prop | Type | Description |
Expand All @@ -288,6 +390,8 @@ Used in the prop `renderPaginationItem` of `<GalleryPagination>`. This component

**Example usage of `GalleryPaginationItem`**
```jsx
// your-gallery.js

const handlePaginationItemClick = ({ event, index }) => {
console.log(event, index)
}
Expand All @@ -306,6 +410,35 @@ const handlePaginationItemClick = ({ event, index }) => {
/>
```

```tsx
// your-gallery.tsx

import type { GalleryPaginationItemClickArgs } from "@wethegit/react-gallery"

interface GalleryItemDataType {
image: string
alt: string
id: number
}

const handlePaginationItemClick = ({ event, index }: GalleryPaginationItemClickArgs) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the type-only import and brought GalleryItemDataType into scope in the example. Commit: fde8f2c.

console.log(event, index)
}

<GalleryPagination<GalleryItemDataType>
renderPaginationItem={({ index, active, item }) => (
<GalleryPaginationItem
index={index}
active={active}
key={item.id}
onClick={handlePaginationItemClick}
>
<span>{index + 1}</span>
</GalleryPaginationItem>
)}
/>
```

## Accessibility

The gallery component handles tabbing, focus management, and live-region announcements out-of-the-box. All relevant patterns used in this component follow the guidelines for carousels as documented by the [Web Accessibility Initiative](https://www.w3.org/WAI/).
Expand All @@ -319,6 +452,8 @@ Regarding the ARIA-live text, check out the section on this gallery's [`ariaLive
For reduced motion implementations, you can detect the user's preference via the `matchMedia` API, and adjust the CSS custom property, `--duration` on the `.gallery` selector. Check out the example below, which adds a style tag to the gallery, and overrides the `--duration` property based on the preference. You could also do this via a conditional className, if you prefer. An alternative is be to pass this `prefersReducedMotion` value as a prop, which could be helpful if you use the Styled Components library.

```jsx
// your-gallery.js

const YourGallery = () => {
// Get the user's motion preference:
const prefersReducedMotion = window.matchMedia(
Expand Down Expand Up @@ -346,6 +481,36 @@ const YourGallery = () => {
}
```

```tsx
// your-gallery.tsx

const YourGallery = () => {
// Get the user's motion preference:
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches

// Create an inline style object
const style = {
"--duration": prefersReducedMotion ? "0s" : "0.5s",
} as CSSProperties

return (
// Pass the style overrides to the <Gallery> component
<Gallery items={GALLERY_ITEMS} style={style}>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an optional CSSProperties style prop and forwarded it to Gallery’s root element while preserving its internal touch offset. Commit: 5894c2e.

<GalleryMain<GalleryItemDataType>
renderGalleryItem={({ item, index, active }) => (
<GalleryItem key={item.id} index={index} active={active}>
<img src={item.image} alt={item.alt} />
</GalleryItem>
)}
/>
{/* ...etc */}
</Gallery>
)
}
```

## useGallery hook

The gallery package exposes a `useGallery` React hook. It returns a single object, the properties of which are outlined below.
Expand Down
Loading