shijingsh-react-native-smart-sortable-sudoku-grid

    1.0.5 • Public • Published

    react-native-smart-sortable-sudoku-grid

    npm npm npm npm

    A smart sortable sudoku grid for React Native apps. Written in JS for cross-platform support. It works on iOS and Android.

    Preview

    react-native-smart-sortable-sudoku-grid-preview react-native-smart-sortable-sudoku-grid-preview-android

    Installation

    npm install react-native-smart-sortable-sudoku-grid --save
    

    Full Demo

    see ReactNativeComponentDemos

    Usage

    Install the SortableSudokuGrid package from npm with:

    $ npm install react-native-smart-sortable-sudoku-grid --save

    Then, require it from your app's JavaScript files with:

    import SortableSudokuGrid from 'react-native-smart-sortable-sudoku-grid';

    Complete Example:

    import React, {
        Component,
    } from 'react'
    import {
        ScrollView,
        StyleSheet,
        View,
        Image,
        Text,
        TouchableOpacity,
        TouchableWithoutFeedback,
        Alert,
        Animated,
    } from 'react-native'
    
    import SortableSudokuGrid from 'react-native-smart-sortable-sudoku-grid'
    
    import image_cash from '../images/cash.png'
    import image_credit from '../images/credit.png'
    import image_transfer from '../images/transfer.png'
    import image_loan from '../images/loan.png'
    import image_charge from '../images/charge.png'
    import image_payment from '../images/payment.png'
    import image_shopping from '../images/shopping.png'
    import image_service from '../images/service.png'
    import image_donate from '../images/donate.png'
    
    import image_add from '../images/add.png'
    import image_remove from '../images/remove.png'
    import image_locked from '../images/locked.png'
    
    const dataList = [
        {
            icon: image_cash,
            title: 'cash',
        },
        {
            icon: image_credit,
            title: 'credit',
        },
        {
            icon: image_transfer,
            title: 'transfer',
        },
        {
            icon: image_loan,
            title: 'loan',
        },
        {
            icon: image_charge,
            title: 'charge',
        },
        {
            icon: image_payment,
            title: 'payment',
        },
        {
            icon: image_shopping,
            title: 'shopping',
        },
        {
            icon: image_service,
            title: 'service',
        },
        {
            icon: image_donate,
            title: 'donate',
        },
    ]
    
    const columnCount = 3
    
    export default class ThreeColumns extends Component {
    
        constructor (props) {
            super(props)
            this.state = {
                dataSource: [ ...dataList ],
                candidates: [],
                sortable: false,
                scrollEnabled: true,
                disabled: false,
                managementButtonText: 'Manage',
                opacity: new Animated.Value(0),
            }
            this._sortableSudokuGrid = null
        }
    
        render () {
            return (
                <ScrollView
                    scrollEnabled={this.state.scrollEnabled}
                    style={{marginTop: 44 + 20, }}>
                    <View
                        style={{height: 50, paddingHorizontal: 10, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }}>
                        <View style={{flex: 1, justifyContent: 'center',}}>
                            <Text>My Applications: </Text>
                        </View>
                        <TouchableOpacity
                            onPress={this._onPressManagementButton}>
                            <View style={{flex: 1, justifyContent: 'center',}}>
                                <Text>{this.state.managementButtonText}</Text>
                            </View>
                        </TouchableOpacity>
    
                    </View>
                    <SortableSudokuGrid
                        ref={ component => this._sortableSudokuGrid = component }
                        containerStyle={{ backgroundColor: '#fff',}}
                        columnCount={columnCount}
                        dataSource={this.state.dataSource}
                        renderCell={this._renderGridCell}
                        sortable={this.state.sortable}
                    />
                    <View
                        style={{height: 50, paddingHorizontal: 10, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }}>
                        <View style={{flex: 1, justifyContent: 'center',}}>
                            <Text>Candidates: </Text>
                        </View>
                    </View>
                    <SortableSudokuGrid
                        ref={ component => this._candidatesSudokuGrid = component }
                        containerStyle={{ backgroundColor: '#fff',}}
                        columnCount={columnCount}
                        dataSource={this.state.candidates}
                        renderCell={this._renderCandidateCell}
                        sortable={false}
                    />
                </ScrollView>
            )
        }
    
        _renderGridCell = (data, component) => {
            return (
                <TouchableOpacity
                    disabled={this.state.disabled}
                    style={{flex: 1, padding: 6, position: 'relative', }}
                    onPress={ this._onPressCell.bind(this, data) }>
                    <View style={{ overflow: 'hidden', backgroundColor: '#fff',
                              justifyContent: 'center', alignItems: 'center', flex: 1,
                              borderWidth: StyleSheet.hairlineWidth, borderColor: '#eee', }}>
                        <Image source={data.icon} style={{width: 30, height: 30, marginHorizontal: 10, marginBottom: 10,}}/>
                        <Text>{data.title}</Text>
                    </View>
                    <TouchableOpacity
                        disabled={!this.state.disabled}
                        style={{position: 'absolute', right: 8, top: 8, width: 30, height: 30, }}
                        onPress={this._onRemoveCellButtonPress.bind(this, component)}>
                        <Animated.View
                            style={{flex: 1, opacity: this.state.opacity, justifyContent: 'center', alignItems: 'center', }}>
                            <View
                                style={{ borderRadius: 10, borderWidth: StyleSheet.hairlineWidth, borderColor: '#FF7F7F', width: 22, height: 22, justifyContent: 'center', alignItems: 'center', overflow: 'hidden', }}>
                                <Image source={image_remove} style={{width: 20, height: 20, }}/>
                            </View>
                        </Animated.View>
                    </TouchableOpacity>
                </TouchableOpacity>
            )
        }
    
        _renderCandidateCell = (data, component) => {
            return (
                <TouchableOpacity
                    disabled={this.state.disabled}
                    style={{flex: 1, padding: 6, position: 'relative', }}
                    onPress={ this._onPressCandidateCell.bind(this, data) }>
                    <View style={{ overflow: 'hidden', backgroundColor: '#fff',
                              justifyContent: 'center', alignItems: 'center', flex: 1,
                              borderWidth: StyleSheet.hairlineWidth, borderColor: '#eee', }}>
                        <Image source={data.icon} style={{width: 30, height: 30, marginHorizontal: 10, marginBottom: 10,}}/>
                        <Text>{data.title}</Text>
                    </View>
                    <TouchableOpacity
                        disabled={!this.state.disabled}
                        style={{position: 'absolute', right: 8, top: 8, width: 30, height: 30, }}
                        onPress={this._onRemoveCandidatesCellButtonPress.bind(this, component)}>
                        <Animated.View
                            style={{flex: 1, opacity: this.state.opacity, justifyContent: 'center', alignItems: 'center', }}>
                            <View
                                style={{ borderRadius: 10, borderWidth: StyleSheet.hairlineWidth, borderColor: '#5CC46C', width: 22, height: 22, justifyContent: 'center', alignItems: 'center', overflow: 'hidden', }}>
                                <Image source={image_add} style={{width: 20, height: 20, }}/>
                            </View>
                        </Animated.View>
                    </TouchableOpacity>
                </TouchableOpacity>
            )
        }
    
        _onPressCell = (data) => {
            Alert.alert('clicked grid cell -> ' + data.title)
        }
    
        _onPressCandidateCell = (data) => {
            Alert.alert('clicked candidate cell -> ' + data.title)
        }
    
        _onPressManagementButton = () => {
            let scrollEnabled = !this.state.scrollEnabled
            let disabled = !this.state.disabled
            let managementButtonText = this.state.managementButtonText == 'Manage' ? 'Complete' : 'Manage'
            let sortable = !this.state.sortable
            let opacity = sortable ? new Animated.Value(1) : new Animated.Value(0)
            this.setState({
                scrollEnabled,
                managementButtonText,
                disabled,
                sortable,
                opacity,
            })
            if (!sortable) {
                let sortedDataSource = this._sortableSudokuGrid.getSortedDataSource()
                //console.log(`_onPressManagementButton get sorted/added/removed DataSource`)
                //console.log(sortedDataSource)
                let candidateDataSource = this._candidatesSudokuGrid.getSortedDataSource()
                //console.log(`_onPressManagementButton get sorted/added/removed candidateDataSource`)
                //console.log(candidateDataSource)
            }
        }
    
        _onRemoveCellButtonPress = (component) => {
            let cellIndex = this._sortableSudokuGrid._cells.findIndex((cell) => {
                return cell.component === component
            })
    
            this._sortableSudokuGrid.removeCell({
                cellIndex,
                callback: (removedDataList) => {
                    if(removedDataList.length > 0) {
                        let data = removedDataList[0]
                        this._candidatesSudokuGrid.addCell({
                            data,
                        })
                    }
                }
            })
        }
    
        _onRemoveCandidatesCellButtonPress = (component) => {
            let cellIndex = this._candidatesSudokuGrid._cells.findIndex((cell) => {
                return cell.component === component
            })
    
            this._candidatesSudokuGrid.removeCell({
                cellIndex,
                callback: (removedDataList) => {
                    if(removedDataList.length > 0) {
                        let data = removedDataList[0]
                        this._sortableSudokuGrid.addCell({
                            data,
                        })
                    }
                }
            })
        }
    
    }

    Props

    Prop Type Optional Default Description
    rowWidth number Yes deviceWidth determines the width of a row.
    rowHeight number Yes deviceWidth determines the height of a row.
    columnCount number No determines how many columns a row contains.
    dataSource array No determines the datasource of grid
    renderCell func No A function that returns the grid cell component.
    containerStyle style Yes see react-native documents
    sortable bool Yes determines if the gird cell can be sortable

    Method

    • addCell({ data, callback, }): add a new cell with data to grid
    • removeCell({ cellIndex, callback, }): remove a cell from grid by cellIndex
    • getSortedDataSource: return a sorted(added/removed) dataSource

    Install

    npm i shijingsh-react-native-smart-sortable-sudoku-grid

    DownloadsWeekly Downloads

    1

    Version

    1.0.5

    License

    MIT

    Unpacked Size

    49.4 kB

    Total Files

    8

    Last publish

    Collaborators

    • liukefu