apostrophe 4.11.2 → 4.13.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 (78) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/lib/moog.js +8 -0
  3. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +1 -1
  4. package/modules/@apostrophecms/asset/index.js +7 -1
  5. package/modules/@apostrophecms/asset/lib/globalIcons.js +2 -1
  6. package/modules/@apostrophecms/color-field/index.js +13 -1
  7. package/modules/@apostrophecms/color-field/ui/apos/components/AposColor.vue +70 -31
  8. package/modules/@apostrophecms/color-field/ui/apos/components/AposInputColor.vue +25 -20
  9. package/modules/@apostrophecms/color-field/ui/apos/lib/AposColorAlpha.vue +1 -6
  10. package/modules/@apostrophecms/color-field/ui/apos/lib/AposColorHue.vue +1 -1
  11. package/modules/@apostrophecms/color-field/ui/apos/lib/AposColorInfo.vue +62 -0
  12. package/modules/@apostrophecms/color-field/ui/apos/logic/AposInputColor.js +15 -36
  13. package/modules/@apostrophecms/color-field/ui/apos/mixins/AposColorMixin.js +8 -1
  14. package/modules/@apostrophecms/doc-type/index.js +3 -1
  15. package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +8 -3
  16. package/modules/@apostrophecms/file/index.js +1 -0
  17. package/modules/@apostrophecms/file-tag/index.js +1 -0
  18. package/modules/@apostrophecms/http/lib/big-upload-middleware.js +34 -34
  19. package/{lib → modules/@apostrophecms/http/ui/apos}/big-upload-client.js +18 -4
  20. package/modules/@apostrophecms/http/ui/apos/package.json +4 -0
  21. package/modules/@apostrophecms/i18n/i18n/de.json +0 -1
  22. package/modules/@apostrophecms/i18n/i18n/en.json +16 -1
  23. package/modules/@apostrophecms/i18n/i18n/es.json +0 -1
  24. package/modules/@apostrophecms/i18n/i18n/fr.json +0 -1
  25. package/modules/@apostrophecms/i18n/i18n/it.json +0 -1
  26. package/modules/@apostrophecms/i18n/i18n/pt-BR.json +0 -1
  27. package/modules/@apostrophecms/i18n/i18n/sk.json +0 -1
  28. package/modules/@apostrophecms/i18n/index.js +397 -0
  29. package/modules/@apostrophecms/i18n/ui/apos/apps/AposI18nBatchReporting.js +161 -0
  30. package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +274 -52
  31. package/modules/@apostrophecms/image/index.js +1 -0
  32. package/modules/@apostrophecms/image-tag/index.js +1 -0
  33. package/modules/@apostrophecms/job/index.js +1 -2
  34. package/modules/@apostrophecms/modal/index.js +2 -1
  35. package/modules/@apostrophecms/modal/ui/apos/apps/AposModals.js +1 -0
  36. package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +9 -2
  37. package/modules/@apostrophecms/modal/ui/apos/components/AposModalReport.vue +414 -0
  38. package/modules/@apostrophecms/module/index.js +1 -0
  39. package/modules/@apostrophecms/notification/index.js +8 -13
  40. package/modules/@apostrophecms/notification/ui/apos/apps/AposNotification.js +5 -0
  41. package/modules/@apostrophecms/notification/ui/apos/components/AposNotification.vue +110 -148
  42. package/modules/@apostrophecms/notification/ui/apos/components/TheAposNotifications.vue +10 -91
  43. package/modules/@apostrophecms/page/index.js +24 -1
  44. package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +2 -1
  45. package/modules/@apostrophecms/piece-type/index.js +33 -2
  46. package/modules/@apostrophecms/piece-type/ui/apos/components/AposUtilityOperations.vue +1 -0
  47. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapColor.vue +23 -52
  48. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapStyles.vue +1 -0
  49. package/modules/@apostrophecms/schema/index.js +222 -79
  50. package/modules/@apostrophecms/schema/lib/addFieldTypes.js +12 -11
  51. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRange.vue +99 -66
  52. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRelationship.vue +3 -1
  53. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +40 -30
  54. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +1 -0
  55. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +25 -21
  56. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRange.js +27 -16
  57. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputWrapper.js +3 -0
  58. package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +27 -23
  59. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputChoicesMixin.js +4 -3
  60. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputMixin.js +10 -4
  61. package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +3 -2
  62. package/modules/@apostrophecms/ui/ui/apos/components/AposButtonSplit.vue +50 -53
  63. package/modules/@apostrophecms/ui/ui/apos/components/AposColorCheckerboard.vue +20 -0
  64. package/modules/@apostrophecms/ui/ui/apos/components/AposTable.vue +346 -0
  65. package/modules/@apostrophecms/ui/ui/apos/scss/global/_inputs.scss +3 -2
  66. package/modules/@apostrophecms/ui/ui/apos/scss/global/_theme.scss +4 -0
  67. package/modules/@apostrophecms/ui/ui/apos/scss/mixins/_zindex.scss +1 -1
  68. package/modules/@apostrophecms/ui/ui/apos/stores/modal.js +13 -0
  69. package/modules/@apostrophecms/ui/ui/apos/stores/notification.js +204 -0
  70. package/modules/@apostrophecms/user/index.js +1 -0
  71. package/package.json +1 -1
  72. package/test/big-upload.js +3 -4
  73. package/test/i18n-batch.js +568 -0
  74. package/test/moog.js +47 -0
  75. package/test/relationships.js +21 -3
  76. package/test/schemas.js +549 -0
  77. package/modules/@apostrophecms/color-field/ui/apos/lib/AposColorCheckerboard.vue +0 -90
  78. package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalizeErrors.vue +0 -154
