0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-08-06 06:47: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:
Gazook89
2026-04-24 22:06:52 -05:00
parent 87ed5d107d
commit 359d87440b
8 changed files with 117 additions and 9 deletions
+2
View File
@@ -1,6 +1,8 @@
import { createRoot } from 'react-dom/client';
import Admin from './admin.jsx';
import { bootstrapAnchorPositioningPolyfill } from '../components/anchorPositioningPolyfill.js';
const props = window.__INITIAL_PROPS__ || {};
createRoot(document.getElementById('reactRoot')).render(<Admin {...props} />);
bootstrapAnchorPositioningPolyfill();
+11 -4
View File
@@ -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 -3
View File
@@ -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}
+2
View File
@@ -1,6 +1,8 @@
import { createRoot } from 'react-dom/client';
import Homebrew from './homebrew.jsx';
import { bootstrapAnchorPositioningPolyfill } from '../components/anchorPositioningPolyfill.js';
const props = window.__INITIAL_PROPS__ || {};
createRoot(document.getElementById('reactRoot')).render(<Homebrew {...props} />);
bootstrapAnchorPositioningPolyfill();