@iqual/nuxt-icms 1.1.0 → 1.2.2

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 (418) hide show
  1. package/assets/css/ckeditor.css +4 -0
  2. package/assets/css/components/container.css +2 -2
  3. package/assets/css/tailwind.css +1 -1
  4. package/assets/css/typography.css +4 -0
  5. package/assets/symbols/download.svg +3 -0
  6. package/bundles.ts +4 -1
  7. package/components/Blokkli/TextMedia/index.vue +1 -2
  8. package/components/DesignSystem/Atoms/Caption.vue +15 -0
  9. package/components/DesignSystem/Atoms/LinkListItem.vue +21 -0
  10. package/components/DesignSystem/Molecules/MediaLightbox.vue +273 -0
  11. package/components/DesignSystem/Molecules/MediaSlider.vue +33 -22
  12. package/components/DesignSystem/Organisms/Map.vue +61 -0
  13. package/components/DesignSystem/README.md +489 -0
  14. package/components/Media/Image/index.vue +4 -162
  15. package/components/Media/RemoteVideo/index.vue +3 -3
  16. package/components/Node/Icms/Page/SearchResult/fragment.graphql +8 -0
  17. package/components/Node/Icms/Page/SearchResult/index.vue +12 -0
  18. package/components/Node/Icms/Page/Teaser/fragment.graphql +17 -0
  19. package/components/Node/Icms/Page/Teaser/index.vue +20 -0
  20. package/components/Node/Icms/Page/fragment.graphql +18 -0
  21. package/components/Node/Icms/Page/index.vue +5 -3
  22. package/components/Paragraph/CallToAction/index.vue +12 -8
  23. package/components/Paragraph/Card/Layout/index.vue +2 -2
  24. package/components/Paragraph/Contact/index.vue +1 -2
  25. package/components/Paragraph/Downloads/index.vue +4 -16
  26. package/components/Paragraph/FAQ/Layout/index.vue +24 -3
  27. package/components/Paragraph/FlipTeasers/index.vue +2 -2
  28. package/components/Paragraph/Gallery/index.vue +35 -172
  29. package/components/Paragraph/HeroImage/index.vue +13 -4
  30. package/components/Paragraph/IconText/Layout/index.vue +1 -2
  31. package/components/Paragraph/Media/index.vue +7 -2
  32. package/components/Paragraph/Table/index.vue +2 -2
  33. package/components/Paragraph/Team/Layout/index.vue +2 -2
  34. package/components/Paragraph/Teasers/fragment.graphql +2 -15
  35. package/components/Paragraph/Teasers/index.vue +12 -15
  36. package/components/Paragraph/TextMedia/index.vue +40 -33
  37. package/components/Paragraph/Timeline/Element/index.vue +1 -1
  38. package/components/Paragraph/Timeline/Layout/fragment.graphql +1 -0
  39. package/components/Paragraph/Timeline/Layout/index.vue +9 -6
  40. package/components/Paragraph/iFrame/index.vue +16 -2
  41. package/components/Search/Facets/FacetDropdownUI.vue +222 -0
  42. package/components/Search/Facets/FacetedSearchUI.vue +397 -0
  43. package/components/Search/Facets/fragment.graphql +40 -0
  44. package/components/Section/Footer/index.vue +15 -14
  45. package/components/Section/Header/GlobalMenu.vue +34 -34
  46. package/components/Section/Header/LanguageDropdown.vue +60 -73
  47. package/components/Section/Header/LanguageSwitcher.vue +37 -0
  48. package/components/Section/Header/MetaMenu.vue +27 -20
  49. package/components/Section/Header/index.vue +91 -79
  50. package/components/ui/accordion/Accordion.vue +2 -2
  51. package/components/ui/accordion/AccordionContent.vue +5 -5
  52. package/components/ui/accordion/AccordionItem.vue +9 -10
  53. package/components/ui/accordion/AccordionTrigger.vue +5 -5
  54. package/components/ui/alert/Alert.vue +17 -0
  55. package/components/ui/alert/AlertDescription.vue +14 -0
  56. package/components/ui/alert/AlertTitle.vue +14 -0
  57. package/components/ui/alert/index.ts +24 -0
  58. package/components/ui/alert-dialog/AlertDialog.vue +15 -0
  59. package/components/ui/alert-dialog/AlertDialogAction.vue +22 -0
  60. package/components/ui/alert-dialog/AlertDialogCancel.vue +29 -0
  61. package/components/ui/alert-dialog/AlertDialogContent.vue +43 -0
  62. package/components/ui/alert-dialog/AlertDialogDescription.vue +27 -0
  63. package/components/ui/alert-dialog/AlertDialogFooter.vue +21 -0
  64. package/components/ui/alert-dialog/AlertDialogHeader.vue +16 -0
  65. package/components/ui/alert-dialog/AlertDialogTitle.vue +24 -0
  66. package/components/ui/alert-dialog/AlertDialogTrigger.vue +12 -0
  67. package/components/ui/alert-dialog/index.ts +9 -0
  68. package/components/ui/aspect-ratio/AspectRatio.vue +12 -0
  69. package/components/ui/aspect-ratio/index.ts +1 -0
  70. package/components/ui/auto-form/AutoForm.vue +106 -0
  71. package/components/ui/auto-form/AutoFormField.vue +45 -0
  72. package/components/ui/auto-form/AutoFormFieldArray.vue +110 -0
  73. package/components/ui/auto-form/AutoFormFieldBoolean.vue +41 -0
  74. package/components/ui/auto-form/AutoFormFieldDate.vue +57 -0
  75. package/components/ui/auto-form/AutoFormFieldEnum.vue +49 -0
  76. package/components/ui/auto-form/AutoFormFieldFile.vue +74 -0
  77. package/components/ui/auto-form/AutoFormFieldInput.vue +36 -0
  78. package/components/ui/auto-form/AutoFormFieldNumber.vue +32 -0
  79. package/components/ui/auto-form/AutoFormFieldObject.vue +78 -0
  80. package/components/ui/auto-form/AutoFormLabel.vue +14 -0
  81. package/components/ui/auto-form/constant.ts +40 -0
  82. package/components/ui/auto-form/dependencies.ts +93 -0
  83. package/components/ui/auto-form/index.ts +15 -0
  84. package/components/ui/auto-form/interface.ts +95 -0
  85. package/components/ui/auto-form/utils.ts +188 -0
  86. package/components/ui/avatar/Avatar.vue +22 -0
  87. package/components/ui/avatar/AvatarFallback.vue +12 -0
  88. package/components/ui/avatar/AvatarImage.vue +10 -0
  89. package/components/ui/avatar/index.ts +25 -0
  90. package/components/ui/badge/Badge.vue +17 -0
  91. package/components/ui/badge/index.ts +26 -0
  92. package/components/ui/breadcrumb/Breadcrumb.vue +13 -0
  93. package/components/ui/breadcrumb/BreadcrumbEllipsis.vue +22 -0
  94. package/components/ui/breadcrumb/BreadcrumbItem.vue +16 -0
  95. package/components/ui/breadcrumb/BreadcrumbLink.vue +20 -0
  96. package/components/ui/breadcrumb/BreadcrumbList.vue +16 -0
  97. package/components/ui/breadcrumb/BreadcrumbPage.vue +19 -0
  98. package/components/ui/breadcrumb/BreadcrumbSeparator.vue +21 -0
  99. package/components/ui/breadcrumb/index.ts +7 -0
  100. package/components/ui/button/Button.vue +4 -2
  101. package/components/ui/button/index.ts +9 -9
  102. package/components/ui/calendar/Calendar.vue +62 -0
  103. package/components/ui/calendar/CalendarCell.vue +26 -0
  104. package/components/ui/calendar/CalendarCellTrigger.vue +40 -0
  105. package/components/ui/calendar/CalendarGrid.vue +26 -0
  106. package/components/ui/calendar/CalendarGridBody.vue +12 -0
  107. package/components/ui/calendar/CalendarGridHead.vue +12 -0
  108. package/components/ui/calendar/CalendarGridRow.vue +23 -0
  109. package/components/ui/calendar/CalendarHeadCell.vue +23 -0
  110. package/components/ui/calendar/CalendarHeader.vue +23 -0
  111. package/components/ui/calendar/CalendarHeading.vue +33 -0
  112. package/components/ui/calendar/CalendarNextButton.vue +34 -0
  113. package/components/ui/calendar/CalendarPrevButton.vue +34 -0
  114. package/components/ui/calendar/index.ts +12 -0
  115. package/components/ui/card/Card.vue +21 -0
  116. package/components/ui/card/CardContent.vue +14 -0
  117. package/components/ui/card/CardDescription.vue +14 -0
  118. package/components/ui/card/CardFooter.vue +14 -0
  119. package/components/ui/card/CardHeader.vue +14 -0
  120. package/components/ui/card/CardTitle.vue +18 -0
  121. package/components/ui/card/index.ts +6 -0
  122. package/components/ui/carousel/Carousel.vue +3 -23
  123. package/components/ui/carousel/CarouselContent.vue +1 -2
  124. package/components/ui/carousel/CarouselItem.vue +5 -7
  125. package/components/ui/carousel/CarouselNext.vue +7 -9
  126. package/components/ui/carousel/CarouselPrevious.vue +7 -9
  127. package/components/ui/carousel/index.ts +3 -1
  128. package/components/ui/carousel/interface.ts +3 -1
  129. package/components/ui/carousel/useCarousel.ts +13 -23
  130. package/components/ui/chart/ChartCrosshair.vue +45 -0
  131. package/components/ui/chart/ChartLegend.vue +50 -0
  132. package/components/ui/chart/ChartSingleTooltip.vue +64 -0
  133. package/components/ui/chart/ChartTooltip.vue +40 -0
  134. package/components/ui/chart/index.ts +18 -0
  135. package/components/ui/chart/interface.ts +64 -0
  136. package/components/ui/chart-area/AreaChart.vue +141 -0
  137. package/components/ui/chart-area/index.ts +66 -0
  138. package/components/ui/chart-bar/BarChart.vue +116 -0
  139. package/components/ui/chart-bar/index.ts +66 -0
  140. package/components/ui/chart-donut/DonutChart.vue +101 -0
  141. package/components/ui/chart-donut/index.ts +39 -0
  142. package/components/ui/chart-line/LineChart.vue +107 -0
  143. package/components/ui/chart-line/index.ts +66 -0
  144. package/components/ui/checkbox/Checkbox.vue +1 -1
  145. package/components/ui/collapsible/Collapsible.vue +15 -0
  146. package/components/ui/collapsible/CollapsibleContent.vue +12 -0
  147. package/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
  148. package/components/ui/collapsible/index.ts +3 -0
  149. package/components/ui/command/Command.vue +31 -0
  150. package/components/ui/command/CommandDialog.vue +21 -0
  151. package/components/ui/command/CommandEmpty.vue +21 -0
  152. package/components/ui/command/CommandGroup.vue +30 -0
  153. package/components/ui/command/CommandInput.vue +35 -0
  154. package/components/ui/command/CommandItem.vue +27 -0
  155. package/components/ui/command/CommandList.vue +28 -0
  156. package/components/ui/command/CommandSeparator.vue +24 -0
  157. package/components/ui/command/CommandShortcut.vue +14 -0
  158. package/components/ui/command/index.ts +9 -0
  159. package/components/ui/context-menu/ContextMenu.vue +15 -0
  160. package/components/ui/context-menu/ContextMenuCheckboxItem.vue +41 -0
  161. package/components/ui/context-menu/ContextMenuContent.vue +37 -0
  162. package/components/ui/context-menu/ContextMenuGroup.vue +12 -0
  163. package/components/ui/context-menu/ContextMenuItem.vue +35 -0
  164. package/components/ui/context-menu/ContextMenuLabel.vue +27 -0
  165. package/components/ui/context-menu/ContextMenuPortal.vue +12 -0
  166. package/components/ui/context-menu/ContextMenuRadioGroup.vue +19 -0
  167. package/components/ui/context-menu/ContextMenuRadioItem.vue +41 -0
  168. package/components/ui/context-menu/ContextMenuSeparator.vue +22 -0
  169. package/components/ui/context-menu/ContextMenuShortcut.vue +14 -0
  170. package/components/ui/context-menu/ContextMenuSub.vue +19 -0
  171. package/components/ui/context-menu/ContextMenuSubContent.vue +36 -0
  172. package/components/ui/context-menu/ContextMenuSubTrigger.vue +36 -0
  173. package/components/ui/context-menu/ContextMenuTrigger.vue +14 -0
  174. package/components/ui/context-menu/index.ts +14 -0
  175. package/components/ui/dialog/Dialog.vue +2 -6
  176. package/components/ui/dialog/DialogClose.vue +2 -1
  177. package/components/ui/dialog/DialogContent.vue +10 -12
  178. package/components/ui/dialog/DialogDescription.vue +6 -10
  179. package/components/ui/dialog/DialogScrollContent.vue +15 -21
  180. package/components/ui/dialog/DialogTitle.vue +9 -6
  181. package/components/ui/dialog/DialogTrigger.vue +2 -1
  182. package/components/ui/drawer/Drawer.vue +19 -0
  183. package/components/ui/drawer/DrawerContent.vue +28 -0
  184. package/components/ui/drawer/DrawerDescription.vue +21 -0
  185. package/components/ui/drawer/DrawerFooter.vue +14 -0
  186. package/components/ui/drawer/DrawerHeader.vue +14 -0
  187. package/components/ui/drawer/DrawerOverlay.vue +19 -0
  188. package/components/ui/drawer/DrawerTitle.vue +21 -0
  189. package/components/ui/drawer/index.ts +8 -0
  190. package/components/ui/dropdown-menu/DropdownMenu.vue +15 -0
  191. package/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +41 -0
  192. package/components/ui/dropdown-menu/DropdownMenuContent.vue +39 -0
  193. package/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
  194. package/components/ui/dropdown-menu/DropdownMenuItem.vue +30 -0
  195. package/components/ui/dropdown-menu/DropdownMenuLabel.vue +26 -0
  196. package/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +19 -0
  197. package/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +42 -0
  198. package/components/ui/dropdown-menu/DropdownMenuSeparator.vue +24 -0
  199. package/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
  200. package/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
  201. package/components/ui/dropdown-menu/DropdownMenuSubContent.vue +31 -0
  202. package/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +35 -0
  203. package/components/ui/dropdown-menu/DropdownMenuTrigger.vue +14 -0
  204. package/components/ui/dropdown-menu/index.ts +16 -0
  205. package/components/ui/form/FormControl.vue +16 -0
  206. package/components/ui/form/FormDescription.vue +20 -0
  207. package/components/ui/form/FormItem.vue +20 -0
  208. package/components/ui/form/FormLabel.vue +23 -0
  209. package/components/ui/form/FormMessage.vue +16 -0
  210. package/components/ui/form/index.ts +7 -0
  211. package/components/ui/form/injectionKeys.ts +4 -0
  212. package/components/ui/form/useFormField.ts +30 -0
  213. package/components/ui/hover-card/HoverCard.vue +15 -0
  214. package/components/ui/hover-card/HoverCardContent.vue +43 -0
  215. package/components/ui/hover-card/HoverCardTrigger.vue +12 -0
  216. package/components/ui/hover-card/index.ts +3 -0
  217. package/components/ui/input/Input.vue +1 -1
  218. package/components/ui/menubar/Menubar.vue +36 -0
  219. package/components/ui/menubar/MenubarCheckboxItem.vue +41 -0
  220. package/components/ui/menubar/MenubarContent.vue +45 -0
  221. package/components/ui/menubar/MenubarGroup.vue +12 -0
  222. package/components/ui/menubar/MenubarItem.vue +36 -0
  223. package/components/ui/menubar/MenubarLabel.vue +14 -0
  224. package/components/ui/menubar/MenubarMenu.vue +12 -0
  225. package/components/ui/menubar/MenubarRadioGroup.vue +20 -0
  226. package/components/ui/menubar/MenubarRadioItem.vue +41 -0
  227. package/components/ui/menubar/MenubarSeparator.vue +21 -0
  228. package/components/ui/menubar/MenubarShortcut.vue +14 -0
  229. package/components/ui/menubar/MenubarSub.vue +20 -0
  230. package/components/ui/menubar/MenubarSubContent.vue +40 -0
  231. package/components/ui/menubar/MenubarSubTrigger.vue +32 -0
  232. package/components/ui/menubar/MenubarTrigger.vue +31 -0
  233. package/components/ui/menubar/index.ts +15 -0
  234. package/components/ui/navigation-menu/NavigationMenu.vue +34 -0
  235. package/components/ui/navigation-menu/NavigationMenuContent.vue +35 -0
  236. package/components/ui/navigation-menu/NavigationMenuIndicator.vue +26 -0
  237. package/components/ui/navigation-menu/NavigationMenuItem.vue +12 -0
  238. package/components/ui/navigation-menu/NavigationMenuLink.vue +19 -0
  239. package/components/ui/navigation-menu/NavigationMenuList.vue +31 -0
  240. package/components/ui/navigation-menu/NavigationMenuTrigger.vue +36 -0
  241. package/components/ui/navigation-menu/NavigationMenuViewport.vue +35 -0
  242. package/components/ui/navigation-menu/index.ts +14 -0
  243. package/components/ui/number-field/NumberField.vue +24 -0
  244. package/components/ui/number-field/NumberFieldContent.vue +14 -0
  245. package/components/ui/number-field/NumberFieldDecrement.vue +26 -0
  246. package/components/ui/number-field/NumberFieldIncrement.vue +26 -0
  247. package/components/ui/number-field/NumberFieldInput.vue +16 -0
  248. package/components/ui/number-field/index.ts +5 -0
  249. package/components/ui/pagination/PaginationEllipsis.vue +24 -0
  250. package/components/ui/pagination/PaginationFirst.vue +31 -0
  251. package/components/ui/pagination/PaginationLast.vue +31 -0
  252. package/components/ui/pagination/PaginationNext.vue +31 -0
  253. package/components/ui/pagination/PaginationPrev.vue +31 -0
  254. package/components/ui/pagination/index.ts +10 -0
  255. package/components/ui/pin-input/PinInput.vue +25 -0
  256. package/components/ui/pin-input/PinInputGroup.vue +20 -0
  257. package/components/ui/pin-input/PinInputInput.vue +20 -0
  258. package/components/ui/pin-input/PinInputSeparator.vue +16 -0
  259. package/components/ui/pin-input/index.ts +4 -0
  260. package/components/ui/popover/Popover.vue +15 -0
  261. package/components/ui/popover/PopoverContent.vue +49 -0
  262. package/components/ui/popover/PopoverTrigger.vue +12 -0
  263. package/components/ui/popover/index.ts +3 -0
  264. package/components/ui/progress/Progress.vue +41 -0
  265. package/components/ui/progress/index.ts +1 -0
  266. package/components/ui/radio-group/RadioGroupItem.vue +1 -1
  267. package/components/ui/range-calendar/RangeCalendar.vue +62 -0
  268. package/components/ui/range-calendar/RangeCalendarCell.vue +26 -0
  269. package/components/ui/range-calendar/RangeCalendarCellTrigger.vue +42 -0
  270. package/components/ui/range-calendar/RangeCalendarGrid.vue +26 -0
  271. package/components/ui/range-calendar/RangeCalendarGridBody.vue +12 -0
  272. package/components/ui/range-calendar/RangeCalendarGridHead.vue +12 -0
  273. package/components/ui/range-calendar/RangeCalendarGridRow.vue +23 -0
  274. package/components/ui/range-calendar/RangeCalendarHeadCell.vue +23 -0
  275. package/components/ui/range-calendar/RangeCalendarHeader.vue +23 -0
  276. package/components/ui/range-calendar/RangeCalendarHeading.vue +33 -0
  277. package/components/ui/range-calendar/RangeCalendarNextButton.vue +34 -0
  278. package/components/ui/range-calendar/RangeCalendarPrevButton.vue +34 -0
  279. package/components/ui/range-calendar/index.ts +12 -0
  280. package/components/ui/resizable/ResizableHandle.vue +28 -0
  281. package/components/ui/resizable/ResizablePanelGroup.vue +23 -0
  282. package/components/ui/resizable/index.ts +3 -0
  283. package/components/ui/scroll-area/ScrollArea.vue +31 -0
  284. package/components/ui/scroll-area/ScrollBar.vue +32 -0
  285. package/components/ui/scroll-area/index.ts +2 -0
  286. package/components/ui/select/SelectContent.vue +1 -1
  287. package/components/ui/select/SelectItem.vue +1 -1
  288. package/components/ui/select/SelectSeparator.vue +1 -1
  289. package/components/ui/select/SelectTrigger.vue +1 -1
  290. package/components/ui/separator/Separator.vue +37 -0
  291. package/components/ui/separator/index.ts +1 -0
  292. package/components/ui/sheet/Sheet.vue +15 -0
  293. package/components/ui/sheet/SheetClose.vue +12 -0
  294. package/components/ui/sheet/SheetContent.vue +58 -0
  295. package/components/ui/sheet/SheetDescription.vue +24 -0
  296. package/components/ui/sheet/SheetFooter.vue +19 -0
  297. package/components/ui/sheet/SheetHeader.vue +16 -0
  298. package/components/ui/sheet/SheetTitle.vue +24 -0
  299. package/components/ui/sheet/SheetTrigger.vue +12 -0
  300. package/components/ui/sheet/index.ts +32 -0
  301. package/components/ui/sidebar/Sidebar.vue +85 -0
  302. package/components/ui/sidebar/SidebarContent.vue +17 -0
  303. package/components/ui/sidebar/SidebarFooter.vue +17 -0
  304. package/components/ui/sidebar/SidebarGroup.vue +17 -0
  305. package/components/ui/sidebar/SidebarGroupAction.vue +26 -0
  306. package/components/ui/sidebar/SidebarGroupContent.vue +17 -0
  307. package/components/ui/sidebar/SidebarGroupLabel.vue +24 -0
  308. package/components/ui/sidebar/SidebarHeader.vue +17 -0
  309. package/components/ui/sidebar/SidebarInput.vue +21 -0
  310. package/components/ui/sidebar/SidebarInset.vue +20 -0
  311. package/components/ui/sidebar/SidebarMenu.vue +17 -0
  312. package/components/ui/sidebar/SidebarMenuAction.vue +34 -0
  313. package/components/ui/sidebar/SidebarMenuBadge.vue +25 -0
  314. package/components/ui/sidebar/SidebarMenuButton.vue +51 -0
  315. package/components/ui/sidebar/SidebarMenuButtonChild.vue +35 -0
  316. package/components/ui/sidebar/SidebarMenuItem.vue +17 -0
  317. package/components/ui/sidebar/SidebarMenuSkeleton.vue +34 -0
  318. package/components/ui/sidebar/SidebarMenuSub.vue +21 -0
  319. package/components/ui/sidebar/SidebarMenuSubButton.vue +35 -0
  320. package/components/ui/sidebar/SidebarMenuSubItem.vue +8 -0
  321. package/components/ui/sidebar/SidebarProvider.vue +81 -0
  322. package/components/ui/sidebar/SidebarRail.vue +32 -0
  323. package/components/ui/sidebar/SidebarSeparator.vue +18 -0
  324. package/components/ui/sidebar/SidebarTrigger.vue +26 -0
  325. package/components/ui/sidebar/index.ts +60 -0
  326. package/components/ui/sidebar/utils.ts +19 -0
  327. package/components/ui/skeleton/Skeleton.vue +14 -0
  328. package/components/ui/skeleton/index.ts +1 -0
  329. package/components/ui/slider/Slider.vue +37 -0
  330. package/components/ui/slider/index.ts +1 -0
  331. package/components/ui/sonner/Sonner.vue +23 -0
  332. package/components/ui/sonner/index.ts +1 -0
  333. package/components/ui/stepper/Stepper.vue +32 -0
  334. package/components/ui/stepper/StepperDescription.vue +24 -0
  335. package/components/ui/stepper/StepperIndicator.vue +36 -0
  336. package/components/ui/stepper/StepperItem.vue +28 -0
  337. package/components/ui/stepper/StepperSeparator.vue +32 -0
  338. package/components/ui/stepper/StepperTitle.vue +24 -0
  339. package/components/ui/stepper/StepperTrigger.vue +27 -0
  340. package/components/ui/stepper/index.ts +7 -0
  341. package/components/ui/switch/Switch.vue +40 -0
  342. package/components/ui/switch/index.ts +1 -0
  343. package/components/ui/table/Table.vue +16 -0
  344. package/components/ui/table/TableBody.vue +14 -0
  345. package/components/ui/table/TableCaption.vue +14 -0
  346. package/components/ui/table/TableCell.vue +21 -0
  347. package/components/ui/table/TableEmpty.vue +38 -0
  348. package/components/ui/table/TableFooter.vue +14 -0
  349. package/components/ui/table/TableHead.vue +14 -0
  350. package/components/ui/table/TableHeader.vue +14 -0
  351. package/components/ui/table/TableRow.vue +14 -0
  352. package/components/ui/table/index.ts +9 -0
  353. package/components/ui/tabs/TabsContent.vue +6 -11
  354. package/components/ui/tabs/TabsList.vue +8 -8
  355. package/components/ui/tabs/TabsTrigger.vue +9 -11
  356. package/components/ui/tags-input/TagsInput.vue +24 -0
  357. package/components/ui/tags-input/TagsInputInput.vue +21 -0
  358. package/components/ui/tags-input/TagsInputItem.vue +24 -0
  359. package/components/ui/tags-input/TagsInputItemDelete.vue +26 -0
  360. package/components/ui/tags-input/TagsInputItemText.vue +21 -0
  361. package/components/ui/tags-input/index.ts +5 -0
  362. package/components/ui/textarea/Textarea.vue +1 -1
  363. package/components/ui/toast/Toast.vue +30 -0
  364. package/components/ui/toast/ToastAction.vue +21 -0
  365. package/components/ui/toast/ToastClose.vue +24 -0
  366. package/components/ui/toast/ToastDescription.vue +21 -0
  367. package/components/ui/toast/ToastProvider.vue +12 -0
  368. package/components/ui/toast/ToastTitle.vue +21 -0
  369. package/components/ui/toast/ToastViewport.vue +19 -0
  370. package/components/ui/toast/Toaster.vue +30 -0
  371. package/components/ui/toast/index.ts +39 -0
  372. package/components/ui/toast/use-toast.ts +165 -0
  373. package/components/ui/toggle/Toggle.vue +38 -0
  374. package/components/ui/toggle/index.ts +28 -0
  375. package/components/ui/toggle-group/ToggleGroup.vue +36 -0
  376. package/components/ui/toggle-group/ToggleGroupItem.vue +37 -0
  377. package/components/ui/toggle-group/index.ts +2 -0
  378. package/components/ui/tooltip/Tooltip.vue +15 -0
  379. package/components/ui/tooltip/TooltipContent.vue +33 -0
  380. package/components/ui/tooltip/TooltipProvider.vue +12 -0
  381. package/components/ui/tooltip/TooltipTrigger.vue +12 -0
  382. package/components/ui/tooltip/index.ts +4 -0
  383. package/components/ui/v-calendar/Calendar.vue +343 -0
  384. package/components/ui/v-calendar/index.ts +22 -0
  385. package/composables/useAccordionScroll.ts +1 -1
  386. package/composables/useContentSearch.ts +0 -0
  387. package/composables/useGlobalConfig.ts +57 -0
  388. package/composables/useGraphqlCacheability.ts +22 -0
  389. package/composables/useImageSources.ts +208 -0
  390. package/composables/useInitData.ts +20 -112
  391. package/composables/useMediaLightbox.ts +114 -0
  392. package/composables/useMenu.ts +66 -0
  393. package/composables/useMessageBus.ts +74 -0
  394. package/composables/useNavigationOffset.ts +1 -1
  395. package/layouts/default.vue +2 -2
  396. package/layouts/error.vue +8 -10
  397. package/modules/dynamicEntityComponentResolver.ts +162 -0
  398. package/modules/dynamicParagraphResolver.ts +1 -1
  399. package/nuxt.config.ts +11 -22
  400. package/package.json +2 -2
  401. package/pages/[...slug]/index.vue +2 -2
  402. package/pages/index.vue +2 -2
  403. package/pages/node/[nid]/index.vue +2 -2
  404. package/plugins/graphqlMiddleware.ts +27 -68
  405. package/plugins/initData.ts +105 -0
  406. package/queries/query.contentSearch.graphql +17 -0
  407. package/{composables → queries}/query.initData.graphql +2 -8
  408. package/queries/query.loadTranslations.graphql +5 -0
  409. package/tailwind.config.ts +1 -0
  410. package/types/initData.ts +1 -0
  411. package/components/Section/Header/SearchLink.vue +0 -26
  412. package/composables/languageLinks.ts +0 -31
  413. package/composables/useMainMenuLinks.ts +0 -69
  414. package/composables/useMetaMenuLinks.ts +0 -44
  415. package/modules/dynamicNodeResolver.ts +0 -95
  416. package/pages/search/index.vue +0 -69
  417. package/pages/static-page/example.vue +0 -40
  418. package/queries/fragment.routeQuery.graphql +0 -51
