Skip to content

Commit a20f7a6

Browse files
committed
mobile support.
1 parent f9381b3 commit a20f7a6

21 files changed

+397
-96
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Features:
1212
* full generic & configurable,
1313
* light/dark themes,
1414
* works on modern browsers,
15-
* ~~works on mobile~~ (TODO).
15+
* works on mobile.
1616

1717
## 👀 Examples
1818

css/designer-dark.css

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
.sqd-theme-dark .sqd-toolbox {
1111
background: #3F3F3F;
1212
}
13-
.sqd-theme-dark .sqd-toolbox-title {
13+
.sqd-theme-dark .sqd-toolbox-header-title {
1414
color: #FFF;
15+
1516
}
1617
.sqd-theme-dark .sqd-toolbox-filter {
1718
border: 0;
@@ -57,7 +58,10 @@
5758
/* dark > .sqd-smart-editor */
5859

5960
.sqd-theme-dark .sqd-smart-editor {
60-
background: #484848;
61+
background: #3F3F3F;
62+
}
63+
.sqd-theme-dark .sqd-smart-editor-toggle {
64+
background: #6F6F6F;
6165
}
6266

6367
/* dark > .sqd-task */

css/designer-light.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
background: #FFF;
6060
box-shadow: 0 0 8px rgba(0, 0, 0, .15);
6161
}
62+
.sqd-theme-light .sqd-smart-editor-toggle {
63+
background: #FFF;
64+
box-shadow: 0 0 8px rgba(0, 0, 0, .15);
65+
}
6266

6367
/* light > .sqd-task */
6468

css/designer.css

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
display: flex;
55
width: 100%;
66
height: 100%;
7-
overflow: none;
87
}
98
.sqd-designer, .sqd-drag {
109
font-size: 13px;
@@ -25,47 +24,62 @@
2524
}
2625
.sqd-toolbox {
2726
position: absolute;
28-
display: flex;
29-
flex-direction: column;
3027
top: 10px;
3128
left: 10px;
3229
z-index: 20;
3330
box-sizing: border-box;
3431
border-radius: 10px;
35-
max-height: 70%;
32+
width: 125px;
3633
}
3734
.sqd-toolbox-header {
35+
position: relative;
3836
padding: 10px;
37+
cursor: pointer;
3938
}
40-
.sqd-toolbox-title {
39+
.sqd-toolbox-header-title {
4140
display: block;
42-
text-align: center;
43-
margin-bottom: 10px;
41+
}
42+
.sqd-toolbox-toggle-icon {
43+
position: absolute;
44+
top: 50%;
45+
right: 10px;
46+
width: 16px;
47+
height: 16px;
48+
margin: -8px 0 0;
49+
}
50+
.sqd-toolbox-header:hover .sqd-toolbox-toggle-icon {
51+
opacity: .6;
52+
}
53+
.sqd-scrollbox {
54+
position: relative;
55+
overflow: hidden;
56+
}
57+
.sqd-scrollbox-body {
58+
position: absolute;
59+
top: 0;
60+
left: 0;
4461
}
4562
.sqd-toolbox-filter {
4663
display: block;
64+
box-sizing: border-box;
4765
padding: 6px 8px;
4866
outline: none;
49-
width: 100px;
50-
margin: 0 auto;
67+
width: 105px;
68+
margin: 0 10px 10px;
5169
box-sizing: border-box;
5270
border-radius: 10px;
5371
}
54-
.sqd-toolbox-container {
55-
flex: 1;
56-
padding: 0 10px;
57-
overflow: auto;
58-
}
5972
.sqd-toolbox-group-title {
6073
text-align: center;
6174
padding: 5px 0;
62-
margin: 0 0 10px;
75+
margin: 0 10px 10px;
6376
border-radius: 10px;
6477
}
6578
.sqd-toolbox-item {
6679
position: relative;
6780
border-radius: 5px;
68-
margin: 0 0 10px;
81+
margin: 0 10px 10px;
82+
width: 105px;
6983
cursor: move;
7084
}
7185
.sqd-toolbox-item-icon {
@@ -126,10 +140,9 @@
126140
/* .sqd-workspace */
127141

128142
.sqd-workspace {
129-
display: block;
130143
flex: 1;
131144
position: relative;
132-
height: 100%;
145+
display: block;
133146
}
134147
.sqd-workspace-canvas {
135148
position: absolute;
@@ -146,9 +159,52 @@
146159

147160
/* .sqd-smart-editor */
148161

162+
.sqd-smart-editor-toggle {
163+
position: absolute;
164+
top: 0;
165+
z-index: 29;
166+
width: 36px;
167+
height: 64px;
168+
border-bottom-left-radius: 10px;
169+
cursor: pointer;
170+
}
171+
.sqd-smart-editor-toggle-icon {
172+
position: absolute;
173+
top: 50%;
174+
left: 50%;
175+
width: 24px;
176+
height: 24px;
177+
margin: -12px 0 0 -12px;
178+
}
179+
.sqd-smart-editor-toggle:hover .sqd-smart-editor-toggle-icon {
180+
opacity: .6;
181+
}
149182
.sqd-smart-editor {
183+
z-index: 30;
184+
}
185+
.sqd-layout-desktop .sqd-smart-editor {
186+
position: relative;
150187
width: 300px;
151-
height: 100%;
188+
}
189+
.sqd-layout-desktop .sqd-smart-editor-toggle {
190+
right: 300px;
191+
}
192+
.sqd-layout-desktop .sqd-smart-editor-toggle.sqd-collapsed {
193+
right: 0;
194+
}
195+
.sqd-layout-mobile .sqd-smart-editor {
196+
position: absolute;
197+
top: 0;
198+
right: 0;
199+
bottom: 0;
200+
left: 41px;
201+
}
202+
.sqd-layout-mobile .sqd-smart-editor-toggle {
203+
left: 5px;
204+
}
205+
.sqd-layout-mobile .sqd-smart-editor-toggle.sqd-collapsed {
206+
left: auto;
207+
right: 0;
152208
}
153209

154210
/* .sqd-task */

examples/assets/light-dark.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ function install(placeholder, theme) {
4141
},
4242

4343
editors: {
44-
isHidden: true,
4544
globalEditorProvider: () => {
4645
return document.createElement('div');
4746
},

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sequential-workflow-designer",
3-
"version": "0.1.1",
3+
"version": "0.1.2",
44
"main": "./lib/designer.js",
55
"types": "./lib/designer.d.ts",
66
"repository": {
Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
import { Dom } from '../core/dom';
2-
3-
const CENTER_ICON =
4-
'<path d="M0 0h48v48h-48z" fill="none"/><path d="M24 16c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm-14 14h-4v8c0 2.21 1.79 4 4 4h8v-4h-8v-8zm0-20h8v-4h-8c-2.21 0-4 1.79-4 4v8h4v-8zm28-4h-8v4h8v8h4v-8c0-2.21-1.79-4-4-4zm0 32h-8v4h8c2.21 0 4-1.79 4-4v-8h-4v8z"/>';
5-
const DELETE_ICON =
6-
'<path d="M24 4c-11.05 0-20 8.95-20 20s8.95 20 20 20 20-8.95 20-20-8.95-20-20-20zm10 27.17l-2.83 2.83-7.17-7.17-7.17 7.17-2.83-2.83 7.17-7.17-7.17-7.17 2.83-2.83 7.17 7.17 7.17-7.17 2.83 2.83-7.17 7.17 7.17 7.17z" fill="#E01A24"/><path d="M0 0h48v48h-48z" fill="none"/>';
7-
const MOVE_ICON =
8-
'<path d="M20 18h8v-6h6l-10-10-10 10h6v6zm-2 2h-6v-6l-10 10 10 10v-6h6v-8zm28 4l-10-10v6h-6v8h6v6l10-10zm-18 6h-8v6h-6l10 10 10-10h-6v-6z"/><path d="M0 0h48v48h-48z" fill="none"/>';
2+
import { Icons } from '../core/icons';
93

104
export class ControlBarView {
115
public static create(parent: HTMLElement): ControlBarView {
126
const root = Dom.element('div', {
137
class: 'sqd-control-bar'
148
});
159

16-
const deleteButton = createButton(DELETE_ICON, 'Delete selected step');
10+
const deleteButton = createButton(Icons.delete, 'Delete selected step');
1711
deleteButton.classList.add('sqd-hidden');
1812

19-
const resetButton = createButton(CENTER_ICON, 'Reset');
13+
const resetButton = createButton(Icons.center, 'Reset');
2014

21-
const moveButton = createButton(MOVE_ICON, 'Turn on/off drag and drop');
15+
const moveButton = createButton(Icons.move, 'Turn on/off drag and drop');
2216
moveButton.classList.add('sqd-disabled');
2317

2418
root.appendChild(resetButton);
@@ -35,16 +29,25 @@ export class ControlBarView {
3529
private readonly resetButton: Element
3630
) {}
3731

38-
public bindDeleteButtonClick(handler: (e: Event) => void) {
39-
this.deleteButton.addEventListener('click', handler);
32+
public bindDeleteButtonClick(handler: () => void) {
33+
this.deleteButton.addEventListener('click', e => {
34+
e.preventDefault();
35+
handler();
36+
});
4037
}
4138

42-
public bindMoveButtonClick(handler: (e: Event) => void) {
43-
this.moveButton.addEventListener('click', handler);
39+
public bindMoveButtonClick(handler: () => void) {
40+
this.moveButton.addEventListener('click', e => {
41+
e.preventDefault();
42+
handler();
43+
});
4444
}
4545

46-
public bindResetButtonClick(handler: (e: Event) => void) {
47-
this.resetButton.addEventListener('click', handler);
46+
public bindResetButtonClick(handler: () => void) {
47+
this.resetButton.addEventListener('click', e => {
48+
e.preventDefault();
49+
handler();
50+
});
4851
}
4952

5053
public setIsDeleteButtonHidden(isHidden: boolean) {
@@ -61,11 +64,7 @@ function createButton(iconContent: string, title: string): HTMLElement {
6164
class: 'sqd-control-bar-button',
6265
title
6366
});
64-
const icon = Dom.svg('svg', {
65-
class: 'sqd-control-bar-button-icon',
66-
viewBox: '0 0 48 48'
67-
});
68-
icon.innerHTML = iconContent;
67+
const icon = Icons.create('sqd-control-bar-button-icon', iconContent);
6968
button.appendChild(icon);
7069
return button;
7170
}

src/control-bar/control-bar.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ export class ControlBar {
66
public static create(parent: HTMLElement, context: DesignerContext): ControlBar {
77
const view = ControlBarView.create(parent);
88
const bar = new ControlBar(view, context);
9-
view.bindDeleteButtonClick(e => bar.onDeleteButtonClicked(e));
10-
view.bindMoveButtonClick(e => bar.onMoveButtonClicked(e));
11-
view.bindResetButtonClick(e => bar.onResetButtonClicked(e));
9+
view.bindDeleteButtonClick(() => bar.onDeleteButtonClicked());
10+
view.bindMoveButtonClick(() => bar.onMoveButtonClicked());
11+
view.bindResetButtonClick(() => bar.onResetButtonClicked());
1212
context.onIsReadonlyChanged.subscribe(() => bar.onIsReadonlyChanged());
1313
context.onSelectedStepChanged.subscribe(() => bar.onSelectedStepChanged());
1414
context.onIsMoveModeEnabledChanged.subscribe(i => bar.onIsMoveModeEnabledChanged(i));
@@ -29,8 +29,7 @@ export class ControlBar {
2929
this.view.setIsMoveButtonDisabled(!isEnabled);
3030
}
3131

32-
private onDeleteButtonClicked(e: Event) {
33-
e.preventDefault();
32+
private onDeleteButtonClicked() {
3433
if (this.context.selectedStep) {
3534
const parentSequence = this.context.getSelectedStepParentSequence();
3635
SequenceModifier.deleteStep(this.context.selectedStep, parentSequence);
@@ -40,13 +39,11 @@ export class ControlBar {
4039
}
4140
}
4241

43-
private onResetButtonClicked(e: Event) {
44-
e.preventDefault();
42+
private onResetButtonClicked() {
4543
this.context.resetViewPort();
4644
}
4745

48-
private onMoveButtonClicked(e: Event) {
49-
e.preventDefault();
46+
private onMoveButtonClicked() {
5047
this.context.toggleIsMoveModeEnabled();
5148
}
5249

src/core/icons.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Dom } from './dom';
2+
3+
// Source: https://github.com/google/material-design-icons
4+
export class Icons {
5+
public static center =
6+
'<path d="M0 0h48v48h-48z" fill="none"/><path d="M24 16c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm-14 14h-4v8c0 2.21 1.79 4 4 4h8v-4h-8v-8zm0-20h8v-4h-8c-2.21 0-4 1.79-4 4v8h4v-8zm28-4h-8v4h8v8h4v-8c0-2.21-1.79-4-4-4zm0 32h-8v4h8c2.21 0 4-1.79 4-4v-8h-4v8z"/>';
7+
public static delete =
8+
'<path d="M24 4c-11.05 0-20 8.95-20 20s8.95 20 20 20 20-8.95 20-20-8.95-20-20-20zm10 27.17l-2.83 2.83-7.17-7.17-7.17 7.17-2.83-2.83 7.17-7.17-7.17-7.17 2.83-2.83 7.17 7.17 7.17-7.17 2.83 2.83-7.17 7.17 7.17 7.17z" fill="#E01A24"/><path d="M0 0h48v48h-48z" fill="none"/>';
9+
public static move =
10+
'<path d="M20 18h8v-6h6l-10-10-10 10h6v6zm-2 2h-6v-6l-10 10 10 10v-6h6v-8zm28 4l-10-10v6h-6v8h6v6l10-10zm-18 6h-8v6h-6l10 10 10-10h-6v-6z"/><path d="M0 0h48v48h-48z" fill="none"/>';
11+
public static options =
12+
'<path d="M0 0h48v48h-48z" fill="none"/><path d="M38.86 25.95c.08-.64.14-1.29.14-1.95s-.06-1.31-.14-1.95l4.23-3.31c.38-.3.49-.84.24-1.28l-4-6.93c-.25-.43-.77-.61-1.22-.43l-4.98 2.01c-1.03-.79-2.16-1.46-3.38-1.97l-.75-5.3c-.09-.47-.5-.84-1-.84h-8c-.5 0-.91.37-.99.84l-.75 5.3c-1.22.51-2.35 1.17-3.38 1.97l-4.98-2.01c-.45-.17-.97 0-1.22.43l-4 6.93c-.25.43-.14.97.24 1.28l4.22 3.31c-.08.64-.14 1.29-.14 1.95s.06 1.31.14 1.95l-4.22 3.31c-.38.3-.49.84-.24 1.28l4 6.93c.25.43.77.61 1.22.43l4.98-2.01c1.03.79 2.16 1.46 3.38 1.97l.75 5.3c.08.47.49.84.99.84h8c.5 0 .91-.37.99-.84l.75-5.3c1.22-.51 2.35-1.17 3.38-1.97l4.98 2.01c.45.17.97 0 1.22-.43l4-6.93c.25-.43.14-.97-.24-1.28l-4.22-3.31zm-14.86 5.05c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/>';
13+
public static close =
14+
'<path d="M38 12.83l-2.83-2.83-11.17 11.17-11.17-11.17-2.83 2.83 11.17 11.17-11.17 11.17 2.83 2.83 11.17-11.17 11.17 11.17 2.83-2.83-11.17-11.17z"/><path d="M0 0h48v48h-48z" fill="none"/>';
15+
public static arrowDown =
16+
'<path d="M14.83 16.42l9.17 9.17 9.17-9.17 2.83 2.83-12 12-12-12z"/><path d="M0-.75h48v48h-48z" fill="none"/>';
17+
18+
public static create(className: string, content?: string): SVGElement {
19+
const icon = Dom.svg('svg', {
20+
class: className,
21+
viewBox: '0 0 48 48'
22+
});
23+
if (content) {
24+
icon.innerHTML = content;
25+
}
26+
return icon;
27+
}
28+
}

0 commit comments

Comments
 (0)