@conduction/nextcloud-vue 2.56.0-beta.38 → 2.56.0-beta.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +2 -0
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +36 -0
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +55 -40
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +3 -26
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +74 -53
- package/dist/esm/utils/boardReferenceColumns.js +63 -4
- package/dist/esm/utils/boardReferenceColumns.js.map +1 -1
- package/dist/esm/utils/contentHeaderLink.js +48 -1
- package/dist/esm/utils/contentHeaderLink.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +255 -121
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +74 -53
- package/package.json +1 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +2 -0
- package/src/components/CnTabsWidget/CnTabsWidget.vue +71 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +3 -26
- package/src/schemas/app-manifest-v2.schema.json +3 -1
- package/src/utils/boardReferenceColumns.js +62 -3
- package/src/utils/contentHeaderLink.js +47 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/nextcloud-vue.cjs.js.map
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 40733961 bytes
|
|
4
|
+
sha256: b2553a52f3be9cab59141f90ce15f9187f55454f0b96154befc4aab1ccf8c601
|
package/dist/nextcloud-vue.css
CHANGED
|
@@ -21010,7 +21010,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21010
21010
|
}
|
|
21011
21011
|
|
|
21012
21012
|
|
|
21013
|
-
.cn-widget-wrapper[data-v-
|
|
21013
|
+
.cn-widget-wrapper[data-v-4f6c55f6] {
|
|
21014
21014
|
position: relative;
|
|
21015
21015
|
height: 100%;
|
|
21016
21016
|
display: flex;
|
|
@@ -21024,13 +21024,13 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21024
21024
|
}
|
|
21025
21025
|
|
|
21026
21026
|
/* Headerless date chip — floated over the top-right of a flush card. */
|
|
21027
|
-
.cn-widget-wrapper__floating-meta[data-v-
|
|
21027
|
+
.cn-widget-wrapper__floating-meta[data-v-4f6c55f6] {
|
|
21028
21028
|
position: absolute;
|
|
21029
21029
|
top: 8px;
|
|
21030
21030
|
inset-inline-end: 10px;
|
|
21031
21031
|
z-index: 2;
|
|
21032
21032
|
}
|
|
21033
|
-
.cn-widget-wrapper__content[data-v-
|
|
21033
|
+
.cn-widget-wrapper__content[data-v-4f6c55f6] {
|
|
21034
21034
|
flex: 1;
|
|
21035
21035
|
overflow: auto;
|
|
21036
21036
|
min-height: 0;
|
|
@@ -21046,24 +21046,24 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21046
21046
|
So it is structural instead. `:has()` keys on the table component's own root
|
|
21047
21047
|
class, which means a table is flush by construction and no caller can
|
|
21048
21048
|
reintroduce the gap by forgetting a prop. */
|
|
21049
|
-
.cn-widget-wrapper__content[data-v-
|
|
21050
|
-
.cn-widget-wrapper__content[data-v-
|
|
21049
|
+
.cn-widget-wrapper__content[data-v-4f6c55f6]:has(> .cn-table-container),
|
|
21050
|
+
.cn-widget-wrapper__content[data-v-4f6c55f6]:has(> .cn-widget-object-table) {
|
|
21051
21051
|
padding: 0;
|
|
21052
21052
|
}
|
|
21053
21053
|
|
|
21054
21054
|
/* Keyboard focus ring for the now-focusable scrollable content region. */
|
|
21055
|
-
.cn-widget-wrapper__content[data-v-
|
|
21055
|
+
.cn-widget-wrapper__content[data-v-4f6c55f6]:focus-visible {
|
|
21056
21056
|
outline: 2px solid var(--color-primary-element);
|
|
21057
21057
|
outline-offset: -2px;
|
|
21058
21058
|
}
|
|
21059
|
-
.cn-widget-wrapper--borderless[data-v-
|
|
21059
|
+
.cn-widget-wrapper--borderless[data-v-4f6c55f6] {
|
|
21060
21060
|
border: none;
|
|
21061
21061
|
background: transparent;
|
|
21062
21062
|
}
|
|
21063
|
-
.cn-widget-wrapper--borderless .cn-widget-wrapper__content[data-v-
|
|
21063
|
+
.cn-widget-wrapper--borderless .cn-widget-wrapper__content[data-v-4f6c55f6] {
|
|
21064
21064
|
padding: 0;
|
|
21065
21065
|
}
|
|
21066
|
-
.cn-widget-wrapper--flush .cn-widget-wrapper__content[data-v-
|
|
21066
|
+
.cn-widget-wrapper--flush .cn-widget-wrapper__content[data-v-4f6c55f6] {
|
|
21067
21067
|
padding: 0;
|
|
21068
21068
|
}
|
|
21069
21069
|
|
|
@@ -21071,8 +21071,8 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21071
21071
|
above. A dashboard renders every widget `flush`, and without this their
|
|
21072
21072
|
fields touch the card's edges. Borderless and chromeless cards, and the
|
|
21073
21073
|
Nextcloud dashboard variant, keep their own padding. */
|
|
21074
|
-
.cn-widget-wrapper--flush:not(.cn-widget-wrapper--borderless, .cn-widget-wrapper--nc-dashboard) > .cn-widget-wrapper__content[data-v-
|
|
21075
|
-
.cn-widget-wrapper--flush:not(.cn-widget-wrapper--borderless, .cn-widget-wrapper--nc-dashboard) > .cn-widget-wrapper__content[data-v-
|
|
21074
|
+
.cn-widget-wrapper--flush:not(.cn-widget-wrapper--borderless, .cn-widget-wrapper--nc-dashboard) > .cn-widget-wrapper__content[data-v-4f6c55f6]:has(> .cn-form-widget),
|
|
21075
|
+
.cn-widget-wrapper--flush:not(.cn-widget-wrapper--borderless, .cn-widget-wrapper--nc-dashboard) > .cn-widget-wrapper__content[data-v-4f6c55f6]:has(> .cn-kb-search-widget) {
|
|
21076
21076
|
padding: 16px;
|
|
21077
21077
|
}
|
|
21078
21078
|
|
|
@@ -21083,7 +21083,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21083
21083
|
a square panel, which is the last visible piece of a card that is supposed
|
|
21084
21084
|
to be absent. `CnDetailCard.cn-detail-card--chromeless` zeroes the same
|
|
21085
21085
|
thing for the same reason. */
|
|
21086
|
-
.cn-widget-wrapper--chromeless[data-v-
|
|
21086
|
+
.cn-widget-wrapper--chromeless[data-v-4f6c55f6] {
|
|
21087
21087
|
border-radius: 0;
|
|
21088
21088
|
}
|
|
21089
21089
|
|
|
@@ -21095,7 +21095,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21095
21095
|
* so users can override any token. Combined selector raises specificity above
|
|
21096
21096
|
* the base `.cn-widget-wrapper` rules it supersedes.
|
|
21097
21097
|
*/
|
|
21098
|
-
.cn-widget-wrapper__header[data-v-
|
|
21098
|
+
.cn-widget-wrapper__header[data-v-4f6c55f6] {
|
|
21099
21099
|
display: flex;
|
|
21100
21100
|
align-items: center;
|
|
21101
21101
|
justify-content: space-between;
|
|
@@ -21111,7 +21111,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21111
21111
|
/* Actions with no title beside them. `header-left` is not rendered at all in
|
|
21112
21112
|
this mode, and the header is `space-between`, so a single child would sit
|
|
21113
21113
|
flush LEFT where every other surface puts its actions on the right. */
|
|
21114
|
-
.cn-widget-wrapper__header--actions-only[data-v-
|
|
21114
|
+
.cn-widget-wrapper__header--actions-only[data-v-4f6c55f6] {
|
|
21115
21115
|
justify-content: flex-end;
|
|
21116
21116
|
}
|
|
21117
21117
|
|
|
@@ -21127,11 +21127,11 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21127
21127
|
no-descending-specificity asks for. The cascade did not need it (this
|
|
21128
21128
|
selector is more specific either way), a reader does: an override written
|
|
21129
21129
|
above the thing it overrides has to be read twice. */
|
|
21130
|
-
.cn-widget-wrapper--chromeless .cn-widget-wrapper__header[data-v-
|
|
21130
|
+
.cn-widget-wrapper--chromeless .cn-widget-wrapper__header[data-v-4f6c55f6] {
|
|
21131
21131
|
border-bottom: none;
|
|
21132
21132
|
padding-inline: 0;
|
|
21133
21133
|
}
|
|
21134
|
-
.cn-widget-wrapper__header-left[data-v-
|
|
21134
|
+
.cn-widget-wrapper__header-left[data-v-4f6c55f6] {
|
|
21135
21135
|
display: flex;
|
|
21136
21136
|
align-items: center;
|
|
21137
21137
|
gap: 8px;
|
|
@@ -21140,19 +21140,19 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21140
21140
|
of centering between icon and actions (header is space-between). */
|
|
21141
21141
|
flex: 1 1 auto;
|
|
21142
21142
|
}
|
|
21143
|
-
.cn-widget-wrapper__icon[data-v-
|
|
21143
|
+
.cn-widget-wrapper__icon[data-v-4f6c55f6] {
|
|
21144
21144
|
width: 24px;
|
|
21145
21145
|
height: 24px;
|
|
21146
21146
|
flex-shrink: 0;
|
|
21147
21147
|
color: var(--cn-widget-icon-color, var(--color-primary-element));
|
|
21148
21148
|
}
|
|
21149
|
-
.cn-widget-wrapper__title-stack[data-v-
|
|
21149
|
+
.cn-widget-wrapper__title-stack[data-v-4f6c55f6] {
|
|
21150
21150
|
display: flex;
|
|
21151
21151
|
flex-direction: column;
|
|
21152
21152
|
gap: 2px;
|
|
21153
21153
|
min-width: 0;
|
|
21154
21154
|
}
|
|
21155
|
-
.cn-widget-wrapper__eyebrow[data-v-
|
|
21155
|
+
.cn-widget-wrapper__eyebrow[data-v-4f6c55f6] {
|
|
21156
21156
|
font-size: 13px;
|
|
21157
21157
|
line-height: 1.3;
|
|
21158
21158
|
color: var(--color-text-maxcontrast);
|
|
@@ -21160,7 +21160,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21160
21160
|
overflow: hidden;
|
|
21161
21161
|
text-overflow: ellipsis;
|
|
21162
21162
|
}
|
|
21163
|
-
.cn-widget-wrapper__title[data-v-
|
|
21163
|
+
.cn-widget-wrapper__title[data-v-4f6c55f6] {
|
|
21164
21164
|
font-weight: 600;
|
|
21165
21165
|
font-size: 14px;
|
|
21166
21166
|
margin: 0;
|
|
@@ -21168,34 +21168,34 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21168
21168
|
overflow: hidden;
|
|
21169
21169
|
text-overflow: ellipsis;
|
|
21170
21170
|
}
|
|
21171
|
-
.cn-widget-wrapper.cn-widget-wrapper--nc-dashboard[data-v-
|
|
21171
|
+
.cn-widget-wrapper.cn-widget-wrapper--nc-dashboard[data-v-4f6c55f6] {
|
|
21172
21172
|
background: var(--color-main-background-blur, var(--color-main-background));
|
|
21173
21173
|
-webkit-backdrop-filter: var(--filter-background-blur, none);
|
|
21174
21174
|
backdrop-filter: var(--filter-background-blur, none);
|
|
21175
21175
|
border: none;
|
|
21176
21176
|
border-radius: var(--border-radius-container-large, 16px);
|
|
21177
21177
|
}
|
|
21178
|
-
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__header[data-v-
|
|
21178
|
+
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__header[data-v-4f6c55f6] {
|
|
21179
21179
|
padding: 16px;
|
|
21180
21180
|
border-bottom: none;
|
|
21181
21181
|
}
|
|
21182
|
-
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__header-left[data-v-
|
|
21182
|
+
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__header-left[data-v-4f6c55f6] {
|
|
21183
21183
|
gap: 16px;
|
|
21184
21184
|
}
|
|
21185
|
-
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__icon[data-v-
|
|
21185
|
+
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__icon[data-v-4f6c55f6] {
|
|
21186
21186
|
width: 32px;
|
|
21187
21187
|
height: 32px;
|
|
21188
21188
|
background-size: 32px;
|
|
21189
21189
|
}
|
|
21190
|
-
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__title[data-v-
|
|
21190
|
+
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__title[data-v-4f6c55f6] {
|
|
21191
21191
|
font-size: 20px;
|
|
21192
21192
|
font-weight: 700;
|
|
21193
21193
|
line-height: 24px;
|
|
21194
21194
|
}
|
|
21195
|
-
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__content[data-v-
|
|
21195
|
+
.cn-widget-wrapper--nc-dashboard .cn-widget-wrapper__content[data-v-4f6c55f6] {
|
|
21196
21196
|
padding: 0 16px 16px;
|
|
21197
21197
|
}
|
|
21198
|
-
.cn-widget-wrapper__title-meta[data-v-
|
|
21198
|
+
.cn-widget-wrapper__title-meta[data-v-4f6c55f6] {
|
|
21199
21199
|
display: flex;
|
|
21200
21200
|
align-items: center;
|
|
21201
21201
|
gap: 4px;
|
|
@@ -21204,7 +21204,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21204
21204
|
white-space: nowrap;
|
|
21205
21205
|
flex-shrink: 0;
|
|
21206
21206
|
}
|
|
21207
|
-
.cn-widget-wrapper__actions[data-v-
|
|
21207
|
+
.cn-widget-wrapper__actions[data-v-4f6c55f6] {
|
|
21208
21208
|
display: flex;
|
|
21209
21209
|
gap: 4px;
|
|
21210
21210
|
flex-shrink: 0;
|
|
@@ -21212,7 +21212,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21212
21212
|
|
|
21213
21213
|
/* The header's text link (`headerLink`). Theme hooks: --cn-widget-header-link-size
|
|
21214
21214
|
and --cn-widget-header-link-weight. */
|
|
21215
|
-
.cn-widget-wrapper__header-link[data-v-
|
|
21215
|
+
.cn-widget-wrapper__header-link[data-v-4f6c55f6] {
|
|
21216
21216
|
align-self: center;
|
|
21217
21217
|
padding: 0 calc(1 * var(--default-grid-baseline));
|
|
21218
21218
|
color: var(--color-primary-element);
|
|
@@ -21221,11 +21221,11 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21221
21221
|
text-decoration: none;
|
|
21222
21222
|
white-space: nowrap;
|
|
21223
21223
|
}
|
|
21224
|
-
.cn-widget-wrapper__header-link[data-v-
|
|
21225
|
-
.cn-widget-wrapper__header-link[data-v-
|
|
21224
|
+
.cn-widget-wrapper__header-link[data-v-4f6c55f6]:hover,
|
|
21225
|
+
.cn-widget-wrapper__header-link[data-v-4f6c55f6]:focus-visible {
|
|
21226
21226
|
text-decoration: underline;
|
|
21227
21227
|
}
|
|
21228
|
-
.cn-widget-wrapper__header-link[data-v-
|
|
21228
|
+
.cn-widget-wrapper__header-link[data-v-4f6c55f6]:focus-visible {
|
|
21229
21229
|
outline: 2px solid var(--color-primary-element);
|
|
21230
21230
|
outline-offset: 2px;
|
|
21231
21231
|
border-radius: var(--border-radius-small, 4px);
|
|
@@ -21236,7 +21236,7 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21236
21236
|
wrapper is ever rendered without it. Material-design-icon components paint
|
|
21237
21237
|
with `fill: currentColor`, so this reaches them; the :deep rule below makes
|
|
21238
21238
|
it reach a raw <svg> in the slot too. */
|
|
21239
|
-
.cn-widget-wrapper__title-icon[data-v-
|
|
21239
|
+
.cn-widget-wrapper__title-icon[data-v-4f6c55f6] {
|
|
21240
21240
|
display: flex;
|
|
21241
21241
|
align-items: center;
|
|
21242
21242
|
flex-shrink: 0;
|
|
@@ -21256,17 +21256,17 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21256
21256
|
|
|
21257
21257
|
/* Right-positioned title icons sit AFTER the actions, so the margin belongs on
|
|
21258
21258
|
the other side or it pushes the icon off the header's right edge. */
|
|
21259
|
-
.cn-widget-wrapper__title-icon[data-v-
|
|
21259
|
+
.cn-widget-wrapper__title-icon[data-v-4f6c55f6]:last-child {
|
|
21260
21260
|
margin-inline-end: 0;
|
|
21261
21261
|
margin-inline-start: 8px;
|
|
21262
21262
|
}
|
|
21263
21263
|
|
|
21264
21264
|
/* Material-design-icon components paint with `fill: currentColor`, so the
|
|
21265
21265
|
colour above reaches them; this makes it reach a raw <svg> in the slot too. */
|
|
21266
|
-
.cn-widget-wrapper__title-icon[data-v-
|
|
21266
|
+
.cn-widget-wrapper__title-icon[data-v-4f6c55f6] svg {
|
|
21267
21267
|
fill: currentcolor;
|
|
21268
21268
|
}
|
|
21269
|
-
.cn-widget-wrapper__footer[data-v-
|
|
21269
|
+
.cn-widget-wrapper__footer[data-v-4f6c55f6] {
|
|
21270
21270
|
display: flex;
|
|
21271
21271
|
justify-content: flex-end;
|
|
21272
21272
|
gap: 8px;
|
|
@@ -21274,12 +21274,12 @@ a.cn-xwiki-card__title[data-v-1a6b61fd]:hover {
|
|
|
21274
21274
|
border-top: 1px solid var(--color-border);
|
|
21275
21275
|
flex-shrink: 0;
|
|
21276
21276
|
}
|
|
21277
|
-
.cn-widget-wrapper__footer-link[data-v-
|
|
21277
|
+
.cn-widget-wrapper__footer-link[data-v-4f6c55f6] {
|
|
21278
21278
|
font-size: 13px;
|
|
21279
21279
|
color: var(--color-primary-element);
|
|
21280
21280
|
text-decoration: none;
|
|
21281
21281
|
}
|
|
21282
|
-
.cn-widget-wrapper__footer-link[data-v-
|
|
21282
|
+
.cn-widget-wrapper__footer-link[data-v-4f6c55f6]:hover {
|
|
21283
21283
|
text-decoration: underline;
|
|
21284
21284
|
}
|
|
21285
21285
|
|
|
@@ -25328,7 +25328,7 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25328
25328
|
|
|
25329
25329
|
|
|
25330
25330
|
/* A stack (`widgetIds`): the panel's widget, then cards 20px apart. */
|
|
25331
|
-
.cn-tabs-widget__stack[data-v-
|
|
25331
|
+
.cn-tabs-widget__stack[data-v-4294c502] {
|
|
25332
25332
|
display: flex;
|
|
25333
25333
|
flex-direction: column;
|
|
25334
25334
|
gap: 20px;
|
|
@@ -25337,19 +25337,19 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25337
25337
|
/* A gridded stack (`columns` / `layout` on the tab): 12 columns, widgets wrap
|
|
25338
25338
|
onto the next row, a row's cards as tall as the tallest. Narrow, it is the
|
|
25339
25339
|
plain stack again. */
|
|
25340
|
-
.cn-tabs-widget__stack--grid[data-v-
|
|
25340
|
+
.cn-tabs-widget__stack--grid[data-v-4294c502] {
|
|
25341
25341
|
display: grid;
|
|
25342
25342
|
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
25343
25343
|
align-items: stretch;
|
|
25344
25344
|
}
|
|
25345
|
-
.cn-tabs-widget__stack--grid[data-v-
|
|
25345
|
+
.cn-tabs-widget__stack--grid[data-v-4294c502] > * {
|
|
25346
25346
|
min-width: 0;
|
|
25347
25347
|
}
|
|
25348
25348
|
@media (max-width: 700px) {
|
|
25349
|
-
.cn-tabs-widget__stack--grid[data-v-
|
|
25349
|
+
.cn-tabs-widget__stack--grid[data-v-4294c502] {
|
|
25350
25350
|
grid-template-columns: minmax(0, 1fr);
|
|
25351
25351
|
}
|
|
25352
|
-
.cn-tabs-widget__stack--grid[data-v-
|
|
25352
|
+
.cn-tabs-widget__stack--grid[data-v-4294c502] > * {
|
|
25353
25353
|
grid-column: auto !important;
|
|
25354
25354
|
}
|
|
25355
25355
|
}
|
|
@@ -25383,7 +25383,7 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25383
25383
|
`!important` or on load order this library does not control. The same
|
|
25384
25384
|
technique, for the same reason, is used on `.cn-tabs__nav .cn-tabs__nav-item`
|
|
25385
25385
|
in CnTabs to beat Nextcloud's own button margin. */
|
|
25386
|
-
.cn-tabs-widget.cn-tabs-widget[data-v-
|
|
25386
|
+
.cn-tabs-widget.cn-tabs-widget[data-v-4294c502] {
|
|
25387
25387
|
background-color: transparent;
|
|
25388
25388
|
border: 0;
|
|
25389
25389
|
border-radius: 0;
|
|
@@ -25407,12 +25407,12 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25407
25407
|
below it: the rule ran straight on to the widget's edge and read as a
|
|
25408
25408
|
border sticking out past a rounded corner (Ruben, 2026-09-13). Ending it
|
|
25409
25409
|
where the curve begins makes the rule and the curve one continuous edge. */
|
|
25410
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25410
|
+
.cn-tabs-widget__tabs[data-v-4294c502] .cn-tabs__bar {
|
|
25411
25411
|
border-bottom: none;
|
|
25412
25412
|
padding: 0;
|
|
25413
25413
|
position: relative;
|
|
25414
25414
|
}
|
|
25415
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25415
|
+
.cn-tabs-widget__tabs[data-v-4294c502] .cn-tabs__bar::after {
|
|
25416
25416
|
border-bottom: 1px solid var(--color-border);
|
|
25417
25417
|
content: '';
|
|
25418
25418
|
inset-block-end: 0;
|
|
@@ -25425,11 +25425,11 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25425
25425
|
own background-coloured bottom edge, which only works if it paints ABOVE the
|
|
25426
25426
|
pseudo-element: a positioned pseudo-element otherwise paints over every
|
|
25427
25427
|
in-flow sibling, rule included. */
|
|
25428
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25428
|
+
.cn-tabs-widget__tabs[data-v-4294c502] .cn-tabs__nav-item--active {
|
|
25429
25429
|
position: relative;
|
|
25430
25430
|
z-index: 1;
|
|
25431
25431
|
}
|
|
25432
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25432
|
+
.cn-tabs-widget__tabs[data-v-4294c502] {
|
|
25433
25433
|
display: flex;
|
|
25434
25434
|
flex-direction: column;
|
|
25435
25435
|
/* Grow to the widget's height, so the panel fills the grid cell the
|
|
@@ -25447,7 +25447,7 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25447
25447
|
the open tab, but padding sits inside the painted box — only a margin would
|
|
25448
25448
|
have opened that gap, and a zero top put every panel's content against the
|
|
25449
25449
|
strip. */
|
|
25450
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25450
|
+
.cn-tabs-widget__tabs[data-v-4294c502] .cn-tabs__content {
|
|
25451
25451
|
background-color: var(--color-main-background);
|
|
25452
25452
|
/* Three sides only: the bar's rule (redrawn above, stopping at the corner)
|
|
25453
25453
|
is this sheet's top edge, and the open tab erases the slice of it
|
|
@@ -25467,7 +25467,7 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25467
25467
|
overflow: auto;
|
|
25468
25468
|
padding: 12px;
|
|
25469
25469
|
}
|
|
25470
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25470
|
+
.cn-tabs-widget__tabs[data-v-4294c502] .cn-tab {
|
|
25471
25471
|
height: 100%;
|
|
25472
25472
|
}
|
|
25473
25473
|
|
|
@@ -25475,15 +25475,36 @@ button.cn-stepper__step[data-v-776581d4] {
|
|
|
25475
25475
|
(margin 0 -16px -16px). The panel of a tab pads 12px, so on a tab that
|
|
25476
25476
|
holds the list directly the footer stuck out 4px on the right and at the
|
|
25477
25477
|
bottom and made the panel scroll. It bleeds exactly the panel's padding. */
|
|
25478
|
-
.cn-tabs-widget__tabs[data-v-
|
|
25478
|
+
.cn-tabs-widget__tabs[data-v-4294c502] .cn-tabs__content > .cn-tab > .cn-detail-widget-host--bare .cn-object-list-widget__add {
|
|
25479
25479
|
margin: auto -12px -12px;
|
|
25480
25480
|
}
|
|
25481
|
-
|
|
25481
|
+
|
|
25482
|
+
/* The open panel's header link, beside the strip. Same look and theme hooks
|
|
25483
|
+
as a card header link (CnWidgetWrapper). */
|
|
25484
|
+
.cn-tabs-widget__header-link[data-v-4294c502] {
|
|
25485
|
+
align-self: center;
|
|
25486
|
+
padding: 0 calc(1 * var(--default-grid-baseline));
|
|
25487
|
+
color: var(--color-primary-element);
|
|
25488
|
+
font-size: var(--cn-widget-header-link-size, 14px);
|
|
25489
|
+
font-weight: var(--cn-widget-header-link-weight, 600);
|
|
25490
|
+
text-decoration: none;
|
|
25491
|
+
white-space: nowrap;
|
|
25492
|
+
}
|
|
25493
|
+
.cn-tabs-widget__header-link[data-v-4294c502]:hover,
|
|
25494
|
+
.cn-tabs-widget__header-link[data-v-4294c502]:focus-visible {
|
|
25495
|
+
text-decoration: underline;
|
|
25496
|
+
}
|
|
25497
|
+
.cn-tabs-widget__header-link[data-v-4294c502]:focus-visible {
|
|
25498
|
+
outline: 2px solid var(--color-primary-element);
|
|
25499
|
+
outline-offset: 2px;
|
|
25500
|
+
border-radius: var(--border-radius-small, 4px);
|
|
25501
|
+
}
|
|
25502
|
+
.cn-tabs-widget__title[data-v-4294c502] {
|
|
25482
25503
|
align-items: center;
|
|
25483
25504
|
display: inline-flex;
|
|
25484
25505
|
gap: 6px;
|
|
25485
25506
|
}
|
|
25486
|
-
.cn-tabs-widget__title-icon[data-v-
|
|
25507
|
+
.cn-tabs-widget__title-icon[data-v-4294c502] {
|
|
25487
25508
|
flex: 0 0 auto;
|
|
25488
25509
|
}
|
|
25489
25510
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conduction/nextcloud-vue",
|
|
3
|
-
"version": "2.56.0-beta.
|
|
3
|
+
"version": "2.56.0-beta.39",
|
|
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": {
|
|
@@ -4242,6 +4242,8 @@ export default {
|
|
|
4242
4242
|
narrowBy,
|
|
4243
4243
|
narrowValue: narrowBy ? this.boardNarrowValue : '',
|
|
4244
4244
|
capacityField: source.capacityField || '',
|
|
4245
|
+
neutralColor: typeof source.neutralColor === 'string' ? source.neutralColor : '',
|
|
4246
|
+
colorMap: source.colorMap && typeof source.colorMap === 'object' ? source.colorMap : null,
|
|
4245
4247
|
})
|
|
4246
4248
|
},
|
|
4247
4249
|
|
|
@@ -15,7 +15,19 @@
|
|
|
15
15
|
is showing. This is the point of the component: six tabbed
|
|
16
16
|
widgets used to mean six card headers stacked down the page. -->
|
|
17
17
|
<template #nav-end>
|
|
18
|
+
<!-- The open panel's header link ("All sales invoices"): a panel
|
|
19
|
+
draws no card header, so the link its widget declares is
|
|
20
|
+
drawn here, and changes with the tab. -->
|
|
21
|
+
<component
|
|
22
|
+
:is="activeHeaderLinkTarget.tag"
|
|
23
|
+
v-if="activeHeaderLinkTarget.tag"
|
|
24
|
+
class="cn-tabs-widget__header-link"
|
|
25
|
+
data-testid="cn-tabs-widget-header-link"
|
|
26
|
+
v-bind="activeHeaderLinkTarget.attrs">
|
|
27
|
+
{{ cnTranslate(activeHeaderLink.label) }}
|
|
28
|
+
</component>
|
|
18
29
|
<CnActionsMenu
|
|
30
|
+
v-if="showActions"
|
|
19
31
|
:showRefresh="showRefresh"
|
|
20
32
|
:showRequestFeature="showRequestFeature"
|
|
21
33
|
:showDocumentation="showDocumentation"
|
|
@@ -169,6 +181,7 @@ import CnIcon from '../CnIcon/CnIcon.vue'
|
|
|
169
181
|
import CnTab from '../CnTabs/CnTab.vue'
|
|
170
182
|
import CnTabs from '../CnTabs/CnTabs.vue'
|
|
171
183
|
import { normalizeLook } from '../../composables/useLook.js'
|
|
184
|
+
import { headerLinkTarget, widgetHeaderLink } from '../../utils/contentHeaderLink.js'
|
|
172
185
|
import { resolveTabCount } from '../../utils/detailActionModel.js'
|
|
173
186
|
import { fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
174
187
|
import { isActivityWidget } from '../../utils/headerMeta.js'
|
|
@@ -430,6 +443,18 @@ export default {
|
|
|
430
443
|
default: () => ({}),
|
|
431
444
|
},
|
|
432
445
|
|
|
446
|
+
/**
|
|
447
|
+
* Whether the strip draws its Actions menu at all. `false` drops the
|
|
448
|
+
* whole menu, the open panel's own items included, for a board that
|
|
449
|
+
* draws none. Manifest: `content.showActions` on the tabs widget.
|
|
450
|
+
*
|
|
451
|
+
* @spec openspec/changes/tabs-widget-actions-off/specs/tabs-widget-actions-off/spec.md#requirement-a-manifest-can-turn-off-the-tab-strips-actions-menu
|
|
452
|
+
*/
|
|
453
|
+
showActions: {
|
|
454
|
+
type: Boolean,
|
|
455
|
+
default: true,
|
|
456
|
+
},
|
|
457
|
+
|
|
433
458
|
/** Show the Refresh entry in the hoisted Actions menu. */
|
|
434
459
|
showRefresh: {
|
|
435
460
|
type: Boolean,
|
|
@@ -654,6 +679,29 @@ export default {
|
|
|
654
679
|
return this.activeTab?.widgetId || ''
|
|
655
680
|
},
|
|
656
681
|
|
|
682
|
+
/**
|
|
683
|
+
* The header link the open tab's widget declares (`headerLink` on the
|
|
684
|
+
* definition, or in its content), or null. For a stack, the first
|
|
685
|
+
* widget's.
|
|
686
|
+
*
|
|
687
|
+
* @spec openspec/changes/tabs-widget-header-link/specs/tabs-widget-header-link/spec.md#requirement-the-tab-strip-draws-the-open-panels-header-link
|
|
688
|
+
* @return {object|null}
|
|
689
|
+
*/
|
|
690
|
+
activeHeaderLink() {
|
|
691
|
+
return widgetHeaderLink(this.activeTab?.widget)
|
|
692
|
+
},
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* How to draw the open panel's header link: a router link for a
|
|
696
|
+
* route, an anchor for an href, nothing otherwise.
|
|
697
|
+
*
|
|
698
|
+
* @spec openspec/changes/tabs-widget-header-link/specs/tabs-widget-header-link/spec.md#requirement-the-tab-strip-draws-the-open-panels-header-link
|
|
699
|
+
* @return {{tag: string, attrs: object}}
|
|
700
|
+
*/
|
|
701
|
+
activeHeaderLinkTarget() {
|
|
702
|
+
return headerLinkTarget(this.activeHeaderLink, Boolean(this.$router))
|
|
703
|
+
},
|
|
704
|
+
|
|
657
705
|
/**
|
|
658
706
|
* The active child's label, so the Actions menu names what it acts on.
|
|
659
707
|
*
|
|
@@ -1231,6 +1279,29 @@ export default {
|
|
|
1231
1279
|
margin: auto -12px -12px;
|
|
1232
1280
|
}
|
|
1233
1281
|
|
|
1282
|
+
/* The open panel's header link, beside the strip. Same look and theme hooks
|
|
1283
|
+
as a card header link (CnWidgetWrapper). */
|
|
1284
|
+
.cn-tabs-widget__header-link {
|
|
1285
|
+
align-self: center;
|
|
1286
|
+
padding: 0 calc(1 * var(--default-grid-baseline));
|
|
1287
|
+
color: var(--color-primary-element);
|
|
1288
|
+
font-size: var(--cn-widget-header-link-size, 14px);
|
|
1289
|
+
font-weight: var(--cn-widget-header-link-weight, 600);
|
|
1290
|
+
text-decoration: none;
|
|
1291
|
+
white-space: nowrap;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
.cn-tabs-widget__header-link:hover,
|
|
1295
|
+
.cn-tabs-widget__header-link:focus-visible {
|
|
1296
|
+
text-decoration: underline;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
.cn-tabs-widget__header-link:focus-visible {
|
|
1300
|
+
outline: 2px solid var(--color-primary-element);
|
|
1301
|
+
outline-offset: 2px;
|
|
1302
|
+
border-radius: var(--border-radius-small, 4px);
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1234
1305
|
.cn-tabs-widget__title {
|
|
1235
1306
|
align-items: center;
|
|
1236
1307
|
display: inline-flex;
|
|
@@ -176,6 +176,7 @@
|
|
|
176
176
|
|
|
177
177
|
<script>
|
|
178
178
|
import { translate as t } from '@nextcloud/l10n'
|
|
179
|
+
import { headerLinkTarget } from '../../utils/contentHeaderLink.js'
|
|
179
180
|
import { slotRenders } from '../../utils/slotContent.js'
|
|
180
181
|
import { CnActionsMenu } from '../CnActionsMenu/index.js'
|
|
181
182
|
|
|
@@ -686,17 +687,7 @@ export default {
|
|
|
686
687
|
* @return {string}
|
|
687
688
|
*/
|
|
688
689
|
headerLinkTag() {
|
|
689
|
-
|
|
690
|
-
if (!link || typeof link.label !== 'string' || link.label === '') {
|
|
691
|
-
return ''
|
|
692
|
-
}
|
|
693
|
-
if (link.route && this.$router) {
|
|
694
|
-
return 'router-link'
|
|
695
|
-
}
|
|
696
|
-
if (typeof link.href === 'string' && link.href !== '') {
|
|
697
|
-
return 'a'
|
|
698
|
-
}
|
|
699
|
-
return ''
|
|
690
|
+
return headerLinkTarget(this.headerLink, Boolean(this.$router)).tag
|
|
700
691
|
},
|
|
701
692
|
|
|
702
693
|
/**
|
|
@@ -706,21 +697,7 @@ export default {
|
|
|
706
697
|
* @return {object}
|
|
707
698
|
*/
|
|
708
699
|
headerLinkAttrs() {
|
|
709
|
-
|
|
710
|
-
if (this.headerLinkTag === 'router-link') {
|
|
711
|
-
const to = { name: link.route }
|
|
712
|
-
if (link.params && typeof link.params === 'object') {
|
|
713
|
-
to.params = link.params
|
|
714
|
-
}
|
|
715
|
-
if (link.query && typeof link.query === 'object') {
|
|
716
|
-
to.query = link.query
|
|
717
|
-
}
|
|
718
|
-
return { to }
|
|
719
|
-
}
|
|
720
|
-
if (this.headerLinkTag === 'a') {
|
|
721
|
-
return { href: link.href }
|
|
722
|
-
}
|
|
723
|
-
return {}
|
|
700
|
+
return headerLinkTarget(this.headerLink, Boolean(this.$router)).attrs
|
|
724
701
|
},
|
|
725
702
|
|
|
726
703
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/ConductionNL/nextcloud-vue/main/src/schemas/app-manifest-v2.schema.json",
|
|
4
4
|
"title": "Conduction App Manifest v2",
|
|
5
5
|
"description": "v2 schema for the JSON-driven page and navigation manifest consumed by @conduction/nextcloud-vue. Introduces a uniform widgets[] array on every page type with a per-slot grid coordinate system, a typed actions[] discriminator, and the required $schema field for version detection. v1 manifests continue to validate against app-manifest.schema.json (unchanged).",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.102.0",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"required": ["$schema", "version"],
|
|
9
9
|
"allOf": [
|
|
@@ -1177,6 +1177,8 @@
|
|
|
1177
1177
|
"colorField": { "type": "string", "description": "The referenced row's field that holds the column's dot colour (a badge variant or a CSS colour)." },
|
|
1178
1178
|
"filter": { "type": "object", "description": "Equality filters on the referenced rows, e.g. `{ \"isFinal\": false }` to leave out end states.", "additionalProperties": { "type": ["string", "number", "boolean"] } },
|
|
1179
1179
|
"capacityField": { "type": "string", "minLength": 1, "description": "board-column-capacity (2.100.0): the referenced row's numeric field that holds the column's limit. The header reads \"count / capacity\" and turns full at the limit, and a move into a full row is refused before it is written (the server still guards). A column merged from several rows shows no limit, but each row's own limit still refuses a move into it. A row without a number above 0 has no limit." },
|
|
1180
|
+
"neutralColor": { "type": "string", "minLength": 1, "description": "board-neutral-column-colour (2.101.0): the colour a referenced row holds when nobody chose one (the schema default, e.g. \"grey\"). A column merged from several rows (`mergeBy`) then takes the first row colour that is not this one, and this one only when every row has it. Compared as written: \"Grey\" is not \"grey\", and a hex value is not a name. Unset, a merged column takes its first row's colour." },
|
|
1181
|
+
"colorMap": { "type": "object", "description": "board-column-colour-map (2.102.0): a stored row colour to the CSS colour its column is drawn in, e.g. `{ \"orange\": \"var(--nl-color-orange, #e17000)\" }`, so a palette name draws a theme token. Applied after the merge, so `neutralColor` still compares the stored values. A colour it does not map draws as before.", "additionalProperties": { "type": "string", "minLength": 1 } },
|
|
1180
1182
|
"mergeBy": { "type": "string", "description": "Merge referenced rows with the same value of this field into one column (statuses of every case type by `name`). A drop then writes the row of the card's own parent (`narrowBy`), and is refused when that parent has none." },
|
|
1181
1183
|
"narrowBy": {
|
|
1182
1184
|
"type": "object",
|