@@ -0,0 +1,343 @@
1
+ <script setup lang="ts">
2
+ import type { Calendar } from 'v-calendar'
3
+ import { buttonVariants } from '@/lib/registry/default/ui/button'
4
+ import { cn } from '@/lib/utils'
5
+ import { useVModel } from '@vueuse/core'
6
+ import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
7
+ import { DatePicker } from 'v-calendar'
8
+ import { computed, nextTick, onMounted, ref, useSlots } from 'vue'
9
+ import { isVCalendarSlot } from '.'
10
+
11
+ /* Extracted from v-calendar */
12
+ type DatePickerModel = DatePickerDate | DatePickerRangeObject
13
+ type DateSource = Date | string | number
14
+ type DatePickerDate = DateSource | Partial<SimpleDateParts> | null
15
+ interface DatePickerRangeObject {
16
+ start: Exclude<DatePickerDate, null>
17
+ end: Exclude<DatePickerDate, null>
18
+ }
19
+ interface SimpleDateParts {
20
+ year: number
21
+ month: number
22
+ day: number
23
+ hours: number
24
+ minutes: number
25
+ seconds: number
26
+ milliseconds: number
27
+ }
28
+
29
+ defineOptions({
30
+ inheritAttrs: false,
31
+ })
32
+ const props = withDefaults(defineProps<{
33
+ modelValue?: string | number | Date | DatePickerModel
34
+ modelModifiers?: object
35
+ columns?: number
36
+ type?: 'single' | 'range'
37
+ }>(), {
38
+ type: 'single',
39
+ columns: 1,
40
+ })
41
+ const emits = defineEmits<{
42
+ (e: 'update:modelValue', payload: typeof props.modelValue): void
43
+ }>()
44
+
45
+ const modelValue = useVModel(props, 'modelValue', emits, {
46
+ passive: true,
47
+ })
48
+
49
+ const datePicker = ref<InstanceType<typeof DatePicker>>()
50
+ // @ts-expect-error in this current version of v-calendar has the calendaRef instance, which is required to handle arrow nav.
51
+ const calendarRef = computed<InstanceType<typeof Calendar>>(() => datePicker.value.calendarRef)
52
+
53
+ function handleNav(direction: 'prev' | 'next') {
54
+ if (!calendarRef.value)
55
+ return
56
+
57
+ if (direction === 'prev')
58
+ calendarRef.value.movePrev()
59
+ else calendarRef.value.moveNext()
60
+ }
61
+
62
+ onMounted(async () => {
63
+ await nextTick()
64
+ if (modelValue.value instanceof Date && calendarRef.value)
65
+ calendarRef.value.focusDate(modelValue.value)
66
+ })
67
+
68
+ const $slots = useSlots()
69
+ const vCalendarSlots = computed(() => {
70
+ return Object.keys($slots)
71
+ .filter(name => isVCalendarSlot(name))
72
+ .reduce((obj: Record<string, any>, key: string) => {
73
+ obj[key] = $slots[key]
74
+ return obj
75
+ }, {})
76
+ })
77
+ </script>
78
+
79
+ <template>
80
+ <div class="relative">
81
+ <div v-if="$attrs.mode !== 'time'" class="absolute flex justify-between w-full px-4 top-3 z-[1]">
82
+ <button
83
+ :class="cn(
84
+ buttonVariants({ variant: 'outline' }),
85
+ 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
86
+ )"
87
+ @click="handleNav('prev')"
88
+ >
89
+ <ChevronLeft class="w-4 h-4" />
90
+ </button>
91
+ <button
92
+ :class="cn(
93
+ buttonVariants({ variant: 'outline' }),
94
+ 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
95
+ )"
96
+ @click="handleNav('next')"
97
+ >
98
+ <ChevronRight class="w-4 h-4" />
99
+ </button>
100
+ </div>
101
+
102
+ <DatePicker
103
+ ref="datePicker"
104
+ v-bind="$attrs"
105
+ v-model="modelValue"
106
+ :model-modifiers="modelModifiers"
107
+ class="calendar"
108
+ trim-weeks
109
+ :transition="'none'"
110
+ :columns="columns"
111
+ >
112
+ <template v-for="(_, slot) of vCalendarSlots" #[slot]="scope">
113
+ <slot :name="slot" v-bind="scope" />
114
+ </template>
115
+
116
+ <template #nav-prev-button>
117
+ <ChevronLeft />
118
+ </template>
119
+
120
+ <template #nav-next-button>
121
+ <ChevronRight />
122
+ </template>
123
+ </DatePicker>
124
+ </div>
125
+ </template>
126
+
127
+ <style lang="css">
128
+ .calendar {
129
+ @apply p-3 text-center;
130
+ }
131
+ .calendar .vc-pane-layout {
132
+ @apply grid gap-4 max-sm:!grid-cols-1;
133
+ }
134
+ .calendar .vc-title {
135
+ @apply text-sm font-medium relative z-20;
136
+ }
137
+ .vc-popover-content-wrapper .vc-popover-content {
138
+ @apply mt-3 rounded-md max-w-xs border bg-background;
139
+ }
140
+ .vc-popover-content-wrapper .vc-nav-header {
141
+ @apply flex justify-between items-center p-2;
142
+ }
143
+ .vc-popover-content-wrapper .vc-nav-items {
144
+ @apply grid grid-cols-4 gap-2 p-2;
145
+ }
146
+ .vc-popover-content-wrapper .vc-nav-items .vc-nav-item {
147
+ @apply rounded-md px-2 py-1;
148
+ }
149
+ .vc-popover-content-wrapper .vc-nav-items .vc-nav-item:hover {
150
+ @apply text-muted-foreground bg-muted;
151
+ }
152
+ .vc-popover-content-wrapper .vc-nav-items .vc-nav-item.is-active {
153
+ @apply bg-primary text-primary-foreground;
154
+ }
155
+ .calendar .vc-pane-header-wrapper {
156
+ @apply hidden;
157
+ }
158
+ .calendar .vc-weeks {
159
+ @apply mt-4;
160
+ }
161
+ .calendar .vc-weekdays {
162
+ @apply justify-items-center;
163
+ }
164
+ .calendar .vc-weekday {
165
+ @apply text-muted-foreground rounded-md font-normal text-[0.8rem];
166
+ }
167
+ .calendar .vc-weeks {
168
+ @apply w-full space-y-2 flex flex-col [&>_div]:grid [&>_div]:grid-cols-7;
169
+ }
170
+ .calendar .vc-day:has(.vc-highlights) {
171
+ @apply first:rounded-l-md last:rounded-r-md;
172
+ }
173
+ .calendar .vc-day.is-today:not(:has(.vc-day-layer)) .vc-day-content {
174
+ @apply bg-secondary text-primary rounded-md;
175
+ }
176
+ .calendar .vc-day:has(.vc-highlight-base-start) {
177
+ @apply rounded-l-md;
178
+ }
179
+ .calendar .vc-day:has(.vc-highlight-base-end) {
180
+ @apply rounded-r-md;
181
+ }
182
+ .calendar .vc-day:has(.vc-highlight-bg-outline):not(:has(.vc-highlight-base-start)):not(:has(.vc-highlight-base-end)) {
183
+ @apply rounded-md;
184
+ }
185
+ .calendar .vc-day-content {
186
+ @apply text-center text-sm p-0 relative focus-within:relative focus-within:z-20 inline-flex items-center justify-center ring-offset-background hover:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-accent hover:text-accent-foreground h-9 w-9 font-normal aria-selected:opacity-100 select-none;
187
+ }
188
+ .calendar .vc-day-content:not(.vc-highlight-content-light) {
189
+ @apply rounded-md;
190
+ }
191
+ .calendar .is-not-in-month:not(:has(.vc-highlight-content-solid)):not(:has(.vc-highlight-content-light)):not(:has(.vc-highlight-content-outline)),
192
+ .calendar .vc-disabled {
193
+ @apply text-muted-foreground opacity-50;
194
+ }
195
+ .calendar .vc-highlight-content-solid, .calendar .vc-highlight-content-outline {
196
+ @apply bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground;
197
+ }
198
+ .calendar .vc-highlight-content-light {
199
+ @apply bg-accent text-accent-foreground;
200
+ }
201
+ .calendar .vc-pane-container.in-transition {
202
+ @apply overflow-hidden;
203
+ }
204
+ .calendar .vc-pane-container {
205
+ @apply w-full relative;
206
+ }
207
+ :root {
208
+ --vc-slide-translate: 22px;
209
+ --vc-slide-duration: 0.15s;
210
+ --vc-slide-timing: ease;
211
+ }
212
+
213
+ .calendar .vc-fade-enter-active,
214
+ .calendar .vc-fade-leave-active,
215
+ .calendar .vc-slide-left-enter-active,
216
+ .calendar .vc-slide-left-leave-active,
217
+ .calendar .vc-slide-right-enter-active,
218
+ .calendar .vc-slide-right-leave-active,
219
+ .calendar .vc-slide-up-enter-active,
220
+ .calendar .vc-slide-up-leave-active,
221
+ .calendar .vc-slide-down-enter-active,
222
+ .calendar .vc-slide-down-leave-active,
223
+ .calendar .vc-slide-fade-enter-active,
224
+ .calendar .vc-slide-fade-leave-active {
225
+ transition:
226
+ opacity var(--vc-slide-duration) var(--vc-slide-timing),
227
+ -webkit-transform var(--vc-slide-duration) var(--vc-slide-timing);
228
+ transition:
229
+ transform var(--vc-slide-duration) var(--vc-slide-timing),
230
+ opacity var(--vc-slide-duration) var(--vc-slide-timing);
231
+ transition:
232
+ transform var(--vc-slide-duration) var(--vc-slide-timing),
233
+ opacity var(--vc-slide-duration) var(--vc-slide-timing),
234
+ -webkit-transform var(--vc-slide-duration) var(--vc-slide-timing);
235
+ -webkit-backface-visibility: hidden;
236
+ backface-visibility: hidden;
237
+ pointer-events: none;
238
+ }
239
+
240
+ .calendar .vc-none-leave-active,
241
+ .calendar .vc-fade-leave-active,
242
+ .calendar .vc-slide-left-leave-active,
243
+ .calendar .vc-slide-right-leave-active,
244
+ .calendar .vc-slide-up-leave-active,
245
+ .calendar .vc-slide-down-leave-active {
246
+ position: absolute !important;
247
+ width: 100%;
248
+ }
249
+
250
+ .calendar .vc-none-enter-from,
251
+ .calendar .vc-none-leave-to,
252
+ .calendar .vc-fade-enter-from,
253
+ .calendar .vc-fade-leave-to,
254
+ .calendar .vc-slide-left-enter-from,
255
+ .calendar .vc-slide-left-leave-to,
256
+ .calendar .vc-slide-right-enter-from,
257
+ .calendar .vc-slide-right-leave-to,
258
+ .calendar .vc-slide-up-enter-from,
259
+ .calendar .vc-slide-up-leave-to,
260
+ .calendar .vc-slide-down-enter-from,
261
+ .calendar .vc-slide-down-leave-to,
262
+ .calendar .vc-slide-fade-enter-from,
263
+ .calendar .vc-slide-fade-leave-to {
264
+ opacity: 0;
265
+ }
266
+
267
+ .calendar .vc-slide-left-enter-from,
268
+ .calendar .vc-slide-right-leave-to,
269
+ .calendar .vc-slide-fade-enter-from.direction-left,
270
+ .calendar .vc-slide-fade-leave-to.direction-left {
271
+ -webkit-transform: translateX(var(--vc-slide-translate));
272
+ transform: translateX(var(--vc-slide-translate));
273
+ }
274
+
275
+ .calendar .vc-slide-right-enter-from,
276
+ .calendar .vc-slide-left-leave-to,
277
+ .calendar .vc-slide-fade-enter-from.direction-right,
278
+ .calendar .vc-slide-fade-leave-to.direction-right {
279
+ -webkit-transform: translateX(calc(-1 * var(--vc-slide-translate)));
280
+ transform: translateX(calc(-1 * var(--vc-slide-translate)));
281
+ }
282
+
283
+ .calendar .vc-slide-up-enter-from,
284
+ .calendar .vc-slide-down-leave-to,
285
+ .calendar .vc-slide-fade-enter-from.direction-top,
286
+ .calendar .vc-slide-fade-leave-to.direction-top {
287
+ -webkit-transform: translateY(var(--vc-slide-translate));
288
+ transform: translateY(var(--vc-slide-translate));
289
+ }
290
+
291
+ .calendar .vc-slide-down-enter-from,
292
+ .calendar .vc-slide-up-leave-to,
293
+ .calendar .vc-slide-fade-enter-from.direction-bottom,
294
+ .calendar .vc-slide-fade-leave-to.direction-bottom {
295
+ -webkit-transform: translateY(calc(-1 * var(--vc-slide-translate)));
296
+ transform: translateY(calc(-1 * var(--vc-slide-translate)));
297
+ }
298
+ /**
299
+ * Timepicker styles
300
+ */
301
+ .vc-time-picker {
302
+ @apply flex flex-col items-center p-2;
303
+ }
304
+ .vc-time-picker.vc-invalid {
305
+ @apply pointer-events-none opacity-50;
306
+ }
307
+ .vc-time-picker.vc-attached {
308
+ @apply border-t border-solid border-secondary mt-2;
309
+ }
310
+ .vc-time-picker > * + * {
311
+ @apply mt-1;
312
+ }
313
+ .vc-time-header {
314
+ @apply flex items-center text-sm font-semibold uppercase mt-1 px-1 leading-6;
315
+ }
316
+ .vc-time-select-group {
317
+ @apply inline-flex items-center px-1 rounded-md bg-primary-foreground border border-solid border-secondary;
318
+ }
319
+ .vc-time-select-group .vc-base-icon {
320
+ @apply mr-1 text-primary stroke-primary;
321
+ }
322
+ .vc-time-select-group select {
323
+ @apply bg-primary-foreground p-1 appearance-none outline-none text-center;
324
+ }
325
+ .vc-time-weekday {
326
+ @apply text-muted-foreground tracking-wide;
327
+ }
328
+ .vc-time-month {
329
+ @apply text-primary ml-2;
330
+ }
331
+ .vc-time-day {
332
+ @apply text-primary ml-1;
333
+ }
334
+ .vc-time-year {
335
+ @apply text-muted-foreground ml-2;
336
+ }
337
+ .vc-time-colon {
338
+ @apply mb-0.5;
339
+ }
340
+ .vc-time-decimal {
341
+ @apply ml-0.5;
342
+ }
343
+ </style>
@@ -0,0 +1,22 @@
1
+ export { default as Calendar } from './Calendar.vue'
2
+ import type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts'
3
+
4
+ export function isVCalendarSlot(slotName: string): slotName is CalendarSlotName {
5
+ const validSlots: CalendarSlotName[] = [
6
+ 'day-content',
7
+ 'day-popover',
8
+ 'dp-footer',
9
+ 'footer',
10
+ 'header-title-wrapper',
11
+ 'header-title',
12
+ 'header-prev-button',
13
+ 'header-next-button',
14
+ 'nav',
15
+ 'nav-prev-button',
16
+ 'nav-next-button',
17
+ 'page',
18
+ 'time-header',
19
+ ]
20
+
21
+ return validSlots.includes(slotName as CalendarSlotName)
22
+ }
@@ -1,4 +1,4 @@
1
- import { useNavigationOffset } from '@/composables/useNavigationOffset'
1
+ import { useNavigationOffset } from './useNavigationOffset'
2
2
 
