@iqual/nuxt-icms 1.3.0 → 1.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.
Files changed (122) hide show
  1. package/assets/symbols/chevron-right.svg +1 -1
  2. package/components/Blokkli/HeroImage/index.vue +1 -1
  3. package/components/Blokkli/Teasers/icon.svg +3 -3
  4. package/components/DesignSystem/Atoms/Button.vue +86 -36
  5. package/components/DesignSystem/Atoms/Caption.vue +10 -10
  6. package/components/DesignSystem/Atoms/Container.vue +10 -6
  7. package/components/DesignSystem/Atoms/GridRow.vue +4 -3
  8. package/components/DesignSystem/Atoms/LinkListItem.vue +31 -8
  9. package/components/DesignSystem/Molecules/ButtonGroup.vue +18 -3
  10. package/components/DesignSystem/Molecules/Card.vue +86 -31
  11. package/components/DesignSystem/Molecules/IconText.vue +37 -16
  12. package/components/DesignSystem/Molecules/MediaLightbox.vue +213 -58
  13. package/components/DesignSystem/Molecules/MediaSlider.vue +88 -25
  14. package/components/DesignSystem/Molecules/Partnership.vue +40 -9
  15. package/components/DesignSystem/Molecules/Table.vue +90 -25
  16. package/components/DesignSystem/Molecules/TitleComposition.vue +15 -12
  17. package/components/DesignSystem/Organisms/ContentBlock.vue +61 -15
  18. package/components/DesignSystem/Organisms/FacetedListing.vue +170 -0
  19. package/components/DesignSystem/Organisms/FlipTeaser.vue +119 -47
  20. package/components/DesignSystem/Organisms/HeaderHero.vue +167 -0
  21. package/components/DesignSystem/Organisms/HeaderTextImage.vue +71 -0
  22. package/components/DesignSystem/Organisms/LogoElement.vue +33 -10
  23. package/components/DesignSystem/Organisms/Map.vue +11 -6
  24. package/components/DesignSystem/Organisms/SearchResults.vue +41 -0
  25. package/components/DesignSystem/Organisms/TeamElement.vue +84 -20
  26. package/components/DesignSystem/Organisms/TeaserCard.vue +87 -34
  27. package/components/DesignSystem/Organisms/Testimonial.vue +82 -12
  28. package/components/DesignSystem/Organisms/TimelineElement.vue +42 -12
  29. package/components/DesignSystem/Organisms/TwoColumnTextElement.vue +44 -9
  30. package/components/DesignSystem/Pages/Search.vue +39 -0
  31. package/components/Drupal/Breadcrumb/index.vue +16 -5
  32. package/components/Drupal/Messages/index.vue +16 -5
  33. package/components/Drupal/Webform/fragment.graphql +8 -5
  34. package/components/Drupal/Webform/index.vue +20 -9
  35. package/components/Drupal/Webform/query.graphql +18 -16
  36. package/components/Form/CheckboxInput.vue +6 -6
  37. package/components/Form/CheckboxInputs.vue +5 -5
  38. package/components/Form/FileUploadInput.vue +6 -6
  39. package/components/Form/RadioButtonsInput.vue +5 -5
  40. package/components/Form/SelectInput.vue +7 -7
  41. package/components/Form/SubmitButton.vue +1 -1
  42. package/components/Form/TextAreaInput.vue +2 -2
  43. package/components/Form/TextEmailInput.vue +2 -2
  44. package/components/Form/TextInput.vue +2 -2
  45. package/components/Form/TextPhoneInput.vue +2 -2
  46. package/components/Form/composables/useFormElement.ts +5 -5
  47. package/components/Form/utils/types.ts +8 -7
  48. package/components/Media/Icon/index.vue +10 -6
  49. package/components/Media/Image/index.vue +26 -20
  50. package/components/Media/RemoteVideo/index.vue +34 -21
  51. package/components/Media/Video/index.vue +6 -5
  52. package/components/Node/Icms/Page/Teaser/index.vue +6 -4
  53. package/components/Node/Icms/Page/index.vue +2 -2
  54. package/components/Paragraph/Button/Element/index.vue +9 -2
  55. package/components/Paragraph/CallToAction/index.vue +43 -10
  56. package/components/Paragraph/Card/Element/index.vue +2 -1
  57. package/components/Paragraph/Card/Layout/index.vue +29 -10
  58. package/components/Paragraph/Contact/index.vue +41 -12
  59. package/components/Paragraph/Downloads/index.vue +82 -33
  60. package/components/Paragraph/FAQ/Element/index.vue +41 -12
  61. package/components/Paragraph/FAQ/Layout/index.vue +47 -13
  62. package/components/Paragraph/FlipTeasers/index.vue +26 -6
  63. package/components/Paragraph/Gallery/index.vue +42 -10
  64. package/components/Paragraph/HeroImage/index.vue +62 -16
  65. package/components/Paragraph/IconText/Element/index.vue +7 -1
  66. package/components/Paragraph/IconText/Layout/index.vue +39 -12
  67. package/components/Paragraph/Introduction/index.vue +50 -15
  68. package/components/Paragraph/Logo/Element/fragment.graphql +1 -0
  69. package/components/Paragraph/Logo/Element/index.vue +7 -2
  70. package/components/Paragraph/Media/index.vue +32 -31
  71. package/components/Paragraph/Partnerships/Element/fragment.graphql +1 -0
  72. package/components/Paragraph/Partnerships/Element/index.vue +7 -0
  73. package/components/Paragraph/Partnerships/Layout/index.vue +100 -27
  74. package/components/Paragraph/SingleTestimonial/index.vue +58 -15
  75. package/components/Paragraph/Table/index.vue +32 -9
  76. package/components/Paragraph/Tabs/Element/index.vue +44 -10
  77. package/components/Paragraph/Tabs/Layout/index.vue +123 -37
  78. package/components/Paragraph/Team/Element/index.vue +18 -1
  79. package/components/Paragraph/Team/Layout/index.vue +30 -7
  80. package/components/Paragraph/Teasers/index.vue +33 -7
  81. package/components/Paragraph/Testimonial/Element/index.vue +30 -5
  82. package/components/Paragraph/Testimonial/Layout/index.vue +78 -24
  83. package/components/Paragraph/Text/index.vue +32 -10
  84. package/components/Paragraph/TextMedia/index.vue +44 -13
  85. package/components/Paragraph/Timeline/Element/index.vue +23 -7
  86. package/components/Paragraph/Timeline/Layout/index.vue +232 -67
  87. package/components/Paragraph/TwoColumnText/Element/index.vue +20 -3
  88. package/components/Paragraph/TwoColumnText/Layout/index.vue +8 -1
  89. package/components/Paragraph/iFrame/index.vue +31 -11
  90. package/components/Search/Facets/FacetDropdownUI.vue +351 -77
  91. package/components/Search/Facets/FacetedSearchUI.vue +257 -101
  92. package/components/Search/Facets/fragment.graphql +5 -1
  93. package/components/Search/Input/index.vue +125 -0
  94. package/components/Section/Footer/index.vue +170 -30
  95. package/components/Section/Header/Buttons.vue +34 -0
  96. package/components/Section/Header/DesktopMainMenu.vue +160 -0
  97. package/components/Section/Header/DesktopMainMenuDropdown.vue +170 -0
  98. package/components/Section/Header/LanguageDropdown.vue +95 -64
  99. package/components/Section/Header/LanguageLinks.vue +39 -0
  100. package/components/Section/Header/Logo.vue +23 -0
  101. package/components/Section/Header/MainButtons.vue +31 -0
  102. package/components/Section/Header/MenuIcon.vue +60 -49
  103. package/components/Section/Header/MetaButtons.vue +31 -0
  104. package/components/Section/Header/MetaMenu.vue +55 -53
  105. package/components/Section/Header/MobileMainMenu.vue +23 -0
  106. package/components/Section/Header/MobileMainMenuItem.vue +191 -0
  107. package/components/Section/Header/index.vue +182 -186
  108. package/composables/useMenu.ts +2 -2
  109. package/composables/useMobileMenuOverlayBus.ts +44 -0
  110. package/composables/useNavigationOffset.ts +2 -2
  111. package/composables/useTheme.ts +107 -0
  112. package/formkit.theme.ts +541 -586
  113. package/layouts/default.vue +7 -35
  114. package/layouts/error.vue +7 -32
  115. package/nuxt.config.ts +13 -0
  116. package/package.json +1 -1
  117. package/plugins/initData.ts +8 -5
  118. package/queries/query.initData.graphql +4 -2
  119. package/tailwind.config.ts +11 -11
  120. package/types/global.ts +1 -0
  121. package/components/Section/Header/GlobalMenu.vue +0 -335
  122. package/components/Section/Header/LanguageSwitcher.vue +0 -37
