• Stars
    star
    939
  • Rank 48,667 (Top 1.0 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Functional props composition for UI components (React.js & Vue.js)

ProppyJS

Functional props composition for components
A 1.5kB library integrating with your favourite UI framework

Built with ❀︎ by @fahad19 and contributors

What is ProppyJS?

ProppyJS is a tiny 1.5kB JavaScript library for composing props (object that components receive to render themselves).

It comes with various integration packages giving you the freedom to use it popular rendering libraries.

What does it do?

ProppyJS flow of props

The idea is you express the behaviour of your Component as props first, and then connect it to your Component (which can be either React, Vue.js or Preact) using the same API of Proppy.

The API gives you access to other application-wide dependencies too (like a store using Redux) for convenience anywhere in the components tree.

Packages

Package Status Size Description
proppy proppy-status 1.5K Core package
proppy-react proppy-react-status 1.0K React integration
proppy-vue proppy-vue-status 0.7K Vue.js integration
proppy-preact proppy-preact-status 1.1K Preact integration
proppy-redux proppy-redux-status 0.6K Redux integration
proppy-rx proppy-rx-status 0.6K RxJS integration

Quick start

Installation

With npm:

$ npm install --save proppy

Basics

Factories

For the simplicity of this example, we can start with withProps function from proppy first:

import { withProps } from 'proppy';

const P = withProps({ counter: 1 });

Instances

Now we can get an instance from our factory function by calling it:

const p = P();

To access the props synchronously:

console.log(p.props); // { counter: 1 }

Subscription

Given the nature of our instance having static props, if we subscribe to it, it will emit the props only once:

const unsubscribe = p.subscribe(props => console.log(props));
// { counter: 1 }

To unsubscribe, just call the returned function:

unsubscribe();

Destroy

To cancel all listeners and clear the internal state, just call:

p.destroy();

Dynamic props

There are times when your props require a bit of interactivity. Imagine your component wants to render the current state of counter, but also want to be able to update the value.

We can achieve that using the withState function for example:

import { withState } from 'proppy';

// withState(stateName, setterName, initialState)
const P = withState('counter', 'setCounter', 0);

const p = P();

Initially, the instance will only show you the default initial state for counter:

console.log(p.props);
// { counter: 0, setCounter: Function }

But we can update it too:

p.props.setCounter(5);

console.log(p.props);
// { counter: 5, setCounter: Function }

If you subscribed to the instance, it will keep emitting the new props every time a change occurs:

p.subscribe(props => console.log(props));
// { counter: 0, setCounter: Function }
// { counter: 5, setCounter: Function }

Composition

Proppy also ships with a handy compose function which allows you to compose multiple factories into a single one:

import { compose, withProps, withState } from 'proppy';

const P = compose(
  withProps({ foo: 'foo value' }),
  withProps({ bar: 'bar value' }),
  withState('counter', 'setCounter', 0)
);

Once you create an instance, all the props from those factories will be accessible in a single object:

const p = P();

console.log(p.props);
// {
//   foo: 'foo value',
//   bar: 'bar value',
//   counter: 0,
//   setCounter: Function
// }

Providers

Providers are application-wide dependencies that all Proppy instances can access anywhere.

They are useful especially when you want to maintain them in a single place, but you want Components from anywhere to access them at will.

Imagine setting your application's name, in a providers object like this:

const myProviders = {
  appName: 'My Super Awesome App!'
};

Now when composing your props with Proppy, you want to be able to access them:

import { compose, withProps } from 'proppy';

const P = compose(
  withProps({ foo: 'foo value' }),

  // `withProps` can also generate props using a function
  withProps((props, providers) => {
    return {
      name: providers.appname
    };
  })
);

// pass `myProviders` when calling the factory
const p = P(myProviders);

Your Proppy instance now has these props:

console.log(p.props);
// {
//   foo: 'foo value',
//   name: 'My Super Awesome App!'
// }

Rendering with React

Proppy integrates with React via proppy-react package.

You can install it with npm first:

$ npm install --save react proppy-react

Set providers

Then we need to set our custom providers in our root React component:

// components/Root.js
import React from 'react';
import { ProppyProvider } from 'proppy-react';

import Counter from './Counter';

const myProviders = {};

export default function Root() {
  return (
    <ProppyProvider providers={myProviders}>
      <Counter />
    </ProppyProvider>
  );
}

Attach factory

Now from anywhere in our components tree, we can use the attach higher-order component to connect your Proppy factory to React component:

// components/Counter.js
import React from 'react';
import { attach } from 'proppy-react';
import { compose, withProps, withState } from 'proppy';

const P = compose(
  withProps({ foo: 'foo value' }),
  withState('counter', 'setCounter', 0),
);

function Counter(props) {
  const { foo, counter, setCounter } = props;

  return (
    <div>
      <p>Foo: {foo}</p>

      <p>Counter: {counter}</p>

      <button onClick={() => setCounter(counter + 1)}>
        Increment
      </button>
    </div>
  );
}

export default attach(P)(Counter);

You can do the same with Vue.js and Preact too via proppy-vue and proppy-preact packages respectively.

Inspiration

Original inspiration for this project has been recompose. If your project is using React, you should definitely check it out.

Learn more about the differences between Proppy and other libraries (like Redux and Recompose) in our FAQ page.

License

MIT

More Repositories

1

featurevisor

Git-based feature flags and experimentation management solution for developers
TypeScript
209
star
2

singool

Backbone.js based framework for developing single-page web applications
CoffeeScript
190
star
3

firenze

Adapter based JavaScript ORM for Node.js and the browser
JavaScript
131
star
4

tydel

Typed Models & Collections for JavaScript data structure
JavaScript
37
star
5

shape.less

πŸ”Ά Collection of LESS mixins for various shapes
CSS
36
star
6

huffer

Rapidly develop Ember.js applications with Grunt
CSS
18
star
7

cakephp-bower

🐀 CakePHP Plugin for Twitter Bower
PHP
17
star
8

clear_cache

CakePHP plugin/shell for deleting cache files
PHP
13
star
9

glob-run

Run multiple commands by glob patterns sequentially.
JavaScript
12
star
10

FontAwesomeFinder

AngularJS app for instantly searching FontAwesome icons
JavaScript
11
star
11

social_bookmarks

Croogo plugin for showing graphical social bookmark links
PHP
11
star
12

redux-boilerplate

Boilerplate generator for Redux
JavaScript
9
star
13

themes

Themes for Croogo CMS
PHP
9
star
14

markdown

Markdown plugin for Croogo
PHP
8
star
15

tydel-react

React.js bindings for Tydel
JavaScript
6
star
16

diyai

Dependency Injection in JavaScript/ES6
JavaScript
6
star
17

BowerPackages

AngularJS app for searching Bower packages
CoffeeScript
6
star
18

li3_css

Lithium library for introducing new CSS features
PHP
6
star
19

singool-tasks

Demo plugin built with Singool.js
CoffeeScript
5
star
20

get-params

Get a list of a JavaScript function's parameter names
JavaScript
4
star
21

crypto-js

CryptoJS for Browserify
JavaScript
4
star
22

droxit

create and sync Git repositories with Dropbox
Shell
4
star
23

winston-slack-hook

Slack WebHook transport for Winston logging library
JavaScript
4
star
24

frint-css-poc

CSS Modules PoC with FrintJS
JavaScript
4
star
25

cakephp-stitch

Stitch your JavaScript files as CommonJS for the browser
PHP
4
star
26

singool-cmsui

Experimental responsive CMS UI built in Singool.js
JavaScript
4
star
27

firenze-adapter-mysql

MySQL adapter for firenze.js ORM
JavaScript
3
star
28

wiki

Croogo's wiki
PHP
3
star
29

firenze-adapter-localstorage

localStorage adapter for firenze.js ORM
JavaScript
2
star
30

docume

Generate documentation in README from source files
JavaScript
2
star
31

firenze-adapter-sqlite3

SQLite 3 adapter for firenze.js ORM
JavaScript
2
star
32

material-design-variables

Google's Material Design colour variables
CSS
2
star
33

concat-from-list

Concatenate files listed in JSON/CSON file.
JavaScript
2
star
34

singool-js

Node module for Singool.js framework
CoffeeScript
2
star
35

run-scripts

Run multiple npm scripts sequentially in one go.
JavaScript
2
star
36

tydel-logger

Logger for Tydel
JavaScript
2
star
37

fahad19.github.com

1
star
38

firenze-adapter-memory

Memory adapter for firenze.js ORM
JavaScript
1
star
39

featurevisor-example-cloudflare

Featurevisor CI/CD example with GitHub Actions & Cloudflare Pages
JavaScript
1
star
40

firenze-behavior-slug

Slug behavior for firenze.js ORM
JavaScript
1
star
41

firenze-behavior-timestamp

Timestamp behavior for firenze.js ORM
JavaScript
1
star
42

short-name

Shorten long (human) names.
JavaScript
1
star
43

Sitemaps

Sitemaps plugin for Croogo
PHP
1
star
44

CroogoBot

IRC bot for Croogo
CoffeeScript
1
star
45

test

just for testing purpose
JavaScript
1
star
46

firenze-adapter-redis

Redis adapter for firenze.js ORM
JavaScript
1
star