Git Product home page Git Product logo

simple-keyboard's People

Contributors

armno avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar entkenntnis avatar github-actions[bot] avatar hodgef avatar maddeveloper avatar mkusher avatar patrickjholloway avatar simon04 avatar steinrobert avatar tjallingt avatar vickylance avatar xcrossd 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

simple-keyboard's Issues

Navigation through keys within keyboard

Is your feature request related to a problem? Please describe.
No.

Describe the solution you'd like
I would like to be able to toggle to a mode where I can navigate through the keys in the keyboard using some configurable input. For example, a cursor would start at the top-left most key in the keyboard [0,0]. Pressing the right arrow key on the physical keyboard as an input (or any other configurable input) would move the cursor one column to the right to [0,1]. For example, on a QWERTY layout: if cursor is on 's', moving right will move cursor to 'd'.

Describe alternatives you've considered
The Motte keyboard offers a similar feature: https://jsfiddle.net/Mottie/c6ftvy7r/

Additional context
image

Adding empty rows to layout

Is your feature request related to a problem? Please describe.
I am trying to create a vertical square-like keyboard with simple-keyboard, it involves creating a lot of empty space between each letter. I want simple-keyboard to register those as empty, disabled buttons but it's registering each space as a button.

Describe the solution you'd like
I tried using display: { ' ':'' }. However it didn't work.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Touch down makes input loose focus

Simple-keyboard version
2.21.0

Describe the bug
When using the preventMouseDownDefault property together with useTouchEvents, the input field looses focus when typing on the keyboard. I've attached listeners for focus and blur on my input to toggle visibility of the keyboard. Whenever the textfield looses focus the keyboard hides. It works as expected works correctly with mouse events.

Left and Right Braces do not trigger onChange event

I'm noticing this in the demo as well, but when you type a left or right brace, the onChange callback does not fire. We have a keyboard config setup such as this:

/*
              * u20AC=€ (euro) u00A3=£ (pound)
              * u00A5=¥ (yen) u00A7=§ (section [for law])
              * u007B == {  u007D == } 
*/
 symbols: [
            '@gmail.com @yahoo.com @outlook.com @hotmail.com @mail.com @aol.com',
            '1 2 3 4 5 6 7 8 9 0 {bksp}',
            '\u20AC \u00A3 \u00A5 _ ^ [ ] \u007B \u007D {enter}',
            '{numbers} \u00A7 | ~ ... \\ < > ! ? {numbers}',
            '{abc} .com {space} {abc}'
        ]

Only the button press event fires when you type either the left or right brace, so in that callback, I explicitly check for the values, and reset the simple keyboard input and the value of my text box.

if (button === '\u007B' || button === '\u007D') {
    const newValue = `${keyboard.getInput()}${button}`;
    keyboard.setInput(newValue);
    emailInput.setValue(newValue);
}

The above solution works for my purposes, but I'm assuming this is a bug in the library. I'll continue to investigate to see where there's an issue.

After deleting first character cursor jumps to an end

Describe the bug

  1. Type text in to input for example "123456789"
  2. Put cursor between '3' and '4'
  3. Hit backspace till it deletes '1'
  4. Hit backspace one more time

Expected:
Cursor should have stayed at start of input box and delete nothing

Actual:
It deletes 9

console.log on input focus

Hey,

Firstly, thanks for sharing this awesome library. Very nice keyboard.

I think there might be a console log in the code. Every time I focus on an input Im seeing a log in the console as screenshot shows. Would you be able to remove this? Thanks.
image

Customization of keyboard buttons spacing and large space button

Is your feature request related to a problem? Please describe.
No, i want customize the layout of keyboard [Angular].

Describe the solution you'd like
I want to achieve keyboard same attached image below.

Describe alternatives you've considered
I can change button style by myself but problem is i want larger width space button and other key buttons height and width should be same and also spacing need to be same as attached screenshot.

Stackblitz demo

Additional context

Keyboard I want

Screen Shot 2019-04-16 at 6 37 42 PM

Keyboard looks right now

Screen Shot 2019-04-17 at 10 13 34 AM

Caps and Shift buttons trigger hide

Simple-keyboard version
2.13.2

Describe the bug
I'm following the sample, here, to show/hide the keyboard on input focus.

I notice that when the Caps or Shift buttons are clicked, the keyboard is hidden. I'm guessing this is some behavior related to switching out the keyboard layout when those buttons are clicked, but I would expect that the keyboard would remain visible.

Phystical Keyboard input for Arabic layout

Hi,
I am having an issue which is that I would like to be able to type on my physical keyboard and have the keys trigger click events on the virtual keyboard - this is for typing on an american keyboard and having the input field be in Arabic.

