Coder Social home page Coder Social logo

lovasoa / react-contenteditable Goto Github PK

View Code? Open in Web Editor NEW
1.6K 13.0 216.0 2.38 MB

React component for a div with editable contents

Home Page: http://npmjs.com/package/react-contenteditable

License: Apache License 2.0

HTML 1.55% JavaScript 36.96% TypeScript 61.49%
react html react-component contenteditable wysiwyg editing text

react-contenteditable's Introduction

react-contenteditable

React component for a div with editable contents

Build Status download count bundle size license

Install

npm install react-contenteditable

Usage

import React from 'react'
import ContentEditable from 'react-contenteditable'

class MyComponent extends React.Component {
  constructor() {
    super()
    this.contentEditable = React.createRef();
    this.state = {html: "<b>Hello <i>World</i></b>"};
  };

  handleChange = evt => {
    this.setState({html: evt.target.value});
  };

  render = () => {
    return <ContentEditable
              innerRef={this.contentEditable}
              html={this.state.html} // innerHTML of the editable div
              disabled={false}       // use true to disable editing
              onChange={this.handleChange} // handle innerHTML change
              tagName='article' // Use a custom HTML tag (uses a div by default)
            />
  };
};

Available props

prop description type
innerRef element's ref attribute Object | Function
html required: innerHTML of the editable element String
disabled use true to disable editing Boolean
onChange called whenever innerHTML changes Function
onBlur called whenever the html element is blurred Function
onFocus event fires when an element has received focus Function
onKeyUp called whenever a key is released Function
onKeyDown called whenever a key is pressed Function
className the element's CSS class String
style a collection of CSS properties to apply to the element Object

Known Issues

If you are using hooks, please see this issue. Using this component with useState doesn't work, but you can still use useRef :

const text = useRef('');

const handleChange = evt => {
    text.current = evt.target.value;
};

const handleBlur = () => {
    console.log(text.current);
};

return <ContentEditable html={text.current} onBlur={handleBlur} onChange={handleChange} />

Examples

You can try react-contenteditable right from your browser to see if it fits your project's needs:

react-contenteditable's People

Contributors

abruzzihraig avatar ajbeaven avatar aleemb avatar anatolyefimov avatar carloshpds avatar carloszaldivar avatar clickclickonsal avatar cubex2 avatar dependabot-support avatar dependabot[bot] avatar dudupopkhadze avatar gausie avatar gilesv avatar jeremymlane avatar kurasixo avatar lovasoa avatar lyleunderwood avatar matthewgertner avatar pcorey avatar raineorshine avatar rkorszun avatar samirbr avatar sebcorbin avatar shelimov avatar slgauravsharma avatar ted-marozzi avatar treora avatar wendellliu avatar zeevl 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

react-contenteditable's Issues

Change is always emitted with first blur event

The component always emits change event when I just click in the editable field and the click outside without any change. I can see the reason in emitChange function. There is condition html !== this.lastHtml which is never false on first blur event, because this.lastHtml initial value is never set so at this moment it is undefined. Change event is fired even if there was no change.

I think this.lastHtml should be set in constructor and also should also update on componentDidUpdate, so when blur or change event is fired for the first time, the variable this.lastHtml will be already filled with correct value.

Use "peerDependency" for React

This permits to let the library client bring its own version of React and in my case permitted sometimes to avoid bugs like having 2 concurrent versions of React in some complex bug settings, or when not doing npm dedupe

Require not working as expected on NodeJS

Not sure if you can call this a bug, but the export default statement exports not the class but an object that places the module at the default key. This is intended by the transpiler as esnext/es6-module-transpiler#85 suggests and they provide solutions for importing on CommonJS systems. Should we change the example on the Readme so that it is valid in every case, or should we export using module.exports to make the require syntax valid in Node (I don't know if this may have other repercussions)?

Allow refs to be used

Refs are now used to work with inner html, please allow refs to be specified and executed with html magic

Does not handle case where browser reformats the html

Sometimes when you do node.innerHtml = stateHtml, the browser do reformat the html, so you may end up with a stateHtml in your state that is different from node.innerHtml

It was a problem in my app because it could lead the component to always return true to shouldComponentUpdate, making the component always re-render (including caret jump problems etc).

