@conduction/nextcloud-vue 2.90.0 → 2.92.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 (88) hide show
  1. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +10 -5
  2. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  3. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  4. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  5. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +15 -1
  6. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  7. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +1 -1
  8. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  9. package/dist/esm/components/CnDialog/CnDialog.vue2.js +1 -1
  10. package/dist/esm/components/CnDialog/CnDialog.vue2.js.map +1 -1
  11. package/dist/esm/components/CnDialog/CnDialog.vue3.js.map +1 -1
  12. package/dist/esm/components/CnDialogHeader/CnDialogHeader.vue2.js +1 -1
  13. package/dist/esm/components/CnDialogHeader/CnDialogHeader.vue2.js.map +1 -1
  14. package/dist/esm/components/CnDialogHeader/CnDialogHeader.vue3.js.map +1 -1
  15. package/dist/esm/components/CnFormDialog/CnFormDialog.vue.js +1 -1
  16. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +18 -10
  17. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  18. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +16 -8
  19. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  20. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +1 -1
  21. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +16 -1
  22. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -1
  23. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +1 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -1
  25. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue.js +1 -1
  26. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js +156 -3
  27. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js.map +1 -1
  28. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js +168 -52
  29. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js.map +1 -1
  30. package/dist/esm/components/CnModuleCard/CnModuleCard.vue.js +9 -0
  31. package/dist/esm/components/CnModuleCard/CnModuleCard.vue.js.map +1 -0
  32. package/dist/esm/components/CnModuleCard/CnModuleCard.vue2.js +83 -0
  33. package/dist/esm/components/CnModuleCard/CnModuleCard.vue2.js.map +1 -0
  34. package/dist/esm/components/CnModuleCard/CnModuleCard.vue3.js +119 -0
  35. package/dist/esm/components/CnModuleCard/CnModuleCard.vue3.js.map +1 -0
  36. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue.js +1 -1
  37. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js +6 -3
  38. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js.map +1 -1
  39. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue3.js.map +1 -1
  40. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  41. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +33 -2
  42. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  43. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  44. package/dist/esm/components/CnTextWidget/CnTextWidget.vue.js +1 -1
  45. package/dist/esm/components/CnTextWidget/CnTextWidget.vue2.js +63 -4
  46. package/dist/esm/components/CnTextWidget/CnTextWidget.vue2.js.map +1 -1
  47. package/dist/esm/components/CnTextWidget/CnTextWidget.vue3.js +19 -2
  48. package/dist/esm/components/CnTextWidget/CnTextWidget.vue3.js.map +1 -1
  49. package/dist/esm/index.js +2 -0
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/l10n/en.json.js +22 -1
  52. package/dist/esm/l10n/en.json.js.map +1 -1
  53. package/dist/esm/l10n/nl.json.js +21 -1
  54. package/dist/esm/l10n/nl.json.js.map +1 -1
  55. package/dist/esm/library-style.js +1 -1
  56. package/dist/esm/nextcloud-vue.css +328 -114
  57. package/dist/esm/utils/boardDate.js +35 -1
  58. package/dist/esm/utils/boardDate.js.map +1 -1
  59. package/dist/esm/utils/fillTemplate.js +12 -3
  60. package/dist/esm/utils/fillTemplate.js.map +1 -1
  61. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  62. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  63. package/dist/nextcloud-vue.cjs.js +11569 -10871
  64. package/dist/nextcloud-vue.cjs.js.map +2 -2
  65. package/dist/nextcloud-vue.css +328 -114
  66. package/l10n/en.json +22 -1
  67. package/l10n/nl.json +21 -1
  68. package/package.json +1 -1
  69. package/src/components/CnDataTable/CnDataTable.vue +10 -5
  70. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +16 -2
  71. package/src/components/CnDialog/CnDialog.vue +1 -1
  72. package/src/components/CnDialog/index.js +7 -0
  73. package/src/components/CnDialogHeader/CnDialogHeader.vue +1 -1
  74. package/src/components/CnDialogHeader/index.js +7 -0
  75. package/src/components/CnFormDialog/CnFormDialog.md +1 -0
  76. package/src/components/CnFormDialog/CnFormDialog.vue +13 -0
  77. package/src/components/CnIndexPage/CnIndexPageWidgets.vue +17 -2
  78. package/src/components/CnLinkCardsPage/CnLinkCardsPage.vue +338 -5
  79. package/src/components/CnModuleCard/CnModuleCard.vue +258 -0
  80. package/src/components/CnObjectSidebar/CnObjectSidebar.vue +6 -3
  81. package/src/components/CnTabsWidget/CnTabsWidget.vue +33 -2
  82. package/src/components/CnTextWidget/CnTextWidget.vue +89 -4
  83. package/src/components/index.js +2 -0
  84. package/src/index.js +2 -0
  85. package/src/schemas/app-manifest-v2.schema.json +59 -2
  86. package/src/utils/boardDate.js +34 -0
  87. package/src/utils/fillTemplate.js +12 -3
  88. package/src/utils/validateManifestV2.compiled.js +3 -3
