Code Monkey home page Code Monkey logo

Comments (10)

SupremeTechnopriest avatar SupremeTechnopriest commented on May 19, 2024

Hi @kamranayub, this error is not caused by IdleTImer. It's because you are not exporting your app component and the test suite cant find it. Ive updated your example here.

from react-idle-timer.

SupremeTechnopriest avatar SupremeTechnopriest commented on May 19, 2024

Also, I would probably use IdleTimer as a standalone component and not as a wrapper component. <IdleTImer /> vs <IdleTimer>{{some content}}</IdleTimer>. This way your app state is separate from IdleTimer state.

from react-idle-timer.

kamranayub avatar kamranayub commented on May 19, 2024

from react-idle-timer.

kamranayub avatar kamranayub commented on May 19, 2024

Ah hah! I figured it out. It was due to how react-idle-timer is exported as a module and how I described it in TypeScript.

This declaration file works as expected:

declare module "react-idle-timer" {
  import * as React from "react";

  class IdleTimer extends React.Component<IdleTimerProps> {
    /**
     * Restore initial state and restart timer
     */
    reset(): void;

    /**
     * Store remaining time and stop timer
     */
    pause(): void;

    /**
     * Resumes a paused timer
     */
    resume(): void;

    /**
     * Time remaining before idle (number of ms)
     */
    getRemainingTime(): number;

    /**
     * How much time has elapsed (timestamp)
     */
    getElapsedTime(): number;

    /**
     * Last time the user was active
     */
    getLastActiveTime(): number;

    /**
     * Returns wether or not the user is idle
     */
    isIdle(): boolean;
  }

  namespace IdleTimer {

  }

  interface IdleTimerProps {
    ref: (ref: IdleTimer) => any;

    /**
     * Activity Timeout in milliseconds default: 1200000
     */
    timeout?: number;

    /**
     * DOM events to listen to default: see [default events](https://github.com/SupremeTechnopriest/react-idle-timer#default-events)
     */
    events?: string[];

    /**
     * Element reference to bind activity listeners to default: document
     */
    element?: Node;

    /**
     * Start the timer on mount default: true
     */
    startOnMount?: boolean;

    /**
     * Bind events passively default: true
     */
    passive?: boolean;

    /**
     * Capture events default: true
     */
    capture?: boolean;

    /**
     * Function to call when user becomes active
     */
    onActive?: () => void;

    /**
     * Function to call when user is idle
     */
    onIdle?: () => void;
  }

  export = IdleTimer;
}

I may try to contribute a @types package for this.

from react-idle-timer.

SupremeTechnopriest avatar SupremeTechnopriest commented on May 19, 2024

@kamranayub Please do! That would be great!

from react-idle-timer.

kamranayub avatar kamranayub commented on May 19, 2024

OK, this was actually a little more involved.

I was having the issue I originally posted above in my CRA TS project when running Jest tests. I had no problems using the component in my application at runtime, though.

My tsconfig.test.json file has a different module format than the main application, due to some issues with react-scripts-ts:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "commonjs"
  }
}

For whatever reason, this module type causes a problem when trying to use the following import syntax:

import IdleTimer from "react-idle-timer";

While this works at runtime (webpack can import it properly), Jest cannot handle this and throws the error above (it's basically undefined).

The import has to look like this when running through tests:

import * as IdleTimer from "react-idle-timer";

This will work with the Jest tests.

So to handle both working at runtime and working during tests, I introduced a component prop on my wrapper component that uses whatever instance is passed so I can override it during tests. Super hacky but short of redoing how this package gets bundled, I don't know what to do to fix it.

These are the TS definitions I eventually ended up with:

declare module "react-idle-timer" {
  import * as React from "react";

  class IdleTimer extends React.Component<IdleTimerProps> {
    /**
     * Restore initial state and restart timer
     */
    reset(): void;

    /**
     * Store remaining time and stop timer
     */
    pause(): void;

    /**
     * Resumes a paused timer
     */
    resume(): void;

    /**
     * Time remaining before idle (number of ms)
     */
    getRemainingTime(): number;

    /**
     * How much time has elapsed (timestamp)
     */
    getElapsedTime(): number;

    /**
     * Last time the user was active
     */
    getLastActiveTime(): number;

    /**
     * Returns wether or not the user is idle
     */
    isIdle(): boolean;
  }

  export interface IdleTimerProps {
    ref: (ref: IdleTimer) => any;

    /**
     * Activity Timeout in milliseconds default: 1200000
     */
    timeout?: number;

    /**
     * DOM events to listen to default: see [default events](https://github.com/SupremeTechnopriest/react-idle-timer#default-events)
     */
    events?: string[];

    /**
     * Element reference to bind activity listeners to default: document
     */
    element?: Node;

    /**
     * Start the timer on mount default: true
     */
    startOnMount?: boolean;

    /**
     * Bind events passively default: true
     */
    passive?: boolean;

    /**
     * Capture events default: true
     */
    capture?: boolean;

    /**
     * Function to call when user becomes active
     */
    onActive?: () => void;

    /**
     * Function to call when user is idle
     */
    onIdle?: () => void;
  }

  export default IdleTimer;
}

The weird part is I can't repro this exactly in CodeSandbox. It apparently works in tests and at runtime with import * as IdleTimer syntax.

https://codesandbox.io/s/n0y232k4p0

πŸ€·β€β™‚οΈ

from react-idle-timer.

SupremeTechnopriest avatar SupremeTechnopriest commented on May 19, 2024

Sounds like it's the way default exports are handled by typescript? I'm not too familiar with ts. I like it in concept but haven't really done anything with it. I see that react has the same style of import import * as React from "react"; where usually you can just import React from 'react'?

Glad you got something working... but not sure theres anything I can do on my end to help you clean it up. If it helps, I use Rollup to build the component. The main export is a cjs module and the module export is an es module. See here.

from react-idle-timer.

kamranayub avatar kamranayub commented on May 19, 2024

from react-idle-timer.

MQuy avatar MQuy commented on May 19, 2024

I had the same problem. It seems that typescript cannot pick module in package.json but webpack can.
You can check details here: microsoft/TypeScript#21423
I wonder that can we disable module in our package.json temporarity? @SupremeTechnopriest

from react-idle-timer.

paigeflourin avatar paigeflourin commented on May 19, 2024

Hi @kamranayub ,

would happen to explain to me how to implement this? sorry i am new to this but i am creating an SPFX app and i need to check a user's idle time. i have forked your codesandbox and tried to implement the example in the readme but i can't make it work.

https://codesandbox.io/s/n0y232k4p0

from react-idle-timer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.