fds-vue-core 6.2.12 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/fds-vue-core.cjs.js +145 -85
  2. package/dist/fds-vue-core.cjs.js.map +1 -1
  3. package/dist/fds-vue-core.es.js +146 -86
  4. package/dist/fds-vue-core.es.js.map +1 -1
  5. package/dist/tsconfig.build.tsbuildinfo +1 -1
  6. package/package.json +1 -1
  7. package/src/components/Blocks/FdsBlockAlert/FdsBlockAlert.stories.ts +0 -3
  8. package/src/components/Blocks/FdsBlockAlert/FdsBlockAlert.vue +5 -4
  9. package/src/components/Blocks/FdsBlockAlert/types.ts +0 -1
  10. package/src/components/FdsModal/FdsModal.stories.ts +0 -4
  11. package/src/components/FdsModal/FdsModal.vue +3 -2
  12. package/src/components/FdsModal/types.ts +0 -1
  13. package/src/components/FdsPagination/FdsPagination.vue +7 -6
  14. package/src/components/FdsPagination/types.ts +0 -1
  15. package/src/components/FdsSearchSelect/FdsSearchSelect.stories.ts +1 -8
  16. package/src/components/FdsSearchSelect/FdsSearchSelect.vue +0 -2
  17. package/src/components/FdsSearchSelect/types.ts +0 -1
  18. package/src/components/FdsSearchSelectPro/FdsSearchSelectPro.stories.ts +2 -9
  19. package/src/components/FdsSearchSelectPro/FdsSearchSelectPro.vue +13 -8
  20. package/src/components/FdsSearchSelectPro/types.ts +1 -3
  21. package/src/components/FdsSearchSelectPro/useSearchSelectProItems.ts +8 -5
  22. package/src/components/Form/FdsInput/FdsInput.stories.ts +20 -6
  23. package/src/components/Form/FdsInput/FdsInput.vue +21 -5
  24. package/src/components/Form/FdsInput/types.ts +0 -1
  25. package/src/components/Typography/FdsListHeading/FdsListHeading.stories.ts +0 -3
  26. package/src/components/Typography/FdsListHeading/FdsListHeading.vue +4 -3
  27. package/src/components/Typography/FdsListHeading/types.ts +0 -1
  28. package/src/lang/en.json +19 -0
  29. package/src/lang/sv.json +19 -0
@@ -36,6 +36,86 @@ function useHasSlot(name = "default") {
36
36
  return vnodes.some((vnode) => vnode.type !== vue.Comment);
37
37
  });
38
38
  }