In my app I fixed it with something like that:

    componentDidUpdate: function() {
        const node = ReactDOM.findDOMNode(this);
        const html = this.props.html;

        // Bypass VDOM diff by React and updates the dom if it is not correct
        // See http://stackoverflow.com/a/27255103/82609
        if ( node.innerHTML !== html ) {
            node.innerHTML = this.props.html;

            // If DOM node is still different after that, it's because the browser decided to reformat it!
            // we emit the reformatting as a change so that we are sync with the store!
            // (otherwise shouldComponentUpdate may not kick in next time, leading to re-render!)
            const finalInnerHtml = node.innerHTML;
            if ( finalInnerHtml !== html ) {
                this.props.onChange(finalInnerHtml);
            }
        }
    },

Just reporting that problem for documentation purpose, because I can't make a PR as your onChange callback takes an event and I don't have one in this case.

Removing outline/border on focus

How do I remove the outline/border when the field is selected? Passing below object as prop (style) doesn't seem to work:

{
  ':focus': {
      outline: 'none',
      border: 'none',
    },
}

Styling inline works fine otherwise, so I'm guessing that's how the lib is intended to be used. Sorry if I'm missing something.

Thanks!

onFocus/onBlur

Is there an easy way to get onFocus and obBlur events fired by the component?

For example I don't want to respond to every onChange event when user is typing a long string, but only once the control is loosing focus...

Thanks!

Support TypeScript or keep ES6

import * as React from 'react';
import * as ContentEditable from 'react-contenteditable';

class ComposeForm extends React.Component<Props, State> {
	render () {
		let { html, disabled, onChange } = this.props;

		return <ContentEditable html={ html } disabled={ disabled } onChange={ onChange } />;
	}
}

export default ComposeForm;
[at-loader] Checking finished with 1 errors
[at-loader] views/routes/Comments/Compose/Form/index.tsx:11:11 
    JSX element type 'ContentEditable' does not have any construct or call signatures. 

The default constructor is not available as well:

import ContentEditable from 'react-contenteditable';
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of `ComposeForm`.

I can add an annotation, but it does not help as well:

declare module 'react-contenteditable' {
	interface Props extends React.Props<ContentEditable> {
		disabled?: boolean,
		html?: string,
		onChange?: Function
	}

	class ContentEditable extends React.Component<Props, void> {}
	export default ContentEditable;
}

My temporary solution is:

import ContentEditable = require('react-contenteditable');
declare module 'react-contenteditable' {
	interface Props extends React.Props<ContentEditable> {
		[property: string]: any
	}

	class ContentEditable extends React.Component<Props, void> {}
	export = ContentEditable;
}

So, is there any reason to compile the resulting code to ES3?

Element doesn't update on same input after cleaning

Found a bug that can be reproduced like this:

  1. Enter some value in ContentEditable (for example, 1)
  2. Clear html of ContentEditable with this.setState({ inputValue: "" })
  3. Type 1 again
  4. ???
  5. Component doesn't update, despite the changes in value (1 -> "" -> 1)

Code example for better understanding:

class SomeClass extends Rect.Component {
state = {
    inputValue: ''
}

handleMessageInputSend = e => {
    let inputValueForTest = this.state.inputValue
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()

      if (inputValueForTest.trim().split('<br>').join('') !== '') {
        // Submitting value here
       // ...
       // and cleaning the value of ContentEditable
        this.setState({inputValue: ''})
      }
  
    }
  }
render() {
    return (
        <ContentEditable
                html={this.state.inputValue}
                disabled={false}   
                onChange={this.updateInputValue}
                onKeyPress={this.handleMessageInputSend}
        />
    )
}
}

findDOMNode is now in ReactDOM

Nice project.
However, in React 0.14 it warns with

React.findDOMNode is deprecated. Please use ReactDOM.findDOMNode from require('react-dom') instead

Also, it may be nice to have a test coverage

Demo page

Maybe we need to build a simple demo page to make this project more attractive and more convenient for testing ?
😄

IE11 Problem

I'm currently testing my app on Windows with IE11 because it's the standard browser in our company.
We have a commenting feature which uses react-contenteditable. As it seems IE11 converts htmlEl.inner.HTML = null to the string 'null' - but Chrome converts null values to an empty string ('').
On IE11 it looks like:
image

