@brickflow/ui 0.0.41 → 0.0.43

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 (38) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/Button/icons.demo.vue +9 -8
  3. package/dist/runtime/components/Button/index.vue +83 -51
  4. package/dist/runtime/components/Button/size.demo.vue +8 -7
  5. package/dist/runtime/components/Button/slots.demo.vue +10 -8
  6. package/dist/runtime/components/Button/state.demo.vue +10 -8
  7. package/dist/runtime/components/Button/variants.demo.vue +10 -8
  8. package/dist/runtime/components/Icon/basic.demo.vue +13 -10
  9. package/dist/runtime/components/Icon/gallery.demo.vue +48 -38
  10. package/dist/runtime/components/Icon/index.vue +15 -9
  11. package/dist/runtime/components/Link/basic.demo.vue +7 -7
  12. package/dist/runtime/components/Link/index.vue +81 -50
  13. package/dist/runtime/pages/ui.vue +513 -346
  14. package/package.json +1 -1
  15. package/dist/runtime/components/Button/icons.demo.d.vue.ts +0 -8
  16. package/dist/runtime/components/Button/icons.demo.vue.d.ts +0 -8
  17. package/dist/runtime/components/Button/index.d.vue.ts +0 -53
  18. package/dist/runtime/components/Button/index.vue.d.ts +0 -53
  19. package/dist/runtime/components/Button/size.demo.d.vue.ts +0 -7
  20. package/dist/runtime/components/Button/size.demo.vue.d.ts +0 -7
  21. package/dist/runtime/components/Button/slots.demo.d.vue.ts +0 -7
  22. package/dist/runtime/components/Button/slots.demo.vue.d.ts +0 -7
  23. package/dist/runtime/components/Button/state.demo.d.vue.ts +0 -7
  24. package/dist/runtime/components/Button/state.demo.vue.d.ts +0 -7
  25. package/dist/runtime/components/Button/variants.demo.d.vue.ts +0 -7
  26. package/dist/runtime/components/Button/variants.demo.vue.d.ts +0 -7
  27. package/dist/runtime/components/Icon/basic.demo.d.vue.ts +0 -8
  28. package/dist/runtime/components/Icon/basic.demo.vue.d.ts +0 -8
  29. package/dist/runtime/components/Icon/gallery.demo.d.vue.ts +0 -8
  30. package/dist/runtime/components/Icon/gallery.demo.vue.d.ts +0 -8
  31. package/dist/runtime/components/Icon/index.d.vue.ts +0 -7
  32. package/dist/runtime/components/Icon/index.vue.d.ts +0 -7
  33. package/dist/runtime/components/Link/basic.demo.d.vue.ts +0 -8
  34. package/dist/runtime/components/Link/basic.demo.vue.d.ts +0 -8
  35. package/dist/runtime/components/Link/index.d.vue.ts +0 -51
  36. package/dist/runtime/components/Link/index.vue.d.ts +0 -51
  37. package/dist/runtime/pages/ui.d.vue.ts +0 -4
  38. package/dist/runtime/pages/ui.vue.d.ts +0 -4
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  },
5
5
  "configKey": "brickflowUi",
6
6
  "name": "@brickflow/ui",
7
- "version": "0.0.41",
7
+ "version": "0.0.43",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.3",
10
10
  "unbuild": "3.6.1"
@@ -1,13 +1,14 @@
1
- <script>
2
- export const uiDemo = {
3
- description: "Set leadingIcon and trailingIcon to an icon name. Slots take precedence when both are provided.",
4
- title: "Icons"
5
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ description: 'Set leadingIcon and trailingIcon to an icon name. Slots take precedence when both are provided.',
4
+ title: 'Icons',
5
+ }
6
6
  </script>
7
7
 
8
- <script setup>
9
- import { firstIconName } from "#brickflow-ui-icons";
10
- import Button from "./index.vue";
8
+ <script lang="ts" setup>
9
+ import { firstIconName } from '#brickflow-ui-icons'
10
+
11
+ import Button from './index.vue'
11
12
  </script>
12
13
 
13
14
  <template>