I've found the physicalKeyboardHighlight and actually it doesn't seem to highlight any of my letter keys (using Chrome on Linux). I've also found the physicalKeyboardInterface method, and used the initKeyboardListener, however this does not appear to do anything. I don't know if that's because there is an issue as described with highlights issue, or if I am using it wrong.

Thanks!!

[Documentation update] CSS is not loaded in Angular6+

Simple-keyboard version
2.14.2

Bug
Following this reddit thread, some users (including me) reported that CSS is not loaded in Angular 6+ using an import statement to load CSS file.

Solution
Just don't import the css using "import 'simple-keyboard/build/css/index.css';" in the component file. Instead, open angular.json at the root of your project, find the styles array, and add "node_modules/simple-keyboard/build/css/index.css" to it.

It seems it's a new way to load CSS files in new angular. Doing this, I had no further problems with CSS loading.

Max Length

Hi thanks for the great work you have done..

how to limit the number of character in the input. Normally we will use maxlength attribute. But in this case maxlength is does not working..

And also is it possible to move to next input box by clicking at tab or enter button?

cheers

zul

KeyboardLayoutObject type not allowing custom layouts

Simple-keyboard version
2.20.3

Describe the bug
In your demo example, you add a custom layout name to the layout object. However, the interface does not support it, and is impossible to extend, as it is not exported.

  interface KeyboardLayoutObject {
    default: string[];
    shift?: string[];
  }

Perhaps it should be like this?

 interface KeyboardLayoutObject {
    default: string[];
    shift?: string[];
    [key: string]: string[];
  }

cursor position

Simple-keyboard version
"react-simple-keyboard": "^1.21.2"

Describe the bug
I have added logic to keep track of cursor position. This works fine. But have two problems.

  1. if you use the js keyboard to type abc and move the cursor to be behind a. Click backspace. The cursor is moved to the back of bc. This is the expected behaviour. Now any input from the js keyboard is still typed behind the beginning of the bc. Typing 1. Expected should be bc1. Actual is 1bc. The cursor is currently positioned at the back of bc. It seems like the keyboard cursor position have not moved. This only happens when removing the first charactor.

  2. Referring to the unit test below. It seems like the keyboard cursor did not move.

// unit test
it('should type on the onscreen keyboard with correct cursor position', () => {
    const mountNode = document.createElement('div');
    document.body.appendChild(mountNode);

    const component = mount(<Input {...defaultProps} />, {attachTo: mountNode});

    const input = document.querySelector('input');
    document.querySelector('[data-skbtn="1"]').click();
    document.querySelector('[data-skbtn="2"]').click();
    document.querySelector('[data-skbtn="3"]').click();
    document.querySelector('[data-skbtn="4"]').click();

    expect(input.selectionStart).toBe(4);
    expect(input.value).toBe('1234');
    document.querySelector('[data-skbtn="{bksp}"]').click();
    expect(input.selectionStart).toBe(3);
    expect(input.value).toBe('123');

    input.setSelectionRange(1, 1);
    document.querySelector('[data-skbtn="a"]').click();
    expect(input.selectionStart).toBe(2);
    // currently this cannot be tested. It works fine on screen.
    // expect(input.value).toBe('1a23');
    component.unmount();
});

   import React from 'react';
import * as PropTypes from 'prop-types';
import Keyboard from 'react-simple-keyboard';
import classNames from 'classnames';
import Portal from '@material-ui/core/Portal';
import 'react-simple-keyboard/build/css/index.css';
import styles from './Input.module.scss';

class Input extends React.PureComponent {
    static propTypes = {
        placeholder: PropTypes.string.isRequired,
        onChange: PropTypes.func.isRequired,
        onFocus: PropTypes.func,
        value: PropTypes.string,
        className: PropTypes.string,
        enableVirtualKeyboard: PropTypes.bool,
    };

    static defaultProps = {
        enableVirtualKeyboard: false,
    };

    state = {
        layoutName: 'default',
        value: '',
        showKeyboard: false,
    };

    keyboardRef = React.createRef(); // the keyboard div

    simpleKeyboardRef = React.createRef(); // the keyboard component

    inputRef = React.createRef(); // the input element

    showKeyboard = enable => {
        if (!this.props.enableVirtualKeyboard) return;

        if (this.state.showKeyboard !== enable) {
            this.setState({showKeyboard: enable});
            if (!enable) {
                window.removeEventListener('mousedown', this.handleWindowMousedown);
            }
        }
    };