@@ -1,12 +1,13 @@
1
1
  <template>
2
- <div class="container mb-[30px] h-6 pt-20">
3
- <section v-if="links.length" class="relative mobile-only:overflow-hidden">
4
- <nav class="breadcrumb" aria-label="breadcrumbs">
2
+ <div :class="themedClass('containerClass', 'container mb-[30px] h-6 pt-20')">
3
+ <section v-if="links.length" class="relative mobile-only:overflow-hidden" :class="themedClass('sectionClass')">
4
+ <nav class="breadcrumb" aria-label="breadcrumbs" :class="themedClass('navClass')">
5
5
  <ol
6
6
  ref="list"
7
7
  itemscope
8
8
  itemtype="http://schema.org/BreadcrumbList"
9
9
  class="flex items-center whitespace-nowrap"
10
+ :class="themedClass('listClass')"
10
11
  >
11
12
  <li
12
13
  v-for="(link, index) in linksComputed"
@@ -14,9 +15,10 @@
14
15
  itemprop="itemListElement"
15
16
  itemscope
16
17
  itemtype="http://schema.org/ListItem"
18
+ :class="themedClass('listItemClass')"
17
19
  >
18
- <component :is="link.tag" v-bind="link.props" itemprop="item">
19
- <span itemprop="name">
20
+ <component :is="link.tag" v-bind="link.props" itemprop="item" :class="themedClass('linkClass')">
21
+ <span itemprop="name" :class="themedClass('linkLabelClass')">
20
22
  {{ link.title }}