On Chrome:
image

I've been playing around and figured out, that this quickfix solved the problem:

'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var OBSERVER_CONFIG = { childList: true, subtree: true, characterData: true };

var ContentEditable = function (_React$Component) {
  _inherits(ContentEditable, _React$Component);

  function ContentEditable() {
    _classCallCheck(this, ContentEditable);

    var _this = _possibleConstructorReturn(this, (ContentEditable.__proto__ || Object.getPrototypeOf(ContentEditable)).call(this));

    _this.emitChange = _this.emitChange.bind(_this);
    return _this;
  }

  _createClass(ContentEditable, [{
    key: 'render',
    value: function render() {
      var _this2 = this;

      var _props = this.props,
          tagName = _props.tagName,
          html = _props.html,
          props = _objectWithoutProperties(_props, ['tagName', 'html']);

      return _react2.default.createElement(tagName || 'div', _extends({}, props, {
        ref: function ref(e) {
          return _this2.htmlEl = e;
        },
        onBlur: this.props.onBlur || this.emitChange,
        contentEditable: !this.props.disabled,
        dangerouslySetInnerHTML: { __html: html }
      }), this.props.children);
    }
  }, {
    key: 'componentDidMount',
    value: function componentDidMount() {
      var _this3 = this;

      this.observer = new MutationObserver(function (mutations) {
        mutations.forEach(_this3.emitChange);
      });
      this.observer.observe(this.htmlEl, OBSERVER_CONFIG);
    }
  }, {
    key: 'shouldComponentUpdate',
    value: function shouldComponentUpdate(nextProps) {
      // We need not rerender if the change of props simply reflects the user's
      // edits. Rerendering in this case would make the cursor/caret jump.
      return (
        // Rerender if there is no element yet... (somehow?)
        !this.htmlEl
        // ...or if html really changed... (programmatically, not by user edit)
        || nextProps.html !== this.htmlEl.innerHTML && nextProps.html !== this.props.html
        // ...or if editing is enabled or disabled.
        || this.props.disabled !== nextProps.disabled
        // ...or if className changed
        || this.props.className !== nextProps.className
      );
    }
  }, {
    key: 'componentDidUpdate',
    value: function componentDidUpdate() {
      if (this.htmlEl && this.props.html !== this.htmlEl.innerHTML) {
        // Perhaps React (whose VDOM gets outdated because we often prevent
        // rerendering) did not update the DOM. So we update it manually now.
        this.htmlEl.innerHTML = this.props.html;
      }
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this.observer.disconnect();
    }
  }, {
    key: 'emitChange',
    value: function emitChange(evt) {
      if (!this.htmlEl) return;
+      if (this.htmlEl.innerHTML === 'null') this.htmlEl.innerHTML = '';
      var html = this.htmlEl.innerHTML;
      if (this.props.onChange && html !== this.lastHtml) {
        evt.target.value = html;
        this.props.onChange(evt);
      }
      this.lastHtml = html;
    }
  }]);

  return ContentEditable;
}(_react2.default.Component);

exports.default = ContentEditable;
module.exports = exports['default'];

Does anybody else experienced this problem?
I'll make a PR if anybody agees with my approach...

Removing id on content editable div

Currently id=contenteditable is added to contenteditable div.
This is causing problems when multiple instances of this component is used on same page.

Can we remove id ?

Typescript Support

Nice to see this amazing project.

Do it support Typescript? I think Typescript could be useful when guide someone like me to get started with this amazing project.

Waring while using this component

I am seeing following error while using your component
(A component is contentEditable and contains children managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.)

How i can surpass this?

Emiting change on blur

Why do we need emitting change on blur? In my project, a save button is enabled if any of the inputs change but if the user changes nothing but just lose focus, it enables the button again.

Edit: #16 fixes the problem but 1.1.0 version is available on npm. Can we publish the 2.0.0?

programmatically changing html prevents next onChange() from firing

It looks like the logic for determining when the onChange event should be fired needs to be updated. When parent components programmatically update the html property, the lastHtml property is not updated. lastHtml is only updated when users type and onChange events are fired. lastHtml also needs to be updated on programmatic changes to the html; otherwise the component gets out of sync with its last state, and the next character changed in the component by the user will not fire the onChange event.

