From b820abadd8e3db165933d7983fcb840d8f8c6b81 Mon Sep 17 00:00:00 2001
From: Trezy
Date: Tue, 31 Dec 2024 01:11:25 -0600
Subject: [PATCH 1/4] refactor: make unprefixed elements opt-in
BREAKING CHANGE: unprefixed elements must be explicitly added
Signed-off-by: Trezy
---
eslint.config.mjs | 8 +++++++-
src/global.ts | 7 +++----
src/index.ts | 2 ++
src/typedefs/HostConfig.ts | 3 +--
src/typedefs/NamespacedPixiElements.ts | 5 -----
src/typedefs/PixiElements.ts | 11 ++---------
src/typedefs/PrefixedPixiElements.ts | 5 +++++
src/typedefs/UnprefixedPixiElements.ts | 10 ++++++++++
8 files changed, 30 insertions(+), 21 deletions(-)
delete mode 100644 src/typedefs/NamespacedPixiElements.ts
create mode 100644 src/typedefs/PrefixedPixiElements.ts
create mode 100644 src/typedefs/UnprefixedPixiElements.ts
diff --git a/eslint.config.mjs b/eslint.config.mjs
index c349ec55..2657c51e 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -12,6 +12,12 @@ export default [
{
rules: {
'max-len': 0,
+ '@typescript-eslint/no-empty-object-type': [
+ 0,
+ {
+ allowInterfaces: 'with-single-extends',
+ },
+ ],
},
},
{
@@ -20,7 +26,6 @@ export default [
'*.test.tsx',
],
rules: {
- '@typescript-eslint/no-unused-expressions': 0,
'@typescript-eslint/dot-notation': [
0,
{
@@ -29,6 +34,7 @@ export default [
allowIndexSignaturePropertyAccess: true,
},
],
+ '@typescript-eslint/no-unused-expressions': 0,
'dot-notation': 0,
},
},
diff --git a/src/global.ts b/src/global.ts
index 9a1651fb..c0b27b88 100644
--- a/src/global.ts
+++ b/src/global.ts
@@ -1,4 +1,3 @@
-import { type NamespacedPixiElements } from './typedefs/NamespacedPixiElements';
import { type PixiElements } from './typedefs/PixiElements';
import type {} from 'react';
@@ -10,7 +9,7 @@ declare module 'react'
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX
{
- interface IntrinsicElements extends PixiElements, NamespacedPixiElements {}
+ interface IntrinsicElements extends PixiElements {}
}
}
@@ -19,7 +18,7 @@ declare module 'react/jsx-runtime'
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX
{
- interface IntrinsicElements extends PixiElements, NamespacedPixiElements {}
+ interface IntrinsicElements extends PixiElements {}
}
}
@@ -28,6 +27,6 @@ declare module 'react/jsx-dev-runtime'
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX
{
- interface IntrinsicElements extends PixiElements, NamespacedPixiElements {}
+ interface IntrinsicElements extends PixiElements {}
}
}
diff --git a/src/index.ts b/src/index.ts
index e8879a07..20bcff12 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -18,4 +18,6 @@ export { useExtend } from './hooks/useExtend';
export { useSuspenseAssets } from './hooks/useSuspenseAssets';
export { useTick } from './hooks/useTick';
export { type ApplicationRef } from './typedefs/ApplicationRef';
+export { type PixiElements } from './typedefs/PixiElements';
export { type PixiReactElementProps } from './typedefs/PixiReactNode';
+export { type UnprefixedPixiElements } from './typedefs/UnprefixedPixiElements';
diff --git a/src/typedefs/HostConfig.ts b/src/typedefs/HostConfig.ts
index 97bf6b33..817c749a 100644
--- a/src/typedefs/HostConfig.ts
+++ b/src/typedefs/HostConfig.ts
@@ -2,7 +2,6 @@ import {
type Container,
type Filter,
} from 'pixi.js';
-import { type NamespacedPixiElements } from './NamespacedPixiElements';
import { type PixiElements } from './PixiElements';
import { type PixiReactNode } from './PixiReactNode';
@@ -21,7 +20,7 @@ export interface HostConfig
suspenseInstance: PixiReactNode;
textInstance: PixiReactNode;
timeoutHandle: number;
- type: keyof PixiElements | keyof NamespacedPixiElements;
+ type: keyof PixiElements;
updatePayload: object;
transitionStatus: null,
}
diff --git a/src/typedefs/NamespacedPixiElements.ts b/src/typedefs/NamespacedPixiElements.ts
deleted file mode 100644
index e413cefe..00000000
--- a/src/typedefs/NamespacedPixiElements.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { type PixiElements } from './PixiElements';
-
-export type NamespacedPixiElements = {
- [K in keyof PixiElements as `pixi${Capitalize}`]: PixiElements[K];
-};
diff --git a/src/typedefs/PixiElements.ts b/src/typedefs/PixiElements.ts
index 72b908a1..de1992d8 100644
--- a/src/typedefs/PixiElements.ts
+++ b/src/typedefs/PixiElements.ts
@@ -1,10 +1,3 @@
-import { type NameOverrides } from '../constants/NameOverrides';
-import { type PixiComponents } from './PixiComponents';
-import { type PixiReactElementProps } from './PixiReactNode';
+import { type PrefixedPixiElements } from './PrefixedPixiElements';
-import type * as PIXI from 'pixi.js';
-
-export type PixiElements = {
- [K in PixiComponents as K extends keyof typeof NameOverrides ? typeof NameOverrides[K] : Uncapitalize]:
- PixiReactElementProps;
-};
+export interface PixiElements extends PrefixedPixiElements {}
diff --git a/src/typedefs/PrefixedPixiElements.ts b/src/typedefs/PrefixedPixiElements.ts
new file mode 100644
index 00000000..a9e0190a
--- /dev/null
+++ b/src/typedefs/PrefixedPixiElements.ts
@@ -0,0 +1,5 @@
+import { type UnprefixedPixiElements } from './UnprefixedPixiElements';
+
+export type PrefixedPixiElements = {
+ [K in keyof UnprefixedPixiElements as `pixi${Capitalize}`]: UnprefixedPixiElements[K];
+};
diff --git a/src/typedefs/UnprefixedPixiElements.ts b/src/typedefs/UnprefixedPixiElements.ts
new file mode 100644
index 00000000..5529a566
--- /dev/null
+++ b/src/typedefs/UnprefixedPixiElements.ts
@@ -0,0 +1,10 @@
+import { type NameOverrides } from '../constants/NameOverrides';
+import { type PixiComponents } from './PixiComponents';
+import { type PixiReactElementProps } from './PixiReactNode';
+
+import type * as PIXI from 'pixi.js';
+
+export type UnprefixedPixiElements = {
+ [K in PixiComponents as K extends keyof typeof NameOverrides ? typeof NameOverrides[K] : Uncapitalize]:
+ PixiReactElementProps;
+};
From 18cbb930c524a0a316c82afcb4557f211ea2e406 Mon Sep 17 00:00:00 2001
From: Trezy
Date: Tue, 31 Dec 2024 01:55:56 -0600
Subject: [PATCH 2/4] docs: update the readme
Signed-off-by: Trezy
---
README.md | 118 ++++++++++++++++++++++++++++++------------------------
1 file changed, 65 insertions(+), 53 deletions(-)
diff --git a/README.md b/README.md
index b336370c..048d4b39 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
- Pixi React
+ @pixi/react
@@ -24,23 +24,23 @@
-Pixi React is an open-source, production-ready library to render high performant PixiJS applications in React.
+`@pixi/react` is an open-source, production-ready library to render high performant PixiJS applications in React.
## Features
-- React v17 and v18 support
+- React v19 support
- PixiJS v8 support
## Getting Started
### Quick Start
-If you want to start a new React project from scratch then we recommend [Create React App](https://github.com/facebook/create-react-app), but Pixi React should work with any React application (Remix, Next.js, etc).
-To add to an existing React application, just install the dependencies:
+If you want to start a new React project from scratch then we recommend [Create React App](https://github.com/facebook/create-react-app), but `@pixi/react` should work with any React application (Remix, Next.js, etc).
+To add `@pixi/react` to an existing React application, just install the dependencies:
-#### Install Pixi React Dependencies
+#### Install Dependencies
```bash
-npm install pixi.js@^8.2.1 @pixi/react@beta
+npm install pixi.js@^8.2.6 @pixi/react@beta
```
#### Pixie React Usage
@@ -70,9 +70,9 @@ const MyComponent = () => {
return (
-
-
-
+
+
+
)
}
@@ -82,9 +82,9 @@ const MyComponent = () => {
### `extend`
-One of the most important concepts to understand with Pixi React v8 is `extend`. Normally, Pixi React would have to import all pf Pixi.js to be able to provide the full library as JSX components. Instead, we use an internal catalogue of components populated by the `extend` API. This allows you to define exactly which parts of Pixi.js you want to import, keeping your bundle sizes small.
+One of the most important concepts to understand with v8 is `extend`. Normally `@pixi/react` would have to import all pf Pixi.js to be able to provide the full library as JSX components. Instead, we use an internal catalogue of components populated by the `extend` API. This allows you to define exactly which parts of Pixi.js you want to import, keeping your bundle sizes small.
-To allow Pixi React to use a Pixi.js component, pass it to the `extend` API:
+To allow `@pixi/react` to use a Pixi.js component, pass it to the `extend` API:
```jsx
import { Container } from 'pixi.js'
@@ -93,7 +93,7 @@ import { extend } from '@pixi/react'
extend({ Container })
const MyComponent = () => (
-
+
)
```
@@ -104,7 +104,7 @@ const MyComponent = () => (
#### ``
-The `` component is used to wrap your Pixi React app. The `` component can take [all props that can be set](https://pixijs.download/release/docs/app.ApplicationOptions.html) on [`PIXI.Application`](https://pixijs.download/release/docs/app.Application.html).
+The `` component is used to wrap your `@pixi/react` app. The `` component can take [all props that can be set](https://pixijs.download/release/docs/app.ApplicationOptions.html) on [`PIXI.Application`](https://pixijs.download/release/docs/app.Application.html).
##### Example Usage
@@ -150,25 +150,25 @@ const MyComponent = () => {
#### Pixi Components
-All other Pixi React components should be included in your IDE's intellisense/autocomplete once you've installed/imported `@pixi/react`. If it's exported from Pixi.js, it's supported as a component in Pixi React. The only difference is that Pixi React components will always start with lowercase characters. Here's a selection of commonly used components:
+All other components should be included in your IDE's intellisense/autocomplete once you've installed/imported `@pixi/react`. If it's exported from Pixi.js, it's supported as a component with the `pixi` prefix. Here's a selection of commonly used components:
```jsx
-
-
-
-
-
-
+
+
+
+
+
+
```
-##### ``
+##### ``
-The `graphics` component has a special `draw` property. `draw` takes a callback which receives the `Graphics` context, allowing drawing to happen on every tick.
+The `pixiGraphics` component has a special `draw` property. `draw` takes a callback which receives the `Graphics` context, allowing drawing to happen on every tick.
```jsx
const MyComponent = () => {
return (
- {
+ {
graphics.clear()
graphics.setFillStyle({ color: 'red' })
graphics.rect(0, 0, 100, 100)
@@ -178,12 +178,9 @@ const MyComponent = () => {
}
```
-> [!IMPORTANT]
-> You may run into some components that conflict with others. For example, the `` component conflicts with the `` component that's built-in to React for use in SVGs. To address this issue, all components are available with the `pixi` prefix. For example, you can replace the `` component with the `` component. It will have the same functionality with none of the collisions.
-
#### Custom Components
-Pixi React supports custom components via the `extend` API. For example, you can create a `` component using the [`pixi-viewport`](https://github.com/davidfig/pixi-viewport) library:
+`@pixi/react` supports custom components via the `extend` API. For example, you can create a `` component using the [`pixi-viewport`](https://github.com/davidfig/pixi-viewport) library:
```jsx
import { extend } from '@pixi/react'
@@ -193,34 +190,15 @@ extend({ Viewport })
const MyComponent = () => {
-
+
}
```
-##### For Typescript Users
-
-If you're using Typescript, this new `` component will throw type errors. Pixi React exports a `PixiReactElementProps` type that can be used to solve this. You'll need to pass the `Viewport` into `PixiReactElementProps` and inject it into JSX:
-
-```ts
-import { type PixiReactElementProps } from '@pixi/react'
-import { type Viewport } from 'pixi-viewport'
-
-declare global {
- namespace JSX {
- interface IntrinsicElements {
- viewport: PixiReactElementProps;
- }
- }
-}
-```
+The `extend` API will teach `@pixi/react` about your components, but TypeScript won't know about them nor their props. If you're using Typescript, check out our [docs for Typescript Users](#for-typescript-users).
### Hooks
-#### `useApp`
-
-**DEPRECATED.** Use `useApplication` hook instead.
-
#### `useApplication`
`useApplication` allows access to the parent `PIXI.Application` created by the `` component. This hook _will not work_ outside of an `` component. Additionally, the parent application is passed via [React Context](https://react.dev/reference/react/useContext). This means `useApplication` will only work appropriately in _child components_, and in the same component that creates the ``.
@@ -268,10 +246,6 @@ const ParentComponent = () => (
)
```
-#### `useAsset`
-
-**DEPRECATED.** Use `useAssets` or `useSuspenseAssets` instead.
-
#### `useAssets`
The `useAssets` hook wraps the functionality of [Pixi's Asset loader](https://pixijs.download/release/docs/assets.Assets.html) and [Cache](https://pixijs.download/release/docs/assets.Cache.html) into a convenient React hook. The hook can accept an array of items which are either an [`UnresolvedAsset`](https://pixijs.download/release/docs/assets.html#UnresolvedAsset) or a url.
@@ -423,3 +397,41 @@ const MyComponent = () => {
> useTick(updateCount)
> }
> ```
+
+### For Typescript Users
+
+#### Custom Components
+
+`@pixi/react` already offers types for built-in components, but custom components need to be added to the library's type catalogue so it knows how to handle them. This can be achieved by adding your custom components to the `PixiElements` interface. Here's what it may look like to add the `viewport` component from our earlier `extend` example:
+
+```ts
+// global.d.ts
+import { type PixiReactElementProps } from '@pixi/react'
+import { type Viewport } from 'pixi-viewport'
+
+declare module '@pixi/react' {
+ interface PixiElements {
+ viewport: PixiReactElementProps;
+ }
+}
+```
+
+Now you'll be able to use your custom component in your project without any type errors!
+
+#### Unprefixed Elements
+
+If you like to live life on the wild side, you can enable unprefixed Pixi elements (i.e. `` instead of ``) by adding the `UnprefixedPixiElements` interface to the `PixiElements` interface.
+
+```ts
+// global.d.ts
+import { type UnprefixedPixiElements } from '@pixi/react'
+
+declare module '@pixi/react' {
+ interface PixiElements extends UnprefixedPixiElements {}
+}
+```
+
+The prefixed and unprefixed elements have the same functionality, but we recommend sticking to the prefixed components to avoid collisions with other libraries that add intrinsic elements to JSX (such as [`react-dom`](https://www.npmjs.com/package/react-dom) and [`@react-three/fiber`](https://www.npmjs.com/package/@react-three/fiber)).
+
+> [!IMPORTANT]
+> Some components conflict with other libaries, such as `
);
expect(elements.props.children).toHaveLength(4);
- expect(elements.props.children[0].type).toEqual('graphics');
+ expect(elements.props.children[0].type).toEqual('pixiGraphics');
expect(elements.props.children[0].props.draw).toBeTypeOf('function');
- expect(elements.props.children[1].type).toEqual('sprite');
+ expect(elements.props.children[1].type).toEqual('pixiSprite');
expect(elements.props.children[1].props.draw).toBeUndefined();
expect(elements.props.children[1].props.texture).toBeInstanceOf(Texture);
- expect(elements.props.children[2].type).toEqual('alphaFilter');
+ expect(elements.props.children[2].type).toEqual('pixiAlphaFilter');
expect(elements.props.children[2].props.alpha).toEqual(0.5);
expect(elements.props.children[3].type).toEqual('pixiText');
From 8158b2bf5d8813230a441d9847cb762b8e9e6015 Mon Sep 17 00:00:00 2001
From: Trezy
Date: Fri, 3 Jan 2025 23:53:31 -0600
Subject: [PATCH 4/4] docs: add information about extending built-in types
Signed-off-by: Trezy
---
README.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/README.md b/README.md
index 048d4b39..e3c7edfb 100644
--- a/README.md
+++ b/README.md
@@ -435,3 +435,17 @@ The prefixed and unprefixed elements have the same functionality, but we recomme
> [!IMPORTANT]
> Some components conflict with other libaries, such as `