    handleWindowMousedown = e => {
        // Clicks outside the keyboard should close the keyboard except the input element
        if (
            !(this.keyboardRef.current && this.keyboardRef.current.contains(e.target)) &&
            !this.inputRef.current.contains(e.target)
        ) {
            this.showKeyboard(false);
        }
    };

    componentWillUnmount() {
        window.removeEventListener('mousedown', this.handleWindowMousedown);
    }

    onChangeKeyboard = input => {
        let inputValue = input;
        // physical keyboard give input as an event object
        if (typeof input === 'object') {
            inputValue = input.target.value;
        }

        const inputElement = this.inputRef.current;

        // get the current cursor position and increment to the next position
        let cursorNextPosition =
            inputElement.selectionStart + inputValue.length - this.state.value.length;
        // if the next cursor is 0 at the beginning return the cursor to the back of the input
        cursorNextPosition = !cursorNextPosition ? inputValue.length : cursorNextPosition;

        this.setState({value: inputValue}, () =>
            this.simpleKeyboardRef.keyboard.setInput(inputValue)
        );
        this.props.onChange(inputValue);

        // only adjust cursor when input is from virtual keyboard
        if (typeof input !== 'object') {
            inputElement.focus();
            inputElement.setSelectionRange(cursorNextPosition, cursorNextPosition);
        }
    };

    componentDidUpdate(prevProps) {
        // parent clearing the input value
        if (this.props.value !== prevProps.value && this.props.value === '') {
            this.onChangeKeyboard('');
        }
    }

    onKeyPress = button => {
        // handle the shift and caps lock buttons
        if (button === '{shift}' || button === '{lock}') this.handleShift();
    };

    handleShift = () => {
        const layoutName = this.state.layoutName;

        this.setState({
            layoutName: layoutName === 'default' ? 'shift' : 'default',
        });
    };

    render() {
        const keyboardClasses = classNames(styles.keyboard, {
            [styles.keyboardHide]: !this.state.showKeyboard, // defaults to hide
        });

        return (
            <React.Fragment>
                <input
                    ref={this.inputRef}
                    className={this.props.className}
                    value={this.state.value}
                    placeholder={this.props.placeholder}
                    onChange={this.onChangeKeyboard}
                    onFocus={e => {
                        this.props.onFocus(e.target.value);
                        this.showKeyboard(true);
                    }}
                />
                <Portal>
                    <div ref={this.keyboardRef} className={keyboardClasses}>
                        <Keyboard
                            ref={r => {
                                this.simpleKeyboardRef = r;
                            }}
                            layoutName={this.state.layoutName}
                            onChange={this.onChangeKeyboard}
                            onKeyPress={this.onKeyPress}
                            preventMouseDownDefault
                            stopMouseDownPropagation
                            useMouseEvents
                            useButtonTag
                            beforeRender={() =>
                                window.addEventListener('mousedown', this.handleWindowMousedown)
                            }
                            layout={{
                                default: [
                                    '` 1 2 3 4 5 6 7 8 9 0 - = {bksp}',
                                    '{tab} q w e r t y u i o p [ ] \\',
                                    "{lock} a s d f g h j k l ; ' {enter}",
                                    '{shift} z x c v b n m , . / {shift}',
                                    '@ {space}',
                                ],
                                shift: [
                                    '~ ! @ # $ % ^ & * ( ) _ + {bksp}',
                                    '{tab} Q W E R T Y U I O P { } |',
                                    '{lock} A S D F G H J K L : " {enter}',
                                    '{shift} Z X C V B N M < > ? {shift}',
                                    '{space}',
                                ],
                            }}
                        />
                    </div>
                </Portal>
            </React.Fragment>
        );
    }
}

export default Input;

types

[ts]
Could not find a declaration file for module 'simple-keyboard'. 'd:/.../node_modules/simple-keyboard/build/index.js' implicitly has an 'any' type.
Try npm install @types/simple-keyboard if it exists or add a new declaration (.d.ts) file containing declare module 'simple-keyboard';

How can I enable caret ?

Hi,
I see some caret implementation in the code but I don't know how to handle the caret or at least show it to the users.
Thanks.

Add Chinese mode with pinyin

Is your feature request related to a problem? Please describe.
I can't add some Chinese words

Describe the solution you'd like
Add the options to choose the words or phrase.

Describe alternatives you've considered
no

Additional context
no

Backspace always deletes last character

Backspace key is always deleting last character.
Steps to reproduce:

'|' is showing cursor position

Type few characters for example - "REACT|"
move cursor in between some where - for example - "REA|CT"
Press backspace - it deletes 'T' rather than 'A'

Input value not visible when text is longer than the element width

Simple-keyboard version
2.21.0