@@ -1,47 +1,79 @@
1
- <script>
2
- const UI_CONFIG = defineUiConfig();
1
+ <script lang="ts">
2
+ const UI_CONFIG = defineUiConfig<{
3
+ colorClasses: Record<string, Record<string, string>>
4
+ colorDefault: string
5
+ loadingIconName: string
6
+ sizeClasses: Record<string, string>
7
+ sizeDefault: string
8
+ sizeIconClasses: Record<string, string>
9
+ variantDefault: string
10
+ }>()
11
+
12
+ export type ButtonConfig = typeof UI_CONFIG
3
13
  </script>
4
14
 
5
- <script setup>
6
- import { computed, shallowRef } from "vue";
7
- import Icon from "../Icon/index.vue";
8
- import BaseLink from "../Link/index.vue";
9
- const props = defineProps({
10
- block: { type: Boolean, required: false },
11
- color: { type: String, required: false, default: UI_CONFIG.colorDefault },
12
- disabled: { type: Boolean, required: false },
13
- icon: { type: String, required: false, default: void 0 },
14
- loading: { type: Boolean, required: false },
15
- rounded: { type: Boolean, required: false, default: false },
16
- size: { type: String, required: false, default: UI_CONFIG.sizeDefault },
17
- square: { type: Boolean, required: false },
18
- to: { type: null, required: false, default: void 0 },
19
- trailingIcon: { type: String, required: false, default: void 0 },
20
- type: { type: String, required: false, default: "button" },
21
- variant: { type: String, required: false, default: UI_CONFIG.variantDefault }
22
- });
23
- const colorClasses = UI_CONFIG.colorClasses;
24
- const sizeClasses = UI_CONFIG.sizeClasses;
25
- const sizeIconClasses = UI_CONFIG.sizeIconClasses;
26
- const component = computed(() => props.to === void 0 ? "button" : BaseLink);
27
- const disabled = computed(() => props.disabled || props.loading);
28
- const isButton = computed(() => props.to === void 0);
29
- const classes = computed(() => [
30
- UI_STYLE.base,
31
- sizeClasses[props.size],
32
- colorClasses[props.color][props.variant],
33
- props.block && UI_STYLE.state.block,
34
- props.square && UI_STYLE.state.square,
35
- disabled.value && UI_STYLE.state.disabled
36
- ]);
37
- const isAnimating = shallowRef(false);
38
- const animationTapClass = UI_STYLE.animationTap;
39
- function handleTap() {
40
- isAnimating.value = false;
41
- requestAnimationFrame(() => {
42
- isAnimating.value = true;
43
- });
44
- }
15
+ <script setup lang="ts">
16
+ import type { RouteLocationRaw } from 'vue-router'
17
+
18
+ import { computed, shallowRef } from 'vue'
19
+
20
+ import Icon from '../Icon/index.vue'
21
+ import BaseLink from '../Link/index.vue'
22
+ const props = withDefaults(
23
+ defineProps<{
24
+ block?: boolean
25
+ color?: ButtonColor
26
+ disabled?: boolean
27
+ icon?: string
28
+ loading?: boolean
29
+ rounded?: boolean
30
+ size?: ButtonSize
31
+ square?: boolean
32
+ to?: RouteLocationRaw
33
+ trailingIcon?: string
34
+ type?: 'button' | 'reset' | 'submit'
35
+ variant?: ButtonVariant
36
+ }>(),
37
+ {
38
+ color: UI_CONFIG.colorDefault,
39
+ icon: undefined,
40
+ rounded: false,
41
+ size: UI_CONFIG.sizeDefault,
42
+ to: undefined,
43
+ trailingIcon: undefined,
44
+ type: 'button',
45
+ variant: UI_CONFIG.variantDefault,
46
+ },
47
+ )
48
+
49
+ const colorClasses = UI_CONFIG.colorClasses
50
+ const sizeClasses = UI_CONFIG.sizeClasses
51
+ const sizeIconClasses = UI_CONFIG.sizeIconClasses
52
+ type ButtonColor = Extract<keyof typeof colorClasses, string>
53
+ type ButtonSize = Extract<keyof typeof sizeClasses, string>
54
+ type ButtonVariant = Extract<keyof (typeof colorClasses)[ButtonColor], string>
55
+
56
+ const component = computed(() => (props.to === undefined ? 'button' : BaseLink))
57
+ const disabled = computed(() => props.disabled || props.loading)
58
+ const isButton = computed(() => props.to === undefined)
59
+ const classes = computed(() => [
60
+ UI_STYLE.base,
61
+ sizeClasses[props.size],
62
+ colorClasses[props.color][props.variant],
63
+ props.block && UI_STYLE.state.block,
64
+ props.square && UI_STYLE.state.square,
65
+ disabled.value && UI_STYLE.state.disabled,
66
+ ])
67
+
68
+ const isAnimating = shallowRef(false)
69
+ const animationTapClass = UI_STYLE.animationTap
70
+ function handleTap(): void {
71
+ isAnimating.value = false
72
+
73
+ requestAnimationFrame(() => {
74
+ isAnimating.value = true
75
+ })
76
+ }
45
77
  </script>
