@ditojs/admin 2.71.1 → 2.73.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 (52) hide show
  1. package/dist/dito-admin.css +1 -1
  2. package/dist/dito-admin.es.js +2647 -2495
  3. package/dist/dito-admin.umd.js +5 -5
  4. package/package.json +33 -33
  5. package/src/DitoContext.js +8 -0
  6. package/src/components/DitoAccount.vue +1 -1
  7. package/src/components/DitoAffix.vue +56 -0
  8. package/src/components/DitoAffixes.vue +82 -0
  9. package/src/components/DitoClipboard.vue +3 -3
  10. package/src/components/DitoContainer.vue +24 -16
  11. package/src/components/DitoCreateButton.vue +7 -12
  12. package/src/components/DitoDialog.vue +1 -1
  13. package/src/components/DitoEditButtons.vue +3 -3
  14. package/src/components/DitoForm.vue +3 -6
  15. package/src/components/DitoHeader.vue +0 -13
  16. package/src/components/DitoLabel.vue +24 -42
  17. package/src/components/DitoMenu.vue +30 -34
  18. package/src/components/DitoPagination.vue +1 -1
  19. package/src/components/DitoPane.vue +10 -8
  20. package/src/components/DitoPanel.vue +2 -2
  21. package/src/components/DitoSchema.vue +5 -2
  22. package/src/components/DitoSchemaInlined.vue +1 -1
  23. package/src/components/DitoScopes.vue +1 -1
  24. package/src/components/DitoTableHead.vue +3 -3
  25. package/src/components/DitoTabs.vue +5 -5
  26. package/src/components/DitoTrail.vue +23 -18
  27. package/src/components/DitoTreeItem.vue +8 -8
  28. package/src/components/index.js +2 -1
  29. package/src/mixins/DitoMixin.js +1 -1
  30. package/src/mixins/EmitterMixin.js +13 -7
  31. package/src/mixins/SortableMixin.js +1 -1
  32. package/src/styles/_button.scss +99 -98
  33. package/src/styles/_layout.scss +14 -12
  34. package/src/styles/_pulldown.scss +17 -15
  35. package/src/styles/_table.scss +23 -22
  36. package/src/types/DitoTypeButton.vue +62 -19
  37. package/src/types/DitoTypeCheckboxes.vue +1 -1
  38. package/src/types/DitoTypeColor.vue +16 -10
  39. package/src/types/DitoTypeDate.vue +21 -7
  40. package/src/types/DitoTypeList.vue +9 -9
  41. package/src/types/DitoTypeMarkup.vue +8 -7
  42. package/src/types/DitoTypeMultiselect.vue +2 -2
  43. package/src/types/DitoTypeNumber.vue +15 -5
  44. package/src/types/DitoTypeRadio.vue +1 -1
  45. package/src/types/DitoTypeSelect.vue +7 -7
  46. package/src/types/DitoTypeSlider.vue +3 -3
  47. package/src/types/DitoTypeSwitch.vue +3 -3
  48. package/src/types/DitoTypeText.vue +15 -5
  49. package/src/types/DitoTypeTextarea.vue +2 -2
  50. package/src/types/DitoTypeUpload.vue +7 -7
  51. package/src/utils/schema.js +4 -1
  52. package/src/components/DitoElement.vue +0 -68
@@ -2,7 +2,7 @@
2
2
 
3
3
  .dito-button {
4
4
  // .dito-button with order-arrows:
5
- .dito-order-arrows {
5
+ &__order-arrows {
6
6
  display: inline-block;
7
7
  width: math.round($button-order-arrow-size * $math-sqrt2);
8
8
  padding-left: $form-spacing;
@@ -22,7 +22,7 @@
22
22
  }
23
23
  }
24
24
 
25
- &.dito-order-asc .dito-order-arrows {
25
+ &--order-asc &__order-arrows {
26
26
  &::before {
27
27
  bottom: 0;
28
28
  }
@@ -32,7 +32,7 @@
32
32
  }
33
33
  }
34
34
 
35
- &.dito-order-desc .dito-order-arrows {
35
+ &--order-desc &__order-arrows {
36
36
  &::before {
37
37
  display: none;
38
38
  }
@@ -41,80 +41,111 @@
41
41
  top: 0;
42
42
  }
43
43
  }
44
- }
45
44
 
