@salesforce/templates 66.17.0-beta.3 → 66.17.1

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 (154) hide show
  1. package/lib/generators/lightningAppGenerator.js +7 -7
  2. package/lib/generators/lightningAppGenerator.js.map +1 -1
  3. package/lib/generators/uiBundleGenerator.d.ts +1 -0
  4. package/lib/generators/uiBundleGenerator.js +12 -0
  5. package/lib/generators/uiBundleGenerator.js.map +1 -1
  6. package/lib/generators/visualforceComponentGenerator.js +2 -2
  7. package/lib/generators/visualforceComponentGenerator.js.map +1 -1
  8. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +674 -831
  9. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +680 -837
  10. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +1765 -1639
  11. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +1771 -1645
  12. package/lib/templates/uiBundles/angularbasic/package-lock.json +674 -831
  13. package/lib/templates/uiBundles/reactbasic/package-lock.json +1765 -1639
  14. package/lib/templates/uiBundles/vuebasic/.forceignore +15 -0
  15. package/lib/templates/uiBundles/vuebasic/.graphqlrc.yml +2 -0
  16. package/lib/templates/uiBundles/vuebasic/.prettierignore +9 -0
  17. package/lib/templates/uiBundles/vuebasic/.prettierrc +11 -0
  18. package/lib/templates/uiBundles/vuebasic/README.md +43 -0
  19. package/lib/templates/uiBundles/vuebasic/_uibundle.uibundle-meta.xml +7 -0
  20. package/lib/templates/uiBundles/vuebasic/codegen.yml +95 -0
  21. package/lib/templates/uiBundles/vuebasic/components.json +19 -0
  22. package/lib/templates/uiBundles/vuebasic/eslint.config.js +110 -0
  23. package/lib/templates/uiBundles/vuebasic/index.html +12 -0
  24. package/lib/templates/uiBundles/vuebasic/package-lock.json +15489 -0
  25. package/lib/templates/uiBundles/vuebasic/package.json +72 -0
  26. package/lib/templates/uiBundles/vuebasic/playwright.config.ts +24 -0
  27. package/lib/templates/uiBundles/vuebasic/scripts/get-graphql-schema.mjs +71 -0
  28. package/lib/templates/uiBundles/vuebasic/scripts/rewrite-e2e-assets.mjs +23 -0
  29. package/lib/templates/uiBundles/vuebasic/src/App.vue +5 -0
  30. package/lib/templates/uiBundles/vuebasic/src/api/graphqlClient.ts +44 -0
  31. package/lib/templates/uiBundles/vuebasic/src/appLayout.vue +80 -0
  32. package/lib/templates/uiBundles/vuebasic/src/components/alerts/status-alert.vue +59 -0
  33. package/lib/templates/uiBundles/vuebasic/src/components/layouts/card-layout.vue +30 -0
  34. package/lib/templates/uiBundles/vuebasic/src/components/ui/alert/Alert.vue +21 -0
  35. package/lib/templates/uiBundles/vuebasic/src/components/ui/alert/AlertAction.vue +17 -0
  36. package/lib/templates/uiBundles/vuebasic/src/components/ui/alert/AlertDescription.vue +22 -0
  37. package/lib/templates/uiBundles/vuebasic/src/components/ui/alert/AlertTitle.vue +22 -0
  38. package/lib/templates/uiBundles/vuebasic/src/components/ui/alert/index.ts +25 -0
  39. package/lib/templates/uiBundles/vuebasic/src/components/ui/avatar/Avatar.vue +23 -0
  40. package/lib/templates/uiBundles/vuebasic/src/components/ui/avatar/AvatarFallback.vue +31 -0
  41. package/lib/templates/uiBundles/vuebasic/src/components/ui/avatar/AvatarImage.vue +16 -0
  42. package/lib/templates/uiBundles/vuebasic/src/components/ui/avatar/index.ts +3 -0
  43. package/lib/templates/uiBundles/vuebasic/src/components/ui/button/Button.vue +33 -0
  44. package/lib/templates/uiBundles/vuebasic/src/components/ui/button/index.ts +43 -0
  45. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/Card.vue +29 -0
  46. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/CardAction.vue +22 -0
  47. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/CardContent.vue +17 -0
  48. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/CardDescription.vue +17 -0
  49. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/CardFooter.vue +22 -0
  50. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/CardHeader.vue +22 -0
  51. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/CardTitle.vue +22 -0
  52. package/lib/templates/uiBundles/vuebasic/src/components/ui/card/index.ts +7 -0
  53. package/lib/templates/uiBundles/vuebasic/src/components/ui/checkbox/Checkbox.vue +43 -0
  54. package/lib/templates/uiBundles/vuebasic/src/components/ui/checkbox/index.ts +1 -0
  55. package/lib/templates/uiBundles/vuebasic/src/components/ui/collapsible/Collapsible.vue +19 -0
  56. package/lib/templates/uiBundles/vuebasic/src/components/ui/collapsible/CollapsibleContent.vue +12 -0
  57. package/lib/templates/uiBundles/vuebasic/src/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
  58. package/lib/templates/uiBundles/vuebasic/src/components/ui/collapsible/index.ts +3 -0
  59. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/Dialog.vue +15 -0
  60. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogClose.vue +12 -0
  61. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogContent.vue +59 -0
  62. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogDescription.vue +31 -0
  63. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogFooter.vue +33 -0
  64. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogHeader.vue +17 -0
  65. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogOverlay.vue +31 -0
  66. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogPortal.vue +12 -0
  67. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogTitle.vue +26 -0
  68. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/DialogTrigger.vue +12 -0
  69. package/lib/templates/uiBundles/vuebasic/src/components/ui/dialog/index.ts +10 -0
  70. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
  71. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +51 -0
  72. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuContent.vue +47 -0
  73. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
  74. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuItem.vue +44 -0
  75. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +30 -0
  76. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuPortal.vue +12 -0
  77. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  78. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +52 -0
  79. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +26 -0
  80. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +19 -0
  81. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
  82. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +37 -0
  83. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +38 -0
  84. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  85. package/lib/templates/uiBundles/vuebasic/src/components/ui/dropdown-menu/index.ts +15 -0
  86. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/Field.vue +27 -0
  87. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldContent.vue +22 -0
  88. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldDescription.vue +24 -0
  89. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldError.vue +48 -0
  90. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldGroup.vue +22 -0
  91. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldLabel.vue +24 -0
  92. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldLegend.vue +29 -0
  93. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldSeparator.vue +31 -0
  94. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldSet.vue +22 -0
  95. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/FieldTitle.vue +22 -0
  96. package/lib/templates/uiBundles/vuebasic/src/components/ui/field/index.ts +33 -0
  97. package/lib/templates/uiBundles/vuebasic/src/components/ui/index.ts +115 -0
  98. package/lib/templates/uiBundles/vuebasic/src/components/ui/input/Input.vue +30 -0
  99. package/lib/templates/uiBundles/vuebasic/src/components/ui/input/index.ts +1 -0
  100. package/lib/templates/uiBundles/vuebasic/src/components/ui/label/Label.vue +29 -0
  101. package/lib/templates/uiBundles/vuebasic/src/components/ui/label/index.ts +1 -0
  102. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/Pagination.vue +17 -0
  103. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/PaginationContent.vue +15 -0
  104. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/PaginationEllipsis.vue +23 -0
  105. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/PaginationItem.vue +7 -0
  106. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/PaginationLink.vue +31 -0
  107. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/PaginationNext.vue +29 -0
  108. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/PaginationPrevious.vue +29 -0
  109. package/lib/templates/uiBundles/vuebasic/src/components/ui/pagination/index.ts +7 -0
  110. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/Popover.vue +15 -0
  111. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/PopoverAnchor.vue +12 -0
  112. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/PopoverContent.vue +44 -0
  113. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/PopoverDescription.vue +17 -0
  114. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/PopoverHeader.vue +17 -0
  115. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/PopoverTitle.vue +14 -0
  116. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/PopoverTrigger.vue +12 -0
  117. package/lib/templates/uiBundles/vuebasic/src/components/ui/popover/index.ts +7 -0
  118. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/Select.vue +15 -0
  119. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectContent.vue +65 -0
  120. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectGroup.vue +26 -0
  121. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectItem.vue +41 -0
  122. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectLabel.vue +26 -0
  123. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectScrollDownButton.vue +32 -0
  124. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectScrollUpButton.vue +32 -0
  125. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectSeparator.vue +24 -0
  126. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectTrigger.vue +45 -0
  127. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/SelectValue.vue +12 -0
  128. package/lib/templates/uiBundles/vuebasic/src/components/ui/select/index.ts +10 -0
  129. package/lib/templates/uiBundles/vuebasic/src/components/ui/separator/Separator.vue +33 -0
  130. package/lib/templates/uiBundles/vuebasic/src/components/ui/separator/index.ts +1 -0
  131. package/lib/templates/uiBundles/vuebasic/src/components/ui/skeleton/Skeleton.vue +15 -0
  132. package/lib/templates/uiBundles/vuebasic/src/components/ui/skeleton/index.ts +1 -0
  133. package/lib/templates/uiBundles/vuebasic/src/components/ui/sonner/Sonner.vue +29 -0
  134. package/lib/templates/uiBundles/vuebasic/src/components/ui/sonner/index.ts +3 -0
  135. package/lib/templates/uiBundles/vuebasic/src/components/ui/spinner/Spinner.vue +17 -0
  136. package/lib/templates/uiBundles/vuebasic/src/components/ui/spinner/index.ts +1 -0
  137. package/lib/templates/uiBundles/vuebasic/src/composables/useAsyncData.ts +69 -0
  138. package/lib/templates/uiBundles/vuebasic/src/lib/utils.ts +6 -0
  139. package/lib/templates/uiBundles/vuebasic/src/main.ts +6 -0
  140. package/lib/templates/uiBundles/vuebasic/src/pages/Home.vue +10 -0
  141. package/lib/templates/uiBundles/vuebasic/src/pages/NotFound.vue +18 -0
  142. package/lib/templates/uiBundles/vuebasic/src/router-utils.ts +32 -0
  143. package/lib/templates/uiBundles/vuebasic/src/router.ts +40 -0
  144. package/lib/templates/uiBundles/vuebasic/src/styles/global.css +134 -0
  145. package/lib/templates/uiBundles/vuebasic/src/test/setup.ts +1 -0
  146. package/lib/templates/uiBundles/vuebasic/tsconfig.json +45 -0
  147. package/lib/templates/uiBundles/vuebasic/tsconfig.node.json +13 -0
  148. package/lib/templates/uiBundles/vuebasic/ui-bundle.json +7 -0
  149. package/lib/templates/uiBundles/vuebasic/vite-env.d.ts +14 -0
  150. package/lib/templates/uiBundles/vuebasic/vite.config.ts +106 -0
  151. package/lib/templates/uiBundles/vuebasic/vitest-env.d.ts +2 -0
  152. package/lib/utils/constants.d.ts +1 -1
  153. package/lib/utils/constants.js +1 -1
  154. package/package.json +3 -1
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import type { SelectItemProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { CheckIcon } from '@lucide/vue';
6
+ import { SelectItem, SelectItemIndicator, SelectItemText } from 'reka-ui';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const props = defineProps<
10
+ SelectItemProps & { class?: HTMLAttributes['class'] }
11
+ >();
12
+
13
+ const delegatedProps = computed(() => {
14
+ const { class: _class, ...rest } = props;
15
+ return rest;
16
+ });
17
+ </script>
18
+
19
+ <template>
20
+ <SelectItem
21
+ data-slot="select-item"
22
+ v-bind="delegatedProps"
23
+ :class="
24
+ cn(
25
+ `focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,
26
+ props.class
27
+ )
28
+ "
29
+ >
30
+ <span
31
+ class="pointer-events-none absolute right-2 flex size-4 items-center justify-center"
32
+ >
33
+ <SelectItemIndicator>
34
+ <CheckIcon class="pointer-events-none" />
35
+ </SelectItemIndicator>
36
+ </span>
37
+ <SelectItemText>
38
+ <slot />
39
+ </SelectItemText>
40
+ </SelectItem>
41
+ </template>
@@ -0,0 +1,26 @@
1
+ <script setup lang="ts">
2
+ import type { SelectLabelProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { SelectLabel } from 'reka-ui';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ const props = defineProps<
9
+ SelectLabelProps & { class?: HTMLAttributes['class'] }
10
+ >();
11
+
12
+ const delegatedProps = computed(() => {
13
+ const { class: _class, ...rest } = props;
14
+ return rest;
15
+ });
16
+ </script>
17
+
18
+ <template>
19
+ <SelectLabel
20
+ data-slot="select-label"
21
+ v-bind="delegatedProps"
22
+ :class="cn('text-muted-foreground px-1.5 py-1 text-xs', props.class)"
23
+ >
24
+ <slot />
25
+ </SelectLabel>
26
+ </template>
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import type { SelectScrollDownButtonProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { ChevronDownIcon } from '@lucide/vue';
6
+ import { SelectScrollDownButton } from 'reka-ui';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const props = defineProps<
10
+ SelectScrollDownButtonProps & { class?: HTMLAttributes['class'] }
11
+ >();
12
+
13
+ const delegatedProps = computed(() => {
14
+ const { class: _class, ...rest } = props;
15
+ return rest;
16
+ });
17
+ </script>
18
+
19
+ <template>
20
+ <SelectScrollDownButton
21
+ data-slot="select-scroll-down-button"
22
+ v-bind="delegatedProps"
23
+ :class="
24
+ cn(
25
+ `bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4`,
26
+ props.class
27
+ )
28
+ "
29
+ >
30
+ <ChevronDownIcon />
31
+ </SelectScrollDownButton>
32
+ </template>
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import type { SelectScrollUpButtonProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { ChevronUpIcon } from '@lucide/vue';
6
+ import { SelectScrollUpButton } from 'reka-ui';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const props = defineProps<
10
+ SelectScrollUpButtonProps & { class?: HTMLAttributes['class'] }
11
+ >();
12
+
13
+ const delegatedProps = computed(() => {
14
+ const { class: _class, ...rest } = props;
15
+ return rest;
16
+ });
17
+ </script>
18
+
19
+ <template>
20
+ <SelectScrollUpButton
21
+ data-slot="select-scroll-up-button"
22
+ v-bind="delegatedProps"
23
+ :class="
24
+ cn(
25
+ `bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4`,
26
+ props.class
27
+ )
28
+ "
29
+ >
30
+ <ChevronUpIcon />
31
+ </SelectScrollUpButton>
32
+ </template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ import type { SelectSeparatorProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { SelectSeparator } from 'reka-ui';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ const props = defineProps<
9
+ SelectSeparatorProps & { class?: HTMLAttributes['class'] }
10
+ >();
11
+
12
+ const delegatedProps = computed(() => {
13
+ const { class: _class, ...rest } = props;
14
+ return rest;
15
+ });
16
+ </script>
17
+
18
+ <template>
19
+ <SelectSeparator
20
+ data-slot="select-separator"
21
+ v-bind="delegatedProps"
22
+ :class="cn('bg-border -mx-1 my-1 h-px pointer-events-none', props.class)"
23
+ />
24
+ </template>
@@ -0,0 +1,45 @@
1
+ <script setup lang="ts">
2
+ import type { SelectTriggerProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { ChevronDownIcon } from '@lucide/vue';
6
+ import { SelectIcon, SelectTrigger, useForwardProps } from 'reka-ui';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const props = withDefaults(
10
+ defineProps<
11
+ SelectTriggerProps & {
12
+ class?: HTMLAttributes['class'];
13
+ size?: 'sm' | 'default';
14
+ }
15
+ >(),
16
+ { size: 'default' }
17
+ );
18
+
19
+ const delegatedProps = computed(() => {
20
+ const { class: _class, size: _size, ...rest } = props;
21
+ return rest;
22
+ });
23
+ const forwardedProps = useForwardProps(delegatedProps);
24
+ </script>
25
+
26
+ <template>
27
+ <SelectTrigger
28
+ data-slot="select-trigger"
29
+ :data-size="size"
30
+ v-bind="forwardedProps"
31
+ :class="
32
+ cn(
33
+ `border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0`,
34
+ props.class
35
+ )
36
+ "
37
+ >
38
+ <slot />
39
+ <SelectIcon as-child>
40
+ <ChevronDownIcon
41
+ class="text-muted-foreground size-4 pointer-events-none"
42
+ />
43
+ </SelectIcon>
44
+ </SelectTrigger>
45
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import type { SelectValueProps } from 'reka-ui';
3
+ import { SelectValue } from 'reka-ui';
4
+
5
+ const props = defineProps<SelectValueProps>();
6
+ </script>
7
+
8
+ <template>
9
+ <SelectValue data-slot="select-value" v-bind="props">
10
+ <slot />
11
+ </SelectValue>
12
+ </template>
@@ -0,0 +1,10 @@
1
+ export { default as Select } from './Select.vue';
2
+ export { default as SelectContent } from './SelectContent.vue';
3
+ export { default as SelectGroup } from './SelectGroup.vue';
4
+ export { default as SelectItem } from './SelectItem.vue';
5
+ export { default as SelectLabel } from './SelectLabel.vue';
6
+ export { default as SelectScrollDownButton } from './SelectScrollDownButton.vue';
7
+ export { default as SelectScrollUpButton } from './SelectScrollUpButton.vue';
8
+ export { default as SelectSeparator } from './SelectSeparator.vue';
9
+ export { default as SelectTrigger } from './SelectTrigger.vue';
10
+ export { default as SelectValue } from './SelectValue.vue';
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import type { SeparatorProps } from 'reka-ui';
3
+ import type { HTMLAttributes } from 'vue';
4
+ import { computed } from 'vue';
5
+ import { Separator } from 'reka-ui';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ const props = withDefaults(
9
+ defineProps<SeparatorProps & { class?: HTMLAttributes['class'] }>(),
10
+ {
11
+ orientation: 'horizontal',
12
+ decorative: true,
13
+ }
14
+ );
15
+
16
+ const delegatedProps = computed(() => {
17
+ const { class: _class, ...rest } = props;
18
+ return rest;
19
+ });
20
+ </script>
21
+
22
+ <template>
23
+ <Separator
24
+ data-slot="separator"
25
+ v-bind="delegatedProps"
26
+ :class="
27
+ cn(
28
+ 'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
29
+ props.class
30
+ )
31
+ "
32
+ />
33
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Separator } from './Separator.vue';
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue';
3
+ import { cn } from '@/lib/utils';
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes['class'];
7
+ }>();
8
+ </script>
9
+
10
+ <template>
11
+ <div
12
+ data-slot="skeleton"
13
+ :class="cn('bg-accent animate-pulse rounded-md', props.class)"
14
+ />
15
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Skeleton } from './Skeleton.vue';
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import { Toaster as Sonner } from 'vue-sonner';
3
+ import type { ToasterProps } from 'vue-sonner';
4
+
5
+ /**
6
+ * Renders the toast container. Use with `toast()` from `vue-sonner` for
7
+ * messages with title, description, actions, and variants (success, error,
8
+ * warning).
9
+ *
10
+ * @example
11
+ * import { toast } from 'vue-sonner';
12
+ * toast('Event has been created', {
13
+ * description: 'Sunday, December 03, 2023 at 9:00 AM',
14
+ * action: { label: 'Undo', onClick: () => {} },
15
+ * });
16
+ * toast.success('Saved!');
17
+ * toast.error('Something went wrong');
18
+ * toast.warning('Please review');
19
+ */
20
+ // Defaults for position/richColors; callers can still override via props.
21
+ const props = withDefaults(defineProps<ToasterProps>(), {
22
+ position: 'top-right',
23
+ richColors: true,
24
+ });
25
+ </script>
26
+
27
+ <template>
28
+ <Sonner v-bind="props" />
29
+ </template>
@@ -0,0 +1,3 @@
1
+ export { default as Sonner } from './Sonner.vue';
2
+ export { default as Toaster } from './Sonner.vue';
3
+ export { toast } from 'vue-sonner';
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue';
3
+ import { Loader2Icon } from '@lucide/vue';
4
+ import { cn } from '@/lib/utils';
5
+
6
+ const props = defineProps<{
7
+ class?: HTMLAttributes['class'];
8
+ }>();
9
+ </script>
10
+
11
+ <template>
12
+ <Loader2Icon
13
+ role="status"
14
+ aria-label="Loading"
15
+ :class="cn('size-4 animate-spin', props.class)"
16
+ />
17
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Spinner } from './Spinner.vue';
@@ -0,0 +1,69 @@
1
+ import type { Ref, WatchSource } from 'vue';
2
+ import { ref, shallowRef, watch } from 'vue';
3
+
4
+ /** Reactive async-data snapshot: current data, loading, and error. */
5
+ export interface AsyncData<T> {
6
+ /** Latest successful result. Kept visible during a refetch. */
7
+ data: Ref<T | null>;
8
+ /** True while a fetch for the current args is in flight. */
9
+ loading: Ref<boolean>;
10
+ /** Error message from the most recent failed fetch, else null. */
11
+ error: Ref<string | null>;
12
+ }
13
+
14
+ /**
15
+ * Runs an async `fetcher` immediately and again whenever `source` changes,
16
+ * exposing the result as reactive refs. Stale responses (the source changed
17
+ * during a fetch, or the component unmounted) are dropped via a generation
18
+ * counter, so only the latest in-flight request can write state.
19
+ *
20
+ * The Vue analogue of the React `useAsyncData` hook and the Angular
21
+ * `createAsyncData` helper: the state shape (`data` / `loading` / `error`) is
22
+ * identical so pages port across frameworks unchanged.
23
+ *
24
+ * @typeParam TArgs - The reactive arguments passed to the fetcher.
25
+ * @typeParam T - The fetched result type.
26
+ * @param source - Reactive source (ref, getter, or array of them) whose value
27
+ * is forwarded to `fetcher`. Re-runs on change.
28
+ * @param fetcher - Async function producing the data for the current args.
29
+ * @returns Reactive `{ data, loading, error }` refs.
30
+ */
31
+ export function useAsyncData<TArgs, T>(
32
+ source: WatchSource<TArgs>,
33
+ fetcher: (args: TArgs) => Promise<T>
34
+ ): AsyncData<T> {
35
+ const data = shallowRef<T | null>(null);
36
+ const loading = ref<boolean>(true);
37
+ const error = ref<string | null>(null);
38
+
39
+ let generation = 0;
40
+
41
+ const run = (args: TArgs): void => {
42
+ const current = ++generation;
43
+ loading.value = true;
44
+ error.value = null;
45
+
46
+ fetcher(args)
47
+ .then(result => {
48
+ if (current === generation) {
49
+ data.value = result;
50
+ }
51
+ })
52
+ .catch((err: unknown) => {
53
+ console.error(err);
54
+ if (current === generation) {
55
+ error.value =
56
+ err instanceof Error ? err.message : 'An error occurred';
57
+ }
58
+ })
59
+ .finally(() => {
60
+ if (current === generation) {
61
+ loading.value = false;
62
+ }
63
+ });
64
+ };
65
+
66
+ watch(source, args => run(args), { immediate: true, deep: true });
67
+
68
+ return { data, loading, error };
69
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,6 @@
1
+ import { createApp } from 'vue';
2
+ import App from '@/App.vue';
3
+ import { router } from '@/router';
4
+ import './styles/global.css';
5
+
6
+ createApp(App).use(router).mount('#app');
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts"></script>
2
+
3
+ <template>
4
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
5
+ <div class="text-center">
6
+ <h1 class="text-4xl font-bold text-gray-900 mb-4">Home</h1>
7
+ <p class="text-lg text-gray-600 mb-8">Welcome to your Vue application.</p>
8
+ </div>
9
+ </div>
10
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import { RouterLink } from 'vue-router';
3
+ </script>
4
+
5
+ <template>
6
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
7
+ <div class="text-center">
8
+ <h1 class="text-4xl font-bold text-gray-900 mb-4">404</h1>
9
+ <p class="text-lg text-gray-600 mb-8">Page not found</p>
10
+ <RouterLink
11
+ to="/"
12
+ class="inline-block px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
13
+ >
14
+ Go to Home
15
+ </RouterLink>
16
+ </div>
17
+ </div>
18
+ </template>
@@ -0,0 +1,32 @@
1
+ import type { RouteRecordRaw } from 'vue-router';
2
+ import { routes } from './router';
3
+
4
+ export type RouteWithFullPath = RouteRecordRaw & { fullPath: string };
5
+
6
+ const joinPath = (parentPath: string, childPath: string): string => {
7
+ if (childPath.startsWith('/')) {
8
+ return childPath;
9
+ }
10
+ if (childPath === '') {
11
+ return parentPath || '/';
12
+ }
13
+ return parentPath === '/' ? `/${childPath}` : `${parentPath}/${childPath}`;
14
+ };
15
+
16
+ const flatMapRoutes = (
17
+ route: RouteRecordRaw,
18
+ parentPath: string = ''
19
+ ): RouteWithFullPath[] => {
20
+ const fullPath = joinPath(parentPath, route.path ?? '');
21
+
22
+ const routeWithPath = { ...route, fullPath } as RouteWithFullPath;
23
+
24
+ const childRoutes =
25
+ route.children?.flatMap(child => flatMapRoutes(child, fullPath)) || [];
26
+
27
+ return [routeWithPath, ...childRoutes];
28
+ };
29
+
30
+ export const getAllRoutes = (): RouteWithFullPath[] => {
31
+ return routes.flatMap(route => flatMapRoutes(route));
32
+ };
@@ -0,0 +1,40 @@
1
+ import {
2
+ createRouter,
3
+ createWebHistory,
4
+ type RouteRecordRaw,
5
+ } from 'vue-router';
6
+ import AppLayout from '@/appLayout.vue';
7
+ import HomePage from '@/pages/Home.vue';
8
+ import NotFound from '@/pages/NotFound.vue';
9
+
10
+ // The route-merger composes feature routes into this `routes` array by matching
11
+ // on `path`, so features ship a router.ts with the same top-level `path: ''`
12
+ // node and their child routes are appended as siblings of the base app's routes.
13
+ export const routes: RouteRecordRaw[] = [
14
+ {
15
+ path: '/',
16
+ component: AppLayout,
17
+ children: [
18
+ {
19
+ path: '',
20
+ component: HomePage,
21
+ meta: { showInNavigation: true, label: 'Home' },
22
+ },
23
+ {
24
+ path: ':pathMatch(.*)*',
25
+ component: NotFound,
26
+ },
27
+ ],
28
+ },
29
+ ];
30
+
31
+ // Normalize basename: strip trailing slash so it matches URLs like /lwr/application/ai/c-app
32
+ const rawBasePath = (globalThis as { SFDC_ENV?: { basePath?: string } })
33
+ .SFDC_ENV?.basePath;
34
+ const basename =
35
+ typeof rawBasePath === 'string' ? rawBasePath.replace(/\/+$/, '') : undefined;
36
+
37
+ export const router = createRouter({
38
+ history: createWebHistory(basename),
39
+ routes,
40
+ });
@@ -0,0 +1,134 @@
1
+ @import 'tailwindcss';
2
+
3
+ @layer base {
4
+ html,
5
+ body,
6
+ #app {
7
+ @apply min-h-screen;
8
+ }
9
+
10
+ body {
11
+ @apply antialiased bg-white;
12
+ }
13
+ }
14
+
15
+ @import 'tw-animate-css';
16
+
17
+ @custom-variant dark (&:is(.dark *));
18
+
19
+ @theme inline {
20
+ --color-background: var(--background);
21
+ --color-foreground: var(--foreground);
22
+ --color-card: var(--card);
23
+ --color-card-foreground: var(--card-foreground);
24
+ --color-popover: var(--popover);
25
+ --color-popover-foreground: var(--popover-foreground);
26
+ --color-primary: var(--primary);
27
+ --color-primary-foreground: var(--primary-foreground);
28
+ --color-secondary: var(--secondary);
29
+ --color-secondary-foreground: var(--secondary-foreground);
30
+ --color-muted: var(--muted);
31
+ --color-muted-foreground: var(--muted-foreground);
32
+ --color-accent: var(--accent);
33
+ --color-accent-foreground: var(--accent-foreground);
34
+ --color-destructive: var(--destructive);
35
+ --color-destructive-foreground: var(--destructive-foreground);
36
+ --color-border: var(--border);
37
+ --color-input: var(--input);
38
+ --color-ring: var(--ring);
39
+ --color-chart-1: var(--chart-1);
40
+ --color-chart-2: var(--chart-2);
41
+ --color-chart-3: var(--chart-3);
42
+ --color-chart-4: var(--chart-4);
43
+ --color-chart-5: var(--chart-5);
44
+ --radius-sm: calc(var(--radius) - 4px);
45
+ --radius-md: calc(var(--radius) - 2px);
46
+ --radius-lg: var(--radius);
47
+ --radius-xl: calc(var(--radius) + 4px);
48
+ --color-sidebar: var(--sidebar);
49
+ --color-sidebar-foreground: var(--sidebar-foreground);
50
+ --color-sidebar-primary: var(--sidebar-primary);
51
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
52
+ --color-sidebar-accent: var(--sidebar-accent);
53
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
54
+ --color-sidebar-border: var(--sidebar-border);
55
+ --color-sidebar-ring: var(--sidebar-ring);
56
+ }
57
+
58
+ :root {
59
+ --radius: 0.625rem;
60
+ --background: oklch(1 0 0);
61
+ --foreground: oklch(0.145 0 0);
62
+ --card: oklch(1 0 0);
63
+ --card-foreground: oklch(0.145 0 0);
64
+ --popover: oklch(1 0 0);
65
+ --popover-foreground: oklch(0.145 0 0);
66
+ --primary: oklch(0.205 0 0);
67
+ --primary-foreground: oklch(0.985 0 0);
68
+ --secondary: oklch(0.97 0 0);
69
+ --secondary-foreground: oklch(0.205 0 0);
70
+ --muted: oklch(0.97 0 0);
71
+ --muted-foreground: oklch(0.556 0 0);
72
+ --accent: oklch(0.97 0 0);
73
+ --accent-foreground: oklch(0.205 0 0);
74
+ --destructive: oklch(0.577 0.245 27.325);
75
+ --border: oklch(0.922 0 0);
76
+ --input: oklch(0.922 0 0);
77
+ --ring: oklch(0.708 0 0);
78
+ --chart-1: oklch(0.646 0.222 41.116);
79
+ --chart-2: oklch(0.6 0.118 184.704);
80
+ --chart-3: oklch(0.398 0.07 227.392);
81
+ --chart-4: oklch(0.828 0.189 84.429);
82
+ --chart-5: oklch(0.769 0.188 70.08);
83
+ --sidebar: oklch(0.985 0 0);
84
+ --sidebar-foreground: oklch(0.145 0 0);
85
+ --sidebar-primary: oklch(0.205 0 0);
86
+ --sidebar-primary-foreground: oklch(0.985 0 0);
87
+ --sidebar-accent: oklch(0.97 0 0);
88
+ --sidebar-accent-foreground: oklch(0.205 0 0);
89
+ --sidebar-border: oklch(0.922 0 0);
90
+ --sidebar-ring: oklch(0.708 0 0);
91
+ }
92
+
93
+ .dark {
94
+ --background: oklch(0.145 0 0);
95
+ --foreground: oklch(0.985 0 0);
96
+ --card: oklch(0.205 0 0);
97
+ --card-foreground: oklch(0.985 0 0);
98
+ --popover: oklch(0.205 0 0);
99
+ --popover-foreground: oklch(0.985 0 0);
100
+ --primary: oklch(0.922 0 0);
101
+ --primary-foreground: oklch(0.205 0 0);
102
+ --secondary: oklch(0.269 0 0);
103
+ --secondary-foreground: oklch(0.985 0 0);
104
+ --muted: oklch(0.269 0 0);
105
+ --muted-foreground: oklch(0.708 0 0);
106
+ --accent: oklch(0.269 0 0);
107
+ --accent-foreground: oklch(0.985 0 0);
108
+ --destructive: oklch(0.704 0.191 22.216);
109
+ --border: oklch(1 0 0 / 10%);
110
+ --input: oklch(1 0 0 / 15%);
111
+ --ring: oklch(0.556 0 0);
112
+ --chart-1: oklch(0.488 0.243 264.376);
113
+ --chart-2: oklch(0.696 0.17 162.48);
114
+ --chart-3: oklch(0.769 0.188 70.08);
115
+ --chart-4: oklch(0.627 0.265 303.9);
116
+ --chart-5: oklch(0.645 0.246 16.439);
117
+ --sidebar: oklch(0.205 0 0);
118
+ --sidebar-foreground: oklch(0.985 0 0);
119
+ --sidebar-primary: oklch(0.488 0.243 264.376);
120
+ --sidebar-primary-foreground: oklch(0.985 0 0);
121
+ --sidebar-accent: oklch(0.269 0 0);
122
+ --sidebar-accent-foreground: oklch(0.985 0 0);
123
+ --sidebar-border: oklch(1 0 0 / 10%);
124
+ --sidebar-ring: oklch(0.556 0 0);
125
+ }
126
+
127
+ @layer base {
128
+ * {
129
+ @apply border-border outline-ring/50;
130
+ }
131
+ body {
132
+ @apply bg-background text-foreground;
133
+ }
134
+ }
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/vitest';