Describe the bug
When typing some long content inside a small input field, once the input is full with content for the current width, you cannot see what you are typing. The expected behaviour should be like the normal input where the text scrolls once you reach the end on the field so you can actually see the characters you type in.

I made an example code here, just try to write a long text with the simple keyboard, and you will no longer see what you type --> https://codesandbox.io/s/simplekeyboardnpmdemos-jydqh

Use touch events

I'm actually working on adding an option useTouchEvents, because I need it for my project. Are you interested to see it as PR?

Remove react peer dependency

The package.json specifies react as a peer dependency but it's my understanding the vanillaJS version shouldn't depend on it correct?

Keyboard numbers vs. number pad numbers

Hello, we have a "PIN pad" and are trying to figure out how we can map the normal keyboard number keys and the number pad keys together so that they will both highlight the same simple-keyboard key.

For example, if we use the {numpad1} key in simple-keyboard, it only highlights when using the number pad key, but not the "1" key on the keyboard. And vice versa, if we use the 1 key, only the "1" key on the keyboard will highlight, but not the number pad key.

Is there a configuration item that I have missed, or something that I can do to have this type of function?

Thank you!

Can not include multiple keyboards in an Angular component

Simple-keyboard version
2.14.3

Describe the bug
In Angular 6, when trying to include multiple keyboards in a component (embedding simple keyboard as a component itself), only the first one is displayed/working.
Here is a minimal Github project that shows the issue: https://github.com/ddahan/pockey

Screenshots

image

Debug

image

As you can see, the first app-simple-component div contains a keyboard html content, but the second div contains nothing.

Negative, Floating number value in number type field

Simple-keyboard version
v2.13.4

Describe the bug
I tried to put a negative or floating point number in a number type input field, when I put - or .(for example only -, or only 2.), the input field comes empty.

Also if i enter a negative number(lets say -9) and try to use backspace, I can't remove that character. Seems only work around is to define that input as text field.

Please let me know any solution.

Cursor position in Edge browser for a touch screen device

Simple-keyboard version
2.15.2

Describe the bug
On a touch device in Edge browser, there is an issue with synchronizing the caret position. The problem is that Edge doesn't seem to allow placing the caret by clicking somewhere within the bounds of the text, but allows the user to drag the caret cursor. This 'dragging' doesn't fire touchend event, so the input's cursor and virtual keyboard caret go out of sync (the caretEventHandler is not executed). Does anyone know if this dragging behaviour in Edge (on touch device) can be prevented or changed to allow positioning within the text with a simple touch or if there is some Edge specific event for dragging the cursor and calliing caretEventHandler in it ?

Does the keyboard has a show/hide function?

Hi, I very love your library. It's easy to use and simple. Once I tried it, I fund I couldn't hide the keyboard. I would like to open the keyboard when people are clicking on the text box and when they finish typing, they just click on the outside and dismiss the keyboard

Input loses focus & cursor on simple-keyboard keypress

Using simple-keyboard v2.6.8. Testing in Chrome 70.0.3538.77 (Official Build) (64-bit) on macOS 10.12.6.

When selecting a text input, it gets a CSS :focus selector. When interacting with the keyboard to enter text into the input field, the keyboard steals focus and the :focus selector and cursor both disappear.

image
image

Sandbox example

Styling buttons

Hi. Can we use theme to style individual buttons? I've been unable to do so or to target the buttons themselves, and I'd love to make those buttons taller, adjust padding, etc. Thanks!

Angular tests fail: Error: KEYBOARD_DOM_ERROR

Hi,
the simple keyboard works very good, but unfortunately now all tests of components that use it fail like this:

WARN: '".simple-keyboard" was not found in the DOM.'
HeadlessChrome 72.0.3626 (Mac OS X 10.14.3) RegistrationComponent should create FAILED
Error: KEYBOARD_DOM_ERROR

Is there a good solution to this?

[TS] Property 'shift' of type 'string[] | undefined' is not assignable to string index type 'string[]

Simple-keyboard version
"version": "2.21.1",

Describe the bug
Getting type-error in a typescript environment:

ERROR in .../node_modules/simple-keyboard/build/index.d.ts
4:5 Property 'shift' of type 'string[] | undefined' is not assignable to string index type 'string[]'.
    2 |   interface KeyboardLayoutObject {
    3 |     default: string[];
  > 4 |     shift?: string[];
      |     ^
    5 |     [key: string]: string[];
    6 |   }
    7 | 

making shift not optional removes the error - but I don't know if this is the best or even correct way to go.

Custom buttons? '{close}': '↓'

Just wondering if this the correct way to make custom buttons since it wasn't documented.