21
23
  </span>
22
24
  </component>
@@ -32,10 +34,19 @@
32
34
  import type { BreadcrumbFragment } from '#graphql-operations'
33
35
  import type { Langcode } from '#nuxt-language-negotiation/config'
34
36
  import { NuxtLink } from '#components'
37
+ import { useTheme } from '@iqual/nuxt-icms/composables/useTheme'
38
+ const themedClass = useTheme()
35
39
 
36
40
  const props = defineProps<{
37
41
  links: BreadcrumbFragment[]
38
42
  language?: Langcode
43
+ containerClass?: string
44
+ sectionClass?: string
45
+ navClass?: string
46
+ listClass?: string
47
+ listItemClass?: string
48
+ linkClass?: string
49
+ linkLabelClass?: string
39
50
  }>()
40
51
 
41
52
  const list = ref<HTMLOListElement | null>(null)
@@ -1,23 +1,34 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="messages.length"
4
- class="fixed bottom-0 left-0 z-[9999999] w-full text-white"
4
+ class="fixed bottom-0 left-0 z-[9999999] w-full"
5
+ :class="themedClass('wrapperClass', 'text-white')"
5
6
  >
6
7
  <div
7
8
  v-for="(message, i) in messages"
8
9
  :key="i"
9
- class="flex items-center justify-between rounded p-6 font-medium"
10
- :class="classes[message.type]"
10
+ class="flex items-center justify-between "
11
+ :class="cn(themedClass('innerClass', 'rounded p-6 font-medium'), classes[message.type])"
11
12
  @click="removeMessage(i)"
12
13
  >
13
- <div v-html="message.message" />
14
- <SpriteSymbol name="close" class="size-6" />
14
+ <div v-html="message.message" :class="themedClass('messageClass')"/>
15
+ <SpriteSymbol name="close" :class="themedClass('iconClass', 'size-6')" />
15
16
  </div>
16
17
  </div>
17
18
  </template>
18
19
 
19
20
  <script lang="ts" setup>
20
21
  import type { DrupalMessageType } from '@iqual/nuxt-icms/composables/useDrupalMessages'
22
+ import cn from '@iqual/nuxt-icms/composables/useCn'
23
+ import { useTheme } from '@iqual/nuxt-icms/composables/useTheme'
24
+ const themedClass = useTheme()
25
+
26
+ const props = defineProps<{
27
+ wrapperClass?: string
28
+ innerClass?: string
29
+ messageClass?: string
30
+ iconClass?: string
31
+ }>()
21
32
 
22
33
  const { messages, removeMessage } = useDrupalMessages()
23
34
 
