@everchron/ec-shards 6.2.2 → 7.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.
Files changed (111) hide show
  1. package/dist/ec-shards.common.js +3154 -2114
  2. package/dist/ec-shards.common.js.map +1 -1
  3. package/dist/ec-shards.css +1 -1
  4. package/dist/ec-shards.umd.js +3154 -2114
  5. package/dist/ec-shards.umd.js.map +1 -1
  6. package/dist/ec-shards.umd.min.js +2 -2
  7. package/dist/ec-shards.umd.min.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/components/action-toolbar/action-toolbar.vue +1 -1
  10. package/src/components/alert/alert.vue +27 -4
  11. package/src/components/avatar/avatar.vue +2 -1
  12. package/src/components/breadcrumb/breadcrumb.vue +2 -2
  13. package/src/components/breadcrumb-button/breadcrumb-button.vue +15 -3
  14. package/src/components/breadcrumb-title/breadcrumb-title.vue +1 -1
  15. package/src/components/button/button.vue +65 -54
  16. package/src/components/button-collapse/button-collapse.vue +49 -6
  17. package/src/components/button-context/button-context.vue +30 -1
  18. package/src/components/button-dialog/button-dialog.vue +22 -8
  19. package/src/components/button-more/button-more.vue +44 -4
  20. package/src/components/button-table/button-table.vue +13 -1
  21. package/src/components/button-toolbar/button-toolbar.vue +50 -19
  22. package/src/components/button-toolbar-icon/button-toolbar-icon.vue +23 -7
  23. package/src/components/checkbox/checkbox.vue +0 -1
  24. package/src/components/collapse/collapse.vue +28 -7
  25. package/src/components/collection-control/collection-control.vue +40 -7
  26. package/src/components/comment/comment.vue +1 -1
  27. package/src/components/context-menu/context-menu.vue +88 -5
  28. package/src/components/data-card/data-card.vue +52 -14
  29. package/src/components/data-card-list/data-card-list.vue +1 -1
  30. package/src/components/data-grid/data-grid-cell.vue +1 -1
  31. package/src/components/data-grid/data-grid-group.vue +6 -1
  32. package/src/components/data-grid/data-grid-head-cell.vue +32 -2
  33. package/src/components/data-grid/data-grid-row.vue +1 -1
  34. package/src/components/data-grid/data-grid.vue +2 -2
  35. package/src/components/data-list/data-list.vue +1 -1
  36. package/src/components/data-list-item/data-list-item.vue +28 -9
  37. package/src/components/directory-entry/directory-entry.vue +7 -4
  38. package/src/components/document-state/document-state.vue +1 -1
  39. package/src/components/dropdown/dropdown.vue +23 -1
  40. package/src/components/dropzone/dropzone.vue +21 -3
  41. package/src/components/empty-state/empty-state.vue +1 -1
  42. package/src/components/entry-link/entry-link.vue +16 -3
  43. package/src/components/favicon/favicon.vue +1 -1
  44. package/src/components/file-icon/file-icon.vue +1 -1
  45. package/src/components/file-list/file-list.vue +1 -1
  46. package/src/components/file-list-item/file-list-item.vue +79 -17
  47. package/src/components/flag/flag.vue +75 -1
  48. package/src/components/folder-selector/folder-selector.vue +1 -1
  49. package/src/components/form-check/form-check.vue +9 -2
  50. package/src/components/form-set/form-set.vue +4 -4
  51. package/src/components/index.js +2 -0
  52. package/src/components/input-clear/input-clear.vue +20 -3
  53. package/src/components/jumper-document/jumper-document.vue +16 -4
  54. package/src/components/jumper-index/jumper-index.vue +19 -4
  55. package/src/components/jumper-page/jumper-page.vue +3 -1
  56. package/src/components/layout-data-table/layout-data-table.vue +5 -5
  57. package/src/components/layout-directory/layout-directory.vue +4 -4
  58. package/src/components/layout-index/layout-index.vue +2 -2
  59. package/src/components/legend-item/legend-item.vue +15 -1
  60. package/src/components/log-message/log-message.vue +11 -1
  61. package/src/components/map/map.vue +20 -3
  62. package/src/components/mixins/focus-ring.vue +47 -0
  63. package/src/components/mixins/unique-id.js +17 -0
  64. package/src/components/modal/modal.vue +5 -2
  65. package/src/components/modal-header/modal-header.vue +43 -19
  66. package/src/components/multiselect-option/multiselect-option.vue +1 -1
  67. package/src/components/multiselect-search-token/multiselect-search-token.vue +33 -6
  68. package/src/components/multiselect-token/multiselect-token.vue +28 -3
  69. package/src/components/overlay/overlay.vue +6 -6
  70. package/src/components/pagination/pagination.vue +5 -5
  71. package/src/components/popover-list/popover-list.vue +5 -1
  72. package/src/components/popover-list-headline/popover-list-headline.vue +4 -1
  73. package/src/components/popover-list-item/popover-list-item.vue +27 -8
  74. package/src/components/progress/progress.vue +7 -1
  75. package/src/components/quicklink/quicklink.vue +29 -18
  76. package/src/components/radiobutton/radiobutton.vue +2 -2
  77. package/src/components/rating-favorability/rating-favorability.vue +5 -1
  78. package/src/components/rating-star-read/rating-star-read.vue +1 -1
  79. package/src/components/select/select.vue +12 -2
  80. package/src/components/select-text/select-text.vue +7 -2
  81. package/src/components/select-tile/select-tile.vue +26 -2
  82. package/src/components/separator/separator.vue +1 -1
  83. package/src/components/sequence-map/sequence-map.vue +1 -1
  84. package/src/components/sequence-map-button/sequence-map-button.vue +14 -2
  85. package/src/components/sidebar-footer/sidebar-footer.vue +2 -2
  86. package/src/components/sidebar-header/sidebar-header.vue +2 -2
  87. package/src/components/sortbutton/sortbutton.vue +22 -7
  88. package/src/components/sticker/sticker.vue +1 -1
  89. package/src/components/swatches-picker/swatches-picker.vue +28 -3
  90. package/src/components/switch/switch.vue +24 -8
  91. package/src/components/tab/tab.vue +16 -2
  92. package/src/components/tab-bar/tab-bar.vue +1 -1
  93. package/src/components/tab-button/tab-button.vue +61 -1
  94. package/src/components/tabs/tabs.vue +2 -1
  95. package/src/components/tag/tag.vue +17 -5
  96. package/src/components/tag-cloud/tag-cloud.vue +3 -1
  97. package/src/components/toast/toast.vue +18 -3
  98. package/src/components/toasts/toasts.vue +1 -1
  99. package/src/components/toolbar/toolbar.vue +1 -1
  100. package/src/components/transcript-state/transcript-state.vue +1 -1
  101. package/src/components/tree-list/tree-list-item.vue +77 -12
  102. package/src/components/tree-list/tree-list.vue +7 -1
  103. package/src/stories/Changelog.stories.mdx +8 -0
  104. package/src/stories/button/button.stories.js +7 -7
  105. package/src/stories/button-more/button-more.stories.js +8 -8
  106. package/src/stories/button-toolbar/button-toolbar.stories.js +5 -5
  107. package/src/stories/button-toolbar-icon/button-toolbar-icon.stories.js +6 -6
  108. package/src/stories/popover-list/popover-list.stories.js +7 -2
  109. package/src/stories/sortbutton/sortbutton.stories.js +4 -4
  110. package/src/stories/tag/tag.stories.js +7 -7
  111. package/src/stories/tree-list/tree-list.stories.js +3 -0