46
78
 
47
79
  <template>
@@ -49,16 +81,16 @@ function handleTap() {
49
81
  :is="component"
50
82
  v-bind="animationTapClass ? { onPointerupPassive: handleTap } : {}"
51
83
  :to="props.to"
52
- :type="isButton ? props.type : void 0"
53
- :disabled="isButton ? disabled : void 0"
54
- :aria-busy="props.loading || void 0"
55
- :aria-disabled="disabled || void 0"
56
- :tabindex="disabled && !isButton ? -1 : void 0"
84
+ :type="isButton ? props.type : undefined"
85
+ :disabled="isButton ? disabled : undefined"
86
+ :aria-busy="props.loading || undefined"
87
+ :aria-disabled="disabled || undefined"
88
+ :tabindex="disabled && !isButton ? -1 : undefined"
57
89
  :class="[classes, isAnimating && animationTapClass]"
58
90
  data-testid="ui-button"
59
91
  :style="{
60
- borderRadius: props.rounded && '99999px'
61
- }"
92
+ borderRadius: props.rounded && '99999px',
93
+ }"
62
94
  @contextmenu.prevent
63
95
  >
64
96
  <span
@@ -74,7 +106,7 @@ function handleTap() {
74
106
  />
75
107
  <Icon
76
108
  v-else
77
- :name="props.icon"
109
+ :name="props.icon!"
78
110
  :class="sizeIconClasses[props.size]"
79
111
  aria-hidden="true"
80
112
  />
@@ -94,7 +126,7 @@ function handleTap() {
94
126
  >
95
127
  <slot name="trailing">
96
128
  <Icon
97
- :name="props.trailingIcon"
129
+ :name="props.trailingIcon!"
98
130
  :class="sizeIconClasses[props.size]"
99
131
  aria-hidden="true"
100
132
  />
@@ -1,12 +1,13 @@
1
- <script>
2
- export const uiDemo = {
3
- title: "Size & Rounded"
4
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ title: 'Size & Rounded',
4
+ }
5
5
  </script>
6
6
 
7
- <script setup>
8
- import { buttonConfig, firstIconName } from "#brickflow-ui-icons";
9
- import Button from "./index.vue";
7
+ <script lang="ts" setup>
8
+ import { buttonConfig, firstIconName } from '#brickflow-ui-icons'
9
+
10
+ import Button from './index.vue'
10
11
  </script>
11
12
 
12
13
  <template>
@@ -1,13 +1,15 @@
1
- <script>
2
- export const uiDemo = {
3
- title: "Slots"
4
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ title: 'Slots',
4
+ }
5
5
  </script>
6
6
 
7
- <script setup>
8
- import { ref } from "vue";
9
- import Button from "./index.vue";
10
- const clicks = ref(0);
7
+ <script lang="ts" setup>
8
+ import { ref } from 'vue'
9
+
10
+ import Button from './index.vue'
11
+
12
+ const clicks = ref(0)
11
13
  </script>
12
14
 
13
15
  <template>
@@ -1,13 +1,15 @@
1
- <script>
2
- export const uiDemo = {
3
- title: "State"
4
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ title: 'State',
4
+ }
5
5
  </script>
6
6
 
7
- <script setup>
8
- import { buttonConfig } from "#brickflow-ui-icons";
9
- import Button from "./index.vue";
10
- const firstColorClasses = Object.values(buttonConfig.colorClasses)[0] ?? {};
7
+ <script lang="ts" setup>
8
+ import { buttonConfig } from '#brickflow-ui-icons'
9
+
10
+ import Button from './index.vue'
11
+
12
+ const firstColorClasses = Object.values(buttonConfig.colorClasses)[0] ?? {}
11
13
  </script>
12
14
 
13
15
  <template>
@@ -1,13 +1,15 @@
1
- <script>
2
- export const uiDemo = {
3
- title: "Color & Variants"
4
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ title: 'Color & Variants',
4
+ }
5
5
  </script>
6
6
 
7
- <script setup>
8
- import { buttonConfig } from "#brickflow-ui-icons";
9
- import Button from "./index.vue";
10
- const firstColorClasses = Object.values(buttonConfig.colorClasses)[0] ?? {};
7
+ <script lang="ts" setup>
8
+ import { buttonConfig } from '#brickflow-ui-icons'
9
+
10
+ import Button from './index.vue'
11
+
12
+ const firstColorClasses = Object.values(buttonConfig.colorClasses)[0] ?? {}
11
13
  </script>
12
14
 
13
15
  <template>
@@ -1,15 +1,18 @@
1
- <script>
2
- export const uiDemo = {
3
- description: "The name matches the SVG filename without its extension.",
4
- title: "Basic usage"
5
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ description: 'The name matches the SVG filename without its extension.',
4
+ title: 'Basic usage',
5
+ }
6
6
  </script>
7
7
 
8
- <script setup>
9
- import { ref } from "vue";
10
- import { firstIconName } from "#brickflow-ui-icons";
11
- import Icon from "./index.vue";
12
- const iconName = ref(firstIconName);
8
+ <script lang="ts" setup>
9
+ import { ref } from 'vue'
10
+
11
+ import { firstIconName } from '#brickflow-ui-icons'
12
+
13
+ import Icon from './index.vue'
14
+
15
+ const iconName = ref(firstIconName)
13
16
  </script>
14
17
 
15
18
  <template>
@@ -1,36 +1,44 @@
1
- <script>
2
- export const uiDemo = {
3
- description: "Browse every icon available in the project, filter by name, and click to copy its name.",
4
- title: "Icon gallery"
5
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ description: 'Browse every icon available in the project, filter by name, and click to copy its name.',
4
+ title: 'Icon gallery',
5
+ }
6
6
  </script>
7
7
 
8
- <script setup>
9
- import { computed, onBeforeUnmount, ref } from "vue";
10
- import { iconNames } from "#brickflow-ui-icons";
11
- import Icon from "./index.vue";
12
- const search = ref("");
13
- const copiedIconName = ref("");
14
- const copyError = ref("");
15
- let copiedTimeout;
16
- const filteredIconNames = computed(() => {
17
- const query = search.value.trim().toLocaleLowerCase();
18
- return query ? iconNames.filter((name) => name.toLocaleLowerCase().includes(query)) : iconNames;
19
- });
20
- const copyIconName = async (name) => {
21
- copyError.value = "";
22
- try {
23
- await navigator.clipboard.writeText(name);
24
- clearTimeout(copiedTimeout);
25
- copiedIconName.value = name;
26
- copiedTimeout = setTimeout(() => {
27
- copiedIconName.value = "";
28
- }, 2e3);
29
- } catch {
30
- copyError.value = "Could not copy the icon name. Please try again.";
8
+ <script lang="ts" setup>
9
+ import { computed, onBeforeUnmount, ref } from 'vue'
10
+
11
+ import { iconNames } from '#brickflow-ui-icons'
12
+
13
+ import Icon from './index.vue'
14
+
15
+ const search = ref('')
16
+ const copiedIconName = ref('')
17
+ const copyError = ref('')
18
+ let copiedTimeout: ReturnType<typeof setTimeout> | undefined
19
+
20
+ const filteredIconNames = computed(() => {
21
+ const query = search.value.trim().toLocaleLowerCase()
22
+
23
+ return query ? iconNames.filter((name) => name.toLocaleLowerCase().includes(query)) : iconNames
24
+ })
25
+
26
+ const copyIconName = async (name: string): Promise<void> => {
27
+ copyError.value = ''
28
+
29
+ try {
30
+ await navigator.clipboard.writeText(name)
31
+ clearTimeout(copiedTimeout)
32
+ copiedIconName.value = name
33
+ copiedTimeout = setTimeout(() => {
34
+ copiedIconName.value = ''
35
+ }, 2000)
36
+ } catch {
37
+ copyError.value = 'Could not copy the icon name. Please try again.'
38
+ }
31
39
  }
32
- };
33
- onBeforeUnmount(() => clearTimeout(copiedTimeout));
40
+
41
+ onBeforeUnmount(() => clearTimeout(copiedTimeout))
34
42
  </script>
35
43
 
36
44
  <template>
@@ -75,7 +83,7 @@ onBeforeUnmount(() => clearTimeout(copiedTimeout));
75
83
  class="sr-only"
76
84
  role="status"
77
85
  >
78
- {{ copiedIconName ? `Copied ${copiedIconName}` : "" }}
86
+ {{ copiedIconName ? `Copied ${copiedIconName}` : '' }}
79
87
  </p>
80
88
  <p
81
89
  v-if="copyError"
@@ -98,9 +106,11 @@ onBeforeUnmount(() => clearTimeout(copiedTimeout));
98
106
  type="button"
99
107
  :aria-label="`Copy ${name}`"
100
108
  :class="[
101
- 'group flex w-full cursor-pointer flex-col items-center gap-3 rounded-xl border px-3 py-5 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400',
102
- copiedIconName === name ? 'border-green-500/50 bg-green-500/10' : 'border-zinc-900 bg-zinc-950/50 hover:border-zinc-700 hover:bg-zinc-900/70'
103
- ]"
109
+ 'group flex w-full cursor-pointer flex-col items-center gap-3 rounded-xl border px-3 py-5 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400',
110
+ copiedIconName === name
111
+ ? 'border-green-500/50 bg-green-500/10'
112
+ : 'border-zinc-900 bg-zinc-950/50 hover:border-zinc-700 hover:bg-zinc-900/70',
113
+ ]"
104
114
  :title="`Copy ${name}`"
105
115
  @click="copyIconName(name)"
106
116
  >
@@ -111,11 +121,11 @@ onBeforeUnmount(() => clearTimeout(copiedTimeout));
111
121
  />
112
122
  <span
113
123
  :class="[
114
- 'w-full truncate text-center font-mono text-xs transition-colors',
115
- copiedIconName === name ? 'text-green-400' : 'text-zinc-400 group-hover:text-zinc-100'
116
- ]"
124
+ 'w-full truncate text-center font-mono text-xs transition-colors',
125
+ copiedIconName === name ? 'text-green-400' : 'text-zinc-400 group-hover:text-zinc-100',
126
+ ]"
117
127
  >