3
3
  export function useAccordionScroll(el: ComponentPublicInstance | undefined): { handleAccordionOpen: () => void } {
4
4
  if (!el) return { handleAccordionOpen: () => { } }
File without changes
@@ -0,0 +1,57 @@
1
+
2
+ export async function useGlobalConfig() {
3
+ const initData = useInitData()
4
+
5
+ const companyLogo = computed(() => {
6
+ return initData.globalConfig.value.companyLogo
7
+ })
8
+
9
+ const companyLogoAlt = computed(() => {
10
+ return initData.globalConfig.value.companyLogoAlt
11
+ })
12
+
13
+ const companyName = computed(() => {
14
+ return initData.globalConfig.value.companyName
15
+ })
16
+
17
+ const companyDescription = computed(() => {
18
+ return initData.globalConfig.value.companyDescription
19
+ })
20
+
21
+ const address = computed(() => {
22
+ return initData.globalConfig.value.address
23
+ })
24
+
25
+ const phoneNumber = computed(() => {
26
+ return initData.globalConfig.value.phoneNumber
27
+ })
28
+
29
+ const emailAddress = computed(() => {
30
+ return initData.globalConfig.value.emailAddress
31
+ })
32
+
33
+ const contactButtons = computed(() => {
34
+ return initData.globalConfig.value.contactButtons
35
+ })
36
+
37
+ const metaLinks = computed(() => {
38
+ return initData.globalConfig.value.metaLinks
39
+ })
40
+
41
+ const socialMediaLinks = computed(() => {
42
+ return initData.globalConfig.value.socialMediaLinks
43
+ })
44
+
45
+ return {
46
+ companyLogo,
47
+ companyLogoAlt,
48
+ companyName,
49
+ companyDescription,
50
+ address,
51
+ phoneNumber,
52
+ emailAddress,
53
+ contactButtons,
54
+ metaLinks,
55
+ socialMediaLinks,
56
+ }
57
+ }
@@ -0,0 +1,22 @@
1
+ import type { GraphqlResponseTyped } from '#nuxt-graphql-middleware/response'
2
+ import type { H3Event } from 'h3'
3
+
4
+ export function useGraphqlCacheability(
5
+ event: H3Event,
6
+ response?: GraphqlResponseTyped,
7
+ ) {
8
+ if (import.meta.server) {
9
+ useCDNHeaders((cdn) => {
10
+ const cacheability = response?.extensions.cacheability
11
+ if (!cacheability?.isCacheable) {
12
+ cdn.private()
13
+ return
14
+ }
15
+
16
+ cdn
17
+ .public()
18
+ .setNumeric('maxAge', cacheability.maxAge)
19
+ .addTags(cacheability.tagsCdn)
20
+ }, event)
21
+ }
22
+ }
@@ -0,0 +1,208 @@
1
+ import type { ImageSizesVariant } from '@nuxt/image'
2
+ import type { MediaImageFragment } from '#graphql-operations'
3
+
4
+ interface ImageSource {
5
+ sizes?: string
6
+ srcset: string
7
+ media?: string
8
+ }
9
+
10
+ interface UseImageSourcesOptions {
11
+ media: Ref<MediaImageFragment> | MediaImageFragment
12
+ imageAspectRatios?: Ref<string | undefined> | string | undefined
13
+ imageSizes?: Ref<string | undefined> | string | undefined
14
+ }
15
+
16
+ // Local implementation of parseSizes from @nuxt/image
17
+ function parseSizes(input: Record<string, string | number> | string): Record<string, string> {
18
+ const sizes: Record<string, string> = {}
19
+ if (typeof input === "string") {
20
+ for (const entry of input.split(/[\s,]+/).filter((e) => e)) {
21
+ const s = entry.split(":")
22
+ if (s.length !== 2) {
23
+ sizes["1px"] = s[0].trim()
24
+ } else {
25
+ sizes[s[0].trim()] = s[1].trim()
26
+ }
27
+ }
28
+ } else {
29
+ Object.assign(sizes, input)
30
+ }
31
+ return sizes
32
+ }
33
+
34
+ // Helper function, copied from NuxtImage.
35
+ function getSizesVariant(key: string, size: string, hwRatio: number, img: any): ImageSizesVariant | undefined {
36
+ const screenMaxWidth = (img.options.screens && img.options.screens[key]) || Number.parseInt(key)
37
+ const isFluid = size.endsWith('vw')
38
+ if (!isFluid && /^\d+$/.test(size)) {
39
+ size = size + 'px'
40
+ }
41
+ if (!isFluid && !size.endsWith('px')) {
42
+ return undefined
43
+ }
44
+ let _cWidth = Number.parseInt(size)
45
+ if (!screenMaxWidth || !_cWidth) {
46
+ return undefined
47
+ }
48
+ if (isFluid) {
49
+ _cWidth = Math.round((_cWidth / 100) * screenMaxWidth)
50
+ }
51
+ const _cHeight = Math.round(_cWidth * hwRatio)
52
+ return {
53
+ size,
54
+ screenMaxWidth,
55
+ _cWidth,
56
+ _cHeight,
57
+ }
58
+ }
59
+
60
+ // Helper function, copied from NuxtImage.
61
+ function finaliseSizeVariants(sizeVariants: any[]) {
62
+ sizeVariants.sort((v1, v2) => v1.screenMaxWidth - v2.screenMaxWidth)
63
+
64
+ // de-duplicate size variants (by key `media`)
65
+ let previousMedia = null
66
+ for (let i = sizeVariants.length - 1; i >= 0; i--) {
67
+ const sizeVariant = sizeVariants[i]
68
+ if (sizeVariant.media === previousMedia) {
69
+ sizeVariants.splice(i, 1)
70
+ }
71
+ previousMedia = sizeVariant.media
72
+ }
73
+
74
+ for (let i = 0; i < sizeVariants.length; i++) {
75
+ sizeVariants[i].media = sizeVariants[i + 1]?.media || ''
76
+ }
77
+ }
78
+
79
+ // Helper function, copied from NuxtImage.
80
+ function finaliseSrcsetVariants(srcsetVariants: any[]) {
81
+ // sort by width
82
+ srcsetVariants.sort((v1, v2) => v1.width - v2.width)
83
+
84
+ // de-duplicate srcset variants (by key `width`)
85
+ let previousWidth = null
86
+ for (let i = srcsetVariants.length - 1; i >= 0; i--) {
87
+ const sizeVariant = srcsetVariants[i]
88
+ if (sizeVariant.width === previousWidth) {
89
+ srcsetVariants.splice(i, 1)
90
+ }
91
+ previousWidth = sizeVariant.width
92
+ }
93
+ }
94
+
95
+ export function useImageSources(options: UseImageSourcesOptions) {
96
+ const img = useImage()
97
+ const baseUrl = useRuntimeConfig().public.imageBaseUrl
98
+
99
+ // Convert props to refs if they aren't already
100
+ const mediaRef = toRef(options.media)
101
+ const imageAspectRatiosRef = toRef(options.imageAspectRatios)
102
+ const imageSizesRef = toRef(options.imageSizes)
103
+
104
+ const placeHolderImage = computed(() => {
105
+ const sourceImage = baseUrl + mediaRef.value?.sourceUrl?.path
106
+ if (!sourceImage || sourceImage === baseUrl) return ''
107
+ return img(sourceImage, { format: 'webp', width: 100, blur: 100 })
108
+ })
109
+
110
+ const imageSources = computed((): ImageSource[] => {
111
+ const sourceImage = baseUrl + mediaRef.value?.sourceUrl?.path
112
+ if (!sourceImage || sourceImage === baseUrl) return []
113
+
114
+ const sources: ImageSource[] = []
115
+ const imgSizes = imageSizesRef.value ?? Object.keys(img.options.screens).map(key => `${key}:100vw`).join(' ')
116
+
117
+ // No aspect ratios provided.
118
+ if (!imageAspectRatiosRef.value) {
119
+ const imageSize = img.getSizes(sourceImage, {
120
+ sizes: imgSizes,
121
+ modifiers: {
122
+ format: 'webp'
123
+ }
124
+ })
125
+ // Cast the ImageSizes result to our ImageSource interface
126
+ sources.push(imageSize as ImageSource)
127
+ return sources
128
+ }
129
+
130
+ // Aspect ratios provided.
131
+ const parsedAspectRatios = parseSizes(imageAspectRatiosRef.value)
132
+ const parsedImageSizes = parseSizes(imgSizes)
133
+ const densities = img.options.densities
134
+ const keys = Object.keys(parsedImageSizes)
135
+ const lastKey = keys[keys.length - 1]
136
+
137
+ for (const keyAspectRatios in parsedAspectRatios) {
138
+ const [l, h] = parsedAspectRatios[keyAspectRatios].split('/').map(Number)
139
+ const hwRatio = (l && h) ? h / l : 0
140
+ const sizeVariants = []
141
+ const srcsetVariants = []
142
+
143
+ let screenSizes = Object.keys(parsedImageSizes)
144
+ if (Object.keys(parsedImageSizes).includes(keyAspectRatios)) {
145
+ const minSizeIndex = Object.keys(parsedImageSizes).indexOf(keyAspectRatios)
146
+ screenSizes = Object.keys(parsedImageSizes).slice(minSizeIndex)
147
+ }
148
+
149
+ for (const index in screenSizes) {
150
+ const screenSize = screenSizes[index]
151
+
152
+ const variant = getSizesVariant(screenSize, String(parsedImageSizes[screenSize]), hwRatio, img)
153
+ if (variant === undefined) {
154
+ continue
155
+ }
156
+
157
+ // Add size variant with 'media'.
158
+ sizeVariants.push({
159
+ size: variant.size,
160
+ screenMaxWidth: variant.screenMaxWidth,
161
+ media: `(max-width: ${variant.screenMaxWidth}px)`,
162
+ })
163
+
164
+ // Add srcset variants and ignore densities (for current 'size' processed).
165
+ srcsetVariants.push({
166
+ width: variant._cWidth,
167
+ src: img(sourceImage, {
168
+ width: variant._cWidth ? variant._cWidth : undefined,
169
+ height: variant._cHeight ? variant._cHeight : undefined,
170
+ fit: 'cover',
171
+ format: 'webp'
172
+ }),
173
+ })
174
+
175
+ // Make sure to not create duplicate size variants for the same screen size.
176
+ if (keyAspectRatios != screenSize && Object.keys(parsedAspectRatios).includes(screenSize)) {
177
+ break
178
+ }
179
+ }
180
+
181
+ const media = sizeVariants.slice(-1)[0]?.media
182
+ finaliseSizeVariants(sizeVariants)
183
+ finaliseSrcsetVariants(srcsetVariants)
184
+
185
+ const sizesVal = sizeVariants.length ? sizeVariants.map(v => `${v.media ? v.media + ' ' : ''}${v.size}`).join(', ') : undefined
186
+ const suffix = sizesVal ? 'w' : 'x'
187
+ const srcsetVal = srcsetVariants.map(v => `${v.src} ${v.width}${suffix}`).join(', ')
188
+
189
+ const source: ImageSource = {
190
+ sizes: sizesVal,
191
+ srcset: srcsetVal,
192
+ }
193
+
194
+ if (keyAspectRatios != Object.keys(parsedAspectRatios).slice(-1)[0]) {
195
+ source.media = media
196
+ }
197
+ sources.push(source)
198
+ }
199
+ return sources
200
+ })
201
+
202
+ return {
203
+ placeHolderImage,
204
+ imageSources
205
+ }
206
+ }
207
+
208
+ export type { ImageSource }