mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-08-06 08:57:38 +00:00
add oddbird polyfill - not quite working
Not quite working yet. polyfill is loaded, but positioned elements are spanning whole viewport. Parking this for now.
This commit is contained in:
@@ -71,10 +71,14 @@ const Anchored = ({ children })=>{
|
||||
// forward ref for AnchoredTrigger
|
||||
const AnchoredTrigger = forwardRef(({ toggleVisibility, visible, children, className, ...props }, ref)=>(
|
||||
<button
|
||||
ref={ref}
|
||||
ref={(el)=>{
|
||||
// setAttribute bypasses React's style sanitization so the anchor polyfill can read it
|
||||
el?.setAttribute('style', `anchor-name: --${props.id}`);
|
||||
if(typeof ref === 'function') ref(el);
|
||||
else if(ref) ref.current = el;
|
||||
}}
|
||||
className={`anchored-trigger${visible ? ' active' : ''} ${className}`}
|
||||
onClick={toggleVisibility}
|
||||
style={{ anchorName: `--${props.id}` }} // setting anchor properties here allows greater recyclability.
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
@@ -84,9 +88,12 @@ const AnchoredTrigger = forwardRef(({ toggleVisibility, visible, children, class
|
||||
// forward ref for AnchoredBox
|
||||
const AnchoredBox = forwardRef(({ visible, children, className, anchorId, ...props }, ref)=>(
|
||||
<div
|
||||
ref={ref}
|
||||
ref={(el)=>{
|
||||
el?.setAttribute('style', `position-anchor: --${anchorId}`);
|
||||
if(typeof ref === 'function') ref(el);
|
||||
else if(ref) ref.current = el;
|
||||
}}
|
||||
className={`anchored-box${visible ? ' active' : ''} ${className}`}
|
||||
style={{ positionAnchor: `--${anchorId}` }} // setting anchor properties here allows greater recyclability.
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import './anchorPositioningPolyfill.less';
|
||||
|
||||
let polyfillPromise;
|
||||
|
||||
const supportsAnchorPositioning = ()=>'anchorName' in document.documentElement.style;
|
||||
|
||||
const afterInitialRender = ()=>new Promise((resolve)=>{
|
||||
requestAnimationFrame(()=>{
|
||||
requestAnimationFrame(resolve);
|
||||
});
|
||||
});
|
||||
|
||||
export const bootstrapAnchorPositioningPolyfill = ()=>{
|
||||
if(supportsAnchorPositioning()) return Promise.resolve(false);
|
||||
if(polyfillPromise) return polyfillPromise;
|
||||
|
||||
polyfillPromise = afterInitialRender()
|
||||
.then(async ()=>{
|
||||
const { default: polyfill } = await import('@oddbird/css-anchor-positioning/fn');
|
||||
await polyfill();
|
||||
return true;
|
||||
})
|
||||
.catch((error)=>{
|
||||
polyfillPromise = undefined;
|
||||
throw error;
|
||||
});
|
||||
|
||||
return polyfillPromise;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
.hb-anchor-source {
|
||||
anchor-name: var(--hb-anchor-name);
|
||||
}
|
||||
|
||||
.hb-anchor-target {
|
||||
position-anchor: var(--hb-position-anchor);
|
||||
}
|
||||
|
||||
.hb-position-area {
|
||||
position-area: var(--hb-position-area);
|
||||
}
|
||||
|
||||
.hb-position-try-fallbacks {
|
||||
position-try-fallbacks: var(--hb-position-try-fallbacks);
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
import './dropdown.less';
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import _ from 'lodash';
|
||||
|
||||
// use react context to keep track of the menu depth (menus in menus)
|
||||
@@ -27,6 +27,16 @@ const Dropdown = ({ groupName, className = null, icon, children, color = null, c
|
||||
// A menu is a submenu if depth > 0
|
||||
const isSubMenu = depth > 0;
|
||||
|
||||
const wrapperRef = useRef(null);
|
||||
const menuRef = useRef(null);
|
||||
|
||||
// Use setAttribute instead of the React style prop because React silently strips unknown CSS
|
||||
// properties (like anchor-name) from inline styles in browsers that don't support them.
|
||||
// setAttribute writes raw CSS text that the anchor positioning polyfill can read.
|
||||
useEffect(()=>{
|
||||
wrapperRef.current?.setAttribute('style', `anchor-name: ${anchorName}`);
|
||||
menuRef.current?.setAttribute('style', `position-anchor: ${anchorName}`);
|
||||
}, [anchorName]);
|
||||
|
||||
// hide popover with click inside iframe (not supported by light dismiss)
|
||||
useEffect(()=>{
|
||||
@@ -59,7 +69,7 @@ const Dropdown = ({ groupName, className = null, icon, children, color = null, c
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={['menu-wrapper', className].join(' ')} style={{ anchorName }} role='none' >
|
||||
<div ref={wrapperRef} className={['menu-wrapper', className].join(' ')} role='none' >
|
||||
<button
|
||||
id={groupName.replace(' ', '-')}
|
||||
className={['menu-item', color].join(' ')}
|
||||
@@ -73,10 +83,10 @@ const Dropdown = ({ groupName, className = null, icon, children, color = null, c
|
||||
</button>
|
||||
<MenuDepthContext.Provider value={depth + 1}>
|
||||
<div
|
||||
ref={menuRef}
|
||||
id={menuId}
|
||||
className='menu-list'
|
||||
popover='auto'
|
||||
style={{ positionAnchor: anchorName }}
|
||||
role='menu'
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user