118
- {{ copiedIconName === name ? "Copied" : name }}
128
+ {{ copiedIconName === name ? 'Copied' : name }}
119
129
  </span>
120
130
  </button>
121
131
  </li>
@@ -1,12 +1,18 @@
1
- <script setup>
2
- import { computed } from "vue";
3
- defineOptions({
4
- inheritAttrs: false
5
- });
6
- const props = defineProps({
7
- name: { type: String, required: true }
8
- });
9
- const classes = computed(() => `icon-${props.name}`);
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ })
7
+
8
+ const props = withDefaults(
9
+ defineProps<{
10
+ name: string
11
+ }>(),
12
+ {},
13
+ )
14
+
15
+ const classes = computed(() => `icon-${props.name}`)
10
16
  </script>
11
17
 
12
18
  <template>
@@ -1,12 +1,12 @@
1
- <script>
2
- export const uiDemo = {
3
- description: "Internal navigation keeps the current locale.",
4
- title: "Basic usage"
5
- };
1
+ <script lang="ts">
2
+ export const uiDemo = {
3
+ description: 'Internal navigation keeps the current locale.',
4
+ title: 'Basic usage',
5
+ }
6
6
  </script>
7
7
 
8
- <script setup>
9
- import Link from "./index.vue";
8
+ <script lang="ts" setup>
9
+ import Link from './index.vue'
10
10
  </script>