46
- .dito-button-create:empty::before {
47
- content: 'Create';
48
- }
45
+ &--create:empty::before {
46
+ content: 'Create';
47
+ }
49
48
 
50
- .dito-button-add:empty::before {
51
- content: 'Add';
52
- }
49
+ &--add:empty::before {
50
+ content: 'Add';
51
+ }
53
52
 
54
- .dito-button-delete:empty::before {
55
- content: 'Delete';
56
- }
53
+ &--delete:empty::before {
54
+ content: 'Delete';
55
+ }
57
56
 
58
- .dito-button-remove:empty::before {
59
- content: 'Remove';
60
- }
57
+ &--remove:empty::before {
58
+ content: 'Remove';
59
+ }
61
60
 
62
- .dito-button-edit:empty::before {
63
- content: 'Edit';
64
- }
61
+ &--edit:empty::before {
62
+ content: 'Edit';
63
+ }
65
64
 
66
- .dito-button-clear:empty::before {
67
- content: 'Clear';
68
- }
65
+ &--clear:empty::before {
66
+ content: 'Clear';
67
+ }
69
68
 
70
- .dito-button-save:empty::before {
71
- content: 'Save';
72
- }
69
+ &--save:empty::before {
70
+ content: 'Save';
71
+ }
73
72
 
74
- .dito-button-apply:empty::before {
75
- content: 'Apply';
76
- }
73
+ &--apply:empty::before {
74
+ content: 'Apply';
75
+ }
77
76
 
78
- .dito-button-login:empty::before {
79
- content: 'Login';
80
- }
77
+ &--login:empty::before {
78
+ content: 'Login';
79
+ }
81
80
 
82
- .dito-button-ok:empty::before {
83
- content: 'OK';
84
- }
81
+ &--ok:empty::before {
82
+ content: 'OK';
83
+ }
85
84
 
86
- .dito-button-cancel:empty::before {
87
- content: 'Cancel';
88
- }
85
+ &--cancel:empty::before {
86
+ content: 'Cancel';
87
+ }
89
88
 
90
- .dito-button-close:empty::before {
91
- content: 'Close';
92
- }
89
+ &--close:empty::before {
90
+ content: 'Close';
91
+ }
93
92
 
94
- .dito-button-drag:empty::before {
95
- content: 'Drag';
96
- }
93
+ &--drag:empty::before {
94
+ content: 'Drag';
95
+ }
97
96
 
98
- .dito-button-copy:empty::before {
99
- content: 'Copy';
100
- }
97
+ &--copy:empty::before {
98
+ content: 'Copy';
99
+ }
101
100
 
102
- .dito-button-paste:empty::before {
103
- content: 'Paste';
104
- }
101
+ &--paste:empty::before {
102
+ content: 'Paste';
103
+ }
104
+
105
+ &--drag {
106
+ cursor: grab;
107
+
108
+ &:active {
109
+ cursor: grabbing;
110
+ }
111
+ }
105
112
 