package/l10n/en.json CHANGED
@@ -499,6 +499,7 @@
499
499
  "NC Activity is currently unavailable.": "NC Activity is currently unavailable.",
500
500
  "Could not load activity.": "Could not load activity.",
501
501
  "Today": "Today",
502
+ "Today, {date}": "Today, {date}",
502
503
  "Last 8 hours": "Last 8 hours",
503
504
  "Last 24 hours": "Last 24 hours",
504
505
  "Last 7 days": "Last 7 days",
@@ -1473,7 +1474,27 @@
1473
1474
  "Link related object": "Link related object",
1474
1475
  "{type} parts": "{type} parts",
1475
1476
  "Cannot save: this record has no id, so the edit would create a duplicate instead of updating it.": "Cannot save: this record has no id, so the edit would create a duplicate instead of updating it.",
1476
- "Save failed": "Save failed"
1477
+ "Save failed": "Save failed",
1478
+ "Modules": "Modules",
1479
+ "In the menu": "In the menu",
1480
+ "Off": "Off",
1481
+ "Pages": "Pages",
1482
+ "Open {module}": "Open {module}",
1483
+ "{list} and {last}": "{list} and {last}",
1484
+ "%n page: {pages}": [
1485
+ "%n page: {pages}",
1486
+ "%n pages: {pages}"
1487
+ ],
1488
+ "%n page, including {pages}": [
1489
+ "%n page, including {pages}",
1490
+ "%n pages, including {pages}"
1491
+ ],
1492
+ "{on} of %n is in the menu": [
1493
+ "{on} of %n is in the menu",
1494
+ "{on} of %n are in the menu"
1495
+ ],
1496
+ "Put it in the menu:": "Put it in the menu:",
1497
+ "Admin settings": "Admin settings"
1477
1498
  },
