@iqual/nuxt-icms 1.0.13 → 1.1.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 (40) hide show
  1. package/components/Blokkli/Timeline/Element/icms_timeline_element.svg +7 -0
  2. package/components/Blokkli/Timeline/Element/icon.svg +7 -0
  3. package/components/Blokkli/Timeline/Element/index.vue +14 -0
  4. package/components/Blokkli/Timeline/Layout/icms_layout_timeline.svg +16 -0
  5. package/components/Blokkli/Timeline/Layout/icon.svg +16 -0
  6. package/components/Blokkli/Timeline/Layout/index.vue +14 -0
  7. package/components/Blokkli/iFrame/icon-blokkli-option-large-spacing-bottom.svg +1 -0
  8. package/components/Blokkli/iFrame/icon-blokkli-option-large-spacing-top.svg +1 -0
  9. package/components/Blokkli/iFrame/icon-blokkli-option-no-spacing.svg +1 -0
  10. package/components/Blokkli/iFrame/icon-blokkli-option-small-spacing-bottom.svg +1 -0
  11. package/components/Blokkli/iFrame/icon-blokkli-option-small-spacing-top.svg +1 -0
  12. package/components/Blokkli/iFrame/{Layout/index.vue → index.vue} +2 -6
  13. package/components/DesignSystem/Organisms/TimelineElement.vue +92 -0
  14. package/components/Media/Image/index.vue +1 -1
  15. package/components/Media/RemoteVideo/index.vue +18 -11
  16. package/components/Media/Video/index.vue +6 -4
  17. package/components/Paragraph/Media/index.vue +13 -8
  18. package/components/Paragraph/Timeline/Element/fragment.graphql +16 -0
  19. package/components/Paragraph/Timeline/Element/index.vue +31 -0
  20. package/components/Paragraph/Timeline/Layout/fragment.graphql +14 -0
  21. package/components/Paragraph/Timeline/Layout/index.vue +325 -0
  22. package/components/Paragraph/iFrame/{Layout/fragment.graphql → fragment.graphql} +2 -6
  23. package/components/Paragraph/iFrame/index.vue +56 -0
  24. package/nuxt.config.ts +17 -10
  25. package/package.json +1 -1
  26. package/server/graphqlMiddleware.serverOptions.ts +3 -3
  27. package/tests/pages.spec.ts +101 -0
  28. package/vitest.config.mts +2 -2
  29. package/components/Blokkli/iFrame/Element/icon.svg +0 -5
  30. package/components/Blokkli/iFrame/Element/index.vue +0 -14
  31. package/components/Paragraph/iFrame/Element/fragment.graphql +0 -9
  32. package/components/Paragraph/iFrame/Element/index.vue +0 -16
  33. package/components/Paragraph/iFrame/Layout/index.vue +0 -161
  34. package/pages/__tests__/index.ts +0 -77
  35. /package/components/Blokkli/{iFrame → Timeline}/Layout/icon-blokkli-option-large-spacing-bottom.svg +0 -0
  36. /package/components/Blokkli/{iFrame → Timeline}/Layout/icon-blokkli-option-large-spacing-top.svg +0 -0
  37. /package/components/Blokkli/{iFrame → Timeline}/Layout/icon-blokkli-option-no-spacing.svg +0 -0
  38. /package/components/Blokkli/{iFrame → Timeline}/Layout/icon-blokkli-option-small-spacing-bottom.svg +0 -0
  39. /package/components/Blokkli/{iFrame → Timeline}/Layout/icon-blokkli-option-small-spacing-top.svg +0 -0
  40. /package/components/Blokkli/iFrame/{Layout/icon.svg → icon.svg} +0 -0