package/CHANGELOG.md CHANGED
@@ -1,10 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.13.0 (2025-02-19)
4
+
5
+ ### Adds
6
+
7
+ * Supports progress notification type, can be used when no job are involved. Manage progress state into the new `processes` entity.
8
+ * Moves global notification logic into Pinia store as well as job polling that updates processes.
9
+
10
+ ### Fixes
11
+
12
+ * Field inputs inside an array modal can now be focused/tabbed via keyboard
13
+ * Fixes admin bar overlapping widget area add menu.
14
+ * Fixed the checkered background for gauging color transparency.
15
+ * Fixes `group.operations` (batch configuration) merging between modules in the same way that `group.fields` are merged.
16
+ * The i18n manager detects the current locale correctly in some edge cases, like when the locale is changed per document (Editor Modal) and the localization manager is opened from a relationship manager via a document context menu.
17
+
18
+ ### Adds
19
+
20
+ * Add support for batch localization of pieces and pages.
21
+ * Adds type for each file uploaded by big-upload. Moves big-upload-client to `apos/ui` folder and makes it esm.
22
+ * When present, projections for reverse relationships now automatically include the special id and field storage properties for the relationship in question, allowing the related documents to be successfully returned.
23
+ * Introduce `AposModalReport` component for displaying table reports. It's accessible via `apos.report(content, options)` method and it's now used in the `@apostrophecms/i18n` module for detailed reporting after a batch localization operation.
24
+
25
+ ### Changes
26
+
27
+ * The array editor's `isModified` method is now a computed property for consistency.
28
+ * The `modal` configuration property for batch operations without a group is now accepted and works as expected in the same way as for grouped operations.
29
+ * Explicitly enable document versions for `@apostrophecms/file-tag`, `@apostrophecms/file`, `@apostrophecms/image-tag` and `@apostrophecms/image` piece types.
30
+
31
+ ### Adds
32
+
33
+ * If `error.cause` is prevent, log the property.
34
+
35
+ ## 4.12.0 (2025-01-27)
36
+
37
+ ### Fixes
38
+
39
+ * Fixes ability to change color hue by clicking the color hue bar rather than dragging the indicator.
40
+ * Prevents the rich text control bar from closing while using certain UI within the color picker.
41
+ * Saving a document via the dialog box properly refreshes the main content area when on a "show page" (when the context document is a piece rather than a page)
42
+ * Fixes the `AposButtonSplit` markup to follow the HTML5 specification, optimizes the component performance, visuals and testability.
43
+ * Fixes a case where releationship button overlaps a context menu.
44
+
45
+ ### Adds
46
+
47
+ * Ability to disable the color spectrum UI of a color picker
48
+ * Accessibility improvement for the rich text editor Typography toolbar item.
49
+ * Adds `moduleLabels` prop to `AposDocContextMenu` to pass it to opened modals from custom operations (used by templates to define labels to display on the export modal).
50
+
51
+ ### Changes
52
+
53
+ * Range style updates.
54
+ * The `pickerOptions` sub property of a color field's configuration has been merged with it's parent `options` object.
55
+ * Reworks `inline` and `micro` UI of some fields (color, range, select). Improve global inline style.
56
+ * Makes the range input being a number all the time instead of a string that we convert manually.
57
+ * Command line tasks can run before the first frontend asset build without error messages.
58
+
3
59
  ## 4.11.2 (2024-12-29)
