Skip to content

Commit

Permalink
Merge pull request #10 from desko27/feature/support-closing-animations
Browse files Browse the repository at this point in the history
Support closing animations
  • Loading branch information
desko27 authored Aug 22, 2024
2 parents 63e18c4 + b29eb4c commit 20594ed
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Bring your React component, `react-call` gives you the `call(<props>)` method.
- 🤯 Call from outside React
- 🌀 Flexible: it's your component
- 🚀 Supports React Native and SSR
- 📦 Extremely lightweight: <500B
- 📦 Extremely lightweight: ~500B
- 🕳️ Zero dependencies

# The pattern
Expand Down
2 changes: 1 addition & 1 deletion bundlesize.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"files": [
{
"path": "./dist/*.js",
"maxSize": "500 B"
"maxSize": "550 B"
}
]
}
18 changes: 15 additions & 3 deletions lib/createCallable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {

export function createCallable<Props = void, Response = void, RootProps = {}>(
UserComponent: UserComponentType<Props, Response, RootProps>,
unmountingDelay = 0,
): Callable<Props, Response, RootProps> {
let $setStack: PrivateStackStateSetter<Props, Response> | null = null
let $nextKey = 0
Expand All @@ -20,12 +21,23 @@ export function createCallable<Props = void, Response = void, RootProps = {}>(
const promise = Promise.withResolvers<Response>()

const end = (response: Response) => {
if ($setStack === null) return
promise.resolve(response)
$setStack((prev) => prev.filter((c) => c.key !== key))
if (!$setStack) return
const scopedSetStack = $setStack

if (unmountingDelay > 0) {
scopedSetStack((prev) =>
prev.map((c) => (c.key !== key ? c : { ...c, ended: true })),
)
}

globalThis.setTimeout(
() => scopedSetStack((prev) => prev.filter((c) => c.key !== key)),
unmountingDelay,
)
}

$setStack((prev) => [...prev, { key, props, end }])
$setStack((prev) => [...prev, { key, props, end, ended: false }])
return promise.promise
},
Root: (rootProps: RootProps) => {
Expand Down
1 change: 1 addition & 0 deletions lib/createCallable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface PrivateCallContext<Props, Response> {
key: string
props: Props
end: (response: Response) => void
ended: boolean
}
export type PrivateStackState<Props, Response> = PrivateCallContext<
Props,
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-call",
"version": "1.2.0",
"version": "1.3.0-0",
"description": "Call your React components",
"repository": "desko27/react-call",
"author": "Ismael Ramon <[email protected]> (https://desko.dev)",
Expand Down
11 changes: 9 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState } from 'react'
import { createCallable } from '#lib/main'

type Props = { message: string }
Expand All @@ -8,7 +9,7 @@ const Modal = createCallable<Props, Response, RootProps>(
({ call, message }) => (
<div>
<p>
{call.root.userName}, {message}
{call.root.userName}, {message} {call.ended && <span>(ended)</span>}
</p>
<button type="button" onClick={() => call.end(true)}>
Yes
Expand All @@ -18,20 +19,26 @@ const Modal = createCallable<Props, Response, RootProps>(
</button>
</div>
),
2000,
)

export function App() {
const [visible, setVisible] = useState(true)

const handleConfirm = async () => {
const result = await Modal.call({ message: 'are you sure?' })
console.log(`Resolved: ${result}`)
}

return (
<div>
<button type="button" onClick={() => setVisible((p) => !p)}>
Toggle
</button>
<button type="button" onClick={handleConfirm}>
Confirm
</button>
<Modal.Root userName="desko27" />
{visible && <Modal.Root userName="desko27" />}
</div>
)
}

0 comments on commit 20594ed

Please sign in to comment.