const keyboardLayout = {
      default: [
        '1 2 3 4 5 6 7 8 9 0 - = {bksp}',
        'Q W E R T Y U I O P [ ] \\',
        "A S D F G H J K L ; ' {enter}",
        'Z X C V B N M , . /',
        '{space} {close}',
      ],
    };


const keyboardDisplay = {
'{close}': '↓',
}

Keyboard integration

It would be nice to add keyup even listeners for development so we can quickly type stuff without having to press it.

If you have a readOnly input field and you have keyup even listener on the page you still may want to have the field change by injecting the e.key onto the component. right now all logic is handled internally and the onChange event changes the input field. Would be nice to add a e.key in a prop

Add option for event to keep focus on input field

Is your feature request related to a problem? Please describe.
Clicking a button makes the browser focusing the button - the focus on the input field gets lost

Describe the solution you'd like
It would be nice to add an option to keep the focus on the input field. This can be achieved by using the mouse down event in combination with preventDefault().

Additional context
Pretty similar to the issue addressed in #14. I could help with the implementation if you would consider this as a good new feature :)
Here is an example:
https://jsfiddle.net/m4a67w1u/

Quickly typing on iPads.

This is probably more an issue of your demo and the documentation than of the library: if you quickly type on an iPad there is a high chance you will trigger a double tap zoom, which is built into mobile safari. So on the page, zooming should probably be disabled for the keyboard to be useful on an iPad.

But great library!

Input isnt validated in Angular forms

Simple-keyboard version
Running 2.20.3

I have noticed that when using Angular form validation that even though the input does show (visually), the form.controls value and Angular validation (like ng-invalid if a field is set to required) do not update.

If you type into an input with the virtual keyboard and inspect the element the ng-reflect-model doesnt update.

This can be replicated within the simple-keyboard Angular demo in codesandbox.io. Importing FormModule in app.module.ts and NgForm in your component and creating a basic template driven form.

Any idea on a workaround for this? Forcing the form.controls to get the value doesn't work because the value still appears to be empty.

Thanks.

[Feature] [Build] Non-minified Build Files

Would be nice if non-minified files (simple-keyboard.js, simple-keyboard.css) were available as well as the minified versions provided in /build

Use-case: people who have their own project build steps that bundle / minify code don't necessarily want to use the already minified files; and having non-minified files are much easier to develop with / debug etc..

(Note: I tried un-minifying from index.js and index.js.map, but ended up essentially back to the development source code / modules. Would be great if the simple-keyboard.js had all the required JS in a single file, but just not minified...)

Problem to run angular project with simple-keyboard

What I did was execute "npm install simple-keyboard --save"

and after I ran my app I received this erro:

ERROR Failed to compile with 35 errors 3:49:41 PM

These dependencies were not found:

  • child_process in ./node_modules/protractor/built/runner.js, ./node_modules/protractor/built/debugger.js and 4 others
  • fs in ./node_modules/blocking-proxy/built/lib/webdriver_logger.js, ./node_modules/fs.realpath/index.js and 21 others
  • net in ./node_modules/https-proxy-agent/index.js, ./node_modules/protractor/built/debugger.js and 1 other
  • repl in ./node_modules/protractor/built/debugger.js
  • tls in ./node_modules/https-proxy-agent/index.js

To install them, you can run: npm install --save child_process fs net repl tls

This relative module was not found:

  • ./lib-cov/SauceLabs in ./node_modules/saucelabs/index.js

Tabbed/spatial navigation focus lost

I'd like to use this keyboard when mouse is not available (e.g. keyboard, controller, remote control only). Im currently trying to combine this library with this spatial navigation library. That works great, except onClick the key loses its focus.

I've read the source, and it doesn't look like you're rerendering the DOM every press, so do you have any idea what could be causing this?

I'm using this library with react-simple-keyboard by the way, but since that React Component is only some small wrapper for this library, I'm asking here :)

My current options are

      useButtonTag={true}
      preventMouseDownDefault={true}

Module Parse Failing during Production Build

Hi all-

I'm using the on-screen keyboard for a project I've been working on that will be displayed on a touch screen monitor in the cafeteria at my company for employees to enter in their e-mail address and send themselves an email with some info about various topics. I built this web app using Ionic 4 and am running into an issue while building a production version of the application.

The error I'm seeing is as follows:
Error: ./node_modules/simple-keyboard/build/css/index.css Module parse failed: Unexpected token (12:10) You may need an appropriate loader to handle this file type.

I've done some messing around myself and can't seem to figure out the issue. Has anyone seen this issue thus far?

Thanks all,
-Mike

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.