Skip to content

Commit 4756774

Browse files
committed
refactor: centralize forwarded input attrs
1 parent 4f21329 commit 4756774

File tree

3 files changed

+74
-64
lines changed

3 files changed

+74
-64
lines changed

src/components/shared/BaseNumberInput.vue

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import BaseInputFrame from './BaseInputFrame.vue'
3-
import { computed, useAttrs, useId } from 'vue'
3+
import { useForwardInputAttrs } from './useForwardInputAttrs'
4+
import { computed, useId } from 'vue'
45
56
defineOptions({ inheritAttrs: false })
67
@@ -38,37 +39,13 @@ const emit = defineEmits<{
3839
(e: 'input' | 'change', value: Event): void
3940
}>()
4041
41-
const attrs = useAttrs()
42-
const containerClass = computed(() => attrs.class)
43-
const containerStyle = computed(() => attrs.style)
44-
const describedByAttr = computed(
45-
() => attrs['aria-describedby'] as string | undefined
46-
)
47-
48-
const baseForwardedAttrs = computed<Record<string, unknown>>(() => {
49-
const rest = { ...(attrs as Record<string, unknown>) }
50-
delete rest.class
51-
delete rest.style
52-
delete rest['aria-describedby']
53-
return rest
54-
})
55-
56-
const isListenerAttr = (key: string) => /^on[A-Z]/.test(key)
57-
58-
const frameAttrs = computed(() =>
59-
Object.fromEntries(
60-
Object.entries(baseForwardedAttrs.value).filter(
61-
([key]) => !isListenerAttr(key)
62-
)
63-
)
64-
)
65-
66-
const inputAttrs = computed<Record<string, unknown>>(() => {
67-
const rest = { ...baseForwardedAttrs.value }
68-
delete rest.id
69-
delete rest.value
70-
return rest
71-
})
42+
const {
43+
containerClass,
44+
containerStyle,
45+
describedByAttr,
46+
frameAttrs,
47+
inputAttrs
48+
} = useForwardInputAttrs()
7249
7350
const generatedId = useId()
7451
const inputId = computed(() => props.id ?? generatedId)

src/components/shared/BaseTextInput.vue

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import BaseInputFrame from './BaseInputFrame.vue'
3-
import { computed, useAttrs, useId } from 'vue'
3+
import { useForwardInputAttrs } from './useForwardInputAttrs'
4+
import { computed, useId } from 'vue'
45
56
defineOptions({ inheritAttrs: false })
67
@@ -46,37 +47,13 @@ const emit = defineEmits<{
4647
(e: 'input' | 'change', value: Event): void
4748
}>()
4849
49-
const attrs = useAttrs()
50-
const containerClass = computed(() => attrs.class)
51-
const containerStyle = computed(() => attrs.style)
52-
const describedByAttr = computed(
53-
() => attrs['aria-describedby'] as string | undefined
54-
)
55-
56-
const baseForwardedAttrs = computed<Record<string, unknown>>(() => {
57-
const rest = { ...(attrs as Record<string, unknown>) }
58-
delete rest.class
59-
delete rest.style
60-
delete rest['aria-describedby']
61-
return rest
62-
})
63-
64-
const isListenerAttr = (key: string) => /^on[A-Z]/.test(key)
65-
66-
const frameAttrs = computed(() =>
67-
Object.fromEntries(
68-
Object.entries(baseForwardedAttrs.value).filter(
69-
([key]) => !isListenerAttr(key)
70-
)
71-
)
72-
)
73-
74-
const inputAttrs = computed<Record<string, unknown>>(() => {
75-
const rest = { ...baseForwardedAttrs.value }
76-
delete rest.id
77-
delete rest.value
78-
return rest
79-
})
50+
const {
51+
containerClass,
52+
containerStyle,
53+
describedByAttr,
54+
frameAttrs,
55+
inputAttrs
56+
} = useForwardInputAttrs()
8057
8158
const generatedId = useId()
8259
const inputId = computed(() => props.id ?? generatedId)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { computed, useAttrs } from 'vue'
2+
3+
type Attrs = Record<string, unknown>
4+
5+
const listenerPattern = /^on[A-Z]/
6+
const frameSpecificKeys = new Set(['role', 'tabindex'])
7+
8+
const shouldStayOnFrame = (key: string) =>
9+
key.startsWith('data-') ||
10+
key.startsWith('aria-') ||
11+
frameSpecificKeys.has(key)
12+
13+
export const useForwardInputAttrs = () => {
14+
const attrs = useAttrs()
15+
16+
const containerClass = computed(() => attrs.class)
17+
const containerStyle = computed(() => attrs.style)
18+
const describedByAttr = computed(
19+
() => attrs['aria-describedby'] as string | undefined
20+
)
21+
22+
const baseForwardedAttrs = computed<Attrs>(() => {
23+
const rest = { ...(attrs as Attrs) }
24+
delete rest.class
25+
delete rest.style
26+
delete rest['aria-describedby']
27+
return rest
28+
})
29+
30+
const frameAttrs = computed<Attrs>(() =>
31+
Object.fromEntries(
32+
Object.entries(baseForwardedAttrs.value).filter(([key]) => {
33+
if (listenerPattern.test(key)) return false
34+
return shouldStayOnFrame(key)
35+
})
36+
)
37+
)
38+
39+
const inputAttrs = computed<Attrs>(() =>
40+
Object.fromEntries(
41+
Object.entries(baseForwardedAttrs.value).filter(([key]) => {
42+
if (listenerPattern.test(key)) return false
43+
if (shouldStayOnFrame(key)) return false
44+
return key !== 'id' && key !== 'value'
45+
})
46+
)
47+
)
48+
49+
return {
50+
containerClass,
51+
containerStyle,
52+
describedByAttr,
53+
frameAttrs,
54+
inputAttrs
55+
}
56+
}

0 commit comments

Comments
 (0)