@conduction/nextcloud-vue 2.104.0 → 2.105.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.
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +93 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +6 -3
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +3 -3
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +59 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue.js +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue.js +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js +2 -0
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js +32 -29
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue.js +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js +73 -4
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js +74 -27
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +54 -1
- 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/CnIndexPage/useSelfFetchList.js +3 -2
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue.js +9 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue.js.map +1 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue2.js +88 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue3.js +39 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js.map +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js +3 -3
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +16 -4
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js +11 -0
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +4 -4
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +16 -14
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +4 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +4 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +566 -295
- package/dist/esm/utils/libraryWidgetKeys.js +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/nextcloudApps.js +45 -0
- package/dist/esm/utils/nextcloudApps.js.map +1 -0
- package/dist/esm/utils/scopeListLayout.js +9 -2
- package/dist/esm/utils/scopeListLayout.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/visibleWhen.js +12 -4
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +3054 -2517
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +566 -295
- package/l10n/en.json +4 -1
- package/l10n/nl.json +4 -1
- package/package.json +1 -1
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -1
- package/src/components/CnChartWidget/CnChartWidget.md +2 -0
- package/src/components/CnChartWidget/CnChartWidget.vue +93 -1
- package/src/components/CnDashboardPage/CnDashboardPage.vue +9 -6
- package/src/components/CnDetailPage/CnDetailPage.md +1 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +59 -1
- package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -1
- package/src/components/CnFeaturesBoard/CnFeaturesBoard.vue +4 -1
- package/src/components/CnFlowsPage/CnFlowBoard.vue +132 -8
- package/src/components/CnIndexPage/CnIndexPage.md +1 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +54 -1
- package/src/components/CnIndexPage/useSelfFetchList.js +3 -2
- package/src/components/CnNoticeWidget/CnNoticeWidget.vue +153 -0
- package/src/components/CnNoticeWidget/index.js +12 -0
- package/src/components/CnSettingsField/CnSettingsField.vue +4 -1
- package/src/components/CnSetupWizard/CnSetupWizard.vue +9 -1
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +15 -4
- package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
- package/src/components/index.js +1 -0
- package/src/css/dialog.css +20 -2
- package/src/css/look-board-detail.css +77 -4
- package/src/css/look-board-index.css +36 -2
- package/src/css/look-board.css +97 -12
- package/src/index.js +1 -0
- package/src/schemas/app-manifest-v2.schema.json +36 -3
- package/src/utils/libraryWidgetKeys.js +1 -0
- package/src/utils/nextcloudApps.js +50 -0
- package/src/utils/scopeListLayout.js +9 -2
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +12 -4
|
@@ -1288,6 +1288,7 @@ import {
|
|
|
1288
1288
|
import { reportBindingProblems } from '../../utils/diagnostics.js'
|
|
1289
1289
|
import { fetchGroupedCounts } from '../../utils/fetchAggregate.js'
|
|
1290
1290
|
import { fetchFilterCounts, fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
1291
|
+
import { unwrapAppConfig } from '../../utils/formatMetric.js'
|
|
1291
1292
|
import { buildExportUrl } from '../../utils/indexExportHelpers.js'
|
|
1292
1293
|
import { lensUnavailableText } from '../../utils/lensAvailability.js'
|
|
1293
1294
|
import { isModifiedClick, openRowTarget } from '../../utils/linkNavigation.js'
|
|
@@ -1677,6 +1678,8 @@ export default {
|
|
|
1677
1678
|
cnCustomComponents: { default: () => ({}) },
|
|
1678
1679
|
/** The permissions the user holds, provided by CnAppRoot; for gated page tabs. */
|
|
1679
1680
|
cnPermissions: { default: () => [] },
|
|
1681
|
+
/** The app config an ancestor provides, for `@config.<key>` in quick-filter labels. */
|
|
1682
|
+
cnAppConfig: { default: null },
|
|
1680
1683
|
/** The app id CnAppRoot provides, for the plural form of `countSubtitle`. */
|
|
1681
1684
|
cnAppId: { default: '' },
|
|
1682
1685
|
/**
|
|
@@ -3133,6 +3136,19 @@ export default {
|
|
|
3133
3136
|
default: true,
|
|
3134
3137
|
},
|
|
3135
3138
|
|
|
3139
|
+
/**
|
|
3140
|
+
* The app config `@config.<key>` tokens resolve against, in quick-filter
|
|
3141
|
+
* filters and labels (`"Residence @config.municipality"`), as on the
|
|
3142
|
+
* dashboard and detail pages. Merged over a config an ancestor provides
|
|
3143
|
+
* on `cnAppConfig`. Manifest: `config.appConfig`.
|
|
3144
|
+
*
|
|
3145
|
+
* @type {object}
|
|
3146
|
+
*/
|
|
3147
|
+
appConfig: {
|
|
3148
|
+
type: Object,
|
|
3149
|
+
default: () => ({}),
|
|
3150
|
+
},
|
|
3151
|
+
|
|
3136
3152
|
/**
|
|
3137
3153
|
* Keep the "Showing X of Y" counter visible beside the inline search field,
|
|
3138
3154
|
* after any `#after-search` controls (only relevant with `inlineSearch`,
|
|
@@ -6678,11 +6694,21 @@ export default {
|
|
|
6678
6694
|
effectiveQuickFilters() {
|
|
6679
6695
|
const own = withPersonalLenses(this.presented('quickFilters') || this.generatedQuickFilters, this.personalLenses)
|
|
6680
6696
|
if (own && own.length > 0) {
|
|
6681
|
-
return own
|
|
6697
|
+
return own.map((tab) => this.withConfigLabels(tab))
|
|
6682
6698
|
}
|
|
6683
6699
|
return (this.isNamedSource && this.namedQuickFilters) || null
|
|
6684
6700
|
},
|
|
6685
6701
|
|
|
6702
|
+
/**
|
|
6703
|
+
* The app config `@config.<key>` tokens resolve against: the `appConfig`
|
|
6704
|
+
* prop over a config an ancestor provides.
|
|
6705
|
+
*
|
|
6706
|
+
* @return {object} The config.
|
|
6707
|
+
*/
|
|
6708
|
+
effectiveAppConfig() {
|
|
6709
|
+
return { ...unwrapAppConfig(this.cnAppConfig), ...(this.appConfig || {}) }
|
|
6710
|
+
},
|
|
6711
|
+
|
|
6686
6712
|
/**
|
|
6687
6713
|
* Whether the Add button renders. A named source that declares
|
|
6688
6714
|
* `showAdd: false` suppresses it (a task is created by a flow, never
|
|
@@ -8766,6 +8792,33 @@ export default {
|
|
|
8766
8792
|
this.$emit('sort-change', value)
|
|
8767
8793
|
},
|
|
8768
8794
|
|
|
8795
|
+
/**
|
|
8796
|
+
* A quick filter with `@config.<key>` in its `label` or `activeLabel`
|
|
8797
|
+
* (`"Residence @config.municipality"`): the label translated first, then
|
|
8798
|
+
* each token replaced by its configured value. A key the config does
|
|
8799
|
+
* not hold leaves its token in place. Other tabs pass unchanged.
|
|
8800
|
+
*
|
|
8801
|
+
* @param {object} tab A quick-filter tab.
|
|
8802
|
+
* @return {object} The tab, with its labels resolved.
|
|
8803
|
+
*/
|
|
8804
|
+
withConfigLabels(tab) {
|
|
8805
|
+
if (!tab || typeof tab !== 'object') {
|
|
8806
|
+
return tab
|
|
8807
|
+
}
|
|
8808
|
+
const hasToken = (value) => typeof value === 'string' && value.includes('@config.')
|
|
8809
|
+
if (!hasToken(tab.label) && !hasToken(tab.activeLabel)) {
|
|
8810
|
+
return tab
|
|
8811
|
+
}
|
|
8812
|
+
const config = this.effectiveAppConfig
|
|
8813
|
+
const fill = (value) => (hasToken(value)
|
|
8814
|
+
? this.cnTranslate(value).replace(/@config\.([A-Za-z0-9_.-]*[A-Za-z0-9_])/g, (token, key) => {
|
|
8815
|
+
const found = this.getByPath(config, key)
|
|
8816
|
+
return found === undefined || found === null || found === '' ? token : String(found)
|
|
8817
|
+
})
|
|
8818
|
+
: value)
|
|
8819
|
+
return { ...tab, label: fill(tab.label), activeLabel: fill(tab.activeLabel) }
|
|
8820
|
+
},
|
|
8821
|
+
|
|
8769
8822
|
/**
|
|
8770
8823
|
* @param {{key: string, order: string, keys?: Array<{key: string, order: string}>}} payload Sort change from CnDataTable.
|
|
8771
8824
|
* @return {void}
|
|
@@ -171,7 +171,8 @@ export function useSelfFetchList(props, instance, inject, extras = {}) {
|
|
|
171
171
|
const objCtx = unwrapCtx(objectCtxRaw)
|
|
172
172
|
const base = (objCtx && typeof objCtx === 'object') ? { ...objCtx } : {}
|
|
173
173
|
base.workspace = unwrapCtx(workspaceCtxRaw) || {}
|
|
174
|
-
|
|
174
|
+
// The page's own `appConfig` prop wins over a config an ancestor provides.
|
|
175
|
+
base.config = { ...(unwrapCtx(appConfigRaw) || {}), ...(props.appConfig || {}) }
|
|
175
176
|
return base
|
|
176
177
|
}
|
|
177
178
|
|
|
@@ -183,7 +184,7 @@ export function useSelfFetchList(props, instance, inject, extras = {}) {
|
|
|
183
184
|
// never again. Stringified (like CnDeltaWidget's `sourceKey`) so the
|
|
184
185
|
// watcher fires on real content changes only, not object identity.
|
|
185
186
|
const workspaceSignature = computed(() => JSON.stringify(unwrapCtx(workspaceCtxRaw) || {}))
|
|
186
|
-
const appConfigSignature = computed(() => JSON.stringify(unwrapCtx(appConfigRaw) || {}))
|
|
187
|
+
const appConfigSignature = computed(() => JSON.stringify({ ...(unwrapCtx(appConfigRaw) || {}), ...(props.appConfig || {}) }))
|
|
187
188
|
|
|
188
189
|
// Pass register/schema in their positional id slots (not as a {register, schema} object as
|
|
189
190
|
// second arg) — that previously made fetch URLs go to `/api/objects/undefined/[object Object]`.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
- SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
- SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
-->
|
|
5
|
+
<template>
|
|
6
|
+
<section
|
|
7
|
+
v-if="resolvedText || resolvedTitle"
|
|
8
|
+
class="cn-notice-widget"
|
|
9
|
+
:class="`cn-notice-widget--${resolvedVariant}`"
|
|
10
|
+
:aria-label="resolvedTitle || null"
|
|
11
|
+
role="note"
|
|
12
|
+
data-testid="cn-notice-widget">
|
|
13
|
+
<CnIcon
|
|
14
|
+
class="cn-notice-widget__icon"
|
|
15
|
+
:name="resolvedIcon"
|
|
16
|
+
:size="18"
|
|
17
|
+
aria-hidden="true" />
|
|
18
|
+
<p class="cn-notice-widget__text">
|
|
19
|
+
<strong v-if="resolvedTitle" class="cn-notice-widget__title" data-testid="cn-notice-widget-title">{{ resolvedTitle }}</strong>{{ resolvedTitle && resolvedText ? ' ' : '' }}{{ resolvedText }}
|
|
20
|
+
</p>
|
|
21
|
+
</section>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script>
|
|
25
|
+
import { CnIcon } from '../CnIcon/index.js'
|
|
26
|
+
|
|
27
|
+
/** The tones a notice takes, and the icon each shows by default. */
|
|
28
|
+
const VARIANT_ICONS = Object.freeze({
|
|
29
|
+
info: 'InformationOutline',
|
|
30
|
+
warning: 'AlertOutline',
|
|
31
|
+
error: 'AlertCircleOutline',
|
|
32
|
+
success: 'CheckCircleOutline',
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* CnNoticeWidget — a toned notice box: an icon, a bold title and a line of
|
|
37
|
+
* text in one rounded box, as the boards draw a warning beside a record
|
|
38
|
+
* (DqSociaalDomein "Bijzondere persoonsgegevens: gezondheid. Elke inzage
|
|
39
|
+
* wordt gelogd met het doel."). Usable in a detail page's side column, its
|
|
40
|
+
* body grid and on a dashboard as widget type `notice`; the surface applies
|
|
41
|
+
* the widget's `visibleWhen`.
|
|
42
|
+
*
|
|
43
|
+
* `content`: `{ variant?, title?, text, icon? }`. `variant` is `info`
|
|
44
|
+
* (default), `warning`, `error` or `success`; `title` and `text` go through
|
|
45
|
+
* the host's translate; `icon` names a CnIcon instead of the variant's own.
|
|
46
|
+
*
|
|
47
|
+
* ```vue
|
|
48
|
+
* <CnNoticeWidget :content="{ variant: 'warning', title: 'Special category data: health.', text: 'Every view is logged with its purpose.' }" />
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export default {
|
|
52
|
+
name: 'CnNoticeWidget',
|
|
53
|
+
|
|
54
|
+
components: { CnIcon },
|
|
55
|
+
|
|
56
|
+
inject: {
|
|
57
|
+
/** The host app's translate function (CnAppRoot `cnTranslate`). */
|
|
58
|
+
cnTranslate: { default: () => (key) => key },
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
props: {
|
|
62
|
+
/**
|
|
63
|
+
* The notice: `{ variant?, title?, text, icon? }`.
|
|
64
|
+
*
|
|
65
|
+
* @type {{variant?: string, title?: string, text?: string, icon?: string}}
|
|
66
|
+
*/
|
|
67
|
+
content: {
|
|
68
|
+
type: Object,
|
|
69
|
+
default: () => ({}),
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
computed: {
|
|
74
|
+
/** @return {string} `info`, `warning`, `error` or `success`. */
|
|
75
|
+
resolvedVariant() {
|
|
76
|
+
const variant = this.content && this.content.variant === 'danger' ? 'error' : this.content && this.content.variant
|
|
77
|
+
return Object.hasOwn(VARIANT_ICONS, variant) ? variant : 'info'
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/** @return {string} The icon name. */
|
|
81
|
+
resolvedIcon() {
|
|
82
|
+
const icon = this.content && this.content.icon
|
|
83
|
+
return typeof icon === 'string' && icon !== '' ? icon : VARIANT_ICONS[this.resolvedVariant]
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
/** @return {string} The title through the host translate. */
|
|
87
|
+
resolvedTitle() {
|
|
88
|
+
return this.translate(this.content && this.content.title)
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
/** @return {string} The text through the host translate. */
|
|
92
|
+
resolvedText() {
|
|
93
|
+
return this.translate(this.content && this.content.text)
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
methods: {
|
|
98
|
+
/**
|
|
99
|
+
* @param {unknown} text A manifest string.
|
|
100
|
+
* @return {string} Its translation, '' for anything but a non-empty string.
|
|
101
|
+
*/
|
|
102
|
+
translate(text) {
|
|
103
|
+
if (typeof text !== 'string' || text === '') {
|
|
104
|
+
return ''
|
|
105
|
+
}
|
|
106
|
+
return typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
<style scoped>
|
|
113
|
+
.cn-notice-widget {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: flex-start;
|
|
116
|
+
gap: 10px;
|
|
117
|
+
padding: 14px 16px;
|
|
118
|
+
border-radius: var(--cn-board-card-radius, 12px);
|
|
119
|
+
font-size: 14px;
|
|
120
|
+
line-height: 1.5;
|
|
121
|
+
background: color-mix(in srgb, var(--color-info, #0071ad) 10%, var(--color-main-background));
|
|
122
|
+
color: var(--color-main-text);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.cn-notice-widget--warning {
|
|
126
|
+
background: var(--color-warning-light, #fff4de);
|
|
127
|
+
color: var(--color-warning-text, #7a4f00);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.cn-notice-widget--error {
|
|
131
|
+
background: color-mix(in srgb, var(--color-error, #db0606) 10%, var(--color-main-background));
|
|
132
|
+
color: var(--color-error-text, var(--color-main-text));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.cn-notice-widget--success {
|
|
136
|
+
background: color-mix(in srgb, var(--color-success, #2d7b41) 10%, var(--color-main-background));
|
|
137
|
+
color: var(--color-success-text, var(--color-main-text));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.cn-notice-widget__icon {
|
|
141
|
+
flex: 0 0 auto;
|
|
142
|
+
margin-top: 2px;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.cn-notice-widget__text {
|
|
146
|
+
margin: 0;
|
|
147
|
+
overflow-wrap: anywhere;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.cn-notice-widget__title {
|
|
151
|
+
font-weight: 700;
|
|
152
|
+
}
|
|
153
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
*
|
|
5
|
+
* CnNoticeWidget — a toned notice box (icon, bold title, text) for a side
|
|
6
|
+
* column, a detail body or a dashboard (widget type `notice`).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import CnNoticeWidget from './CnNoticeWidget.vue'
|
|
10
|
+
|
|
11
|
+
export { CnNoticeWidget }
|
|
12
|
+
export default CnNoticeWidget
|
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
class="cn-settings-field__image"
|
|
19
19
|
role="group"
|
|
20
20
|
:aria-labelledby="`${inputId}-label`">
|
|
21
|
-
|
|
21
|
+
<!-- `hideLabel` keeps the name for a screen reader only. -->
|
|
22
|
+
<span :id="`${inputId}-label`"
|
|
23
|
+
class="cn-settings-field__image-label"
|
|
24
|
+
:class="{ 'hidden-visually': field.hideLabel === true }">{{ label }}</span>
|
|
22
25
|
<div class="cn-settings-field__image-row">
|
|
23
26
|
<span class="cn-settings-field__image-tile" :data-testid="`cn-settings-field-image-${field.key}`">
|
|
24
27
|
<img v-if="stringValue" :src="stringValue" :alt="t('nextcloud-vue', 'Current {name}', { name: label })">
|
|
@@ -126,7 +126,15 @@
|
|
|
126
126
|
<NcNoteCard v-if="isChoiceDisabled(step)" type="warning">
|
|
127
127
|
{{ dependsOnHint(step) }}
|
|
128
128
|
</NcNoteCard>
|
|
129
|
-
|
|
129
|
+
<!-- `noteStyle: "card"` sets the note as an info card (DqInstellen). -->
|
|
130
|
+
<NcNoteCard
|
|
131
|
+
v-if="stepNote(step) && step.noteStyle === 'card'"
|
|
132
|
+
type="info"
|
|
133
|
+
class="cn-setup-step__note-card"
|
|
134
|
+
data-testid="cn-setup-step-note">
|
|
135
|
+
{{ stepNote(step) }}
|
|
136
|
+
</NcNoteCard>
|
|
137
|
+
<p v-else-if="stepNote(step)" class="cn-setup-step__note" data-testid="cn-setup-step-note">
|
|
130
138
|
{{ stepNote(step) }}
|
|
131
139
|
</p>
|
|
132
140
|
</template>
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
<div class="cn-version-info__details">
|
|
36
36
|
<!-- Application Name (the board card can leave it to its description: `showAppName`) -->
|
|
37
37
|
<div v-if="!isBoard || (showAppName && !compact)" class="cn-version-info__item" data-testid="cn-version-info-app-name">
|
|
38
|
-
<span class="cn-version-info__label">{{ fieldLabels.appName }}
|
|
38
|
+
<span class="cn-version-info__label">{{ fieldLabels.appName }}{{ labelColon }}</span>
|
|
39
39
|
<span class="cn-version-info__value">{{ appName }}</span>
|
|
40
40
|
</div>
|
|
41
41
|
|
|
42
42
|
<!-- Version -->
|
|
43
43
|
<div class="cn-version-info__item">
|
|
44
|
-
<span class="cn-version-info__label">{{ fieldLabels.version }}
|
|
44
|
+
<span class="cn-version-info__label">{{ fieldLabels.version }}{{ labelColon }}</span>
|
|
45
45
|
<span class="cn-version-info__value">{{ appVersion }}</span>
|
|
46
46
|
</div>
|
|
47
47
|
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
which draws the row ("Unknown" until the app reports it) with the
|
|
50
50
|
up-to-date state inline ("0.4.47, bijgewerkt"). -->
|
|
51
51
|
<div v-if="configuredVersion || isBoard" class="cn-version-info__item" data-testid="cn-version-info-configured">
|
|
52
|
-
<span class="cn-version-info__label">{{ fieldLabels.configuredVersion }}
|
|
52
|
+
<span class="cn-version-info__label">{{ fieldLabels.configuredVersion }}{{ labelColon }}</span>
|
|
53
53
|
<span class="cn-version-info__value">{{ isBoard ? boardConfiguredText : configuredVersion }}</span>
|
|
54
54
|
</div>
|
|
55
55
|
|
|
56
56
|
<!-- Additional items -->
|
|
57
57
|
<div v-for="item in additionalItems" :key="item.label" class="cn-version-info__item">
|
|
58
|
-
<span class="cn-version-info__label">{{ item.label }}
|
|
58
|
+
<span class="cn-version-info__label">{{ item.label }}{{ labelColon }}</span>
|
|
59
59
|
<span class="cn-version-info__value" :class="item.statusClass">{{ item.value }}</span>
|
|
60
60
|
</div>
|
|
61
61
|
|
|
@@ -320,6 +320,17 @@ export default {
|
|
|
320
320
|
},
|
|
321
321
|
|
|
322
322
|
computed: {
|
|
323
|
+
/**
|
|
324
|
+
* The colon after each label: none on the compact board card, which
|
|
325
|
+
* sets each label beside its value ("Versie 0.4.47", DqInstellingenAlgemeen);
|
|
326
|
+
* one otherwise, PqBeheer's card included.
|
|
327
|
+
*
|
|
328
|
+
* @return {string} The colon, or ''.
|
|
329
|
+
*/
|
|
330
|
+
labelColon() {
|
|
331
|
+
return this.isBoard && this.compact ? '' : ':'
|
|
332
|
+
},
|
|
333
|
+
|
|
323
334
|
/**
|
|
324
335
|
* The field labels: the app's, else the library's in the reader's language.
|
|
325
336
|
*
|
|
@@ -21,6 +21,7 @@ import CnExportsWidget from '../CnExportsWidget/CnExportsWidget.vue'
|
|
|
21
21
|
import CnHeaderWidget from '../CnHeaderWidget/CnHeaderWidget.vue'
|
|
22
22
|
import CnIntegrationWidget from '../CnIntegrationWidget/CnIntegrationWidget.vue'
|
|
23
23
|
import CnNavCardGrid from '../CnNavCardGrid/CnNavCardGrid.vue'
|
|
24
|
+
import CnNoticeWidget from '../CnNoticeWidget/CnNoticeWidget.vue'
|
|
24
25
|
import CnObjectDataWidget from '../CnObjectDataWidget/CnObjectDataWidget.vue'
|
|
25
26
|
import CnObjectGeoWidget from '../CnObjectGeoWidget/CnObjectGeoWidget.vue'
|
|
26
27
|
import CnObjectMetadataWidget from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue'
|
|
@@ -86,6 +87,7 @@ export const BUILT_IN_WIDGETS = {
|
|
|
86
87
|
related: CnRelatedObjectsWidget,
|
|
87
88
|
integration: CnIntegrationWidget,
|
|
88
89
|
banner: CnBannerWidget,
|
|
90
|
+
notice: CnNoticeWidget,
|
|
89
91
|
'audit-trail': CnAuditTrailWidget,
|
|
90
92
|
timeline: CnTimelineWidget,
|
|
91
93
|
header: CnHeaderWidget,
|
package/src/components/index.js
CHANGED
|
@@ -131,6 +131,7 @@ export { CnContactPicker } from './CnContactPicker/index.js'
|
|
|
131
131
|
export { CnContactCreate } from './CnContactCreate/index.js'
|
|
132
132
|
export { CnResourceSelect } from './CnResourceSelect/index.js'
|
|
133
133
|
export { CnSearchSelect } from './CnSearchSelect/index.js'
|
|
134
|
+
export { CnNoticeWidget } from './CnNoticeWidget/index.js'
|
|
134
135
|
export { CnPropertySourceField } from './CnPropertySourceField/index.js'
|
|
135
136
|
export { CnDurationField } from './CnDurationField/index.js'
|
|
136
137
|
export { CnFavouriteToggle } from './CnFavouriteToggle/index.js'
|
package/src/css/dialog.css
CHANGED
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
* --cn-dialog-eyebrow-tracking letter spacing; 0 by default, 0.06em suits capitals
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
/* The nldesign theme sets a dialog's radius with `!important` through its
|
|
17
|
+
dialog radius token, so the board's 12px goes to that token.
|
|
18
|
+
@spec openspec/changes/board-dialog-theme/specs/board-dialog-theme/spec.md#requirement-a-board-dialog-keeps-its-frame-and-inset-under-a-theme */
|
|
16
19
|
.cn-dialog-board {
|
|
20
|
+
--nldesign-component-dialog-border-radius: var(--cn-board-card-radius, 12px);
|
|
17
21
|
--cn-dialog-width: 640px;
|
|
18
22
|
--cn-dialog-danger: var(--color-error);
|
|
19
23
|
--cn-dialog-eyebrow-color: var(--color-primary-element-text, var(--color-main-text));
|
|
@@ -26,16 +30,26 @@
|
|
|
26
30
|
background-color: color-mix(in srgb, var(--color-main-text) 45%, transparent);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
/* Width by role, capped at the viewport minus a 16px gutter each side.
|
|
33
|
+
/* Width by role, capped at the viewport minus a 16px gutter each side. The
|
|
34
|
+
shadow carries `!important`: the nldesign theme removes every
|
|
35
|
+
`.modal-container`'s shadow with `!important` and offers no token for it. */
|
|
30
36
|
.modal-mask.cn-dialog-board .modal-wrapper--normal > .modal-container,
|
|
31
37
|
.modal-mask.cn-dialog-board .modal-wrapper .modal-container {
|
|
32
38
|
width: var(--cn-dialog-width);
|
|
33
39
|
max-width: min(var(--cn-dialog-width), calc(100% - 32px));
|
|
34
40
|
border-radius: var(--cn-board-card-radius, 12px);
|
|
35
|
-
box-shadow: 0 12px 40px color-mix(in srgb, var(--color-main-text) 28%, transparent);
|
|
41
|
+
box-shadow: 0 12px 40px color-mix(in srgb, var(--color-main-text) 28%, transparent) !important;
|
|
36
42
|
overflow: hidden;
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
/* The board's header and body carry their own 24px inset. NcDialog pads its
|
|
46
|
+
container 4px at the top and 12px at the start, which put the title and
|
|
47
|
+
the fields 36px in; its rule outranked the one above through the scoped
|
|
48
|
+
`.dialog__modal[data-v-…]`, so this one names the class too. */
|
|
49
|
+
.modal-mask.cn-dialog-board.dialog__modal .modal-wrapper .modal-container {
|
|
50
|
+
padding: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
/* The header is ours: NcModal's own close button and NcDialog's heading give
|
|
40
54
|
way (the heading stays as the accessible name, visually hidden). The mask
|
|
41
55
|
class raises the rule above NcButton's `.button-vue[data-v-…]`, whose
|
|
@@ -269,6 +283,10 @@
|
|
|
269
283
|
border-radius: 16px 16px 0 0;
|
|
270
284
|
}
|
|
271
285
|
|
|
286
|
+
.cn-dialog-board {
|
|
287
|
+
--nldesign-component-dialog-border-radius: 16px 16px 0 0;
|
|
288
|
+
}
|
|
289
|
+
|
|
272
290
|
.modal-mask.cn-dialog-board .modal-container::before {
|
|
273
291
|
content: '';
|
|
274
292
|
display: block;
|
|
@@ -203,6 +203,58 @@
|
|
|
203
203
|
width: auto;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
/* ---- The follow pill (DqZaak "Volgen") ---------------------------------- */
|
|
207
|
+
/* The board draws the follow control under the title as a 28px pill: 13px
|
|
208
|
+
text at 600 on the main background, a grey border, a 14px icon 6px from its
|
|
209
|
+
label. Live it was Nextcloud's 34px tertiary button, 15px bold in the
|
|
210
|
+
primary colour. The theme tokens carry the weight and radius past the
|
|
211
|
+
nldesign theme's `!important`; the follower count takes the same pill.
|
|
212
|
+
@spec openspec/changes/board-follow-pill/specs/board-follow-pill/spec.md#requirement-the-board-follow-control-is-a-pill */
|
|
213
|
+
.cn-look-board .cn-detail-page .cn-follow-toggle .button-vue {
|
|
214
|
+
--nldesign-component-button-font-weight: 600;
|
|
215
|
+
--nldesign-component-button-border-radius: 14px;
|
|
216
|
+
--nldesign-component-button-secondary-action-color: var(--color-main-text);
|
|
217
|
+
--nldesign-component-button-secondary-action-background-color: var(--color-main-background);
|
|
218
|
+
--nldesign-component-button-secondary-action-border-color: var(--color-border-dark);
|
|
219
|
+
--nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
|
|
220
|
+
box-sizing: border-box;
|
|
221
|
+
height: 28px;
|
|
222
|
+
min-height: 28px;
|
|
223
|
+
min-width: 0;
|
|
224
|
+
padding: 0 10px;
|
|
225
|
+
border: 1px solid var(--color-border-dark);
|
|
226
|
+
border-radius: 14px;
|
|
227
|
+
background: var(--color-main-background);
|
|
228
|
+
color: var(--color-main-text);
|
|
229
|
+
font-size: 13px;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.cn-look-board .cn-detail-page .cn-follow-toggle .button-vue:hover {
|
|
233
|
+
background: var(--color-background-hover);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.cn-look-board .cn-detail-page .cn-follow-toggle .button-vue .button-vue__wrapper {
|
|
237
|
+
gap: 6px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.cn-look-board .cn-detail-page .cn-follow-toggle .button-vue .button-vue__icon {
|
|
241
|
+
width: 14px;
|
|
242
|
+
min-width: 14px;
|
|
243
|
+
height: 14px;
|
|
244
|
+
min-height: 14px;
|
|
245
|
+
color: var(--color-main-text);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.cn-look-board .cn-detail-page .cn-follow-toggle .button-vue .button-vue__icon svg {
|
|
249
|
+
width: 14px;
|
|
250
|
+
height: 14px;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.cn-look-board .cn-detail-page .cn-follow-toggle .button-vue .button-vue__text {
|
|
254
|
+
margin: 0;
|
|
255
|
+
padding: 0;
|
|
256
|
+
}
|
|
257
|
+
|
|
206
258
|
/* ---- Folder tabs ------------------------------------------------------- */
|
|
207
259
|
|
|
208
260
|
/* The strip draws no line of its own (design-system pull request 147). The card under it
|
|
@@ -222,7 +274,7 @@
|
|
|
222
274
|
}
|
|
223
275
|
|
|
224
276
|
/* Tabs sit on the card's top edge; only the open tab reaches 1px further
|
|
225
|
-
down (min-height
|
|
277
|
+
down (min-height 38px below), over the card's top border. Top-aligned so
|
|
226
278
|
the inactive tabs do not stretch to the open tab's height. */
|
|
227
279
|
.cn-look-board .cn-tabs--board .cn-tabs__nav {
|
|
228
280
|
align-items: flex-start;
|
|
@@ -256,8 +308,15 @@
|
|
|
256
308
|
|
|
257
309
|
/* `margin: 0`: a tab is a <button>, and Nextcloud's core stylesheet gives
|
|
258
310
|
every `button:not(.button-vue)` `margin: 3px 3px 3px 0`, which put the strip
|
|
259
|
-
3px low and the tabs 7px apart instead of 4 (DqZaak "Zaakonderdelen").
|
|
311
|
+
3px low and the tabs 7px apart instead of 4 (DqZaak "Zaakonderdelen").
|
|
312
|
+
The nldesign theme sets every button's weight and radius with `!important`
|
|
313
|
+
through its button tokens, which drew every tab bold with four rounded
|
|
314
|
+
corners; the tab hands the board's values to those tokens. A tab is 37px
|
|
315
|
+
with or without a count (DqZaak), not 34px without one.
|
|
316
|
+
@spec openspec/changes/board-tabs-theme/specs/board-tabs-theme/spec.md#requirement-board-folder-tabs-keep-the-boards-weight-shape-and-height-under-a-theme */
|
|
260
317
|
.cn-look-board .cn-tabs--board .cn-tabs__nav-item {
|
|
318
|
+
--nldesign-component-button-font-weight: 400;
|
|
319
|
+
--nldesign-component-button-border-radius: 8px 8px 0 0;
|
|
261
320
|
background-color: var(--color-background-dark);
|
|
262
321
|
border: 1px solid var(--color-border-dark);
|
|
263
322
|
border-bottom: none;
|
|
@@ -265,17 +324,18 @@
|
|
|
265
324
|
font-size: 14px;
|
|
266
325
|
font-weight: 400;
|
|
267
326
|
margin: 0;
|
|
268
|
-
min-height:
|
|
327
|
+
min-height: 37px;
|
|
269
328
|
padding: 8px 12px;
|
|
270
329
|
}
|
|
271
330
|
|
|
272
331
|
/* The open tab: the panel's colour, bold, and no coloured top edge. */
|
|
273
332
|
.cn-look-board .cn-tabs--board .cn-tabs__nav-item.cn-tabs__nav-item--active {
|
|
333
|
+
--nldesign-component-button-font-weight: 700;
|
|
274
334
|
background-color: var(--color-main-background);
|
|
275
335
|
border-bottom: 1px solid var(--color-main-background);
|
|
276
336
|
border-top: 1px solid var(--color-border-dark);
|
|
277
337
|
font-weight: 700;
|
|
278
|
-
min-height:
|
|
338
|
+
min-height: 38px;
|
|
279
339
|
padding-bottom: 9px;
|
|
280
340
|
padding-top: 8px;
|
|
281
341
|
position: relative;
|
|
@@ -456,6 +516,19 @@
|
|
|
456
516
|
padding: 10px 22px 20px;
|
|
457
517
|
}
|
|
458
518
|
|
|
519
|
+
/* A stat tile in a side card (DqZaak "Termijn") sits on the card's inset as
|
|
520
|
+
the board draws it. The card-fit wrapper is flush, and the wrapper's own
|
|
521
|
+
flush rule loads after this sheet and outranked the side card's padding,
|
|
522
|
+
so the value sat 11px from the card's edge instead of 23px.
|
|
523
|
+
@spec openspec/changes/board-dashboard-widget-inset/specs/board-dashboard-widget-inset/spec.md#requirement-a-stat-tile-in-a-detail-side-card-keeps-the-cards-inset */
|
|
524
|
+
.cn-look-board .cn-detail-page__side .cn-detail-page__card-fit > .cn-widget-wrapper__content:has(> .cn-kpi-card--board) {
|
|
525
|
+
padding: 10px 22px 20px;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.cn-look-board .cn-detail-page__side .cn-detail-page__card-fit > .cn-widget-wrapper__content > .cn-kpi-card--board {
|
|
529
|
+
padding: 0;
|
|
530
|
+
}
|
|
531
|
+
|
|
459
532
|
/* No Actions menu on a side card. */
|
|
460
533
|
.cn-look-board .cn-detail-page__side .cn-widget-wrapper__actions {
|
|
461
534
|
display: none;
|
|
@@ -163,8 +163,15 @@
|
|
|
163
163
|
gap: 8px;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/* A chip is a <button>: the nldesign theme sets every button's radius and
|
|
167
|
+
weight with `!important` through its button tokens, which drew the chips
|
|
168
|
+
as 8px boxes at 700 (DqTeamwachtrij), so the chip hands its pill radius and
|
|
169
|
+
600 to those tokens.
|
|
170
|
+
@spec openspec/changes/board-chips-theme/specs/board-chips-theme/spec.md#requirement-board-chips-stay-pills-under-a-theme */
|
|
166
171
|
.cn-look-board .cn-saved-views__chips .cn-saved-views__chip,
|
|
167
172
|
.cn-look-board .cn-quick-filter-bar .cn-quick-filter-bar__tab {
|
|
173
|
+
--nldesign-component-button-border-radius: 19px;
|
|
174
|
+
--nldesign-component-button-font-weight: 600;
|
|
168
175
|
display: inline-flex;
|
|
169
176
|
align-items: center;
|
|
170
177
|
gap: 8px;
|
|
@@ -267,12 +274,30 @@
|
|
|
267
274
|
padding: 0;
|
|
268
275
|
}
|
|
269
276
|
|
|
270
|
-
/*
|
|
277
|
+
/* The toolbar's buttons are the board's neutral control (DqTeamwachtrij
|
|
278
|
+
"Filter"): the main text at 600 on the main background with a grey border.
|
|
279
|
+
The nldesign theme paints a secondary button in the primary colour with
|
|
280
|
+
`!important` through its button tokens, so the bar hands the board's values
|
|
281
|
+
to those tokens.
|
|
282
|
+
@spec openspec/changes/board-toolbar-buttons-theme/specs/board-toolbar-buttons-theme/spec.md#requirement-board-toolbar-buttons-are-neutral-under-a-theme */
|
|
283
|
+
.cn-look-board .cn-actions-bar:not(.cn-look-nextcloud *) {
|
|
284
|
+
--nldesign-component-button-font-weight: 600;
|
|
285
|
+
--nldesign-component-button-secondary-action-color: var(--color-main-text);
|
|
286
|
+
--nldesign-component-button-secondary-action-background-color: var(--color-main-background);
|
|
287
|
+
--nldesign-component-button-secondary-action-border-color: var(--color-border-dark);
|
|
288
|
+
--nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* Filter: a labelled secondary button, 36px, radius 8, 12px at both sides
|
|
292
|
+
and 14px text, with the active count. NcButton with an icon pads its start
|
|
293
|
+
4px and sets 15px. */
|
|
271
294
|
.cn-look-board .cn-actions-bar__filter-button.button-vue,
|
|
272
295
|
.cn-look-board .cn-actions-bar__filter-menu .button-vue {
|
|
273
296
|
min-height: 36px;
|
|
274
297
|
height: 36px;
|
|
298
|
+
padding: 0 12px;
|
|
275
299
|
border-radius: 8px;
|
|
300
|
+
font-size: 14px;
|
|
276
301
|
font-weight: 600;
|
|
277
302
|
}
|
|
278
303
|
|
|
@@ -513,9 +538,18 @@
|
|
|
513
538
|
|
|
514
539
|
/* The header row is near-white on the boards (#fafbfc), not the hover grey,
|
|
515
540
|
its labels 14px muted. The ink also goes to --nldesign-color-on-surface,
|
|
516
|
-
which a theme that forces the body ink onto every span (thematiq) reads.
|
|
541
|
+
which a theme that forces the body ink onto every span (thematiq) reads.
|
|
542
|
+
The nldesign theme paints every `th` with `!important` through its table
|
|
543
|
+
header tokens, and the sort button in it through its button weight token
|
|
544
|
+
(bold), so the cell hands the board's ground, ink and weight to those
|
|
545
|
+
tokens too.
|
|
546
|
+
@spec openspec/changes/board-table-head-theme/specs/board-table-head-theme/spec.md#requirement-a-board-table-header-keeps-the-boards-ground-ink-and-weight-under-a-theme */
|
|
517
547
|
.cn-look-board .cn-table-container--board .cn-data-table th {
|
|
518
548
|
--nldesign-color-on-surface: var(--color-text-maxcontrast);
|
|
549
|
+
--nldesign-component-table-header-background-color: var(--cn-board-table-head-bg, color-mix(in srgb, var(--color-background-hover) 40%, var(--color-main-background)));
|
|
550
|
+
--nldesign-component-table-header-color: var(--color-text-maxcontrast);
|
|
551
|
+
--nldesign-component-table-header-font-weight: 600;
|
|
552
|
+
--nldesign-component-button-font-weight: 600;
|
|
519
553
|
padding: 12px 16px;
|
|
520
554
|
border-bottom: 0;
|
|
521
555
|
background: var(--cn-board-table-head-bg, color-mix(in srgb, var(--color-background-hover) 40%, var(--color-main-background)));
|