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
1 change: 0 additions & 1 deletion dev/pages/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ export default function ComboBoxPage() {

return (
<div style={{ display: 'grid', gridTemplateRows: 'auto auto', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>

{/* Demo component section */}
<div style={{ gridColumn: '1 / -1' }}>
<h1>ComboBox</h1>
Expand Down
1 change: 0 additions & 1 deletion dev/pages/ConfirmDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export default function ConfirmDialogPage() {

return (
<div style={{ display: 'grid', gridTemplateRows: 'auto auto', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>

{/* Demo component section */}
<div style={{ gridColumn: '1 / -1' }}>
<h1>ConfirmDialog</h1>
Expand Down
1 change: 0 additions & 1 deletion dev/pages/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ export default function ContextMenuPage() {
}
`}</style>
<div style={{ display: 'grid', gridTemplateRows: 'auto auto', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>

{/* Demo component section */}
<div style={{ gridColumn: '1 / -1' }}>
<h1>ContextMenu</h1>
Expand Down
1 change: 0 additions & 1 deletion dev/pages/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export default function DatePickerPage() {

return (
<div style={{ display: 'grid', gridTemplateRows: 'auto auto', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>

{/* Demo component section */}
<div style={{ gridColumn: '1 / -1' }}>
<h1>DatePicker</h1>
Expand Down
1 change: 0 additions & 1 deletion dev/pages/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export default function SelectPage() {

return (
<div style={{ display: 'grid', gridTemplateRows: 'auto auto', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>

{/* Demo component section */}
<div style={{ gridColumn: '1 / -1' }}>
<h1>Select</h1>
Expand Down
1 change: 0 additions & 1 deletion dev/pages/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export default function TextFieldPage() {

return (
<div style={{ display: 'grid', gridTemplateRows: 'auto auto', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>

{/* Demo component section */}
<div style={{ gridColumn: '1 / -1' }}>
<h1>TextField</h1>
Expand Down
12 changes: 6 additions & 6 deletions dev/pages/master-detail-layout-styles.css
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
html,
body {
height: 100%;
height: 100%;
}

vaadin-master-detail-layout {
border: solid 1px #ccc;
border: solid 1px #ccc;
}

vaadin-master-detail-layout:is([overlay], [stack])::part(detail) {
background: #fff;
background: #fff;
}

vaadin-master-detail-layout[orientation='horizontal'][overlay]::part(detail) {
border-inline-start: solid 1px #ccc;
border-inline-start: solid 1px #ccc;
}

vaadin-master-detail-layout[orientation='vertical'][overlay]::part(detail) {
border-block-start: solid 1px #ccc;
}
border-block-start: solid 1px #ccc;
}
2 changes: 1 addition & 1 deletion packages/react-components-pro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,4 @@
"./utils/createComponent.js": "./utils/createComponent.js",
"./utils/createComponent.js.map": "./utils/createComponent.js.map"
}
}
}
2 changes: 1 addition & 1 deletion packages/react-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -558,4 +558,4 @@
"./renderers/useSimpleRenderer.js": "./renderers/useSimpleRenderer.js",
"./renderers/useSimpleRenderer.js.map": "./renderers/useSimpleRenderer.js.map"
}
}
}
75 changes: 43 additions & 32 deletions packages/react-components/src/MasterDetailLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ function Master({ children }: MasterProps) {
}

function DetailPlaceholder({ children }: DetailPlaceholderProps) {
return <div slot="detail-placeholder" style={{ height: '100%' }}>{children}</div>;
return (
<div slot="detail-placeholder" style={{ height: '100%' }}>
{children}
</div>
);
}

/**
Expand Down Expand Up @@ -88,36 +92,38 @@ function Detail({ children }: DetailProps) {

// _startTransition calls the callback synchronously for add/replace,
// and asynchronously for remove.
layout._startTransition(transitionType, async () => {
if (transitionType === 'replace' && currentDetailsRef.current) {
// For replace, _startTransition moved the current div to the
// detail-outgoing slot for the outgoing animation. Clone it so the
// WC can animate the clone out, then hide the React-managed original
// so the WC's post-animation cleanup won't remove it from the DOM.
const clone = currentDetailsRef.current.cloneNode(true) as HTMLElement;
clone.setAttribute('slot', 'detail-outgoing');
layout.appendChild(clone);
currentDetailsRef.current.setAttribute('slot', 'detail-hidden');
} else if (currentDetailsRef.current) {
currentDetailsRef.current.setAttribute('slot', 'detail-hidden');
}
if (nextDetailsRef.current) {
nextDetailsRef.current.style.display = '';
const hasNext = nextDetailsRef.current.childElementCount > 0;
nextDetailsRef.current.setAttribute('slot', hasNext ? 'detail' : 'detail-hidden');
}

// Wait for Lit elements to render
await Promise.resolve();

// Recompute layout state with the new DOM
layout.recalculateLayout();
}).then(() => {
// Animation finished — sync React state to match DOM reality
setCurrentChildren(children);
currentDetailsKey.current = nextDetailsKey;
setState('idle');
});
layout
._startTransition(transitionType, async () => {
if (transitionType === 'replace' && currentDetailsRef.current) {
// For replace, _startTransition moved the current div to the
// detail-outgoing slot for the outgoing animation. Clone it so the
// WC can animate the clone out, then hide the React-managed original
// so the WC's post-animation cleanup won't remove it from the DOM.
const clone = currentDetailsRef.current.cloneNode(true) as HTMLElement;
clone.setAttribute('slot', 'detail-outgoing');
layout.appendChild(clone);
currentDetailsRef.current.setAttribute('slot', 'detail-hidden');
} else if (currentDetailsRef.current) {
currentDetailsRef.current.setAttribute('slot', 'detail-hidden');
}
if (nextDetailsRef.current) {
nextDetailsRef.current.style.display = '';
const hasNext = nextDetailsRef.current.childElementCount > 0;
nextDetailsRef.current.setAttribute('slot', hasNext ? 'detail' : 'detail-hidden');
}

// Wait for Lit elements to render
await Promise.resolve();

// Recompute layout state with the new DOM
layout.recalculateLayout();
})
.then(() => {
// Animation finished — sync React state to match DOM reality
setCurrentChildren(children);
currentDetailsKey.current = nextDetailsKey;
setState('idle');
});
}
}, [state, currentChildren]);

Expand Down Expand Up @@ -150,7 +156,12 @@ function validateChildren(children: React.ReactNode) {
React.Children.forEach(children, (child) => {
// Ignore non-React elements
// We especially want to ignore text nodes to allow for whitespace resulting from formatting
if (React.isValidElement(child) && child.type !== Master && child.type !== Detail && child.type !== DetailPlaceholder) {
if (
React.isValidElement(child) &&
child.type !== Master &&
child.type !== Detail &&
child.type !== DetailPlaceholder
) {
throw new Error(
'Invalid child in MasterDetailLayout. Only <MasterDetailLayout.Master>, <MasterDetailLayout.Detail>, and <MasterDetailLayout.DetailPlaceholder> components are allowed. Check the component docs for proper usage.',
);
Expand Down
13 changes: 10 additions & 3 deletions packages/react-components/src/MenuBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ export type MenuBarItem<TItemData extends object = object> = Omit<_MenuBarItem<T
children?: Array<SubMenuItem<TItemData>>;
};

export type MenuBarItemSelectedEvent<TItem extends MenuBarItem = MenuBarItem> = CustomEvent<{ value: MenuBarItem<TItem> }>;
export type MenuBarItemSelectedEvent<TItem extends MenuBarItem = MenuBarItem> = CustomEvent<{
value: MenuBarItem<TItem>;
}>;

export type MenuBarProps<TItem extends MenuBarItem = MenuBarItem> = Partial<Omit<_MenuBarProps, 'items' | 'onItemSelected'>> &
export type MenuBarProps<TItem extends MenuBarItem = MenuBarItem> = Partial<
Omit<_MenuBarProps, 'items' | 'onItemSelected'>
> &
Readonly<{
items?: Array<TItem>;

onItemSelected?: (event: MenuBarItemSelectedEvent<TItem>) => void;
}>;

function MenuBar<TItem extends MenuBarItem = MenuBarItem>(props: MenuBarProps<TItem>, ref: ForwardedRef<MenuBarElement>): ReactElement | null {
function MenuBar<TItem extends MenuBarItem = MenuBarItem>(
props: MenuBarProps<TItem>,
ref: ForwardedRef<MenuBarElement>,
): ReactElement | null {
const [itemPortals, webComponentItems] = mapItemsWithComponents(props.items, 'vaadin-menu-bar-item');

const onItemSelected = props.onItemSelected;
Expand Down
8 changes: 1 addition & 7 deletions types/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,7 @@ export type Pattern =
* via the `patternProperty` "^/(html|css|js)/[^/\n\r]+$".
*/
export type NameConverter =
| 'as-is'
| 'PascalCase'
| 'camelCase'
| 'lowercase'
| 'UPPERCASE'
| 'kebab-case'
| 'snake_case';
'as-is' | 'PascalCase' | 'camelCase' | 'lowercase' | 'UPPERCASE' | 'kebab-case' | 'snake_case';
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^/(html|css|js)/[^/\n\r]+$".
Expand Down
Loading