@@ -1,20 +1,20 @@
1
1
  <template>
2
2
  <li>
3
- <div v-if="type === 'checkbox'" class="ecs-popover-list-item control no-hover">
3
+ <div v-if="type === 'checkbox'" class="ecs-popover-list-item control no-hover" role="menuitem" tabindex="-1">
4
4
  <ecs-checkbox @input="$emit('input', $event)" :disabled="disabled" :value="value" :value-false="valueFalse" :value-true="valueTrue" :indeterminate="indeterminate">
5
5
  <slot></slot>
6
6
  </ecs-checkbox>
7
7
  <span v-if="suffix" class="after">{{suffix}}</span>
8
8
  </div>
9
9
 
10
- <div v-else-if="type === 'radiobutton'" class="ecs-popover-list-item control no-hover">
10
+ <div v-else-if="type === 'radiobutton'" class="ecs-popover-list-item control no-hover" role="menuitem" tabindex="-1">
11
11
  <ecs-radiobutton @change="$emit('change', $event)" :disabled="disabled" :checked="value">
12
12
  <slot></slot>
13
13
  </ecs-radiobutton>
14
14
  <span v-if="suffix" class="after">{{suffix}}</span>
15
15
  </div>
16
16
 
17
- <div v-else-if="type === 'switch'" class="ecs-popover-list-item control no-hover">
17
+ <div v-else-if="type === 'switch'" class="ecs-popover-list-item control no-hover" role="menuitem" tabindex="-1">
18
18
  <ecs-switch @input="$emit('input', $event)" :value="value" :value-false="valueFalse" :value-true="valueTrue" size="sml-toggle" :disabled="disabled">
