fds-vue-core 2.1.10 → 2.1.15

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 (71) hide show
  1. package/components.d.ts +5 -3
  2. package/dist/fds-vue-core.cjs.js +174 -79
  3. package/dist/fds-vue-core.cjs.js.map +1 -1
  4. package/dist/fds-vue-core.es.js +175 -80
  5. package/dist/fds-vue-core.es.js.map +1 -1
  6. package/package.json +12 -12
  7. package/src/components/Blocks/FdsBlockAlert/FdsBlockAlert.stories.ts +60 -33
  8. package/src/components/Blocks/FdsBlockAlert/FdsBlockAlert.vue +5 -1
  9. package/src/components/Blocks/FdsBlockContent/FdsBlockContent.stories.ts +44 -41
  10. package/src/components/Blocks/FdsBlockExpander/FdsBlockExpander.stories.ts +33 -30
  11. package/src/components/Blocks/FdsBlockExpander/FdsBlockExpander.vue +51 -16
  12. package/src/components/Blocks/FdsBlockExpander/types.ts +2 -0
  13. package/src/components/Blocks/FdsBlockInfo/FdsBlockInfo.stories.ts +42 -39
  14. package/src/components/Blocks/FdsBlockLink/FdsBlockLink.stories.ts +42 -39
  15. package/src/components/Blocks/FdsBlockLink/FdsBlockLink.vue +13 -1
  16. package/src/components/Blocks/FdsBlockLink/types.ts +2 -0
  17. package/src/components/Buttons/ButtonBaseProps.ts +5 -0
  18. package/src/components/Buttons/FdsButtonCopy/FdsButtonCopy.stories.ts +1 -1
  19. package/src/components/Buttons/FdsButtonCopy/types.ts +1 -0
  20. package/src/components/Buttons/FdsButtonDownload/FdsButtonDownload.stories.ts +4 -4
  21. package/src/components/Buttons/FdsButtonDownload/FdsButtonDownload.vue +14 -16
  22. package/src/components/Buttons/FdsButtonDownload/types.ts +22 -0
  23. package/src/components/Buttons/FdsButtonIcon/FdsButtonIcon.stories.ts +2 -2
  24. package/src/components/Buttons/FdsButtonIcon/FdsButtonIcon.vue +1 -1
  25. package/src/components/Buttons/FdsButtonIcon/types.ts +1 -0
  26. package/src/components/Buttons/FdsButtonMinor/FdsButtonMinor.stories.ts +2 -2
  27. package/src/components/Buttons/FdsButtonMinor/FdsButtonMinor.vue +4 -1
  28. package/src/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.stories.ts +4 -4
  29. package/src/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.stories.ts +2 -2
  30. package/src/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.vue +1 -1
  31. package/src/components/FdsIcon/FdsIcon.stories.ts +1 -1
  32. package/src/components/FdsModal/FdsModal.stories.ts +7 -7
  33. package/src/components/FdsModal/FdsModal.vue +6 -1
  34. package/src/components/FdsModal/types.ts +1 -0
  35. package/src/components/FdsPagination/FdsPagination.stories.ts +5 -5
  36. package/src/components/FdsPagination/types.ts +3 -0
  37. package/src/components/FdsSearchSelect/FdsSearchSelect.stories.ts +9 -9
  38. package/src/components/FdsSearchSelect/FdsSearchSelect.vue +7 -30
  39. package/src/components/FdsSearchSelect/types.ts +7 -0
  40. package/src/components/FdsSpinner/FdsSpinner.stories.ts +1 -1
  41. package/src/components/FdsSticker/FdsSticker.stories.ts +23 -20
  42. package/src/components/FdsSticker/FdsSticker.vue +6 -5
  43. package/src/components/FdsTreeView/FdsTreeView.stories.ts +1 -1
  44. package/src/components/FdsTreeView/types.ts +4 -1
  45. package/src/components/FdsTruncatedText/FdsTruncatedText.stories.ts +4 -4
  46. package/src/components/FdsTruncatedText/FdsTruncatedText.vue +6 -7
  47. package/src/components/Form/FdsCheckbox/FdsCheckbox.stories.ts +4 -4
  48. package/src/components/Form/FdsCheckbox/FdsCheckbox.vue +6 -6
  49. package/src/components/Form/FdsCheckbox/types.ts +2 -0
  50. package/src/components/Form/FdsInput/FdsInput.stories.ts +5 -5
  51. package/src/components/Form/FdsInput/FdsInput.vue +14 -19
  52. package/src/components/Form/FdsInput/types.ts +4 -0
  53. package/src/components/Form/FdsRadio/FdsRadio.stories.ts +1 -1
  54. package/src/components/Form/FdsRadio/FdsRadio.vue +6 -6
  55. package/src/components/Form/FdsRadio/types.ts +1 -0
  56. package/src/components/Form/FdsSelect/FdsSelect.stories.ts +4 -4
  57. package/src/components/Form/FdsSelect/FdsSelect.vue +5 -1
  58. package/src/components/Form/FdsTextarea/FdsTextarea.stories.ts +2 -2
  59. package/src/components/Table/FdsTable/FdsTable.stories.ts +3 -3
  60. package/src/components/Table/FdsTableHead/FdsTableHead.stories.ts +6 -6
  61. package/src/components/Table/FdsTableHead/FdsTableHead.vue +9 -15
  62. package/src/components/Table/FdsTableHead/types.ts +1 -0
  63. package/src/components/Tabs/FdsTabs/FdsTabs.stories.ts +9 -9
  64. package/src/components/Tabs/FdsTabs/FdsTabs.vue +5 -1
  65. package/src/components/Tabs/FdsTabsItem/FdsTabsItem.vue +26 -2
  66. package/src/components/Tabs/FdsTabsItem/types.ts +2 -0
  67. package/src/components/Typography/FdsText/FdsText.stories.ts +14 -14
  68. package/src/components/Typography/FdsText/FdsText.vue +18 -2
  69. package/src/components/Typography/FdsText/types.ts +1 -0
  70. package/src/index.ts +1 -1
  71. package/src/.DS_Store +0 -0