39
+ const en = {
40
+ "FdsBlockAlert.close": "Close",
41
+ "FdsBlockAlert.showLess": "Show less",
42
+ "FdsBlockAlert.showMore": "Show more",
43
+ "FdsInput.clearInput": "Clear input",
44
+ "FdsInput.hidePassword": "Hide",
45
+ "FdsInput.openDatePicker": "Open date picker",
46
+ "FdsInput.showPassword": "Show",
47
+ "FdsInput.today": "(today)",
48
+ "FdsListHeading.loading": "Loading...",
49
+ "FdsListHeading.separator": "of",
50
+ "FdsModal.closeModal": "Close modal window",
51
+ "FdsPagination.currentPage": "Current page",
52
+ "FdsPagination.firstPage": "Go to first page",
53
+ "FdsPagination.lastPage": "Go to last page",
54
+ "FdsPagination.nextPage": "Go to next page",
55
+ "FdsPagination.previousPage": "Go to previous page",
56
+ "FdsSearchSelectPro.loadingMore": "Loading more...",
57
+ "FdsSearchSelectPro.showMore": "Show more",
58
+ "FdsSearchSelectPro.unspecified": "Unspecified",
59
+ "FdsWeekCalendar.nextWeek": "Next week",
60
+ "FdsWeekCalendar.previousWeek": "Previous week",
61
+ "FdsWeekCalendar.today": "Today",
62
+ "FdsWeekCalendar.week": "week"
63
+ };
64
+ const sv = {
65
+ "FdsBlockAlert.close": "Stäng",
66
+ "FdsBlockAlert.showLess": "Visa mindre",
67
+ "FdsBlockAlert.showMore": "Visa mer",
68
+ "FdsInput.clearInput": "Rensa input",
69
+ "FdsInput.hidePassword": "Dölj",
70
+ "FdsInput.openDatePicker": "Öppna datumväljare",
71
+ "FdsInput.showPassword": "Visa",
72
+ "FdsInput.today": "(idag)",
73
+ "FdsListHeading.loading": "Laddar...",
74
+ "FdsListHeading.separator": "av",
75
+ "FdsModal.closeModal": "Stäng dialogruta",
76
+ "FdsPagination.currentPage": "Aktuell sida",
77
+ "FdsPagination.firstPage": "Gå till första sidan",
78
+ "FdsPagination.lastPage": "Gå till sista sidan",
79
+ "FdsPagination.nextPage": "Gå till nästa sida",
80
+ "FdsPagination.previousPage": "Gå till föregående sida",
81
+ "FdsSearchSelectPro.loadingMore": "Hämtar fler...",
82
+ "FdsSearchSelectPro.showMore": "Visa fler",
83
+ "FdsSearchSelectPro.unspecified": "Ospecificerat",
84
+ "FdsWeekCalendar.nextWeek": "Nästa vecka",
85
+ "FdsWeekCalendar.previousWeek": "Föregående vecka",
86
+ "FdsWeekCalendar.today": "Idag",
87
+ "FdsWeekCalendar.week": "vecka"
88
+ };
89
+ const FDS_VUE_CORE_I18N_KEY = /* @__PURE__ */ Symbol("fds-vue-core:i18n");
90
+ const translations = {
91
+ en,
92
+ sv
93
+ };
94
+ const useFdsI18n = () => {
95
+ const i18n = vue.inject(FDS_VUE_CORE_I18N_KEY, void 0);
96
+ const locale = vue.computed(() => {
97
+ const locale2 = i18n?.global?.locale ?? i18n?.locale;
98
+ if (typeof locale2 === "string") return locale2;
99
+ if (locale2 && typeof locale2 === "object" && "value" in locale2 && typeof locale2.value === "string") {
100
+ return locale2.value;
101
+ }
102
+ return "sv-SE";
103
+ });
104
+ const activeLanguage = vue.computed(() => locale.value.toLowerCase().split("-")[0]);
105
+ const dictionary = vue.computed(() => {
106
+ const currentDictionary = translations[activeLanguage.value];
107
+ return currentDictionary ?? translations.sv;
108
+ });
109
+ const t = (key) => {
110
+ const value = dictionary.value[key];
111
+ return typeof value === "string" ? value : "";
112
+ };
113
+ return {
114
+ i18n,
115
+ locale,
116
+ t
117
+ };
118
+ };
39
119
  const icons = {
40
120
  addCircle: () => `
41
121
  <svg viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
@@ -654,7 +734,6 @@ const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
654
734
  collapsable: { type: Boolean, default: false },
655
735
  expanded: { type: Boolean, default: false },
656
736
  heading: { default: void 0 },
657
- locale: { default: "sv" },
658
737
  icon: {},
659
738
  dataTestid: { default: void 0 }
660
739
  },
@@ -662,12 +741,13 @@ const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
662
741
  setup(__props, { emit: __emit }) {
663
742
  const props = __props;
664
743
  const { id } = useAttrsWithDefaults(props);
744
+ const { t } = useFdsI18n();
665
745
  const emit = __emit;
666
746
  const isExpanded = vue.ref(props.expanded);
667
747
  const isVisible = vue.ref(props.visible);
668
- const expandLabel = vue.computed(() => props.locale === "sv" ? "Visa mer" : "Show more");
669
- const collapseLabel = vue.computed(() => props.locale === "sv" ? "Visa mindre" : "Show less");
670
- const closeLabel = vue.computed(() => props.locale === "sv" ? "Stäng" : "Close");
748
+ const expandLabel = vue.computed(() => t("FdsBlockAlert.showMore"));
749
+ const collapseLabel = vue.computed(() => t("FdsBlockAlert.showLess"));
750
+ const closeLabel = vue.computed(() => t("FdsBlockAlert.close"));
671
751
  const hasSlot = useHasSlot();
672
752
  vue.watch(
673
753
  () => props.visible,
@@ -1016,7 +1096,7 @@ const _hoisted_10$3 = { class: "flex items-start justify-between gap-4" };
1016
1096
  const _hoisted_11$3 = { class: "flex items-center gap-3" };
1017
1097
  const _hoisted_12$2 = { class: "m-0 text-base font-main font-bold tracking-wide" };
1018
1098
  const _hoisted_13$2 = { class: "flex items-start gap-3" };
1019
- const _hoisted_14$1 = { class: "mb-0-last-child" };
1099
+ const _hoisted_14$2 = { class: "mb-0-last-child" };
1020
1100
  const smallIconSize = 24;
1021
1101
  const largeIconSize = 48;
1022
1102
  const _sfc_main$D = /* @__PURE__ */ vue.defineComponent({
@@ -1090,7 +1170,7 @@ const _sfc_main$D = /* @__PURE__ */ vue.defineComponent({
1090
1170
  ])
1091
1171
  ])
1092
1172
  ], 2)) : vue.createCommentVNode("", true),
1093
- vue.createElementVNode("div", _hoisted_14$1, [
1173
+ vue.createElementVNode("div", _hoisted_14$2, [
1094
1174
  vue.renderSlot(_ctx.$slots, "default")
1095
1175
  ])
1096
1176
  ]))
@@ -4928,7 +5008,6 @@ const _sfc_main$u = /* @__PURE__ */ vue.defineComponent({
4928
5008
  movable: { type: Boolean, default: false },
4929
5009
  resizable: { type: Boolean, default: false },
4930
5010
  info: { default: void 0 },
4931
- locale: { default: "sv" },
4932
5011
  dataTestid: { default: void 0 },
4933
5012
  onClose: {}
4934
5013
  },
@@ -4940,6 +5019,7 @@ const _sfc_main$u = /* @__PURE__ */ vue.defineComponent({
4940
5019
  let cleanupFocusTrap = null;
4941
5020
  const previouslyFocusedElement = vue.ref(null);
4942
5021
  const hasFooterSlot = useHasSlot("modal-footer");
5022
+ const { t } = useFdsI18n();
4943
5023
  const modalInnerRef = vue.ref(null);
4944
5024
  const {
4945
5025
  isCustomPositioned,
@@ -4993,7 +5073,7 @@ const _sfc_main$u = /* @__PURE__ */ vue.defineComponent({
4993
5073
  "fill-yellow-600": props.info === "warning"
4994
5074
  }
4995
5075
  ]);
4996
- const closeLabel = vue.computed(() => props.locale === "sv" ? "Stäng dialogruta" : "Close modal window");
5076
+ const closeLabel = vue.computed(() => t("FdsModal.closeModal"));
4997
5077
  const footerClasses = vue.computed(() => [
4998
5078
  "mt-6 flex flex-col gap-4 left-0 right-0",
4999
5079
  {
@@ -8484,7 +8564,6 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
8484
8564
  invalidMessage: {},
8485
8565
  labelLeft: { type: Boolean, default: false },
8486
8566
  clearButton: { type: Boolean, default: false },
8487
- locale: { default: "sv" },
8488
8567
  mask: { default: void 0 },
8489
8568
  modelValue: {},
8490
8569
  value: { default: void 0 },
@@ -8526,6 +8605,7 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
8526
8605
  const props = __props;
8527
8606
  const emit = __emit;
8528
8607
  const { id, type, maxlength, attrs } = useAttrsWithDefaults(props);
8608
+ const { t } = useFdsI18n();
8529
8609
  const inputType = vue.computed(() => type.value ?? props.type ?? "text");
8530
8610
  const autoId = `fds-input-${Math.random().toString(36).slice(2, 9)}`;
8531
8611
  const inputId = vue.computed(() => id.value ?? autoId);
@@ -8554,10 +8634,11 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
8554
8634
  "data-testid": props.dataTestid ?? void 0
8555
8635
  };
8556
8636
  });
8557
- const clearButtonLabel = vue.computed(() => props.locale === "sv" ? "Rensa input" : "Clear input");
8558
- const passwordButtonShowLabel = vue.computed(() => props.locale === "sv" ? "Visa" : "Show");
8559
- const passwordButtonHideLabel = vue.computed(() => props.locale === "sv" ? "Dölj" : "Hide");
8560
- const dateButtonLabel = vue.computed(() => props.locale === "sv" ? "Öppna datumväljare" : "Open date picker");
8637
+ const clearButtonLabel = vue.computed(() => t("FdsInput.clearInput"));
8638
+ const passwordButtonShowLabel = vue.computed(() => t("FdsInput.showPassword"));
8639
+ const passwordButtonHideLabel = vue.computed(() => t("FdsInput.hidePassword"));
8640
+ const dateButtonLabel = vue.computed(() => t("FdsInput.openDatePicker"));
8641
+ const todayLabel = vue.computed(() => t("FdsInput.today"));
8561
8642
  const showInvalidMessage = vue.computed(() => props.valid === false && !props.optional && props.invalidMessage);
8562
8643
  const isInvalid = vue.computed(() => props.valid === false && !props.optional && !props.disabled);
8563
8644
  const isValid2 = vue.computed(() => props.valid === true);
@@ -8567,6 +8648,17 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
8567
8648
  const showClearButton = vue.computed(() => props.clearButton && !!internalValue.value && !props.disabled);
8568
8649
  const showValidationIcon = vue.computed(() => isInvalid.value || isValid2.value);
8569
8650
  const showDateIcon = vue.computed(() => inputType.value === "date");
8651
+ const todayIsoDate = vue.computed(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
8652
+ const showTodaySuffixInField = vue.computed(
8653
+ () => inputType.value === "date" && String(internalValue.value ?? "") === todayIsoDate.value
8654
+ );
8655
+ const todaySuffixClasses = vue.computed(() => [
8656
+ "pointer-events-none absolute top-1/2 -translate-y-1/2 text-base leading-6",
8657
+ props.disabled ? "text-gray-800" : "text-gray-900"
8658
+ ]);
8659
+ const todaySuffixStyle = vue.computed(() => ({
8660
+ left: "calc(0.75rem + 10ch + 0.25rem)"
8661
+ }));
8570
8662
  const rightIconCount = vue.computed(() => {
8571
8663
  let count = 0;
8572
8664
  if (showDateIcon.value) count++;
@@ -8817,7 +8909,12 @@ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
8817
8909
  text: showPassword.value ? passwordButtonHideLabel.value : passwordButtonShowLabel.value,
8818
8910
  onClick: toggleShowPassword
8819
8911
  }, null, 8, ["icon", "text"])) : vue.createCommentVNode("", true)
8820
- ], 2)
8912
+ ], 2),
8913
+ showTodaySuffixInField.value ? (vue.openBlock(), vue.createElementBlock("span", {
8914
+ key: 0,
8915
+ class: vue.normalizeClass(todaySuffixClasses.value),
8916
+ style: vue.normalizeStyle(todaySuffixStyle.value)
8917
+ }, vue.toDisplayString(todayLabel.value), 7)) : vue.createCommentVNode("", true)
8821
8918
  ])
8822
8919
  ], 2)
8823
8920
  ], 2),
@@ -9002,7 +9099,7 @@ const _hoisted_13$1 = {
9002
9099
  key: 1,
9003
9100
  class: "max-h-72 overflow-auto border border-gray-200 rounded-md"
9004
9101
  };
9005
- const _hoisted_14 = { class: "w-full text-left text-xs border-collapse" };
9102
+ const _hoisted_14$1 = { class: "w-full text-left text-xs border-collapse" };
9006
9103
  const _hoisted_15 = ["onClick"];
9007
9104
  const _hoisted_16 = { class: "py-1.5 px-3 font-mono break-all" };
9008
9105
  const _hoisted_17 = { class: "py-1.5 px-3 font-mono whitespace-pre-wrap break-all" };
@@ -9344,7 +9441,7 @@ const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
9344
9441
  }, {
9345
9442
  default: vue.withCtx(() => [
9346
9443
  !sessionStorageEntries.value.length ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_12$1, "Inga värden i sessionStorage.")) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_13$1, [
9347
- vue.createElementVNode("table", _hoisted_14, [
9444
+ vue.createElementVNode("table", _hoisted_14$1, [
9348
9445
  _cache[15] || (_cache[15] = vue.createElementVNode("thead", { class: "bg-gray-50" }, [
9349
9446
  vue.createElementVNode("tr", null, [
9350
9447
  vue.createElementVNode("th", { class: "py-2 px-3 font-semibold" }, "Nyckel"),
@@ -9690,7 +9787,6 @@ const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
9690
9787
  current: {},
9691
9788
  max: {},
9692
9789
  loading: { type: Boolean, default: false },
9693
- locale: { default: "sv" },
9694
9790
  dataTestid: { default: void 0 },
9695
9791
  onPaginate: {}
9696
9792
  },
@@ -9698,6 +9794,7 @@ const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
9698
9794
  setup(__props, { emit: __emit }) {
9699
9795
  const props = __props;
9700
9796
  const { id } = useAttrsWithDefaults(props);
9797
+ const { t } = useFdsI18n();
9701
9798
  const emit = __emit;
9702
9799
  const loadingIndicator = vue.ref("");
9703
9800
  const internalValue = vue.ref(props.current);
@@ -9711,11 +9808,11 @@ const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
9711
9808
  return attrs;
9712
9809
  });
9713
9810
  const inputValue = vue.computed(() => String(internalValue.value));
9714
- const nextPageLabel = vue.computed(() => props.locale === "sv" ? "Gå till nästa sida" : "Go to next page");
9715
- const prevPageLabel = vue.computed(() => props.locale === "sv" ? "Gå till föregående sida" : "Go to previous page");
9716
- const firstPageLabel = vue.computed(() => props.locale === "sv" ? "Gå till första sidan" : "Go to first page");
9717
- const lastPageLabel = vue.computed(() => props.locale === "sv" ? "Gå till sista sidan" : "Go to last page");
9718
- const inputAriaLabel = vue.computed(() => props.locale === "sv" ? "Aktuell sida" : "Current page");
9811
+ const nextPageLabel = vue.computed(() => t("FdsPagination.nextPage"));
9812
+ const prevPageLabel = vue.computed(() => t("FdsPagination.previousPage"));
9813
+ const firstPageLabel = vue.computed(() => t("FdsPagination.firstPage"));
9814
+ const lastPageLabel = vue.computed(() => t("FdsPagination.lastPage"));
9815
+ const inputAriaLabel = vue.computed(() => t("FdsPagination.currentPage"));
9719
9816
  vue.watch(
9720
9817
  () => props.current,
9721
9818
  (newValue) => {
@@ -10131,7 +10228,6 @@ const _sfc_main$k = /* @__PURE__ */ vue.defineComponent({
10131
10228
  borderless: { type: Boolean, default: false },
10132
10229
  marginless: { type: Boolean, default: false },
10133
10230
  maxListHeight: { default: void 0 },
10134
- locale: { default: "sv" },
10135
10231
  clearTrigger: { type: Boolean, default: false },
10136
10232
  dataTestid: { default: void 0 },
10137
10233
  onChange: {},
@@ -10532,7 +10628,6 @@ const _sfc_main$k = /* @__PURE__ */ vue.defineComponent({
10532
10628
  valid: valid.value,
10533
10629
  invalidMessage: __props.invalidMessage,
10534
10630
  disabled: __props.disabled,
10535
- locale: __props.locale,
10536
10631
  type: "search",
10537
10632
  value: searchTerm.value,
10538
10633
  id: inputId,
@@ -10543,7 +10638,7 @@ const _sfc_main$k = /* @__PURE__ */ vue.defineComponent({
10543
10638
  searchIcon: !__props.disabled && !hasInputValue.value,
10544
10639
  onInput: handleInput,
10545
10640
  onClearInput: handleClear
10546
- }), null, 16, ["label", "meta", "labelLeft", "valid", "invalidMessage", "disabled", "locale", "value", "clearButton", "mask", "searchIcon"])
10641
+ }), null, 16, ["label", "meta", "labelLeft", "valid", "invalidMessage", "disabled", "value", "clearButton", "mask", "searchIcon"])
10547
10642
  ])
10548
10643
  ])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$7, [
10549
10644
  vue.createElementVNode("div", _hoisted_5$7, vue.toDisplayString(__props.singleItemLabel), 1),
@@ -10943,9 +11038,11 @@ const useSearchSelectProItems = ({
10943
11038
  isMultiple,
10944
11039
  isPid
10945
11040
  }) => {
11041
+ const { locale: activeLocale, t } = useFdsI18n();
10946
11042
  const matchingItems = vue.ref([]);
10947
11043
  const displayedItems = vue.ref([]);
10948
11044
  const visibleItemsLimit = vue.ref(props.maxItems && props.maxItems > 0 ? props.maxItems : null);
11045
+ const resolvedLocale = vue.computed(() => activeLocale.value.toLowerCase().startsWith("en") ? "en" : "sv");
10949
11046
  const toStableValue = (value) => {
10950
11047
  if (Array.isArray(value)) {
10951
11048
  return value.map((item) => toStableValue(item));
@@ -11021,7 +11118,7 @@ const useSearchSelectProItems = ({
11021
11118
  const reorderExplicitDividerGroups = (items, locale) => {
11022
11119
  const dividerLabelField = searchFields.value[0] ?? "label";
11023
11120
  const unspecifiedGroupKey = "__UNSPECIFIED__";
11024
- const defaultUnspecifiedLabel = locale === "sv" ? "Ospecificerat" : "Unspecified";
11121
+ const defaultUnspecifiedLabel = t("FdsSearchSelectPro.unspecified");
11025
11122
  const unspecifiedLabel = String(props.unspecifiedLabel ?? "").trim() || defaultUnspecifiedLabel;
11026
11123
  const isUnspecifiedDividerLabel = (raw) => {
11027
11124
  const trimmed = raw.trim();
@@ -11029,7 +11126,7 @@ const useSearchSelectProItems = ({
11029
11126
  const lower = trimmed.toLowerCase();
11030
11127
  if (lower === unspecifiedGroupKey.toLowerCase()) return true;
11031
11128
  const candidates = new Set(
11032
- [unspecifiedLabel, defaultUnspecifiedLabel, "Ospecificerat", "Unspecified"].map((s) => s.trim().toLowerCase()).filter(Boolean)
11129
+ [unspecifiedLabel, defaultUnspecifiedLabel].map((s) => s.trim().toLowerCase()).filter(Boolean)
11033
11130
  );
11034
11131
  return candidates.has(lower);
11035
11132
  };
@@ -11075,13 +11172,13 @@ const useSearchSelectProItems = ({
11075
11172
  const dividerField2 = props.dividerField ?? "isDivider";
11076
11173
  const hasExplicitDividers = baseItems.some((item) => item[dividerField2] === true || item.type === "divider");
11077
11174
  if (!hasExplicitDividers) return baseItems;
11078
- const locale2 = props.locale === "sv" ? "sv" : "en";
11175
+ const locale2 = resolvedLocale.value;
11079
11176
  return reorderExplicitDividerGroups(baseItems, locale2);
11080
11177
  }
11081
11178
  const dividerField = props.dividerField ?? "isDivider";
11082
11179
  const levelField = props.levelField ?? "level";
11083
- const locale = props.locale === "sv" ? "sv" : "en";
11084
- const defaultUnspecifiedLabel = locale === "sv" ? "Ospecificerat" : "Unspecified";
11180
+ const locale = resolvedLocale.value;
11181
+ const defaultUnspecifiedLabel = t("FdsSearchSelectPro.unspecified");
11085
11182
  const unspecifiedLabel = String(props.unspecifiedLabel ?? "").trim() || defaultUnspecifiedLabel;
11086
11183
  const grouped = /* @__PURE__ */ new Map();
11087
11184
  const groupLabels = /* @__PURE__ */ new Map();
@@ -11282,6 +11379,7 @@ const _hoisted_12 = {
11282
11379
  class: "block m-0 list-none p-0"
11283
11380
  };
11284
11381
  const _hoisted_13 = { class: "p-3 flex items-center gap-2" };
11382
+ const _hoisted_14 = { key: 0 };
11285
11383
  const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11286
11384
  __name: "FdsSearchSelectPro",
11287
11385
  props: {
@@ -11325,7 +11423,6 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11325
11423
  invalidMessage: { default: "" },
11326
11424
  noResultPrompt: { default: "" },
11327
11425
  maxListHeight: { default: void 0 },
11328
- locale: { default: "sv" },
11329
11426
  unspecifiedLabel: { default: void 0 },
11330
11427
  dataTestid: { default: void 0 },
11331
11428
  onChange: {},
@@ -11340,6 +11437,7 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11340
11437
  setup(__props, { expose: __expose, emit: __emit }) {
11341
11438
  const props = __props;
11342
11439
  const searchFields = vue.computed(() => props.searchFields ?? []);
11440
+ const { t } = useFdsI18n();
11343
11441
  const emit = __emit;
11344
11442
  const dropdownVisible = vue.ref(false);
11345
11443
  const searchTerm = vue.ref("");
@@ -11447,8 +11545,8 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11447
11545
  });
11448
11546
  };
11449
11547
  const hasInputValue = vue.computed(() => searchTerm.value.length > 0);
11450
- const resolvedLoadMoreLabel = vue.computed(() => props.locale === "sv" ? "Visa fler" : "Show more");
11451
- const resolvedLoadingMoreLabel = vue.computed(() => props.locale === "sv" ? "Hämtar fler..." : "Loading more...");
11548
+ const resolvedLoadMoreLabel = vue.computed(() => t("FdsSearchSelectPro.showMore"));
11549
+ const resolvedLoadingMoreLabel = vue.computed(() => t("FdsSearchSelectPro.loadingMore"));
11452
11550
  const displayInputValue = vue.computed(() => {
11453
11551
  if (!inputHasFocus.value && !hasSelection.value && !searchTerm.value.length && props.displayValue) {
11454
11552
  return props.displayValue;
@@ -11523,12 +11621,16 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11523
11621
  };
11524
11622
  let changeTimeout = null;
11525
11623
  let inputTimeout = null;
11624
+ const isDebouncingChange = vue.ref(false);
11625
+ const isSearching = vue.computed(() => isDebouncingChange.value || props.loading);
11526
11626
  const debouncedEmitChange = (value) => {
11527
11627
  if (changeTimeout) clearTimeout(changeTimeout);
11528
11628
  const delay = Math.max(0, props.debounceMs ?? 500);
11629
+ isDebouncingChange.value = true;
11529
11630
  changeTimeout = setTimeout(() => {
11530
11631
  const formattedValue = formatPidWithDash(value);
11531
11632
  emit("change", formattedValue);
11633
+ isDebouncingChange.value = false;
11532
11634
  }, delay);
11533
11635
  };
11534
11636
  const debouncedEmitInput = (ev) => {
@@ -11872,6 +11974,7 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11872
11974
  window.removeEventListener("mouseup", onClickOutside);
11873
11975
  if (changeTimeout) clearTimeout(changeTimeout);
11874
11976
  if (inputTimeout) clearTimeout(inputTimeout);
11977
+ isDebouncingChange.value = false;
11875
11978
  const input = getInputElement();
11876
11979
  if (input) {
11877
11980
  input.removeEventListener("keydown", handleInputKeyDown);
@@ -11933,7 +12036,6 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11933
12036
  valid: valid.value,
11934
12037
  invalidMessage: __props.invalidMessage,
11935
12038
  disabled: __props.disabled,
11936
- locale: __props.locale,
11937
12039
  type: "search",
11938
12040
  value: displayInputValue.value,
11939
12041
  id: inputId,
@@ -11941,10 +12043,10 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11941
12043
  mask: pidMask.value,
11942
12044
  maskOptions: { lazy: true }
11943
12045
  }, inputAriaAttrs.value, {
11944
- searchIcon: !__props.disabled && inputHasFocus.value && !hasInputValue.value && !hasSelection.value,
12046
+ searchIcon: !__props.disabled && !inputHasFocus.value && !hasInputValue.value && !hasSelection.value && !dropdownVisible.value,
11945
12047
  onInput: handleInput,
11946
12048
  onClearInput: handleClear
11947
- }), null, 16, ["label", "meta", "labelLeft", "valid", "invalidMessage", "disabled", "locale", "value", "clearButton", "mask", "searchIcon"])
12049
+ }), null, 16, ["label", "meta", "labelLeft", "valid", "invalidMessage", "disabled", "value", "clearButton", "mask", "searchIcon"])
11948
12050
  ])
11949
12051
  ]),
11950
12052
  dropdownVisible.value && !__props.disabled ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -11966,7 +12068,7 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
11966
12068
  ]),
11967
12069
  _: 1
11968
12070
  }),
11969
- __props.loading ? (vue.openBlock(), vue.createBlock(_sfc_main$B, {
12071
+ isSearching.value ? (vue.openBlock(), vue.createBlock(_sfc_main$B, {
11970
12072
  key: 0,
11971
12073
  color: "blue",
11972
12074
  size: "20px"
@@ -12072,9 +12174,9 @@ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
12072
12174
  ], 32)
12073
12175
  ], 64)) : (vue.openBlock(), vue.createElementBlock("ul", _hoisted_12, [
12074
12176
  vue.createElementVNode("li", _hoisted_13, [
12075
- vue.createElementVNode("span", null, vue.toDisplayString(__props.noResultPrompt), 1),
12076
- __props.loading ? (vue.openBlock(), vue.createBlock(_sfc_main$B, {
12077
- key: 0,
12177
+ !isSearching.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_14, vue.toDisplayString(__props.noResultPrompt), 1)) : vue.createCommentVNode("", true),
12178
+ isSearching.value ? (vue.openBlock(), vue.createBlock(_sfc_main$B, {
12179
+ key: 1,
12078
12180
  color: "blue",
12079
12181
  size: "20px"
12080
12182
  })) : vue.createCommentVNode("", true)
@@ -14630,48 +14732,6 @@ function subDays(date, amount, options) {
14630
14732
  function subWeeks(date, amount, options) {
14631
14733
  return addWeeks(date, -1, options);
14632
14734
  }
14633
- const en = {
14634
- "FdsWeekCalendar.nextWeek": "Next week",
14635
- "FdsWeekCalendar.previousWeek": "Previous week",
14636
- "FdsWeekCalendar.today": "Today",
14637
- "FdsWeekCalendar.week": "week"
14638
- };
14639
- const sv = {
14640
- "FdsWeekCalendar.nextWeek": "Nästa vecka",
14641
- "FdsWeekCalendar.previousWeek": "Föregående vecka",
14642
- "FdsWeekCalendar.today": "Idag",
14643
- "FdsWeekCalendar.week": "vecka"
14644
- };
14645
- const FDS_VUE_CORE_I18N_KEY = /* @__PURE__ */ Symbol("fds-vue-core:i18n");
14646
- const translations = {
14647
- en,
14648
- sv
14649
- };
14650
- const useFdsI18n = () => {
14651
- const i18n = vue.inject(FDS_VUE_CORE_I18N_KEY, void 0);
14652
- const locale = vue.computed(() => {
14653
- const locale2 = i18n?.global?.locale ?? i18n?.locale;
14654
- if (typeof locale2 === "string") return locale2;
14655
- if (locale2 && typeof locale2 === "object" && "value" in locale2 && typeof locale2.value === "string") {
14656
- return locale2.value;
14657
- }
14658
- return "sv-SE";
14659
- });
14660
- const activeLanguage = vue.computed(() => locale.value.toLowerCase().split("-")[0]);
14661
- const dictionary = vue.computed(() => {
14662
- const currentDictionary = translations[activeLanguage.value];
14663
- return currentDictionary ?? translations.sv;
14664
- });
14665
- const t = (key) => {
14666
- const value = dictionary.value[key];
14667
- return typeof value === "string" ? value : "";
14668
- };
14669
- return {
14670
- i18n,
14671
- locale,
14672
- t
14673
- };
14674
- };
14675
14735
  const capitalizeFirstLetter$1 = (value) => {
14676
14736
  if (!value) return value;
14677
14737
  return value.charAt(0).toUpperCase() + value.slice(1);
@@ -16064,12 +16124,12 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
16064
16124
  total: {},
16065
16125
  unfiltered: {},
16066
16126
  text: {},
16067
- language: { default: "sv" },
16068
16127
  dataTestid: { default: void 0 }
16069
16128
  },
16070
16129
  setup(__props) {
16071
16130
  const props = __props;
16072
16131
  const attrs = vue.useAttrs();
16132
+ const { t } = useFdsI18n();
16073
16133
  const consumerClass = vue.computed(() => classValueToString(attrs.class));
16074
16134
  const rootAttrs = vue.computed(() => {
16075
16135
  const result = { ...attrs };
@@ -16079,7 +16139,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
16079
16139
  }
16080
16140
  return result;
16081
16141
  });
16082
- const separatorText = () => props.language === "sv" ? "av" : "of";
16142
+ const separatorText = () => t("FdsListHeading.separator");
16083
16143
  const headingText = vue.computed(() => {
16084
16144
  if (!props.total) {
16085
16145
  let result = "0";
@@ -16101,7 +16161,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
16101
16161
  if (props.loadingText && props.loadingText.length > 0) {
16102
16162
  return props.loadingText;
16103
16163
  }
16104
- return props.language === "sv" ? "Laddar..." : "Loading...";
16164
+ return t("FdsListHeading.loading");
16105
16165
  };
16106
16166
  const wrapperClasses = vue.computed(() => {
16107
16167
  const baseClasses = "inline-block mb-3 h-7 font-bold text-xl";