Giter VIP home page Giter VIP logo

react-fns's Introduction

repo-banner

react-fns is a collection of imperative Browser API's turned into declarative React components and higher-order components for lots of common situations.

Quick Start

npm i react-fns --save

Resources

Author

Contributors

Thanks goes to these wonderful people (emoji key):


MICHAEL JACKSON

πŸ€”

Pavel Prichodko

πŸ’» πŸ“–

Richard Powell

πŸ’»

Tim Brown

πŸ“–

Jack Moore

πŸ’»

Dayle Rees

πŸ“–

Thomas Flemming

πŸ“–

Sam Kvale

πŸ› πŸ’»

Rhys Powell

πŸ’»

Jeppe Reinhold

πŸ“–

Victor MagalhΓ£es

πŸ› πŸ’»

Macklin Underdown

πŸ“–

This project follows the all-contributors specification. Contributions of any kind welcome!

react-fns's People

Contributors

brimtown avatar daylerees avatar dtinth avatar fraserxu avatar hontas avatar jaredpalmer avatar jeetiss avatar jtmthf avatar lukeaus avatar macklinu avatar narigo avatar prichodko avatar rhysforyou avatar robinmalfait avatar thomasfl avatar tvthatsme avatar txhawks avatar vhfmag avatar xtalx avatar yuchi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-fns's Issues

More side effect oriented APIs?

I was working on an idea of declarative side effect management in React. Basically manage side effects as components such as Promises, Redirects, Title, MetaTags, WebWorkers, ...
I discussed the idea with Kent C. Dodds and he introduced me to this amazing library. He also suggested if we could ass these features to react-fns?
I like the idea. Are you having this in the roadmap so we could help make this happen?

I'd be happy to share what I've done so far and push this library forward.

<Location />

I'm curious if a component for location would be positively received. If so, I'd be happy to contribute a PR.

My thoughts are it would pass the following props to the component to be rendered, each coming from window.location:

  • href
  • protocol
  • host
  • hostname
  • port
  • pathname
  • search
  • hash
  • username
  • password
  • origin

Additionally, I'd like to see a query (perhaps theres a better name) prop passed to the child component that is the parsed location.search.

Concept:

/**
 * If the user navigated to https://example.com?q=cute+kittens, query would be:
 * ```
 * { q: 'cute+kittens' }
 * ```
 */
const Example = () => (
  <Location
    render={({ query }) =>
      <Search searchString={query.q} />
    }
  />
)

I'd like to contribute but... Typescript

Would you accept a component written in just plain ES6 and not Typescript?
This is a really good project and I'd like to contribute to it.

Keep up the good work anyway ⚑️

<Media /> with Rollup configuration

Using my rollup configuration I have to import as follows:

import { Media } from 'react-fns`'

<Media.default>
</Media.default>

Rollup Configuration:

import eslint from 'rollup-plugin-eslint';
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';
import commonjs from 'rollup-plugin-commonjs';

const pkg = require('./package.json');

const external = Object.keys({
	...pkg.dependencies,
	...pkg.devDependencies,
	...pkg.peerDependencies,
});

export default {
	input: 'src/index.js',
	output: [
		{
			file: pkg.main,
			format: 'cjs',
			sourceMap: true,
		},
		{
			file: pkg.module,
			format: 'es',
			sourceMap: true,
		},
	],
	external,
	plugins: [
		resolve(), // resolve external modules from npm
		eslint({
			exclude: '/node_modules/**',
		}),
		babel({
			exclude: '/node_modules/**', // only transpile our source code
		}),
		commonjs({
			'/node_modules/color/index': ['color'],
		}),
		process.env.NODE_ENV === 'production' && terser(),
	],
};

Also, create-react-app seems to import correctly. Any suggestions on modifying my rollup setup so as to NOT have to use default.

[Enhancement] WithWindowSize initial render width height is both 0(zero).

Hello, thank you for this wonderful library!
When I using WithWindowSize components, the first render props I get is zero (both width & height).
I think we can enhance this by checking if window exists on state initialization.
If it exists, assign window.innerWidth & window.innerHeight, otherwise, set it to zero.
I'm so sorry I can't make any pull request because I have no idea what typescript and tests is.
Thank you for your listening!