11
11
 
12
12
  <template>
@@ -8,55 +8,86 @@
8
8
  </NuxtLink>
9
9
  </template>
10
10
 
11
- <script setup>
12
- import { computed, ref } from "vue";
13
- import { useRouter } from "vue-router";
14
- import { useTranslate } from "../../composables/useTranslate";
15
- defineOptions({ inheritAttrs: false });
16
- const props = defineProps({
17
- activeClass: { type: String, required: false, default: void 0 },
18
- class: { type: [Array, String], required: false, default: void 0 },
19
- custom: { type: Boolean, required: false, default: false },
20
- exactActiveClass: { type: String, required: false, default: void 0 },
21
- external: { type: Boolean, required: false, default: false },
22
- faster: { type: Boolean, required: false, default: false },
23
- href: { type: null, required: false, default: void 0 },
24
- onClick: { type: Function, required: false, default: void 0 },
25
- onPointerdown: { type: Function, required: false, default: void 0 },
26
- prefetch: { type: Boolean, required: false, default: false },
27
- rel: { type: [null, String], required: false, default: void 0 },
28
- replace: { type: Boolean, required: false, default: false },
29
- style: { type: Object, required: false, default: void 0 },
30
- target: { type: [String, null, Object], required: false, default: void 0 },
31
- to: { type: null, required: false, default: void 0 }
32
- });
33
- const { localePath } = useTranslate();
34
- const prepareProps = computed(() => {
35
- const { faster: _faster, onPointerdown: _onPointerdown, ...linkProps } = props;
36
- const refineDrops = { ...linkProps, onPointerdown: props.faster ? handlePointerDown : void 0 };
37
- if (typeof props.to === "string") {
38
- return { ...refineDrops, to: localePath(props.to) };
39
- } else if (props.to?.path) {
40
- return { ...refineDrops, to: { ...props.to, path: localePath(props.to.path) } };
41
- }
42
- return refineDrops;
43
- });
44
- const linkRef = ref();
45
- function handlePointerDown(e) {
46
- const router = useRouter();
47
- props.onPointerdown?.();
48
- if (e.button !== 0) {
49
- return;
50
- }
51
- if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
52
- return;
53
- }
54
- e.preventDefault();
55
- const to = prepareProps.value.to;
56
- if (!to) {
57
- return;
11
+ <script lang="ts" setup>
12
+ import { type ComponentPublicInstance, computed, ref } from 'vue'
13
+ import { type RouteLocationPathRaw, type RouteLocationRaw, useRouter } from 'vue-router'
14
+
15
+ import { useTranslate } from '../../composables/useTranslate'
16
+
17
+ defineOptions({ inheritAttrs: false })
18
+
19
+ const props = withDefaults(
20
+ defineProps<{
21
+ activeClass?: string
22
+ class?: (false | string)[] | string
23
+ custom?: boolean
24
+ exactActiveClass?: string
25
+ external?: boolean
26
+ faster?: boolean
27
+ href?: RouteLocationRaw
28
+ onClick?: () => void
29
+ onPointerdown?: () => void
30
+ prefetch?: boolean
31
+ rel?: null | string
32
+ replace?: boolean
33
+ style?: Record<string, string>
34
+ target?: '_blank' | '_parent' | '_self' | '_top' | null | (Record<string, never> & string)
35
+ to?: RouteLocationRaw
36
+ }>(),
37
+ {
38
+ activeClass: undefined,
39
+ class: undefined,
40
+ custom: false,
41
+ exactActiveClass: undefined,
42
+ external: false,
43
+ faster: false,
44
+ href: undefined,
45
+ onClick: undefined,
46
+ onPointerdown: undefined,
47
+ prefetch: false,
48
+ rel: undefined,
49
+ replace: false,
50
+ style: undefined,
51
+ target: undefined,
52
+ to: undefined,
53
+ },
54
+ )
55
+ const { localePath } = useTranslate()
56
+
57
+ const prepareProps = computed(() => {
58
+ const { faster: _faster, onPointerdown: _onPointerdown, ...linkProps } = props
59
+ const refineDrops = { ...linkProps, onPointerdown: props.faster ? handlePointerDown : undefined }
60
+
61
+ if (typeof props.to === 'string') {
62
+ return { ...refineDrops, to: localePath(props.to) }
63
+ } else if ((props.to as RouteLocationPathRaw)?.path) {
64
+ return { ...refineDrops, to: { ...props.to, path: localePath((props.to as RouteLocationPathRaw).path) } }
65
+ }
66
+
67
+ return refineDrops
68
+ })
69
+ const linkRef = ref<ComponentPublicInstance>()
70
+
71
+ function handlePointerDown(e: PointerEvent): void {
72
+ const router = useRouter()
73
+ props.onPointerdown?.()
74
+ if (e.button !== 0) {
75
+ return
76
+ }
77
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
78
+ return
79
+ }
80
+
81
+ e.preventDefault()
82
+
83
+ const to = prepareProps.value.to
84
+
85
+ if (!to) {
86
+ return
87
+ }
88
+
89
+ props.replace ? router.replace(to) : router.push(to)
58
90
  }
59
- props.replace ? router.replace(to) : router.push(to);
60
- }
61
- defineExpose({ linkRef });
91
+
92
+ defineExpose({ linkRef })
62
93
  </script>