Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "feat: supports new automatic JSX runtime",
"packageName": "@fluentui/react-jsx-runtime",
"email": "bernardo.sunderhus@gmail.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Fragment } from 'react';
import * as React_2 from 'react';

// @public (undocumented)
export function createElement<P extends {}>(type: React_2.ElementType<P>, props?: P | null, ...children: React_2.ReactNode[]): React_2.ReactElement<P> | null;
export function createElement<P extends {}>(type: React_2.ElementType<P>, props?: P | null, ...children: React_2.ReactNode[]): React_2.ReactElement<P>;

export { Fragment }

Expand Down
12 changes: 12 additions & 0 deletions packages/react-components/react-jsx-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@
"import": "./lib/index.js",
"require": "./lib-commonjs/index.js"
},
"./jsx-dev-runtime": {
"types": "./dist/jsx-dev-runtime.d.ts",
"node": "./lib-commonjs/jsx-dev-runtime.js",
"import": "./lib/jsx-dev-runtime.js",
"require": "./lib-commonjs/jsx-dev-runtime.js"
},
"./jsx-runtime": {
"types": "./dist/jsx-runtime.d.ts",
"node": "./lib-commonjs/jsx-runtime.js",
"import": "./lib/jsx-runtime.js",
"require": "./lib-commonjs/jsx-runtime.js"
},
"./package.json": "./package.json"
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
/** @jsxRuntime classic */
/** @jsxFrag Fragment */
/** @jsx createElement */

import { render } from '@testing-library/react';
import {
ComponentProps,
ComponentState,
Slot,
assertSlots,
getSlotsNext,
resolveShorthand,
slot,
} from '@fluentui/react-utilities';
import { assertSlots, getSlotsNext, resolveShorthand, slot } from '@fluentui/react-utilities';
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import { createElement } from './createElement';

describe('createElement with getSlotsNext', () => {
Expand Down Expand Up @@ -55,6 +47,7 @@ describe('createElement with getSlotsNext', () => {
<div>
<div>1</div>
<div>2</div>
<div>3</div>
</div>,
);

Expand All @@ -66,6 +59,9 @@ describe('createElement with getSlotsNext', () => {
<div>
2
</div>
<div>
3
</div>
</div>
`);
});
Expand Down Expand Up @@ -347,7 +343,5 @@ describe('createElement with assertSlots', () => {

expect(result.container.firstChild).toMatchInlineSnapshot(`<span />`);
});

it.todo("should pass 'as' property to base element that aren't html element");
});
});
Original file line number Diff line number Diff line change
@@ -1,61 +1,21 @@
import * as React from 'react';
import {
UnknownSlotProps,
isSlot,
SlotComponentType,
SLOT_ELEMENT_TYPE_SYMBOL,
SLOT_RENDER_FUNCTION_SYMBOL,
} from '@fluentui/react-utilities';
import { isSlot } from '@fluentui/react-utilities';
import { createElementFromSlotComponent } from './jsx/createElementFromSlotComponent';
import { createCompatSlotComponent } from './utils/createCompatSlotComponent';

export function createElement<P extends {}>(
type: React.ElementType<P>,
props?: P | null,
...children: React.ReactNode[]
): React.ReactElement<P> | null {
): React.ReactElement<P> {
// TODO:
// this is for backwards compatibility with getSlotsNext
// it should be removed once getSlotsNext is obsolete
if (isSlot<P>(props)) {
return createElementFromSlotComponent(
{ ...props, [SLOT_ELEMENT_TYPE_SYMBOL]: type } as SlotComponentType<P>,
children,
);
return createElementFromSlotComponent(createCompatSlotComponent(type, props), children);
}
if (isSlot<P>(type)) {
return createElementFromSlotComponent(type, children);
}
return React.createElement(type, props, ...children);
}

function createElementFromSlotComponent<Props extends UnknownSlotProps>(
type: SlotComponentType<Props>,
overrideChildren: React.ReactNode[],
): React.ReactElement<Props> | null {
const {
as,
[SLOT_ELEMENT_TYPE_SYMBOL]: baseElementType,
[SLOT_RENDER_FUNCTION_SYMBOL]: renderFunction,
...propsWithoutMetadata
} = type;
const props = propsWithoutMetadata as UnknownSlotProps as Props;

const elementType = typeof baseElementType === 'string' ? as ?? baseElementType : baseElementType;

if (typeof elementType !== 'string' && as) {
props.as = as;
}

if (renderFunction) {
if (overrideChildren.length > 0) {
props.children = React.createElement(React.Fragment, {}, ...overrideChildren);
}

return React.createElement(
React.Fragment,
{},
renderFunction(elementType as React.ElementType<Props>, props),
) as React.ReactElement<Props>;
}

return React.createElement(elementType, props, ...overrideChildren);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type * as React from 'react';
import { isSlot } from '@fluentui/react-utilities';
import { jsxDEVFromSlotComponent } from './jsx/jsxDEVFromSlotComponent';
import { createCompatSlotComponent } from './utils/createCompatSlotComponent';
import { DevRuntime } from './utils/DevRuntime';

export { Fragment } from 'react';

export function jsxDEV<P extends {}>(
type: React.ElementType<P>,
props: P,
key?: React.Key,
source?: boolean,
self?: unknown,
): React.ReactElement<P> {
// TODO:
// this is for backwards compatibility with getSlotsNext
// it should be removed once getSlotsNext is obsolete
if (isSlot<P>(props)) {
return jsxDEVFromSlotComponent(createCompatSlotComponent(type, props), null, key, source, self);
}
if (isSlot<P>(type)) {
return jsxDEVFromSlotComponent(type, props, key, source, self);
}
return DevRuntime.jsxDEV(type, props, key, source, self);
}
Loading