Mailto marks cc and bcc as optional, but fires TypeError when those are not given

In MailtoProps, both cc and bcc are optional string arrays:

export interface MailtoProps extends React.HTMLAttributes<HTMLAnchorElement> {
  /** Email address */
  email: string;
  /** Subject */
  subject?: string;
  /** List of email addresses to CC */
  cc?: string[];
  /** List of email addresses to Bcc */
  bcc?: string[];
  /** Email body text */
  body?: string;
}

Nonetheless, when stringifying them inside the query string, neither is checked for nullity:

`mailto:${email}?${qs.stringify({
    subject,
    cc: cc.join(', '),
    bcc: bcc.join(', '),
    body,
})}`

That can be detected by typescript if the strictNullChecks flag is activated.

Missing peer dependency definition in package.json

In trying to figure out how much this package would add to bundle size, bundlephobia was unable to check this, since

MissingDependencyError
This package (or this version) uses `react`, but does not specify them either as a dependency or a peer dependency

Wouldn't it make sense to define said peer dependency?

TypeScript error in featureDetection.ts

When trying to build the project, I get a TypeScript error in src/utils/featureDetection.ts:

9   (window as EventTarget).addEventListener('testPassive', null, opts);
                                                            ~~~~

src/utils/featureDetection.ts(9,59): error TS2345: Argument of type 'null' is not assignable to parameter of type 'EventListener | EventListenerObject | undefined'.


10   (window as EventTarget).removeEventListener('testPassive', null, opts);
                                                                ~~~~

src/utils/featureDetection.ts(10,62): error TS2345: Argument of type 'null' is not assignable to parameter of type 'EventListener | EventListenerObject | undefined'.

It seems that we are passing null as the 2nd argument, where we should have passed undefined as per the type definition in lib.es6.d.ts:

