@citizenplane/pimp 16.1.0 → 16.2.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 (60) hide show
  1. package/dist/pimp.es.js +474 -478
  2. package/dist/pimp.umd.js +3 -3
  3. package/dist/style.css +1 -1
  4. package/package.json +10 -9
  5. package/src/components/CpDate.vue +3 -1
  6. package/src/components/CpMultiselect.vue +2 -5
  7. package/src/components/CpTable.vue +4 -2
  8. package/src/components/CpTelInput.vue +18 -12
  9. package/src/components/CpToast.vue +1 -1
  10. package/src/components/CpTransitionExpand.vue +23 -20
  11. package/src/libs/CoreDatepicker.vue +1 -0
  12. package/src/stories/BaseInputLabel.stories.ts +1 -1
  13. package/src/stories/Colors.stories.ts +1 -1
  14. package/src/stories/CpAccordion.stories.ts +1 -1
  15. package/src/stories/CpAccordionGroup.stories.ts +1 -1
  16. package/src/stories/CpAirlineLogo.stories.ts +5 -2
  17. package/src/stories/CpAlert.stories.ts +1 -1
  18. package/src/stories/CpBadge.stories.ts +1 -1
  19. package/src/stories/CpButton.stories.ts +1 -1
  20. package/src/stories/CpCheckbox.stories.ts +1 -1
  21. package/src/stories/CpContextualMenu.stories.ts +5 -1
  22. package/src/stories/CpDate.stories.ts +1 -1
  23. package/src/stories/CpDatepicker.stories.ts +22 -18
  24. package/src/stories/CpDialog.stories.ts +1 -1
  25. package/src/stories/CpHeading.stories.ts +2 -1
  26. package/src/stories/CpIcon.stories.ts +1 -1
  27. package/src/stories/CpInput.stories.ts +22 -6
  28. package/src/stories/CpItemActions.stories.ts +20 -4
  29. package/src/stories/CpLoader.stories.ts +1 -1
  30. package/src/stories/CpMenuItem.stories.ts +1 -1
  31. package/src/stories/CpMultiselect.stories.ts +1 -1
  32. package/src/stories/CpPartnerBadge.stories.ts +5 -2
  33. package/src/stories/CpRadio.stories.ts +1 -1
  34. package/src/stories/CpRadioGroup.stories.ts +1 -1
  35. package/src/stories/CpSelect.stories.ts +18 -3
  36. package/src/stories/CpSelectMenu.stories.ts +64 -45
  37. package/src/stories/CpSelectableButton.stories.ts +1 -1
  38. package/src/stories/CpSwitch.stories.ts +1 -1
  39. package/src/stories/CpTable.stories.ts +15 -12
  40. package/src/stories/CpTableEmptyState.stories.ts +1 -1
  41. package/src/stories/CpTabs.stories.ts +1 -1
  42. package/src/stories/CpTelInput.stories.ts +13 -6
  43. package/src/stories/CpText.stories.ts +1 -1
  44. package/src/stories/CpTextarea.stories.ts +15 -4
  45. package/src/stories/CpToast.stories.ts +22 -6
  46. package/src/stories/CpTooltip.stories.ts +1 -1
  47. package/src/stories/CpTransitionCounter.stories.ts +1 -1
  48. package/src/stories/CpTransitionExpand.stories.ts +1 -1
  49. package/src/stories/CpTransitionListItems.stories.ts +1 -1
  50. package/src/stories/CpTransitionSize.stories.ts +1 -1
  51. package/src/stories/CpTransitionSlide.stories.ts +1 -1
  52. package/src/stories/CpTransitionTabContent.stories.ts +1 -1
  53. package/src/stories/Dimensions.stories.ts +1 -1
  54. package/src/stories/Easings.stories.ts +1 -1
  55. package/src/stories/FocusRings.stories.ts +1 -1
  56. package/src/stories/Shadows.stories.ts +1 -1
  57. package/src/stories/Typography.stories.ts +1 -1
  58. package/src/types/primevue-toasteventbus.d.ts +14 -0
  59. package/tsconfig.json +1 -0
  60. package/.lintstagedrc.json +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@citizenplane/pimp",
