Skip to content

Commit

Permalink
Merge pull request #77 from FrameMuse/73-enhance-modalcomponent-type
Browse files Browse the repository at this point in the history
Enhance `ModalComponent` type
  • Loading branch information
FrameMuse authored Mar 25, 2023
2 parents b233f3c + 0c2bc13 commit 49bba4b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 31 deletions.
20 changes: 10 additions & 10 deletions coverage/clover.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1679786905577" clover="3.2.0">
<project timestamp="1679786905577" name="All files">
<coverage generated="1679787979361" clover="3.2.0">
<project timestamp="1679787979361" name="All files">
<metrics statements="106" coveredstatements="85" conditionals="53" coveredconditionals="35" methods="37" coveredmethods="31" elements="196" coveredelements="151" complexity="0" loc="106" ncloc="106" packages="1" files="7" classes="7"/>
<file name="container.tsx" path="/home/kotto/github/react-modal-global/src/container.tsx">
<metrics statements="9" coveredstatements="9" conditionals="14" coveredconditionals="14" methods="3" coveredmethods="3"/>
Expand Down Expand Up @@ -82,14 +82,14 @@
</file>
<file name="hooks.ts" path="/home/kotto/github/react-modal-global/src/hooks.ts">
<metrics statements="8" coveredstatements="8" conditionals="3" coveredconditionals="2" methods="3" coveredmethods="3"/>
<line num="35" count="59" type="stmt"/>
<line num="36" count="58" type="cond" truecount="2" falsecount="0"/>
<line num="38" count="54" type="stmt"/>
<line num="43" count="2" type="stmt"/>
<line num="49" count="90" type="stmt"/>
<line num="51" count="90" type="stmt"/>
<line num="52" count="28" type="stmt"/>
<line num="55" count="90" type="stmt"/>
<line num="36" count="59" type="stmt"/>
<line num="37" count="58" type="cond" truecount="2" falsecount="0"/>
<line num="40" count="54" type="stmt"/>
<line num="55" count="2" type="stmt"/>
<line num="61" count="90" type="stmt"/>
<line num="63" count="90" type="stmt"/>
<line num="64" count="28" type="stmt"/>
<line num="67" count="90" type="stmt"/>
</file>
<file name="index.ts" path="/home/kotto/github/react-modal-global/src/index.ts">
<metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>
Expand Down
28 changes: 14 additions & 14 deletions coverage/lcov.info
Original file line number Diff line number Diff line change
Expand Up @@ -176,27 +176,27 @@ BRH:13
end_of_record
TN:
SF:src/hooks.ts
FN:34,useModalContext
FN:48,useModalState
FN:51,(anonymous_2)
FN:35,useModalContext
FN:60,useModalState
FN:63,(anonymous_2)
FNF:3
FNH:3
FNDA:59,useModalContext
FNDA:90,useModalState
FNDA:28,(anonymous_2)
DA:35,59
DA:36,58
DA:38,54
DA:43,2
DA:49,90
DA:51,90
DA:52,28
DA:55,90
DA:36,59
DA:37,58
DA:40,54
DA:55,2
DA:61,90
DA:63,90
DA:64,28
DA:67,90
LF:8
LH:8
BRDA:36,0,0,4
BRDA:36,0,1,54
BRDA:48,1,0,0
BRDA:37,0,0,4
BRDA:37,0,1,54
BRDA:60,1,0,0
BRF:3
BRH:2
end_of_record
Expand Down
24 changes: 18 additions & 6 deletions src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,40 @@ copies or substantial portions of the Software.
*/

import { ComponentLifecycle, ReactNode, useContext, useEffect, useState } from "react"
import { useContext, useEffect, useState } from "react"

import { modalContext } from "./context"
import { Modal, ModalController, ModalState } from "./controller"
import { ModalWindow } from "./types"


/**
* Used inside a modal component to access the modal context (`ModalWindow`).
*
* Accepts a generic type that is used to infer the props of the modal component.
* It has 3 overloads:
* 1. `useModalContext<ModalComponent>()` - infers the props from the class component type.
* 2. `useModalContext<typeof ModalComponent>()` - infers the props from the function component type.
* 3. `useModalContext<unknown>()` - infers any type besides the above.
* 1. `useModalContext<typeof ModalClassComponent>()` - infers the props from the class component type.
* 2. `useModalContext<typeof ModalFunctionComponent>()` - infers the props from the function component type.
* 3. `useModalContext<{ c: 3 }>()` - you can enter props by yourself too.
*/
export function useModalContext<T>(): ModalWindow<T extends ComponentLifecycle<infer P, unknown> | ((props: infer P) => ReactNode) ? P : T> {
export function useModalContext<T>(): any {
const context = useContext(modalContext)
if (!context) throw new Error("ModalError: useModalContext must be used within a modalContext")

return context as never
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return context as ModalWindow<any>
}

// /* Type Testing */
// class ModalClassComponent extends Component<{ a: 1 }> { }
// // eslint-disable-next-line @typescript-eslint/no-unused-vars
// function ModalFunctionComponent(props: { b: 2 }) { return null }

// useModalContext<typeof ModalClassComponent>() // => ModalWindow<{ a: 1 }>
// useModalContext<typeof ModalFunctionComponent>() // => ModalWindow<{ b: 2 }>
// useModalContext<{ c: 3 }>() // => ModalWindow<{ c: 3 }>
// useModalContext() // => ModalWindow<unknown>



const DEFAULT_STATE: ModalState = {
Expand Down
9 changes: 8 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ copies or substantial portions of the Software.
import { ReactElement } from "react"
import { HasRequiredKeys } from "type-fest"

export type ModalComponent<P = unknown> = ((props: P) => ReactElement | null) | (() => ReactElement | null)
/**
* A modal component can be either a function component or a class component.
*/
export type ModalComponent<P = unknown> =
// Function Component
| ((props: P) => ReactElement | null)
| (() => ReactElement | null)


export interface ModalParams {
/**
Expand Down

0 comments on commit 49bba4b

Please sign in to comment.