106
- .dito-button-drag {
107
- cursor: grab;
113
+ &--overlay {
114
+ $overlay-inset: calc(2 * $border-width);
108
115
 
109
- &:active {
110
- cursor: grabbing;
116
+ position: absolute;
117
+ inset: $overlay-inset;
118
+ left: unset;
119
+ padding: 0;
120
+ border: 0;
121
+ border-radius: $border-radius;
122
+ cursor: pointer;
123
+
124
+ &.dito-button--clear {
125
+ width: calc(2em - 2 * ($border-width + $overlay-inset));
126
+ display: none;
127
+
128
+ @at-root .dito-component:hover:not(:has(.dito-component)) & {
129
+ display: block;
130
+ }
131
+
132
+ &::before {
133
+ @extend %icon-clear;
134
+
135
+ color: $color-grey;
136
+ }
137
+
138
+ &:hover::before {
139
+ color: $color-black;
140
+ }
141
+ }
111
142
  }
112
143
  }
113
144
 
114
145
  .dito-buttons {
115
146
  // TODO: BEM
116
147
 
117
- &.dito-buttons-large {
148
+ &--large {
118
149
  --button-margin: 3px;
119
150
 
120
151
  font-size: $header-font-size;
@@ -133,11 +164,11 @@
133
164
  }
134
165
  }
135
166
 
136
- &.dito-buttons-main {
167
+ &--main {
137
168
  border-top: $border-style;
138
169
  }
139
170
 
140
- &.dito-buttons-sticky {
171
+ &--sticky {
141
172
  align-self: flex-end;
142
173
  position: sticky;
143
174
  bottom: 0;
@@ -153,69 +184,39 @@
153
184
  }
154
185
  }
155
186
 
156
- &.dito-buttons-round,
157
- &.dito-buttons-small {
187
+ &--round,
188
+ &--small {
158
189
  // For now, nothing for these:
159
- // .dito-button-create:empty::before,
160
- // .dito-button-add:empty::before
190
+ // .dito-button--create:empty::before,
191
+ // .dito-button--add:empty::before
161
192
 
162
- .dito-button-upload:empty::before {
193
+ .dito-button--upload:empty::before {
163
194
  @extend %icon-upload;
164
195
  }
165
196
 
166
- .dito-button-delete:empty::before,
167
- .dito-button-remove:empty::before {
197
+ .dito-button--delete:empty::before,
198
+ .dito-button--remove:empty::before {
168
199
  @extend %icon-remove;
169
200
  }
170
201
 
171
- .dito-button-edit:empty::before {
202
+ .dito-button--edit:empty::before {
172
203
  @extend %icon-edit;
173
204
  }
174
205
 
175
- .dito-button-clear:empty::before {
206
+ .dito-button--clear:empty::before {
176
207
  @extend %icon-clear;
177
208
  }
178
209
 
179
- .dito-button-drag:empty::before {
210
+ .dito-button--drag:empty::before {
180
211
  @extend %icon-drag;
181
212
  }
182
213
 
183
- .dito-button-copy:empty::before {
214
+ .dito-button--copy:empty::before {
184
215
  @extend %icon-copy;
185
216
  }
186
217
 
187
- .dito-button-paste:empty::before {
218
+ .dito-button--paste:empty::before {
188
219
  @extend %icon-paste;
189
220
  }
190
221
  }
191
222
  }
192
-
193
- .dito-button-overlay {
194
- position: absolute;
195
- inset: $border-width;
196
- left: unset;
197
- padding: 0;
198
- border: 0;
199
- border-radius: $border-radius;
200
- cursor: pointer;
201
-
202
- &.dito-button-clear {
203
- width: 2em;
204
- background: $color-white;
205
- display: none;
206
-
207
- @at-root .dito-component:hover:not(:has(.dito-component)) & {
208
- display: block;
209
- }
210
-
211
- &::before {
212
- @extend %icon-clear;
213
-
214
- color: $color-grey;
215
- }
216
-
217
- &:hover::before {
218
- color: $color-black;
219
- }
220
- }
221
- }
@@ -1,17 +1,19 @@
1
- .dito-layout-vertical,
2
- .dito-layout-horizontal {
3
- display: flex;
4
-
5
- > * {
6
- flex: 0 0 auto;
1
+ .dito-layout {
2
+ &--vertical,
3
+ &--horizontal {
7
4
  display: flex;
5
+
6
+ > * {
7
+ flex: 0 0 auto;
8
+ display: flex;
9
+ }
8
10
  }
9
- }
10
11
 
11
- .dito-layout-horizontal {
12
- gap: $form-spacing;
13
- }
12
+ &--horizontal {
13
+ gap: $form-spacing;
14
+ }
14
15
 
15
- .dito-layout-vertical {
16
- flex-direction: column;
16
+ &--vertical {
17
+ flex-direction: column;
18
+ }
17
19
  }
@@ -1,6 +1,8 @@
1
1
  @import '../styles/_imports';
2
2
 
3
- ul.dito-pulldown {
3
+ .dito-pulldown {
4
+ $self: &;
5
+
4
6
  display: none;
5
7
  position: absolute;
6
8
  top: 0;
@@ -9,28 +11,28 @@ ul.dito-pulldown {
9
11
  box-shadow: $shadow-window;
10
12
  overflow: hidden;
11
13
 
12
- &.dito-open {
14
+ &--open {
13
15
  display: block;
14
16
  }
15
17
 
16
18
  li {
17
19
  @include user-select(none);
20
+ }
18
21
 
19
- a {
20
- display: block;
21
- padding: $pulldown-padding;
22
- line-height: 1;
23
- background: $button-color;
22
+ &__item {
23
+ display: block;
24
+ padding: $pulldown-padding;
25
+ line-height: 1;
26
+ background: $button-color;
24
27
 
25
- &.dito-disabled {
26
- color: $color-disabled;
27
- cursor: default;
28
- }
28
+ &--disabled {
29
+ color: $color-disabled;
30
+ cursor: default;
31
+ }
29
32
 
30
- &:not(.dito-disabled):hover {
31
- background: $color-active;
32
- color: $color-white;
33
- }
33
+ &:not(&--disabled):hover {
34
+ background: $color-active;
35
+ color: $color-white;
34
36
  }
35
37
  }
36
38
  }
@@ -48,7 +48,9 @@
48
48
  border-bottom-right-radius: $border-radius;
49
49
  }
50
50
 
51
- table.dito-table {
51
+ .dito-table {
52
+ $self: &;
53
+
52
54
  --separator-width: #{$border-width};
53
55
 
54
56
  width: 100%;
@@ -67,24 +69,24 @@ table.dito-table {
67
69
  &:last-child {
68
70
  padding-right: $form-spacing;
69
71
  }
72
+ }
73
+ }
74
+ }
70
75
 
71
- &.dito-cell-edit-buttons {
72
- width: 1%;
76
+ &__buttons {
77
+ width: 1%;
73
78
 
74
- &,
75
- .dito-button {
76
- // To align better with `vertical-align: baseline` in normal td:
77
- vertical-align: top;
78
- }
79
- }
80
- }
79
+ &,
80
+ .dito-button {
81
+ // To align better with `vertical-align: baseline` in normal td:
82
+ vertical-align: top;
81
83
  }
82
84
  }
83
85
 
84
- &.dito-table-larger-padding {
86
+ &--larger-padding {
85
87
  // Add more spacing to cells in tables except those containing edit buttons,
86
88
  // to better align cell texts with edit buttons.
87
- td:not(.dito-cell-edit-buttons) {
89
+ td:not(#{$self}__buttons) {
88
90
  $padding: $form-spacing * 1.5;
89
91
 
90
92
  padding: $padding 0 $padding $padding;
@@ -92,7 +94,7 @@ table.dito-table {
92
94
  // Variants of list styles: separators and alternate colors.
93
95
  }
94
96
 
95
- &.dito-table-separators {
97
+ &--separators {
96
98
  > tbody > tr + tr,
97
99
  > tbody:not(:empty) + tfoot > tr {
98
100
  > td {
@@ -101,16 +103,16 @@ table.dito-table {
101
103
  }
102
104
  }
103
105
 
104
- &.dito-table-alternate-colors {
106
+ &--alternate-colors {
105
107
  > tbody > tr:nth-child(odd),
106
- &.dito-table-even-count > tfoot > tr {
108
+ &#{$self}--even-count > tfoot > tr {
107
109
  > td {
108
110
  background: $color-white;
109
111
  }
110
112
  }
111
113
  }
112
114
 
113
- &.dito-table-background {
115
+ &--background {
114
116
  > tbody,
115
117
  > tfoot {
116
118
  > tr > td {
@@ -152,7 +154,7 @@ table.dito-table {
152
154
  &:focus {
153
155
  z-index: 1;
154
156
  }
155
- // Add left/rigth borders to the normal tbody cells.
157
+ // Add left/right borders to the normal tbody cells.
156
158
  }
157
159
  }
158
160
 
@@ -212,11 +214,10 @@ table.dito-table {
212
214
  &:last-child {
213
215
  @include table-border-bottom-right;
214
216
  }
215
- // Nested .dito-table:
216
217
  }
217
- }
218
218
 
219
- table.dito-table table.dito-table,
220
- .dito-form-nested table.dito-table {
221
- margin: 0;
219
+ #{$self} & {
220
+ // Nested .dito-table
221
+ margin: 0;
222
+ }
222
223
  }
@@ -1,43 +1,62 @@
1
1
  <template lang="pug">
2
- button.dito-button(
2
+ DitoButton.dito-button(
3
3
  :id="dataPath"
4
4
  ref="element"
5
5
  :type="type"
6
+ :text="text"
6
7
  :title="title"
7
8
  :class="buttonClass"
8
9
  v-bind="attributes"
9
10
  )
10
- .dito-button__text(
11
- v-if="text"
12
- ) {{ text }}
13
- .dito-info(
14
- v-if="!label && info"
15
- :data-info="info"
16
- )
11
+ template(#prefix)
12
+ DitoAffixes(
13
+ v-if="prefixes.length > 0"
14
+ :items="prefixes"
15
+ :parentContext="context"
16
+ )
17
+ template(#suffix)
18
+ DitoAffixes(
19
+ v-if="suffixes.length > 0"
20
+ :items="suffixes"
21
+ :parentContext="context"
22
+ )
23
+ .dito-info(
24
+ v-if="!label && info"
25
+ :data-info="info"
26
+ )
17
27
  </template>
18
28
 
19
29
  <script>
20
30
  import DitoTypeComponent from '../DitoTypeComponent.js'
31
+ import DitoAffixes from '../components/DitoAffixes.vue'
32
+ import { DitoButton } from '@ditojs/ui/src'
21
33
  import { getSchemaAccessor } from '../utils/accessor.js'
22
34
  import { hasResource } from '../utils/resource.js'
23
- import { labelize } from '@ditojs/utils'
35
+ import { labelize, asArray } from '@ditojs/utils'
24
36
 
25
37
  export default DitoTypeComponent.register(
26
38
  ['button', 'submit'],
27
39
  // @vue/component
28
40
  {
41
+ components: { DitoAffixes, DitoButton },
29
42
  defaultValue: () => undefined, // Callback to override `defaultValue: null`
30
43
  excludeValue: true,
31
44
  defaultWidth: 'auto',
32
45
  generateLabel: false,
33
46
 
47
+ data() {
48
+ return {
49
+ isRunning: false
50
+ }
51
+ },
52
+
34
53
  computed: {
35
54
  verb() {
36
55
  return this.verbs[this.name]
37
56
  },
38
57
 
39
58
  buttonClass() {
40
- return this.verb ? `dito-button-${this.verb}` : null
59
+ return this.verb ? `dito-button--${this.verb}` : null
41
60
  },
42
61
 
43
62
  text: getSchemaAccessor('text', {
@@ -53,6 +72,14 @@ export default DitoTypeComponent.register(
53
72
  default: null
54
73
  }),
55
74
 
75
+ prefixes() {
76
+ return asArray(this.schema.prefix)
77
+ },
78
+
79
+ suffixes() {
80
+ return asArray(this.schema.suffix)
81
+ },
82
+
56
83
  closeForm: getSchemaAccessor('closeForm', {
57
84
  type: Boolean,
58
85
  default: false
@@ -71,15 +98,31 @@ export default DitoTypeComponent.register(
71
98
  },
72
99
 
73
100
  async onClick() {
74
- const res = await this.emitEvent('click', {
75
- parent: this.schemaComponent
76
- })
77
- // Have buttons that define resources call `this.submit()` by default:
78
- if (
79
- res === undefined && // Meaning: don't prevent default.
80
- hasResource(this.schema)
81
- ) {
82
- await this.submit()
101
+ this.isRunning = true
102
+ try {
103
+ const res = await this.emitEvent('click', {
104
+ parent: this.schemaComponent
105
+ })
106
+ // Have buttons that define resources call `this.submit()` by default:
107
+ if (
108
+ res === undefined && // Meaning: don't prevent default.
109
+ hasResource(this.schema)
110
+ ) {
111
+ await this.submit()
112
+ }
113
+ } catch (error) {
114
+ const res = await this.emitEvent('error', { error })
115
+ if (res === undefined) {
116
+ if (error instanceof AggregateError) {
117
+ for (const err of error.errors) {
118
+ this.notify({ type: 'error', text: err })
119
+ }
120
+ } else {
121
+ this.notify({ type: 'error', text: error })
122
+ }
123
+ }
124
+ } finally {
125
+ this.isRunning = false
83
126
  }
84
127
  }
85
128
  }
@@ -1,7 +1,7 @@
1
1
  <template lang="pug">
2
2
  ul.dito-checkboxes(
3
3
  :id="dataPath"
4
- :class="`dito-layout-${schema.layout || 'vertical'}`"
4
+ :class="`dito-layout--${schema.layout || 'vertical'}`"
5
5
  )
6
6
  li(
7
7
  v-for="option in options"
@@ -1,10 +1,10 @@
1
1
  <template lang="pug">
2
- Trigger.dito-color(
2
+ DitoTrigger.dito-color(
3
3
  v-model:show="showPopup"
4
4
  trigger="focus"
5
5
  )
6
6
  template(#trigger)
7
- .dito-input(:class="{ 'dito-focus': showPopup }")
7
+ .dito-input(:class="{ 'dito-input--focus': showPopup }")
8
8
  input(
9
9
  :id="dataPath"
10
10
  ref="element"
@@ -13,17 +13,17 @@ Trigger.dito-color(
13
13
  size="8"
14
14
  v-bind="attributes"
15
15
  )
16
- .dito-color-preview.dito-inherit-focus(
16
+ .dito-color__preview(
17
17
  v-if="value"
18
18
  )
19
19
  div(:style="{ background: `#${hexValue || '00000000'}` }")
20
- button.dito-button-clear.dito-button-overlay(
20
+ button.dito-button--clear.dito-button--overlay(
21
21
  v-if="showClearButton"
22
22
  :disabled="disabled"
23
23
  @click.stop="clear"
24
24
  )
25
25
  template(#popup)
26
- SketchPicker.dito-color-picker(
26
+ SketchPicker.dito-color__picker(
27
27
  v-model="colorValue"
28
28
  :disableAlpha="!alpha"
29
29
  :disableFields="!inputs"
@@ -35,7 +35,7 @@ Trigger.dito-color(
35
35
  import tinycolor from 'tinycolor2'
36
36
  import { Sketch as SketchPicker } from '@lk77/vue3-color'
37
37
  import { isObject, isString } from '@ditojs/utils'
38
- import { Trigger } from '@ditojs/ui/src'
38
+ import { DitoTrigger } from '@ditojs/ui/src'
39
39
  import DitoTypeComponent from '../DitoTypeComponent.js'
40
40
  import { getSchemaAccessor } from '../utils/accessor.js'
41
41
 
@@ -48,7 +48,7 @@ SketchPicker.computed.hex = function () {
48
48
 
49
49
  // @vue/component
50
50
  export default DitoTypeComponent.register('color', {
51
- components: { Trigger, SketchPicker },
51
+ components: { DitoTrigger, SketchPicker },
52
52
 
53
53
  data() {
54
54
  return {
@@ -224,11 +224,11 @@ $color-swatch-radius: $border-radius - $border-width;
224
224
  }
225
225
  }
226
226
 
227
- .dito-button-clear {
227
+ .dito-button--clear {
228
228
  margin-right: $color-swatch-width;
229
229
  }
230
230
 
231
- .dito-color-picker {
231
+ &__picker {
232
232
  margin: $popup-margin;
233
233
  border: $border-style;
234
234
  border-radius: $border-radius;
@@ -236,7 +236,7 @@ $color-swatch-radius: $border-radius - $border-width;
236
236
  box-shadow: $shadow-window;
237
237
  }
238
238
 
239
- .dito-color-preview {
239
+ &__preview {
240
240
  background: $pattern-transparency;
241
241
  border-left: $border-style;
242
242
 
@@ -251,5 +251,11 @@ $color-swatch-radius: $border-radius - $border-width;
251
251
  border-bottom-right-radius: $color-swatch-radius;
252
252
  }
253
253
  }
254
+
255
+ // Inherit input focus state
256
+ .dito-input:focus-within &__preview,
257
+ .dito-input--focus &__preview {
258
+ border-left-color: $color-active;
259
+ }
254
260
  }
255
261
  </style>