fix(channels): stable tag column width, no popover flash, no sync wrap (R8 S1 UAT)
Three UAT refinements on the tag cell + popover platform: - Fixed tag-column width (w-[15rem], was max-w): under table-layout:auto a content- driven cell re-solved every column's width on each chip added, so the table visibly shifted (and the "+N" count flickered) until the cap was hit. A fixed footprint makes adding/removing tags move nothing (verified: column x unchanged, "+N" count stable). - No popover flash: gate the floating surface's visibility on Floating UI's isPositioned so it never paints at (0,0) top-left for a frame before the transform lands. - Sync cell no longer wraps: flex-nowrap so the recent/full badges stay on one line (the column grows to fit them instead of breaking to two rows).
This commit is contained in:
@@ -64,7 +64,7 @@ export function useAnchoredPopover(opts: AnchoredPopoverOptions) {
|
||||
// null when not inside a <FloatingTree> — the hook still works, just without nested-layer awareness.
|
||||
const nodeId = useFloatingNodeId();
|
||||
|
||||
const { refs, floatingStyles, context, middlewareData } = useFloating({
|
||||
const { refs, floatingStyles, context, middlewareData, isPositioned } = useFloating({
|
||||
nodeId,
|
||||
open: opts.open,
|
||||
onOpenChange: opts.onOpenChange,
|
||||
@@ -108,6 +108,7 @@ export function useAnchoredPopover(opts: AnchoredPopoverOptions) {
|
||||
refs,
|
||||
floatingStyles,
|
||||
context,
|
||||
isPositioned,
|
||||
referenceHidden: middlewareData.hide?.referenceHidden ?? false,
|
||||
...interactions,
|
||||
};
|
||||
@@ -134,8 +135,16 @@ export function PopoverSurface({
|
||||
focusManaged?: boolean;
|
||||
initialFocus?: number | React.MutableRefObject<HTMLElement | null>;
|
||||
}) {
|
||||
const { context, refs, floatingStyles, getFloatingProps, nodeId, referenceHidden, open } =
|
||||
popover;
|
||||
const {
|
||||
context,
|
||||
refs,
|
||||
floatingStyles,
|
||||
getFloatingProps,
|
||||
nodeId,
|
||||
referenceHidden,
|
||||
isPositioned,
|
||||
open,
|
||||
} = popover;
|
||||
const mergedRef = useMergeRefs([refs.setFloating, floatingRef ?? null]);
|
||||
const floatingProps = getFloatingProps();
|
||||
|
||||
@@ -149,8 +158,12 @@ export function PopoverSurface({
|
||||
style={{
|
||||
...(floatingProps.style as CSSProperties | undefined),
|
||||
...floatingStyles,
|
||||
// Trigger scrolled out of its clipping scroller → hide-and-follow rather than float over chrome.
|
||||
...(referenceHidden ? { visibility: "hidden", pointerEvents: "none" } : null),
|
||||
// Hide until (a) the first position is measured — else it flashes at top-left (0,0) before
|
||||
// the transform lands — and (b) while the trigger is scrolled out of its clipping scroller
|
||||
// (hide-and-follow rather than float over the chrome).
|
||||
...(!isPositioned || referenceHidden
|
||||
? { visibility: "hidden", pointerEvents: "none" }
|
||||
: null),
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -190,10 +190,12 @@ export function ChannelTagsControl({
|
||||
const fade = useScrollFade();
|
||||
|
||||
return (
|
||||
// max-w caps the cell's MAX-CONTENT so `table-layout:auto` can't ignore the column width and let
|
||||
// an over-tagged row stretch the whole table (the documented channel/About-column trap). The chip
|
||||
// row then greedily fits within it and collapses the rest into "+N".
|
||||
<div className="flex items-center gap-1 w-full max-w-[15rem] min-w-0">
|
||||
// FIXED width (not just max-w): under `table-layout:auto` a content-driven cell re-solves the
|
||||
// whole table's column widths every time a chip is added — the table visibly shifts until the cap
|
||||
// is hit. A fixed width makes the cell's footprint constant, so adding/removing tags never moves
|
||||
// any column; the chip row greedily fits within it and collapses the rest into "+N". (max-w-full
|
||||
// lets a narrower card shrink it.)
|
||||
<div className="flex items-center gap-1 w-[15rem] max-w-full min-w-0">
|
||||
<div ref={rowRef} className="flex items-center gap-1 min-w-0 flex-1 overflow-hidden">
|
||||
{attached.slice(0, visible).map((tg) => (
|
||||
<TagChip
|
||||
|
||||
@@ -1003,7 +1003,7 @@ function SyncCell({ c }: { c: ManagedChannel }) {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="flex flex-wrap items-center gap-1">
|
||||
<div className="flex flex-nowrap items-center gap-1 whitespace-nowrap">
|
||||
<SyncBadge
|
||||
ok={c.recent_synced}
|
||||
label={t("channels.row.recent")}
|
||||
|
||||
Reference in New Issue
Block a user