@@ -0,0 +1,325 @@
1
+ <template>
2
+ <DesignSystemAtomsContainer :color-scheme="colorScheme" :spacing="spacing">
3
+ <DesignSystemAtomsGridRow v-if="pretitle || title || subtitle || text">
4
+ <div class="col-span-12">
5
+ <DesignSystemOrganismsContentBlock
6
+ :pretitle="pretitle"
7
+ :title="title"
8
+ :titleStyle="titleStyle"
9
+ :titleWeight="titleWeight"
10
+ :subtitle="subtitle"
11
+ :text="text"
12
+ :colorScheme="colorScheme"
13
+ :hasDecorativeLine="Boolean(subtitle || text)"
14
+ />
15
+ </div>
16
+ </DesignSystemAtomsGridRow>
17
+
18
+ <DesignSystemAtomsGridRow class="mt-10 lg:mt-20">
19
+ <!-- Anchor navigation -->
20
+ <div class="relative col-span-12 mb-6 lg:col-span-4 lg:mb-0">
21
+ <ul
22
+ v-if="!isEditing"
23
+ class="sticky left-0 top-32 z-10 flex flex-col gap-2"
24
+ >
25
+ <li v-for="(item, index) in props.timelineElements" :key="index">
26
+ <button
27
+ @click="handleAnchorLinkClick(Number(index))"
28
+ class="cursor-pointer transition-colors duration-200 ease-in-out"
29
+ :class="{
30
+ 'font-semibold': currentIndex === Number(index),
31
+ }"
32
+ >
33
+ {{ item.props?.title }}
34
+ </button>
35
+ </li>
36
+ </ul>
37
+ </div>
38
+
39
+ <div class="relative col-span-12 lg:col-span-8">
40
+ <!-- Mobile slider navigation -->
41
+ <div
42
+ v-if="isMobile && !isEditing"
43
+ class="relative col-span-12 mb-10 lg:col-span-4"
44
+ >
45
+ <ul
46
+ :class="decorativeLine({ colorScheme })"
47
+ class="flex h-0.5 flex-nowrap items-center justify-between"
48
+ >
49
+ <li
50
+ v-for="(_, index) in props.timelineElements"
51
+ :key="index"
52
+ class="p-4 first:-translate-x-4 last:translate-x-4"
53
+ >
54
+ <button
55
+ @click="handleAnchorLinkClick(Number(index))"
56
+ :class="
57
+ carouselDot({
58
+ colorScheme,
59
+ active: currentIndex === Number(index),
60
+ })
61
+ "
62
+ ></button>
63
+ </li>
64
+ </ul>
65
+ </div>
66
+
67
+ <!-- Mobile slider -->
68
+ <Carousel
69
+ v-if="isMobile && !isEditing"
70
+ @init-api="setApi"
71
+ :class="carousel({ colorScheme })"
72
+ >
73
+ <BlokkliField
74
+ v-slot="{ items }"
75
+ name="field_icms_timeline_elements"
76
+ :list="timelineElements"
77
+ proxy-mode
78
+ >
79
+ <CarouselContent class="m-0 gap-8">
80
+ <BlokkliItem v-for="item in items" v-bind="item" />
81
+ </CarouselContent>
82
+ </BlokkliField>
83
+ <CarouselPrevious
84
+ class="-bottom-[90px] left-0 top-auto xl:bottom-auto xl:left-16 xl:top-1/2"
85
+ :class="carouselButton({ colorScheme })"
86
+ >
87
+ <ChevronLeft :size="24" :stroke-width="1" />
88
+ </CarouselPrevious>
89
+ <CarouselNext
90
+ class="-bottom-[90px] left-[66px] top-auto xl:bottom-auto xl:left-auto xl:right-16 xl:top-1/2"
91
+ :class="carouselButton({ colorScheme })"
92
+ >
93
+ <ChevronRight :size="24" :stroke-width="1" />
94
+ </CarouselNext>
95
+ </Carousel>
96
+
97
+ <!-- Desktop timeline -->
98
+ <BlokkliField
99
+ v-if="isEditing || !isMobile"
100
+ name="field_icms_timeline_elements"
101
+ :list="timelineElements"
102
+ class="flex flex-col gap-32"
103
+ :class="{ droptarget: isEditing }"
104
+ />
105
+
106
+ <!-- Desktop line -->
107
+ <template v-if="!isMobile && !isEditing">
108
+ <div :class="decorativeCircle({ colorScheme })" class="top-0"></div>
109
+ <div
110
+ :class="decorativeLine({ colorScheme })"
111
+ class="absolute left-1/2 top-0 h-full w-0.5 -translate-x-1/2"
112
+ ></div>
113
+ <div
114
+ :class="decorativeCircle({ colorScheme })"
115
+ class="bottom-0"
116
+ ></div>
117
+ </template>
118
+ </div>
119
+ </DesignSystemAtomsGridRow>
120
+ </DesignSystemAtomsContainer>
121
+ </template>
122
+
123
+ <script lang="ts" setup>
124
+ import type { ParagraphIcmsLayoutTimelineFragment } from '#graphql-operations'
125
+ import { tv } from 'tailwind-variants'
126
+ import type { CarouselApi } from '@iqual/nuxt-icms/components/ui/carousel'
127
+ import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
128
+
129
+ const props = defineProps<ParagraphIcmsLayoutTimelineFragment>()
130
+
131
+ const { options, isEditing } = useAttrs().blokkliData
132
+
133
+ const { isMobile } = useIsMobile()
134
+
135
+ const colorScheme = computed(() => {
136
+ return options.value.colorScheme
137
+ })
138
+
139
+ const spacing = computed(() => {
140
+ return { bottom: options.value.spacingBottom, top: options.value.spacingTop }
141
+ })
142
+
143
+ const childTitleWeight = useChildTitleWeight(props.titleWeight ?? '')
144
+
145
+ const api = ref<CarouselApi>()
146
+ function setApi(val: CarouselApi) {
147
+ api.value = val
148
+
149
+ val?.on('select', () => {
150
+ const selectedIndex = val.selectedScrollSnap()
151
+ setCurrentIndex(selectedIndex)
152
+ })
153
+ }
154
+
155
+ const currentIndex = ref(0)
156
+ const setCurrentIndex = (index: number) => {
157
+ if (index < 0 || index >= (props.timelineElements?.length ?? 0)) return
158
+ currentIndex.value = index
159
+ }
160
+
161
+ const scrollToCarousel = (index: number) => {
162
+ if (!index && !api.value) return
163
+ nextTick(() => {
164
+ api.value?.scrollTo(index)
165
+ })
166
+ }
167
+
168
+ const scrollToElement = (element: HTMLElement) => {
169
+ if (!element) return
170
+ nextTick(() => {
171
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' })
172
+ })
173
+ }
174
+
175
+ const getTimelineElements = () =>
176
+ document.querySelectorAll('[data-timeline-element]')
177
+
178
+ const handleAnchorLinkClick = (index: number) => {
179
+ if (isMobile.value) {
180
+ setCurrentIndex(index)
181
+ scrollToCarousel(index)
182
+ } else {
183
+ const elements = getTimelineElements()
184
+ scrollToElement(elements[index] as HTMLElement)
185
+ }
186
+ }
187
+
188
+ const timelineObserver = ref<IntersectionObserver | null>(null)
189
+
190
+ onMounted(() => {
191
+ if (isEditing || isMobile.value) return
192
+
193
+ const elements = getTimelineElements()
194
+
195
+ timelineObserver.value = new IntersectionObserver(
196
+ (entries) => {
197
+ entries.forEach((entry) => {
198
+ if (entry.isIntersecting) {
199
+ const index = Array.from(elements).indexOf(
200
+ entry.target as HTMLElement,
201
+ )
202
+ if (index !== -1) {
203
+ setCurrentIndex(index)
204
+ }
205
+ }
206
+ })
207
+ },
208
+ {
209
+ rootMargin: '-10% 0px -80% 0px',
210
+ threshold: 0,
211
+ },
212
+ )
213
+
214
+ elements.forEach((element) => {
215
+ timelineObserver.value?.observe(element)
216
+ })
217
+ })
218
+
219
+ onUnmounted(() => {
220
+ timelineObserver.value?.disconnect()
221
+ })
222
+
223
+ const carousel = tv({
224
+ base: 'rounded-lg',
225
+ variants: {
226
+ colorScheme: {
227
+ none: 'bg-white',
228
+ dark: 'bg-gray-950',
229
+ light: 'bg-gray-50',
230
+ accent: 'bg-primary-600',
231
+ },
232
+ },
233
+ defaultVariants: {
234
+ colorScheme: 'none',
235
+ },
236
+ })
237
+
238
+ const carouselButton = tv({
239
+ base: 'size-10 border-none disabled:opacity-40 @sm:size:12 @md:size-16 [&_svg]:size-auto',
240
+ variants: {
241
+ colorScheme: {
242
+ none: 'bg-gray-50 text-black hover:bg-black hover:text-white dark:bg-gray-50 dark:text-black hover:dark:bg-black hover:dark:text-white',
243
+ dark: 'bg-white text-black hover:bg-gray-100 hover:text-black dark:bg-white dark:text-black hover:dark:bg-gray-100 hover:dark:text-black',
244
+ light:
245
+ 'bg-gray-100 text-black hover:bg-black hover:text-white dark:bg-gray-100 dark:text-black hover:dark:bg-black hover:dark:text-white',
246
+ accent:
247
+ 'bg-primary-700 text-white hover:bg-primary-800 hover:text-white dark:bg-primary-700 dark:text-white hover:dark:bg-primary-800 hover:dark:text-white',
248
+ },
249
+ },
250
+ defaultVariants: {
251
+ colorScheme: 'none',
252
+ },
253
+ })
254
+
255
+ const decorativeLine = tv({
256
+ base: '',
257
+ variants: {
258
+ colorScheme: {
259
+ none: 'bg-gray-200',
260
+ dark: 'bg-white',
261
+ light: 'bg-gray-200',
262
+ accent: 'bg-white',
263
+ },
264
+ },
265
+ defaultVariants: {
266
+ colorScheme: 'none',
267
+ },
268
+ })
269
+
270
+ const decorativeCircle = tv({
271
+ base: 'absolute left-1/2 size-4 -translate-x-1/2 border-2 rounded-full z-10',
272
+ variants: {
273
+ colorScheme: {
274
+ none: 'border-gray-200 bg-white',
275
+ dark: 'border-white bg-gray-950',
276
+ light: 'border-gray-200 bg-gray-50',
277
+ accent: 'border-white bg-primary-600',
278
+ },
279
+ },
280
+ defaultVariants: {
281
+ colorScheme: 'none',
282
+ },
283
+ })
284
+
285
+ const carouselDot = tv({
286
+ base: 'cursor-pointer transition-colors duration-200 ease-in-out size-4 border-2 rounded-full',
287
+ variants: {
288
+ colorScheme: {
289
+ none: 'bg-white border-gray-200',
290
+ dark: 'bg-gray-950 border-white',
291
+ light: 'bg-gray-50 border-gray-200',
292
+ accent: 'bg-primary-600 border-white',
293
+ },
294
+ },
295
+ compoundVariants: [
296
+ {
297
+ colorScheme: 'none',
298
+ active: true,
299
+ class: 'bg-gray-200',
300
+ },
301
+ {
302
+ colorScheme: 'dark',
303
+ active: true,
304
+ class: 'bg-white',
305
+ },
306
+ {
307
+ colorScheme: 'light',
308
+ active: true,
309
+ class: 'bg-gray-200',
310
+ },
311
+ {
312
+ colorScheme: 'accent',
313
+ active: true,
314
+ class: 'bg-white',
315
+ },
316
+ ],
317
+ defaultVariants: {
318
+ colorScheme: 'none',
319
+ active: false,
320
+ },
321
+ })
322
+
323
+ provide('colorScheme', colorScheme)
324
+ provide('titleWeight', childTitleWeight)
325
+ </script>
@@ -4,10 +4,6 @@ fragment paragraphIcmsLayoutIframe on ParagraphIcmsLayoutIframe {
4
4
  titleWeight: fieldIcmsTitleWeight
5
5
  titleStyle: fieldIcmsTitleStyle
6
6
  text: fieldIcmsText
7
- iFrameElements: fieldIcmsIframeElements {
8
- ...paragraphsFieldItem
9
- props {
10
- ...paragraphIcmsIframeElement
11
- }
12
- }
7
+ embed: fieldIcmsEmbedCode
8
+ height: fieldIcmsIframeHeight
13
9
  }
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <DesignSystemAtomsContainer :colorScheme="colorScheme" :spacing="spacing">
3
+ <DesignSystemAtomsGridRow>
4
+ <div :class="textWrapperClassList">
5
+ <DesignSystemOrganismsContentBlock
6
+ :pretitle="pretitle"
7
+ :title="title"
8
+ :titleWeight="titleWeight"
9
+ :text="text"
10
+ :colorScheme="colorScheme"
11
+ />
12
+
13
+ <div
14
+ v-if="embed"
15
+ v-html="embed"
16
+ class="embed-wrapper mt-10"
17
+ :style="{ '--iframe-height': `${props.height || 600}px` }"
18
+ />
19
+ </div>
20
+ </DesignSystemAtomsGridRow>
21
+ </DesignSystemAtomsContainer>
22
+ </template>
23
+
24
+ <script lang="ts" setup>
25
+ import type { ParagraphIcmsLayoutIframeFragment } from '#graphql-operations'
26
+
27
+ const props = defineProps<ParagraphIcmsLayoutIframeFragment>()
28
+
29
+ const { options, isEditing } = useAttrs().blokkliData
30
+
31
+ const textWrapperClassList = computed(() => {
32
+ if (options.value.textWidth === 'medium') {
33
+ return ['col-span-8', 'col-start-3']
34
+ } else if (options.value.textWidth === 'narrow') {
35
+ return ['col-span-8', 'col-start-3', 'md:col-span-6', 'md:col-start-4']
36
+ }
37
+ return ['col-span-12']
38
+ })
39
+
40
+ const colorScheme = computed(() => {
41
+ return options.value.colorScheme
42
+ })
43
+
44
+ const spacing = computed(() => {
45
+ return { bottom: options.value.spacingBottom, top: options.value.spacingTop }
46
+ })
47
+
48
+ provide('isEditing', isEditing)
49
+ </script>
50
+
51
+ <style>
52
+ .embed-wrapper > iframe {
53
+ width: 100%;
54
+ height: var(--iframe-height, 600px);
55
+ }
56
+ </style>
package/nuxt.config.ts CHANGED
@@ -168,15 +168,21 @@ export default defineNuxtConfig({
168
168
  drupalRoute: {
169
169
  enabled: true,
170
170
  routeQueries: {
171
- nodeIcmsPage: { fragments: [
172
- 'nodeIcmsPage'
173
- ] },
174
- slug: { fragments: [
175
- 'nodeIcmsPage',
176
- ]},
177
- nodeCanonical: { fragments: [
178
- 'nodeIcmsPage',
179
- ]},
171
+ nodeIcmsPage: {
172
+ fragments: [
173
+ 'nodeIcmsPage'
174
+ ]
175
+ },
176
+ slug: {
177
+ fragments: [
178
+ 'nodeIcmsPage',
179
+ ]
180
+ },
181
+ nodeCanonical: {
182
+ fragments: [
183
+ 'nodeIcmsPage',
184
+ ]
185
+ },
180
186
  },
181
187
  },
182
188
  devMode: {
@@ -217,6 +223,7 @@ export default defineNuxtConfig({
217
223
  'paragraphIcmsLayoutMedia',
218
224
  'paragraphIcmsLayoutDownloads',
219
225
  'paragraphIcmsLayoutIframe',
226
+ 'paragraphIcmsLayoutTimeline',
220
227
  // Element components
221
228
  'paragraphIcmsButtonElement',
222
229
  'paragraphIcmsCardElement',
@@ -228,7 +235,7 @@ export default defineNuxtConfig({
228
235
  'paragraphIcms2ColTextElement',
229
236
  'paragraphIcmsLogoElement',
230
237
  'paragraphIcmsPartnershipElement',
231
- 'paragraphIcmsIframeElement',
238
+ 'paragraphIcmsTimelineElement',
232
239
  ]
233
240
  }
234
241
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iqual/nuxt-icms",
3
- "version": "1.0.13",
3
+ "version": "1.1.0",
4
4
  "description": "ICMS Base",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1,8 +1,8 @@
1
1
  import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/server-options'
2
- import { extractCacheability } from '~/packages/nuxt-icms/server/utils/cacheability'
3
- import type { GraphqlCacheability } from '~/packages/nuxt-icms/server/helpers'
2
+ import { extractCacheability } from '@iqual/nuxt-icms/server/utils/cacheability'
3
+ import type { GraphqlCacheability } from '@iqual/nuxt-icms/server/helpers'
4
4
  import { defaultLangcode, langcodes } from '#nuxt-language-negotiation/config'
5
- import { buildProxyRequestHeaders } from '~/packages/nuxt-icms/server/helpers/request'
5
+ import { buildProxyRequestHeaders } from '@iqual/nuxt-icms/server/helpers/request'
6
6
 
7
7
  export default defineGraphqlServerOptions<{
8
8
  extensions: {
@@ -0,0 +1,101 @@
1
+ import path from 'path'
2
+ import { promises as fsp } from 'fs'
3
+ import { describe, it, expect } from 'vitest'
4
+ import * as ts from 'typescript'
5
+ import { parse as parseSfc } from '@vue/compiler-sfc'
6
+
7
+ // Recursively find all Vue files in a directory
8
+ async function findVueFiles(
9
+ dir: string,
10
+ ignorePatterns: string[] = [],
11
+ ): Promise<string[]> {
12
+ const entries = await fsp.readdir(dir, { withFileTypes: true })
13
+ const files: string[] = []
14
+
15
+ for (const entry of entries) {
16
+ const fullPath = path.join(dir, entry.name)
17
+
18
+ // Skip if path matches any ignore pattern
19
+ if (ignorePatterns.some((pattern) => fullPath.includes(pattern))) {
20
+ continue
21
+ }
22
+
23
+ if (entry.isDirectory()) {
24
+ const subFiles = await findVueFiles(fullPath, ignorePatterns)
25
+ files.push(...subFiles)
26
+ } else if (entry.name.endsWith('.vue')) {
27
+ files.push(fullPath)
28
+ }
29
+ }
30
+
31
+ return files
32
+ }
33
+
34
+ // Parse a Vue SFC and check if the component's script calls the given function at least once.
35
+ function functionIsCalledAtLeastOnce(
36
+ vueFileContents: string,
37
+ functionName: string,
38
+ ): boolean {
39
+ const result = parseSfc(vueFileContents)
40
+ const script = result.descriptor.scriptSetup?.content
41
+ if (!script) {
42
+ return false
43
+ }
44
+ const sourceFile = ts.createSourceFile(
45
+ 'temp.ts',
46
+ script,
47
+ ts.ScriptTarget.ES2015,
48
+ true,
49
+ )
50
+
51
+ let isCalled = false
52
+
53
+ function visit(node: ts.Node) {
54
+ if (
55
+ ts.isCallExpression(node) &&
56
+ node.expression.getText(sourceFile) === functionName
57
+ ) {
58
+ isCalled = true
59
+ }
60
+
61
+ if (!isCalled) {
62
+ ts.forEachChild(node, visit)
63
+ }
64
+ }
65
+
66
+ ts.forEachChild(sourceFile, visit)
67
+
68
+ return isCalled
69
+ }
70
+
71
+ describe('The Nuxt page component', async () => {
72
+ const rootDir = path.resolve(__dirname, './../app/pages')
73
+ const ignorePatterns = ['blokkli']
74
+
75
+ const pageFilePaths = await findVueFiles(rootDir, ignorePatterns)
76
+ console.log(pageFilePaths)
77
+
78
+ const pageComponentFiles = await Promise.all(
79
+ pageFilePaths.map((filePath) => {
80
+ return fsp.readFile(filePath, { encoding: 'utf8' }).then((content) => {
81
+ return {
82
+ filePath,
83
+ content,
84
+ }
85
+ })
86
+ }),
87
+ )
88
+
89
+ pageComponentFiles.forEach(({ filePath, content }) => {
90
+ it(`"${filePath}" should call useDrupalRouteQuery()`, () => {
91
+ expect(
92
+ functionIsCalledAtLeastOnce(content, 'useDrupalRouteQuery'),
93
+ ).toEqual(true)
94
+ })
95
+ it(`"${filePath}" should call renderPageDependencies()`, () => {
96
+ expect(
97
+ functionIsCalledAtLeastOnce(content, 'renderPageDependencies'),
98
+ ).toEqual(true)
99
+ })
100
+ })
101
+ })
package/vitest.config.mts CHANGED
@@ -6,9 +6,9 @@ export default defineVitestConfig({
6
6
  globals: true,
7
7
  environment: 'nuxt',
8
8
  alias: {
9
- '~': path.resolve(__dirname, './'),
9
+ '~': path.resolve(__dirname, './app'),
10
+ '~~': path.resolve(__dirname, './'),
10
11
  },
11
- include: ['**/__tests__/*.*'],
12
12
  coverage: {
13
13
  all: true,
14
14
  provider: 'v8',
@@ -1,5 +0,0 @@
1
- <svg width="18" height="14" viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg" style="fill:none!important;">
2
- <path d="M6 1L1.80023 6.03972C1.33667 6.59599 1.33667 7.40401 1.80023 7.96028L6 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
3
- <path d="M12 13L16.1998 7.96028C16.6633 7.40401 16.6633 6.59599 16.1998 6.03972L12 1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
4
- <path d="M7.5 10.5L10.5 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
5
- </svg>
@@ -1,14 +0,0 @@
1
- <template>
2
- <ParagraphIFrameElement v-bind="props" :blokkliData="blokkliData" />
3
- </template>
4
-
5
- <script lang="ts" setup>
6
- import type { ParagraphIcmsIframeElementFragment } from '#graphql-operations'
7
-
8
- const props = defineProps<ParagraphIcmsIframeElementFragment>()
9
-
10
- const blokkliData = defineBlokkli({
11
- bundle: 'icms_iframe_element',
12
- })
13
-
14
- </script>
@@ -1,9 +0,0 @@
1
- fragment paragraphIcmsIframeElement on ParagraphIcmsIframeElement {
2
- title: fieldIcmsTitle
3
- link: fieldIcmsLink {
4
- uri {
5
- path
6
- }
7
- }
8
- height: fieldIcmsNumber
9
- }
@@ -1,16 +0,0 @@
1
- <template>
2
- <DesignSystemMoleculesIFrame
3
- :title="title"
4
- :link="link?.uri?.path"
5
- :height="height"
6
- :is-editing="isEditing"
7
- />
8
- </template>
9
-
10
- <script lang="ts" setup>
11
- import type { ParagraphIcmsIframeElementFragment } from '#graphql-operations'
12
-
13
- defineProps<ParagraphIcmsIframeElementFragment>()
14
-
15
- const isEditing = inject<boolean>('isEditing')
16
- </script>