Controllable ContentEditable

I'm wondering if it's possible to make a ContentEditable controllable? I'm not exactly sure of how to get the name attribute of the ContentEditable itself so I can use it as a key for setState. This may be supported, but I can't find much help on it.

Great project though! I'm simply using it as a vertical-expanding div for user input as I didn't want to use jQuery for this.

Add more useful options and documentation

Nice to have this project published as ContentEditables are hard to deal with.

You should probably document that the implementation is "uncontrolled" and that the div content changes before the state is updated.

Also there are some useful options. Here is the full implementation I use in my project, to give you some insights of features I need:

  • Possibility to post-process the div DOM on change before emitting the change (permits to "format" the DOM, like removing inline styles, html comments, classes or things like that.
  • Possibility to "lock" the contenteditable without unmounting/remounting, to avoid flickering effects
  • Possibility to use a placeholder easily
  • Possibility to disable the listening of changes, to allow integration of side effect libraries like AnnotationJS to update the DIV content without triggering the callback/parser
var UncontrolledContentEditable = React.createClass({

    propTypes: {
        // The HTML to set in this content editable
        html: React.PropTypes.string.isRequired,

        // What to do on changes (key input,paste...)
        onChange: React.PropTypes.func.isRequired,

        // Gives the possibility to "reformat" the dom tree before emitting the change
        parser: React.PropTypes.func,

        // Adds a placeholder attribute to the div.
        // Notice that it requires some CSS to work:
        // [contenteditable][placeholder]:empty:not(:focus):before { content: attr(placeholder); }
        placeholder: React.PropTypes.string,

        // Permits to eventually "lock" the contenteditable. It means that the contenteditable will not be editable anymore
        // This is useful to change from edition to read-only mode
        locked: React.PropTypes.bool,

        // This can be useful to be able to disable the listening of changes
        // This allow external libraries to be able to manipulate the content without triggering parsing/change callback
        // This was primarily done to be able to display annotations on text, using AnnotatorJS
        disableChangeListener: React.PropTypes.bool

    },

    shouldComponentUpdate: function(nextProps) {
        // Special case to avoid cursor jumps
        // See http://stackoverflow.com/a/27255103/82609
        var htmlChanged = nextProps.html !== this.getDOMNode().innerHTML;
        //
        var lockedChanged = this.props.locked !== nextProps.locked;
        var onChangeChanged = this.props.onChange !== nextProps.onChange;
        var parserChanged = this.props.parser !== nextProps.parser;
        var placeholderChanged = this.props.placeholder !== nextProps.placeholder;
        var shouldUpdate = htmlChanged || lockedChanged || onChangeChanged || parserChanged || placeholderChanged;
        if ( shouldUpdate ) {
            console.debug("UncontrolledContentEditable -> should update");
        }
        return shouldUpdate;
    },
    componentDidUpdate: function() {
        // Bypass VDOM diff by React and updates the dom if it is not correct
        // See http://stackoverflow.com/a/27255103/82609
        if ( this.props.html !== this.getDOMNode().innerHTML ) {
            this.getDOMNode().innerHTML = this.props.html;
        }
    },

    emitChange: function(e) {
        if ( this.props.disableChangeListener ) {
            return;
        }
        if ( this.props.parser ) {
            this.props.parser(this.getDOMNode());
        }
        var html = this.getDOMNode().innerHTML;
        if ( html !== this.lastHtml) {
            this.props.onChange(html);
        }
        this.lastHtml = html;
    },

    render: function() {
        return <div {...this.props}
            onInput={this.emitChange}
            placeholder={this.props.placeholder}
            contentEditable={!this.props.locked}
            dangerouslySetInnerHTML={{__html: this.props.html}}></div>;
    }

});

How to pass additional index argument to SortableElement?

Is it possible to pass index argument to SortableElement component.

For example:

change this
const SortableItem = SortableElement(({value}) => <div textValue={value}></div>);

to this
const SortableItem = SortableElement(({value,index}) => <div index={index} textValue={value}></div>);

I am unsure what do I need to modify?

Readme should acknowledge tagName prop

I needed a contenteditable h1 tag, and I was about to uninstall this dependency, but then I checked the source code and saw that you can pass an optional tagName prop. Hallelujah! I want to keep others from making the same mistake.

Component should update on style change.

In response to the suggested change here: #36

Currently prop style changes are not rendered by the component.

I had a go at reflecting these changes for style but I believe it would require a deep equality comparison on the style prop passed in to understand that a render needs to occur.

You can see the changes I made as a temporary measure here: https://github.com/jimah/react-contenteditable/blob/master/src/react-contenteditable.js#L26

Lodash has a nice deep equal function but that would be adding a dependency.

Using styles makes cursor jump to the beginning

The code from the example in the README works, but if to add style={{height: '400px'}}, it starts to have the known issue with React and "contentEditable" -- cursors jumps to the beginning of the editing text.

(I'm on Mac OS, Chrome)

Allow autofocus

I would enjoy to see the possibility to get the component focused automatically after rendering.

Support :disabled property

Adding support should be as simple as:

render() {
  const { disabled, ...props } = this.props
  return <div
    {...props}
    onInput={this.emitChange}
    onBlur={this.emitChange}
    contentEditable={!disabled}
    dangerouslySetInnerHTML={{__html: this.props.html}}></div>;
}

Repeating a key quickly causes text insertion without an emitted event.

I have been attempting to create a way to limit the amount of characters that are input into a ContentEditable component. The only issue is that if a user types quickly enough, characters will be inserted into the DOM without a matching onChange event being emitted from the component.

You can test this by simply putting a console.log inside the onChange callback and counting the amount of key strokes and the amount of log messages on your console.

在IE里报错 ,捉急,在线等

ContentEditable.render():A valid React element(or null) must be returned. You may have returned undefined,an arry or some other invalid object.
以上是报错信息,我是这么写的:

disabled not work

When I trying to disable component it still editable.

this.setState({
  readOnly: true
});

//...

<ContentEditable id={ this.editorId }
  className='Editor'
  onBlur={ this.onBlurEditor }
  disabled={ this.state.readOnly }
  data-placeholder={ this.props.placeholder }
/>

Unknown prop 'html'

Using the library today I got this error from React 15.2.1:

frontapp.min.js:59795 Warning: Unknown prop html on

tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop

Renaming the prop html to something else (content in my case) solved the issue

`onChange` is not fired if reset `html` and then input the a char same as before resetting.

The use case is like some IM app, type, send, clear the input, and type a next message.

If send an 'a', clear the input immediately. Later type an 'a', the onChange is not fired.

Code and log below.

import React, { Component } from 'react';
import ContentEditable from 'react-contenteditable';

class App extends Component {
  state = {
    html: '',
  }

  render() {
    const { html } = this.state;

    return (
      <div className="App">
        <ContentEditable
          html={html}
          onChange={e => {
            console.log('onChange', e.target.value);
            this.setState({ html: e.target.value });
          }}
        />
        <button onClick={() => {
          console.log('send', html);
          this.setState({ html: '' });
        }}>send</button>
      </div>
    );
  }
}

export default App;

selection_699

How we save and load safe text?

This component returns HTML. Is there a way to get it to return (and accept) plain text?

I don't want to save HTML to our server, because then any simple hacker can inject any HTML tags they want into this component.

Allow onBlur event

The onBlur event is now overwritten by onChange, please let onBlur be used.

How to detect keys ?

Hei!

I'm trying to figure out how to detect the enter key...
Even tried replacing evt.target.value = html instead evt.target = { value: html }

Though I'm yet to get any results... just a bunch of undefineds.

Thanks for baring with me

Manipulating the HTML leaves the first character at the end when empty

I am trying to make a rich input text field with markup auto-assigned based on the content.

As initial test I tried to wrap whatever insert within a bold tag <b> after stripping down all the eventual markup. When the element is empty and I start typing, the first character insert stays at the end of the content. Demo here: https://codepen.io/nuthinking/pen/ZoKmRx?editors=1010

I really need this library to work, any idea what could be the issue?

Thanks a lot!

New release?

Can you publish a new version of this library to npm? I am running into issues that already appear to be fixed. Thanks.

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.