@conduction/nextcloud-vue 2.3.0 → 2.4.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.
@@ -0,0 +1,133 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
3
+ * SPDX-License-Identifier: EUPL-1.2
4
+ *
5
+ * PUBLIC-SAFE SITE BLOCKS — the entry point a portal renderer can import when
6
+ * it runs at a public origin with NO Nextcloud behind it.
7
+ *
8
+ * WHY THIS ENTRY POINT EXISTS AT ALL
9
+ *
10
+ * nc-vue's main entry is deeply coupled to the Nextcloud runtime: measured on
11
+ * the published build, 154 files reference `@nextcloud/axios` and 157
12
+ * reference `@nextcloud/router`. That is correct for an app rendering inside
13
+ * Nextcloud and fatal for one rendering at `https://portaal.gemeente.nl`,
14
+ * where there is no `OC` global, no session and no translation bundle.
15
+ *
16
+ * WHY THESE ARE NEW COMPONENTS RATHER THAN RE-EXPORTS
17
+ *
18
+ * The first plan was to re-export the existing widgets that "looked clean".
19
+ * A DIRECT import check agreed: 12 of 13 candidates had no `@nextcloud/*`
20
+ * import in their own file. A TRANSITIVE check — following relative imports
21
+ * through the tree — inverted that result completely:
22
+ *
23
+ * CnTextWidget -> @nextcloud/l10n
24
+ * CnHeaderWidget -> @nextcloud/l10n, @nextcloud/router
25
+ * CnCardGrid -> @nextcloud/l10n, @nextcloud/vue,
26
+ * @nextcloud/auth, @nextcloud/event-bus
27
+ * ... 12 of 13 unsafe
28
+ *
29
+ * Only `CnCard` was clean all the way down. Re-exporting the rest under a
30
+ * name promising public safety would have shipped a guarantee that the first
31
+ * public deployment disproved — and it would have failed at RUNTIME, in a
32
+ * browser, on a government portal, rather than at build time here.
33
+ *
34
+ * So these blocks take their strings as PROPS instead of calling `t()`. That
35
+ * single decision is what keeps them portable: `@nextcloud/l10n` is the
36
+ * dependency almost every existing widget trips over.
37
+ *
38
+ * THE GUARANTEE IS CHECKED, NOT ASSERTED. `npm run check:public-safe` walks
39
+ * this entry's transitive imports and fails on any `@nextcloud/*`. A comment
40
+ * claiming purity is worth nothing; the check is in CI.
41
+ */
42
+
43
+ import CnSiteCard from './components/CnSiteCard.vue'
44
+ import CnSiteCardGrid from './components/CnSiteCardGrid.vue'
45
+ import CnSiteEmptyState from './components/CnSiteEmptyState.vue'
46
+ import CnSiteGlossary from './components/CnSiteGlossary.vue'
47
+ import CnSiteHero from './components/CnSiteHero.vue'
48
+ import CnSiteIcon from './components/CnSiteIcon.vue'
49
+ import CnSiteSearch from './components/CnSiteSearch.vue'
50
+ import CnSiteSection from './components/CnSiteSection.vue'
51
+
52
+ export {
53
+ CnSiteCard,
54
+ CnSiteCardGrid,
55
+ CnSiteEmptyState,
56
+ CnSiteGlossary,
57
+ CnSiteHero,
58
+ CnSiteIcon,
59
+ CnSiteSearch,
60
+ CnSiteSection,
61
+ }
62
+
63
+ /**
64
+ * The block vocabulary, keyed by the `widgetKey` a page body declares.
65
+ *
66
+ * A REGISTRY rather than a switch in the consumer. A consumer that resolves
67
+ * blocks with `if (key === 'markdown')` cannot be extended without editing the
68
+ * consumer, which is how portaliq ended up supporting exactly one block type
69
+ * while this library already shipped thirty-four.
70
+ *
71
+ * Anything not in this map is UNKNOWN, and a renderer must say so visibly
72
+ * rather than render nothing — a page silently missing a block looks identical
73
+ * to a page that was authored empty.
74
+ *
75
+ * @type {Record<string, object>}
76
+ */
77
+ export const siteBlockRegistry = {
78
+ hero: CnSiteHero,
79
+ search: CnSiteSearch,
80
+ section: CnSiteSection,
81
+ cardGrid: CnSiteCardGrid,
82
+ card: CnSiteCard,
83
+ emptyState: CnSiteEmptyState,
84
+ glossary: CnSiteGlossary,
85
+ }
86
+
87
+ /**
88
+ * Blocks that are FULL-BLEED BANDS and carry their own container.
89
+ *
90
+ * A band paints edge to edge and constrains its content itself. Rendering one
91
+ * inside a host's content column silently shrinks it: measured against the NL
92
+ * Design System reference, a hero nested in the page container came out
93
+ * 1168px wide against the design's 1280, and no amount of styling inside the
94
+ * hero could recover the missing width because the clamp was an ancestor.
95
+ *
96
+ * The reference's own structure is the model — `main` is full-bleed and every
97
+ * `section` brings a `.container` — so a host must ask this before deciding
98
+ * whether to wrap a block.
99
+ *
100
+ * @param {string} key The block key.
101
+ * @return {boolean} True when the block must NOT be wrapped in a container.
102
+ */
103
+ export function siteBlockIsBand(key) {
104
+ return SITE_BAND_BLOCKS.includes(key)
105
+ }
106
+
107
+ /**
108
+ * @type {Array<string>} The band block keys.
109
+ */
110
+ export const SITE_BAND_BLOCKS = ['hero', 'section']
111
+
112
+ /**
113
+ * Resolve a block component by key.
114
+ *
115
+ * @param {string} key The `widgetKey` from a page body.
116
+ * @return {object|null} The component, or null when the key is unknown.
117
+ */
118
+ export function siteBlockFor(key) {
119
+ return siteBlockRegistry[key] || null
120
+ }
121
+
122
+ /**
123
+ * The keys this entry point can render.
124
+ *
125
+ * Exported so a consumer — or a test — can assert the vocabulary it depends on
126
+ * is actually present, rather than discovering a missing block as a blank area
127
+ * on a live page.
128
+ *
129
+ * @return {Array<string>} The known block keys.
130
+ */
131
+ export function listSiteBlocks() {
132
+ return Object.keys(siteBlockRegistry)
133
+ }