19
19
  <slot></slot>
20
20
  <span v-if="help" class="help">{{help}}</span>
@@ -22,21 +22,23 @@
22
22
  <span v-if="suffix" class="after">{{suffix}}</span>
23
23
  </div>
24
24
 
25
- <div v-else-if="type === 'sort'" @click="$emit('click', $event)" class="ecs-popover-list-item control no-hover">
25
+ <div v-else-if="type === 'sort'" @click="$emit('click', $event)" class="ecs-popover-list-item control no-hover" role="menuitem" tabindex="0">
26
26
  <ecs-sortbutton :sort="sort" :disabled="disabled">
27
27
  <slot></slot>
28
28
  </ecs-sortbutton>
29
29
  <span v-if="suffix" class="after">{{suffix}}</span>
30
+ <ecs-focus-ring :inset="0" />
30
31
  </div>
31
32
 
32
- <a v-else-if="type === 'link'" @click="$emit('click', $event)" class="ecs-popover-list-item"
33
+ <a v-else-if="type === 'link'" @click="$emit('click', $event)" class="ecs-popover-list-item" tabindex="0"
33
34
  :class="[
34
35
  danger ? `danger` : '',
35
36
  subtle ? `subtle` : '',
36
37
  disabled ? `disabled` : '',
37
38
  noHover ? `no-hover` : '',
38
39
  selected ? `selected` : '']"
39
- :href="href">
40
+ :href="href"
41
+ role="menuitem">
40
42
 
41
43
  <ecs-icon v-if="icon" :type="icon" size="24" />
42
44
  <ecs-file-icon v-if="fileIcon" :type="fileIcon" />
@@ -56,6 +58,7 @@
56
58
  </span>
57
59
  <span v-if="suffix" class="after">{{suffix}}</span>
58
60
  <ecs-icon v-if="hoverIcon" :type="hoverIcon" class="hover-icon" />
61
+ <ecs-focus-ring :inset="0" />
59
62
  </a>
60
63
 
61
64
  <button v-else class="ecs-popover-list-item"
@@ -65,7 +68,9 @@
65
68
  disabled ? `disabled` : '',
66
69
  noHover || preventHover ? `no-hover` : '',
67
70
  selected ? `selected` : '']"
68
- @click="$emit('click', $event)">
71
+ @click="$emit('click', $event)"
72
+ role="menuitem"
73
+ tabindex="0">
69
74
 
70
75
  <ecs-icon v-if="icon" :type="icon" size="24" />
71
76
  <ecs-file-icon v-if="fileIcon" :type="fileIcon" />
@@ -85,6 +90,7 @@
85
90
  </span>
86
91
  <span v-if="suffix" class="after">{{suffix}}</span>
87
92
  <ecs-icon v-if="hoverIcon" :type="hoverIcon" size="24" class="hover-icon" />
93
+ <ecs-focus-ring :inset="0" />
88
94
  </button>
89
95
  </li>
90
96
  </template>
@@ -97,9 +103,10 @@
97
103
  import EcsIcon from '../icon/icon'
98
104
  import EcsFileIcon from '../file-icon/file-icon'
99
105
  import EcsButton from '../button/button'
106
+ import EcsFocusRing from '../mixins/focus-ring'
100
107
 