3
- "version": "16.1.0",
3
+ "version": "16.2.0",
4
4
  "scripts": {
5
5
  "dev": "storybook dev -p 8081",
6
6
  "build-storybook": "storybook build --output-dir ./docs",
@@ -11,6 +11,7 @@
11
11
  "lint:style:write": "stylelint \"**/*.{css,scss,vue}\" --fix",
12
12
  "format": "prettier . --write",
13
13
  "test": "jest tests",
14
+ "types": "vue-tsc --noEmit",
14
15
  "commitlint": "commitlint --edit",
15
16
  "prepare": "husky"
16
17
  },
@@ -48,12 +49,11 @@
48
49
  "@commitlint/cli": "20.4.2",
49
50
  "@eslint/eslintrc": "^3.3.3",
50
51
  "@eslint/js": "^9.39.2",
51
- "@storybook/addon-docs": "^9.1.20",
52
- "@storybook/addon-onboarding": "^9.1.17",
53
- "@storybook/addon-vitest": "^9.0.18",
52
+ "@storybook/addon-docs": "^10.3.5",
53
+ "@storybook/addon-onboarding": "^10.3.5",
54
+ "@storybook/addon-vitest": "^10.3.5",
54
55
  "@storybook/preset-scss": "^1.0.3",
55
- "@storybook/vue3": "^9.1.17",
56
- "@storybook/vue3-vite": "^9.1.17",
56
+ "@storybook/vue3-vite": "^10.3.5",
57
57
  "@stylistic/eslint-plugin": "^5.7.1",
58
58
  "@types/feather-icons": "^4.29.4",
59
59
  "@types/vue-tel-input": "^2.1.7",
@@ -71,7 +71,7 @@
71
71
  "eslint-config-prettier": "^10.1.8",
72
72
  "eslint-plugin-perfectionist": "^5.4.0",
73
73
  "eslint-plugin-prettier": "^5.5.5",
74
- "eslint-plugin-storybook": "^9.1.17",
74
+ "eslint-plugin-storybook": "^10.3.5",
75
75
  "eslint-plugin-vue": "^10.7.0",
76
76
  "globals": "^17.2.0",
77
77
  "husky": "^9.1.7",
@@ -82,11 +82,12 @@
82
82
  "prettier": "^3.6.2",
83
83
  "sass": "~1.97.3",
84
84
  "sass-loader": "^16.0.6",
85
- "storybook": "^9.1.17",
85
+ "storybook": "^10.3.5",
86
86
  "ts-jest": "^29.4.6",
87
87
  "typescript-eslint": "^8.54.0",
88
88
  "vite": "^7.3.1",
89
- "vitest": "^4.0.18"
89
+ "vitest": "^4.0.18",
90
+ "vue-tsc": "3.2.5"
90
91
  },