4
60
 
5
61
  ### Fixes
6
62
 
7
63
  * Fixes a bug where images in Media manager are not selectable (click on an image does nothing) in both default and relationship mode.
64
+ * Eliminated superfluous error messages. The convert method now waits for all recursive invocations to complete before attempting to determine if fields are visible.
65
+
66
+ ### Adds
67
+
68
+ * Possibility to set a field not ready when performing async operations, when a field isn't ready, the validation and emit won't occur.
8
69
 
9
70
  ## 4.11.1 (2024-12-18)
10
71
 
@@ -22,7 +83,6 @@
22
83
  * Adds option to disable `tabindex` on `AposToggle` component. A new prop `disableFocus` can be set to `false` to disable the focus on the toggle button. It's enabled by default.
23
84
  * Adds support for event on `addContextOperation`, an option `type` can now be passed and can be `modal` (default) or `event`, in this case it does not try to open a modal but emit a bus event using the action as name.
24
85
 
25
-
26
86
  ### Fixes
27
87
 
28
88
  * Focus properly Widget Editor modals when opened. Keep the previous active focus on the modal when closing the widget editor.
package/lib/moog.js CHANGED
@@ -232,6 +232,10 @@ module.exports = function(options) {
232
232
  if (properties.group) {
233
233
  const groups = klona(that[`${cascade}Groups`]);
234
234
  for (const value of Object.values(properties.group)) {
235
+ // Handle `operations` alias of `fields`. Only one of them should be used.
236
+ if (Array.isArray(value.operations)) {
237
+ value.fields = value.operations;
238
+ }
235
239
  for (const field of value.fields || []) {
236
240
  // Remove fields from existing groups if they're added to a new
237
241
  // group.
@@ -252,6 +256,10 @@ module.exports = function(options) {
252
256
  value.fields = groups[key].fields.concat(value.fields);
253
257
  value.label = value.label || groups[key].label;
254
258
  }
259
+ // Copy back `fields` to `operations` (alias).
260
+ if (Array.isArray(value.operations)) {
261
+ value.operations = value.fields;
262
+ }
255
263
  }
256
264
 
257
265
  that[`${cascade}Groups`] = {
@@ -518,7 +518,7 @@ export default {
518
518
  }
519
519
  }
520
520
 
521
- // Check that refresh hasn't been disbled for this page type
521
+ // Check that refresh hasn't been disabled for this page type
522
522
  const contextOptions = this.context
523
523
  ? apos.modules[this.context.type]
524
524
  : { contentChangedRefresh: true };
@@ -248,6 +248,7 @@ module.exports = {
248
248
  usage: 'Build Apostrophe frontend CSS and JS bundles',
249
249
  afterModuleInit: true,
250
250
  async task(argv = {}) {
251
+ self.inBuildTask = true;
251
252
  if (self.hasBuildModule()) {
252
253
  return self.build(argv);
253
254
  }
@@ -645,9 +646,14 @@ module.exports = {
645
646
  const buildOptions = self.getBuildOptions();
646
647
  const entrypoints = await self.getBuildModule().entrypoints(buildOptions);
647
648
 
649
+ // Command line tasks other than the asset build task do not display a warning
650
+ // if there is no manifest from a previous build attempt as they do not depend
651
+ // on the manifest to succeed
652
+ const silent = self.apos.isTask() && !self.inBuildTask;
648
653
  const {
649
654
  manifest = [], devServerUrl, hmrTypes
650
- } = await self.loadSavedBuildManifest();
655
+ } = await self.loadSavedBuildManifest(silent);
656
+
651
657
  self.currentBuildManifest.devServerUrl = devServerUrl;
652
658
  self.currentBuildManifest.hmrTypes = hmrTypes ?? [];
653
659
 
@@ -61,8 +61,8 @@ module.exports = {
61
61
  'format-list-numbered-icon': 'FormatListNumbered',
62
62
  'format-quote-close-icon': 'FormatQuoteClose',
63
63
  'format-strikethrough-variant-icon': 'FormatStrikethroughVariant',
64
- 'format-superscript-icon': 'FormatSuperscript',
65
64
  'format-subscript-icon': 'FormatSubscript',
65
+ 'format-superscript-icon': 'FormatSuperscript',
66
66
  'format-text-icon': 'FormatText',
67
67
  'format-underline-icon': 'FormatUnderline',
68
68
  'help-circle-icon': 'HelpCircle',
@@ -122,5 +122,6 @@ module.exports = {
122
122
  'unfold-more-horizontal-icon': 'UnfoldMoreHorizontal',
123
123
  'video-icon': 'Video',
124
124
  'view-column-icon': 'ViewColumn',
125
+ 'water-off-icon': 'WaterOff',
125
126
  'web-icon': 'Web'
126
127
  };
@@ -10,6 +10,17 @@ module.exports = {
10
10
  self.name = self.options.name;
11
11
  self.addFieldType();
12
12
  self.enableBrowserData();
13
+ self.defaultOptions = {
14
+ format: 'hex8',
15
+ disableAlpha: false,
16
+ disableFields: false,
17
+ disableSpectrum: false,
18
+ presetColors: [
19
+ '#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321',
20
+ '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2',
21
+ '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF'
22
+ ]
23
+ };
13
24
  },
14
25
  methods(self) {
15
26
  return {
@@ -36,7 +47,8 @@ module.exports = {
36
47
  getBrowserData(req) {
37
48
  return {
38
49
  name: self.name,
39
- action: self.action
50
+ action: self.action,
51
+ defaultOptions: self.defaultOptions
40
52
  };
41
53
  }
42
54
  };
@@ -3,14 +3,22 @@
3
3
  role="application"
4
4
  aria-label="Color picker"
5
5
  class="apos-color"
6
- :class="[disableAlpha ? 'apos-color--disable-alpha' : '']"
6
+ :class="[
7
+ disableAlpha ? 'apos-color--disable-alpha' : null,
8
+ disableSpectrum ? 'apos-color--disable-spectrum' : null,
9
+ disableFields ? 'apos-color--disable-fields' : null,
10
+ !presetColors ? 'apos-color--disable-presets' : null
11
+ ]"
7
12
  >
8
- <div class="apos-color__saturation-wrap">
13
+ <div v-if="!disableSpectrum" class="apos-color__saturation-wrap">
9
14
  <Saturation :value="colors" @change="childChange" />
10
15
  </div>
11
- <div class="apos-color__controls">
16
+ <div
17
+ v-if="!(disableSpectrum && disableAlpha)"
18
+ class="apos-color__controls"
19
+ >
12
20
  <div class="apos-color__sliders">
13
- <div class="apos-color__hue-wrap">
21
+ <div v-if="!disableSpectrum" class="apos-color__hue-wrap">
14
22
  <Hue :value="colors" @change="childChange" />
15
23
  </div>
16
24
  <div v-if="!disableAlpha" class="apos-color__alpha-wrap">
@@ -24,7 +32,7 @@
24
32
  class="apos-color__active-color"
25
33
  :style="{ background: activeColor }"
26
34
  />
27
- <Checkboard />
35
+ <AposColorCheckerboard />
28
36
  </div>
29
37
  </div>
30
38
  <div v-if="!disableFields" class="apos-color__field">
@@ -68,6 +76,7 @@
68
76
  </div>
69
77
  </div>
70
78
  <div
79
+ v-if="presetColors"
71
80
  class="apos-color__presets"
72
81
  role="group"
73
82
  aria-label="A color preset, pick one to set as current color"
@@ -88,7 +97,7 @@
88
97
  class="apos-color__presets-color"
89
98
  @click="handlePreset(c)"
90
99
  >
91
- <Checkboard />
100
+ <AposColorCheckerboard />
92
101
  </div>
93
102
  </template>
94
103
  </div>
@@ -101,14 +110,8 @@ import editableInput from '../lib/AposColorEditableInput.vue';
101
110
  import saturation from '../lib/AposColorSaturation.vue';
102
111
  import hue from '../lib/AposColorHue.vue';
103
112
  import alpha from '../lib/AposColorAlpha.vue';
104
- import checkboard from '../lib/AposColorCheckerboard.vue';
105
113
 
106
- const presetColors = [
107
- '#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321',
108
- '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2',
109
- '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF',
110
- 'rgba(0,0,0,0)'
111
- ];
114
+ const defaultOptions = { ...apos.modules['@apostrophecms/color-field'].defaultOptions };
112
115
 
113
116
  export default {
114
117
  name: 'AposColor',
@@ -116,27 +119,61 @@ export default {
116
119
  Saturation: saturation,
117
120
  Hue: hue,
118
121
  Alpha: alpha,
119
- EditableContent: editableInput,
120
- Checkboard: checkboard
122
+ EditableContent: editableInput
121
123
  },
122
124
  mixins: [ colorMixin ],
123
125
  props: {
124
- presetColors: {
125
- type: Array,
126
+ options: {
127
+ type: Object,
126
128
  default() {
127
- return presetColors;
129
+ return defaultOptions;
128
130
  }
129
- },
130
- disableAlpha: {
131
- type: Boolean,
132
- default: false
133
- },
134
- disableFields: {
135
- type: Boolean,
136
- default: false
137
131
  }
138
132
  },
139
133
  computed: {
134
+ defaultOptions() {
135
+ return defaultOptions;
136
+ },
137
+ finalOptions() {
138
+ let final = { ...this.options };
139
+
140
+ // Handle BC `pickerOptions` sub object.
141
+ // Modern API wins out over BC conflicts
142
+ if (final.pickerOptions) {
143
+ final = {
144
+ ...final.pickerOptions,
145
+ ...final
146
+ };
147
+ delete final.pickerOptions;
148
+ }
149
+
150
+ // Normalize disabling presetColors
151
+ if (
152
+ Array.isArray(final.presetColors) &&
153
+ final.presetColors.length === 0
154
+ ) {
155
+ final.presetColors = false;
156
+ }
157
+
158
+ // If `true`, let defaults through
159
+ if (final.presetColors === true) {
160
+ delete final.presetColors;
161
+ }
162
+
163
+ return Object.assign({ ...this.defaultOptions }, final);
164
+ },
165
+ presetColors() {
166
+ return this.finalOptions.presetColors;
167
+ },
168
+ disableAlpha() {
169
+ return this.finalOptions.disableAlpha;
170
+ },
171
+ disableSpectrum() {
172
+ return this.finalOptions.disableSpectrum;
173
+ },
174
+ disableFields() {
175
+ return this.finalOptions.disableFields;
176
+ },
140
177
  hex() {
141
178
  let hex;
142
179
  if (this.colors.a < 1) {
@@ -201,6 +238,12 @@ export default {
201
238
  box-shadow: 0 0 0 1px rgb(0 0 0 / 15%), 0 8px 16px rgb(0 0 0 / 15%);
202
239
  }
203
240
 
241
+ .apos-color--disable-alpha.apos-color--disable-spectrum.apos-color--disable-fields {
242
+ .apos-color__presets {
243
+ border-top: none;
244
+ }
245
+ }
246
+
204
247
  .apos-color__saturation-wrap {
205
248
  position: relative;
206
249
  overflow: hidden;
@@ -251,10 +294,6 @@ export default {
251
294
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 15%), inset 0 0 4px rgb(0 0 0 / 25%);
252
295
  }
253
296
 
254
- .apos-color__color-wrap .apos-color__checkerboard {
255
- background-size: auto;
256
- }
257
-
258
297
  .apos-color__field {
259
298
  display: flex;
260
299
  padding-top: 4px;
@@ -308,7 +347,7 @@ export default {
308
347
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 15%);
309
348
  }
310
349
 
311
- .apos-color__presets-color .apos-color__checkerboard {
350
+ .apos-color__presets-color {
312
351
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 15%);
313
352
  border-radius: 3px;
314
353
  }
@@ -8,6 +8,13 @@
8
8
  >
9
9
  <template #body>
10
10
  <div class="apos-input-color">
11
+ <AposColorInfo
12
+ v-if="isInline"
13
+ class="apos-input-color__info apos-input-color__info--inline"
14
+ :value="next"
15
+ :is-micro="isMicro"
16
+ @clear="clear"
17
+ />
11
18
  <div class="apos-input-color__ui">
12
19
  <AposContextMenu
13
20
  :button="buttonOptions"
@@ -18,23 +25,19 @@
18
25
  @close="close"
19
26
  >
20
27
  <AposColor
21
- v-bind="pickerOptions"
28
+ :options="options"
22
29
  :model-value="pickerValue"
23
30
  @update:model-value="update"
24
31
  />
25
32
  </AposContextMenu>
26
33
  </div>
27
- <div class="apos-input-color__info" data-apos-test="colorInfo">
28
- {{ valueLabel }}
29
- <AposButton
30
- v-if="next"
31
- type="quiet"
32
- label="apostrophe:clear"
33
- class="apos-input-color__clear"
34
- :modifiers="['no-motion']"
35
- @click="clear"
36
- />
37
- </div>
34
+ <AposColorInfo
35
+ v-if="!isInline"
36
+ class="apos-input-color__info"
37
+ :value="next"
38
+ :is-micro="isMicro"
39
+ @clear="clear"
40
+ />
38
41
  </div>
39
42
  </template>
40
43
  </AposInputWrapper>
@@ -42,8 +45,13 @@
42
45
 
43
46
  <script>
44
47
  import AposInputColorLogic from '../logic/AposInputColor';
48
+ import AposColorInfo from '../lib/AposColorInfo.vue';
49
+
45
50
  export default {
46
51
  name: 'AposInputColor',
52
+ components: {
53
+ AposColorInfo
54
+ },
47
55
  mixins: [ AposInputColorLogic ]
48
56
  };
49
57
  </script>
@@ -54,16 +62,13 @@ export default {
54
62
  align-items: center;
55
63
  }
56
64
 
57
- .apos-input-color__clear {
58
- margin-left: 10px;
59
- }
60
-
61
65
  .apos-input-color__info {
62
- @include type-base;
66
+ margin-left: 15px;
63
67
 
64
- & {
65
- margin-left: 15px;
66
- color: var(--a-text-primary);
68
+ &--inline {
69
+ margin-right: 5px;
70
+ margin-left: 0;
67
71
  }
68
72
  }
73
+
69
74
  </style>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="apos-color__alpha">
3
3
  <div class="apos-color__alpha-checkboard-wrap">
4
- <Checkboard />
4
+ <AposColorCheckerboard />
5
5
  </div>
6
6
  <div class="apos-color__alpha-gradient" :style="{ background: gradientColor }" />
7
7
  <div
@@ -19,13 +19,8 @@
19
19
  </template>
20
20
 
21
21
  <script>
22
- import checkboard from './AposColorCheckerboard.vue';
23
-
24
22
  export default {
25
23
  name: 'AposColorAlpha',
26
- components: {
27
- Checkboard: checkboard
28
- },
29
24
  props: {
30
25
  value: {
31
26
  type: Object,
@@ -2,7 +2,7 @@
2
2
  <div class="apos-color__hue" :class="[directionClass]">
3
3
  <div
4
4
  ref="container"
5
- class="vc-hue-container"
5
+ class="apos-color__hue-container"
6
6
  role="slider"
7
7
  :aria-valuenow="colors.hsl.h"
8
8
  aria-valuemin="0"
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <div class="apos-color-info" data-apos-test="colorInfo">
3
+ <span v-if="!isMicro">
4
+ {{ label }}
5
+ </span>
6
+ <AposButton
7
+ v-if="!isMicro && value"
8
+ type="quiet"
9
+ :label="'apostrophe:clear'"
10
+ class="apos-color-info__clear-btn"
11
+ :modifiers="['no-motion']"
12
+ @click="emit('clear')"
13
+ />
14
+ <AposIndicator
15
+ v-else-if="value"
16
+ class="apos-color-info__clear-icon"
17
+ icon="water-off-icon"
18
+ @click="emit('clear')"
19
+ />
20
+ </div>
21
+ </template>
22
+
23
+ <script setup>
24
+ import { computed } from 'vue';
25
+
26
+ const props = defineProps({
27
+ value: {
28
+ type: String,
29
+ default: null
30
+ },
31
+ isMicro: {
32
+ type: Boolean,
33
+ default: false
34
+ }
35
+ });
36
+
37
+ const label = computed(() => props.value || 'None Selected');
38
+ const emit = defineEmits([ 'clear' ]);
39
+ </script>
40
+
41
+ <style lang="scss">
42
+ .apos-color-info {
43
+ @include type-base;
44
+
45
+ & {
46
+ color: var(--a-text-primary);
47
+ }
48
+ }
49
+
50
+ .apos-color-info__clear-btn {
51
+ margin-left: 10px;
52
+ }
53
+
54
+ .apos-color-info__clear-icon {
55
+ cursor: pointer;
56
+ color: var(--a-base-2);
57
+
58
+ &:hover {
59
+ color: var(--a-primary);
60
+ }
61
+ }
62
+ </style>
@@ -12,24 +12,22 @@ export default {
12
12
  data() {
13
13
  return {
14
14
  active: false,
15
- tinyColorObj: null,
16
- startsNull: false,
17
- defaultFormat: 'hex8',
18
- defaultPickerOptions: {
19
- presetColors: [
20
- '#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321',
21
- '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2',
22
- '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF'
23
- ],
24
- disableAlpha: false,
25
- disableFields: false
26
- }
15
+ tinyColorObj: null
27
16
  };
28
17
  },
29
18
  computed: {
30
- // Color picker doesn't allow null or undefined values
19
+ isMicro() {
20
+ return this.modifiers.includes('micro');
21
+ },
22
+ isInline() {
23
+ return this.modifiers.includes('inline');
24
+ },
31
25
  pickerValue() {
32
- return this.next || '';
26
+ return this.next || this.defaultValue;
27
+ },
28
+ // Color picker doesn't allow null or undefined values
29
+ defaultValue() {
30
+ return this.field.def || '';
33
31
  },
34
32
  buttonOptions() {
35
33
  return {
@@ -38,22 +36,8 @@ export default {
38
36
  color: this.modelValue.data || ''
39
37
  };
40
38
  },
41
- format() {
42
- return this.field.options && this.field.options.format
43
- ? this.field.options.format
44
- : this.defaultFormat;
45
- },
46
- pickerOptions() {
47
- const fieldOptions = this.field.options?.pickerOptions || {};
48
- return Object.assign(this.defaultPickerOptions, fieldOptions);
49
- },
50
-
51
- valueLabel() {
52
- if (this.next) {
53
- return this.next;
54
- } else {
55
- return 'None Selected';
56
- }
39
+ options() {
40
+ return this.field?.options || {};
57
41
  },
58
42
  classList() {
59
43
  return [
@@ -75,12 +59,7 @@ export default {
75
59
  this.active = false;
76
60
  },
77
61
  update(value) {
78
- this.tinyColorObj = new TinyColor(value.hsl);
79
- if (value._cssVariable) {
80
- this.next = value._cssVariable;
81
- } else {
82
- this.next = this.tinyColorObj.toString(this.format);
83
- }
62
+ this.next = value;
84
63
  },
85
64
  validate(value) {
86
65
  if (this.field.required) {
@@ -82,8 +82,15 @@ export default {
82
82
  return this.val;
83
83
  },
84
84
  set(newVal) {
85
+ let stringVal;
86
+ if (newVal._cssVariable) {
87
+ stringVal = newVal._cssVariable;
88
+ } else {
89
+ const colorObj = tinycolor(newVal.hsl);
90
+ stringVal = colorObj.toString(this.finalOptions.format);
91
+ }
85
92
  this.val = newVal;
86
- this.$emit('update:modelValue', newVal);
93
+ this.$emit('update:modelValue', stringVal);
87
94
  }
88
95
  }
89
96
  },
@@ -1751,7 +1751,9 @@ module.exports = {
1751
1751
  const add = [];
1752
1752
  const remove = [];
1753
1753
 
1754
- // Add type in projection by default
1754
+ // Add fundamentals by default to allow Apostrophe's core
1755
+ // operations to find what they expect (determining document type,
1756
+ // distinguishing documents from widgets)
1755
1757
  const hasExclusion = Object.values(projection).some(value => !value);
1756
1758
  if (!_.isEmpty(projection) && !hasExclusion) {
1757
1759
  add.push('type');
@@ -87,6 +87,10 @@ export default {
87
87
  localeSwitched: {
88
88
  type: Boolean,
89
89
  default: false
90
+ },
91
+ moduleLabels: {
92
+ type: Object,
93
+ default: null
90
94
  }
91
95
  },
92
96
  emits: [ 'menu-open', 'menu-close', 'close' ],
@@ -207,7 +211,8 @@ export default {
207
211
 
208
212
  ifProps = ifProps || {};
209
213
  moduleIf = moduleIf || {};
210
- const canSeeOperation = checkIfConditions(this.doc, ifProps) && checkIfConditions(this.moduleOptions, moduleIf);
214
+ const canSeeOperation = checkIfConditions(this.doc, ifProps) &&
215
+ checkIfConditions(this.moduleOptions, moduleIf);
211
216
 
212
217
  if (!canSeeOperation) {
213
218
  return false;
@@ -219,9 +224,8 @@ export default {
219
224
  moduleName() {
220
225
  if (apos.modules[this.context.type].action === apos.modules['@apostrophecms/page'].action) {
221
226
  return '@apostrophecms/page';
222
- } else {
223
- return this.context.type;
224
227
  }
228
+ return this.context.type;
225
229
  },
226
230
  moduleOptions() {
227
231
  return apos.modules[this.moduleName];
@@ -446,6 +450,7 @@ export default {
446
450
  }
447
451
  const props = {
448
452
  moduleName: operation.moduleName || this.moduleName,
453
+ moduleLabels: this.moduleLabels,
449
454
  // For backwards compatibility
450
455
  doc,
451
456
  ...docProps(doc),