@vuu-ui/vuu-ui-controls 1.0.3 → 2.0.0
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/cjs/column-picker/ColumnPicker.css.js +1 -1
- package/cjs/hover-overlay/HoverOverlay.js +2 -1
- package/cjs/hover-overlay/HoverOverlay.js.map +1 -1
- package/cjs/measured-container/useMeasuredContainer.js +1 -2
- package/cjs/measured-container/useMeasuredContainer.js.map +1 -1
- package/esm/column-picker/ColumnPicker.css.js +1 -1
- package/esm/hover-overlay/HoverOverlay.js +2 -1
- package/esm/hover-overlay/HoverOverlay.js.map +1 -1
- package/esm/measured-container/useMeasuredContainer.js +1 -2
- package/esm/measured-container/useMeasuredContainer.js.map +1 -1
- package/package.json +10 -10
- package/types/hover-overlay/HoverOverlay.d.ts +2 -2
- package/cjs/measured-container/useResizeObserver.js +0 -130
- package/cjs/measured-container/useResizeObserver.js.map +0 -1
- package/esm/measured-container/useResizeObserver.js +0 -128
- package/esm/measured-container/useResizeObserver.js.map +0 -1
- package/types/measured-container/useResizeObserver.d.ts +0 -15
|
@@ -8,6 +8,7 @@ const HoverOverlay = ({
|
|
|
8
8
|
children,
|
|
9
9
|
open: openProp = false,
|
|
10
10
|
onOpenChange,
|
|
11
|
+
placement = "right",
|
|
11
12
|
trigger
|
|
12
13
|
}) => {
|
|
13
14
|
const [open, _setOpen] = React.useState(openProp);
|
|
@@ -70,7 +71,7 @@ const HoverOverlay = ({
|
|
|
70
71
|
setOpen(false);
|
|
71
72
|
}
|
|
72
73
|
}, [setOpen]);
|
|
73
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(core.Overlay, { placement
|
|
74
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Overlay, { placement, onOpenChange, open, children: [
|
|
74
75
|
/* @__PURE__ */ jsxRuntime.jsx(core.OverlayTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
75
76
|
"div",
|
|
76
77
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverOverlay.js","sources":["../../../../packages/vuu-ui-controls/src/hover-overlay/HoverOverlay.tsx"],"sourcesContent":["import {\n Overlay,\n OverlayPanel,\n OverlayPanelContent,\n OverlayProps,\n OverlayTrigger,\n} from \"@salt-ds/core\";\nimport { ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface HoverOverlayProps
|
|
1
|
+
{"version":3,"file":"HoverOverlay.js","sources":["../../../../packages/vuu-ui-controls/src/hover-overlay/HoverOverlay.tsx"],"sourcesContent":["import {\n Overlay,\n OverlayPanel,\n OverlayPanelContent,\n OverlayProps,\n OverlayTrigger,\n} from \"@salt-ds/core\";\nimport { ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface HoverOverlayProps\n extends Pick<OverlayProps, \"placement\" | \"onOpenChange\"> {\n children: ReactNode;\n open?: boolean;\n trigger: ReactNode;\n}\n\nexport const HoverOverlay = ({\n children,\n open: openProp = false,\n onOpenChange,\n placement = \"right\",\n trigger,\n}: HoverOverlayProps) => {\n const [open, _setOpen] = useState(openProp);\n const isOpen = useRef(false);\n const showHandle = useRef<ReturnType<typeof setTimeout>>(undefined);\n const hideHandle = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const setOpen = useCallback(\n (open: boolean) => {\n if (open !== isOpen.current) {\n isOpen.current = open;\n _setOpen(open);\n onOpenChange?.(open);\n }\n },\n [onOpenChange],\n );\n\n useEffect(() => {\n if (openProp !== isOpen.current) {\n setOpen(openProp);\n }\n }, [openProp, setOpen]);\n\n const handleOverlayMouseEnter = useCallback(() => {\n if (hideHandle.current) {\n clearTimeout(hideHandle.current);\n hideHandle.current = undefined;\n }\n }, []);\n\n const handleOverlayMouseLeave = useCallback(() => {\n hideHandle.current = setTimeout(() => {\n setOpen(false);\n hideHandle.current = undefined;\n }, 300);\n }, [setOpen]);\n\n const handleMouseEnter = useCallback(() => {\n showHandle.current = setTimeout(() => {\n setOpen(true);\n showHandle.current = undefined;\n }, 400);\n if (hideHandle.current) {\n clearTimeout(hideHandle.current);\n hideHandle.current = undefined;\n }\n }, [setOpen]);\n\n const handleMouseLeave = useCallback(() => {\n if (showHandle.current) {\n clearTimeout(showHandle.current);\n showHandle.current = undefined;\n } else if (isOpen.current) {\n hideHandle.current = setTimeout(() => {\n setOpen(false);\n hideHandle.current = undefined;\n }, 300);\n }\n }, [setOpen]);\n\n const handleClick = useCallback(() => {\n if (showHandle.current) {\n clearTimeout(showHandle.current);\n showHandle.current = undefined;\n } else if (isOpen.current) {\n setOpen(false);\n }\n }, [setOpen]);\n\n return (\n <Overlay placement={placement} onOpenChange={onOpenChange} open={open}>\n <OverlayTrigger>\n <div\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {trigger}\n </div>\n </OverlayTrigger>\n <OverlayPanel>\n <OverlayPanelContent\n onMouseEnter={handleOverlayMouseEnter}\n onMouseLeave={handleOverlayMouseLeave}\n >\n {children}\n </OverlayPanelContent>\n </OverlayPanel>\n </Overlay>\n );\n};\n"],"names":["useState","useRef","useCallback","open","useEffect","jsxs","Overlay","jsx","OverlayTrigger","OverlayPanel","OverlayPanelContent"],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var useResizeObserver = require('./useResizeObserver.js');
|
|
6
5
|
|
|
7
6
|
const ClientWidthHeight = ["clientHeight", "clientWidth"];
|
|
8
7
|
const WidthOnly = ["clientWidth"];
|
|
@@ -154,7 +153,7 @@ const useMeasuredContainer = ({
|
|
|
154
153
|
}
|
|
155
154
|
}
|
|
156
155
|
}, [height, onResizeProp, size.inner]);
|
|
157
|
-
|
|
156
|
+
vuuUtils.useResizeObserver(containerRef, dimensions, onResize, true);
|
|
158
157
|
return {
|
|
159
158
|
containerRef,
|
|
160
159
|
cssSize: size.css,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMeasuredContainer.js","sources":["../../../../packages/vuu-ui-controls/src/measured-container/useMeasuredContainer.ts"],"sourcesContent":["import { isValidNumber } from \"@vuu-ui/vuu-utils\";\nimport {\n CSSProperties,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { MeasuredContainerProps } from \"./MeasuredContainer\";\nimport { useResizeObserver, ResizeHandler } from \"./useResizeObserver\";\n\nconst ClientWidthHeight = [\"clientHeight\", \"clientWidth\"];\nconst WidthOnly = [\"clientWidth\"];\nconst HeightOnly = [\"clientHeight\"];\nconst NO_MEASUREMENT = [] as const;\n\nexport interface ClientSize {\n clientHeight: number;\n clientWidth: number;\n}\n\nconst NullClientSize: Partial<ClientSize> = {\n clientHeight: -1,\n clientWidth: -1,\n};\n\nexport interface MeasuredProps\n extends Pick<\n MeasuredContainerProps,\n \"height\" | \"onResize\" | \"resizeStrategy\" | \"width\"\n > {\n defaultHeight?: number;\n defaultWidth?: number;\n}\n\nexport type CssSize = Pick<CSSProperties, \"height\" | \"width\">;\n\nexport interface MeasuredSize {\n height: number;\n width: number;\n}\n\ninterface MeasuredState {\n css: CssSize;\n outer: CssSize;\n inner?: MeasuredSize;\n}\n\nconst isNumber = (val: unknown): val is number => Number.isFinite(val);\n\nexport interface MeasuredContainerHookResult {\n containerRef: RefObject<HTMLDivElement | null>;\n cssSize: CssSize;\n outerSize: CssSize;\n innerSize?: MeasuredSize;\n}\n\nexport const reduceSizeHeight = (\n size: MeasuredSize,\n value: number,\n): MeasuredSize => {\n if (value === 0) {\n return size;\n } else {\n return {\n height: size.height - value,\n width: size.width,\n };\n }\n};\n\nconst getInitialValue = (\n value: number | string | undefined,\n defaultValue: \"auto\" | \"100%\",\n) => {\n if (isValidNumber(value)) {\n return `${value}px`;\n } else if (typeof value === \"string\") {\n return value;\n } else {\n return defaultValue;\n }\n};\n\n// If (outer) height and width are known at initialisation (i.e. they\n// were passed as props), use as initial values for inner size. If there\n// is no border on Table, these values will not change. If there is a border,\n// inner values will be updated once measured.\nconst getInitialCssSize = (\n height?: number | string,\n width?: number | string,\n): CssSize => {\n return {\n height: getInitialValue(height, \"100%\"),\n width: getInitialValue(width, \"auto\"),\n };\n};\n\nconst getInitialInnerSize = (\n height: unknown,\n width: unknown,\n): MeasuredSize | undefined => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height,\n width,\n };\n }\n};\n\nexport const useMeasuredContainer = ({\n defaultHeight = 0,\n defaultWidth = 0,\n height,\n onResize: onResizeProp,\n resizeStrategy = \"responsive\",\n width,\n}: MeasuredProps): MeasuredContainerHookResult => {\n const deferResize = resizeStrategy === \"defer\";\n const sizeRef = useRef<Partial<ClientSize>>(NullClientSize);\n const resizeHandleRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<MeasuredState>({\n css: getInitialCssSize(height, width),\n inner: getInitialInnerSize(height, width),\n outer: {\n height: height ?? \"100%\",\n width: width ?? \"auto\",\n },\n });\n\n const fixedHeight = typeof height === \"number\";\n const fixedWidth = typeof width === \"number\";\n\n const dimensions =\n fixedHeight && fixedWidth\n ? NO_MEASUREMENT\n : fixedHeight\n ? WidthOnly\n : fixedWidth\n ? HeightOnly\n : ClientWidthHeight;\n\n useMemo(() => {\n // TODO why call state from memo.\n // Why not calculate size first inline, then assign that to state\n // on first pass\n setSize((currentSize) => {\n const { inner, outer } = currentSize;\n if (isValidNumber(height) && isValidNumber(width) && inner && outer) {\n const { height: innerHeight, width: innerWidth } = inner;\n const { height: outerHeight, width: outerWidth } = outer;\n\n if (outerHeight !== height || outerWidth !== width) {\n const heightDiff = isValidNumber(outerHeight)\n ? outerHeight - innerHeight\n : 0;\n const widthDiff = isValidNumber(outerWidth)\n ? outerWidth - innerWidth\n : 0;\n return {\n ...currentSize,\n outer: { height, width },\n inner: { height: height - heightDiff, width: width - widthDiff },\n };\n }\n }\n return currentSize;\n });\n }, [height, width]);\n\n const handleResize = useCallback(\n (clientWidth: number | undefined, clientHeight: number | undefined) => {\n const { css, inner, outer } = size;\n let newState: MeasuredState = size;\n if (\n fixedHeight &&\n isNumber(clientWidth) &&\n Math.floor(clientWidth) !== inner?.width\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height,\n },\n };\n } else if (\n fixedWidth &&\n isNumber(clientHeight) &&\n Math.floor(clientHeight) !== inner?.height\n ) {\n newState = {\n css,\n outer,\n inner: {\n height: Math.floor(clientHeight) || defaultHeight,\n width,\n },\n };\n } else if (\n isNumber(clientHeight) &&\n isNumber(clientWidth) &&\n (clientWidth !== inner?.width || clientHeight !== inner?.height)\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height: Math.floor(clientHeight) || defaultHeight,\n },\n };\n }\n\n if (newState !== size) {\n setSize(newState);\n }\n },\n [defaultHeight, defaultWidth, fixedHeight, fixedWidth, height, size, width],\n );\n\n const onResize: ResizeHandler = useCallback(\n ({ clientHeight, clientWidth }: Partial<ClientSize>) => {\n if (deferResize) {\n sizeRef.current.clientHeight = clientHeight;\n sizeRef.current.clientWidth = clientWidth;\n //\n if (resizeHandleRef.current !== null) {\n clearTimeout(resizeHandleRef.current);\n }\n resizeHandleRef.current = setTimeout(() => {\n handleResize(clientWidth, clientHeight);\n }, 40);\n } else {\n handleResize(clientWidth, clientHeight);\n }\n },\n [deferResize, handleResize],\n );\n\n useEffect(() => {\n if (size.inner) {\n if (containerRef.current) {\n if (typeof height !== \"number\" || height === 0) {\n size.inner.height = containerRef.current.clientHeight;\n }\n size.inner.width = containerRef.current.clientWidth;\n onResizeProp?.(size.inner);\n }\n }\n }, [height, onResizeProp, size.inner]);\n\n useResizeObserver(containerRef, dimensions, onResize, true);\n\n return {\n containerRef,\n cssSize: size.css,\n outerSize: size.outer,\n innerSize: size.inner,\n };\n};\n"],"names":["isValidNumber","useRef","useState","useMemo","useCallback","useEffect","useResizeObserver"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useMeasuredContainer.js","sources":["../../../../packages/vuu-ui-controls/src/measured-container/useMeasuredContainer.ts"],"sourcesContent":["import {\n isValidNumber,\n useResizeObserver,\n type ResizeHandler,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n CSSProperties,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { MeasuredContainerProps } from \"./MeasuredContainer\";\n\nconst ClientWidthHeight = [\"clientHeight\", \"clientWidth\"];\nconst WidthOnly = [\"clientWidth\"];\nconst HeightOnly = [\"clientHeight\"];\nconst NO_MEASUREMENT = [] as const;\n\nexport interface ClientSize {\n clientHeight: number;\n clientWidth: number;\n}\n\nconst NullClientSize: Partial<ClientSize> = {\n clientHeight: -1,\n clientWidth: -1,\n};\n\nexport interface MeasuredProps\n extends Pick<\n MeasuredContainerProps,\n \"height\" | \"onResize\" | \"resizeStrategy\" | \"width\"\n > {\n defaultHeight?: number;\n defaultWidth?: number;\n}\n\nexport type CssSize = Pick<CSSProperties, \"height\" | \"width\">;\n\nexport interface MeasuredSize {\n height: number;\n width: number;\n}\n\ninterface MeasuredState {\n css: CssSize;\n outer: CssSize;\n inner?: MeasuredSize;\n}\n\nconst isNumber = (val: unknown): val is number => Number.isFinite(val);\n\nexport interface MeasuredContainerHookResult {\n containerRef: RefObject<HTMLDivElement | null>;\n cssSize: CssSize;\n outerSize: CssSize;\n innerSize?: MeasuredSize;\n}\n\nexport const reduceSizeHeight = (\n size: MeasuredSize,\n value: number,\n): MeasuredSize => {\n if (value === 0) {\n return size;\n } else {\n return {\n height: size.height - value,\n width: size.width,\n };\n }\n};\n\nconst getInitialValue = (\n value: number | string | undefined,\n defaultValue: \"auto\" | \"100%\",\n) => {\n if (isValidNumber(value)) {\n return `${value}px`;\n } else if (typeof value === \"string\") {\n return value;\n } else {\n return defaultValue;\n }\n};\n\n// If (outer) height and width are known at initialisation (i.e. they\n// were passed as props), use as initial values for inner size. If there\n// is no border on Table, these values will not change. If there is a border,\n// inner values will be updated once measured.\nconst getInitialCssSize = (\n height?: number | string,\n width?: number | string,\n): CssSize => {\n return {\n height: getInitialValue(height, \"100%\"),\n width: getInitialValue(width, \"auto\"),\n };\n};\n\nconst getInitialInnerSize = (\n height: unknown,\n width: unknown,\n): MeasuredSize | undefined => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height,\n width,\n };\n }\n};\n\nexport const useMeasuredContainer = ({\n defaultHeight = 0,\n defaultWidth = 0,\n height,\n onResize: onResizeProp,\n resizeStrategy = \"responsive\",\n width,\n}: MeasuredProps): MeasuredContainerHookResult => {\n const deferResize = resizeStrategy === \"defer\";\n const sizeRef = useRef<Partial<ClientSize>>(NullClientSize);\n const resizeHandleRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<MeasuredState>({\n css: getInitialCssSize(height, width),\n inner: getInitialInnerSize(height, width),\n outer: {\n height: height ?? \"100%\",\n width: width ?? \"auto\",\n },\n });\n\n const fixedHeight = typeof height === \"number\";\n const fixedWidth = typeof width === \"number\";\n\n const dimensions =\n fixedHeight && fixedWidth\n ? NO_MEASUREMENT\n : fixedHeight\n ? WidthOnly\n : fixedWidth\n ? HeightOnly\n : ClientWidthHeight;\n\n useMemo(() => {\n // TODO why call state from memo.\n // Why not calculate size first inline, then assign that to state\n // on first pass\n setSize((currentSize) => {\n const { inner, outer } = currentSize;\n if (isValidNumber(height) && isValidNumber(width) && inner && outer) {\n const { height: innerHeight, width: innerWidth } = inner;\n const { height: outerHeight, width: outerWidth } = outer;\n\n if (outerHeight !== height || outerWidth !== width) {\n const heightDiff = isValidNumber(outerHeight)\n ? outerHeight - innerHeight\n : 0;\n const widthDiff = isValidNumber(outerWidth)\n ? outerWidth - innerWidth\n : 0;\n return {\n ...currentSize,\n outer: { height, width },\n inner: { height: height - heightDiff, width: width - widthDiff },\n };\n }\n }\n return currentSize;\n });\n }, [height, width]);\n\n const handleResize = useCallback(\n (clientWidth: number | undefined, clientHeight: number | undefined) => {\n const { css, inner, outer } = size;\n let newState: MeasuredState = size;\n if (\n fixedHeight &&\n isNumber(clientWidth) &&\n Math.floor(clientWidth) !== inner?.width\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height,\n },\n };\n } else if (\n fixedWidth &&\n isNumber(clientHeight) &&\n Math.floor(clientHeight) !== inner?.height\n ) {\n newState = {\n css,\n outer,\n inner: {\n height: Math.floor(clientHeight) || defaultHeight,\n width,\n },\n };\n } else if (\n isNumber(clientHeight) &&\n isNumber(clientWidth) &&\n (clientWidth !== inner?.width || clientHeight !== inner?.height)\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height: Math.floor(clientHeight) || defaultHeight,\n },\n };\n }\n\n if (newState !== size) {\n setSize(newState);\n }\n },\n [defaultHeight, defaultWidth, fixedHeight, fixedWidth, height, size, width],\n );\n\n const onResize: ResizeHandler = useCallback(\n ({ clientHeight, clientWidth }: Partial<ClientSize>) => {\n if (deferResize) {\n sizeRef.current.clientHeight = clientHeight;\n sizeRef.current.clientWidth = clientWidth;\n //\n if (resizeHandleRef.current !== null) {\n clearTimeout(resizeHandleRef.current);\n }\n resizeHandleRef.current = setTimeout(() => {\n handleResize(clientWidth, clientHeight);\n }, 40);\n } else {\n handleResize(clientWidth, clientHeight);\n }\n },\n [deferResize, handleResize],\n );\n\n useEffect(() => {\n if (size.inner) {\n if (containerRef.current) {\n if (typeof height !== \"number\" || height === 0) {\n size.inner.height = containerRef.current.clientHeight;\n }\n size.inner.width = containerRef.current.clientWidth;\n onResizeProp?.(size.inner);\n }\n }\n }, [height, onResizeProp, size.inner]);\n\n useResizeObserver(containerRef, dimensions, onResize, true);\n\n return {\n containerRef,\n cssSize: size.css,\n outerSize: size.outer,\n innerSize: size.inner,\n };\n};\n"],"names":["isValidNumber","useRef","useState","useMemo","useCallback","useEffect","useResizeObserver"],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ const HoverOverlay = ({
|
|
|
6
6
|
children,
|
|
7
7
|
open: openProp = false,
|
|
8
8
|
onOpenChange,
|
|
9
|
+
placement = "right",
|
|
9
10
|
trigger
|
|
10
11
|
}) => {
|
|
11
12
|
const [open, _setOpen] = useState(openProp);
|
|
@@ -68,7 +69,7 @@ const HoverOverlay = ({
|
|
|
68
69
|
setOpen(false);
|
|
69
70
|
}
|
|
70
71
|
}, [setOpen]);
|
|
71
|
-
return /* @__PURE__ */ jsxs(Overlay, { placement
|
|
72
|
+
return /* @__PURE__ */ jsxs(Overlay, { placement, onOpenChange, open, children: [
|
|
72
73
|
/* @__PURE__ */ jsx(OverlayTrigger, { children: /* @__PURE__ */ jsx(
|
|
73
74
|
"div",
|
|
74
75
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverOverlay.js","sources":["../../../../packages/vuu-ui-controls/src/hover-overlay/HoverOverlay.tsx"],"sourcesContent":["import {\n Overlay,\n OverlayPanel,\n OverlayPanelContent,\n OverlayProps,\n OverlayTrigger,\n} from \"@salt-ds/core\";\nimport { ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface HoverOverlayProps
|
|
1
|
+
{"version":3,"file":"HoverOverlay.js","sources":["../../../../packages/vuu-ui-controls/src/hover-overlay/HoverOverlay.tsx"],"sourcesContent":["import {\n Overlay,\n OverlayPanel,\n OverlayPanelContent,\n OverlayProps,\n OverlayTrigger,\n} from \"@salt-ds/core\";\nimport { ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface HoverOverlayProps\n extends Pick<OverlayProps, \"placement\" | \"onOpenChange\"> {\n children: ReactNode;\n open?: boolean;\n trigger: ReactNode;\n}\n\nexport const HoverOverlay = ({\n children,\n open: openProp = false,\n onOpenChange,\n placement = \"right\",\n trigger,\n}: HoverOverlayProps) => {\n const [open, _setOpen] = useState(openProp);\n const isOpen = useRef(false);\n const showHandle = useRef<ReturnType<typeof setTimeout>>(undefined);\n const hideHandle = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const setOpen = useCallback(\n (open: boolean) => {\n if (open !== isOpen.current) {\n isOpen.current = open;\n _setOpen(open);\n onOpenChange?.(open);\n }\n },\n [onOpenChange],\n );\n\n useEffect(() => {\n if (openProp !== isOpen.current) {\n setOpen(openProp);\n }\n }, [openProp, setOpen]);\n\n const handleOverlayMouseEnter = useCallback(() => {\n if (hideHandle.current) {\n clearTimeout(hideHandle.current);\n hideHandle.current = undefined;\n }\n }, []);\n\n const handleOverlayMouseLeave = useCallback(() => {\n hideHandle.current = setTimeout(() => {\n setOpen(false);\n hideHandle.current = undefined;\n }, 300);\n }, [setOpen]);\n\n const handleMouseEnter = useCallback(() => {\n showHandle.current = setTimeout(() => {\n setOpen(true);\n showHandle.current = undefined;\n }, 400);\n if (hideHandle.current) {\n clearTimeout(hideHandle.current);\n hideHandle.current = undefined;\n }\n }, [setOpen]);\n\n const handleMouseLeave = useCallback(() => {\n if (showHandle.current) {\n clearTimeout(showHandle.current);\n showHandle.current = undefined;\n } else if (isOpen.current) {\n hideHandle.current = setTimeout(() => {\n setOpen(false);\n hideHandle.current = undefined;\n }, 300);\n }\n }, [setOpen]);\n\n const handleClick = useCallback(() => {\n if (showHandle.current) {\n clearTimeout(showHandle.current);\n showHandle.current = undefined;\n } else if (isOpen.current) {\n setOpen(false);\n }\n }, [setOpen]);\n\n return (\n <Overlay placement={placement} onOpenChange={onOpenChange} open={open}>\n <OverlayTrigger>\n <div\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {trigger}\n </div>\n </OverlayTrigger>\n <OverlayPanel>\n <OverlayPanelContent\n onMouseEnter={handleOverlayMouseEnter}\n onMouseLeave={handleOverlayMouseLeave}\n >\n {children}\n </OverlayPanelContent>\n </OverlayPanel>\n </Overlay>\n );\n};\n"],"names":["open"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { isValidNumber } from '@vuu-ui/vuu-utils';
|
|
1
|
+
import { isValidNumber, useResizeObserver } from '@vuu-ui/vuu-utils';
|
|
2
2
|
import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
|
|
3
|
-
import { useResizeObserver } from './useResizeObserver.js';
|
|
4
3
|
|
|
5
4
|
const ClientWidthHeight = ["clientHeight", "clientWidth"];
|
|
6
5
|
const WidthOnly = ["clientWidth"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMeasuredContainer.js","sources":["../../../../packages/vuu-ui-controls/src/measured-container/useMeasuredContainer.ts"],"sourcesContent":["import { isValidNumber } from \"@vuu-ui/vuu-utils\";\nimport {\n CSSProperties,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { MeasuredContainerProps } from \"./MeasuredContainer\";\nimport { useResizeObserver, ResizeHandler } from \"./useResizeObserver\";\n\nconst ClientWidthHeight = [\"clientHeight\", \"clientWidth\"];\nconst WidthOnly = [\"clientWidth\"];\nconst HeightOnly = [\"clientHeight\"];\nconst NO_MEASUREMENT = [] as const;\n\nexport interface ClientSize {\n clientHeight: number;\n clientWidth: number;\n}\n\nconst NullClientSize: Partial<ClientSize> = {\n clientHeight: -1,\n clientWidth: -1,\n};\n\nexport interface MeasuredProps\n extends Pick<\n MeasuredContainerProps,\n \"height\" | \"onResize\" | \"resizeStrategy\" | \"width\"\n > {\n defaultHeight?: number;\n defaultWidth?: number;\n}\n\nexport type CssSize = Pick<CSSProperties, \"height\" | \"width\">;\n\nexport interface MeasuredSize {\n height: number;\n width: number;\n}\n\ninterface MeasuredState {\n css: CssSize;\n outer: CssSize;\n inner?: MeasuredSize;\n}\n\nconst isNumber = (val: unknown): val is number => Number.isFinite(val);\n\nexport interface MeasuredContainerHookResult {\n containerRef: RefObject<HTMLDivElement | null>;\n cssSize: CssSize;\n outerSize: CssSize;\n innerSize?: MeasuredSize;\n}\n\nexport const reduceSizeHeight = (\n size: MeasuredSize,\n value: number,\n): MeasuredSize => {\n if (value === 0) {\n return size;\n } else {\n return {\n height: size.height - value,\n width: size.width,\n };\n }\n};\n\nconst getInitialValue = (\n value: number | string | undefined,\n defaultValue: \"auto\" | \"100%\",\n) => {\n if (isValidNumber(value)) {\n return `${value}px`;\n } else if (typeof value === \"string\") {\n return value;\n } else {\n return defaultValue;\n }\n};\n\n// If (outer) height and width are known at initialisation (i.e. they\n// were passed as props), use as initial values for inner size. If there\n// is no border on Table, these values will not change. If there is a border,\n// inner values will be updated once measured.\nconst getInitialCssSize = (\n height?: number | string,\n width?: number | string,\n): CssSize => {\n return {\n height: getInitialValue(height, \"100%\"),\n width: getInitialValue(width, \"auto\"),\n };\n};\n\nconst getInitialInnerSize = (\n height: unknown,\n width: unknown,\n): MeasuredSize | undefined => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height,\n width,\n };\n }\n};\n\nexport const useMeasuredContainer = ({\n defaultHeight = 0,\n defaultWidth = 0,\n height,\n onResize: onResizeProp,\n resizeStrategy = \"responsive\",\n width,\n}: MeasuredProps): MeasuredContainerHookResult => {\n const deferResize = resizeStrategy === \"defer\";\n const sizeRef = useRef<Partial<ClientSize>>(NullClientSize);\n const resizeHandleRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<MeasuredState>({\n css: getInitialCssSize(height, width),\n inner: getInitialInnerSize(height, width),\n outer: {\n height: height ?? \"100%\",\n width: width ?? \"auto\",\n },\n });\n\n const fixedHeight = typeof height === \"number\";\n const fixedWidth = typeof width === \"number\";\n\n const dimensions =\n fixedHeight && fixedWidth\n ? NO_MEASUREMENT\n : fixedHeight\n ? WidthOnly\n : fixedWidth\n ? HeightOnly\n : ClientWidthHeight;\n\n useMemo(() => {\n // TODO why call state from memo.\n // Why not calculate size first inline, then assign that to state\n // on first pass\n setSize((currentSize) => {\n const { inner, outer } = currentSize;\n if (isValidNumber(height) && isValidNumber(width) && inner && outer) {\n const { height: innerHeight, width: innerWidth } = inner;\n const { height: outerHeight, width: outerWidth } = outer;\n\n if (outerHeight !== height || outerWidth !== width) {\n const heightDiff = isValidNumber(outerHeight)\n ? outerHeight - innerHeight\n : 0;\n const widthDiff = isValidNumber(outerWidth)\n ? outerWidth - innerWidth\n : 0;\n return {\n ...currentSize,\n outer: { height, width },\n inner: { height: height - heightDiff, width: width - widthDiff },\n };\n }\n }\n return currentSize;\n });\n }, [height, width]);\n\n const handleResize = useCallback(\n (clientWidth: number | undefined, clientHeight: number | undefined) => {\n const { css, inner, outer } = size;\n let newState: MeasuredState = size;\n if (\n fixedHeight &&\n isNumber(clientWidth) &&\n Math.floor(clientWidth) !== inner?.width\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height,\n },\n };\n } else if (\n fixedWidth &&\n isNumber(clientHeight) &&\n Math.floor(clientHeight) !== inner?.height\n ) {\n newState = {\n css,\n outer,\n inner: {\n height: Math.floor(clientHeight) || defaultHeight,\n width,\n },\n };\n } else if (\n isNumber(clientHeight) &&\n isNumber(clientWidth) &&\n (clientWidth !== inner?.width || clientHeight !== inner?.height)\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height: Math.floor(clientHeight) || defaultHeight,\n },\n };\n }\n\n if (newState !== size) {\n setSize(newState);\n }\n },\n [defaultHeight, defaultWidth, fixedHeight, fixedWidth, height, size, width],\n );\n\n const onResize: ResizeHandler = useCallback(\n ({ clientHeight, clientWidth }: Partial<ClientSize>) => {\n if (deferResize) {\n sizeRef.current.clientHeight = clientHeight;\n sizeRef.current.clientWidth = clientWidth;\n //\n if (resizeHandleRef.current !== null) {\n clearTimeout(resizeHandleRef.current);\n }\n resizeHandleRef.current = setTimeout(() => {\n handleResize(clientWidth, clientHeight);\n }, 40);\n } else {\n handleResize(clientWidth, clientHeight);\n }\n },\n [deferResize, handleResize],\n );\n\n useEffect(() => {\n if (size.inner) {\n if (containerRef.current) {\n if (typeof height !== \"number\" || height === 0) {\n size.inner.height = containerRef.current.clientHeight;\n }\n size.inner.width = containerRef.current.clientWidth;\n onResizeProp?.(size.inner);\n }\n }\n }, [height, onResizeProp, size.inner]);\n\n useResizeObserver(containerRef, dimensions, onResize, true);\n\n return {\n containerRef,\n cssSize: size.css,\n outerSize: size.outer,\n innerSize: size.inner,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useMeasuredContainer.js","sources":["../../../../packages/vuu-ui-controls/src/measured-container/useMeasuredContainer.ts"],"sourcesContent":["import {\n isValidNumber,\n useResizeObserver,\n type ResizeHandler,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n CSSProperties,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { MeasuredContainerProps } from \"./MeasuredContainer\";\n\nconst ClientWidthHeight = [\"clientHeight\", \"clientWidth\"];\nconst WidthOnly = [\"clientWidth\"];\nconst HeightOnly = [\"clientHeight\"];\nconst NO_MEASUREMENT = [] as const;\n\nexport interface ClientSize {\n clientHeight: number;\n clientWidth: number;\n}\n\nconst NullClientSize: Partial<ClientSize> = {\n clientHeight: -1,\n clientWidth: -1,\n};\n\nexport interface MeasuredProps\n extends Pick<\n MeasuredContainerProps,\n \"height\" | \"onResize\" | \"resizeStrategy\" | \"width\"\n > {\n defaultHeight?: number;\n defaultWidth?: number;\n}\n\nexport type CssSize = Pick<CSSProperties, \"height\" | \"width\">;\n\nexport interface MeasuredSize {\n height: number;\n width: number;\n}\n\ninterface MeasuredState {\n css: CssSize;\n outer: CssSize;\n inner?: MeasuredSize;\n}\n\nconst isNumber = (val: unknown): val is number => Number.isFinite(val);\n\nexport interface MeasuredContainerHookResult {\n containerRef: RefObject<HTMLDivElement | null>;\n cssSize: CssSize;\n outerSize: CssSize;\n innerSize?: MeasuredSize;\n}\n\nexport const reduceSizeHeight = (\n size: MeasuredSize,\n value: number,\n): MeasuredSize => {\n if (value === 0) {\n return size;\n } else {\n return {\n height: size.height - value,\n width: size.width,\n };\n }\n};\n\nconst getInitialValue = (\n value: number | string | undefined,\n defaultValue: \"auto\" | \"100%\",\n) => {\n if (isValidNumber(value)) {\n return `${value}px`;\n } else if (typeof value === \"string\") {\n return value;\n } else {\n return defaultValue;\n }\n};\n\n// If (outer) height and width are known at initialisation (i.e. they\n// were passed as props), use as initial values for inner size. If there\n// is no border on Table, these values will not change. If there is a border,\n// inner values will be updated once measured.\nconst getInitialCssSize = (\n height?: number | string,\n width?: number | string,\n): CssSize => {\n return {\n height: getInitialValue(height, \"100%\"),\n width: getInitialValue(width, \"auto\"),\n };\n};\n\nconst getInitialInnerSize = (\n height: unknown,\n width: unknown,\n): MeasuredSize | undefined => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height,\n width,\n };\n }\n};\n\nexport const useMeasuredContainer = ({\n defaultHeight = 0,\n defaultWidth = 0,\n height,\n onResize: onResizeProp,\n resizeStrategy = \"responsive\",\n width,\n}: MeasuredProps): MeasuredContainerHookResult => {\n const deferResize = resizeStrategy === \"defer\";\n const sizeRef = useRef<Partial<ClientSize>>(NullClientSize);\n const resizeHandleRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<MeasuredState>({\n css: getInitialCssSize(height, width),\n inner: getInitialInnerSize(height, width),\n outer: {\n height: height ?? \"100%\",\n width: width ?? \"auto\",\n },\n });\n\n const fixedHeight = typeof height === \"number\";\n const fixedWidth = typeof width === \"number\";\n\n const dimensions =\n fixedHeight && fixedWidth\n ? NO_MEASUREMENT\n : fixedHeight\n ? WidthOnly\n : fixedWidth\n ? HeightOnly\n : ClientWidthHeight;\n\n useMemo(() => {\n // TODO why call state from memo.\n // Why not calculate size first inline, then assign that to state\n // on first pass\n setSize((currentSize) => {\n const { inner, outer } = currentSize;\n if (isValidNumber(height) && isValidNumber(width) && inner && outer) {\n const { height: innerHeight, width: innerWidth } = inner;\n const { height: outerHeight, width: outerWidth } = outer;\n\n if (outerHeight !== height || outerWidth !== width) {\n const heightDiff = isValidNumber(outerHeight)\n ? outerHeight - innerHeight\n : 0;\n const widthDiff = isValidNumber(outerWidth)\n ? outerWidth - innerWidth\n : 0;\n return {\n ...currentSize,\n outer: { height, width },\n inner: { height: height - heightDiff, width: width - widthDiff },\n };\n }\n }\n return currentSize;\n });\n }, [height, width]);\n\n const handleResize = useCallback(\n (clientWidth: number | undefined, clientHeight: number | undefined) => {\n const { css, inner, outer } = size;\n let newState: MeasuredState = size;\n if (\n fixedHeight &&\n isNumber(clientWidth) &&\n Math.floor(clientWidth) !== inner?.width\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height,\n },\n };\n } else if (\n fixedWidth &&\n isNumber(clientHeight) &&\n Math.floor(clientHeight) !== inner?.height\n ) {\n newState = {\n css,\n outer,\n inner: {\n height: Math.floor(clientHeight) || defaultHeight,\n width,\n },\n };\n } else if (\n isNumber(clientHeight) &&\n isNumber(clientWidth) &&\n (clientWidth !== inner?.width || clientHeight !== inner?.height)\n ) {\n newState = {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height: Math.floor(clientHeight) || defaultHeight,\n },\n };\n }\n\n if (newState !== size) {\n setSize(newState);\n }\n },\n [defaultHeight, defaultWidth, fixedHeight, fixedWidth, height, size, width],\n );\n\n const onResize: ResizeHandler = useCallback(\n ({ clientHeight, clientWidth }: Partial<ClientSize>) => {\n if (deferResize) {\n sizeRef.current.clientHeight = clientHeight;\n sizeRef.current.clientWidth = clientWidth;\n //\n if (resizeHandleRef.current !== null) {\n clearTimeout(resizeHandleRef.current);\n }\n resizeHandleRef.current = setTimeout(() => {\n handleResize(clientWidth, clientHeight);\n }, 40);\n } else {\n handleResize(clientWidth, clientHeight);\n }\n },\n [deferResize, handleResize],\n );\n\n useEffect(() => {\n if (size.inner) {\n if (containerRef.current) {\n if (typeof height !== \"number\" || height === 0) {\n size.inner.height = containerRef.current.clientHeight;\n }\n size.inner.width = containerRef.current.clientWidth;\n onResizeProp?.(size.inner);\n }\n }\n }, [height, onResizeProp, size.inner]);\n\n useResizeObserver(containerRef, dimensions, onResize, true);\n\n return {\n containerRef,\n cssSize: size.css,\n outerSize: size.outer,\n innerSize: size.inner,\n };\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "2.0.0",
|
|
3
3
|
"description": "VUU UI Controls",
|
|
4
4
|
"author": "heswell",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@vuu-ui/vuu-data-types": "
|
|
8
|
-
"@vuu-ui/vuu-protocol-types": "
|
|
9
|
-
"@vuu-ui/vuu-table-types": "
|
|
7
|
+
"@vuu-ui/vuu-data-types": "2.0.0",
|
|
8
|
+
"@vuu-ui/vuu-protocol-types": "2.0.0",
|
|
9
|
+
"@vuu-ui/vuu-table-types": "2.0.0"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@vuu-ui/vuu-context-menu": "
|
|
13
|
-
"@vuu-ui/vuu-data-react": "
|
|
14
|
-
"@vuu-ui/vuu-layout": "
|
|
15
|
-
"@vuu-ui/vuu-popups": "
|
|
16
|
-
"@vuu-ui/vuu-table": "
|
|
17
|
-
"@vuu-ui/vuu-utils": "
|
|
12
|
+
"@vuu-ui/vuu-context-menu": "2.0.0",
|
|
13
|
+
"@vuu-ui/vuu-data-react": "2.0.0",
|
|
14
|
+
"@vuu-ui/vuu-layout": "2.0.0",
|
|
15
|
+
"@vuu-ui/vuu-popups": "2.0.0",
|
|
16
|
+
"@vuu-ui/vuu-table": "2.0.0",
|
|
17
|
+
"@vuu-ui/vuu-utils": "2.0.0",
|
|
18
18
|
"@salt-ds/core": "1.54.1",
|
|
19
19
|
"@salt-ds/icons": "1.16.0",
|
|
20
20
|
"@salt-ds/styles": "0.2.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { OverlayProps } from "@salt-ds/core";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
-
export interface HoverOverlayProps extends Pick<OverlayProps, "onOpenChange"> {
|
|
3
|
+
export interface HoverOverlayProps extends Pick<OverlayProps, "placement" | "onOpenChange"> {
|
|
4
4
|
children: ReactNode;
|
|
5
5
|
open?: boolean;
|
|
6
6
|
trigger: ReactNode;
|
|
7
7
|
}
|
|
8
|
-
export declare const HoverOverlay: ({ children, open: openProp, onOpenChange, trigger, }: HoverOverlayProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare const HoverOverlay: ({ children, open: openProp, onOpenChange, placement, trigger, }: HoverOverlayProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var React = require('react');
|
|
4
|
-
|
|
5
|
-
const observedMap = /* @__PURE__ */ new Map();
|
|
6
|
-
const getTargetSize = (element, size, dimension) => {
|
|
7
|
-
switch (dimension) {
|
|
8
|
-
case "height":
|
|
9
|
-
return size.height;
|
|
10
|
-
case "clientHeight":
|
|
11
|
-
return Math.floor(element.clientHeight);
|
|
12
|
-
case "clientWidth":
|
|
13
|
-
return Math.floor(element.clientWidth);
|
|
14
|
-
case "contentHeight":
|
|
15
|
-
return size.contentHeight;
|
|
16
|
-
case "contentWidth":
|
|
17
|
-
return size.contentWidth;
|
|
18
|
-
case "scrollHeight":
|
|
19
|
-
return Math.ceil(Math.floor(element.scrollHeight));
|
|
20
|
-
case "scrollWidth":
|
|
21
|
-
return Math.ceil(Math.floor(element.scrollWidth));
|
|
22
|
-
case "width":
|
|
23
|
-
return size.width;
|
|
24
|
-
default:
|
|
25
|
-
return 0;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
29
|
-
for (const entry of entries) {
|
|
30
|
-
const { target, borderBoxSize, contentBoxSize } = entry;
|
|
31
|
-
const observedTarget = observedMap.get(target);
|
|
32
|
-
if (observedTarget) {
|
|
33
|
-
const [{ blockSize: height, inlineSize: width }] = borderBoxSize;
|
|
34
|
-
const [{ blockSize: contentHeight, inlineSize: contentWidth }] = contentBoxSize;
|
|
35
|
-
const { onResize, measurements } = observedTarget;
|
|
36
|
-
let sizeChanged = false;
|
|
37
|
-
for (const [dimension, size] of Object.entries(measurements)) {
|
|
38
|
-
const newSize = getTargetSize(
|
|
39
|
-
target,
|
|
40
|
-
{ height, width, contentHeight, contentWidth },
|
|
41
|
-
dimension
|
|
42
|
-
);
|
|
43
|
-
if (newSize !== size) {
|
|
44
|
-
sizeChanged = true;
|
|
45
|
-
measurements[dimension] = newSize;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (sizeChanged) {
|
|
49
|
-
onResize && onResize(measurements);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
function useResizeObserver(ref, dimensions, onResize, reportInitialSize = false) {
|
|
55
|
-
const dimensionsRef = React.useRef(dimensions);
|
|
56
|
-
const measure = React.useCallback((target) => {
|
|
57
|
-
const { width, height } = target.getBoundingClientRect();
|
|
58
|
-
const { clientWidth: contentWidth, clientHeight: contentHeight } = target;
|
|
59
|
-
const flooredHeight = Math.floor(height);
|
|
60
|
-
const flooredWidth = Math.floor(width);
|
|
61
|
-
return dimensionsRef.current.reduce(
|
|
62
|
-
(map, dim) => {
|
|
63
|
-
map[dim] = getTargetSize(
|
|
64
|
-
target,
|
|
65
|
-
{
|
|
66
|
-
width: flooredWidth,
|
|
67
|
-
height: flooredHeight,
|
|
68
|
-
contentHeight,
|
|
69
|
-
contentWidth
|
|
70
|
-
},
|
|
71
|
-
dim
|
|
72
|
-
);
|
|
73
|
-
return map;
|
|
74
|
-
},
|
|
75
|
-
{}
|
|
76
|
-
);
|
|
77
|
-
}, []);
|
|
78
|
-
React.useEffect(() => {
|
|
79
|
-
const target = ref.current;
|
|
80
|
-
async function registerObserver() {
|
|
81
|
-
observedMap.set(target, { measurements: {} });
|
|
82
|
-
const observedTarget = observedMap.get(target);
|
|
83
|
-
if (observedTarget) {
|
|
84
|
-
const measurements = measure(target);
|
|
85
|
-
observedTarget.measurements = measurements;
|
|
86
|
-
resizeObserver.observe(target);
|
|
87
|
-
if (reportInitialSize) {
|
|
88
|
-
onResize(measurements);
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
console.log(
|
|
92
|
-
`%cuseResizeObserver an target expected to be under observation wa snot found. This warrants investigation`,
|
|
93
|
-
"font-weight:bold; color:red;"
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (target) {
|
|
98
|
-
if (observedMap.has(target)) {
|
|
99
|
-
console.log(
|
|
100
|
-
`useResizeObserver attemping to observe same element twice`,
|
|
101
|
-
{
|
|
102
|
-
target
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
registerObserver();
|
|
107
|
-
}
|
|
108
|
-
return () => {
|
|
109
|
-
if (target && observedMap.has(target)) {
|
|
110
|
-
resizeObserver.unobserve(target);
|
|
111
|
-
observedMap.delete(target);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}, [measure, ref]);
|
|
115
|
-
React.useEffect(() => {
|
|
116
|
-
const target = ref.current;
|
|
117
|
-
const record = observedMap.get(target);
|
|
118
|
-
if (record) {
|
|
119
|
-
if (dimensionsRef.current !== dimensions) {
|
|
120
|
-
dimensionsRef.current = dimensions;
|
|
121
|
-
const measurements = measure(target);
|
|
122
|
-
record.measurements = measurements;
|
|
123
|
-
}
|
|
124
|
-
record.onResize = onResize;
|
|
125
|
-
}
|
|
126
|
-
}, [dimensions, measure, ref, onResize]);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
exports.useResizeObserver = useResizeObserver;
|
|
130
|
-
//# sourceMappingURL=useResizeObserver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useResizeObserver.js","sources":["../../../../packages/vuu-ui-controls/src/measured-container/useResizeObserver.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef } from \"react\";\n\nexport const WidthHeight = [\"height\", \"width\"];\nexport const WidthOnly = [\"width\"];\n\nexport type measurements<T = string | number> = {\n height?: T;\n clientHeight?: number;\n clientWidth?: number;\n contentHeight?: number;\n contentWidth?: number;\n scrollHeight?: number;\n scrollWidth?: number;\n width?: T;\n};\ntype measuredDimension = keyof measurements<number>;\n\nexport type ResizeHandler = (measurements: measurements<number>) => void;\n\ntype observedDetails = {\n onResize?: ResizeHandler;\n measurements: measurements<number>;\n};\nconst observedMap = new Map<HTMLElement, observedDetails>();\n\nconst getTargetSize = (\n element: HTMLElement,\n size: {\n height: number;\n width: number;\n contentHeight: number;\n contentWidth: number;\n },\n dimension: measuredDimension,\n): number => {\n switch (dimension) {\n case \"height\":\n return size.height;\n case \"clientHeight\":\n return Math.floor(element.clientHeight);\n case \"clientWidth\":\n return Math.floor(element.clientWidth);\n case \"contentHeight\":\n return size.contentHeight;\n case \"contentWidth\":\n return size.contentWidth;\n case \"scrollHeight\":\n return Math.ceil(Math.floor(element.scrollHeight));\n case \"scrollWidth\":\n return Math.ceil(Math.floor(element.scrollWidth));\n case \"width\":\n return size.width;\n default:\n return 0;\n }\n};\n\n// TODO should we make this create-on-demand\nconst resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n const observedTarget = observedMap.get(target as HTMLElement);\n if (observedTarget) {\n const [{ blockSize: height, inlineSize: width }] = borderBoxSize;\n const [{ blockSize: contentHeight, inlineSize: contentWidth }] =\n contentBoxSize;\n const { onResize, measurements } = observedTarget;\n let sizeChanged = false;\n for (const [dimension, size] of Object.entries(measurements)) {\n const newSize = getTargetSize(\n target as HTMLElement,\n { height, width, contentHeight, contentWidth },\n dimension as measuredDimension,\n );\n\n if (newSize !== size) {\n sizeChanged = true;\n measurements[dimension as measuredDimension] = newSize;\n }\n }\n if (sizeChanged) {\n // TODO only return measured sizes\n onResize && onResize(measurements);\n }\n }\n }\n});\n\n// TODO use an optional lag (default to false) to ask to fire onResize\n// with initial size\nexport function useResizeObserver(\n ref: RefObject<Element | HTMLElement | null>,\n dimensions: readonly string[],\n onResize: ResizeHandler,\n reportInitialSize = false,\n) {\n const dimensionsRef = useRef(dimensions);\n\n const measure = useCallback((target: HTMLElement): measurements<number> => {\n const { width, height } = target.getBoundingClientRect();\n const { clientWidth: contentWidth, clientHeight: contentHeight } = target;\n const flooredHeight = Math.floor(height);\n const flooredWidth = Math.floor(width);\n\n return dimensionsRef.current.reduce(\n (map: { [key: string]: number }, dim) => {\n map[dim] = getTargetSize(\n target,\n {\n width: flooredWidth,\n height: flooredHeight,\n contentHeight,\n contentWidth,\n },\n dim as measuredDimension,\n );\n return map;\n },\n {},\n );\n }, []);\n\n // TODO use ref to store resizeHandler here\n // resize handler registered with REsizeObserver will never change\n // use ref to store user onResize callback here\n // resizeHandler will call user callback.current\n\n // Keep this effect separate in case user inadvertently passes different\n // dimensions or callback instance each time - we only ever want to\n // initiate new observation when ref changes.\n useEffect(() => {\n const target = ref.current as HTMLElement;\n async function registerObserver() {\n // Create the map entry immediately. useEffect may fire below\n // before fonts are ready and attempt to update entry\n observedMap.set(target, { measurements: {} as measurements<number> });\n // await document.fonts.ready;\n const observedTarget = observedMap.get(target);\n if (observedTarget) {\n const measurements = measure(target);\n observedTarget.measurements = measurements;\n resizeObserver.observe(target);\n if (reportInitialSize) {\n onResize(measurements);\n }\n } else {\n console.log(\n `%cuseResizeObserver an target expected to be under observation wa snot found. This warrants investigation`,\n \"font-weight:bold; color:red;\",\n );\n }\n }\n\n if (target) {\n // TODO might we want multiple callers to attach a listener to the same element ?\n if (observedMap.has(target)) {\n console.log(\n `useResizeObserver attemping to observe same element twice`,\n {\n target,\n },\n );\n // throw Error(\n // \"useResizeObserver attemping to observe same element twice\"\n // );\n }\n // TODO set a pending entry on map\n registerObserver();\n }\n return () => {\n if (target && observedMap.has(target)) {\n resizeObserver.unobserve(target);\n observedMap.delete(target);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [measure, ref]);\n\n useEffect(() => {\n const target = ref.current as HTMLElement;\n const record = observedMap.get(target);\n if (record) {\n if (dimensionsRef.current !== dimensions) {\n dimensionsRef.current = dimensions;\n const measurements = measure(target);\n record.measurements = measurements;\n }\n // Might not have changed, but no harm ...\n record.onResize = onResize;\n }\n }, [dimensions, measure, ref, onResize]);\n}\n"],"names":["useRef","useCallback","useEffect"],"mappings":"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"}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { useRef, useCallback, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
const observedMap = /* @__PURE__ */ new Map();
|
|
4
|
-
const getTargetSize = (element, size, dimension) => {
|
|
5
|
-
switch (dimension) {
|
|
6
|
-
case "height":
|
|
7
|
-
return size.height;
|
|
8
|
-
case "clientHeight":
|
|
9
|
-
return Math.floor(element.clientHeight);
|
|
10
|
-
case "clientWidth":
|
|
11
|
-
return Math.floor(element.clientWidth);
|
|
12
|
-
case "contentHeight":
|
|
13
|
-
return size.contentHeight;
|
|
14
|
-
case "contentWidth":
|
|
15
|
-
return size.contentWidth;
|
|
16
|
-
case "scrollHeight":
|
|
17
|
-
return Math.ceil(Math.floor(element.scrollHeight));
|
|
18
|
-
case "scrollWidth":
|
|
19
|
-
return Math.ceil(Math.floor(element.scrollWidth));
|
|
20
|
-
case "width":
|
|
21
|
-
return size.width;
|
|
22
|
-
default:
|
|
23
|
-
return 0;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
27
|
-
for (const entry of entries) {
|
|
28
|
-
const { target, borderBoxSize, contentBoxSize } = entry;
|
|
29
|
-
const observedTarget = observedMap.get(target);
|
|
30
|
-
if (observedTarget) {
|
|
31
|
-
const [{ blockSize: height, inlineSize: width }] = borderBoxSize;
|
|
32
|
-
const [{ blockSize: contentHeight, inlineSize: contentWidth }] = contentBoxSize;
|
|
33
|
-
const { onResize, measurements } = observedTarget;
|
|
34
|
-
let sizeChanged = false;
|
|
35
|
-
for (const [dimension, size] of Object.entries(measurements)) {
|
|
36
|
-
const newSize = getTargetSize(
|
|
37
|
-
target,
|
|
38
|
-
{ height, width, contentHeight, contentWidth },
|
|
39
|
-
dimension
|
|
40
|
-
);
|
|
41
|
-
if (newSize !== size) {
|
|
42
|
-
sizeChanged = true;
|
|
43
|
-
measurements[dimension] = newSize;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (sizeChanged) {
|
|
47
|
-
onResize && onResize(measurements);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
function useResizeObserver(ref, dimensions, onResize, reportInitialSize = false) {
|
|
53
|
-
const dimensionsRef = useRef(dimensions);
|
|
54
|
-
const measure = useCallback((target) => {
|
|
55
|
-
const { width, height } = target.getBoundingClientRect();
|
|
56
|
-
const { clientWidth: contentWidth, clientHeight: contentHeight } = target;
|
|
57
|
-
const flooredHeight = Math.floor(height);
|
|
58
|
-
const flooredWidth = Math.floor(width);
|
|
59
|
-
return dimensionsRef.current.reduce(
|
|
60
|
-
(map, dim) => {
|
|
61
|
-
map[dim] = getTargetSize(
|
|
62
|
-
target,
|
|
63
|
-
{
|
|
64
|
-
width: flooredWidth,
|
|
65
|
-
height: flooredHeight,
|
|
66
|
-
contentHeight,
|
|
67
|
-
contentWidth
|
|
68
|
-
},
|
|
69
|
-
dim
|
|
70
|
-
);
|
|
71
|
-
return map;
|
|
72
|
-
},
|
|
73
|
-
{}
|
|
74
|
-
);
|
|
75
|
-
}, []);
|
|
76
|
-
useEffect(() => {
|
|
77
|
-
const target = ref.current;
|
|
78
|
-
async function registerObserver() {
|
|
79
|
-
observedMap.set(target, { measurements: {} });
|
|
80
|
-
const observedTarget = observedMap.get(target);
|
|
81
|
-
if (observedTarget) {
|
|
82
|
-
const measurements = measure(target);
|
|
83
|
-
observedTarget.measurements = measurements;
|
|
84
|
-
resizeObserver.observe(target);
|
|
85
|
-
if (reportInitialSize) {
|
|
86
|
-
onResize(measurements);
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
console.log(
|
|
90
|
-
`%cuseResizeObserver an target expected to be under observation wa snot found. This warrants investigation`,
|
|
91
|
-
"font-weight:bold; color:red;"
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (target) {
|
|
96
|
-
if (observedMap.has(target)) {
|
|
97
|
-
console.log(
|
|
98
|
-
`useResizeObserver attemping to observe same element twice`,
|
|
99
|
-
{
|
|
100
|
-
target
|
|
101
|
-
}
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
registerObserver();
|
|
105
|
-
}
|
|
106
|
-
return () => {
|
|
107
|
-
if (target && observedMap.has(target)) {
|
|
108
|
-
resizeObserver.unobserve(target);
|
|
109
|
-
observedMap.delete(target);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
}, [measure, ref]);
|
|
113
|
-
useEffect(() => {
|
|
114
|
-
const target = ref.current;
|
|
115
|
-
const record = observedMap.get(target);
|
|
116
|
-
if (record) {
|
|
117
|
-
if (dimensionsRef.current !== dimensions) {
|
|
118
|
-
dimensionsRef.current = dimensions;
|
|
119
|
-
const measurements = measure(target);
|
|
120
|
-
record.measurements = measurements;
|
|
121
|
-
}
|
|
122
|
-
record.onResize = onResize;
|
|
123
|
-
}
|
|
124
|
-
}, [dimensions, measure, ref, onResize]);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export { useResizeObserver };
|
|
128
|
-
//# sourceMappingURL=useResizeObserver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useResizeObserver.js","sources":["../../../../packages/vuu-ui-controls/src/measured-container/useResizeObserver.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef } from \"react\";\n\nexport const WidthHeight = [\"height\", \"width\"];\nexport const WidthOnly = [\"width\"];\n\nexport type measurements<T = string | number> = {\n height?: T;\n clientHeight?: number;\n clientWidth?: number;\n contentHeight?: number;\n contentWidth?: number;\n scrollHeight?: number;\n scrollWidth?: number;\n width?: T;\n};\ntype measuredDimension = keyof measurements<number>;\n\nexport type ResizeHandler = (measurements: measurements<number>) => void;\n\ntype observedDetails = {\n onResize?: ResizeHandler;\n measurements: measurements<number>;\n};\nconst observedMap = new Map<HTMLElement, observedDetails>();\n\nconst getTargetSize = (\n element: HTMLElement,\n size: {\n height: number;\n width: number;\n contentHeight: number;\n contentWidth: number;\n },\n dimension: measuredDimension,\n): number => {\n switch (dimension) {\n case \"height\":\n return size.height;\n case \"clientHeight\":\n return Math.floor(element.clientHeight);\n case \"clientWidth\":\n return Math.floor(element.clientWidth);\n case \"contentHeight\":\n return size.contentHeight;\n case \"contentWidth\":\n return size.contentWidth;\n case \"scrollHeight\":\n return Math.ceil(Math.floor(element.scrollHeight));\n case \"scrollWidth\":\n return Math.ceil(Math.floor(element.scrollWidth));\n case \"width\":\n return size.width;\n default:\n return 0;\n }\n};\n\n// TODO should we make this create-on-demand\nconst resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n const observedTarget = observedMap.get(target as HTMLElement);\n if (observedTarget) {\n const [{ blockSize: height, inlineSize: width }] = borderBoxSize;\n const [{ blockSize: contentHeight, inlineSize: contentWidth }] =\n contentBoxSize;\n const { onResize, measurements } = observedTarget;\n let sizeChanged = false;\n for (const [dimension, size] of Object.entries(measurements)) {\n const newSize = getTargetSize(\n target as HTMLElement,\n { height, width, contentHeight, contentWidth },\n dimension as measuredDimension,\n );\n\n if (newSize !== size) {\n sizeChanged = true;\n measurements[dimension as measuredDimension] = newSize;\n }\n }\n if (sizeChanged) {\n // TODO only return measured sizes\n onResize && onResize(measurements);\n }\n }\n }\n});\n\n// TODO use an optional lag (default to false) to ask to fire onResize\n// with initial size\nexport function useResizeObserver(\n ref: RefObject<Element | HTMLElement | null>,\n dimensions: readonly string[],\n onResize: ResizeHandler,\n reportInitialSize = false,\n) {\n const dimensionsRef = useRef(dimensions);\n\n const measure = useCallback((target: HTMLElement): measurements<number> => {\n const { width, height } = target.getBoundingClientRect();\n const { clientWidth: contentWidth, clientHeight: contentHeight } = target;\n const flooredHeight = Math.floor(height);\n const flooredWidth = Math.floor(width);\n\n return dimensionsRef.current.reduce(\n (map: { [key: string]: number }, dim) => {\n map[dim] = getTargetSize(\n target,\n {\n width: flooredWidth,\n height: flooredHeight,\n contentHeight,\n contentWidth,\n },\n dim as measuredDimension,\n );\n return map;\n },\n {},\n );\n }, []);\n\n // TODO use ref to store resizeHandler here\n // resize handler registered with REsizeObserver will never change\n // use ref to store user onResize callback here\n // resizeHandler will call user callback.current\n\n // Keep this effect separate in case user inadvertently passes different\n // dimensions or callback instance each time - we only ever want to\n // initiate new observation when ref changes.\n useEffect(() => {\n const target = ref.current as HTMLElement;\n async function registerObserver() {\n // Create the map entry immediately. useEffect may fire below\n // before fonts are ready and attempt to update entry\n observedMap.set(target, { measurements: {} as measurements<number> });\n // await document.fonts.ready;\n const observedTarget = observedMap.get(target);\n if (observedTarget) {\n const measurements = measure(target);\n observedTarget.measurements = measurements;\n resizeObserver.observe(target);\n if (reportInitialSize) {\n onResize(measurements);\n }\n } else {\n console.log(\n `%cuseResizeObserver an target expected to be under observation wa snot found. This warrants investigation`,\n \"font-weight:bold; color:red;\",\n );\n }\n }\n\n if (target) {\n // TODO might we want multiple callers to attach a listener to the same element ?\n if (observedMap.has(target)) {\n console.log(\n `useResizeObserver attemping to observe same element twice`,\n {\n target,\n },\n );\n // throw Error(\n // \"useResizeObserver attemping to observe same element twice\"\n // );\n }\n // TODO set a pending entry on map\n registerObserver();\n }\n return () => {\n if (target && observedMap.has(target)) {\n resizeObserver.unobserve(target);\n observedMap.delete(target);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [measure, ref]);\n\n useEffect(() => {\n const target = ref.current as HTMLElement;\n const record = observedMap.get(target);\n if (record) {\n if (dimensionsRef.current !== dimensions) {\n dimensionsRef.current = dimensions;\n const measurements = measure(target);\n record.measurements = measurements;\n }\n // Might not have changed, but no harm ...\n record.onResize = onResize;\n }\n }, [dimensions, measure, ref, onResize]);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { RefObject } from "react";
|
|
2
|
-
export declare const WidthHeight: string[];
|
|
3
|
-
export declare const WidthOnly: string[];
|
|
4
|
-
export type measurements<T = string | number> = {
|
|
5
|
-
height?: T;
|
|
6
|
-
clientHeight?: number;
|
|
7
|
-
clientWidth?: number;
|
|
8
|
-
contentHeight?: number;
|
|
9
|
-
contentWidth?: number;
|
|
10
|
-
scrollHeight?: number;
|
|
11
|
-
scrollWidth?: number;
|
|
12
|
-
width?: T;
|
|
13
|
-
};
|
|
14
|
-
export type ResizeHandler = (measurements: measurements<number>) => void;
|
|
15
|
-
export declare function useResizeObserver(ref: RefObject<Element | HTMLElement | null>, dimensions: readonly string[], onResize: ResizeHandler, reportInitialSize?: boolean): void;
|