91
92
  "eslintConfig": {
92
93
  "extends": [
@@ -246,7 +246,9 @@ const selectDynamicClass = computed(() => {
246
246
  })
247
247
 
248
248
  const autocompleteFields = computed(() => {
249
- if (!props.autocompleteBirthday) return 'off'
249
+ if (!props.autocompleteBirthday) {
250
+ return { day: 'off', month: 'off', year: 'off' }
251
+ }
250
252
 
251
253
  return {
252
254
  day: 'bday-day',
@@ -166,11 +166,8 @@ const selectModel = computed({
166
166
  get() {
167
167
  return props.modelValue
168
168
  },
169
- set(value: string | object | string[] | null) {
170
- if (typeof value === 'string') {
171
- return
172
- }
173
-
169
+ set(value) {
170
+ if (typeof value === 'string') return
174
171
  emit('update:modelValue', value)
175
172
  },
176
173
  })
@@ -126,6 +126,8 @@
126
126
  <script setup lang="ts">
127
127
  import { ref, computed, useId, watch } from 'vue'
128
128
 
129
+ import type { MenuItemCommandEvent } from 'primevue/menuitem'
130
+
129
131
  import { CpTableColumnObject } from '@/constants/CpTableColumn'
130
132
 
131
133
  import CpContextualMenu from '@/components/CpContextualMenu.vue'
@@ -154,7 +156,7 @@ interface Pagination {
154
156
  }
155
157
 
156
158
  interface RowOptions {
157
- action: (rowData: Record<string, unknown>, $event: MouseEvent) => void
159
+ action: (rowData: Record<string, unknown>, $event: Event) => void
158
160
  icon: string
159
161
  id: string
160
162
  isAsync?: boolean
@@ -228,7 +230,7 @@ const currentRowData = ref<Record<string, unknown>>({})
228
230
  const contextualMenuItems = computed(() => {
229
231
  return props.rowOptions.map((option) => ({
230
232
  ...option,
231
- command: ({ originalEvent }: { originalEvent: MouseEvent }) => option.action(currentRowData.value, originalEvent),
233
+ command: (event: MenuItemCommandEvent) => option.action(currentRowData.value, event.originalEvent),
232
234
  }))
233
235
  })
234
236
 
@@ -41,7 +41,9 @@
41
41
  </template>
42
42
 
43
43
  <script setup lang="ts">
44
- import { useAttrs, ref, useId, computed, nextTick } from 'vue'
44
+ import { computed, nextTick, ref, useAttrs, useId, useTemplateRef } from 'vue'
45
+
46
+ import type { ComponentPublicInstance } from 'vue'
45
47
 
46
48
  import BaseInputLabel from '@/components/BaseInputLabel.vue'
47
49
 
@@ -97,7 +99,13 @@ interface Emits {
97
99
  }
98
100
 
99
101
  const inputModel = defineModel<string>()
100
- const telInputRef = ref<HTMLInputElement | null>(null)
102
+
103
+ type VueTelInputInstance = ComponentPublicInstance & {
104
+ $el: HTMLElement
105
+ focus: VoidFunction
106
+ }
107
+
108
+ const telInputRefElement = useTemplateRef<VueTelInputInstance>('telInputRef')
101
109
 
102
110
  const helpMessageId = useId()
103
111
  const errorMessageId = useId()
@@ -139,27 +147,25 @@ const displayErrorMessage = computed(() => props.isInvalid && props.errorMessage
139
147
  const displayHelp = computed(() => props.help?.length && !displayErrorMessage.value)
140
148
 
141
149
  const focusOnInput = async () => {
142
- if (!telInputRef.value) return
143
- setTimeout(() => telInputRef.value?.focus(), 1)
150
+ if (!telInputRefElement.value) return
151
+ setTimeout(() => telInputRefElement.value?.focus(), 1)
144
152
  }
145
153
 
146
154
  const handleDropdownOpen = async () => {
147
- if (!telInputRef.value) return
155
+ if (!telInputRefElement.value) return
156
+
148
157
  await nextTick()
149
158
 
150
- const searchBox = telInputRef.value?.$el?.querySelector('input.vti__search_box')
159
+ const searchBox = telInputRefElement.value?.$el?.querySelector('input.vti__search_box')
160
+
151
161
  if (!searchBox) return
152
162
 
153
163
  setTimeout(() => searchBox.focus(), 1)
154
164
  }
155
165
 
156
- const handleCountryChanged = (country: { iso2: string }) => {
157
- emit('countryChanged', country?.iso2 || '')
158
- }
166
+ const handleCountryChanged = (country: { iso2: string }) => emit('countryChanged', country?.iso2 || '')
159
167
 
160
- const handleOnValidate = (phoneObject: PhoneObject) => {
161
- emit('validate', phoneObject)
162
- }
168
+ const handleOnValidate = (phoneObject: PhoneObject) => emit('validate', phoneObject)
163
169
  </script>
164
170
 
165
171
  <style lang="scss">
@@ -92,7 +92,7 @@ interface Message {
92
92
  summary: string
93
93
  }
94
94
 
95
- onMounted(() => ToastEventBus.on('add', handleToastAdded))
95
+ onMounted(() => ToastEventBus.on('add', (payload: unknown) => handleToastAdded(payload as Message)))
96
96
 
97
97
  const displayTimer = (message: Message) => message.showTimer && message.life !== undefined
98
98
 
@@ -1,47 +1,50 @@
1
1
  <template>
2
- <transition name="expand" @enter="enter" @after-enter="afterEnter" @leave="leave">
2
+ <transition name="expand" @after-enter="afterEnter" @enter="enter" @leave="leave">
3
3
  <slot />
4
4
  </transition>
5
5
  </template>
6
6
 
7
7
  <script setup lang="ts">
8
- const afterEnter = (element: HTMLElement): void => {
9
- element.style.height = `auto`
8
+ const afterEnter = (element: Element) => {
9
+ const el = element as HTMLElement
10
+ el.style.height = `auto`
10
11
  }
11
12
 
12
- const enter = (element: HTMLElement): void => {
13
- const { width } = getComputedStyle(element)
13
+ const enter = (element: Element) => {
14
+ const el = element as HTMLElement
15
+ const { width } = getComputedStyle(el)
14
16
 
15
- element.style.width = width
16
- element.style.position = `absolute`
17
- element.style.visibility = `hidden`
18
- element.style.height = `auto`
17
+ el.style.width = width
18
+ el.style.position = `absolute`
19
+ el.style.visibility = `hidden`
20
+ el.style.height = `auto`
19
21
 
20
- const { height } = getComputedStyle(element)
22
+ const { height } = getComputedStyle(el)
21
23
 
22
- element.style.width = ''
23
- element.style.position = ''
24
- element.style.visibility = ''
25
- element.style.height = '0'
24
+ el.style.width = ''
25
+ el.style.position = ''
26
+ el.style.visibility = ''
27
+ el.style.height = '0'
26
28
 
27
29
  // Force repaint to make sure the
28
30
  // animation is triggered correctly.
29
31
 
30
32
  // @typescript-eslint/no-unused-expressions
31
- void getComputedStyle(element).height
33
+ void getComputedStyle(el).height
32
34
 
33
- requestAnimationFrame(() => (element.style.height = height))
35
+ requestAnimationFrame(() => (el.style.height = height))
34
36
  }
35
37
 
36
- const leave = (element: HTMLElement): void => {
37
- const { height } = getComputedStyle(element)
38
+ const leave = (element: Element): void => {
39
+ const el = element as HTMLElement
40
+ const { height } = getComputedStyle(el)
38
41
 
39
- element.style.height = height
42
+ el.style.height = height
40
43
 
41
44
  // Force repaint to make sure the
42
45
  // animation is triggered correctly.
43
46
  requestAnimationFrame(() => {
44
- element.style.height = '0'
47
+ el.style.height = '0'
45
48
  })
46
49
  }
47
50
  </script>
@@ -127,6 +127,7 @@
127
127
  </template>
128
128
 
129
129
  <script lang="ts">
130
+ // @ts-nocheck — legacy Options API bundle; excluded from strict type-checking until a typed rewrite.
130
131
  import { DateTime, Info } from 'luxon'
131
132
  import { useId } from 'vue'
132
133
 
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import BaseInputLabel from '@/components/BaseInputLabel.vue'
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import { docLabelStyle } from '@/stories/documentationStyles'
4
4
  import type { Token } from '@/stories/tokenUtils'
@@ -1,6 +1,6 @@
1
1
  import { computed } from 'vue'
2
2
 
3
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
4
4
  import type { MenuItem } from 'primevue/menuitem'
5
5
 
6
6
  import type { CpAccordionBaseProps } from '@/components/CpAccordion.vue'
@@ -1,6 +1,6 @@
1
1
  import { computed } from 'vue'
2
2
 
3
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
4
4
  import type { MenuItem } from 'primevue/menuitem'
5
5
 
6
6
  import CpAccordion from '@/components/CpAccordion.vue'
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpAirlineLogo from '@/components/CpAirlineLogo.vue'
4
4
 
@@ -38,9 +38,12 @@ const meta = {
38
38
  } satisfies Meta<typeof CpAirlineLogo>
39
39
 
40
40
  export default meta
41
+
41
42
  type Story = StoryObj<typeof meta>
42
43
 
43
- const defaultRender = (args: Args) => ({
44
+ type AirlineLogoStoryArgs = NonNullable<Story['args']>
45
+
46
+ const defaultRender = (args: AirlineLogoStoryArgs) => ({
44
47
  components: { CpAirlineLogo },
45
48
  setup() {
46
49
  return { args }
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpAlert from '@/components/CpAlert.vue'
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpBadge from '@/components/CpBadge.vue'
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpButton from '@/components/CpButton.vue'
4
4
  import CpIcon from '@/components/CpIcon.vue'
@@ -1,6 +1,6 @@
1
1
  import { ref, computed } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpCheckbox from '@/components/CpCheckbox.vue'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { computed, ref } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpButton from '@/components/CpButton.vue'
6
6
  import CpContextualMenu from '@/components/CpContextualMenu.vue'
@@ -29,6 +29,7 @@ const meta = {
29
29
  } satisfies Meta<typeof CpContextualMenu>
30
30
 
31
31
  export default meta
32
+
32
33
  type Story = StoryObj<typeof meta>
33
34
 
34
35
  /**
@@ -36,6 +37,9 @@ type Story = StoryObj<typeof meta>
36
37
  * a separator and a critical "Delete" action.
37
38
  */
38
39
  export const Default: Story = {
40
+ args: {
41
+ items: [],
42
+ },
39
43
  render: () => ({
40
44
  components: { CpButton, CpContextualMenu },
41
45
  setup() {
@@ -1,6 +1,6 @@
1
1
  import { ref } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpDate from '@/components/CpDate.vue'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { ref } from 'vue'
2
2
 
3
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpDatepicker from '@/components/CpDatepicker.vue'
6
6
 
@@ -35,25 +35,29 @@ const meta = {
35
35
  } satisfies Meta<typeof CpDatepicker>
36
36
 
37
37
  export default meta
38
+
38
39
  type Story = StoryObj<typeof meta>
39
40
 
40
- const datepickerRender = (args: Args) => ({
41
+ type DatepickerStoryArgs = NonNullable<Story['args']>
42
+
43
+ const defaultTemplate = `
44
+ <div style="height: 35vh; max-width: 600px; padding: 20px;">
45
+ <CpDatepicker
46
+ v-bind="args"
47
+ @dates="(selectedDates) => dates = selectedDates"
48
+ />
49
+ </div>
50
+ `
51
+
52
+ const renderDatepicker = (args: DatepickerStoryArgs) => ({
41
53
  components: { CpDatepicker },
42
54
  setup() {
43
- const dates = ref([])
55
+ const dates = ref<string[]>([])
44
56
  return { args, dates }
45
57
  },
46
- template: `
47
- <div style="height: 35vh; max-width: 600px; padding: 20px;">
48
- <CpDatepicker v-bind="args" @dates="(selectedDates) => dates = selectedDates" />
49
- </div>
50
- `,
58
+ template: defaultTemplate,
51
59
  })
52
60
 
53
- /**
54
- * Default single-date picker. Use the controls to experiment with each
55
- * prop in isolation.
56
- */
57
61
  export const Default: Story = {
58
62
  args: {
59
63
  mode: 'single',
@@ -64,7 +68,7 @@ export const Default: Story = {
64
68
  isInline: false,
65
69
  singleMonth: false,
66
70
  },
67
- render: datepickerRender,
71
+ render: renderDatepicker,
68
72
  }
69
73
 
70
74
  /**
@@ -77,7 +81,7 @@ export const DateRange: Story = {
77
81
  label: 'Select Date Range',
78
82
  placeholder: 'Choose date range',
79
83
  },
80
- render: datepickerRender,
84
+ render: renderDatepicker,
81
85
  }
82
86
 
83
87
  /**
@@ -90,7 +94,7 @@ export const WithError: Story = {
90
94
  isError: true,
91
95
  errorMessage: 'Please select a valid date',
92
96
  },
93
- render: datepickerRender,
97
+ render: renderDatepicker,
94
98
  }
95
99
 
96
100
  /**
@@ -103,7 +107,7 @@ export const WithInitialDates: Story = {
103
107
  initDateOne: '2024-03-15',
104
108
  label: 'Datepicker with Initial Date',
105
109
  },
106
- render: datepickerRender,
110
+ render: renderDatepicker,
107
111
  }
108
112
 
109
113
  /**
@@ -116,7 +120,7 @@ export const SingleMonth: Story = {
116
120
  singleMonth: true,
117
121
  label: 'Single Month View',
118
122
  },
119
- render: datepickerRender,
123
+ render: renderDatepicker,
120
124
  }
121
125
 
122
126
  /**
@@ -129,5 +133,5 @@ export const AllowPastDates: Story = {
129
133
  allowPastDates: true,
130
134
  label: 'Allow Past Dates',
131
135
  },
132
- render: datepickerRender,
136
+ render: renderDatepicker,
133
137
  }
@@ -1,6 +1,6 @@
1
1
  import { ref } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpDialog from '@/components/CpDialog.vue'
6
6
 
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpHeading from '@/components/CpHeading.vue'
4
4
 
@@ -36,6 +36,7 @@ const meta = {
36
36
  } satisfies Meta<typeof CpHeading>
37
37
 
38
38
  export default meta
39
+
39
40
  type Story = StoryObj<typeof meta>
40
41
 
41
42
  /**
@@ -1,4 +1,4 @@
1
- import type { Args, Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpIcon from '@/components/CpIcon.vue'
4
4
 
@@ -1,12 +1,23 @@
1
1
  import { ref } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { ComponentPropsAndSlots, Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpIcon from '@/components/CpIcon.vue'
6
6
  import CpInput from '@/components/CpInput.vue'
7
7
 
8
8
  import { docCellStyle, docLabelStyle, docRowColumnStyle } from '@/stories/documentationStyles'
9
9
 
10
+ /** Native attributes forwarded to the inner `<input>` (not declared as Vue props). */
11
+ type CpInputPassthroughAttrs = {
12
+ autocomplete?: string
13
+ disabled?: boolean
14
+ placeholder?: string
15
+ required?: boolean
16
+ type?: string
17
+ }
18
+
19
+ type CpInputStoryArgs = ComponentPropsAndSlots<typeof CpInput> & CpInputPassthroughAttrs
20
+
10
21
  const inputSizes = ['sm', 'md', 'lg'] as const
11
22
  const inputTypes = ['text', 'email', 'password', 'number', 'tel', 'url'] as const
12
23
 
@@ -59,10 +70,15 @@ const meta = {
59
70
  description: 'Autocomplete attribute value',
60
71
  },
61
72
  },
62
- } satisfies Meta<typeof CpInput>
73
+ } satisfies Meta<CpInputStoryArgs>
63
74
 
64
75
  export default meta
65
- type Story = StoryObj<typeof meta>
76
+
77
+ // Use explicit args type: `StoryObj<typeof meta>` would re-infer args from `component` only
78
+ // and drop native attributes passed through `$attrs`.
79
+ type Story = StoryObj<CpInputStoryArgs>
80
+
81
+ type StoryArgs = Partial<CpInputStoryArgs>
66
82
 
67
83
  /**
68
84
  * Default input. Use the controls to experiment with each prop in isolation.
@@ -82,7 +98,7 @@ export const Default: Story = {
82
98
  isSearch: false,
83
99
  help: '',
84
100
  },
85
- render: (args) => ({
101
+ render: (args: StoryArgs) => ({
86
102
  components: { CpInput },
87
103
  setup() {
88
104
  const value = ref('')
@@ -249,7 +265,7 @@ export const Mask: Story = {
249
265
  */
250
266
  export const WithIcon: Story = {
251
267
  args: { ...Default.args },
252
- render: (args) => ({
268
+ render: (args: StoryArgs) => ({
253
269
  components: { CpInput, CpIcon },
254
270
  setup() {
255
271
  const value = ref('')
@@ -276,7 +292,7 @@ export const WithIcon: Story = {
276
292
  */
277
293
  export const WithUnits: Story = {
278
294
  args: { ...Default.args },
279
- render: (args) => ({
295
+ render: (args: StoryArgs) => ({
280
296
  components: { CpInput },
281
297
  setup() {
282
298
  const value = ref('')
@@ -1,6 +1,6 @@
1
1
  import { ref } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
  import type { MenuItem } from 'primevue/menuitem'
5
5
 
6
6
  import CpItemActions from '@/components/CpItemActions.vue'
@@ -25,13 +25,29 @@ type Story = StoryObj<typeof meta>
25
25
  * still opening the menu on the trigger button.
26
26
  */
27
27
  export const Default: Story = {
28
+ args: {
29
+ actions: [],
30
+ },
28
31
  render: () => ({
29
32
  components: { CpItemActions },
30
33
  setup() {
31
34
  const actions = ref<MenuItem[]>([
32
- { icon: 'edit', label: 'Action 1', command: () => alert('Action 1 clicked') },
33
- { icon: 'download', label: 'Action 3', command: () => alert('Action 3 clicked') },
34
- { icon: 'trash-2', label: 'Action 2', command: () => alert('Action 2 clicked'), isCritical: true },
35
+ {
36
+ icon: 'edit',
37
+ label: 'Action 1',
38
+ command: () => alert('Action 1 clicked'),
39
+ },
40
+ {
41
+ icon: 'download',
42
+ label: 'Action 3',
43
+ command: () => alert('Action 3 clicked'),
44
+ },
45
+ {
46
+ icon: 'trash-2',
47
+ label: 'Action 2',
48
+ command: () => alert('Action 2 clicked'),
49
+ isCritical: true,
50
+ },
35
51
  ])
36
52
 
37
53
  const listItems = [1, 2, 3, 4]
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpLoader from '@/components/CpLoader.vue'
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpMenuItem from '@/components/CpMenuItem.vue'
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { ref, toValue } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpMultiselect from '@/components/CpMultiselect.vue'
6
6