interface EventTarget {
    addEventListener(type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
    dispatchEvent(evt: Event): boolean;
    removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}

It looks like this got merged in #45 by @vhfmag (please chip in if you can), but seeing as this makes it impossible to run the buildcommand, it seems strange that this wasn't caught, so I'm tempted to believe that this is only a problem on my end, however I cannot figure out why?
I've tried both with the bundled TS version 2.5.0 and the currently newest 2.6.1.

Am I doing something wrong, or do we indeed need to fix this? If so, I'll happily make a PR.

Network's initial state doesn't reflect connection status

Navigator's state is started as follows: state: NetworkProps = { online: false }. Given that the state is only changed inside handleOnline and handleOffline, the state only goes online after an online event.

For the component to work with SSR, I think it would be better to sync the state with navigator.onLine inside componenDidMount (something like this.setState({ online: navigator && navigator.onLine || false })). I will be submitting a PR.

Scroll not working in ie11

steps to reproduce

create a new app with CRA.

npm install react-fns

Add the following Scroll component :

import React from "react";
import { Scroll } from "react-fns";

function ScrollListener() {
  return (
    // This `<Scroll />` is from react-fns package
    <Scroll
      throttle={100}
      render={({ x, y }) => {
        console.log("y from scroll listener ", y);
        return <div>y scoll: {y}</div>;
      }}
    />
  );
}

export default ScrollListener;

render the ScrollListener component in App.js.

Open in IE 11 and scroll y will be undefined.

Open in Chrome and scroll y will give you the correct value.

Any ideas of needed polyfills? or how to make it work for IE11?

WindowSize's defaultProps mispells throttle property as debounce

WindowSize component's Props are defined as follows:

export interface WindowSizeConfig {
  throttle?: number;
}

But later on, when defaultProps is defined, throttle property is mispelled as debounce:

static defaultProps = {
  debounce: 100,
};

So that, if the throttle property is not given, undefined will be passed to setTimeout inside the throttle utility function. In my browser (Firefox 58.0b6), it behaves the same as if I had given a timeout of 0.

redux bindings question

Hi guys,

Since most of these apis provide somehow global state ( like device orientation, geo position... ) I think it is a good idea to provide an option to put them in the global app state ( e.g. redux store )

Do you think its ok to write some redux bindings where applicable?

<Stringify /> Utility

The readme is littered with JSON.stringify

How about instead of

import { withDeviceMotion } from 'react-fns'

const Inner = ({ alpha, beta, gamma, absolute }) =>
  <pre>
    {JSON.stringify({alpha, beta, gamma}, null, 2)}
  </pre>

export default withDeviceMotion(Inner)

we have

import { withDeviceMotion, Stringify } from 'react-fns'

const Inner = ({ alpha, beta, gamma, absolute }) =>
  <Stringify value={{alpha, beta, gamma}} indent="2" />

export default withDeviceMotion(Inner)

<Audio />

I had the idea for a component with an API that looks something like this:

<Audio src="audiofile.mp3">
  {(isPlaying, play, pause) => {
    return isPlaying ? (
      <MyPauseButton onClick={pause} />
    ) : (
      <MyPlayButton onClick={play} />
    );
  }}
</Audio>

Think that would be a good fit for this repo?

<Location />

Hello Guys, This project is very cool and useful. I was wondering if it would be interesting to add support for the browser API window.location. There are several use cases for this API, if you want I can even mention a few.

And I can submit the PR.

Media component only works when passing children prop rather than render prop

The following does not work:

import { Media } from 'react-fns'

const Example = () =>
  <Media
    query="(min-width: 1000px)"
    render={(match) =>
     <div>
        {match ? 'mobile' : 'desktop'}
     </div>
    }
  />

export default Example

but this does:

import { Media } from 'react-fns'

const Example = () =>
  <Media
    query="(min-width: 1000px)"
    children={(match) =>
     <div>
        {match ? 'mobile' : 'desktop'}
     </div>
    }
  />

export default Example

<MouseEvent /> ?

Would a component that wraps mouse/touch events be useful to have in this package?

This would be incredibly useful for reactive programming and makes me think that something similar must already exist.

edit: I noticed in the roadmap there is "MousePosition" is that the same as mouse event?

Contributing

Hi guys,

It will be really great if there is a CONTRIBUTING file with some explanations for the newbies

I cant get the project running. Tried the build and start script:
npm run build gave me lots of TS errors (error TS2307: Cannot find module 'react'.)
npm start: Error: spawn tsc-watch ENOENT

Im sure Im doing something wrong, but right now I feel a bit stuck.

Contributions guide must be added

Hello, libs idea is fantastic, but at this moment it isn't clear for me how to best contribute to.
In particular, I would like to see guide on what features components should and shouldn't have.
eg there is a conversation about redundancy of some features that not a part of Web APIs: #54

Adding contributions guide would help to resolve that kind of disputes in future. Thanks

DeviceMotionProps doesn't expose its properties as nullables, even though DeviceMotionEvent does

DeviceMotionProps is defined as follows:

export interface DeviceMotionProps {
  acceleration: DeviceAcceleration;
  accelerationIncludingGravity: DeviceAcceleration;
  rotationRate: DeviceRotationRate;
  interval: number;
}

All of those properties are directly acquired from a DeviceMotionEvent:

handleDeviceMotion = (e: DeviceMotionEvent) => {
  this.setState({
    acceleration: e.acceleration,
    accelerationIncludingGravity: e.accelerationIncludingGravity,
    rotationRate: e.rotationRate,
    interval: e.interval,
  });
};

But TypeScript's lib.dom.d.ts defines all of those properties as nullables:

interface DeviceMotionEvent extends Event {
    readonly acceleration: DeviceAcceleration | null;
    readonly accelerationIncludingGravity: DeviceAcceleration | null;
    readonly interval: number | null;
    readonly rotationRate: DeviceRotationRate | null;
    initDeviceMotionEvent(type: string, bubbles: boolean, cancelable: boolean, acceleration: DeviceAccelerationDict | null, accelerationIncludingGravity: DeviceAccelerationDict | null, rotationRate: DeviceRotationRateDict | null, interval: number | null): void;
}

As such, I think DeviceMotionProps should mark them nullable so that whoever uses the component is warned that they should handle such a case.

Need demo page

Love the idea of this project, but it needs a demo page

Consider enabling TypeScript's strict mode to fix bugs and preemptively catch new ones

It may be a little too much to just come, make my first contributions and already suggest a major configuration change, but I think it can boost code quality and prevent further bugs. Here goes the rationale:

By enabling the flag strict inside tsconfig.json, TypeScript enables five other flags (as of 2.5, actually just four): noImplicitAny (that was already enabled and caused #43), noImplicitThis, alwaysStrict, strictNullChecks and strictFunctionTypes (the last from 2.6 on). That's what the other three do:

  • noImplicitThis: it forces every reference to this to be either directly typed or to have a detectable type in the context.
  • alwaysStrict: parses files in strict mode and emit "use strict" in every source file. Strict mode prevents from assigning to undefined or a getter-only property and makes JavaScript overall safer, refer to MDN for more information.
  • strictNullChecks: that's the essential one. It gives you an error at compile time when trying to access a property from a nullable or optional variable, forcing you to handle edge cases, such as const greet (names: string[] | null) => "Hello, " + names.join(", "), where it would give an error, so that one could explicitly handle the null case (i.e.: const greet (names: string[] | null) => "Hello, " + (names ? names.join(", ") : "strangers")). It also prevents from assigning a nullable variable to a non-nullable one.

What do you think?

<Battery />

Hey @jaredpalmer

When I first saw your repo, I get excited. I was working on something sometime ago like that. However, I would be happy to make my first contribution with a component containing battery functionality from browser api. Seems fair for you?

Thanks

Baris

Build and test on CI

When submitting a PR to this codebase, it would be awesome if Travis or another CI service ran the build and test scripts on the branch to ensure merged PRs won't break the build.

If you're interested in using Travis, I would be happy to submit a PR with a .travis.yml config file. You would need to enable this repo on Travis first. At the moment, this is what I see when visiting https://travis-ci.org/jaredpalmer/react-fns:

image

Let me know if I can help with this - thanks! πŸ˜„

media component acts as a conditional not as a render prop

If my 'query' isn't valid to the browser, it just doesn't render, it doesn't send matches: false, down. If it is valid for my browsers current state, it renders and sends matches: null down.

What I would expect: Render should always happen, value of render prop should change.

<QueryParam> provider + editor?

I was wondering what your thoughts were on a PR that added a component with the following API:

<QueryParam>{({ queryParams, patchQueryParams }) => ... }</QueryParams>

calling patchQueryParams({ userId: undefined }) will delete the userId query param and leave the others unchanged.

If you feel like this belongs in this library, I'd be happy to make a PR.

Build script is broken

Just found the project, loved it and thought of contributing. πŸ˜„

But after running yarn, the build script is executed and gives two typescript errors:

src/utils/throttle.ts(11,7): error TS7034: Variable 'callbackArgs' implicitly has type 'any' in some locations where its type cannot be determined.
src/utils/throttle.ts(15,25): error TS7005: Variable 'callbackArgs' implicitly has an 'any' type.

The fix should be as easy as providing type information for the callbackArgs variable. In case the issue is confirmed, I'll be submitting a PR.

Question: HoC with render prop vs function as child component

First, this is an awesome library! πŸŽ‰ I'll definitely be using (and hopefully contributing) to this.

I just wanted to ask a question out of curiosity and learning. Why did you choose a render prop that accepts a function over a function as a child component? I do really like how using a render prop keeps things succinct. I was just curious if there any benefits with going with one over the other?

Thanks in advance!

SSR?

Hi! Just found this on trending, love it 😍

I'm using next (React with SSR), I have not yet tested this lib with SSR but since most of the exposed components from here needs browser APIs to function, there's different ways you could handle that in an SSR case.

If SSR is supported I think it should be documented what the approach is (to not render on the server, sending placeholder values or something else)

and likewise, if you decide not to support SSR then that should be stated in the readme too πŸ‘

Thanks!

<Fetch /> and withFetch

So I know fetch, I like fetch, and now that I see that wrapping the Fetch api is on this component's roadmap I'm interested in trying to implement it.

What props would it need? My initial assumption is something like this:
-render: (response) => stuff to render
render would also call response.json(), response.blob() etc before giving you the response depending on the mime type
-renderUntilResponse: () => stuff to render until the response comes, default render nothing
-renderIfFailed: (response) => stuff to render if it comes back with a non-20* response, default render nothing
-endpoint: string
-requestOptions: object, default {}
-rawRequest: boolean, don't call .then(response => response.json()) before handing the request object over to the render prop. Default false.

Am I missing anything? Is this not what y'all had in mind for a fetch component?

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.