npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-dnd-ax

v1.2.6

Published

React drag and drop HOC with accessibility and keyboard actions support.

Downloads

25

Readme

License: MIT

React DnD AX

Motivation

There are many great React Drag and Drop components available on Github. Such as the first search result you will get on google: React Dnd. However, to fulfill the requirements of developing a website that requires full accessibility, web and mobile supports, we still need to write our own components. Therefore, we are sharing this HOC, which provides full accessibility support, can work on mobile and desktop applications, and easy to be integrated with your existing react components.

DEMO

https://artecher.github.io/react-dnd-ax-demo/

As storybook doesn't support mobile view, please visit this site on desktop or create your own project with sources code in this repo locally. We are planning to replace storybook in the future.

Run demo locally

npm install && npm start

The browser will open automaticly and navigate to localhost:3000/ If you wanna see the Complex Example, go to src/index.js, comment line 4-5, and uncomment line 7-8

Features

  • Shipped as High Order Components (HOC) - Which means no pain to be integrated with your existing components
  • freedom on customization - Styles of the list can be fully customized
  • Perfect support for Mobile and Desktop
  • Accessibility support- User is able to work with it purely on keyboard
  • Easy and simply examples to help you adopt

Installation

npm install react-dnd-ax --save

Use a module bundler that supports either ES2016 or CommonJS (webpack, Rollup):

//  Compile ES6 with Babel
import { DragNDropContainer, DragNDropItem } from 'react-dnd-ax'

// Without ES6 compiler
var Sortable = require('react-dnd-ax')
var SortableContainer = Sortable.DragNDropContainer
var SortableItem = Sortable.DragNDropItem

If you don't like Module Bundler, you can simply load UMD and style file

<link href="react-dnd-ax/dist/umd/bundle.css" />
<script src="react-dnd-ax/dist/umd/react-dnd-ax.js"></script>

If you want to use compressed JS file (compressed by UglifyJs,no sourceMap):;

<script src="react-dnd-ax/dist/umd/react-dnd-ax.min.js"></script>

Usage

IMPORTANT!Need to import react-dnd-ax.css into your html page

run examples locally

npm install
npm run storybook

then go to http://localhost:9001 in your browser to see examples

Optionally, run examples in Docker

docker-compose up

Stop docker examples and clean up

^C
docker-compose down

Basic Example

import React from 'react'
import {Icon} from 'react-fa'

import {DragNDropContainer, DragNDropItem} from '../../react-dnd-ax'
import {basicItems} from '../data'

import '../styles/common.scss'
import './basic-example.scss'

class BasicExample extends React.Component {
  state = {
    items: basicItems,
  }

  onReorderLinks = (newItems) => {
    this.setState({
      items: [...newItems]
    })
  }

  render() {
    const BasicItem = DragNDropItem(({item, itemRef, dragPointRef}) => {
      return (
        <div
          className="item-row"
          ref={itemRef} // mandatory: put this attribute to the container element of the movable item
        >
            <span className="text">{item.text}</span>
            <button
              ref={dragPointRef} // mandatory: put this attribute to the drag handler
              className="drag-point"
              draggable // mandatory HTML attribute for drag handler
              tabIndex="0" // mandatory HTML attribute, make it possible to focus on the drag handler
              title="Drag this link to reorder the item" // AX title
            >
              <Icon name="arrows"/>
            </button>
        </div>
      )
    })

    const BasicList = DragNDropContainer((props) => {
      return (
        <div id="modules-section">
          {
            props.items.map((item, index) => {
              return <BasicItem
                item={item}
                index={index} // mandatory: give index to the DragNDropItem HOC
                key={item.id}
                preview={<div>{item.text}</div>} // customize your preview
                {...props} // mandatory: need to pass down the props
              />
            })
          }
        </div>
      )
    })

    return (
      <div id="basic-container" className="container">
        <BasicList
          items={this.state.items}
          boundingElementId="container"
          onReorderItem={this.onReorderLinks}
          scrollContainerId="basic-container"
        />
      </div>
    )
  }
}

export default BasicExample

Complex Example (integration with existing components)

import React from 'react'

import { DragNDropContainer, DragNDropItem } from '../../react-dnd-ax'
import { countries } from '../data'
import Country from './Country'

import '../styles/common.scss'
import './ComplexExample.scss'

class ComplexExample extends React.Component {
  state = {
    countries: countries,
  }

  onReorderCountries = (newOrderCountries) => {
    this.setState({
      countries: [...newOrderCountries]
    })
  }

  render() {
    const ModuleItem = DragNDropItem(Country) // Country is your existing component

    const CountryList = DragNDropContainer((props) => {
      return (
        <div>
          {
            props.items.map((country, index) => {
              return <ModuleItem
                country={country}
                index={index} // mandatory: give index to the DragNDropItem HOC
                key={country.name}
                preview={<span>{country.name}</span>} // customize your preview
                {...props} // mandatory: need to pass down the props
              />
            })
          }
        </div>
      )
    })

    return (
      <div id="complex-container" className="container">
        <CountryList
          items={this.state.countries}
          onReorderItem={this.onReorderCountries}
          scrollContainerId="complex-container"
        />
      </div>
    )
  }
}

export default ComplexExample

PropTypes

DragNDropItem

Prop | Type | Description --- | --- | --- index | number | the index value of a single item preview | React Element | the preview html element when dragging the movable item

DragNDropContainer

Prop | Type | Description --- | --- | --- items | Array | the array consists of movable items onReorderItem(reorderedItems, sourceDragItem) | Function | the callback function triggered by dropping a movable item scrollContainerId | String | the container id of the drag and drop component (usage refer to examples) boundingElementId | String | Id of anchor element for positioning drag and drop preview item if an ancestor element's styling prevents fixed position (optional)

