Skip to content

Commit

Permalink
feat(): Added Sortable
Browse files Browse the repository at this point in the history
  • Loading branch information
ykadosh committed Jun 14, 2021
1 parent 7e92cdc commit ab55f99
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/components/Sortable/Item/Item.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React, {useContext, useRef} from 'react';
import cls from 'classnames';
import Draggable from 'components/Draggable';
import Context from '../Sortable.context';
import {propTypes, defaultProps} from './Item.props';
import './Item.scss';

const Item = ({children, index, ...props}) => {
const ref = useRef();
const context = useContext(Context);
const source = Draggable.useSource({
data: {index},
onBeginDrag: () => {
context.sort.current.from = index;
context.sort.current.displacement = ref.current.getBoundingClientRect().height;
context.onBeginSort();
},
onDrop: () => {
context.sort.current = {};
context.onEndSort();
},
});
const target = Draggable.useTarget({
data: {index},
onBeginHover: source => {
// When swapping, the dragged element moves below the clone, triggering a 'mouseover'
// event on itself. To prevent an infinite loop, we verify that the dragged item is not the target.
if (source.data.index !== index && context.sort.current.to !== index) {
context.sort.current.to = index;
context.onSort(context.sort.current)
context.sort.current.from = index;
}
},
});
const combined = Draggable.useCombined(source, target);
return (
<Draggable {...props} {...combined} className={cls('sortable-item', props.className)} ref={ref}>
{children}
</Draggable>
);
};

Item.propTypes = propTypes;
Item.defaultProps = defaultProps;

export default Item;
26 changes: 26 additions & 0 deletions src/components/Sortable/Item/Item.props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {number, node} from 'prop-types';

export const propTypes = {
children: node,
index: number.isRequired,
};

export const defaultProps = {
children: null,
};
3 changes: 3 additions & 0 deletions src/components/Sortable/Item/Item.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.sortable-item {
transition: transform 2s ease-out;
}
19 changes: 19 additions & 0 deletions src/components/Sortable/Sortable.context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React from 'react';

export default React.createContext({});
40 changes: 40 additions & 0 deletions src/components/Sortable/Sortable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React, {useMemo, useRef} from 'react';
import Context from './Sortable.context';
import {propTypes, defaultProps} from './Sortable.props';

export const Sortable = ({children, onBeginSort, onSort, onEndSort}) => {
const context = useRef({});
const sort = useRef({});
context.current = {onBeginSort, onSort, onEndSort};
return (
<Context.Provider value={useMemo(() => ({
sort,
onBeginSort: (...args) => context.current.onBeginSort(...args),
onSort: (...args) => context.current.onSort(...args),
onEndSort: (...args) => context.current.onEndSort(...args),
}), [])}>
{children}
</Context.Provider>
);
};

Sortable.propTypes = propTypes;
Sortable.defaultProps = defaultProps;

export default Sortable;
32 changes: 32 additions & 0 deletions src/components/Sortable/Sortable.props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {func, node} from 'prop-types';
import {noop} from 'utility/memory';

export const propTypes = {
children: node,
onBeginSort: func,
onSort: func,
onEndSort: func,
};

export const defaultProps = {
children: null,
onBeginSort: noop,
onSort: noop,
onEndSort: noop,
};
22 changes: 22 additions & 0 deletions src/components/Sortable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Sortable from './Sortable';
import Item from './Item/Item';

Sortable.Item = Item;

export default Sortable;
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export {default as Draggable} from './Draggable';
export {default as Movable} from './Movable';
export {default as Resizable} from './Resizable';
export {default as Scrollable} from './Scrollable';
export {default as Sortable} from './Sortable';
export {default as Stackable} from './Stackable';
export {default as Scalable} from './Scalable';
export {default as Pannable} from './Pannable';
Expand Down

0 comments on commit ab55f99

Please sign in to comment.