Skip to content

Commit cc6aef3

Browse files
committed
chore: resolved ui-forms typescript errors
1 parent 8a8883d commit cc6aef3

File tree

18 files changed

+165
-104
lines changed

18 files changed

+165
-104
lines changed

packages/eslint-config-ripple/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
module.exports = {
22
parser: 'vue-eslint-parser',
3+
parserOptions: {
4+
parser: '@typescript-eslint/parser',
5+
ecmaFeatures: {
6+
jsx: false
7+
}
8+
},
39
env: {
410
browser: true,
511
node: true,

packages/ripple-ui-forms/cypress/support/component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ import { mount } from 'cypress/vue'
2828
import { h } from 'vue'
2929
import RplFauxForm from './components/RplFauxForm.vue'
3030
import { RplButton, RplIcon } from '@dpc-sdp/ripple-ui-core/vue'
31+
declare global {
32+
namespace Cypress {
33+
interface Chainable {
34+
/**
35+
* Custom command to mount a Vue component.
36+
* @example cy.mount(MyComponent)
37+
*/
38+
mount: typeof mount
39+
}
40+
}
41+
}
3142

3243
Cypress.on('uncaught:exception', (err) => {
3344
// https://stackoverflow.com/a/50387233 Ignore Resize observer loop
@@ -36,7 +47,7 @@ Cypress.on('uncaught:exception', (err) => {
3647
}
3748
})
3849

39-
Cypress.Commands.add('mount', (component, options = {}) => {
50+
Cypress.Commands.add('mount', ((component: any, options: any = {}) => {
4051
return mount(
4152
() => {
4253
return h(RplFauxForm, { component, componentProps: options.props })
@@ -49,7 +60,7 @@ Cypress.Commands.add('mount', (component, options = {}) => {
4960
}
5061
}
5162
)
52-
})
63+
}) as typeof mount)
5364

5465
// Example use:
5566
// cy.mount(MyComponent)

packages/ripple-ui-forms/src/components/RplForm/RplForm.vue

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import {
1717
type FormKitPlugin
1818
} from '@formkit/core'
1919
import { getValidationMessages } from '@formkit/validation'
20-
import { createMultiStepPlugin } from '@formkit/addons'
20+
import {
21+
type StepChangeData,
22+
type StepSlotData,
23+
createMultiStepPlugin
24+
} from '@formkit/addons'
2125
import rplFormInputs from '../../plugin'
2226
import RplFormAlert from '../RplFormAlert/RplFormAlert.vue'
2327
import RplFormSteps from '../RplFormSteps/RplFormSteps.vue'
@@ -26,6 +30,7 @@ import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
2630
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
2731
import { sanitisePIIFields } from '../../lib/sanitisePII'
2832
import useFormFocus from '../../composables/useFormFocus'
33+
import { RplFormKitStepNode } from '../../types'
2934
3035
interface Props {
3136
id: string
@@ -104,32 +109,29 @@ const stepsRef = ref(null)
104109
const serverMessageRef = ref(null)
105110
const errorSummaryRef = ref(null)
106111
const cachedErrors = ref<Record<string, CachedError>>({})
107-
const submitCounter = ref(0)
108-
const focusStepField = ref(null)
109-
const focusStepFromLabel = ref(null)
112+
const submitCounter = ref<number>(0)
113+
const focusStepField = ref<string | null>(null)
114+
const focusStepFromLabel = ref<string | null>(null)
110115
const stepsId = `${props.id}-steps`
111116
112-
const formSteps = computed(() => {
117+
const formSteps = computed<RplFormKitStepNode[]>(() => {
113118
if (!props.schema || !Array.isArray(props.schema)) return []
114119
115-
return props.schema.filter((i) => i['$step'])
120+
return props.schema.filter((item: unknown) => {
121+
return (<RplFormKitStepNode>item)['$step']
122+
}) as unknown as RplFormKitStepNode[]
116123
})
117124
const isLastStep = () => {
118-
return getNode(stepsId)?.context?.steps?.find((s) => s?.isActiveStep)
119-
?.isLastStep
125+
const currentNode = getNode(stepsId)
126+
const steps = (currentNode?.context?.steps || []) as StepSlotData[]
127+
return steps?.find((s) => s?.isActiveStep)?.isLastStep
120128
}
121129
const getFormNode = (node?: FormKitNode) => {
122130
return formSteps.value.length ? getNode(stepsId) : node || getNode(props.id)
123131
}
124-
interface Steps {
125-
findIndex: (arg0) => string
126-
find: (arg0) => { stepName: string }
127-
}
128-
const getStepEventData = (
129-
step: { stepIndex: number; stepName: string } = null
130-
) => {
132+
const getStepEventData = (step: StepSlotData | null = null) => {
131133
if (!formSteps.value.length) return {}
132-
const steps: Steps = getFormNode()?.context?.steps as Steps
134+
const steps: StepSlotData[] = getFormNode()?.context?.steps as StepSlotData[]
133135
134136
return {
135137
index: step
@@ -193,7 +195,9 @@ provide('onFormReset', onFormReset)
193195
const submitLabel =
194196
props.schema?.find((field) => field?.key === 'actions')?.label || 'Submit'
195197
196-
const getErrorMessages = (node: FormKitNode) => {
198+
const getErrorMessages = (node?: FormKitNode) => {
199+
if (!node) return {}
200+
197201
const validations = getValidationMessages(node)
198202
199203
const cachedErrorsMap = {}
@@ -211,7 +215,7 @@ const getErrorMessages = (node: FormKitNode) => {
211215
return cachedErrorsMap
212216
}
213217
214-
const submitHandler = (form, node: FormKitNode) => {
218+
const submitHandler = (form: any, node: FormKitNode) => {
215219
// If a user hits enter within a form field in a multistep form
216220
// we check if in there's a next step and if so navigate to that instead of submitting
217221
if (formSteps.value.length && !isLastStep()) {
@@ -296,7 +300,7 @@ const errorSummaryMessages = computed(() => {
296300
})
297301
298302
const rplFormConfig = ref({
299-
rootClasses: function (sectionKey) {
303+
rootClasses: function (sectionKey: string) {
300304
return {
301305
[`rpl-form__${sectionKey}`]: true
302306
}
@@ -383,7 +387,11 @@ const emitStepChange = (currentStep, targetStep, forwards) => {
383387
focusStepFromLabel.value = null
384388
}
385389
386-
const handleStepChange = async ({ currentStep, delta, targetStep }) => {
390+
const handleStepChange = async ({
391+
currentStep,
392+
delta,
393+
targetStep
394+
}: StepChangeData) => {
387395
const forwards = delta > 0
388396
let isStepValid = currentStep.isValid
389397

packages/ripple-ui-forms/src/components/RplFormActions/RplFormActions.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { computed, inject, onMounted } from 'vue'
44
import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
55
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
66
import { getCaptchaElementId } from '../../utils/getCaptchaElementId'
7+
import { IRplFormProvidedState } from '../../types'
78
89
interface Props {
910
id: string
@@ -49,7 +50,7 @@ const iconPosition = computed(() => {
4950
return undefined
5051
})
5152
52-
const form: object = inject('form')
53+
const form: IRplFormProvidedState | undefined = inject('form')
5354
const onCaptchaElementReady: (() => void) | undefined = inject(
5455
'onCaptchaElementReady'
5556
)

packages/ripple-ui-forms/src/components/RplFormDateSelect/RplFormDateSelect.vue

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
1212
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
1313
import { sanitisePIIField } from '../../lib/sanitisePII'
1414
15-
import VueDatePicker from '@vuepic/vue-datepicker'
15+
import VueDatePicker, { VueDatePickerProps } from '@vuepic/vue-datepicker'
1616
import '@vuepic/vue-datepicker/dist/main.css'
1717
1818
interface Props {
@@ -177,43 +177,45 @@ watch(
177177
)
178178
179179
// Vue-datepicker config
180-
const params = computed(() => ({
181-
enableTimePicker: false,
182-
disabled: props.disabled,
183-
name: props.name,
184-
id: props.id,
185-
format: 'd/MM/yyyy',
186-
placeholder: 'dd/mm/yyyy',
187-
dayNames: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
188-
locale: 'en-AU',
189-
offset: '0',
190-
hideOffsetDates: false,
191-
arrowNavigation: true,
192-
highlight:
193-
highlightedRange?.value?.length > 1 ? highlightedRange.value : undefined,
194-
markers: highlightedRange?.value?.length > 1 ? markers?.value : undefined,
195-
minDate:
196-
highlightedRange.value?.length > 0 &&
197-
props.minDate !== '' &&
198-
props.minDate !== undefined
199-
? parse(props.minDate, props.dateFormat, new Date())
200-
: null,
201-
maxDate:
202-
highlightedRange.value?.length > 0 &&
203-
props.maxDate !== '' &&
204-
props.maxDate !== undefined
205-
? parse(props.maxDate, props.dateFormat, new Date())
206-
: null,
207-
startDate: internalDate.value ? internalDate.value : undefined,
208-
autoApply: true,
209-
textInput: {
210-
format: 'd/M/yyyy',
211-
selectOnFocus: true
212-
},
213-
actionRow: {
214-
showPreview: false
215-
}
216-
}))
180+
const params = computed<VueDatePickerProps>(() => {
181+
return {
182+
enableTimePicker: false,
183+
disabled: props.disabled,
184+
name: props.name,
185+
id: props.id,
186+
format: 'd/MM/yyyy',
187+
placeholder: 'dd/mm/yyyy',
188+
dayNames: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
189+
locale: 'en-AU',
190+
offset: '0',
191+
hideOffsetDates: false,
192+
arrowNavigation: true,
193+
highlight:
194+
highlightedRange?.value?.length > 1 ? highlightedRange.value : undefined,
195+
markers: highlightedRange?.value?.length > 1 ? markers?.value : undefined,
196+
minDate:
197+
highlightedRange.value?.length > 0 &&
198+
props.minDate !== '' &&
199+
props.minDate !== undefined
200+
? parse(props.minDate, props.dateFormat, new Date())
201+
: null,
202+
maxDate:
203+
highlightedRange.value?.length > 0 &&
204+
props.maxDate !== '' &&
205+
props.maxDate !== undefined
206+
? parse(props.maxDate, props.dateFormat, new Date())
207+
: null,
208+
startDate: internalDate.value ? internalDate.value : undefined,
209+
autoApply: true,
210+
textInput: {
211+
format: 'd/M/yyyy',
212+
selectOnFocus: true
213+
},
214+
actionRow: {
215+
showPreview: false
216+
}
217+
} as VueDatePickerProps
218+
})
217219
218220
watch(internalDate, (updated) => {
219221
if (updated) {

packages/ripple-ui-forms/src/components/RplFormDropdown/RplFormDropdown.vue

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ export default {
55
</script>
66

77
<script setup lang="ts">
8-
import { computed, ref, watch, nextTick, inject, type Ref } from 'vue'
8+
import { computed, ref, watch, nextTick, inject } from 'vue'
99
import { onClickOutside, useDebounceFn } from '@vueuse/core'
1010
import useFormkitFriendlyEventEmitter from '../../composables/useFormkitFriendlyEventEmitter'
1111
import MultiValueLabel from './MultiValueLabel.vue'
1212
import MultiValueTagList from './MultiValueTagList.vue'
1313
import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
1414
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
1515
import { sanitisePIIField } from '../../lib/sanitisePII'
16+
import { IRplFormProvidedState } from '../../types'
1617
1718
export interface RplFormDropdownOption {
1819
id: string
@@ -75,7 +76,8 @@ const emit = defineEmits<{
7576
): void
7677
}>()
7778
78-
const form: object = inject('form', undefined)
79+
const form: IRplFormProvidedState | undefined = inject('form')
80+
7981
const { emitRplEvent } = useRippleEvent('rpl-form-dropdown', emit)
8082
8183
const defaultOptionId = '__default-option'
@@ -84,11 +86,11 @@ const containerRef = ref(null)
8486
const inputRef = ref(null)
8587
const menuRef = ref(null)
8688
const searchCache = ref('')
87-
const searchRef = ref<Ref<HTMLInputElement | null>>(null)
89+
const searchRef = ref<HTMLInputElement | null>(null)
8890
const searchValue = ref('')
8991
const searchFocused = ref(false)
9092
const filtering = ref(false)
91-
const toggleRef = ref<Ref<HTMLElement>>(null)
93+
const toggleRef = ref<HTMLElement | null>(null)
9294
const tagListRef = ref(null)
9395
const focusTag = ref(0)
9496
@@ -231,11 +233,15 @@ const handleSearchLeft = () => {
231233
}
232234
}
233235
234-
const handleSearchUpdate = (event: Event) => {
236+
const handleSearchUpdate = (event: InputEvent) => {
235237
filtering.value = true
236238
237239
// If the single search value is cleared the selected option should be cleared
238-
if (singleSearch.value && props.value && event.target?.value === '') {
240+
if (
241+
singleSearch.value &&
242+
props.value &&
243+
(<HTMLInputElement>event.target)?.value === ''
244+
) {
239245
useFormkitFriendlyEventEmitter(props, emit, 'onChange', null)
240246
}
241247
}

packages/ripple-ui-forms/src/components/RplFormInput/RplFormInput.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useDebounceFn } from '@vueuse/core'
1010
import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
1111
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
1212
import { sanitisePIIField } from '../../lib/sanitisePII'
13+
import { IRplFormProvidedState } from '../../types'
1314
1415
interface Props {
1516
id: string
@@ -65,7 +66,7 @@ const emit = defineEmits<{
6566
6667
const { emitRplEvent } = useRippleEvent('rpl-form-input', emit)
6768
68-
const form: object = inject('form')
69+
const form: IRplFormProvidedState | undefined = inject('form')
6970
7071
const classes = computed(() => {
7172
return {

packages/ripple-ui-forms/src/components/RplFormNumber/RplFormNumber.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import useFormkitFriendlyEventEmitter from '../../composables/useFormkitFriendly
1111
import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
1212
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
1313
import { sanitisePIIField } from '../../lib/sanitisePII'
14+
import { IRplFormProvidedState } from '../../types.js'
1415
1516
interface Props {
1617
id: string
@@ -63,7 +64,7 @@ const emit = defineEmits<{
6364
6465
const { emitRplEvent } = useRippleEvent('rpl-form-number', emit)
6566
66-
const form: any = inject('form')
67+
const form: IRplFormProvidedState | undefined = inject('form')
6768
6869
const classes = computed(() => {
6970
return {

packages/ripple-ui-forms/src/components/RplFormOptionButtons/RplFormOptionButtons.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { inject } from 'vue'
44
import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
55
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
66
import { sanitisePIIField } from '../../lib/sanitisePII'
7+
import { IRplFormProvidedState } from '../../types'
78
89
export interface Props {
910
id: string
@@ -37,7 +38,7 @@ const emit = defineEmits<{
3738
(e: 'update', payload: rplEventPayload & { action: 'update' }): void
3839
}>()
3940
40-
const form: object = inject('form')
41+
const form: IRplFormProvidedState | undefined = inject('form')
4142
const { emitRplEvent } = useRippleEvent('rpl-form-option-buttons', emit)
4243
4344
const handleChange = (selectedId: string) => {

packages/ripple-ui-forms/src/components/RplFormOptions/RplFormCheckboxGroup.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { inject } from 'vue'
55
import { useRippleEvent } from '@dpc-sdp/ripple-ui-core'
66
import type { rplEventPayload } from '@dpc-sdp/ripple-ui-core'
77
import { sanitisePIIField } from '../../lib/sanitisePII'
8+
import { IRplFormProvidedState } from '../../types'
89
910
interface Props {
1011
id: string
@@ -39,7 +40,7 @@ const emit = defineEmits<{
3940
(e: 'update', payload: rplEventPayload & { action: 'update' }): void
4041
}>()
4142
42-
const form: object = inject('form')
43+
const form: IRplFormProvidedState | undefined = inject('form')
4344
const { emitRplEvent } = useRippleEvent('rpl-form-checkbox-group', emit)
4445
4546
const handleToggle = (selectedValue: string) => {

0 commit comments

Comments
 (0)