101
108
  export default {
102
- components: { EcsCheckbox, EcsRadiobutton, EcsSwitch, EcsSortbutton, EcsIcon, EcsFileIcon, EcsButton },
109
+ components: { EcsCheckbox, EcsRadiobutton, EcsSwitch, EcsSortbutton, EcsIcon, EcsFileIcon, EcsButton, EcsFocusRing },
103
110
 
104
111
  props: {
105
112
  /** Determines the type of popover list item.*/
@@ -269,6 +276,18 @@
269
276
  white-space: nowrap;
270
277
  cursor: pointer;
271
278
 
279
+ &:focus{
280
+ outline: none;
281
+ }
282
+
283
+ &:focus-visible{
284
+ outline: none;
285
+
286
+ .ecs-focus-ring{
287
+ display: block;
288
+ }
289
+ }
290
+
272
291
  &:hover,
273
292
  &.active{
274
293
  background: rgba($color-blue-8, .08);
@@ -1,5 +1,11 @@
1
1
  <template>
2
- <div class="ecs-progress">
2
+ <div
3
+ class="ecs-progress"
4
+ role="progressbar"
5
+ aria-label="Progress"
6
+ :aria-valuenow="100 * (value / computedMax)"
7
+ aria-valuemin="0"
8
+ :aria-valuemax="computedMax">
3
9
  <div
4
10
  class="ecs-progress-bar"
5
11
  :class="
@@ -4,18 +4,20 @@
4
4
  active ? 'active' : '',
5
5
  disabled ? 'disabled' : ''
6
6
  ]">
7
- <label v-if="type === 'icon'" @click="$emit('click', $event)">
7
+ <label v-if="type === 'icon'" @click="$emit('click', $event)" tabindex="0" role="button">
8
8
  <ecs-icon :type="icon" />
9
9
  <span class="filter-description">{{label}}</span>
10
10
  <small v-if="count" class="filter-count">{{count}}</small>
11
+ <ecs-focus-ring />
11
12
  </label>
12
13
 
13
- <div v-else-if="type === 'favorability'" class="ecs-form-check" @click="$emit('click', $event)">
14
+ <div v-else-if="type === 'favorability'" class="ecs-form-check" @click="$emit('click', $event)" tabindex="0" role="button">
14
15
  <ecs-rating-favorability :type="favorabilityType" :rating="rating" :label="false" :disabled="disabled" />
15
16
  <label class="ml-3">
16
17
  <span class="static-label">{{label}}</span>
17
18
  </label>
18
19
  <small v-if="count" class="filter-count">{{count}}</small>
20
+ <ecs-focus-ring />
19
21
  </div>
20
22
 
21
23
  <ecs-checkbox v-else @input="$emit('input', $event)" :value="value" :value-false="valueFalse" :value-true="valueTrue" :disabled="disabled">
@@ -42,9 +44,10 @@
42
44
  import EcsRatingFavorability from '../rating-favorability/rating-favorability'
43
45
  import EcsSwitch from '../switch/switch'
44
46
  import EcsIcon from '../icon/icon'
47
+ import EcsFocusRing from '../mixins/focus-ring'
45
48
 
46
49
  export default {
47
- components: { EcsCheckbox, EcsRatingStarRead, EcsRatingFavorability, EcsSwitch, EcsIcon },
50
+ components: { EcsCheckbox, EcsRatingStarRead, EcsRatingFavorability, EcsSwitch, EcsIcon, EcsFocusRing },
48
51
 
49
52
  props: {
50
53
  label: {
@@ -176,28 +179,36 @@
176
179
  margin-left: auto;
177
180
  }
178
181
 
179
- .ecs-form-select{
180
- margin-left: auto;
181
- }
182
-
183
- &.has-checkbox{
182
+ &.has-checkbox > .ecs-form-check{
184
183
  padding: 0 10px;
184
+ position: relative;
185
+ height: 32px;
186
+
187
+ &:focus-visible{
188
+ z-index: 1;
189
+ outline: none;
190
+
191
+ .ecs-focus-ring{
192
+ display: block;
193
+ }
194
+ }
185
195
  }
186
196
 
187
- &.has-icon{
197
+ &.has-icon > label{
188
198
  padding: 0 10px 0 4px;
189
-
190
- [type="checkbox"],
191
- [type="radio"]{
192
- position: absolute;
193
- opacity: 0;
199
+ position: relative;
200
+ height: 32px;
201
+
202
+ &:focus-visible{
203
+ z-index: 1;
204
+ outline: none;
205
+
206
+ .ecs-focus-ring{
207
+ display: block;
208
+ }
194
209
  }
195
210
  }
196
211
 
197
- &.has-select{
198
- padding-right: 4px;
199
- }
200
-
201
212
  &.active{
202
213
  background: $color-blue-2;
203
214
 
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <ecs-form-check :class="[
3
3
  inline ? `ecs-form-check-inline` : '',
4
- disabled ? `disabled` : '',
5
4
  $slots.default ? '' : 'stand-alone']">
6
5
 
7
6
  <input
@@ -16,7 +15,8 @@
16
15
  :disabled="disabled"
17
16
  v-model="computedLocalChecked"
18
17
  @change="handleChange">
19
- <label
18
+
19
+ <label
20
20
  class="ecs-form-check-label"
21
21
  :for="id">
22
22
 
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <div class="ecs-favorability" :class="[typeClass, disabled ? 'disabled' : '']" @click="$emit('click', $event)">
2
+ <div @click="$emit('click', $event)"
3
+ class="ecs-favorability"
4
+ :class="[typeClass, disabled ? 'disabled' : '']"
5
+ :aria-busy="loading">
6
+
3
7
  <div class="ecs-favorability-button" :class="[css, loading ? 'loading' : '']" :title="labelText">
4
8
  <ecs-icon :type="iconType" />
5
9
  </div>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-rating-read" :class="[sizeClass]">
2
+ <div class="ecs-rating-read" :class="[sizeClass]" :aria-busy="loading" :aria-label="rating + ' stars'">
3
3
  <div v-if="!loading" class="ecs-stars-read" :data-maximum="maximum" :data-rating="rating"></div>
4
4
  <ecs-skeleton-loader v-else type="single" :line-height="3" :width="100" />
5
5
  </div>
@@ -149,6 +149,11 @@ export default {
149
149
  }
150
150
  }
151
151
 
152
+ &:focus-within{
153
+ border-color: rgba($color-blue-8, .5);
154
+ box-shadow: 0 0 0 2px rgba($color-blue-8, .15);
155
+ }
156
+
152
157
  &.disabled{
153
158
  opacity: .5;
154
159
  }
@@ -173,11 +178,11 @@ export default {
173
178
  outline: none;
174
179
  }
175
180
 
176
- &:required:invalid {
181
+ &:required:invalid{
177
182
  color: #858f9e;
178
183
  }
179
184
 
180
- option[value=""][disabled] {
185
+ option[value=""][disabled]{
181
186
  display: none;
182
187
  }
183
188
 
@@ -196,6 +201,11 @@ export default {
196
201
  border: 1px solid $color-gray-4;
197
202
  box-shadow: none;
198
203
  }
204
+
205
+ &:focus-within{
206
+ border: 1px solid $color-gray-6;
207
+ box-shadow: 0 0 0 2px rgba($color-gray-8, .15);
208
+ }
199
209
  }
200
210
 
201
211
  &-invisible{
@@ -13,14 +13,16 @@
13
13
  >
14
14
  <slot></slot>
15
15
  </select>
16
+ <ecs-focus-ring :inset="size == 'xsml' ? -2 : -4" />
16
17
  </div>
17
18
  </template>
18
19
 
19
20
  <script>
20
21
  import EcsIcon from '../icon/icon'
22
+ import EcsFocusRing from '../mixins/focus-ring'
21
23
 
22
24
  export default {
23
- components: { EcsIcon },
25
+ components: { EcsIcon, EcsFocusRing },
24
26
 
25
27
  props: {
26
28
  /** Determines the size of the select control. */
@@ -155,7 +157,6 @@ export default {
155
157
  @import "../mixins/svg-uri";
156
158
 
157
159
  .ecs-form-select-text{
158
- overflow: hidden;
159
160
  position: relative;
160
161
  display: inline-flex;
161
162
  align-items: center;
@@ -183,6 +184,10 @@ export default {
183
184
 
184
185
  &:focus{
185
186
  outline: none;
187
+
188
+ + .ecs-focus-ring{
189
+ display: block;
190
+ }
186
191
  }
187
192
 
188
193
  option[value=""][disabled] {
@@ -1,16 +1,31 @@
1
1
  <template>
2
- <div @click="$emit('click', $event)" class="ecs-select-tile"
3
- :class="[selected ? 'ecs-select-tile-selected' : '', disabled ? 'ecs-select-tile-disabled' : '']">
2
+ <div
3
+ @click="$emit('click', $event)"
4
+ @keydown.space.prevent="$emit('click', $event)"
5
+ @keydown.enter.prevent="$emit('click', $event)"
6
+ class="ecs-select-tile"
7
+ :class="[selected ? 'ecs-select-tile-selected' : '', disabled ? 'ecs-select-tile-disabled' : '']"
8
+ role="checkbox"
9
+ :aria-checked="selected ? 'true' : 'false'"
10
+ :tabindex="disabled ? '-1' : '0'"
11
+ >
4
12
 
5
13
  <div class="select-check" />
6
14
  <div v-if="illustration" class="illustration" :class="illustration" />
7
15
  <div v-if="label" class="label">{{ label }}</div>
8
16
  <div v-if="helpText" class="help">{{ helpText }}</div>
17
+ <ecs-focus-ring :inset="-6" :radius="12" />
9
18
  </div>
10
19
  </template>
11
20
 
12
21
  <script>
22
+ import EcsFocusRing from '../mixins/focus-ring'
23
+
13
24
  export default {
25
+ components: {
26
+ EcsFocusRing
27
+ },
28
+
14
29
  props: {
15
30
  /** The main label for the tile. */
16
31
  label: {
@@ -68,6 +83,15 @@
68
83
  transition: .2s;
69
84
  position: relative;
70
85
 
86
+ &:focus-visible{
87
+ z-index: 1;
88
+ outline: none;
89
+
90
+ .ecs-focus-ring{
91
+ display: block;
92
+ }
93
+ }
94
+
71
95
  &:hover{
72
96
  box-shadow: 0px 0px 0px 1px rgba(71, 75, 96, 0.05), 0px 2px 4px rgba(71, 75, 96, 0.15);
73
97
  transform: translateY(-4px);
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-separator" :class="classes" :style="{margin: marginStyles, width: width, height: height}" />
2
+ <div class="ecs-separator" :class="classes" :style="{margin: marginStyles, width: width, height: height}" role="separator" />
3
3
  </template>
4
4
 
5
5
  <script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-sequence-map">
2
+ <div class="ecs-sequence-map" role="navigation" aria-label="Steps">
3
3
  <slot></slot>
4
4
  </div>
5
5
  </template>
@@ -1,21 +1,24 @@
1
1
  <template>
2
2
  <button @click="$emit('click', $event)"
3
3
  class="ecs-sequence-map-button"
4
- :class="[active ? 'active' : '', loading ? 'loading' : '', disabled ? 'disabled' : '', completed ? 'completed' : '']">
4
+ :class="[active ? 'active' : '', loading ? 'loading' : '', disabled ? 'disabled' : '', completed ? 'completed' : '']"
5
+ :aria-busy="loading">
5
6
  <span class="count">
6
7
  {{ step }}
7
8
  <ecs-icon v-if="loading" type="loading" class="loading" size="34" />
8
9
  </span>
9
10
  <slot></slot>
11
+ <ecs-focus-ring :inset="4" />
10
12
  <div class="step-indicator" />
11
13
  </button>
12
14
  </template>
13
15
 
14
16
  <script>
15
17
  import EcsIcon from '../icon/icon'
18
+ import EcsFocusRing from '../mixins/focus-ring'
16
19
 
17
20
  export default {
18
- components: { EcsIcon },
21
+ components: { EcsIcon, EcsFocusRing },
19
22
 
20
23
  props: {
21
24
  /** Index of the step. */
@@ -61,6 +64,15 @@
61
64
  transition: .2s;
62
65
  position: relative;
63
66
 
67
+ &:focus-visible{
68
+ z-index: 1;
69
+ outline: none;
70
+
71
+ .ecs-focus-ring{
72
+ display: block;
73
+ }
74
+ }
75
+
64
76
  .count{
65
77
  width: 18px;
66
78
  height: 18px;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-sidebar-footer" :class="[$slots.extension ? 'has-extension' : '']">
2
+ <footer class="ecs-sidebar-footer" :class="[$slots.extension ? 'has-extension' : '']">
3
3
  <!-- @slot Slot that can contain an EcsAlert, which will appear above the sidebar footer. -->
4
4
  <slot name="alert"></slot>
5
5
  <div v-if="$slots.extension" class="ecs-sidebar-footer-extension" :class="[condensed ? 'condensed' : '']">
@@ -9,7 +9,7 @@
9
9
  <div class="ecs-sidebar-footer-inner" :class="[condensed ? 'ecs-sidebar-footer-inner-condensed' : '']">
10
10
  <slot></slot>
11
11
  </div>
12
- </div>
12
+ </footer>
13
13
  </template>
14
14
 
15
15
  <script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-sidebar-header">
2
+ <header class="ecs-sidebar-header">
3
3
  <div class="ecs-sidebar-header-row">
4
4
  <div class="ecs-sidebar-header-title">
5
5
  <slot></slot>
@@ -21,7 +21,7 @@
21
21
  <slot name="tertiaryheader"></slot>
22
22
  </div>
23
23
  </transition>
24
- </div>
24
+ </header>
25
25
  </template>
26
26
 
27
27
  <script>
@@ -1,21 +1,24 @@
1
1
  <template>
2
- <ecs-form-check class="ecs-sort" :class="[
3
- sortClass,
4
- inline ? `ecs-form-check-inline` : '',
5
- disabled ? `disabled` : '']">
2
+ <ecs-form-check
3
+ class="ecs-sort"
4
+ :class="[
5
+ sortClass,
6
+ inline ? `ecs-form-check-inline` : '',]">
6
7
 
7
8
  <span class="ecs-sort-box"></span>
8
- <label class="ecs-form-check-label" @click="$emit('click', $event)">
9
+ <label class="ecs-form-check-label" @click="$emit('click', $event)" role="button" tabindex="0">
9
10
  <slot />
11
+ <ecs-focus-ring />
10
12
  </label>
11
13
  </ecs-form-check>
12
14
  </template>
13
15
 
14
16
  <script>
15
17
  import EcsFormCheck from '../form-check/form-check'
18
+ import EcsFocusRing from '../mixins/focus-ring'
16
19
 
17
20
  export default {
18
- components: { EcsFormCheck },
21
+ components: { EcsFormCheck, EcsFocusRing },
19
22
 
20
23
  props: {
21
24
  /** Disables the sort button. */
@@ -26,7 +29,7 @@
26
29
  /** Determines the current state of the button. */
27
30
  sort: {
28
31
  type: String,
29
- validator: v => ['ascending', 'descending', null].includes(v),
32
+ validator: v => ['ascending', 'descending', null].includes(v),
30
33
  default: null
31
34
  },
32
35
  /** Renders the sort button as an inline element. */
@@ -55,6 +58,7 @@
55
58
  display: inline-block;
56
59
  position: absolute;
57
60
  left: 0;
61
+ top: 1px;
58
62
  width: 18px;
59
63
  height: 18px;
60
64
  background: white;
@@ -95,4 +99,15 @@
95
99
  opacity: .6;
96
100
  }
97
101
  }
102
+
103
+ .ecs-form-check-label{
104
+ &:focus-visible{
105
+ z-index: 1;
106
+ outline: none;
107
+
108
+ .ecs-focus-ring{
109
+ display: block;
110
+ }
111
+ }
112
+ }
98
113
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <svg class="ecs-sticker" v-if="isValidType" :class="spinning ? 'ecs-spinner' : ''"
2
+ <svg class="ecs-sticker" v-if="isValidType" :class="spinning ? 'ecs-spinner' : ''" :aria-busy="spinning"
3
3
  xmlns="http://www.w3.org/2000/svg"
4
4
  viewBox="0 0 16 16"
5
5
  width="16px"
@@ -1,9 +1,19 @@
1
1
  <template>
2
- <div class="ecs-swatches" :class="sizeClass">
2
+ <div
3
+ class="ecs-swatches"
4
+ :class="sizeClass"
5
+ role="radiogroup">
6
+
3
7
  <div
4
8
  v-for="item in swatches" :key="item.id"
5
- @click="selectedColor = item.hex"
9
+ @click="handleItemClick(item)"
10
+ @keydown.space.prevent="handleItemClick(item)"
11
+ @keydown.enter.prevent="handleItemClick(item)"
12
+ role="radio"
13
+ tabindex="0"
6
14
  :title="item.title"
15
+ :aria-label="item.title"
16
+ :aria-checked="selectedColor == item.hex ? 'true' : 'false'"
7
17
  class="ecs-swatches-color"
8
18
  :style="{backgroundColor: item.hex, color: item.hex}"
9
19
  :class="selectedColor == item.hex ? 'active' : ''">
@@ -50,6 +60,10 @@
50
60
  emitSelected(){
51
61
  /** Returns the selected color value as HEX. */
52
62
  this.$emit('input', this.selectedColor)
63
+ },
64
+
65
+ handleItemClick(item) {
66
+ this.selectedColor = item.hex;
53
67
  }
54
68
  },
55
69
 
@@ -129,12 +143,23 @@
129
143
  transform: scale(1.1);
130
144
  }
131
145
 
146
+ &:focus-visible{
147
+ &:before{
148
+ opacity: .8;
149
+ transform: scale(1);
150
+ }
151
+ }
152
+
132
153
  &.active{
133
154
  transform: scale(1.1);
134
155
 
135
156
  &:before{
136
157
  opacity: 1;
137
- transform: scale(1);
158
+ transform: scale(1);
159
+ }
160
+
161
+ &:focus-visible:before{
162
+ transform: scale(1.2);
138
163
  }
139
164
 
140
165
  &:after{
@@ -11,7 +11,7 @@
11
11
  <input
12
12
  type="checkbox"
13
13
  autocomplete="off"
14
- :id="id"
14
+ :id="switchId"
15
15
  :name="name"
16
16
  :required="required"
17
17
  :disabled="disabled"
@@ -19,16 +19,23 @@
19
19
  @change="handleClick">
20
20
  <div class="ecs-slide-switch">
21
21
  <div class="indeterminate" />
22
+ <ecs-focus-ring :radius="20" />
22
23
  </div>
23
24
  </label>
24
- <label v-if="hasDefaultSlot" :for="id">
25
+ <label v-if="hasDefaultSlot" :for="switchId">
25
26
  <slot></slot>
26
27
  </label>
27
28
  </div>
28
29
  </template>
29
30
 
30
31
  <script>
32
+ import EcsFocusRing from '../mixins/focus-ring'
33
+ import { uniqueIdMixin } from '../mixins/unique-id'
34
+
31
35
  export default {
36
+ components: { EcsFocusRing },
37
+ mixins: [uniqueIdMixin],
38
+
32
39
  props: {
33
40
  /** Sets the name attribute. */
34
41
  name: {
@@ -78,16 +85,12 @@
78
85
 
79
86
  data () {
80
87
  return {
81
- id: null,
88
+ switchId: '',
82
89
  checked: !!this.value,
83
90
  oldValue: this.value
84
91
  }
85
92
  },
86
93
 
87
- mounted () {
88
- this.id = this._uid
89
- },
90
-
91
94
  computed: {
92
95
  hasDefaultSlot () {
93
96
  return !!this.$slots.default
@@ -145,6 +148,10 @@
145
148
  this.checked = !this.checked
146
149
  this.$emit('input', this.checked ? this.valueWhenTrue : this.valueWhenFalse)
147
150
  }
151
+ },
152
+
153
+ created() {
154
+ this.switchId = this.generateUniqueId()
148
155
  }
149
156
  }
150
157
  </script>
@@ -155,6 +162,7 @@
155
162
 
156
163
  .ecs-switch{
157
164
  margin: 5px 0;
165
+ position: relative;
158
166
 
159
167
  &-wrapper{
160
168
  display: flex;
@@ -162,7 +170,15 @@
162
170
  }
163
171
 
164
172
  input[type=checkbox] {
165
- display:none;
173
+ opacity: 0;
174
+ position: absolute;
175
+ z-index: -1;
176
+
177
+ &:focus-visible{
178
+ + .ecs-slide-switch .ecs-focus-ring{
179
+ display: block;
180
+ }
181
+ }
166
182
  }
167
183
 
168
184
  .indeterminate{