fds-vue-core 8.2.1 → 8.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fds-vue-core",
3
- "version": "8.2.1",
3
+ "version": "8.2.2",
4
4
  "description": "FDS Vue Core Component Library",
5
5
  "type": "module",
6
6
  "main": "./dist/fds-vue-core.cjs.js",
@@ -37,7 +37,7 @@
37
37
  "fds"
38
38
  ],
39
39
  "engines": {
40
- "node": "^20.19.0 || >=22.12.0"
40
+ "node": ">=22.13.0"
41
41
  },
42
42
  "config": {
43
43
  "commitizen": {
@@ -48,15 +48,15 @@
48
48
  "vue": "^3.5.25"
49
49
  },
50
50
  "dependencies": {
51
- "axios": "1.18.0",
51
+ "axios": "1.18.1",
52
52
  "date-fns": "4.4.0",
53
53
  "imask": "7.6.1",
54
- "libphonenumber-js": "1.13.6",
54
+ "libphonenumber-js": "1.13.7",
55
55
  "tailwindcss": "4.3.1"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@chromatic-com/storybook": "5.2.1",
59
- "@intlify/unplugin-vue-i18n": "11.2.3",
59
+ "@intlify/unplugin-vue-i18n": "11.2.4",
60
60
  "@storybook/addon-a11y": "10.4.6",
61
61
  "@storybook/addon-docs": "10.4.6",
62
62
  "@storybook/addon-vitest": "10.4.6",
@@ -65,8 +65,8 @@
65
65
  "@tailwindcss/vite": "4.3.1",
66
66
  "@types/node": "22.16.5",
67
67
  "@vitejs/plugin-vue": "6.0.7",
68
- "@vitest/browser": "4.1.9",
69
- "fg-devkit": "1.9.1",
68
+ "@vitest/browser": "3.2.4",
69
+ "fg-devkit": "1.12.5",
70
70
  "storybook": "10.4.6",
71
71
  "tsx": "4.22.4",
72
72
  "vite": "7.3.5",
@@ -74,7 +74,7 @@
74
74
  "vite-plugin-vue-devtools": "8.1.3",
75
75
  "vitest": "4.1.9",
76
76
  "vue": "3.5.38",
77
- "vue-i18n": "11.4.5"
77
+ "vue-i18n": "11.4.6"
78
78
  },
79
79
  "knip": {
80
80
  "ignoreBinaries": [
@@ -42,8 +42,7 @@ const sizeClasses: Record<string, string> = {
42
42
  lg: 'text-lg h-[68px] px-6',
43
43
  }
44
44
 
45
- const variantClasses =
46
- 'bg-red-600 border border-red-700 text-white hover:bg-red-700 active:bg-red-800 active:border-red-800'
45
+ const variantClasses = 'bg-blue-600 border border-blue-600 text-white hover:bg-blue-700'
47
46
 
48
47
  const blockElClasses = computed(() => props.block && 'w-full justify-center')
49
48
 
@@ -0,0 +1,93 @@
1
+ type RouterLike = { push: (to: unknown) => Promise<unknown> | unknown }
2
+
3
+ let globalRouter: RouterLike | null = null
4
+ let clickHandler: ((event: MouseEvent) => void) | null = null
5
+
6
+ const isModifiedClick = (event: MouseEvent): boolean => event.metaKey || event.ctrlKey || event.shiftKey || event.altKey
7
+
8
+ const findLinkAnchor = (event: Event): HTMLAnchorElement | null => {
9
+ const { target } = event
10
+ if (!(target instanceof Element)) return null
11
+
12
+ const anchor = target.closest('a[href]')
13
+ return anchor instanceof HTMLAnchorElement ? anchor : null
14
+ }
15
+
16
+ /**
17
+ * Returns true when href is a relative URL suitable for in-app navigation
18
+ * (e.g. `/dashboard`, `page`, `./page`) — not absolute, protocol-relative, or hash-only.
19
+ */
20
+ export const isRelativeHref = (href: string): boolean => {
21
+ if (!href || href.startsWith('#')) return false
22
+ if (/^[a-z][a-z0-9+.-]*:/i.test(href)) return false
23
+ if (href.startsWith('//')) return false
24
+ return true
25
+ }
26
+
27
+ /**
28
+ * Resolves an anchor href to a value suitable for `router.push`.
29
+ * Returns `null` when the link should use normal browser navigation.
30
+ */
31
+ export const resolveRouterLinkTarget = (anchor: HTMLAnchorElement): string | null => {
32
+ if (anchor.hasAttribute('disabled') || anchor.getAttribute('aria-disabled') === 'true') {
33
+ return null
34
+ }
35
+ if (anchor.hasAttribute('download')) return null
36
+ if (anchor.target && anchor.target !== '_self') return null
37
+
38
+ const href = anchor.getAttribute('href')
39
+ if (!href || !isRelativeHref(href)) return null
40
+
41
+ try {
42
+ const url = new URL(href, window.location.href)
43
+ return url.pathname + url.search + url.hash
44
+ } catch {
45
+ return href
46
+ }
47
+ }
48
+
49
+ const handleClick = (event: MouseEvent) => {
50
+ if (event.defaultPrevented) return
51
+ if (event.button !== 0) return
52
+ if (isModifiedClick(event)) return
53
+
54
+ const anchor = findLinkAnchor(event)
55
+ if (!anchor || !globalRouter) return
56
+
57
+ const to = resolveRouterLinkTarget(anchor)
58
+ if (!to) return
59
+
60
+ event.preventDefault()
61
+ void globalRouter.push(to)
62
+ }
63
+
64
+ /**
65
+ * Interceptar klick på relativa `<a href>` och navigerar med `router.push`
66
+ * i stället för full sidladdning. Användbart för HTML/JSON från t.ex. Payload CMS
67
+ * eller Poeditor där `router-link` inte kan användas direkt.
68
+ *
69
+ * Anropa en gång vid app-start:
70
+ * ```ts
71
+ * setupRouterLinkInterceptor(router)
72
+ * ```
73
+ *
74
+ * HTML-exempel:
75
+ * ```html
76
+ * <a href="/dashboard">Öppna dashboard</a>
77
+ * ```
78
+ */
79
+ export const setupRouterLinkInterceptor = (router: RouterLike) => {
80
+ teardownRouterLinkInterceptor()
81
+ globalRouter = router
82
+ clickHandler = handleClick
83
+ document.addEventListener('click', clickHandler)
84
+ }
85
+
86
+ /** Tar bort den globala router-link-interceptorn. */
87
+ export const teardownRouterLinkInterceptor = () => {
88
+ if (clickHandler) {
89
+ document.removeEventListener('click', clickHandler)
90
+ clickHandler = null
91
+ }
92
+ globalRouter = null
93
+ }
package/src/index.ts CHANGED
@@ -71,6 +71,12 @@ import {
71
71
  PID_MASK_OPTIONS,
72
72
  useIsPid,
73
73
  } from './composables/useIsPid'
74
+ import {
75
+ isRelativeHref,
76
+ resolveRouterLinkTarget,
77
+ setupRouterLinkInterceptor,
78
+ teardownRouterLinkInterceptor,
79
+ } from './composables/setupRouterLinkInterceptor'
74
80
  import { useRouteScrollPositions } from './composables/useRouteScrollPositions'
75
81
  import { useViewportBreakpoint } from './composables/useViewportBreakpoint'
76
82
  import { capitalizeFirstLetter } from './helpers/capitalizeFirstLetter'
@@ -131,14 +137,18 @@ export {
131
137
  clearUnsavedChanges,
132
138
  debounce,
133
139
  formatPidWithDash,
140
+ isRelativeHref,
134
141
  getExitGuardWizardId,
135
142
  isPidString,
136
143
  normalizePidSearchValue,
137
144
  PID_MASK,
138
145
  PID_MASK_OPTIONS,
146
+ resolveRouterLinkTarget,
139
147
  setupExitConfirmationGuard,
148
+ setupRouterLinkInterceptor,
140
149
  shouldBlockNavigation,
141
150
  shouldBlockWizardExit,
151
+ teardownRouterLinkInterceptor,
142
152
  useBoldQuery,
143
153
  useDevMode,
144
154
  useDevModeEnvironment,
@@ -1,72 +0,0 @@
1
- declare const _default: {
2
- "App.treeViewTest": "FDS Tree View Test",
3
- "common.plus": "+",
4
- "FdsBlockAlert.close": "Close",
5
- "FdsBlockAlert.showLess": "Show less",
6
- "FdsBlockAlert.showMore": "Show more",
7
- "FdsDevMode.baseBreakpoint": "base",
8
- "FdsDevMode.baseBreakpointRange": "<320px",
9
- "FdsDevMode.toggle.off": "Dev mode: OFF",
10
- "FdsDevMode.toggle.on": "Dev mode: ON",
11
- "FdsDevMode.overlay.close": "Close dev overlay",
12
- "FdsDevMode.overlay.localeEn": "English",
13
- "FdsDevMode.overlay.localeSv": "Svenska",
14
- "FdsDevMode.overlay.open": "Open dev overlay",
15
- "FdsDevMode.overlay.poeditor": "Show translation keys",
16
- "FdsDevModeStorage.actions.close": "Close",
17
- "FdsDevModeStorage.actions.delete": "Delete",
18
- "FdsDevModeStorage.actions.emptyState": "No custom actions configured. Pass customActions prop to FdsDevMode.",
19
- "FdsDevModeStorage.actions.refresh": "Refresh",
20
- "FdsDevModeStorage.actions.save": "Save",
21
- "FdsDevModeStorage.empty.cookies": "No cookies set for this domain.",
22
- "FdsDevModeStorage.empty.localStorage": "No values in localStorage.",
23
- "FdsDevModeStorage.empty.sessionStorage": "No values in sessionStorage.",
24
- "FdsDevModeStorage.keyLabel": "Key",
25
- "FdsDevModeStorage.nameLabel": "Name",
26
- "FdsDevModeStorage.placeholders.cookieName": "cookie-name",
27
- "FdsDevModeStorage.placeholders.localStorageKey": "localStorage-key",
28
- "FdsDevModeStorage.placeholders.sessionStorageKey": "sessionStorage-key",
29
- "FdsDevModeStorage.placeholders.valueAsString": "Value (stored as string)",
30
- "FdsDevModeStorage.tabs.actions": "Actions",
31
- "FdsDevModeStorage.tabs.cookies": "Cookies",
32
- "FdsDevModeStorage.tabs.localStorage": "localStorage",
33
- "FdsDevModeStorage.tabs.sessionStorage": "sessionStorage",
34
- "FdsDevModeStorage.valueLabel": "Value",
35
- "FdsInput.clearInput": "Delete text",
36
- "FdsInput.hidePassword": "Hide",
37
- "FdsInput.openDatePicker": "Open date picker",
38
- "FdsInput.showPassword": "Show",
39
- "FdsInput.today": "(today)",
40
- "FdsListHeading.loading": "Loading...",
41
- "FdsListHeading.separator": "of",
42
- "FdsModal.closeModal": "Close modal window",
43
- "FdsPagination.currentPage": "Current page",
44
- "FdsPagination.firstPage": "Go to first page",
45
- "FdsPagination.lastPage": "Go to last page",
46
- "FdsPagination.loading": "Loading",
47
- "FdsPagination.nextPage": "Go to next page",
48
- "FdsPagination.previousPage": "Go to previous page",
49
- "FdsPhonenumber.countryCode": "Country code",
50
- "FdsPhonenumber.invalidPhone": "Enter a valid phone number",
51
- "FdsPhonenumber.noCountryResults": "No country matches your search",
52
- "FdsPhonenumber.phoneNumber": "Phone number",
53
- "FdsSearchSelectPro.loadingMore": "Loading more...",
54
- "FdsSearchSelectPro.showMore": "Show more",
55
- "FdsSearchSelectPro.unspecified": "Unspecified",
56
- "FdsTextarea.characters": "characters",
57
- "FdsTreeView.childrenCountPrefix": "(+",
58
- "FdsTreeView.closePopover": "Close",
59
- "FdsTreeView.collapseNode": "Collapse {title}",
60
- "FdsTreeView.expandNode": "Expand {title}",
61
- "FdsTreeView.moreOptionsForNode": "More options for {title}",
62
- "FdsWeekCalendar.nextWeek": "Next week",
63
- "FdsWeekCalendar.previousWeek": "Previous week",
64
- "FdsWeekCalendar.today": "Today",
65
- "FdsWeekCalendar.week": "week",
66
- "FdsDevMode.overlay.toggles.apiError": "API error",
67
- "FdsDevMode.overlay.toggles.debugLogging": "Debug logging",
68
- "FdsDevMode.overlay.quickSettings": "Quick settings"
69
- }
70
- ;
71
-
72
- export default _default;
@@ -1,72 +0,0 @@
1
- declare const _default: {
2
- "App.treeViewTest": "FDS Tree View Test",
3
- "common.plus": "+",
4
- "FdsBlockAlert.close": "Stäng",
5
- "FdsBlockAlert.showLess": "Visa mindre",
6
- "FdsBlockAlert.showMore": "Visa mer",
7
- "FdsDevMode.baseBreakpoint": "base",
8
- "FdsDevMode.baseBreakpointRange": "<320px",
9
- "FdsDevMode.toggle.off": "Dev mode: OFF",
10
- "FdsDevMode.toggle.on": "Dev mode: ON",
11
- "FdsDevMode.overlay.close": "Stäng dev-overlay",
12
- "FdsDevMode.overlay.localeEn": "English",
13
- "FdsDevMode.overlay.localeSv": "Svenska",
14
- "FdsDevMode.overlay.open": "Öppna dev-overlay",
15
- "FdsDevMode.overlay.poeditor": "Visa översättningsnycklar",
16
- "FdsDevModeStorage.actions.close": "Stäng",
17
- "FdsDevModeStorage.actions.delete": "Ta bort",
18
- "FdsDevModeStorage.actions.emptyState": "No custom actions configured. Pass customActions prop to FdsDevMode.",
19
- "FdsDevModeStorage.actions.refresh": "Uppdatera",
20
- "FdsDevModeStorage.actions.save": "Spara",
21
- "FdsDevModeStorage.empty.cookies": "Inga cookies satta för domänen.",
22
- "FdsDevModeStorage.empty.localStorage": "Inga värden i localStorage.",
23
- "FdsDevModeStorage.empty.sessionStorage": "Inga värden i sessionStorage.",
24
- "FdsDevModeStorage.keyLabel": "Nyckel",
25
- "FdsDevModeStorage.nameLabel": "Namn",
26
- "FdsDevModeStorage.placeholders.cookieName": "cookie-namn",
27
- "FdsDevModeStorage.placeholders.localStorageKey": "localStorage-nyckel",
28
- "FdsDevModeStorage.placeholders.sessionStorageKey": "sessionStorage-nyckel",
29
- "FdsDevModeStorage.placeholders.valueAsString": "Värde (lagras som sträng)",
30
- "FdsDevModeStorage.tabs.actions": "Actions",
31
- "FdsDevModeStorage.tabs.cookies": "Cookies",
32
- "FdsDevModeStorage.tabs.localStorage": "localStorage",
33
- "FdsDevModeStorage.tabs.sessionStorage": "sessionStorage",
34
- "FdsDevModeStorage.valueLabel": "Värde",
35
- "FdsInput.clearInput": "Rensa text",
36
- "FdsInput.hidePassword": "Dölj",
37
- "FdsInput.openDatePicker": "Öppna datumväljare",
38
- "FdsInput.showPassword": "Visa",
39
- "FdsInput.today": "(idag)",
40
- "FdsListHeading.loading": "Laddar...",
41
- "FdsListHeading.separator": "av",
42
- "FdsModal.closeModal": "Stäng dialogruta",
43
- "FdsPagination.currentPage": "Aktuell sida",
44
- "FdsPagination.firstPage": "Gå till första sidan",
45
- "FdsPagination.lastPage": "Gå till sista sidan",
46
- "FdsPagination.loading": "Laddar",
47
- "FdsPagination.nextPage": "Gå till nästa sida",
48
- "FdsPagination.previousPage": "Gå till föregående sida",
49
- "FdsPhonenumber.countryCode": "Landskod",
50
- "FdsPhonenumber.invalidPhone": "Ange ett giltigt telefonnummer",
51
- "FdsPhonenumber.noCountryResults": "Inget land matchar sökningen",
52
- "FdsPhonenumber.phoneNumber": "Telefonnummer",
53
- "FdsSearchSelectPro.loadingMore": "Hämtar fler...",
54
- "FdsSearchSelectPro.showMore": "Visa fler",
55
- "FdsSearchSelectPro.unspecified": "Ospecificerat",
56
- "FdsTextarea.characters": "tecken",
57
- "FdsTreeView.childrenCountPrefix": "(+",
58
- "FdsTreeView.closePopover": "Stäng",
59
- "FdsTreeView.collapseNode": "Fäll ihop {title}",
60
- "FdsTreeView.expandNode": "Fäll ut {title}",
61
- "FdsTreeView.moreOptionsForNode": "Fler val för {title}",
62
- "FdsWeekCalendar.nextWeek": "Nästa vecka",
63
- "FdsWeekCalendar.previousWeek": "Föregående vecka",
64
- "FdsWeekCalendar.today": "Idag",
65
- "FdsWeekCalendar.week": "vecka",
66
- "FdsDevMode.overlay.toggles.apiError": "API-fel",
67
- "FdsDevMode.overlay.toggles.debugLogging": "Debug-logg",
68
- "FdsDevMode.overlay.quickSettings": "Snabbval"
69
- }
70
- ;
71
-
72
- export default _default;