@@ -1,12 +1,11 @@
1
- fragment webformElementMetadata on WebformElement {
1
+ fragment metadata on WebformElementMetadata {
2
2
  key
3
3
  type
4
4
  title
5
5
  description
6
6
  multiple
7
- required {
8
- message
9
- }
7
+ required
8
+ requiredError
10
9
  }
11
10
 
12
11
  fragment webformElementActions on WebformElementWebformActions {
@@ -72,7 +71,11 @@ fragment webformElementCheckboxes on WebformElementCheckboxes {
72
71
  fragment webformElementWebformFlexbox on WebformElementWebformFlexbox {
73
72
  elements {
74
73
  __typename
75
- ...webformElementMetadata
74
+ ... on WebformElement {
75
+ metadata {
76
+ ...metadata
77
+ }
78
+ }
76
79
  ...webformElementActions
77
80
  ...webformElementTextBase
78
81
  ...webformElementMarkupBase
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <div>
2
+ <div :class="themedClass('wrapperClass')">
3
3
  <Transition name="fade">
4
- <div v-if="!submitted && !showThankYou && !showError">
4
+ <div v-if="!submitted && !showThankYou && !showError" :class="themedClass('formWrapperClass')">
5
5
  <FormKit
6
6
  type="form"
7
7
  :actions="false"
8
- :messages-class="'mt-2'"
8
+ :messages-class="themedClass('messagesClass', 'mt-2')"
9
9
  :incomplete-message="$texts(
10
10
  'webform.submission_validation_incomplete',
11
11
  'Please fill in all required fields.',
@@ -15,17 +15,20 @@
15
15
  >
16
16
  <div
17
17
  v-for="formElement in formDefinition?.elements"
18
- :key="formElement.key"
18
+ :key="formElement?.metadata?.key"
19
+ :class="themedClass('elementWrapperClass')"
19
20
  >
20
21
 
21
22
  <NuxtTurnstile
22
23
  v-model="token"
23
- v-if="formElement.key === 'actions'"
24
+ v-if="formElement?.metadata?.key === 'actions'"
24
25
  />
25
26
 
26
27
  <component
27
- :is="getComponent(formElement.type)"
28
+ v-if="formElement?.metadata?.type"
29
+ :is="getComponent(formElement?.metadata?.type)"
28
30
  :formElement="formElement"
31
+ :class="themedClass('elementClass')"
29
32
  />
30
33
  </div>
31
34
  </FormKit>
@@ -35,7 +38,7 @@
35
38
  <Transition name="fade">
36
39
  <div
37
40
  v-if="showThankYou"
38
- class="mb-4 rounded-lg border border-success-500 px-6 py-4 text-success-500"
41
+ :class="themedClass('successMessageClass', 'mb-4 rounded-lg border border-success-500 px-6 py-4 text-success-500')"
39
42
  >
40
43
  <p>
41
44
  {{
@@ -51,7 +54,7 @@
51
54
  <Transition name="fade">
52
55
  <div
53
56
  v-if="showError"
54
- class="mb-4 rounded-lg border border-error-500 px-6 py-4 text-error-500"
57
+ :class="themedClass('errorMessageClass', 'mb-4 rounded-lg border border-error-500 px-6 py-4 text-error-500')"
55
58
  >
56
59
  <p>
57
60
  {{
@@ -78,6 +81,7 @@ import TextEmailInput from '@iqual/nuxt-icms/components/Form/TextEmailInput.vue'
78
81
  import TextPhoneInput from '@iqual/nuxt-icms/components/Form/TextPhoneInput.vue'
79
82
  import WebformMarkup from '@iqual/nuxt-icms/components/Form/WebformMarkup.vue'
80
83
  import SubmitButton from '@iqual/nuxt-icms/components/Form/SubmitButton.vue'
84
+ import { useTheme } from '@iqual/nuxt-icms/composables/useTheme'
81
85
 
82
86
  interface FormData {
83
87
  [fieldName: string]:
@@ -90,8 +94,15 @@ interface FormData {
90
94
  | undefined
91
95
  }
92
96
 
97
+ const themedClass = useTheme()
98
+
93
99
  const props = defineProps<{
94
100
  formId: string
101
+ wrapperClass: string
102
+ formWrapperClass: string
103
+ messagesClass: string
104
+ elementWrapperClass: string
105
+ elementClass: string
95
106
  }>()
96
107
 
97
108
  const { $texts } = useNuxtApp()
@@ -103,7 +114,7 @@ const showError = ref(false)
103
114
  const queryKey = `drupalWebform-${props?.formId || '0'}`;
104
115
  const { data: formDefinition } = await useAsyncData(queryKey, async () => {
105
116
  return await useGraphqlQuery('webformById', { id: props?.formId }).then(
106
- (v) => v?.data?.entityById || { elements: [] }
117
+ (v) => v?.data?.webformById || { elements: [] }
107
118
  )
108
119
  })
109
120
 
@@ -1,21 +1,23 @@
1
1
  query webformById($id: ID!) {
2
- entityById(id: $id, entityType: WEBFORM) {
3
- ... on Webform {
4
- label
5
- id
6
- elements {
7
- ...webformElementMetadata
8
- ...webformElementActions
9
- ...webformElementTextBase
10
- ...webformElementMarkupBase
11
- ...webformElementTextarea
12
- ...webformElementSelect
13
- ...webformElementManagedFile
14
- ...webformElementTermSelect
15
- ...webformElementWebformFlexbox
16
- ...webformElementRadions
17
- ...webformElementCheckboxes
2
+ webformById(id: "contact") {
3
+ label
4
+ id
5
+ elements {
6
+ ... on WebformElement {
7
+ metadata {
8
+ ...metadata
9
+ }
18
10
  }
11
+ ...webformElementActions
12
+ ...webformElementTextBase
13
+ ...webformElementMarkupBase
14
+ ...webformElementTextarea
15
+ ...webformElementSelect
16
+ ...webformElementManagedFile
17
+ ...webformElementTermSelect
18
+ ...webformElementWebformFlexbox
19
+ ...webformElementRadions
20
+ ...webformElementCheckboxes
19
21
  }
20
22
  }
21
23
  }
@@ -12,8 +12,8 @@ const { cleanDescription, getValidationData } = useFormElement(
12
12
  <template>
13
13
  <FormKit
14
14
  type="checkbox"
15
- :name="formElement.key"
16
- :label="formElement.title"
15
+ :name="formElement?.metadata?.key"
16
+ :label="formElement?.metadata?.title"
17
17
  :help="cleanDescription"
18
18
  :validation="getValidationData.rules || ''"
19
19
  :validationMessages="getValidationData.messages || {}"
@@ -21,13 +21,13 @@ const { cleanDescription, getValidationData } = useFormElement(
21
21
  <template #wrapper="{ node, value }">
22
22
  <div class="flex items-center gap-2">
23
23
  <Checkbox
24
- :id="formElement.key"
24
+ :id="formElement?.metadata?.key"
25
25
  :checked="value"
26
26
  @update:checked="node.input($event)"
27
- class="border-1 shadow-custom-small focus-visible:ring-primary-500 data-[state=checked]:text-primary-500 dark:focus-visible:ring-primary-500 dark:data-[state=checked]:text-primary-500 size-5 border-gray-200 focus-visible:ring-offset-0 data-[state=checked]:bg-white dark:border-gray-200 dark:data-[state=checked]:bg-white"
27
+ class="border-1 focus-visible:ring-primary data-[state=checked]:text-primary dark:focus-visible:ring-primary dark:data-[state=checked]:text-primary size-5 border-gray-200 bg-white focus-visible:ring-offset-0 data-[state=checked]:bg-white dark:border-gray-200 dark:bg-white dark:data-[state=checked]:bg-white"
28
28
  />
29
- <Label :for="formElement.key" class="text-base font-normal">
30
- {{ `${formElement.title}${formElement.required ? '*' : ''}` }}
29
+ <Label :for="formElement?.metadata?.key" class="text-base font-normal">
30
+ {{ `${formElement?.metadata?.title}${formElement?.metadata?.required ? '*' : ''}` }}
31
31
  </Label>
32
32
  </div>
33
33
  </template>
@@ -11,14 +11,14 @@ const { cleanDescription, getValidationData, getFormattedOptions } =
11
11
  <template>
12
12
  <FormKit
13
13
  type="checkbox"
14
- :name="formElement.key"
14
+ :name="formElement?.metadata?.key"
15
15
  :help="cleanDescription"
16
16
  :validation="getValidationData.rules || ''"
17
17
  :validationMessages="getValidationData.messages || {}"
18
18
  >
19
19
  <template #wrapper>
20
20
  <Label class="mb-2 block text-base font-normal">
21
- {{ `${formElement.title}${formElement.required ? '*' : ''}` }}
21
+ {{ `${formElement?.metadata?.title}${formElement?.metadata?.required ? '*' : ''}` }}
22
22
  </Label>
23
23
  <div class="flex flex-col gap-2">
24
24
  <div
@@ -28,11 +28,11 @@ const { cleanDescription, getValidationData, getFormattedOptions } =
28
28
  >
29
29
  <Checkbox
30
30
  :value="option.value"
31
- :id="`${formElement.key}-${index}`"
32
- class="border-1 shadow-custom-small focus-visible:ring-primary-500 data-[state=checked]:text-primary-500 dark:focus-visible:ring-primary-500 dark:data-[state=checked]:text-primary-500 size-5 border-gray-200 focus-visible:ring-offset-0 data-[state=checked]:bg-white dark:border-gray-200 dark:data-[state=checked]:bg-white"
31
+ :id="`${formElement?.metadata?.key}-${index}`"
32
+ class="border-1 focus-visible:ring-primary data-[state=checked]:text-primary dark:focus-visible:ring-primary dark:data-[state=checked]:text-primary size-5 border-gray-200 bg-white focus-visible:ring-offset-0 data-[state=checked]:bg-white dark:border-gray-200 dark:bg-white dark:data-[state=checked]:bg-white"
33
33
  />
34
34
  <Label
35
- :for="`${formElement.key}-${index}`"
35
+ :for="`${formElement?.metadata?.key}-${index}`"
36
36
  class="text-base font-normal"
37
37
  >
38
38
  {{ option.label }}
@@ -11,22 +11,22 @@ const { cleanDescription, getValidationData, getFormattedFileExtensions } =
11
11
  <template>
12
12
  <FormKit
13
13
  type="file"
14
- :name="formElement?.key"
14
+ :name="formElement?.metadata?.key"
15
15
  :accept="getFormattedFileExtensions"
16
16
  :help="cleanDescription"
17
- :multiple="Boolean(formElement.multiple)"
17
+ :multiple="Boolean(formElement?.metadata?.multiple)"
18
18
  :validation="getValidationData.rules || ''"
19
19
  :validationMessages="getValidationData.messages || {}"
20
20
  >
21
21
  <template #wrapper>
22
22
  <div class="grid w-full items-center">
23
- <Label :for="formElement?.key" class="mb-2 block text-base font-normal">
24
- {{ `${formElement.title}${formElement.required ? '*' : ''}` }}
23
+ <Label :for="formElement?.metadata?.key" class="mb-2 block text-base font-normal">
24
+ {{ `${formElement?.metadata?.title}${formElement?.metadata?.required ? '*' : ''}` }}
25
25
  </Label>
26
26
  <Input
27
- :id="formElement?.key"
27
+ :id="formElement?.metadata?.key"
28
28
  type="file"
29
- class="shadow-custom-small file:bg-primary focus-visible:ring-primary-500 dark:focus-visible:ring-primary-500 h-auto cursor-pointer rounded-lg border-gray-200 bg-white px-6 py-4 text-base font-normal !ring-offset-0 transition-all file:mr-6 file:cursor-pointer file:rounded file:px-4 file:py-2 file:text-base file:font-bold file:text-white placeholder:text-gray-300 dark:border-gray-200 dark:bg-white dark:placeholder:text-gray-300"
29
+ class="file:bg-primary focus-visible:ring-primary dark:focus-visible:ring-primary h-auto cursor-pointer rounded-none border-gray-200 bg-white px-6 py-4 text-base font-normal !ring-offset-0 transition-all file:mr-6 file:cursor-pointer file:px-4 file:py-2 file:text-base file:font-bold file:text-white placeholder:text-gray-300 dark:border-gray-200 dark:bg-white dark:placeholder:text-gray-300"
30
30
  />
31
31
  </div>
32
32
  </template>
@@ -11,14 +11,14 @@ const { cleanDescription, getValidationData, getFormattedOptions } =
11
11
  <template>
12
12
  <FormKit
13
13
  type="radio"
14
- :name="formElement.key"
14
+ :name="formElement?.metadata?.key"
15
15
  :help="cleanDescription"
16
16
  :validation="getValidationData.rules || ''"
17
17
  :validationMessages="getValidationData.messages || {}"
18
18
  >
19
19
  <template #wrapper>
20
20
  <Label class="mb-2 block text-base font-normal">
21
- {{ `${formElement.title}${formElement.required ? '*' : ''}` }}
21
+ {{ `${formElement?.metadata?.title}${formElement?.metadata?.required ? '*' : ''}` }}
22
22
  </Label>
23
23
  <RadioGroup>
24
24
  <div
@@ -27,12 +27,12 @@ const { cleanDescription, getValidationData, getFormattedOptions } =
27
27
  class="flex items-center gap-2"
28
28
  >
29
29
  <RadioGroupItem
30
- :id="`${formElement.key}-${index}`"
30
+ :id="`${formElement?.metadata?.key}-${index}`"
31
31
  :value="option.value"
32
- class="border-1 shadow-custom-small focus-visible:ring-primary-500 data-[state=checked]:text-primary-500 dark:focus-visible:ring-primary-500 dark:data-[state=checked]:text-primary-500 size-5 border-gray-200 focus-visible:ring-offset-0 data-[state=checked]:bg-white dark:border-gray-200 dark:data-[state=checked]:bg-white"
32
+ class="border-1 focus-visible:ring-primary data-[state=checked]:text-primary dark:focus-visible:ring-primary dark:data-[state=checked]:text-primary size-5 border-gray-200 bg-white focus-visible:ring-offset-0 data-[state=checked]:bg-white dark:border-gray-200 dark:bg-white dark:data-[state=checked]:bg-white"
33
33
  />
34
34
  <Label
35
- :for="`${formElement.key}-${index}`"
35
+ :for="`${formElement?.metadata?.key}-${index}`"
36
36
  class="text-base font-normal"
37
37
  >
38
38
  {{ option.label }}
@@ -11,12 +11,12 @@ const { cleanDescription, getValidationData, getFormattedOptions } =
11
11
  <template>
12
12
  <FormKit
13
13
  type="select"
14
- :name="formElement.key"
15
- :label="formElement.title"
14
+ :name="formElement?.metadata?.key"
15
+ :label="formElement?.metadata?.title"
16
16
  :help="cleanDescription"
17
17
  :validation="getValidationData.rules"
18
18
  :validationMessages="getValidationData.messages"
19
- :multiple="Boolean(formElement.multiple)"
19
+ :multiple="Boolean(formElement?.metadata?.multiple)"
20
20
  >
21
21
  <template #wrapper="{ value, node }">
22
22
  <Select
@@ -24,19 +24,19 @@ const { cleanDescription, getValidationData, getFormattedOptions } =
24
24
  @update:model-value="node.input"
25
25
  >
26
26
  <SelectTrigger
27
- class="[&[data-state=open]>svg]:transition-200 border-1 shadow-custom-small focus:ring-primary-500 dark:focus:ring-primary-500 h-auto border-gray-200 bg-white px-6 py-4 focus:outline-none focus:ring-offset-0 dark:border-gray-200 dark:bg-white dark:focus:outline-none dark:focus:ring-offset-0 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg]:transition-all"
27
+ class="[&[data-state=open]>svg]:transition-200 border-1 focus:ring-primary dark:focus:ring-primary h-auto rounded-none border-gray-200 bg-white px-6 py-4 focus:outline-none focus:ring-offset-0 dark:border-gray-200 dark:bg-white dark:focus:outline-none dark:focus:ring-offset-0 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg]:transition-all"
28
28
  >
29
29
  <SelectValue
30
- :placeholder="`${formElement.title}${formElement.required ? '*' : ''}`"
30
+ :placeholder="`${formElement?.metadata?.title}${formElement?.metadata?.required ? '*' : ''}`"
31
31
  class="text-medium text-base text-black"
32
32
  >
33
33
  {{
34
- value || `${formElement.title}${formElement.required ? '*' : ''}`
34
+ value || `${formElement?.metadata?.title}${formElement?.metadata?.required ? '*' : ''}`
35
35
  }}
36
36
  </SelectValue>
37
37
  </SelectTrigger>
38
38
  <SelectContent
39
- class="border-1 !shadow-custom-small border-gray-200 bg-white dark:border-gray-200 dark:bg-white [&>div]:!px-0 [&>div]:!py-1"
39
+ class="border-1 rounded-none border-gray-200 bg-white dark:border-gray-200 dark:bg-white [&>div]:!px-0 [&>div]:!py-1"
40
40
  >
41
41
  <SelectItem
42
42
  v-for="(option, index) in getFormattedOptions"
@@ -7,6 +7,6 @@ defineProps<{ formElement: SubmitButton }>()
7
7
  <template>
8
8
  <FormKit
9
9
  type="submit"
10
- :label="formElement?.submitLabel || formElement?.title"
10
+ :label="formElement?.submitLabel || formElement?.metadata?.title"
11
11
  />
12
12
  </template>
@@ -15,8 +15,8 @@ const isFocused = ref<boolean>(false)
15
15
  <FormKit
16
16
  type="textarea"
17
17
  v-model="inputValue"
18
- :name="formElement?.key"
19
- :label="formElement?.title"
18
+ :name="formElement?.metadata?.key"
19
+ :label="formElement?.metadata?.title"
20
20
  :help="cleanDescription"
21
21
  :placeholder="isFocused && !inputValue ? formElement?.placeholder : ''"
22
22
  :validation="getValidationData.rules"
@@ -16,8 +16,8 @@ const isFocused = ref<boolean>(false)
16
16
  <FormKit
17
17
  type="email"
18
18
  v-model="inputValue"
19
- :name="formElement?.key"
20
- :label="formElement?.title"
19
+ :name="formElement?.metadata?.key"
20
+ :label="formElement?.metadata?.title"
21
21
  :help="cleanDescription"
22
22
  :placeholder="isFocused && !inputValue ? formElement?.placeholder : ''"
23
23
  :validation="getValidationData.rules"
@@ -16,8 +16,8 @@ const isFocused = ref<boolean>(false)
16
16
  <FormKit
17
17
  type="text"
18
18
  v-model="inputValue"
19
- :name="formElement?.key"
20
- :label="formElement?.title"
19
+ :name="formElement?.metadata?.key"
20
+ :label="formElement?.metadata?.title"
21
21
  :help="cleanDescription"
22
22
  :placeholder="isFocused && !inputValue ? formElement?.placeholder : ''"
23
23
  :validation="getValidationData.rules"
@@ -16,8 +16,8 @@ const isFocused = ref<boolean>(false)
16
16
  <FormKit
17
17
  type="tel"
18
18
  v-model="inputValue"
19
- :name="formElement?.key"
20
- :label="formElement?.title"
19
+ :name="formElement?.metadata?.key"
20
+ :label="formElement?.metadata?.title"
21
21
  :help="cleanDescription"
22
22
  :placeholder="isFocused && !inputValue ? formElement?.placeholder : ''"
23
23
  :validation="getValidationData.rules"
@@ -3,25 +3,25 @@ import type { FormElement, TextInput, SelectInput, InputOption, CheckboxInputs,
3
3
  export function useFormElement(formElement: FormElement) {
4
4
  const { $texts } = useNuxtApp()
5
5
  const cleanDescription = computed(() => {
6
- if (!formElement.description) return ''
6
+ if (!formElement?.metadata?.description) return ''
7
7
 
8
- return formElement.description.replace(/<[^>]*>/g, '')
8
+ return formElement?.metadata?.description.replace(/<[^>]*>/g, '')
9
9
  });
10
10
 
11
11
  const getValidationData = computed(() => {
12
12
  const rules: string[] = []
13
13
  const messages: Record<string, string> = {}
14
14
 
15
- if (formElement?.required) {
15
+ if (formElement?.metadata?.required) {
16
16
  rules.push('required')
17
- messages['required'] = formElement.required.message || $texts(
17
+ messages['required'] = formElement?.metadata?.requiredError || $texts(
18
18
  'webform.required_field_error',
19
19
  'This field is required.',
20
20
  )
21
21
  }
22
22
 
23
23
  const checkboxInput = formElement as CheckboxInput;
24
- if (checkboxInput?.type === 'checkbox' && checkboxInput?.required) {
24
+ if (checkboxInput?.metadata?.type === 'checkbox' && checkboxInput?.metadata?.required) {
25
25
  rules.push('accepted')
26
26
  }
27
27
 
@@ -1,13 +1,14 @@
1
1
  export type FormKitTypes = 'text' | 'number' | 'meta' | 'url' | 'button' | 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'form' | 'group' | 'hidden' | 'list' | 'month' | 'password'
2
2
 
3
3
  export interface FormElement {
4
- key: string
5
- type: string
6
- title: string
7
- description?: string
8
- multiple?: number
9
- required?: {
10
- message?: string
4
+ metadata: {
5
+ key: string
6
+ type: string
7
+ title: string
8
+ description?: string
9
+ multiple?: number
10
+ required?: boolean
11
+ requiredError?: string
11
12
  }
12
13
  }
13
14
 
@@ -1,15 +1,19 @@
1
1
  <template>
2
- <img
3
- :src="media?.url?.path"
4
- :alt="media?.alt?.alt"
5
- :title="media?.title"
6
- :class="mediaClass"
2
+ <img
3
+ :src="media?.url?.path"
4
+ :alt="media?.alt?.alt"
5
+ :title="media?.title"
6
+ :class="themedClass('mediaClass')"
7
7
  />
8
8
  </template>
9
9
 
10
10
  <script lang="ts" setup>
11
11
  import type { MediaIconFragment } from '#graphql-operations'
12
- const props = defineProps<{
12
+ import { useTheme } from '@iqual/nuxt-icms/composables/useTheme'
13
+
14
+ const themedClass = useTheme()
15
+
16
+ defineProps<{
13
17
  media: MediaIconFragment
14
18
  mediaClass?: string
15
19
  }>()
@@ -1,33 +1,43 @@
1
1
  <template>
2
- <picture :class="mediaClass">
3
- <img v-if="imageSources.length === 1"
4
- :class="elementClass"
5
- :srcset="imageSources[0].srcset"
6
- :sizes="imageSources[0].sizes"
7
- :alt="media?.alt?.alt"
2
+ <picture :class="themedClass('mediaClass')">
3
+ <img
4
+ v-if="imageSources.length === 1"
5
+ :srcset="imageSources[0].srcset"
6
+ :sizes="imageSources[0].sizes"
7
+ :alt="media?.alt?.alt"
8
8
  :title="media?.title"
9
9
  :src="placeHolderImage"
10
10
  :loading="imageLoading"
11
+ :class="themedClass('elementClass', 'w-full')"
11
12
  />
12
- <source v-if="imageSources.length > 1" v-for="(source, key) in imageSources" :key="key"
13
+ <source
14
+ v-if="imageSources.length > 1"
15
+ v-for="(source, key) in imageSources"
16
+ :key="key"
13
17
  :srcset="source.srcset"
14
- :media="source.media"
18
+ :media="source.media"
15
19
  />
16
- <img v-if="imageSources.length > 1"
17
- :src="placeHolderImage"
18
- :alt="media?.alt?.alt"
20
+ <img
21
+ v-if="imageSources.length > 1"
22
+ :src="placeHolderImage"
23
+ :alt="media?.alt?.alt"
19
24
  :title="media?.title"
20
- :class="elementClass"
21
25
  :loading="imageLoading"
26
+ :class="themedClass('elementClass', 'w-full')"
27
+ />
28
+ <figcaption
29
+ v-if="showCaption && media?.caption"
30
+ v-text="media?.caption"
31
+ :class="themedClass('figcaptionClass', 'mt-2 text-center italic')"
22
32
  />
23
- <figcaption v-if="showCaption && media?.caption"
24
- v-text="media?.caption"
25
- :class="figcaptionClass" />
26
33
  </picture>
27
34
  </template>
28
35
 
29
36
  <script lang="ts" setup>
30
37
  import type { MediaImageFragment } from '#graphql-operations'
38
+ import { useTheme } from '@iqual/nuxt-icms/composables/useTheme'
39
+
40
+ const themedClass = useTheme()
31
41
 
32
42
  const props = withDefaults(
33
43
  defineProps<{
@@ -35,15 +45,13 @@ const props = withDefaults(
35
45
  mediaClass?: string
36
46
  imageAspectRatios?: string
37
47
  imageSizes?: string
38
- imageLoading?: "lazy" | "eager" | undefined
48
+ imageLoading?: 'lazy' | 'eager' | undefined
39
49
  showCaption?: boolean
40
50
  figcaptionClass?: string
41
51
  elementClass?: string
42
52
  }>(),
43
53
  {
44
54
  imageLoading: 'lazy',
45
- figcaptionClass: 'mt-2 italic text-center',
46
- elementClass: 'size-full object-cover object-center',
47
55
  },
48
56
  )
49
57
 
@@ -52,6 +60,4 @@ const { placeHolderImage, imageSources } = useImageSources({
52
60
  imageAspectRatios: toRef(props, 'imageAspectRatios'),
53
61
  imageSizes: toRef(props, 'imageSizes'),
54
62
  })
55
-
56
63
  </script>
57
-