@streamoid/ui 0.6.32 → 0.6.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/ScWorkspaceAccountMenu.md +17 -0
- package/dist/index.d.mts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +13 -4
- package/dist/index.mjs +13 -4
- package/package.json +1 -1
|
@@ -196,6 +196,23 @@ Two things will bite you:
|
|
|
196
196
|
`arrow` is `null` until the panel has been measured; `ScPopoverArrow` renders
|
|
197
197
|
nothing for it, so there is no flash of a caret in the wrong place.
|
|
198
198
|
|
|
199
|
+
### Two popovers on one rail
|
|
200
|
+
|
|
201
|
+
Pass `alignRef` — the rail — to both, and they open on the same vertical line
|
|
202
|
+
while each caret still points at its own trigger:
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
const { style, arrow } = useStreamoidAnchoredPopover(triggerRef, panelRef, {
|
|
206
|
+
width: 320,
|
|
207
|
+
alignRef: railRef,
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Without it each panel hangs off its own button, and those sit at different
|
|
212
|
+
insets (each inside a control with its own padding) — so the pair opens about
|
|
213
|
+
twenty pixels apart, one flush to the rail and the other overlapping it, which
|
|
214
|
+
reads as sloppy rather than as one pattern.
|
|
215
|
+
|
|
199
216
|
Use the same hook for **every** popover a rail owns. Mixing it with
|
|
200
217
|
`useStreamoidSidebarPopoverPosition` (which pins to the sidebar CARD's edge)
|
|
201
218
|
puts two menus from the same rail in visibly different places — one tethered to
|
package/dist/index.d.mts
CHANGED
|
@@ -835,6 +835,17 @@ interface StreamoidAnchorRect {
|
|
|
835
835
|
}
|
|
836
836
|
interface StreamoidAnchoredPopoverGeometry {
|
|
837
837
|
anchor: StreamoidAnchorRect;
|
|
838
|
+
/** Sets the horizontal placement when the trigger should not.
|
|
839
|
+
*
|
|
840
|
+
* A rail with two popovers — a workspace menu at the top, an app switcher at
|
|
841
|
+
* the foot — has two triggers at different insets, because each sits inside
|
|
842
|
+
* a button with its own padding. Anchored to those, the two panels open a
|
|
843
|
+
* dozen pixels apart and the pair reads as sloppy rather than as one
|
|
844
|
+
* pattern. Align both to the RAIL and they open on the same line, while the
|
|
845
|
+
* caret still points at whichever trigger was used.
|
|
846
|
+
*
|
|
847
|
+
* Defaults to `anchor`, which is the single-popover case. */
|
|
848
|
+
align?: StreamoidAnchorRect;
|
|
838
849
|
viewportWidth: number;
|
|
839
850
|
viewportHeight: number;
|
|
840
851
|
/** Panel width in pixels. */
|
|
@@ -849,6 +860,10 @@ interface StreamoidAnchoredPopoverGeometry {
|
|
|
849
860
|
interface StreamoidAnchoredPopoverPositionOptions {
|
|
850
861
|
/** Panel width in pixels. */
|
|
851
862
|
width: number;
|
|
863
|
+
/** Element whose edges set the horizontal placement, when the trigger should
|
|
864
|
+
* not. See `align` on the geometry — pass the rail to line two of its
|
|
865
|
+
* popovers up with each other. */
|
|
866
|
+
alignRef?: RefObject<HTMLElement | null>;
|
|
852
867
|
/** Gap between the trigger and the panel. Defaults to 8px. */
|
|
853
868
|
gap?: number;
|
|
854
869
|
/** Keep-out margin from the viewport edges. Defaults to 16px. */
|
|
@@ -900,7 +915,7 @@ declare function resolveAnchoredPopoverArrow({ anchor, panelLeft, panelTop, pane
|
|
|
900
915
|
* below. Nothing else re-places it, so the panel is always visibly attached to
|
|
901
916
|
* the button that opened it rather than parked against a container edge.
|
|
902
917
|
*/
|
|
903
|
-
declare function resolveAnchoredPopoverPosition({ anchor, viewportWidth, viewportHeight, width, height, gap, inset, }: StreamoidAnchoredPopoverGeometry): {
|
|
918
|
+
declare function resolveAnchoredPopoverPosition({ anchor, align, viewportWidth, viewportHeight, width, height, gap, inset, }: StreamoidAnchoredPopoverGeometry): {
|
|
904
919
|
left: number;
|
|
905
920
|
top: number;
|
|
906
921
|
width: number;
|
|
@@ -920,7 +935,7 @@ declare function resolveAnchoredPopoverPosition({ anchor, viewportWidth, viewpor
|
|
|
920
935
|
*/
|
|
921
936
|
/** The position and the caret, measured together — a caret measured on a later
|
|
922
937
|
* render can point somewhere the panel no longer is. */
|
|
923
|
-
declare function useStreamoidAnchoredPopover(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { width, gap, inset }: StreamoidAnchoredPopoverPositionOptions): StreamoidAnchoredPopover;
|
|
938
|
+
declare function useStreamoidAnchoredPopover(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { width, gap, inset, alignRef, }: StreamoidAnchoredPopoverPositionOptions): StreamoidAnchoredPopover;
|
|
924
939
|
declare function useStreamoidAnchoredPopoverPosition(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { width, gap, inset }: StreamoidAnchoredPopoverPositionOptions): StreamoidAnchoredPopoverPosition;
|
|
925
940
|
|
|
926
941
|
interface IScPopoverArrowProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -835,6 +835,17 @@ interface StreamoidAnchorRect {
|
|
|
835
835
|
}
|
|
836
836
|
interface StreamoidAnchoredPopoverGeometry {
|
|
837
837
|
anchor: StreamoidAnchorRect;
|
|
838
|
+
/** Sets the horizontal placement when the trigger should not.
|
|
839
|
+
*
|
|
840
|
+
* A rail with two popovers — a workspace menu at the top, an app switcher at
|
|
841
|
+
* the foot — has two triggers at different insets, because each sits inside
|
|
842
|
+
* a button with its own padding. Anchored to those, the two panels open a
|
|
843
|
+
* dozen pixels apart and the pair reads as sloppy rather than as one
|
|
844
|
+
* pattern. Align both to the RAIL and they open on the same line, while the
|
|
845
|
+
* caret still points at whichever trigger was used.
|
|
846
|
+
*
|
|
847
|
+
* Defaults to `anchor`, which is the single-popover case. */
|
|
848
|
+
align?: StreamoidAnchorRect;
|
|
838
849
|
viewportWidth: number;
|
|
839
850
|
viewportHeight: number;
|
|
840
851
|
/** Panel width in pixels. */
|
|
@@ -849,6 +860,10 @@ interface StreamoidAnchoredPopoverGeometry {
|
|
|
849
860
|
interface StreamoidAnchoredPopoverPositionOptions {
|
|
850
861
|
/** Panel width in pixels. */
|
|
851
862
|
width: number;
|
|
863
|
+
/** Element whose edges set the horizontal placement, when the trigger should
|
|
864
|
+
* not. See `align` on the geometry — pass the rail to line two of its
|
|
865
|
+
* popovers up with each other. */
|
|
866
|
+
alignRef?: RefObject<HTMLElement | null>;
|
|
852
867
|
/** Gap between the trigger and the panel. Defaults to 8px. */
|
|
853
868
|
gap?: number;
|
|
854
869
|
/** Keep-out margin from the viewport edges. Defaults to 16px. */
|
|
@@ -900,7 +915,7 @@ declare function resolveAnchoredPopoverArrow({ anchor, panelLeft, panelTop, pane
|
|
|
900
915
|
* below. Nothing else re-places it, so the panel is always visibly attached to
|
|
901
916
|
* the button that opened it rather than parked against a container edge.
|
|
902
917
|
*/
|
|
903
|
-
declare function resolveAnchoredPopoverPosition({ anchor, viewportWidth, viewportHeight, width, height, gap, inset, }: StreamoidAnchoredPopoverGeometry): {
|
|
918
|
+
declare function resolveAnchoredPopoverPosition({ anchor, align, viewportWidth, viewportHeight, width, height, gap, inset, }: StreamoidAnchoredPopoverGeometry): {
|
|
904
919
|
left: number;
|
|
905
920
|
top: number;
|
|
906
921
|
width: number;
|
|
@@ -920,7 +935,7 @@ declare function resolveAnchoredPopoverPosition({ anchor, viewportWidth, viewpor
|
|
|
920
935
|
*/
|
|
921
936
|
/** The position and the caret, measured together — a caret measured on a later
|
|
922
937
|
* render can point somewhere the panel no longer is. */
|
|
923
|
-
declare function useStreamoidAnchoredPopover(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { width, gap, inset }: StreamoidAnchoredPopoverPositionOptions): StreamoidAnchoredPopover;
|
|
938
|
+
declare function useStreamoidAnchoredPopover(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { width, gap, inset, alignRef, }: StreamoidAnchoredPopoverPositionOptions): StreamoidAnchoredPopover;
|
|
924
939
|
declare function useStreamoidAnchoredPopoverPosition(anchorRef: RefObject<HTMLElement | null>, panelRef: RefObject<HTMLElement | null>, { width, gap, inset }: StreamoidAnchoredPopoverPositionOptions): StreamoidAnchoredPopoverPosition;
|
|
925
940
|
|
|
926
941
|
interface IScPopoverArrowProps {
|
package/dist/index.js
CHANGED
|
@@ -5913,6 +5913,7 @@ var DEFAULT_GAP = 8;
|
|
|
5913
5913
|
var DEFAULT_INSET = 16;
|
|
5914
5914
|
function resolveAnchoredPopoverPosition({
|
|
5915
5915
|
anchor,
|
|
5916
|
+
align,
|
|
5916
5917
|
viewportWidth,
|
|
5917
5918
|
viewportHeight,
|
|
5918
5919
|
width,
|
|
@@ -5922,8 +5923,9 @@ function resolveAnchoredPopoverPosition({
|
|
|
5922
5923
|
}) {
|
|
5923
5924
|
const available = Math.max(0, viewportWidth - inset * 2);
|
|
5924
5925
|
const panelWidth = Math.min(width, available);
|
|
5925
|
-
const
|
|
5926
|
-
const
|
|
5926
|
+
const beside = align ?? anchor;
|
|
5927
|
+
const rightOfAnchor = beside.right + gap;
|
|
5928
|
+
const leftOfAnchor = beside.left - gap - panelWidth;
|
|
5927
5929
|
const fitsRight = rightOfAnchor + panelWidth <= viewportWidth - inset;
|
|
5928
5930
|
const preferredLeft = fitsRight ? rightOfAnchor : leftOfAnchor >= inset ? leftOfAnchor : rightOfAnchor;
|
|
5929
5931
|
const left = Math.max(
|
|
@@ -5941,7 +5943,12 @@ function resolveAnchoredPopoverPosition({
|
|
|
5941
5943
|
);
|
|
5942
5944
|
return { left, top, width: panelWidth };
|
|
5943
5945
|
}
|
|
5944
|
-
function useStreamoidAnchoredPopover(anchorRef, panelRef, {
|
|
5946
|
+
function useStreamoidAnchoredPopover(anchorRef, panelRef, {
|
|
5947
|
+
width,
|
|
5948
|
+
gap = DEFAULT_GAP,
|
|
5949
|
+
inset = DEFAULT_INSET,
|
|
5950
|
+
alignRef
|
|
5951
|
+
}) {
|
|
5945
5952
|
const [state, setState] = (0, import_react16.useState)({
|
|
5946
5953
|
style: {
|
|
5947
5954
|
position: "fixed",
|
|
@@ -5962,6 +5969,7 @@ function useStreamoidAnchoredPopover(anchorRef, panelRef, { width, gap = DEFAULT
|
|
|
5962
5969
|
const panelHeight = panelRef.current?.offsetHeight;
|
|
5963
5970
|
const { left, top, width: panelWidth } = resolveAnchoredPopoverPosition({
|
|
5964
5971
|
anchor: bounds,
|
|
5972
|
+
align: alignRef?.current?.getBoundingClientRect(),
|
|
5965
5973
|
viewportWidth: window.innerWidth,
|
|
5966
5974
|
viewportHeight: window.innerHeight,
|
|
5967
5975
|
width,
|
|
@@ -5994,12 +6002,13 @@ function useStreamoidAnchoredPopover(anchorRef, panelRef, { width, gap = DEFAULT
|
|
|
5994
6002
|
const resizeObserver = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
|
|
5995
6003
|
resizeObserver?.observe(anchor);
|
|
5996
6004
|
if (panelRef.current) resizeObserver?.observe(panelRef.current);
|
|
6005
|
+
if (alignRef?.current) resizeObserver?.observe(alignRef.current);
|
|
5997
6006
|
return () => {
|
|
5998
6007
|
window.removeEventListener("resize", measure);
|
|
5999
6008
|
window.removeEventListener("scroll", measure, true);
|
|
6000
6009
|
resizeObserver?.disconnect();
|
|
6001
6010
|
};
|
|
6002
|
-
}, [anchorRef, panelRef, width, gap, inset]);
|
|
6011
|
+
}, [anchorRef, panelRef, alignRef, width, gap, inset]);
|
|
6003
6012
|
return state;
|
|
6004
6013
|
}
|
|
6005
6014
|
function useStreamoidAnchoredPopoverPosition(anchorRef, panelRef, { width, gap = DEFAULT_GAP, inset = DEFAULT_INSET }) {
|
package/dist/index.mjs
CHANGED
|
@@ -5740,6 +5740,7 @@ var DEFAULT_GAP = 8;
|
|
|
5740
5740
|
var DEFAULT_INSET = 16;
|
|
5741
5741
|
function resolveAnchoredPopoverPosition({
|
|
5742
5742
|
anchor,
|
|
5743
|
+
align,
|
|
5743
5744
|
viewportWidth,
|
|
5744
5745
|
viewportHeight,
|
|
5745
5746
|
width,
|
|
@@ -5749,8 +5750,9 @@ function resolveAnchoredPopoverPosition({
|
|
|
5749
5750
|
}) {
|
|
5750
5751
|
const available = Math.max(0, viewportWidth - inset * 2);
|
|
5751
5752
|
const panelWidth = Math.min(width, available);
|
|
5752
|
-
const
|
|
5753
|
-
const
|
|
5753
|
+
const beside = align ?? anchor;
|
|
5754
|
+
const rightOfAnchor = beside.right + gap;
|
|
5755
|
+
const leftOfAnchor = beside.left - gap - panelWidth;
|
|
5754
5756
|
const fitsRight = rightOfAnchor + panelWidth <= viewportWidth - inset;
|
|
5755
5757
|
const preferredLeft = fitsRight ? rightOfAnchor : leftOfAnchor >= inset ? leftOfAnchor : rightOfAnchor;
|
|
5756
5758
|
const left = Math.max(
|
|
@@ -5768,7 +5770,12 @@ function resolveAnchoredPopoverPosition({
|
|
|
5768
5770
|
);
|
|
5769
5771
|
return { left, top, width: panelWidth };
|
|
5770
5772
|
}
|
|
5771
|
-
function useStreamoidAnchoredPopover(anchorRef, panelRef, {
|
|
5773
|
+
function useStreamoidAnchoredPopover(anchorRef, panelRef, {
|
|
5774
|
+
width,
|
|
5775
|
+
gap = DEFAULT_GAP,
|
|
5776
|
+
inset = DEFAULT_INSET,
|
|
5777
|
+
alignRef
|
|
5778
|
+
}) {
|
|
5772
5779
|
const [state, setState] = useState13({
|
|
5773
5780
|
style: {
|
|
5774
5781
|
position: "fixed",
|
|
@@ -5789,6 +5796,7 @@ function useStreamoidAnchoredPopover(anchorRef, panelRef, { width, gap = DEFAULT
|
|
|
5789
5796
|
const panelHeight = panelRef.current?.offsetHeight;
|
|
5790
5797
|
const { left, top, width: panelWidth } = resolveAnchoredPopoverPosition({
|
|
5791
5798
|
anchor: bounds,
|
|
5799
|
+
align: alignRef?.current?.getBoundingClientRect(),
|
|
5792
5800
|
viewportWidth: window.innerWidth,
|
|
5793
5801
|
viewportHeight: window.innerHeight,
|
|
5794
5802
|
width,
|
|
@@ -5821,12 +5829,13 @@ function useStreamoidAnchoredPopover(anchorRef, panelRef, { width, gap = DEFAULT
|
|
|
5821
5829
|
const resizeObserver = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
|
|
5822
5830
|
resizeObserver?.observe(anchor);
|
|
5823
5831
|
if (panelRef.current) resizeObserver?.observe(panelRef.current);
|
|
5832
|
+
if (alignRef?.current) resizeObserver?.observe(alignRef.current);
|
|
5824
5833
|
return () => {
|
|
5825
5834
|
window.removeEventListener("resize", measure);
|
|
5826
5835
|
window.removeEventListener("scroll", measure, true);
|
|
5827
5836
|
resizeObserver?.disconnect();
|
|
5828
5837
|
};
|
|
5829
|
-
}, [anchorRef, panelRef, width, gap, inset]);
|
|
5838
|
+
}, [anchorRef, panelRef, alignRef, width, gap, inset]);
|
|
5830
5839
|
return state;
|
|
5831
5840
|
}
|
|
5832
5841
|
function useStreamoidAnchoredPopoverPosition(anchorRef, panelRef, { width, gap = DEFAULT_GAP, inset = DEFAULT_INSET }) {
|