This repository has been archived by the owner on Oct 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(drag-and-drop): component implementation (#603)
* feat(chrome-name): component prep for the new editable title * feat(chrome-title): include interaction handlers * feat(editable-title): extract component from preview tile * feat(editable-title-component): implementation and integration * feat(editable-title): implementation of the editable title container * chore(general): fix lint errors from origin * fix(editable-title): rename the state enum : * fix(editable-title): include data-attr directly during rendering * chore(editable-tigle): rename the editable-title-state enum * fix(editable-title): remove fontSize props * feat(editable title): include title type enumerable * chore(editable-title): extract dinamic styled into own functions * chore(page-tile): remove unnecessary HTML and styling * fix(editable-title): remove text truncation on input (edit mode) * fix(editable-container): move global state into an internal state * fix: allow primary and secondary type * fix(editable-title): include required category property * chore(types): include editable title type in the model types * fix(editable-title): save name edited name on blur * feat(drag-area): include component * feat(drag-area): inlude component methods * feat(page-tile): adjustments for drag and drop implementation * chore(utils): implement utils module for reusability * feat(drag-area): include componentsnecessary event handler * feat(element-list): include drag area component * feat(page-list-container): convert funtional component into class * feat(drag-area): include dropt target signal in the component * feat(page-tile): include page tile model * feat(page-tile): WIP create a page tile store * fix(page-tile): remove page tile model and store * feat(page-list): include drag and drop functionality * feat(page-list-container): save reorder page tiles ; * feat(page-list-container): implement drag and drop functionality * feat(page-order): include undo after action * chore(container): remove unused comments * feat(page-order): include states for the page drop index * feat(page-order): highlight styling adjustment * fix(project): dont't remove pages from internal model on reArrangePagesIndex * fix(element-list): fix drag & drop on element list * refactor(drag-area): remove unnecessary props * refactor(drag-element): include anchors interface * refactor(drag-area): include a unnified interface for the data attr ; * refactor(utils): include all helpers in a single place * refactor(drag-area): include getDragAreaAnchors methods
- Loading branch information
1 parent
14a5706
commit f2f6c3c
Showing
24 changed files
with
644 additions
and
305 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import * as Model from '../model'; | ||
|
||
export function calculateDropIndex(init: { | ||
dragged: Model.Element; | ||
target: Model.Element; | ||
}): number { | ||
const { dragged, target } = init; | ||
|
||
// We definitely know the drop target has a parent, thus an index | ||
const newIndex = target.getIndex() as number; | ||
|
||
// The dragged element is dropped into another | ||
// leaf list than it was dragged from. | ||
// True for (1) new elements, (2) elements dragged to other parents | ||
if (dragged.getContainer() !== target.getContainer()) { | ||
return newIndex; | ||
} | ||
|
||
// If the dragged element has a parent, it has an index | ||
const currentIndex = dragged.getIndex(); | ||
|
||
// The dragged element is dropped in the same leaf | ||
// list as it was dragged from. | ||
// Offset the index by the element itself missing from the new list. | ||
if (newIndex > currentIndex) { | ||
return newIndex - 1; | ||
} | ||
|
||
return newIndex; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
export * from './compute-difference'; | ||
export * from './drag-and-drop'; | ||
export * from './ensure-array'; | ||
export * from './guess-name'; | ||
export * from './noop'; | ||
export * from './parse-json'; | ||
export * from './to-json'; | ||
export * from './set-search'; | ||
export * from './target'; | ||
export * from './to-json'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import * as Model from '../model'; | ||
import * as Store from '../store'; | ||
import * as Components from '../components'; | ||
|
||
export function above(node: EventTarget, selector: string): HTMLElement | null { | ||
let el = node as HTMLElement; | ||
let ended = false; | ||
|
||
while (el && !ended) { | ||
if (el.matches(selector)) { | ||
break; | ||
} | ||
|
||
if (el.parentElement !== null) { | ||
el = el.parentElement; | ||
} else { | ||
ended = true; | ||
break; | ||
} | ||
} | ||
|
||
return ended ? null : el; | ||
} | ||
|
||
export function pageFromTarget( | ||
target: EventTarget, | ||
store: Store.ViewStore | ||
): Model.Page | undefined { | ||
const el = above(target, `[${Components.PageAnchors.page}]`); | ||
if (!el) { | ||
return; | ||
} | ||
const pageId = el.getAttribute(Components.PageAnchors.page); | ||
|
||
if (typeof pageId !== 'string') { | ||
return; | ||
} | ||
|
||
const page = store.getPageById(pageId); | ||
|
||
if (!page) { | ||
return; | ||
} | ||
|
||
return page; | ||
} | ||
|
||
export function elementFromTarget( | ||
target: EventTarget, | ||
options: { sibling: boolean; store: Store.ViewStore } | ||
): Model.Element | undefined { | ||
const el = above(target, `[${Components.ElementAnchors.element}]`); | ||
|
||
if (!el) { | ||
return; | ||
} | ||
|
||
const id = el.getAttribute(Components.ElementAnchors.element); | ||
|
||
if (typeof id !== 'string') { | ||
return; | ||
} | ||
|
||
const element = options.store.getElementById(id); | ||
|
||
if (!element) { | ||
return; | ||
} | ||
|
||
return options.sibling ? element.getParent() : element; | ||
} | ||
|
||
export function elementContentFromTarget( | ||
target: EventTarget, | ||
options: { store: Store.ViewStore } | ||
): Model.ElementContent | undefined { | ||
const el = above(target, `[${Components.ElementAnchors.content}]`); | ||
|
||
if (!el) { | ||
return; | ||
} | ||
|
||
const id = el.getAttribute(Components.ElementAnchors.content); | ||
|
||
if (typeof id !== 'string') { | ||
return; | ||
} | ||
|
||
return options.store.getContentById(id); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import * as React from 'react'; | ||
import DemoContainer from '../demo-container'; | ||
|
||
import { DragArea, DragAreaAnchors } from './index'; | ||
|
||
export const DemoDragArea: React.SFC<{}> = (): JSX.Element => ( | ||
<DemoContainer> | ||
<DragArea | ||
anchors={{ | ||
[DragAreaAnchors.element]: '12343', | ||
[DragAreaAnchors.content]: '11111' | ||
}} | ||
onDragStart={e => e} | ||
onDragLeave={e => e} | ||
onDragOver={e => e} | ||
onDrop={e => e} | ||
onDragEnter={e => e} | ||
> | ||
<div draggable>Drag Area Element</div> | ||
</DragArea> | ||
</DemoContainer> | ||
); | ||
|
||
export default DemoDragArea; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import * as React from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
export enum DragAreaAnchors { | ||
element = 'data-id', | ||
content = 'data-content-id' | ||
} | ||
|
||
export interface DragAreaAnchorProps { | ||
[DragAreaAnchors.element]: string; | ||
[DragAreaAnchors.content]: string; | ||
} | ||
|
||
export interface DragAreaProps { | ||
anchors: DragAreaAnchorProps; | ||
onDragEnter: React.DragEventHandler<HTMLElement>; | ||
onDragStart: React.DragEventHandler<HTMLElement>; | ||
onDragLeave: React.DragEventHandler<HTMLElement>; | ||
onDragOver: React.DragEventHandler<HTMLElement>; | ||
onDrop: React.DragEventHandler<HTMLElement>; | ||
onBlur?: React.FocusEventHandler<HTMLElement>; | ||
onChange?: React.FormEventHandler<HTMLElement>; | ||
onClick?: React.MouseEventHandler<HTMLElement>; | ||
onContextMenu?: React.MouseEventHandler<HTMLElement>; | ||
onKeyDown?: React.KeyboardEventHandler<HTMLElement>; | ||
onMouseLeave?: React.MouseEventHandler<HTMLElement>; | ||
onMouseOver?: React.MouseEventHandler<HTMLElement>; | ||
} | ||
|
||
const StyledDragArea = styled.div` | ||
width: 100%; | ||
height: 100%; | ||
`; | ||
|
||
export const DragArea: React.SFC<DragAreaProps> = props => ( | ||
<StyledDragArea | ||
data-drag-root | ||
data-content-id={props.anchors['data-content-id']} | ||
data-id={props.anchors['data-id']} | ||
{...props} | ||
> | ||
{props.children} | ||
</StyledDragArea> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './drag-area'; | ||
export * from './target-signal'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"name": "drag-area", | ||
"displayName": "Drag Area", | ||
"flag": "alpha", | ||
"version": "1.0.0", | ||
"tags": ["globals"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import * as React from 'react'; | ||
import styled from 'styled-components'; | ||
import { Color } from '../colors'; | ||
import { getSpace, SpaceSize } from '../space'; | ||
|
||
export interface TargetSignalProps { | ||
visible: boolean; | ||
} | ||
|
||
interface StyledTargetSignalProps { | ||
visible: boolean; | ||
} | ||
|
||
const TARGET_SIGNAL_SCALE = (props: StyledTargetSignalProps): number => (props.visible ? 1 : 0); | ||
|
||
const StyledTargetSignal = styled.div` | ||
position: relative; | ||
height: ${getSpace(SpaceSize.S)}px; | ||
width: 100%; | ||
margin-top: -${getSpace(SpaceSize.XS)}px; | ||
margin-bottom: -${getSpace(SpaceSize.XS)}px; | ||
z-index: 10; | ||
&::before { | ||
content: ''; | ||
display: block; | ||
position: absolute; | ||
height: 6px; | ||
width: 6px; | ||
left: 0; | ||
top: 3px; | ||
border-radius: 3px; | ||
background: ${Color.Blue40}; | ||
transform: scale(${TARGET_SIGNAL_SCALE}); | ||
transition: transform 0.2s; | ||
z-index: 20; | ||
} | ||
&::after { | ||
content: ''; | ||
display: block; | ||
position: absolute; | ||
height: 2px; | ||
width: calc(100% - 6px); | ||
left: ${getSpace(SpaceSize.XS)}; | ||
top: 5px; | ||
background: ${Color.Blue40}; | ||
transform: scaleY(${TARGET_SIGNAL_SCALE}); | ||
transition: transform 0.2s; | ||
z-index: 20; | ||
} | ||
`; | ||
|
||
export const TargetSignal: React.SFC<TargetSignalProps> = ({ | ||
visible, | ||
...dataPlaceHolder | ||
}): JSX.Element => <StyledTargetSignal {...dataPlaceHolder} visible={visible} />; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.