中文文档

动机

Github 上有非常多优秀的 React DnD 的 组件,尤其是你在 google 上会遇到的第一个搜索结果:React Dnd, 但是在业务中,我相信很多开发者也遇到和我们相同的问题:那就是只需要一个可以拖动重新排序的列表,经过一段时间的调查,我们发现要满足支持多端,高度的自定义,同时还有完美的可访问性支持的组件还不存在,所以就写了这个高阶组件希望分享给有同样需求的开发者。

特性

  • 高阶组件 (HOC) - 可以和你现有的组件完美融和
  • 高度自定义 - 列表的样式和结构完全可控
  • 完美支持桌面和移动端
  • 完美支持 Accessibility(可访问性)- 可以用键盘完成一切操作
  • 简单易用,容易上手

安装

npm install react-dnd-ax --save

使用一个支持 ES2015模块 或者 CommonJs 的工具(webpack, Rollup)来引用:

//  使用 Babel 来编译 ES6
import { DragNDropContainer, DragNDropItem } from 'react-dnd-ax'

// 不使用 ES6 编译器
var Sortable = require('react-dnd-ax')
var SortableContainer = Sortable.DragNDropContainer
var SortableItem = Sortable.DragNDropItem

如果你不使用 Module Bundler, 可以直接加载 UMD 格式的文件,同时需要加载样式文件。

<link href="react-dnd-ax/dist/umd/bundle.css" />
<script src="react-dnd-ax/dist/umd/react-dnd-ax.js"></script>

如果你想使用压缩过的 JS 文件,(使用 UglifyJs 压缩,没有 sourceMap),那么可以引用:

<script src="react-dnd-ax/dist/umd/react-dnd-ax.min.js"></script>

使用

切记!将安装包里面的 react-dnd-ax.css 引入项目的html页面

本地运行例子

npm install
npm run storybook

then go to http://localhost:9001 in your browser to see examples

如果你安装了Docker,你也可以在Docker中运行例子

docker-compose up

停止Docker,并做清理

^C
docker-compose down

简单示例

import React from 'react'
import {Icon} from 'react-fa'

import {DragNDropContainer, DragNDropItem} from '../../react-dnd-ax'
import {basicItems} from '../data'

import '../styles/common.scss'
import './basic-example.scss'

class BasicExample extends React.Component {
  state = {
    items: basicItems,
  }

  onReorderLinks = (newItems) => {
    this.setState({
      items: [...newItems]
    })
  }

  render() {
    const BasicItem = DragNDropItem(({item, itemRef, dragPointRef}) => {
      return (
        <div
          className="item-row"
          ref={itemRef} // mandatory: put this attribute to the container element of the movable item
        >
            <span className="text">{item.text}</span>
            <button
              ref={dragPointRef} // mandatory: put this attribute to the drag handler
              className="drag-point"
              draggable // mandatory HTML attribute for drag handler
              tabIndex="0" // mandatory HTML attribute, make it possible to focus on the drag handler
              title="Drag this link to reorder the item" // AX title
            >
              <Icon name="arrows"/>
            </button>
        </div>
      )
    })

    const BasicList = DragNDropContainer((props) => {
      return (
        <div id="modules-section">
          {
            props.items.map((item, index) => {
              return <BasicItem
                item={item}
                index={index} // mandatory: give index to the DragNDropItem HOC
                key={item.id}
                preview={<div>{item.text}</div>} // customize your preview
                {...props} // mandatory: need to pass down the props
              />
            })
          }
        </div>
      )
    })

    return (
      <div id="basic-container" className="container">
        <BasicList
          items={this.state.items}
          boundingElementId="container"
          onReorderItem={this.onReorderLinks}
          scrollContainerId="basic-container"
        />
      </div>
    )
  }
}

export default BasicExample

复杂示例 (和已有component集成)

import React from 'react'

import { DragNDropContainer, DragNDropItem } from '../../react-dnd-ax'
import { countries } from '../data'
import Country from './Country'

import '../styles/common.scss'
import './ComplexExample.scss'

class ComplexExample extends React.Component {
  state = {
    countries: countries,
  }

  onReorderCountries = (newOrderCountries) => {
    this.setState({
      countries: [...newOrderCountries]
    })
  }

  render() {
    const ModuleItem = DragNDropItem(Country) // Country is your existing component

    const CountryList = DragNDropContainer((props) => {
      return (
        <div>
          {
            props.items.map((country, index) => {
              return <ModuleItem
                country={country}
                index={index} // mandatory: give index to the DragNDropItem HOC
                key={country.name}
                preview={<span>{country.name}</span>} // customize your preview
                {...props} // mandatory: need to pass down the props
              />
            })
          }
        </div>
      )
    })

    return (
      <div id="complex-container" className="container">
        <CountryList
          items={this.state.countries}
          onReorderItem={this.onReorderCountries}
          scrollContainerId="complex-container"
        />
      </div>
    )
  }
}

export default ComplexExample

PropTypes

DragNDropItem

属性 | 类型 | 描述 --- | --- | --- index | number | 当前可移动条目的索引值 preview | React Element | 移动条目是的预览html元素

DragNDropContainer

属性 | 类型 | 描述 --- | --- | --- items | Array | 由可移动的条目组成的数组 onReorderItem(reorderedItems, sourceDragItem) | Function | 当条目被移动时被触发的回掉函数 scrollContainerId | String | drag and drop component的container的id (具体用法见示例) boundingElementId | String | Id of anchor element for positioning drag and drop preview item if an ancestor element's styling prevents fixed position (可选) 有一些浏览器,如Chrome,当父元素有translateZ(0)样式时,会导致preview item得不到正确的y轴的值。这个参与用于修正这个问题。