fix(primitives): make v-model, native attributes and panel styling usable under strict TS
Publish to NPM / Check version changes and publish (push) Successful in 11m33s
Publish to NPM / Check version changes and publish (push) Successful in 11m33s
Consuming the package under `verbatimModuleSyntax` + `strictTemplates` surfaced four defects that forced workarounds downstream. - Drop the deprecated `SelectValue` string alias. It collided with the `SelectValue` component exported from the same barrel, so the component resolved to the type meaning and could not be imported (TS1484). - Narrow the select's model to `SelectModelValue<T, Multiple>` and make `TabsRoot` generic over its value, so a plain `v-model` on a `Ref<string>` type-checks. Both roots declare the value prop and emit explicitly instead of via `defineModel`, which would widen the payload with `| undefined` even though neither control ever clears its value. - Stop declaring `defineModel` keys in `defineEmits` as well. The duplicate erased the payload type from the generated declarations, shipping `(...args: unknown[]) => any` for eleven components' model events. - Let every part accept global DOM attributes (`id`, `role`, `aria-*`, `data-*`, ...) through `PrimitiveAttributes`. The heritage clause is marked `@vue-ignore`, so they stay out of the runtime props and keep falling through via `$attrs` exactly as before. - Give `SelectContent` and `SelectViewport` a single styleable root: the content forwards `$attrs` onto the panel, and the viewport's scrollbar CSS moves to a reference-counted `<head>` style tag. A forwarded `class` was previously dropped, leaving the panel unstyled. The tsconfig vue preset gains `htmlAttributes: ["aria-*", "data-*"]` so hyphenated data attributes are not camelized before they reach those types. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,11 @@ export interface NavigationMenuRootProps extends PrimitiveProps {
|
||||
unmountOnHide?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit contract for `NavigationMenuRoot`. The model events are declared by `defineModel`:
|
||||
* passing a model key through `defineEmits` as well erases its payload type
|
||||
* from the generated declarations, leaving consumers with `unknown`.
|
||||
*/
|
||||
export interface NavigationMenuRootEmits {
|
||||
'update:modelValue': [value: string];
|
||||
}
|
||||
@@ -70,8 +75,6 @@ const {
|
||||
as = 'nav',
|
||||
} = defineProps<NavigationMenuRootProps>();
|
||||
|
||||
defineEmits<NavigationMenuRootEmits>();
|
||||
|
||||
defineSlots<{
|
||||
default?: (props: { modelValue: string }) => unknown;
|
||||
}>();
|
||||
|
||||
@@ -15,6 +15,11 @@ export interface NavigationMenuSubProps extends PrimitiveProps {
|
||||
orientation?: Orientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit contract for `NavigationMenuSub`. The model events are declared by `defineModel`:
|
||||
* passing a model key through `defineEmits` as well erases its payload type
|
||||
* from the generated declarations, leaving consumers with `unknown`.
|
||||
*/
|
||||
export interface NavigationMenuSubEmits {
|
||||
'update:modelValue': [value: string];
|
||||
}
|
||||
@@ -35,8 +40,6 @@ defineOptions({ inheritAttrs: false });
|
||||
|
||||
const { defaultValue, orientation = 'horizontal', as = 'div' } = defineProps<NavigationMenuSubProps>();
|
||||
|
||||
defineEmits<NavigationMenuSubEmits>();
|
||||
|
||||
defineSlots<{
|
||||
default?: (props: { modelValue: string }) => unknown;
|
||||
}>();
|
||||
|
||||
@@ -44,6 +44,14 @@ export interface ToolbarRootEmits {
|
||||
/** Backs `v-model:currentTabStopId`. */
|
||||
'update:currentTabStopId': [value: string | null | undefined];
|
||||
}
|
||||
|
||||
/**
|
||||
* The subset `defineEmits` declares. `update:currentTabStopId` comes from
|
||||
* `defineModel`; passing a model key through `defineEmits` as well erases its
|
||||
* payload type from the generated declarations, leaving consumers with
|
||||
* `unknown`.
|
||||
*/
|
||||
type ToolbarRootOwnEmits = Omit<ToolbarRootEmits, 'update:currentTabStopId'>;
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -64,7 +72,7 @@ const {
|
||||
as = 'div',
|
||||
} = defineProps<ToolbarRootProps>();
|
||||
|
||||
const emit = defineEmits<ToolbarRootEmits>();
|
||||
const emit = defineEmits<ToolbarRootOwnEmits>();
|
||||
|
||||
const { forwardRef } = useForwardExpose();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user