@@ -158,7 +158,7 @@ const mockItems = [
158
158
  ]
159
159
 
160
160
  export const WithItems: Story = {
161
- render: (args) => ({
161
+ render: (args: Story['args']) => ({
162
162
  components: { FdsSearchSelect },
163
163
  setup: () => {
164
164
  const selected = ref<Record<string, unknown> | null>(null)
@@ -184,7 +184,7 @@ export const WithItems: Story = {
184
184
  }
185
185
 
186
186
  export const WithSelectedEarlier: Story = {
187
- render: (args) => ({
187
+ render: (args: Story['args']) => ({
188
188
  components: { FdsSearchSelect },
189
189
  setup: () => {
190
190
  const selected = ref<Record<string, unknown> | null>(null)
@@ -209,7 +209,7 @@ export const WithSelectedEarlier: Story = {
209
209
  }
210
210
 
211
211
  export const SingleOrganization: Story = {
212
- render: (args) => ({
212
+ render: (args: Story['args']) => ({
213
213
  components: { FdsSearchSelect },
214
214
  setup: () => {
215
215
  const selected = ref<Record<string, unknown> | null>(null)
@@ -240,7 +240,7 @@ export const SingleOrganization: Story = {
240
240
  }
241
241
 
242
242
  export const WithValidation: Story = {
243
- render: (args) => ({
243
+ render: (args: Story['args']) => ({
244
244
  components: { FdsSearchSelect },
245
245
  setup: () => {
246
246
  const selected = ref<Record<string, unknown> | null>(null)
@@ -268,7 +268,7 @@ export const WithValidation: Story = {
268
268
  }
269
269
 
270
270
  export const WithLabelLeft: Story = {
271
- render: (args) => ({
271
+ render: (args: Story['args']) => ({
272
272
  components: { FdsSearchSelect },
273
273
  setup: () => {
274
274
  const selected = ref<Record<string, unknown> | null>(null)
@@ -296,7 +296,7 @@ export const WithLabelLeft: Story = {
296
296
  }
297
297
 
298
298
  export const WithAbsoluteList: Story = {
299
- render: (args) => ({
299
+ render: (args: Story['args']) => ({
300
300
  components: { FdsSearchSelect },
301
301
  setup: () => {
302
302
  const selected = ref<Record<string, unknown> | null>(null)
@@ -323,7 +323,7 @@ export const WithAbsoluteList: Story = {
323
323
  }
324
324
 
325
325
  export const Disabled: Story = {
326
- render: (args) => ({
326
+ render: (args: Story['args']) => ({
327
327
  components: { FdsSearchSelect },
328
328
  setup: () => ({ args }),
329
329
  template: '<FdsSearchSelect v-bind="args" :items="args.items" />',
@@ -336,7 +336,7 @@ export const Disabled: Story = {
336
336
  }
337
337
 
338
338
  export const EnglishLocale: Story = {
339
- render: (args) => ({
339
+ render: (args: Story['args']) => ({
340
340
  components: { FdsSearchSelect },
341
341
  setup: () => {
342
342
  const selected = ref<Record<string, unknown> | null>(null)
@@ -368,7 +368,7 @@ export const EnglishLocale: Story = {
368
368
  }
369
369
 
370
370
  export const WithPagination: Story = {
371
- render: (args) => ({
371
+ render: (args: Story['args']) => ({
372
372
  components: { FdsSearchSelect },
373
373
  setup: () => {
374
374
  const selected = ref<Record<string, unknown> | null>(null)
@@ -479,15 +479,9 @@ onBeforeUnmount(() => {
479
479
  </script>
480
480
 
481
481
  <template>
482
- <div
483
- ref="componentRef"
484
- class="fds-search-select block mb-6"
485
- >
482
+ <div ref="componentRef" class="fds-search-select block mb-6">
486
483
  <div class="relative block">
487
- <div
488
- v-if="!singleItemName.length"
489
- class="relative"
490
- >
484
+ <div v-if="!singleItemName.length" class="relative">
491
485
  <div class="relative">
492
486
  <FdsInput
493
487
  :label="label"
@@ -530,14 +524,8 @@ onBeforeUnmount(() => {
530
524
  aria-controls="select-dropdown"
531
525
  >
532
526
  <!-- Loading -->
533
- <div
534
- v-if="loading"
535
- class="flex justify-center p-4"
536
- >
537
- <FdsSpinner
538
- color="blue"
539
- size="48px"
540
- />
527
+ <div v-if="loading" class="flex justify-center p-4">
528
+ <FdsSpinner color="blue" size="48px" />
541
529
  </div>
542
530
 
543
531
  <!-- Results -->
@@ -550,20 +538,12 @@ onBeforeUnmount(() => {
550
538
  {{ displayedItems.length }} {{ searchContext.linkWord }} {{ totalCount }}
551
539
  {{ searchContext.context }}
552
540
  </div>
553
- <div
554
- v-else-if="!searchTerm.length"
555
- class="block m-0 font-light p-4 border-b border-gray-200 rounded-t-md"
556
- >
541
+ <div v-else-if="!searchTerm.length" class="block m-0 font-light p-4 border-b border-gray-200 rounded-t-md">
557
542
  {{ totalCount }} {{ searchContext.context }}
558
543
  </div>
559
544
 
560
545
  <!-- List -->
561
- <ul
562
- class="block m-0 list-none p-0"
563
- role="listbox"
564
- id="select-dropdown"
565
- @keydown="handleListKeyDown"
566
- >
546
+ <ul class="block m-0 list-none p-0" role="listbox" id="select-dropdown" @keydown="handleListKeyDown">
567
547
  <li
568
548
  v-for="(item, index) in displayedItems"
569
549
  :key="index"
@@ -607,10 +587,7 @@ onBeforeUnmount(() => {
607
587
  </template>
608
588
 
609
589
  <!-- No Results -->
610
- <ul
611
- v-else-if="!loading"
612
- class="block m-0 list-none p-0"
613
- >
590
+ <ul v-else-if="!loading" class="block m-0 list-none p-0">
614
591
  <li class="p-4">
615
592
  {{ noResultPrompt }}
616
593
  </li>
@@ -22,4 +22,11 @@ export interface FdsSearchSelectProps {
22
22
  maxListHeight?: number | string
23
23
  locale?: 'sv' | 'en'
24
24
  clearTrigger?: boolean
25
+ onChange?: ((value: string) => void) | Array<(value: string) => void>
26
+ onSearchSelected?:
27
+ | ((value: Record<string, unknown> | null) => void)
28
+ | Array<(value: Record<string, unknown> | null) => void>
29
+ | ((val: Record<string, unknown>) => void)
30
+ onPaginate?: ((value: number) => void) | Array<(value: number) => void>
31
+ onTotal?: ((value: number) => void) | Array<(value: number) => void>
25
32
  }
@@ -23,7 +23,7 @@ export default meta
23
23
  type Story = StoryObj<typeof meta>
24
24
 
25
25
  export const Basic: Story = {
26
- render: (args) => ({
26
+ render: (args: Story['args']) => ({
27
27
  components: { FdsSpinner },
28
28
  setup: () => ({ args }),
29
29
  template: '<FdsSpinner v-bind="args" />',
@@ -1,10 +1,32 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
2
  import FdsSticker from './FdsSticker.vue'
3
3
 
4
+ const stickerTransform = (
5
+ _src: string,
6
+ storyContext: { args?: { variant?: string; bullet?: boolean; default?: string } },
7
+ ) => {
8
+ const args = storyContext?.args || {}
9
+ const attrs = []
10
+
11
+ if (args.variant && args.variant !== 'blue') attrs.push(`variant="${args.variant}"`)
12
+ if (args.bullet) attrs.push(`:bullet="true"`)
13
+
14
+ const attrsStr = attrs.length ? ` ${attrs.join(' ')}` : ''
15
+ const content = args.default || ''
16
+ return `<FdsSticker${attrsStr}>${content}</FdsSticker>`
17
+ }
18
+
4
19
  const meta: Meta<typeof FdsSticker> = {
5
20
  title: 'FDS/FdsSticker',
6
21
  component: FdsSticker,
7
22
  tags: ['autodocs'],
23
+ parameters: {
24
+ docs: {
25
+ source: {
26
+ transform: stickerTransform,
27
+ },
28
+ },
29
+ },
8
30
  argTypes: {
9
31
  variant: {
10
32
  control: { type: 'radio' },
@@ -27,31 +49,12 @@ const meta: Meta<typeof FdsSticker> = {
27
49
  export default meta
28
50
  type Story = StoryObj<typeof meta>
29
51
 
30
- const stickerTransform = (storyContext: { args?: { variant?: string; bullet?: boolean; default?: string } }) => {
31
- const args = storyContext?.args || {}
32
- const attrs = []
33
-
34
- if (args.variant && args.variant !== 'blue') attrs.push(`variant="${args.variant}"`)
35
- if (args.bullet) attrs.push(':bullet="true"')
36
-
37
- const attrsStr = attrs.length ? ` ${attrs.join(' ')}` : ''
38
- const content = args.default || ''
39
- return `<FdsSticker${attrsStr}>${content}</FdsSticker>`
40
- }
41
-
42
52
  export const Default: Story = {
43
- render: (args) => ({
53
+ render: (args: Story['args']) => ({
44
54
  components: { FdsSticker },
45
55
  setup: () => ({ args }),
46
56
  template: `<FdsSticker v-bind="args">{{ args.default }}</FdsSticker>`,
47
57
  }),
48
- parameters: {
49
- docs: {
50
- source: {
51
- transform: stickerTransform,
52
- },
53
- },
54
- },
55
58
  args: {
56
59
  variant: 'blue',
57
60
  default: 'Stick it!',
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed } from 'vue'
2
+ import { computed, type Slot } from 'vue'
3
3
  import type { FdsStickerProps } from './types'
4
4
 
5
5
  const props = withDefaults(defineProps<FdsStickerProps>(), {
@@ -31,14 +31,15 @@ const bulletDotClasses = computed(() => [
31
31
  props.variant === 'gray' && 'bg-gray-400',
32
32
  props.variant === 't_blue' && 'bg-blue-200 border border-blue-300',
33
33
  ])
34
+
35
+ defineSlots<{
36
+ default?: Slot
37
+ }>()
34
38
  </script>
35
39
 
36
40
  <template>
37
41
  <span :class="stickerClasses">
38
- <span
39
- v-if="bullet"
40
- :class="bulletDotClasses"
41
- ></span>
42
+ <span v-if="bullet" :class="bulletDotClasses"></span>
42
43
  <slot />
43
44
  </span>
44
45
  </template>
@@ -128,7 +128,7 @@ export default meta
128
128
  type Story = StoryObj<typeof meta>
129
129
 
130
130
  export const Basic: Story = {
131
- render: (args) => ({
131
+ render: (args: Story['args']) => ({
132
132
  components: { FdsTreeView },
133
133
  setup: () => ({ args }),
134
134
  template: '<FdsTreeView v-bind="args" />',
@@ -115,7 +115,10 @@ export interface FdsTreeViewProps<T = Record<string, unknown>> {
115
115
  titleTemplate?: string
116
116
 
117
117
  /** Get the height of the search container */
118
- getSearchContainerHeight?: () => number | undefined
118
+ onGetSearchContainerHeight?: number
119
+
120
+ /** Array of selected nodes */
121
+ selectedNodes?: FdsNodeShape<T>[]
119
122
  }
120
123
 
121
124
  /**
@@ -1,5 +1,5 @@
1
- import { ref } from 'vue'
2
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import { ref } from 'vue'
3
3
  import FdsTruncatedText from './FdsTruncatedText.vue'
4
4
 
5
5
  const meta: Meta<typeof FdsTruncatedText> = {
@@ -29,7 +29,7 @@ export default meta
29
29
  type Story = StoryObj<typeof meta>
30
30
 
31
31
  export const Default: Story = {
32
- render: (args) => ({
32
+ render: (args: NonNullable<Story['args']>) => ({
33
33
  components: { FdsTruncatedText },
34
34
  setup: () => {
35
35
  const open = ref(args.open)
@@ -43,7 +43,7 @@ export const Default: Story = {
43
43
  }
44
44
 
45
45
  export const WithSlot: Story = {
46
- render: (args) => ({
46
+ render: (args: NonNullable<Story['args']>) => ({
47
47
  components: { FdsTruncatedText },
48
48
  setup: () => {
49
49
  const open = ref(args.open)
@@ -61,7 +61,7 @@ export const WithSlot: Story = {
61
61
  }
62
62
 
63
63
  export const Open: Story = {
64
- render: (args) => ({
64
+ render: (args: NonNullable<Story['args']>) => ({
65
65
  components: { FdsTruncatedText },
66
66
  setup: () => {
67
67
  const open = ref(args.open)
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { computed, onMounted, ref, watch, type Slot } from 'vue'
2
3
  import { useHasSlot } from '../../composables/useHasSlots'
3
- import { computed, onMounted, ref, watch } from 'vue'
4
4
  import FdsButtonMinor from '../Buttons/FdsButtonMinor/FdsButtonMinor.vue'
5
5
  import type { FdsTruncatedTextProps } from './types'
6
6
 
@@ -54,6 +54,10 @@ onMounted(() => {
54
54
  }
55
55
  }
56
56
  })
57
+
58
+ defineSlots<{
59
+ default?: Slot
60
+ }>()
57
61
  </script>
58
62
 
59
63
  <template>
@@ -66,12 +70,7 @@ onMounted(() => {
66
70
  >
67
71
  <slot />
68
72
  </div>
69
- <div
70
- v-else
71
- ref="contentRef"
72
- :class="['content', { open: isOpen }]"
73
- :style="{ maxWidth: `${containerWidth}px` }"
74
- >
73
+ <div v-else ref="contentRef" :class="['content', { open: isOpen }]" :style="{ maxWidth: `${containerWidth}px` }">
75
74
  {{ content }}
76
75
  </div>
77
76
  <FdsButtonMinor
@@ -36,7 +36,7 @@ export const Default: Story = {
36
36
  checked: false,
37
37
  label: 'Checkbox label',
38
38
  },
39
- render: (args) => ({
39
+ render: (args: NonNullable<Story['args']>) => ({
40
40
  components: { FdsCheckbox },
41
41
  setup() {
42
42
  const checked = ref(args.checked)
@@ -65,7 +65,7 @@ export const Checked: Story = {
65
65
  args: {
66
66
  checked: true,
67
67
  },
68
- render: (args) => ({
68
+ render: (args: NonNullable<Story['args']>) => ({
69
69
  components: { FdsCheckbox },
70
70
  setup() {
71
71
  const checked = ref(args.checked)
@@ -97,7 +97,7 @@ export const Indeterminate: Story = {
97
97
  args: {
98
98
  indeterminate: true,
99
99
  },
100
- render: (args) => ({
100
+ render: (args: NonNullable<Story['args']>) => ({
101
101
  components: { FdsCheckbox },
102
102
  setup() {
103
103
  const checked = ref(args.checked)
@@ -130,7 +130,7 @@ export const Disabled: Story = {
130
130
  disabled: true,
131
131
  checked: true,
132
132
  },
133
- render: (args) => ({
133
+ render: (args: NonNullable<Story['args']>) => ({
134
134
  components: { FdsCheckbox },
135
135
  setup() {
136
136
  const checked = ref(args.checked)
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { computed, nextTick, watch, type Slot } from 'vue'
2
3
  import { useHasSlot } from '../../../composables/useHasSlots'
3
- import { computed, nextTick, watch } from 'vue'
4
4
  import type { FdsCheckboxProps } from './types'
5
5
 
6
6
  // Support v-model as boolean (single checkbox) or array (checkbox group)
@@ -119,15 +119,15 @@ watch(
119
119
  },
120
120
  { immediate: true },
121
121
  )
122
+
123
+ defineSlots<{
124
+ default?: Slot
125
+ }>()
122
126
  </script>
123
127
 
124
128
  <template>
125
129
  <div :class="wrapperClasses">
126
- <label
127
- :for="inputId"
128
- :class="[innerWrapperClasses, { 'cursor-not-allowed': disabled }]"
129
- v-bind="$attrs"
130
- >
130
+ <label :for="inputId" :class="[innerWrapperClasses, { 'cursor-not-allowed': disabled }]" v-bind="$attrs">
131
131
  <input
132
132
  :id="inputId"
133
133
  :name="name"
@@ -7,4 +7,6 @@ export interface FdsCheckboxProps {
7
7
  name?: string | undefined
8
8
  id?: string | undefined
9
9
  required?: boolean
10
+ modelValue?: boolean | Array<string | number>
11
+ onChange?: ((value: boolean) => void) | Array<(value: boolean) => void>
10
12
  }
@@ -112,7 +112,7 @@ export default meta
112
112
  type Story = StoryObj<typeof meta>
113
113
 
114
114
  export const Basic: Story = {
115
- render: (args) => ({
115
+ render: (args: Story['args']) => ({
116
116
  components: { FdsInput },
117
117
  setup: () => ({ args }),
118
118
  template: '<FdsInput v-bind="args" />',
@@ -140,7 +140,7 @@ export const WithVModel: Story = {
140
140
  }
141
141
 
142
142
  export const WithMeta: Story = {
143
- render: (args) => ({
143
+ render: (args: Story['args']) => ({
144
144
  components: { FdsInput },
145
145
  setup: () => ({ args }),
146
146
  template: '<FdsInput v-bind="args" meta="Detta är hjälptext som visas under labeln" />',
@@ -184,7 +184,7 @@ export const WithValidation: Story = {
184
184
  }
185
185
 
186
186
  export const Disabled: Story = {
187
- render: (args) => ({
187
+ render: (args: Story['args']) => ({
188
188
  components: { FdsInput },
189
189
  setup: () => ({ args }),
190
190
  template: '<FdsInput v-bind="args" />',
@@ -197,7 +197,7 @@ export const Disabled: Story = {
197
197
  }
198
198
 
199
199
  export const Required: Story = {
200
- render: (args) => ({
200
+ render: (args: Story['args']) => ({
201
201
  components: { FdsInput },
202
202
  setup: () => ({ args }),
203
203
  template: '<FdsInput v-bind="args" />',
@@ -210,7 +210,7 @@ export const Required: Story = {
210
210
  }
211
211
 
212
212
  export const WithLabelLeft: Story = {
213
- render: (args) => ({
213
+ render: (args: Story['args']) => ({
214
214
  components: { FdsInput },
215
215
  setup: () => ({ args }),
216
216
  template: '<FdsInput v-bind="args" />',
@@ -32,6 +32,8 @@ const emit = defineEmits<{
32
32
  (e: 'input', ev: Event): void
33
33
  (e: 'clearInput'): void
34
34
  (e: 'update:value', value: string): void
35
+ (e: 'keyup', ev: KeyboardEvent): void
36
+ (e: 'keyup.enter', ev: KeyboardEvent): void
35
37
  }>()
36
38
 
37
39
  const autoId = `fds-input-${Math.random().toString(36).slice(2, 9)}`
@@ -170,13 +172,10 @@ watch(
170
172
  :for="inputId"
171
173
  class="block font-bold text-gray-900 cursor-pointer"
172
174
  :class="{ 'mb-0': meta, 'mb-1': !meta }"
173
- >{{ label }}</label
174
- >
175
- <div
176
- v-if="meta"
177
- class="font-thin"
178
- :class="{ 'mb-1': !labelLeft }"
179
175
  >
176
+ {{ label }}
177
+ </label>
178
+ <div v-if="meta" class="font-thin" :class="{ 'mb-1': !labelLeft }">
180
179
  {{ meta }}
181
180
  </div>
182
181
  </div>
@@ -196,17 +195,16 @@ watch(
196
195
  :class="inputClasses"
197
196
  v-bind="$attrs"
198
197
  @input="$emit('input', $event)"
198
+ @keyup="
199
+ (ev) => {
200
+ $emit('keyup', ev)
201
+ if (ev.key === 'Enter') $emit('keyup.enter', ev)
202
+ }
203
+ "
199
204
  />
200
205
  <div :class="validationIconClasses">
201
- <FdsIcon
202
- v-if="isInvalid"
203
- name="alert"
204
- class="fill-red-600"
205
- />
206
- <FdsIcon
207
- v-if="isValid"
208
- name="bigSuccess"
209
- />
206
+ <FdsIcon v-if="isInvalid" name="alert" class="fill-red-600" />
207
+ <FdsIcon v-if="isValid" name="bigSuccess" />
210
208
  <FdsButtonIcon
211
209
  v-if="clearButton && !!internalValue && !disabled"
212
210
  icon="cross"
@@ -223,10 +221,7 @@ watch(
223
221
  </div>
224
222
  </div>
225
223
  </div>
226
- <div
227
- v-if="showInvalidMessage"
228
- class="text-red-600 font-bold mt-1"
229
- >
224
+ <div v-if="showInvalidMessage" class="text-red-600 font-bold mt-1">
230
225
  {{ invalidMessage }}
231
226
  </div>
232
227
  </div>
@@ -22,4 +22,8 @@ export interface FdsInputProps {
22
22
  placeholderChar?: string
23
23
  [key: string]: unknown
24
24
  }
25
+ modelValue?: string
26
+ onClearInput?: () => void
27
+ onKeyup?: ((value: KeyboardEvent) => void) | Array<(value: KeyboardEvent) => void>
28
+ onInput?: ((value: string | (Event & { target: HTMLInputElement })) => void) | ((value: Event) => void)
25
29
  }
@@ -28,7 +28,7 @@ export default meta
28
28
  type Story = StoryObj<typeof meta>
29
29
 
30
30
  export const Default: Story = {
31
- render: (args) => ({
31
+ render: (args: NonNullable<Story['args']>) => ({
32
32
  components: { FdsRadio },
33
33
  setup() {
34
34
  const checked = ref(args.checked)
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { computed, type Slot } from 'vue'
2
3
  import { useHasSlot } from '../../../composables/useHasSlots'
3
- import { computed } from 'vue'
4
4
  import type { FdsRadioProps } from './types'
5
5
 
6
6
  // Support v-model for selected value in a radio group (string|number)
@@ -51,15 +51,15 @@ const inputClasses = computed(() => [
51
51
  'peer z-2 bg-white min-w-[20px] min-h-[20px] focus-visible:outline-none rounded-full accent-blue-500',
52
52
  props.disabled && 'cursor-not-allowed',
53
53
  ])
54
+
55
+ defineSlots<{
56
+ default?: Slot
57
+ }>()
54
58
  </script>
55
59
 
56
60
  <template>
57
61
  <div :class="wrapperClasses">
58
- <label
59
- :for="inputId"
60
- :class="[innerWrapperClasses, { 'cursor-not-allowed': disabled }]"
61
- v-bind="$attrs"
62
- >
62
+ <label :for="inputId" :class="[innerWrapperClasses, { 'cursor-not-allowed': disabled }]" v-bind="$attrs">
63
63
  <input
64
64
  :id="inputId"
65
65
  :name="name"
@@ -6,6 +6,7 @@ export interface FdsRadioProps {
6
6
  name?: string
7
7
  id?: string
8
8
  required?: boolean
9
+ modelValue?: string | number | Array<string | number>
9
10
  onKeydown?: ((event: KeyboardEvent) => void) | Array<(event: KeyboardEvent) => void>
10
11
  onBlur?: ((event: FocusEvent) => void) | Array<(event: FocusEvent) => void>
11
12
  onChange?: ((event: Event) => void) | Array<(event: Event) => void>
@@ -37,7 +37,7 @@ export default meta
37
37
  type Story = StoryObj<typeof meta>
38
38
 
39
39
  export const Default: Story = {
40
- render: (args) => ({
40
+ render: (args: Story['args']) => ({
41
41
  components: { FdsSelect },
42
42
  setup: () => ({ args }),
43
43
  template: `<FdsSelect v-bind="args" />`,
@@ -46,7 +46,7 @@ export const Default: Story = {
46
46
 
47
47
  export const Disabled: Story = {
48
48
  args: { disabled: true },
49
- render: (args) => ({
49
+ render: (args: Story['args']) => ({
50
50
  components: { FdsSelect },
51
51
  setup: () => ({ args }),
52
52
  template: `<FdsSelect v-bind="args" />`,
@@ -58,7 +58,7 @@ export const Invalid: Story = {
58
58
  valid: 'false',
59
59
  invalidMessage: 'Välj ett giltigt alternativ',
60
60
  },
61
- render: (args) => ({
61
+ render: (args: Story['args']) => ({
62
62
  components: { FdsSelect },
63
63
  setup: () => ({ args }),
64
64
  template: `<FdsSelect v-bind="args" />`,
@@ -70,7 +70,7 @@ export const Valid: Story = {
70
70
  valid: 'true',
71
71
  modelValue: 'option1',
72
72
  },
73
- render: (args) => ({
73
+ render: (args: Story['args']) => ({
74
74
  components: { FdsSelect },
75
75
  setup: () => ({ args }),
76
76
  template: `<FdsSelect v-bind="args" />`,
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, useSlots } from 'vue'
2
+ import { computed, useSlots, type Slot } from 'vue'
3
3
  import FdsIcon from '../../FdsIcon/FdsIcon.vue'
4
4
  import type { FdsSelectProps } from './types'
5
5
 
@@ -64,6 +64,10 @@ function handleChange(ev: Event) {
64
64
  emit('change', ev)
65
65
  emit('input', ev)
66
66
  }
67
+
68
+ defineSlots<{
69
+ default?: Slot
70
+ }>()
67
71
  </script>
68
72
 
69
73
  <template>
@@ -35,7 +35,7 @@ export default meta
35
35
  type Story = StoryObj<typeof meta>
36
36
 
37
37
  export const Default: Story = {
38
- render: (args) => ({
38
+ render: (args: Story['args']) => ({
39
39
  components: { FdsTextarea },
40
40
  setup: () => ({ args }),
41
41
  template: `<FdsTextarea v-bind="args" />`,
@@ -44,7 +44,7 @@ export const Default: Story = {
44
44
 
45
45
  export const Disabled: Story = {
46
46
  args: { disabled: true },
47
- render: (args) => ({
47
+ render: (args: Story['args']) => ({
48
48
  components: { FdsTextarea },
49
49
  setup: () => ({ args }),
50
50
  template: `<FdsTextarea v-bind="args" />`,