ember-sortable 2.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +239 -108
- package/MIGRATION_GUIDE_MODIFIERS.md +20 -13
- package/MIGRATION_GUIDE_V2.md +20 -8
- package/README.md +94 -169
- package/RELEASE.md +60 -0
- package/V2_MIGRATION_RFC.md +188 -222
- package/addon/modifiers/sortable-group.js +69 -58
- package/addon/modifiers/sortable-handle.js +22 -19
- package/addon/modifiers/sortable-item.js +126 -82
- package/addon/services/ember-sortable.js +3 -6
- package/addon/system/scroll-parent.js +1 -1
- package/addon/utils/coordinate.js +1 -1
- package/addon/utils/css-calculation.js +2 -2
- package/addon/utils/defaults.js +4 -3
- package/addon/utils/keyboard.js +3 -12
- package/addon-test-support/helpers/drag.js +3 -11
- package/addon-test-support/helpers/index.js +1 -4
- package/addon-test-support/helpers/reorder.js +4 -6
- package/addon-test-support/utils/keyboard.js +3 -12
- package/addon-test-support/utils/offset.js +6 -6
- package/app/services/ember-sortable-internal-state.js +1 -0
- package/config/environment.js +2 -2
- package/index.js +0 -20
- package/package.json +56 -33
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
- package/.github/workflows/github_ci.yml +0 -69
- package/addon/components/sortable-group.js +0 -741
- package/addon/components/sortable-handle.js +0 -30
- package/addon/components/sortable-item.js +0 -770
- package/addon/styles/components/sortable-group.css +0 -9
- package/addon/templates/components/sortable-group.hbs +0 -16
- package/addon/templates/components/sortable-handle.hbs +0 -1
- package/addon/templates/components/sortable-item.hbs +0 -2
- package/addon/utils/transitionend.js +0 -22
- package/app/components/sortable-group.js +0 -3
- package/app/components/sortable-handle.js +0 -4
- package/app/components/sortable-item.js +0 -3
- package/vendor/polyfills/closest.js +0 -21
|
@@ -5,16 +5,20 @@
|
|
|
5
5
|
To use modifiers, you must use angle-bracket syntax
|
|
6
6
|
|
|
7
7
|
### New Root component
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
|
|
9
|
+
1. Instead of using `sortable-group` as a component, use `sortable-group` as a modifier
|
|
10
|
+
any element. You no longer need to tell `sortable-group` about the models, so the `each`
|
|
11
|
+
uses the models directly.
|
|
11
12
|
|
|
12
13
|
**Old Component**
|
|
14
|
+
|
|
13
15
|
```hbs
|
|
14
16
|
{{#sortable-group model=model.items onChange=(action "reorderItems") as |group|}}
|
|
15
17
|
{{#each group.model as |item|}}
|
|
16
18
|
```
|
|
19
|
+
|
|
17
20
|
**New Component**
|
|
21
|
+
|
|
18
22
|
```hbs
|
|
19
23
|
<ol {{sortable-group onChange=(action "reorderItems")}}>
|
|
20
24
|
{{#each model.items as |item|}}
|
|
@@ -23,19 +27,21 @@ uses the models directly.
|
|
|
23
27
|
2. Each `item` can be represented by any dom element or component using angle-bracket syntax
|
|
24
28
|
|
|
25
29
|
**Old Component**
|
|
30
|
+
|
|
26
31
|
```hbs
|
|
27
|
-
{{#sortable-group model=model.items onChange=(action
|
|
32
|
+
{{#sortable-group model=model.items onChange=(action 'reorderItems') as |group|}}
|
|
28
33
|
{{#each group.model as |item|}}
|
|
29
34
|
{{#group.item model=item}}
|
|
30
|
-
|
|
35
|
+
{{tem.name}}
|
|
31
36
|
{{/group.item}}
|
|
32
37
|
{{/each}}
|
|
33
38
|
{{/sortable-group}}
|
|
34
39
|
```
|
|
35
40
|
|
|
36
41
|
**New Component with modifier**
|
|
42
|
+
|
|
37
43
|
```hbs
|
|
38
|
-
<ol {{sortable-group onChange=(action
|
|
44
|
+
<ol {{sortable-group onChange=(action 'reorderItems')}}>
|
|
39
45
|
{{#each model.items as |item|}}
|
|
40
46
|
<li {{sortable-item model=item}}>
|
|
41
47
|
{{tem.name}}
|
|
@@ -47,6 +53,7 @@ uses the models directly.
|
|
|
47
53
|
3. The Handle is also any element with a `sortable-handle` applied to it.
|
|
48
54
|
|
|
49
55
|
**Old Component**
|
|
56
|
+
|
|
50
57
|
```hbs
|
|
51
58
|
{{#sortable-group model=model.items onChange=(action "reorderItems") as |group|}}
|
|
52
59
|
{{#each group.model as |modelItem|}}
|
|
@@ -61,28 +68,28 @@ uses the models directly.
|
|
|
61
68
|
```
|
|
62
69
|
|
|
63
70
|
**New Component with modifier**
|
|
71
|
+
|
|
64
72
|
```hbs
|
|
65
|
-
<ol {{sortable-group onChange=(action
|
|
73
|
+
<ol {{sortable-group onChange=(action 'reorderItems')}}>
|
|
66
74
|
{{#each model.items as |item|}}
|
|
67
75
|
<li {{sortable-item model=item}}>
|
|
68
76
|
{{tem.name}}
|
|
69
|
-
<span class=
|
|
77
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
70
78
|
</li>
|
|
71
79
|
{{/each}}
|
|
72
80
|
</ol>
|
|
73
81
|
```
|
|
74
82
|
|
|
75
|
-
4. The modifier `groupModel` property is no longer supported. The equivalent can
|
|
76
|
-
be accomplished by the `action` helper or the new `fn` helper.
|
|
83
|
+
4. The modifier `groupModel` property is no longer supported. The equivalent can
|
|
84
|
+
be accomplished by the `action` helper or the new `fn` helper.
|
|
77
85
|
|
|
78
86
|
```hbs
|
|
79
|
-
<ol {{sortable-group onChange=(action
|
|
87
|
+
<ol {{sortable-group onChange=(action 'reorderItems' model)}}>
|
|
80
88
|
{{#each model.items as |item|}}
|
|
81
89
|
<li {{sortable-item model=item}}>
|
|
82
90
|
{{tem.name}}
|
|
83
|
-
<span class=
|
|
91
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
84
92
|
</li>
|
|
85
93
|
{{/each}}
|
|
86
94
|
</ol>
|
|
87
95
|
```
|
|
88
|
-
|
package/MIGRATION_GUIDE_V2.md
CHANGED
|
@@ -5,16 +5,20 @@
|
|
|
5
5
|
[High Order Components](#Higher Order Components) or [Modifiers](/MIGRATION_GUIDE_MODIFIERS.md)
|
|
6
6
|
|
|
7
7
|
### Higher Order Components
|
|
8
|
+
|
|
8
9
|
`Ember-sortable` can now be built using [higher order components](https://v4.chriskrycho.com/2018/higher-order-components-in-emberjs.html)
|
|
9
10
|
|
|
10
11
|
1. The array of models are now yielded out by `sortable-group`
|
|
11
12
|
|
|
12
13
|
**V1**
|
|
14
|
+
|
|
13
15
|
```hbs
|
|
14
16
|
{{#sortable-group onChange=(action "reorderItems") as |group|}}
|
|
15
17
|
{{#each model.items as |item|}}
|
|
16
18
|
```
|
|
19
|
+
|
|
17
20
|
**V2**
|
|
21
|
+
|
|
18
22
|
```hbs
|
|
19
23
|
{{#sortable-group model=model.items onChange=(action "reorderItems") as |group|}}
|
|
20
24
|
{{#each group.model as |item|}}
|
|
@@ -23,23 +27,25 @@
|
|
|
23
27
|
2. Each `item` can be represented by the yielded `sortable-item` instead of directly using `sortable-item` and passing the `group` manually.
|
|
24
28
|
|
|
25
29
|
**V1**
|
|
30
|
+
|
|
26
31
|
```hbs
|
|
27
|
-
{{#sortable-group onChange=(action
|
|
32
|
+
{{#sortable-group onChange=(action 'reorderItems') as |group|}}
|
|
28
33
|
{{#each model.items as |item|}}
|
|
29
|
-
{{#sortable-item model=item group=group handle=
|
|
34
|
+
{{#sortable-item model=item group=group handle='.handle'}}
|
|
30
35
|
{{item.name}}
|
|
31
|
-
<span class=
|
|
36
|
+
<span class='handle'>↕</span>
|
|
32
37
|
{{/sortable-item}}
|
|
33
38
|
{{/each}}
|
|
34
39
|
{{/sortable-group}}
|
|
35
40
|
```
|
|
36
41
|
|
|
37
42
|
**V2**
|
|
43
|
+
|
|
38
44
|
```hbs
|
|
39
|
-
{{#sortable-group model=model.items onChange=(action
|
|
45
|
+
{{#sortable-group model=model.items onChange=(action 'reorderItems') as |group|}}
|
|
40
46
|
{{#each group.model as |item|}}
|
|
41
47
|
{{#group.item model=item}}
|
|
42
|
-
|
|
48
|
+
...
|
|
43
49
|
{{/group.item}}
|
|
44
50
|
{{/each}}
|
|
45
51
|
{{/sortable-group}}
|
|
@@ -48,18 +54,20 @@
|
|
|
48
54
|
3. It is recommended to use the yielded `sortable-handle` instead of referencing `handle` by `class`, as it guarantees accessibility support.
|
|
49
55
|
|
|
50
56
|
**V1**
|
|
57
|
+
|
|
51
58
|
```hbs
|
|
52
|
-
{{#sortable-group onChange=(action
|
|
59
|
+
{{#sortable-group onChange=(action 'reorderItems') as |group|}}
|
|
53
60
|
{{#each model.items as |item|}}
|
|
54
|
-
{{#sortable-item model=item group=group handle=
|
|
61
|
+
{{#sortable-item model=item group=group handle='.handle'}}
|
|
55
62
|
{{item.name}}
|
|
56
|
-
<span class=
|
|
63
|
+
<span class='handle'>↕</span>
|
|
57
64
|
{{/sortable-item}}
|
|
58
65
|
{{/each}}
|
|
59
66
|
{{/sortable-group}}
|
|
60
67
|
```
|
|
61
68
|
|
|
62
69
|
**V2**
|
|
70
|
+
|
|
63
71
|
```hbs
|
|
64
72
|
{{#sortable-group model=model.items onChange=(action "reorderItems") as |group|}}
|
|
65
73
|
{{#each group.model as |modelItem|}}
|
|
@@ -76,6 +84,7 @@
|
|
|
76
84
|
4. `groupModel` is still supported via `groupModel` instead of `model`
|
|
77
85
|
|
|
78
86
|
**V1**
|
|
87
|
+
|
|
79
88
|
```hbs
|
|
80
89
|
{{#sortable-group model=model onChange=(action "reorderItems") as |group|}}
|
|
81
90
|
{{#each model.items as |item|}}
|
|
@@ -84,6 +93,7 @@
|
|
|
84
93
|
```
|
|
85
94
|
|
|
86
95
|
**V2**
|
|
96
|
+
|
|
87
97
|
```hbs
|
|
88
98
|
{{#sortable-group groupModel=model model=model.items onChange=(action "reorderItems") as |group|}}
|
|
89
99
|
{{#each group.model as |item|}}
|
|
@@ -94,6 +104,7 @@
|
|
|
94
104
|
### Modifiers
|
|
95
105
|
|
|
96
106
|
### Accessibility support
|
|
107
|
+
|
|
97
108
|
1. Keyboard navigation is built into `ember-sortable`.
|
|
98
109
|
2. `a11yItemName`, `a11yAnnouncementConfig`, `itemVisualClass`, `handleVisualClass` can be supplied to enhance the accessibility experience.
|
|
99
110
|
3. Refer to [Accessibility Section](/README.md#Accessibility) for more details.
|
|
@@ -103,6 +114,7 @@
|
|
|
103
114
|
```
|
|
104
115
|
|
|
105
116
|
### Testing
|
|
117
|
+
|
|
106
118
|
1. The `drag` and `reorder` test helpers are no longer global `async` helpers. They are now importable.
|
|
107
119
|
|
|
108
120
|
Refer to [Testing Section](/README.md#Testing) for more details.
|
package/README.md
CHANGED
|
@@ -12,16 +12,21 @@ Sortable UI primitives for Ember.
|
|
|
12
12
|
|
|
13
13
|
[Check out the demo](https://adopted-ember-addons.github.io/ember-sortable/demo/)
|
|
14
14
|
|
|
15
|
-
##
|
|
16
|
-
|
|
15
|
+
## v2 -> v3 Migration
|
|
16
|
+
|
|
17
|
+
The component versions have been removed and you must use the modifier.
|
|
18
|
+
The modifier version does not support `groupModel`, use the currying of the `fn` helper.
|
|
17
19
|
|
|
18
20
|
## v1 -> v2 Migration
|
|
21
|
+
|
|
19
22
|
If you are migrating from `1.x.x` to `2.x.x`,
|
|
20
23
|
For components, please read this [migration guide](/MIGRATION_GUIDE_V2.md).
|
|
21
24
|
For modifiers, please read this [migration guide](/MIGRATION_GUIDE_MODIFIERS.md).
|
|
22
25
|
|
|
23
26
|
## Requirements
|
|
24
27
|
|
|
28
|
+
In version 3.0.0+, Node.js v12 or above And Ember.js v3.24 or above
|
|
29
|
+
|
|
25
30
|
In version 2.0.0+, our `closest` polyfill seems to break some app's `production` build. To mitigate this, the `closest` polyfill will only enabled if it doesn't break the `production` build (if the `polyfill` file is recognized by the build). Affected apps will need to supply their own [closest](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill) polyfill to ensure compatibility with IE. This issue is tracked [here](https://github.com/adopted-ember-addons/ember-sortable/issues/333).
|
|
26
31
|
|
|
27
32
|
We require the `ember-decorators-polyfill` to be installed if you are using this addon with versions of Ember < 3.10.0.
|
|
@@ -38,34 +43,19 @@ $ ember install ember-sortable
|
|
|
38
43
|
|
|
39
44
|
## Usage
|
|
40
45
|
|
|
41
|
-
### component
|
|
42
|
-
```hbs
|
|
43
|
-
{{! app/templates/my-route.hbs }}
|
|
44
|
-
|
|
45
|
-
<SortableGroup @model={{this.model.items}} @onChange={{this.reorderItems}} as |group|>
|
|
46
|
-
{{#each group.model as |modelItem|}}
|
|
47
|
-
<group.item @model={{modelItem}} as |item|>
|
|
48
|
-
{{modelItem.name}}
|
|
49
|
-
<item.handle>
|
|
50
|
-
<span class="handle">↕</span>
|
|
51
|
-
</item.handle>
|
|
52
|
-
</group.item>
|
|
53
|
-
{{/each}}
|
|
54
|
-
</SortableGroup>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### modifier
|
|
58
46
|
```hbs
|
|
59
|
-
{{! app/
|
|
47
|
+
{{! app/components/my-list/template.hbs }}
|
|
60
48
|
|
|
61
|
-
<ol {{sortable-group onChange=
|
|
62
|
-
{{#each
|
|
63
|
-
<li {{sortable-item model=
|
|
64
|
-
{{
|
|
65
|
-
<span class=
|
|
49
|
+
<ol {{sortable-group onChange=this.reorderItems}}>
|
|
50
|
+
{{#each this.items as |item|}}
|
|
51
|
+
<li {{sortable-item model=item}}>
|
|
52
|
+
{{item}}
|
|
53
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
66
54
|
</li>
|
|
67
55
|
{{/each}}
|
|
68
56
|
</ol>
|
|
57
|
+
|
|
58
|
+
<p>The last dragged item was: {{this.lastDragged}}</p>
|
|
69
59
|
```
|
|
70
60
|
|
|
71
61
|
The `onChange` action is called with two arguments:
|
|
@@ -74,75 +64,39 @@ The `onChange` action is called with two arguments:
|
|
|
74
64
|
- The model you just dragged
|
|
75
65
|
|
|
76
66
|
```js
|
|
77
|
-
// app/
|
|
67
|
+
// app/components/my-list/component.js
|
|
78
68
|
|
|
79
|
-
export default
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.set('currentModel.items', itemModels);
|
|
83
|
-
this.set('currentModel.justDragged', draggedModel);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
```
|
|
69
|
+
export default class MyList extends Component {
|
|
70
|
+
@tracked lastDragged;
|
|
71
|
+
@tracked items = ['Coal Ila', 'Askaig', 'Bowmore'];
|
|
88
72
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
```hbs
|
|
95
|
-
{{! app/templates/my-route.hbs }}
|
|
96
|
-
|
|
97
|
-
{{#sortable-group groupModel=model model=model.items onChange=(action "reorderItems") as |group|}}
|
|
98
|
-
{{#each group.model as |modelItem|}}
|
|
99
|
-
{{#group.item model=modelItem as |item|}}
|
|
100
|
-
{{modelItem.name}}
|
|
101
|
-
{{#item.handle}}
|
|
102
|
-
<span class="handle">↕</span>
|
|
103
|
-
{{/item.handle}}
|
|
104
|
-
{{/group.item}}
|
|
105
|
-
{{/each}}
|
|
106
|
-
{{/sortable-group}}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
```js
|
|
110
|
-
// app/routes/my-route.js
|
|
111
|
-
|
|
112
|
-
export default Ember.Route.extend({
|
|
113
|
-
actions: {
|
|
114
|
-
reorderItems(groupModel, itemModels, draggedModel) {
|
|
115
|
-
groupModel.set('items', itemModels);
|
|
116
|
-
}
|
|
73
|
+
@action
|
|
74
|
+
reorderItems(itemModels, draggedModel) {
|
|
75
|
+
this.items = itemModels;
|
|
76
|
+
this.lastDragged = draggedModel;
|
|
117
77
|
}
|
|
118
|
-
}
|
|
78
|
+
}
|
|
119
79
|
```
|
|
120
80
|
|
|
121
81
|
The modifier version does not support `groupModel`, use the currying of `action` or the `fn` helper.
|
|
122
82
|
|
|
123
83
|
```hbs
|
|
124
|
-
{{! app/
|
|
84
|
+
{{! app/components/my-list/template.hbs }}
|
|
125
85
|
|
|
126
|
-
<ol {{sortable-group onChange=(
|
|
127
|
-
{{#each
|
|
128
|
-
<li {{sortable-item model=
|
|
129
|
-
{{
|
|
130
|
-
<span class=
|
|
86
|
+
<ol {{sortable-group onChange=(fn this.reorderItems model)}}>
|
|
87
|
+
{{#each this.items as |item|}}
|
|
88
|
+
<li {{sortable-item model=item}}>
|
|
89
|
+
{{item}}
|
|
90
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
131
91
|
</li>
|
|
132
92
|
{{/each}}
|
|
133
93
|
</ol>
|
|
134
94
|
```
|
|
135
95
|
|
|
136
|
-
|
|
137
96
|
### Changing sort direction
|
|
138
97
|
|
|
139
98
|
To change sort direction, define `direction` on `sortable-group` (default is `y`):
|
|
140
99
|
|
|
141
|
-
component
|
|
142
|
-
```hbs
|
|
143
|
-
{{#sortable-group direction="x" onChange=(action "reorderItems") as |group|}}
|
|
144
|
-
```
|
|
145
|
-
modifier
|
|
146
100
|
```hbs
|
|
147
101
|
<ol {{sortable-group direction="x" onChange=(action "reorderItems")}>
|
|
148
102
|
```
|
|
@@ -156,11 +110,6 @@ In `x` case: elements before current one jump to the left, and elements after cu
|
|
|
156
110
|
|
|
157
111
|
To change this property, define `spacing` on `sortable-item` (default is `0`):
|
|
158
112
|
|
|
159
|
-
component
|
|
160
|
-
```hbs
|
|
161
|
-
{{#sortable-item spacing=15}}
|
|
162
|
-
```
|
|
163
|
-
modifier
|
|
164
113
|
```hbs
|
|
165
114
|
<li {{sortable-item spacing=15}}>
|
|
166
115
|
```
|
|
@@ -171,11 +120,6 @@ modifier
|
|
|
171
120
|
If specified, sorting will not start until after mouse is dragged beyond distance.
|
|
172
121
|
Can be used to allow for clicks on elements within a handle.
|
|
173
122
|
|
|
174
|
-
component
|
|
175
|
-
```hbs
|
|
176
|
-
{{#sortable-item distance=30}}
|
|
177
|
-
```
|
|
178
|
-
modifier
|
|
179
123
|
```hbs
|
|
180
124
|
<li {{sortable-item distance=30}}>
|
|
181
125
|
```
|
|
@@ -184,7 +128,6 @@ modifier
|
|
|
184
128
|
|
|
185
129
|
The `disabled` attribute allows you to disable sorting for the entire group and its child items.
|
|
186
130
|
|
|
187
|
-
modifier
|
|
188
131
|
```hbs
|
|
189
132
|
<li {{sortable-group disabled=true}}>
|
|
190
133
|
```
|
|
@@ -210,7 +153,7 @@ transition of `.125s` in the default case:
|
|
|
210
153
|
|
|
211
154
|
```css
|
|
212
155
|
.sortable-item {
|
|
213
|
-
transition: all .125s;
|
|
156
|
+
transition: all 0.125s;
|
|
214
157
|
}
|
|
215
158
|
```
|
|
216
159
|
|
|
@@ -251,59 +194,39 @@ When the action is called, the item's model will be provided as the only
|
|
|
251
194
|
argument.
|
|
252
195
|
|
|
253
196
|
```js
|
|
254
|
-
// app/
|
|
255
|
-
|
|
256
|
-
export default
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
197
|
+
// app/components/my-list/component.js
|
|
198
|
+
|
|
199
|
+
export default class MyRoute extends Route {
|
|
200
|
+
@action
|
|
201
|
+
dragStarted(item) {
|
|
202
|
+
console.log(`Item started dragging: ${item}`);
|
|
203
|
+
},
|
|
204
|
+
@action
|
|
205
|
+
dragStopped(item) {
|
|
206
|
+
console.log(`Item stopped dragging: ${item}`);
|
|
264
207
|
}
|
|
265
|
-
}
|
|
208
|
+
}
|
|
266
209
|
```
|
|
267
210
|
|
|
268
|
-
component
|
|
269
|
-
```hbs
|
|
270
|
-
{{#sortable-item
|
|
271
|
-
onDragStart=(action "dragStarted")
|
|
272
|
-
onDragStop=(action "dragStopped")
|
|
273
|
-
model=modelItem
|
|
274
|
-
as |item|
|
|
275
|
-
}}
|
|
276
|
-
{{modelItem.name}}
|
|
277
|
-
{{#item.handle}}
|
|
278
|
-
<span class="handle">↕</span>
|
|
279
|
-
{{/item.handle}}
|
|
280
|
-
{{/sortable-item}}
|
|
281
|
-
```
|
|
282
|
-
modifier
|
|
283
211
|
```hbs
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}}
|
|
289
|
-
>
|
|
290
|
-
{{modelItem.name}}
|
|
291
|
-
<span class="handle" {{sortable-handle}}>↕</span>
|
|
292
|
-
</li>
|
|
212
|
+
<li {{sortable-item onDragStart=this.dragStarted onDragStop=this.dragStopped model=item}}>
|
|
213
|
+
{{item}}
|
|
214
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
215
|
+
</li>
|
|
293
216
|
```
|
|
294
217
|
|
|
295
|
-
### Multiple Ember-Sortables renders simultaneously
|
|
218
|
+
### Multiple Ember-Sortables renders simultaneously
|
|
296
219
|
|
|
297
|
-
|
|
220
|
+
There is a service behind the scenes for communication between the group and the items and to maintain state. It does this seemlessly when the elements are rendered on the screen. However, if there are two sortables rendered at the same time, either in the same component or different components, the state management does not know which items belong to which group.
|
|
298
221
|
|
|
299
222
|
Both the `{{sortable-group}}` and `{{sortable-item}}` take an additional argument `groupName`. Should you encounter this conflict, assign a `groupName` to the group and items. You only need to do this for one of the sortables in conflict, but you can on both if you wish.
|
|
300
223
|
|
|
301
224
|
```hbs
|
|
302
|
-
<ol {{sortable-group groupName=
|
|
303
|
-
{{#each
|
|
304
|
-
<li {{sortable-item groupName=
|
|
305
|
-
{{
|
|
306
|
-
<span class=
|
|
225
|
+
<ol {{sortable-group groupName='products' onChange=this.reorderItems}}>
|
|
226
|
+
{{#each this.items as |item|}}
|
|
227
|
+
<li {{sortable-item groupName='products' model=item}}>
|
|
228
|
+
{{item}}
|
|
229
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
307
230
|
</li>
|
|
308
231
|
{{/each}}
|
|
309
232
|
</ol>
|
|
@@ -312,21 +235,21 @@ Both the `{{sortable-group}}` and `{{sortable-item}}` take an additional argumen
|
|
|
312
235
|
Ensure that the same name is passed to both the group and the items, this would be best accomplished by creating property on the component and referring to that property. If you are able to use the `{{#let}}` helper (useful in template only components), using `{{#let}}` makes the usage clearer.
|
|
313
236
|
|
|
314
237
|
```hbs
|
|
315
|
-
{{#let
|
|
316
|
-
<ol {{sortable-group groupName=myGroupName onChange=
|
|
317
|
-
{{#each
|
|
318
|
-
<li {{sortable-item groupName=myGroupName model=
|
|
319
|
-
{{
|
|
320
|
-
<span class=
|
|
238
|
+
{{#let 'products' as |myGroupName|}}
|
|
239
|
+
<ol {{sortable-group groupName=myGroupName onChange=this.reorderItems}}>
|
|
240
|
+
{{#each this.items as |item|}}
|
|
241
|
+
<li {{sortable-item groupName=myGroupName model=item}}>
|
|
242
|
+
{{item}}
|
|
243
|
+
<span class='handle' {{sortable-handle}}>↕</span>
|
|
321
244
|
</li>
|
|
322
245
|
{{/each}}
|
|
323
246
|
</ol>
|
|
324
247
|
{{/let}}
|
|
325
248
|
```
|
|
326
249
|
|
|
327
|
-
|
|
328
250
|
### Disabling Drag (Experimental)
|
|
329
|
-
|
|
251
|
+
|
|
252
|
+
`sortable-item` exposes an optional `disabled` (previously `isDraggingDisabled`) flag that you can use to disable reordering for that particular item. Disabling and item won't prevent it from changing position in the array. The user can still move other non-disabled items to over it.
|
|
330
253
|
|
|
331
254
|
This flag is intended as an utility to make your life easier with 3 main benefits:
|
|
332
255
|
|
|
@@ -341,40 +264,35 @@ No data is mutated by `sortable-group` or `sortable-item`. In the spirit of “d
|
|
|
341
264
|
Each item takes a `model` property. This should be fairly self-explanatory but it’s important to note that it doesn’t do anything with this object besides keeping a reference for later use in `onChange`.
|
|
342
265
|
|
|
343
266
|
### Accessibility
|
|
267
|
+
|
|
344
268
|
The `sortable-group` has support for the following accessibility functionality:
|
|
345
269
|
|
|
346
270
|
#### Built-in Functionalities
|
|
347
271
|
|
|
348
|
-
##### Semantic HTML
|
|
349
|
-
|
|
350
|
-
component
|
|
351
|
-
- `sortable-group`
|
|
352
|
-
an ordered list, `ol`, by default.
|
|
353
|
-
- `sortable-item`
|
|
354
|
-
a list item, `li`, by default.
|
|
355
|
-
|
|
356
|
-
The modifier version can be attached to to any element that makes sense,
|
|
357
|
-
|
|
358
272
|
##### Keyboard Navigation
|
|
273
|
+
|
|
359
274
|
There are 4 modes during keyboard navigation:
|
|
275
|
+
|
|
360
276
|
- **ACTIVATE**
|
|
361
277
|
enables the keyboard navigation.
|
|
362
|
-
Activate via
|
|
278
|
+
Activate via `ENTER/SPACE`
|
|
363
279
|
- **MOVE**
|
|
364
280
|
enables item(s) to be moved up, down, left, or right based on `direction`.
|
|
365
|
-
Activate via
|
|
281
|
+
Activate via `ARROW UP/DOWN/LEFT/RIGHT`
|
|
366
282
|
- **CONFIRM**
|
|
367
283
|
submits the new sort order, invokes the `onChange` action.
|
|
368
|
-
Activate via
|
|
284
|
+
Activate via `ENTER/SPACE`.
|
|
369
285
|
- **CANCEL**
|
|
370
286
|
cancels the new sort order, reverts back to the old sort order.
|
|
371
|
-
Activate via
|
|
287
|
+
Activate via `ESCAPE` or when `focus` is lost.
|
|
372
288
|
|
|
373
289
|
##### Focus Management
|
|
290
|
+
|
|
374
291
|
- When `focus` is on a `item` or `handle`, user can effectively select the `item` via `ENTER/SPACE`. This is the `ACTIVATE` mode.
|
|
375
292
|
- While `ACTIVATE`, the `focus` is locked on `sortable-group` container and will not be lost until `CONFIRM`, `CANCEL`, or `focus` is lost.
|
|
376
293
|
|
|
377
294
|
#### User configurable
|
|
295
|
+
|
|
378
296
|
##### Screen Reader
|
|
379
297
|
|
|
380
298
|
The default language for `ember-sortable` is English. Any language can be supported by passing in the configuration below in the appropriate language.
|
|
@@ -383,6 +301,7 @@ The default language for `ember-sortable` is English. Any language can be suppor
|
|
|
383
301
|
a name for the item. Defaults to `item`.
|
|
384
302
|
- **a11yAnnouncementConfig**
|
|
385
303
|
a map of `action enums` to `functions` that takes the following `config`, which is exposed by `sortable-group`.
|
|
304
|
+
|
|
386
305
|
```javascript
|
|
387
306
|
a11yAnnounceConfig = {
|
|
388
307
|
a11yItemName, // name associated with the name
|
|
@@ -390,11 +309,13 @@ a11yAnnounceConfig = {
|
|
|
390
309
|
maxLength, // length of the items
|
|
391
310
|
direction, // x or y
|
|
392
311
|
delta, // +1 means down or right, -1 means up or left
|
|
393
|
-
}
|
|
312
|
+
};
|
|
394
313
|
```
|
|
314
|
+
|
|
395
315
|
and returns a `string` constructed from the `config`.
|
|
396
316
|
|
|
397
317
|
**Default value**
|
|
318
|
+
|
|
398
319
|
```javascript
|
|
399
320
|
{
|
|
400
321
|
ACTIVATE: function({ a11yItemName, index, maxLength, direction }) {
|
|
@@ -422,6 +343,7 @@ and returns a `string` constructed from the `config`.
|
|
|
422
343
|
```
|
|
423
344
|
|
|
424
345
|
##### Visual Indicator
|
|
346
|
+
|
|
425
347
|
- **handleVisualClass**
|
|
426
348
|
This class will be added to the `sortable-handle` during `ACTIVATE` and `MOVE` operations. This allows you to add custom styles such as `visual arrows` via `pseudo` classes.
|
|
427
349
|
|
|
@@ -432,9 +354,9 @@ and returns a `string` constructed from the `config`.
|
|
|
432
354
|
|
|
433
355
|
`ember-sortable` exposes some acceptance test helpers:
|
|
434
356
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
357
|
+
- [`drag`][drag]: Drags elements by an offset specified in pixels.
|
|
358
|
+
- [`reorder`][reorder]: Reorders elements to the specified state.
|
|
359
|
+
- [`keyboard`][keyboard]: Keycode constants for quick.
|
|
438
360
|
|
|
439
361
|
[drag]: addon-test-support/helpers/drag.js
|
|
440
362
|
[reorder]: addon-test-support/helpers/reorder.js
|
|
@@ -443,32 +365,35 @@ and returns a `string` constructed from the `config`.
|
|
|
443
365
|
To include them in your application, you can import them:
|
|
444
366
|
|
|
445
367
|
```js
|
|
446
|
-
import { drag, reorder }
|
|
447
|
-
import {
|
|
368
|
+
import { drag, reorder } from 'ember-sortable/test-support/helpers';
|
|
369
|
+
import {
|
|
370
|
+
ENTER_KEY_CODE,
|
|
371
|
+
SPACE_KEY_CODE,
|
|
372
|
+
ESCAPE_KEY_CODE,
|
|
373
|
+
ARROW_KEY_CODES,
|
|
374
|
+
} from 'ember-sortable/test-support/utils/keyboard';
|
|
448
375
|
```
|
|
449
376
|
|
|
450
377
|
### Examples
|
|
378
|
+
|
|
451
379
|
`Reorder`
|
|
380
|
+
|
|
452
381
|
```js
|
|
453
|
-
await reorder(
|
|
454
|
-
'mouse',
|
|
455
|
-
'[data-test-vertical-demo-handle]',
|
|
456
|
-
...order
|
|
457
|
-
);
|
|
382
|
+
await reorder('mouse', '[data-test-vertical-demo-handle]', ...order);
|
|
458
383
|
```
|
|
459
384
|
|
|
460
385
|
`Drag`
|
|
386
|
+
|
|
461
387
|
```js
|
|
462
|
-
await drag('mouse', '[data-test-scrollable-demo-handle] .handle', () => {
|
|
388
|
+
await drag('mouse', '[data-test-scrollable-demo-handle] .handle', () => {
|
|
389
|
+
return { dy: itemHeight() * 2 + 1, dx: undefined };
|
|
390
|
+
});
|
|
463
391
|
```
|
|
464
392
|
|
|
465
393
|
`Keyboard`
|
|
394
|
+
|
|
466
395
|
```js
|
|
467
|
-
await triggerKeyEvent(
|
|
468
|
-
'[data-test-vertical-demo-handle]',
|
|
469
|
-
'keydown',
|
|
470
|
-
ENTER_KEY_CODE
|
|
471
|
-
);
|
|
396
|
+
await triggerKeyEvent('[data-test-vertical-demo-handle]', 'keydown', ENTER_KEY_CODE);
|
|
472
397
|
```
|
|
473
398
|
|
|
474
399
|
## Developing
|