1478
1499
  "plurals": {
1479
1500
  "{count} selected": [
package/l10n/nl.json CHANGED
@@ -521,6 +521,7 @@
521
521
  "NC Activity is currently unavailable.": "NC Activiteit is momenteel niet beschikbaar.",
522
522
  "Could not load activity.": "Kon activiteit niet laden.",
523
523
  "Today": "Vandaag",
524
+ "Today, {date}": "Vandaag, {date}",
524
525
  "Last 8 hours": "Laatste 8 uur",
525
526
  "Last 24 hours": "Laatste 24 uur",
526
527
  "Last 7 days": "Laatste 7 dagen",
@@ -1660,7 +1661,26 @@
1660
1661
  "Link related object": "Gerelateerd object koppelen",
1661
1662
  "{type} parts": "Onderdelen van {type}",
1662
1663
  "Cannot save: this record has no id, so the edit would create a duplicate instead of updating it.": "Opslaan kan niet: dit record heeft geen id, dus de wijziging zou een kopie maken in plaats van het record bij te werken.",
1663
- "Save failed": "Opslaan is mislukt"
1664
+ "Save failed": "Opslaan is mislukt",
1665
+ "Modules": "Modules",
1666
+ "In the menu": "In het menu",
1667
+ "Off": "Uit",
1668
+ "Pages": "Pagina's",
1669
+ "Open {module}": "{module} openen",
1670
+ "{list} and {last}": "{list} en {last}",
1671
+ "%n page: {pages}": [
1672
+ "%n pagina: {pages}",
1673
+ "%n pagina's: {pages}"
1674
+ ],
1675
+ "%n page, including {pages}": [
1676
+ "%n pagina, waaronder {pages}",
1677
+ "%n pagina's, waaronder {pages}"
1678
+ ],
1679
+ "{on} of %n is in the menu": [
1680
+ "{on} van %n staat in het menu",
1681
+ "{on} van %n staan in het menu"
1682
+ ],
1683
+ "Put it in the menu:": "In het menu zetten:"
1664
1684
  },
1665
1685
  "plurals": {
1666
1686
  "{count} selected": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conduction/nextcloud-vue",
3
- "version": "2.90.0",
3
+ "version": "2.92.0",
4
4
  "description": "Shared Vue component library for Conduction Nextcloud apps — complements @nextcloud/vue with higher-level components, OpenRegister integration, and NL Design System support",
5
5
  "homepage": "https://github.com/ConductionNL/nextcloud-vue#readme",
6
6
  "bugs": {
@@ -404,6 +404,7 @@ import CnColumnFilterPopover from './CnColumnFilterPopover.vue'
404
404
  import { useClickDragGuard } from '../../composables/useClickDragGuard.js'
405
405
  import { normalizeLook } from '../../composables/useLook.js'
406
406
  import { clearedColumnFilterParams, columnFilterDef, columnFilterParams, columnFilterState, isColumnFilterActive, isColumnSortable } from '../../utils/columnFilters.js'
407
+ import { fillTemplate } from '../../utils/fillTemplate.js'
407
408
  import { lensUnavailableText, readLensReports } from '../../utils/lensAvailability.js'
408
409
  import { followLinkClick, openRowTarget, resolveHref } from '../../utils/linkNavigation.js'
409
410
  import { nextSortState } from '../../utils/multiColumnSort.js'
@@ -561,8 +562,8 @@ export default {
561
562
  *
562
563
  * `secondary` draws a second, muted line under the cell's value: a field
563
564
  * key (`"number"`), a template with `{field}` placeholders
564
- * (`"{number} · {requester}"`, dotted paths allowed), or a function of
565
- * the row. Empty fields leave their placeholder blank; a line that
565
+ * (`"{number} · {requester}"`, dotted paths allowed; `{startAt|weekday}`
566
+ * formats through `fillTemplate`), or a function of the row. Empty fields leave their placeholder blank; a line that
566
567
  * resolves to nothing is not drawn.
567
568
  *
568
569
  * @type {Array<{key: string, label: string, description: string, sortable: boolean, width: string, class: string, cellClass: string, secondary: (string|((row: object) => string))}|string>}
@@ -1769,8 +1770,10 @@ export default {
1769
1770
  /**
1770
1771
  * The secondary line of a cell, from `col.secondary`: a function is
1771
1772
  * called with the row; a string with `{field}` placeholders is a
1772
- * template filled from the row (dotted paths allowed); any other
1773
- * string is a field key. Returns '' when there is nothing to draw.
1773
+ * template filled from the row (dotted paths allowed), where a
1774
+ * `{field|format}` token is formatted by `fillTemplate` ("{startAt|weekday}"
1775
+ * reads "wo 7 okt"); any other string is a field key. Returns '' when
1776
+ * there is nothing to draw.
1774
1777
  *
1775
1778
  * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-table-column-carries-a-secondary-line
1776
1779
  * @param {object} row The row.
@@ -1787,7 +1790,9 @@ export default {
1787
1790
  return ''
1788
1791
  }
1789
1792
  if (spec.includes('{')) {
1790
- const filled = fillSecondaryTemplate(spec, (key) => this.secondaryFieldText(row, key))
1793
+ const filled = fillSecondaryTemplate(spec, (key) => (key.includes('|')
1794
+ ? fillTemplate(`{${key}}`, row)
1795
+ : this.secondaryFieldText(row, key)))
1791
1796
  // A template whose every field is empty leaves only separators:
1792
1797
  // nothing worth a line.
1793
1798
  return /[\p{L}\p{N}]/u.test(filled) ? filled.trim() : ''
@@ -236,7 +236,7 @@
236
236
  <template v-if="widget.icon" #title-icon>
237
237
  <CnIcon :name="widget.icon" :size="20" />
238
238
  </template>
239
- <component :is="renderer" :content="content" v-bind="content" />
239
+ <component :is="renderer" :content="content" v-bind="declaredContent" />
240
240
  </CnWidgetWrapper>
241
241
 
242
242
  <!-- Every other content-driven catalog widget, and every bare-mode
@@ -276,6 +276,7 @@ import { useIntegrationRegistry } from '../../composables/useIntegrationRegistry
276
276
  import { normalizeLook } from '../../composables/useLook.js'
277
277
  import { isAppInstalled } from '../../utils/appInstalled.js'
278
278
  import { widgetHeaderLink } from '../../utils/contentHeaderLink.js'
279
+ import { pickDeclaredProps } from '../../utils/declaredProps.js'
279
280
  import { unwrapAppConfig } from '../../utils/formatMetric.js'
280
281
  import { isActivityWidget } from '../../utils/headerMeta.js'
281
282
  import { PANEL_ACTION_SINK } from '../../utils/panelActions.js'
@@ -997,7 +998,20 @@ export default {
997
998
  if (title) {
998
999
  base.title = title
999
1000
  }
1000
- return { ...base, ...this.content }
1001
+ return { ...base, ...this.declaredContent }
1002
+ },
1003
+
1004
+ /**
1005
+ * The content keys the renderer declares as props. An undeclared key
1006
+ * would fall through as an attribute onto the renderer's root and could
1007
+ * override a value the widget computes there; the whole content still
1008
+ * arrives as `content`.
1009
+ *
1010
+ * @return {object} The declared content keys.
1011
+ * @spec openspec/changes/declared-props-detail-index-sidebar/specs/widget-hosts/spec.md#requirement-a-widget-host-passes-only-the-keys-a-widget-declares
1012
+ */
1013
+ declaredContent() {
1014
+ return pickDeclaredProps(this.renderer, this.content, this.widget?.type || '')
1001
1015
  },
1002
1016
 
1003
1017
  /**
@@ -32,7 +32,7 @@ import { useLook } from '../../composables/useLook.js'
32
32
  import { resolveDialogWidth } from '../../utils/dialogWidths.js'
33
33
 
34
34
  /**
35
- * CnDialog (internal) - the one place where a `Cn*` dialog turns into the
35
+ * CnDialog - the one place where a `Cn*` dialog turns into the
36
36
  * board dialog (screens-dialog-parity).
37
37
  *
38
38
  * In the Nextcloud look it is `NcDialog` with the caller's `size`, unchanged.
@@ -0,0 +1,7 @@
1
+ // SPDX-FileCopyrightText: 2026 Conduction B.V.
2
+ // SPDX-License-Identifier: EUPL-1.2
3
+
4
+ import CnDialog from './CnDialog.vue'
5
+
6
+ export default CnDialog
7
+ export { CnDialog }
@@ -45,7 +45,7 @@ import { NcButton } from '@nextcloud/vue'
45
45
  import Close from 'vue-material-design-icons/Close.vue'
46
46
 
47
47
  /**
48
- * CnDialogHeader (internal) - the board dialog header: eyebrow, 20px title,
48
+ * CnDialogHeader - the board dialog header: eyebrow, 20px title,
49
49
  * subtitle and a round 36px close button.
50
50
  *
51
51
  * The close button emits `close` and is disabled while `noClose` is set, so a
@@ -0,0 +1,7 @@
1
+ // SPDX-FileCopyrightText: 2026 Conduction B.V.
2
+ // SPDX-License-Identifier: EUPL-1.2
3
+
4
+ import CnDialogHeader from './CnDialogHeader.vue'
5
+
6
+ export default CnDialogHeader
7
+ export { CnDialogHeader }
@@ -169,6 +169,7 @@ All user-visible strings have props so they can be pre-translated by the consume
169
169
  | `cancelLabel` | `'Cancel'` | Label for the dismiss button before the action is confirmed. |
170
170
  | `closeLabel` | `'Close'` | Label for the dismiss button after the result is shown. |
171
171
  | `confirmLabel` | `''` | Confirm button label. Defaults to `'Create'` or `'Save'` depending on mode. |
172
+ | `confirmIcon` | `''` | MDI icon name on the Confirm button (`SwapHorizontal`, `Archive`, `Send`, `Gavel`). Defaults to Plus when creating, else a save icon. |
172
173
  | `feedback` | `true` | Toast the write: "Saved {title}" on success, the server's message on failure. `false` suppresses the toasts only. |
173
174
  | `confirmDisabled` | `false` | Keep the Confirm button disabled regardless of the form state. |
174
175
 
@@ -758,6 +758,11 @@
758
758
  @click="executeConfirm">
759
759
  <template #icon>
760
760
  <NcLoadingIcon v-if="loading" :size="20" />
761
+ <CnIcon
762
+ v-else-if="confirmIcon"
763
+ :name="confirmIcon"
764
+ :size="20"
765
+ data-testid="cn-form-dialog-confirm-icon" />
761
766
  <Plus v-else-if="isCreateMode" :size="20" />
762
767
  <ContentSaveOutline v-else :size="20" />
763
768
  </template>
@@ -781,6 +786,7 @@ import CnDurationField from '../CnDurationField/CnDurationField.vue'
781
786
  import CnFieldHelper from '../CnFieldHelper/CnFieldHelper.vue'
782
787
  import CnFileField from '../CnFileField/CnFileField.vue'
783
788
  import CnFormField from '../CnFormField/CnFormField.vue'
789
+ import CnIcon from '../CnIcon/CnIcon.vue'
784
790
  import CnIconBrowser from '../CnIconBrowser/CnIconBrowser.vue'
785
791
  import CnJsonViewer from '../CnJsonViewer/CnJsonViewer.vue'
786
792
  import CnPropertySourceField from '../CnPropertySourceField/CnPropertySourceField.vue'
@@ -1023,6 +1029,7 @@ export default {
1023
1029
  CnSubObjectsField,
1024
1030
  CnChildRecordsField,
1025
1031
  CnDialog,
1032
+ CnIcon,
1026
1033
  CnFormField,
1027
1034
  NcButton,
1028
1035
  NcNoteCard,
@@ -1303,6 +1310,12 @@ export default {
1303
1310
  default: '',
1304
1311
  },
1305
1312
 
1313
+ /** MDI icon name on the Confirm button (`SwapHorizontal`, `Archive`, `Send`, `Gavel`). Defaults to Plus when creating, else a save icon. */
1314
+ confirmIcon: {
1315
+ type: String,
1316
+ default: '',
1317
+ },
1318
+
1306
1319
  /** Keep the Confirm button disabled regardless of the form state, for a host that knows the form cannot be completed. */
1307
1320
  confirmDisabled: {
1308
1321
  type: Boolean,
@@ -34,7 +34,7 @@
34
34
  :is="entry.renderer"
35
35
  :widgetId="entry.id"
36
36
  :content="entry.content"
37
- v-bind="entry.content" />
37
+ v-bind="declaredContent(entry)" />
38
38
  </CnWidgetWrapper>
39
39
  </div>
40
40
  </component>
@@ -43,6 +43,7 @@
43
43
  <script>
44
44
  import CnKpiGrid from '../CnKpiGrid/CnKpiGrid.vue'
45
45
  import CnWidgetWrapper from '../CnWidgetWrapper/CnWidgetWrapper.vue'
46
+ import { pickDeclaredProps } from '../../utils/declaredProps.js'
46
47
  import { canonicalWidgetType } from '../../utils/widgetTypeAliases.js'
47
48
  import { BUILT_IN_WIDGETS } from '../CnWidgetGrid/builtInWidgets.js'
48
49
  import { getWidgetTypeEntry } from '../CnWidgetGrid/dashboardWidgetRegistry.js'
@@ -89,7 +90,7 @@ export default {
89
90
  * The renderable entries, in the listed order.
90
91
  *
91
92
  * @spec openspec/changes/screens-index-stat-row/specs/index-page/spec.md#requirement-an-index-page-can-draw-a-stat-row-above-the-list
92
- * @return {Array<{id: string, title: string, content: object, headerLink: (object|null), renderer: object}>}
93
+ * @return {Array<{id: string, type: string, title: string, content: object, headerLink: (object|null), renderer: object}>}
93
94
  */
94
95
  entries() {
95
96
  const list = Array.isArray(this.widgets) ? this.widgets : []
@@ -109,6 +110,7 @@ export default {
109
110
  const translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (key) => key
110
111
  out.push({
111
112
  id: def.id,
113
+ type: def.type,
112
114
  title: typeof def.title === 'string' && def.title !== '' ? translate(def.title) : '',
113
115
  content: (def.content && typeof def.content === 'object') ? def.content : {},
114
116
  headerLink: (def.headerLink && typeof def.headerLink === 'object') ? def.headerLink : null,
@@ -120,6 +122,19 @@ export default {
120
122
  },
121
123
 
122
124
  methods: {
125
+ /**
126
+ * The content keys an entry's renderer declares as props. An undeclared
127
+ * key would fall through onto the renderer's root; the whole content
128
+ * still arrives as `content`.
129
+ *
130
+ * @param {{ renderer: object, content: object, type?: string, id: string }} entry A resolved entry.
131
+ * @return {object} The declared content keys.
132
+ * @spec openspec/changes/declared-props-detail-index-sidebar/specs/widget-hosts/spec.md#requirement-a-widget-host-passes-only-the-keys-a-widget-declares
133
+ */
134
+ declaredContent(entry) {
135
+ return pickDeclaredProps(entry.renderer, entry.content, entry.type || entry.id)
136
+ },
137
+
123
138
  /**
124
139
  * Resolve a widget type: the consumer registry, then the dashboard
125
140
  * catalog (the type as written, then its alias), then the built-ins.