fix(ct): render attributes (#17991)

This commit is contained in:
sand4rt 2022-10-18 22:02:53 +02:00 committed by GitHub
parent 689c3eb5fe
commit ced3efb688
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 69 additions and 12 deletions

View File

@ -42,6 +42,20 @@ function createChild(child, h) {
return typeof child === 'string' ? child : createWrapper(child, h);
}
/**
* Exists to support fallthrough attributes:
* https://vuejs.org/guide/components/attrs.html#fallthrough-attributes
* @param {any} Component
* @param {string} key
* @return {boolean}
*/
function componentHasKeyInProps(Component, key) {
if (Array.isArray(Component.props))
return Component.props.includes(key);
return Object.entries(Component.props).flat().includes(key);
}
/**
* @param {Component} component
* @param {import('vue').CreateElement} h
@ -96,7 +110,7 @@ function createComponent(component, h) {
const event = key.substring('v-on:'.length);
nodeData.on[event] = value;
} else {
if (isVueComponent)
if (isVueComponent && componentHasKeyInProps(componentFunc, key))
nodeData.props[key] = value;
else
nodeData.attrs[key] = value;

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<link rel="icon" type="image/svg+xml" href="/src/assets/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>

View File

@ -1,5 +1,5 @@
import { useState } from 'react'
import logo from './components/logo.svg'
import logo from './assets/logo.svg'
import './App.css'
function App() {

View File

@ -1,7 +1,13 @@
import { ButtonHTMLAttributes } from "react";
type ButtonProps = {
title: string;
onClick?(props: string): void;
}
export default function Button(props: ButtonProps) {
return <button onClick={() => props.onClick?.('hello')}>{props.title}</button>
className?: string;
} & ButtonHTMLAttributes<HTMLButtonElement>;
export default function Button({ onClick, title, ...attributes }: ButtonProps) {
return <button {...attributes} onClick={() => onClick?.('hello')}>
{title}
</button>
}

View File

@ -13,6 +13,11 @@ test('render props', async ({ mount }) => {
await expect(component).toContainText('Submit');
});
test('render attributes', async ({ mount }) => {
const component = await mount(<Button className="primary" title="Submit" />)
await expect(component).toHaveClass('primary');
});
test('renderer updates props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />)
await expect(component.locator('#props')).toContainText('9001')

View File

@ -1,7 +1,13 @@
import { ButtonHTMLAttributes } from "react";
type ButtonProps = {
title: string;
onClick?(props: string): void;
}
export default function Button(props: ButtonProps) {
return <button onClick={() => props.onClick?.('hello')}>{props.title}</button>
className?: string;
} & ButtonHTMLAttributes<HTMLButtonElement>;
export default function Button({ onClick, title, ...attributes }: ButtonProps) {
return <button {...attributes} onClick={() => onClick?.('hello')}>
{title}
</button>
}

View File

@ -16,6 +16,11 @@ test('render props', async ({ mount }) => {
await expect(component).toContainText('Submit');
});
test('render attributes', async ({ mount }) => {
const component = await mount(<Button className="primary" title="Submit" />)
await expect(component).toHaveClass('primary');
})
test('renderer updates props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />)
await expect(component.locator('#props')).toContainText('9001')

View File

@ -1,7 +1,13 @@
import type { JSX } from "solid-js";
type ButtonProps = {
title: string;
onClick?(props: string): void;
}
export default function Button(props: ButtonProps) {
return <button onClick={() => props.onClick?.('hello')}>{props.title}</button>
className?: string;
} & JSX.ButtonHTMLAttributes<HTMLButtonElement>;
export default function Button({ onClick, title, ...attributes }: ButtonProps) {
return <button {...attributes} onClick={() => onClick?.('hello')}>
{title}
</button>
}

View File

@ -12,6 +12,11 @@ test('render props', async ({ mount }) => {
await expect(component).toContainText('Submit');
});
test('render attributes', async ({ mount }) => {
const component = await mount(<Button className="primary" title="Submit" />)
await expect(component).toHaveClass('primary');
})
test('execute callback when the button is clicked', async ({ mount }) => {
const messages: string[] = [];
const component = await mount(

View File

@ -13,6 +13,11 @@ test('render props', async ({ mount }) => {
await expect(component).toContainText('Submit')
})
test('render attributes', async ({ mount }) => {
const component = await mount(<Button class="primary" title="Submit" />)
await expect(component).toHaveClass('primary');
});
test('renderer updates props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />)
await expect(component.locator('#props')).toContainText('9001')

View File

@ -12,6 +12,11 @@ test('render props', async ({ mount }) => {
await expect(component).toContainText('Submit')
})
test('render attributes', async ({ mount }) => {
const component = await mount(<Button class="primary" title="Submit" />)
await expect(component).toHaveClass('primary');
});
test('renderer updates props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />)
await expect(component.locator('#props')).toContainText('9001')