etudes 0.46.0 → 0.50.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.
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ declare const _default: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
3
+ children?: React.ReactNode;
4
+ } & React.RefAttributes<HTMLElement>>;
5
+ export default _default;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || function (mod) {
26
+ if (mod && mod.__esModule) return mod;
27
+ var result = {};
28
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
+ __setModuleDefault(result, mod);
30
+ return result;
31
+ };
32
+ var __rest = (this && this.__rest) || function (s, e) {
33
+ var t = {};
34
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
35
+ t[p] = s[p];
36
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
37
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
38
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
39
+ t[p[i]] = s[p[i]];
40
+ }
41
+ return t;
42
+ };
43
+ var __importDefault = (this && this.__importDefault) || function (mod) {
44
+ return (mod && mod.__esModule) ? mod : { "default": mod };
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ var classnames_1 = __importDefault(require("classnames"));
48
+ var lodash_1 = __importDefault(require("lodash"));
49
+ var react_1 = __importStar(require("react"));
50
+ exports.default = (0, react_1.forwardRef)(function (_a, ref) {
51
+ var children = _a.children, className = _a.className, props = __rest(_a, ["children", "className"]);
52
+ if (lodash_1.default.isArray(children)) {
53
+ console.error("[etudes::ExtractChild] Only one child is expected, but found ".concat(children.length, ". Only the first child is extracted while the rest are discarded."));
54
+ }
55
+ return (react_1.default.createElement(react_1.default.Fragment, null, react_1.Children.map(children, function (child, idx) {
56
+ if (idx > 0)
57
+ return undefined;
58
+ if ((0, react_1.isValidElement)(child)) {
59
+ return (0, react_1.cloneElement)(child, __assign(__assign({ className: (0, classnames_1.default)(className, child.props.className) }, props), { ref: ref }));
60
+ }
61
+ return child;
62
+ })));
63
+ });
64
+ //# sourceMappingURL=ExtractChild.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExtractChild.js","sourceRoot":"/","sources":["ExtractChild.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AACnC,kDAAsB;AACtB,6CAAoH;AAIpH,kBAAe,IAAA,kBAAU,EAAqB,UAAC,EAI9C,EAAE,GAAG;IAHJ,IAAA,QAAQ,cAAA,EACR,SAAS,eAAA,EACN,KAAK,cAHqC,yBAI9C,CADS;IAER,IAAI,gBAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QACvB,OAAO,CAAC,KAAK,CAAC,uEAAgE,QAAQ,CAAC,MAAM,sEAAmE,CAAC,CAAA;KAClK;IAED,OAAO,CACL,8DACG,gBAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAC,KAAK,EAAE,GAAG;QACjC,IAAI,GAAG,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;QAE7B,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC,EAAE;YACzB,OAAO,IAAA,oBAAY,EAAC,KAAK,sBAAI,SAAS,EAAE,IAAA,oBAAU,EAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAK,KAAK,KAAE,GAAG,KAAA,IAAG,CAAA;SACvG;QAED,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CACD,CACJ,CAAA;AACH,CAAC,CAAC,CAAA","sourcesContent":["import classNames from 'classnames'\nimport _ from 'lodash'\nimport React, { Children, cloneElement, forwardRef, HTMLAttributes, isValidElement, PropsWithChildren } from 'react'\n\ntype Props = PropsWithChildren<HTMLAttributes<HTMLElement>>\n\nexport default forwardRef<HTMLElement, Props>(({\n children,\n className,\n ...props\n}, ref) => {\n if (_.isArray(children)) {\n console.error(`[etudes::ExtractChild] Only one child is expected, but found ${children.length}. Only the first child is extracted while the rest are discarded.`)\n }\n\n return (\n <>\n {Children.map(children, (child, idx) => {\n if (idx > 0) return undefined\n\n if (isValidElement(child)) {\n return cloneElement(child, { className: classNames(className, child.props.className), ...props, ref })\n }\n\n return child\n })}\n </>\n )\n})\n"]}
@@ -1,2 +1,2 @@
1
1
  import { HTMLAttributes, PropsWithChildren } from 'react';
2
- export default function ExtractChildren({ children, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>): JSX.Element;
2
+ export default function ExtractChildren({ children, className, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>): JSX.Element;
@@ -40,13 +40,18 @@ var __rest = (this && this.__rest) || function (s, e) {
40
40
  }
41
41
  return t;
42
42
  };
43
+ var __importDefault = (this && this.__importDefault) || function (mod) {
44
+ return (mod && mod.__esModule) ? mod : { "default": mod };
45
+ };
43
46
  Object.defineProperty(exports, "__esModule", { value: true });
47
+ var classnames_1 = __importDefault(require("classnames"));
44
48
  var react_1 = __importStar(require("react"));
45
49
  function ExtractChildren(_a) {
46
- var children = _a.children, props = __rest(_a, ["children"]);
47
- return (react_1.default.createElement(react_1.default.Fragment, null, react_1.Children.map(children, function (child) {
48
- if ((0, react_1.isValidElement)(child))
49
- return (0, react_1.cloneElement)(child, __assign({}, props));
50
+ var children = _a.children, className = _a.className, props = __rest(_a, ["children", "className"]);
51
+ return (react_1.default.createElement(react_1.default.Fragment, null, react_1.Children.map(children, function (child, idx) {
52
+ if ((0, react_1.isValidElement)(child)) {
53
+ return (0, react_1.cloneElement)(child, __assign({ className: (0, classnames_1.default)(className, child.props.className) }, props));
54
+ }
50
55
  return child;
51
56
  })));
52
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ExtractChildren.js","sourceRoot":"/","sources":["ExtractChildren.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwG;AAExG,SAAwB,eAAe,CAAC,EAAsE;IAApE,IAAA,QAAQ,cAAA,EAAK,KAAK,cAApB,YAAsB,CAAF;IAC1D,OAAO,CACL,8DACG,gBAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAA,KAAK;QAC3B,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC;YAAE,OAAO,IAAA,oBAAY,EAAC,KAAK,eAAO,KAAK,EAAG,CAAA;QACnE,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CACD,CACJ,CAAA;AACH,CAAC;AATD,kCASC","sourcesContent":["import React, { Children, cloneElement, HTMLAttributes, isValidElement, PropsWithChildren } from 'react'\n\nexport default function ExtractChildren({ children, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>) {\n return (\n <>\n {Children.map(children, child => {\n if (isValidElement(child)) return cloneElement(child, { ...props })\n return child\n })}\n </>\n )\n}\n"]}
1
+ {"version":3,"file":"ExtractChildren.js","sourceRoot":"/","sources":["ExtractChildren.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AACnC,6CAAwG;AAExG,SAAwB,eAAe,CAAC,EAAiF;IAA/E,IAAA,QAAQ,cAAA,EAAE,SAAS,eAAA,EAAK,KAAK,cAA/B,yBAAiC,CAAF;IACrE,OAAO,CACL,8DACG,gBAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAC,KAAK,EAAE,GAAG;QACjC,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC,EAAE;YACzB,OAAO,IAAA,oBAAY,EAAC,KAAK,aAAI,SAAS,EAAE,IAAA,oBAAU,EAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAK,KAAK,EAAG,CAAA;SAClG;QAED,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CACD,CACJ,CAAA;AACH,CAAC;AAZD,kCAYC","sourcesContent":["import classNames from 'classnames'\nimport React, { Children, cloneElement, HTMLAttributes, isValidElement, PropsWithChildren } from 'react'\n\nexport default function ExtractChildren({ children, className, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>) {\n return (\n <>\n {Children.map(children, (child, idx) => {\n if (isValidElement(child)) {\n return cloneElement(child, { className: classNames(className, child.props.className), ...props })\n }\n\n return child\n })}\n </>\n )\n}\n"]}
package/lib/Panorama.js CHANGED
@@ -99,10 +99,10 @@ function getAngleFromDisplacement(displacement, originalImageSize, componentSize
99
99
  */
100
100
  function Panorama(_a) {
101
101
  var _b = _a.angle, externalAngle = _b === void 0 ? 0 : _b, _c = _a.speed, speed = _c === void 0 ? 1 : _c, src = _a.src, _d = _a.zeroAnchor, zeroAnchor = _d === void 0 ? 0 : _d, onAngleChange = _a.onAngleChange, onPositionChange = _a.onPositionChange, onDragStart = _a.onDragStart, onDragEnd = _a.onDragEnd, onImageLoadStart = _a.onImageLoadStart, onImageLoadComplete = _a.onImageLoadComplete, onImageLoadError = _a.onImageLoadError, onImageSizeChange = _a.onImageSizeChange, onResize = _a.onResize, props = __rest(_a, ["angle", "speed", "src", "zeroAnchor", "onAngleChange", "onPositionChange", "onDragStart", "onDragEnd", "onImageLoadStart", "onImageLoadComplete", "onImageLoadError", "onImageSizeChange", "onResize"]);
102
- function transform(currentDisplacement, dx, dy) {
103
- var newDisplacement = currentDisplacement - (dx * speed);
102
+ var mapDragPositionToDisplacement = function (currentPosition, dx, dy) {
103
+ var newDisplacement = currentPosition - (dx * speed);
104
104
  return newDisplacement;
105
- }
105
+ };
106
106
  var rootRef = (0, react_1.useRef)(null);
107
107
  var _e = __read((0, useResizeEffect_1.default)(rootRef, { onResize: onResize }), 1), size = _e[0];
108
108
  var _f = __read((0, react_1.useState)(externalAngle), 2), angle = _f[0], setAngle = _f[1];
@@ -113,7 +113,7 @@ function Panorama(_a) {
113
113
  }), _h = __read(_g.isLoading, 1), isLoading = _h[0], _j = __read(_g.imageSize, 1), imageSize = _j[0];
114
114
  var _k = (0, useDragEffect_1.default)(rootRef, {
115
115
  initialValue: 0,
116
- transform: transform,
116
+ transform: mapDragPositionToDisplacement,
117
117
  onDragStart: onDragStart,
118
118
  onDragEnd: onDragEnd,
119
119
  }), _l = __read(_k.isDragging, 1), isDragging = _l[0], _m = __read(_k.value, 2), displacement = _m[0], setDisplacement = _m[1];
@@ -1 +1 @@
1
- {"version":3,"file":"Panorama.js","sourceRoot":"/","sources":["Panorama.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { HTMLAttributes, useEffect, useRef, useState } from 'react'\nimport { Size } from 'spase'\nimport styled from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\nimport useLoadImageEffect from './hooks/useLoadImageEffect'\nimport useResizeEffect from './hooks/useResizeEffect'\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * The current angle in degrees, 0.0 - 360.0, inclusive. When angle is 0 or 360, the left bound of\n * the image is at the center of the component.\n */\n angle?: number\n\n /**\n * The panning speed. This is a multiplier to the number of pixels dragged, i.e. when set to 1,\n * the image will shift the same amount of pixels that were dragged.\n */\n speed?: number\n\n /**\n * The source URL of the image.\n */\n src?: string\n\n /**\n * A decimal percentage of the component width indicating where 0° should be, i.e. if `zeroAnchor`\n * is `0`, the `angle` would be 0° when the left edge of the image is at the left edge of the\n * component.\n */\n zeroAnchor?: number\n\n /**\n * Handler invoked when the positionchanges. This can either be invoked from the `angle` prop\n * being changed or from the image being dragged.\n *\n * @param position - The current position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when the angle changes. This can either be invoked from the `angle` prop being\n * changed or from the image being dragged. When `angle` is being double-binded, ensure that the\n * value is only being set by this handler when `isDragging` is `true` to avoid potential update\n * overflow.\n *\n * @param angle - The current angle.\n * @param isDragging - Specifies if the angle change is due to dragging.\n */\n onAngleChange?: (angle: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging starts.\n */\n onDragStart?: () => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when the image begins loading.\n */\n onImageLoadStart?: () => void\n\n /**\n * Handler invoked when the image is done loading.\n *\n * @param imageElement - The loaded image element.\n */\n onImageLoadComplete?: (imageElement: HTMLImageElement) => void\n\n /**\n * Handler invoked when there is an error loading the image.\n */\n onImageLoadError?: () => void\n\n /**\n * Handler invoked when the image size changes. This is the actual size of the loaded image. When\n * no images are loaded yet, the size is `undefined`.\n *\n * @param size - The actual size of the loaded iamge. If no images are loaded yet, the size is\n * `undefined`.\n */\n onImageSizeChange?: (size?: Size) => void\n\n /**\n * Handler invoked when the size of this component changes.\n *\n * @param size - The size of this component.\n */\n onResize?: (size: Size) => void\n}\n\nfunction getFilledImageSize(originalSize: Size, sizeToFill: Size): Size {\n const { width: originalWidth, height: originalHeight } = originalSize\n const { height: filledHeignt } = sizeToFill\n\n if (originalHeight <= 0) return new Size()\n\n const aspectRatio = filledHeignt / originalHeight\n const filledWidth = aspectRatio * originalWidth\n\n return new Size([filledWidth, filledHeignt])\n}\n\nfunction getDisplacementFromAngle(angle: number, originalImageSize: Size, componentSize: Size, zeroAnchor: number): number {\n const { width: imageWidth } = getFilledImageSize(originalImageSize, componentSize)\n const { width: componentWidth } = componentSize\n const offset = componentWidth*zeroAnchor\n return (angle / 360) * imageWidth - offset\n}\n\nfunction getAngleFromDisplacement(displacement: number, originalImageSize: Size, componentSize: Size, zeroAnchor: number): number {\n const { width: imageWidth } = getFilledImageSize(originalImageSize, componentSize)\n const { width: componentWidth } = componentSize\n const offset = componentWidth*zeroAnchor\n\n let angle = ((displacement + offset) % imageWidth) / imageWidth*360\n while (angle < 0) angle += 360\n return angle\n}\n\n/**\n * A component containing a pannable 360° panorama image. The angle supports two-way binding.\n */\nexport default function Panorama({\n angle: externalAngle = 0,\n speed = 1,\n src,\n zeroAnchor = 0,\n onAngleChange,\n onPositionChange,\n onDragStart,\n onDragEnd,\n onImageLoadStart,\n onImageLoadComplete,\n onImageLoadError,\n onImageSizeChange,\n onResize,\n ...props\n}: Props) {\n function transform(currentDisplacement: number, dx: number, dy: number): number {\n const newDisplacement = currentDisplacement - (dx * speed)\n return newDisplacement\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n\n const [size] = useResizeEffect(rootRef, { onResize })\n const [angle, setAngle] = useState(externalAngle)\n\n const { isLoading: [isLoading], imageSize: [imageSize] } = useLoadImageEffect(src, {\n onImageLoadComplete,\n onImageLoadError,\n onImageSizeChange,\n })\n\n const { isDragging: [isDragging], value: [displacement, setDisplacement] } = useDragEffect(rootRef, {\n initialValue: 0,\n transform,\n onDragStart,\n onDragEnd,\n })\n\n useEffect(() => {\n if (isDragging || isLoading || !imageSize) return\n\n const newDisplacement = getDisplacementFromAngle(externalAngle, imageSize, size, zeroAnchor)\n\n if (newDisplacement !== displacement) {\n setDisplacement(newDisplacement)\n }\n\n if (externalAngle !== angle) {\n setAngle(externalAngle)\n }\n }, [externalAngle, isLoading, imageSize, size, zeroAnchor])\n\n useEffect(() => {\n if (!isDragging || !imageSize) return\n\n const newAngle = getAngleFromDisplacement(displacement, imageSize, size, zeroAnchor)\n\n if (angle !== newAngle) {\n setAngle(newAngle)\n }\n }, [displacement, imageSize, size, zeroAnchor])\n\n useEffect(() => {\n onAngleChange?.(angle, isDragging)\n onPositionChange?.(angle / 360, isDragging)\n }, [angle])\n\n return (\n <StyledRoot ref={rootRef} {...props}>\n <StyledImageContainer\n style={{\n backgroundImage: `url(${src})`,\n backgroundPositionX: `${-displacement}px`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledImageContainer = styled.div`\n background-repeat: repeat;\n background-size: auto 100%;\n height: 100%;\n left: 0;\n margin: 0;\n padding: 0;\n position: absolute;\n top: 0;\n width: 100%;\n`\n\nconst StyledRoot = styled.div`\n align-items: center;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex: 0 0 auto;\n height: 100%;\n justify-content: center;\n padding: 0;\n position: relative;\n touch-action: none;\n width: 100%;\n\n > div {\n height: 100%;\n left: 0;\n margin: 0;\n padding: 0;\n position: absolute;\n top: 0;\n width: 100%;\n }\n`\n"]}
1
+ {"version":3,"file":"Panorama.js","sourceRoot":"/","sources":["Panorama.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { HTMLAttributes, useEffect, useRef, useState } from 'react'\nimport { Size } from 'spase'\nimport styled from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\nimport useLoadImageEffect from './hooks/useLoadImageEffect'\nimport useResizeEffect from './hooks/useResizeEffect'\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * The current angle in degrees, 0.0 - 360.0, inclusive. When angle is 0 or 360, the left bound of\n * the image is at the center of the component.\n */\n angle?: number\n\n /**\n * The panning speed. This is a multiplier to the number of pixels dragged, i.e. when set to 1,\n * the image will shift the same amount of pixels that were dragged.\n */\n speed?: number\n\n /**\n * The source URL of the image.\n */\n src?: string\n\n /**\n * A decimal percentage of the component width indicating where 0° should be, i.e. if `zeroAnchor`\n * is `0`, the `angle` would be 0° when the left edge of the image is at the left edge of the\n * component.\n */\n zeroAnchor?: number\n\n /**\n * Handler invoked when the positionchanges. This can either be invoked from the `angle` prop\n * being changed or from the image being dragged.\n *\n * @param position - The current position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when the angle changes. This can either be invoked from the `angle` prop being\n * changed or from the image being dragged. When `angle` is being double-binded, ensure that the\n * value is only being set by this handler when `isDragging` is `true` to avoid potential update\n * overflow.\n *\n * @param angle - The current angle.\n * @param isDragging - Specifies if the angle change is due to dragging.\n */\n onAngleChange?: (angle: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging starts.\n */\n onDragStart?: () => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when the image begins loading.\n */\n onImageLoadStart?: () => void\n\n /**\n * Handler invoked when the image is done loading.\n *\n * @param imageElement - The loaded image element.\n */\n onImageLoadComplete?: (imageElement: HTMLImageElement) => void\n\n /**\n * Handler invoked when there is an error loading the image.\n */\n onImageLoadError?: () => void\n\n /**\n * Handler invoked when the image size changes. This is the actual size of the loaded image. When\n * no images are loaded yet, the size is `undefined`.\n *\n * @param size - The actual size of the loaded iamge. If no images are loaded yet, the size is\n * `undefined`.\n */\n onImageSizeChange?: (size?: Size) => void\n\n /**\n * Handler invoked when the size of this component changes.\n *\n * @param size - The size of this component.\n */\n onResize?: (size: Size) => void\n}\n\nfunction getFilledImageSize(originalSize: Size, sizeToFill: Size): Size {\n const { width: originalWidth, height: originalHeight } = originalSize\n const { height: filledHeignt } = sizeToFill\n\n if (originalHeight <= 0) return new Size()\n\n const aspectRatio = filledHeignt / originalHeight\n const filledWidth = aspectRatio * originalWidth\n\n return new Size([filledWidth, filledHeignt])\n}\n\nfunction getDisplacementFromAngle(angle: number, originalImageSize: Size, componentSize: Size, zeroAnchor: number): number {\n const { width: imageWidth } = getFilledImageSize(originalImageSize, componentSize)\n const { width: componentWidth } = componentSize\n const offset = componentWidth*zeroAnchor\n return (angle / 360) * imageWidth - offset\n}\n\nfunction getAngleFromDisplacement(displacement: number, originalImageSize: Size, componentSize: Size, zeroAnchor: number): number {\n const { width: imageWidth } = getFilledImageSize(originalImageSize, componentSize)\n const { width: componentWidth } = componentSize\n const offset = componentWidth*zeroAnchor\n\n let angle = ((displacement + offset) % imageWidth) / imageWidth*360\n while (angle < 0) angle += 360\n return angle\n}\n\n/**\n * A component containing a pannable 360° panorama image. The angle supports two-way binding.\n */\nexport default function Panorama({\n angle: externalAngle = 0,\n speed = 1,\n src,\n zeroAnchor = 0,\n onAngleChange,\n onPositionChange,\n onDragStart,\n onDragEnd,\n onImageLoadStart,\n onImageLoadComplete,\n onImageLoadError,\n onImageSizeChange,\n onResize,\n ...props\n}: Props) {\n const mapDragPositionToDisplacement = (currentPosition: number, dx: number, dy: number): number => {\n const newDisplacement = currentPosition - (dx * speed)\n return newDisplacement\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const [size] = useResizeEffect(rootRef, { onResize })\n const [angle, setAngle] = useState(externalAngle)\n\n const { isLoading: [isLoading], imageSize: [imageSize] } = useLoadImageEffect(src, {\n onImageLoadComplete,\n onImageLoadError,\n onImageSizeChange,\n })\n\n const { isDragging: [isDragging], value: [displacement, setDisplacement] } = useDragEffect(rootRef, {\n initialValue: 0,\n transform: mapDragPositionToDisplacement,\n onDragStart,\n onDragEnd,\n })\n\n useEffect(() => {\n if (isDragging || isLoading || !imageSize) return\n\n const newDisplacement = getDisplacementFromAngle(externalAngle, imageSize, size, zeroAnchor)\n\n if (newDisplacement !== displacement) {\n setDisplacement(newDisplacement)\n }\n\n if (externalAngle !== angle) {\n setAngle(externalAngle)\n }\n }, [externalAngle, isLoading, imageSize, size, zeroAnchor])\n\n useEffect(() => {\n if (!isDragging || !imageSize) return\n\n const newAngle = getAngleFromDisplacement(displacement, imageSize, size, zeroAnchor)\n\n if (angle !== newAngle) {\n setAngle(newAngle)\n }\n }, [displacement, imageSize, size, zeroAnchor])\n\n useEffect(() => {\n onAngleChange?.(angle, isDragging)\n onPositionChange?.(angle / 360, isDragging)\n }, [angle])\n\n return (\n <StyledRoot ref={rootRef} {...props}>\n <StyledImageContainer\n style={{\n backgroundImage: `url(${src})`,\n backgroundPositionX: `${-displacement}px`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledImageContainer = styled.div`\n background-repeat: repeat;\n background-size: auto 100%;\n height: 100%;\n left: 0;\n margin: 0;\n padding: 0;\n position: absolute;\n top: 0;\n width: 100%;\n`\n\nconst StyledRoot = styled.div`\n align-items: center;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex: 0 0 auto;\n height: 100%;\n justify-content: center;\n padding: 0;\n position: relative;\n touch-action: none;\n width: 100%;\n\n > div {\n height: 100%;\n left: 0;\n margin: 0;\n padding: 0;\n position: absolute;\n top: 0;\n width: 100%;\n }\n`\n"]}
@@ -72,28 +72,28 @@ var useResizeEffect_1 = __importDefault(require("./hooks/useResizeEffect"));
72
72
  var Panorama_1 = __importDefault(require("./Panorama"));
73
73
  function PanoramaSlider(_a) {
74
74
  var fov = _a.fov, _b = _a.autoDimension, autoDimension = _b === void 0 ? 'width' : _b, viewportSize = _a.viewportSize, cssPanorama = _a.cssPanorama, cssReticle = _a.cssReticle, cssTrack = _a.cssTrack, cssIndicator = _a.cssIndicator, _c = _a.angle, angle = _c === void 0 ? 0 : _c, _d = _a.speed, speed = _d === void 0 ? 1 : _d, src = _a.src, _e = _a.zeroAnchor, zeroAnchor = _e === void 0 ? 0 : _e, onAngleChange = _a.onAngleChange, onPositionChange = _a.onPositionChange, onDragStart = _a.onDragStart, onDragEnd = _a.onDragEnd, onImageLoadStart = _a.onImageLoadStart, onImageLoadComplete = _a.onImageLoadComplete, onImageLoadError = _a.onImageLoadError, onImageSizeChange = _a.onImageSizeChange, onResize = _a.onResize, style = _a.style, props = __rest(_a, ["fov", "autoDimension", "viewportSize", "cssPanorama", "cssReticle", "cssTrack", "cssIndicator", "angle", "speed", "src", "zeroAnchor", "onAngleChange", "onPositionChange", "onDragStart", "onDragEnd", "onImageLoadStart", "onImageLoadComplete", "onImageLoadError", "onImageSizeChange", "onResize", "style"]);
75
- function getImageAspectRatio() {
75
+ var getAspectRatio = function () {
76
76
  if (!imageSize)
77
77
  return 0;
78
78
  var width = imageSize.width, height = imageSize.height;
79
79
  if (height === 0)
80
80
  return 0;
81
81
  return width / height;
82
- }
83
- function getReticleWidth() {
82
+ };
83
+ var getReticleWidth = function () {
84
84
  var angle = lodash_1.default.clamp(fov !== null && fov !== void 0 ? fov : (viewportSize ? (viewportSize.width / (viewportSize.height * aspectRatio)) * 360 : 0), 0, 360);
85
85
  return size.width * (angle / 360);
86
- }
87
- function getAdjustedZeroAnchor() {
86
+ };
87
+ var getAdjustedZeroAnchor = function () {
88
88
  if (size.width <= 0)
89
89
  return zeroAnchor;
90
90
  return ((size.width - reticleWidth) * 0.5 + (zeroAnchor * reticleWidth)) / size.width;
91
- }
91
+ };
92
92
  var rootRef = (0, react_1.useRef)(null);
93
93
  var _f = __read((0, react_1.useState)(undefined), 2), imageSize = _f[0], setImageSize = _f[1];
94
94
  var _g = __read((0, react_1.useState)(false), 2), isDragging = _g[0], setIsDragging = _g[1];
95
95
  var _h = __read((0, useResizeEffect_1.default)(rootRef, { onResize: onResize }), 1), size = _h[0];
96
- var aspectRatio = getImageAspectRatio();
96
+ var aspectRatio = getAspectRatio();
97
97
  var reticleWidth = getReticleWidth();
98
98
  var adjustedZeroAnchor = getAdjustedZeroAnchor();
99
99
  return (react_1.default.createElement(StyledRoot, __assign({ ref: rootRef, style: __assign(__assign({}, style), autoDimension === 'width' ? {
@@ -1 +1 @@
1
- {"version":3,"file":"PanoramaSlider.js","sourceRoot":"/","sources":["PanoramaSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport _ from 'lodash'\nimport React, { HTMLAttributes, useRef, useState } from 'react'\nimport { Size } from 'spase'\nimport styled, { CSSProp } from 'styled-components'\nimport useResizeEffect from './hooks/useResizeEffect'\nimport Panorama, { Props as PanoramaProps } from './Panorama'\n\nexport type Props = HTMLAttributes<HTMLDivElement> & PanoramaProps & {\n /**\n * Field-of-view (0.0 - 360.0 degrees, inclusive) that represents the size of the reticle. 360\n * indicates the reticle covers the entire image. If this is unspecified, the component will\n * attempt to automatically calculate the FOV using the `viewportSize` prop.\n */\n fov?: number\n\n /**\n * Specifies which length (width or height) should be automatically calculated. The counterpart\n * must be known (if `width` is specified here, the component's height must be known, i.e. it is\n * specified in the CSS). Defaults to `width`.\n */\n autoDimension?: 'width' | 'height'\n\n /**\n * Size of the viewport that this component is controlling. A viewport can be thought of as a DOM\n * element containing an aspect-filled image. This is used to automatically calculate the FOV if\n * `fov` prop is not specified. If it is, this prop is ignored.\n */\n viewportSize?: Size\n\n /**\n * Additional CSS to be provided to the internal panorama component.\n */\n cssPanorama?: CSSProp<any>\n\n /**\n * Additional CSS to be provided to the reticle.\n */\n cssReticle?: CSSProp<any>\n\n /**\n * Additional CSS to be provided to the track.\n */\n cssTrack?: CSSProp<any>\n\n /**\n * Additional CSS to be provided to the indicator.\n */\n cssIndicator?: CSSProp<any>\n}\n\nexport default function PanoramaSlider({\n fov,\n autoDimension = 'width',\n viewportSize,\n cssPanorama,\n cssReticle,\n cssTrack,\n cssIndicator,\n angle = 0,\n speed = 1,\n src,\n zeroAnchor = 0,\n onAngleChange,\n onPositionChange,\n onDragStart,\n onDragEnd,\n onImageLoadStart,\n onImageLoadComplete,\n onImageLoadError,\n onImageSizeChange,\n onResize,\n style,\n ...props\n}: Props) {\n function getImageAspectRatio(): number {\n if (!imageSize) return 0\n const { width, height } = imageSize\n if (height === 0) return 0\n return width / height\n }\n\n function getReticleWidth(): number {\n const angle = _.clamp(fov ?? (viewportSize ? (viewportSize.width / (viewportSize.height * aspectRatio)) * 360 : 0), 0, 360)\n return size.width * (angle / 360)\n }\n\n function getAdjustedZeroAnchor() {\n if (size.width <= 0) return zeroAnchor\n\n return ((size.width - reticleWidth) * 0.5 + (zeroAnchor * reticleWidth)) / size.width\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n\n const [imageSize, setImageSize] = useState<Size | undefined>(undefined)\n const [isDragging, setIsDragging] = useState(false)\n const [size] = useResizeEffect(rootRef, { onResize })\n\n const aspectRatio = getImageAspectRatio()\n const reticleWidth = getReticleWidth()\n const adjustedZeroAnchor = getAdjustedZeroAnchor()\n\n return (\n <StyledRoot ref={rootRef} style={{\n ...style,\n ...autoDimension === 'width' ? {\n width: `${size.height * aspectRatio}px`,\n } : {\n height: `${size.width / aspectRatio}px`,\n },\n }} {...props}>\n <StyledPanorama\n angle={angle}\n css={cssPanorama}\n onAngleChange={onAngleChange}\n onDragEnd={() => {\n setIsDragging(false)\n onDragEnd?.()\n }}\n onDragStart={() => {\n setIsDragging(true)\n onDragStart?.()\n }}\n onImageLoadComplete={onImageLoadComplete}\n onImageLoadError={onImageLoadError}\n onImageLoadStart={onImageLoadStart}\n onImageSizeChange={size => setImageSize(size)}\n onPositionChange={onPositionChange}\n speed={speed}\n src={src}\n style={{ height: '100%', width: '100%' }}\n zeroAnchor={adjustedZeroAnchor}\n />\n <StyledTrackContainer>\n <div>\n <StyledTrack className={classNames({ dragging: isDragging })} css={cssTrack}/>\n <StyledReticle className={classNames({ dragging: isDragging })} css={cssReticle} style={{ width: `${reticleWidth}px` }}/>\n <StyledTrack className={classNames({ dragging: isDragging })} css={cssTrack}/>\n </div>\n </StyledTrackContainer>\n <StyledIndicator className={classNames({ dragging: isDragging })} style={{ width: `${reticleWidth}px` }} css={cssIndicator}/>\n </StyledRoot>\n )\n}\n\nconst StyledReticle = styled.div`\n background: rgba(0, 0, 0, .3);\n flex: 0 0 auto;\n height: 100%;\n transition-duration: 100ms;\n transition-property: background;\n transition-timing-function: ease-out;\n\n &.dragging {\n background: rgba(0, 0, 0, 0);\n }\n\n ${props => props.css}\n `\n\nconst StyledTrack = styled.div`\n background: rgba(0, 0, 0, .7);\n display: block;\n flex: 1 0 auto;\n height: 100%;\n pointer-events: none;\n\n ${props => props.css}\n`\n\nconst StyledTrackContainer = styled.div`\n box-sizing: border-box;\n display: block;\n height: 100%;\n left: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n top: 0;\n width: 100%;\n\n > div {\n align-items: center;\n display: flex;\n height: 100%;\n justify-content: flex-start;\n left: 0;\n overflow: visible;\n position: absolute;\n top: 0;\n width: 100%;\n }\n`\n\nconst StyledIndicator = styled.div`\n background: #fff;\n border-radius: 2px;\n bottom: -10px;\n box-sizing: border-box;\n display: block;\n height: 2px;\n left: 0;\n margin: 0 auto;\n opacity: 0;\n right: 0;\n transition: opacity .3s ease-out;\n\n &.dragging {\n opacity: 1;\n }\n\n ${props => props.css}\n`\n\nconst StyledPanorama = styled(Panorama)`\n ${(props: any) => props.css}\n`\n\nconst StyledRoot = styled.div`\n box-sizing: border-box;\n display: block;\n flex: 0 0 auto;\n height: 100%;\n width: 100%;\n`\n"]}
1
+ {"version":3,"file":"PanoramaSlider.js","sourceRoot":"/","sources":["PanoramaSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport _ from 'lodash'\nimport React, { HTMLAttributes, useRef, useState } from 'react'\nimport { Size } from 'spase'\nimport styled, { CSSProp } from 'styled-components'\nimport useResizeEffect from './hooks/useResizeEffect'\nimport Panorama, { Props as PanoramaProps } from './Panorama'\n\nexport type Props = HTMLAttributes<HTMLDivElement> & PanoramaProps & {\n /**\n * Field-of-view (0.0 - 360.0 degrees, inclusive) that represents the size of the reticle. 360\n * indicates the reticle covers the entire image. If this is unspecified, the component will\n * attempt to automatically calculate the FOV using the `viewportSize` prop.\n */\n fov?: number\n\n /**\n * Specifies which length (width or height) should be automatically calculated. The counterpart\n * must be known (if `width` is specified here, the component's height must be known, i.e. it is\n * specified in the CSS). Defaults to `width`.\n */\n autoDimension?: 'width' | 'height'\n\n /**\n * Size of the viewport that this component is controlling. A viewport can be thought of as a DOM\n * element containing an aspect-filled image. This is used to automatically calculate the FOV if\n * `fov` prop is not specified. If it is, this prop is ignored.\n */\n viewportSize?: Size\n\n /**\n * Additional CSS to be provided to the internal panorama component.\n */\n cssPanorama?: CSSProp<any>\n\n /**\n * Additional CSS to be provided to the reticle.\n */\n cssReticle?: CSSProp<any>\n\n /**\n * Additional CSS to be provided to the track.\n */\n cssTrack?: CSSProp<any>\n\n /**\n * Additional CSS to be provided to the indicator.\n */\n cssIndicator?: CSSProp<any>\n}\n\nexport default function PanoramaSlider({\n fov,\n autoDimension = 'width',\n viewportSize,\n cssPanorama,\n cssReticle,\n cssTrack,\n cssIndicator,\n angle = 0,\n speed = 1,\n src,\n zeroAnchor = 0,\n onAngleChange,\n onPositionChange,\n onDragStart,\n onDragEnd,\n onImageLoadStart,\n onImageLoadComplete,\n onImageLoadError,\n onImageSizeChange,\n onResize,\n style,\n ...props\n}: Props) {\n const getAspectRatio = (): number => {\n if (!imageSize) return 0\n const { width, height } = imageSize\n if (height === 0) return 0\n return width / height\n }\n\n const getReticleWidth = (): number => {\n const angle = _.clamp(fov ?? (viewportSize ? (viewportSize.width / (viewportSize.height * aspectRatio)) * 360 : 0), 0, 360)\n return size.width * (angle / 360)\n }\n\n const getAdjustedZeroAnchor = () => {\n if (size.width <= 0) return zeroAnchor\n return ((size.width - reticleWidth) * 0.5 + (zeroAnchor * reticleWidth)) / size.width\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const [imageSize, setImageSize] = useState<Size | undefined>(undefined)\n const [isDragging, setIsDragging] = useState(false)\n const [size] = useResizeEffect(rootRef, { onResize })\n const aspectRatio = getAspectRatio()\n const reticleWidth = getReticleWidth()\n const adjustedZeroAnchor = getAdjustedZeroAnchor()\n\n return (\n <StyledRoot ref={rootRef} style={{\n ...style,\n ...autoDimension === 'width' ? {\n width: `${size.height * aspectRatio}px`,\n } : {\n height: `${size.width / aspectRatio}px`,\n },\n }} {...props}>\n <StyledPanorama\n angle={angle}\n css={cssPanorama}\n onAngleChange={onAngleChange}\n onDragEnd={() => {\n setIsDragging(false)\n onDragEnd?.()\n }}\n onDragStart={() => {\n setIsDragging(true)\n onDragStart?.()\n }}\n onImageLoadComplete={onImageLoadComplete}\n onImageLoadError={onImageLoadError}\n onImageLoadStart={onImageLoadStart}\n onImageSizeChange={size => setImageSize(size)}\n onPositionChange={onPositionChange}\n speed={speed}\n src={src}\n style={{ height: '100%', width: '100%' }}\n zeroAnchor={adjustedZeroAnchor}\n />\n <StyledTrackContainer>\n <div>\n <StyledTrack className={classNames({ dragging: isDragging })} css={cssTrack}/>\n <StyledReticle className={classNames({ dragging: isDragging })} css={cssReticle} style={{ width: `${reticleWidth}px` }}/>\n <StyledTrack className={classNames({ dragging: isDragging })} css={cssTrack}/>\n </div>\n </StyledTrackContainer>\n <StyledIndicator className={classNames({ dragging: isDragging })} style={{ width: `${reticleWidth}px` }} css={cssIndicator}/>\n </StyledRoot>\n )\n}\n\nconst StyledReticle = styled.div`\n background: rgba(0, 0, 0, .3);\n flex: 0 0 auto;\n height: 100%;\n transition-duration: 100ms;\n transition-property: background;\n transition-timing-function: ease-out;\n\n &.dragging {\n background: rgba(0, 0, 0, 0);\n }\n\n ${props => props.css}\n `\n\nconst StyledTrack = styled.div`\n background: rgba(0, 0, 0, .7);\n display: block;\n flex: 1 0 auto;\n height: 100%;\n pointer-events: none;\n\n ${props => props.css}\n`\n\nconst StyledTrackContainer = styled.div`\n box-sizing: border-box;\n display: block;\n height: 100%;\n left: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n top: 0;\n width: 100%;\n\n > div {\n align-items: center;\n display: flex;\n height: 100%;\n justify-content: flex-start;\n left: 0;\n overflow: visible;\n position: absolute;\n top: 0;\n width: 100%;\n }\n`\n\nconst StyledIndicator = styled.div`\n background: #fff;\n border-radius: 2px;\n bottom: -10px;\n box-sizing: border-box;\n display: block;\n height: 2px;\n left: 0;\n margin: 0 auto;\n opacity: 0;\n right: 0;\n transition: opacity .3s ease-out;\n\n &.dragging {\n opacity: 1;\n }\n\n ${props => props.css}\n`\n\nconst StyledPanorama = styled(Panorama)`\n ${(props: any) => props.css}\n`\n\nconst StyledRoot = styled.div`\n box-sizing: border-box;\n display: block;\n flex: 0 0 auto;\n height: 100%;\n width: 100%;\n`\n"]}
package/lib/Slider.js CHANGED
@@ -80,7 +80,7 @@ var debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:sl
80
80
  */
81
81
  function Slider(_a) {
82
82
  var _b = _a.isInverted, isInverted = _b === void 0 ? false : _b, _c = _a.isTrackInteractive, isTrackInteractive = _c === void 0 ? true : _c, _d = _a.onlyDispatchesOnDragEnd, onlyDispatchesOnDragEnd = _d === void 0 ? false : _d, _e = _a.trackPadding, trackPadding = _e === void 0 ? 0 : _e, _f = _a.knobHeight, knobHeight = _f === void 0 ? 30 : _f, _g = _a.knobWidth, knobWidth = _g === void 0 ? 30 : _g, _h = _a.orientation, orientation = _h === void 0 ? 'vertical' : _h, _j = _a.position, externalPosition = _j === void 0 ? 0 : _j, labelProvider = _a.labelProvider, onDragEnd = _a.onDragEnd, onDragStart = _a.onDragStart, onPositionChange = _a.onPositionChange, cssStartingTrack = _a.cssStartingTrack, cssEndingTrack = _a.cssEndingTrack, cssKnob = _a.cssKnob, cssLabel = _a.cssLabel, props = __rest(_a, ["isInverted", "isTrackInteractive", "onlyDispatchesOnDragEnd", "trackPadding", "knobHeight", "knobWidth", "orientation", "position", "labelProvider", "onDragEnd", "onDragStart", "onPositionChange", "cssStartingTrack", "cssEndingTrack", "cssKnob", "cssLabel"]);
83
- function transform(currentPosition, dx, dy) {
83
+ var mapDragPositionToPosition = function (currentPosition, dx, dy) {
84
84
  var _a;
85
85
  var rect = (_a = spase_1.Rect.from(rootRef.current)) !== null && _a !== void 0 ? _a : new spase_1.Rect();
86
86
  var naturalPosition = isInverted ? 1 - currentPosition : currentPosition;
@@ -89,8 +89,8 @@ function Slider(_a) {
89
89
  var naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width));
90
90
  var newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition;
91
91
  return newPosition;
92
- }
93
- function onTrackClick(event) {
92
+ };
93
+ var onTrackClick = function (event) {
94
94
  var _a;
95
95
  if (!isTrackInteractive)
96
96
  return;
@@ -109,12 +109,12 @@ function Slider(_a) {
109
109
  break;
110
110
  }
111
111
  }
112
- }
112
+ };
113
113
  var rootRef = (0, react_1.useRef)(null);
114
114
  var knobRef = (0, react_1.useRef)(null);
115
115
  var _k = (0, useDragEffect_1.default)(knobRef, {
116
116
  initialValue: externalPosition,
117
- transform: transform,
117
+ transform: mapDragPositionToPosition,
118
118
  onDragStart: onDragStart,
119
119
  onDragEnd: onDragEnd,
120
120
  }), _l = __read(_k.isDragging, 1), isDragging = _l[0], _m = __read(_k.value, 2), position = _m[0], setPosition = _m[1];
package/lib/Slider.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.js","sourceRoot":"/","sources":["Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position change events are dispatched only when dragging ends. When disabled,\n * aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position.\n *\n * @param position - The current slider position.\n *\n * @returns The label.\n */\n labelProvider?: (position: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The current position.\n */\n position?: number\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `position` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp\n}\n\n/**\n * A slider component supporting both horizontal and vertical orientations whose sliding position (a\n * decimal between 0.0 and 1.0, inclusive) can be two-way binded. The component consists of four\n * customizable elements: a draggable knob, a label on the knob, a scroll track before the knob and\n * a scroll track after the knob. While the width and height of the slider is inferred from its CSS\n * rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,\n * respectively). The size of the knob does not impact the size of the slider.\n */\nexport default function Slider({\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n position: externalPosition = 0,\n labelProvider,\n onDragEnd,\n onDragStart,\n onPositionChange,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number): number {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: externalPosition,\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // debug('Rendering...', 'OK')\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging || externalPosition === position) return\n\n debug('Updating drag effect value from position prop...', 'OK', `prop=${externalPosition}, effect=${position}`)\n\n setPosition(externalPosition)\n }, [externalPosition])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, isDragging)\n }, [position])\n\n useEffect(() => {\n if (isDragging || !onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, true)\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging === true,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position)}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
1
+ {"version":3,"file":"Slider.js","sourceRoot":"/","sources":["Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position change events are dispatched only when dragging ends. When disabled,\n * aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position.\n *\n * @param position - The current slider position.\n *\n * @returns The label.\n */\n labelProvider?: (position: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The current position.\n */\n position?: number\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `position` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp\n}\n\n/**\n * A slider component supporting both horizontal and vertical orientations whose sliding position (a\n * decimal between 0.0 and 1.0, inclusive) can be two-way binded. The component consists of four\n * customizable elements: a draggable knob, a label on the knob, a scroll track before the knob and\n * a scroll track after the knob. While the width and height of the slider is inferred from its CSS\n * rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,\n * respectively). The size of the knob does not impact the size of the slider.\n */\nexport default function Slider({\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n position: externalPosition = 0,\n labelProvider,\n onDragEnd,\n onDragStart,\n onPositionChange,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n const mapDragPositionToPosition = (currentPosition: number, dx: number, dy: number): number => {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n const onTrackClick = (event: MouseEvent) => {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: externalPosition,\n transform: mapDragPositionToPosition,\n onDragStart,\n onDragEnd,\n })\n\n // debug('Rendering...', 'OK')\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging || externalPosition === position) return\n\n debug('Updating drag effect value from position prop...', 'OK', `prop=${externalPosition}, effect=${position}`)\n\n setPosition(externalPosition)\n }, [externalPosition])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, isDragging)\n }, [position])\n\n useEffect(() => {\n if (isDragging || !onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, true)\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging === true,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position)}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
@@ -142,7 +142,7 @@ function getPositionAt(index, steps) {
142
142
  */
143
143
  function StepwiseSlider(_a) {
144
144
  var id = _a.id, className = _a.className, _b = _a.isInverted, isInverted = _b === void 0 ? false : _b, _c = _a.isTrackInteractive, isTrackInteractive = _c === void 0 ? true : _c, _d = _a.onlyDispatchesOnDragEnd, onlyDispatchesOnDragEnd = _d === void 0 ? false : _d, _e = _a.trackPadding, trackPadding = _e === void 0 ? 0 : _e, _f = _a.knobHeight, knobHeight = _f === void 0 ? 30 : _f, _g = _a.knobWidth, knobWidth = _g === void 0 ? 30 : _g, _h = _a.orientation, orientation = _h === void 0 ? 'vertical' : _h, labelProvider = _a.labelProvider, _j = _a.steps, steps = _j === void 0 ? generateSteps(10) : _j, _k = _a.index, externalIndex = _k === void 0 ? 0 : _k, onIndexChange = _a.onIndexChange, onPositionChange = _a.onPositionChange, onDragEnd = _a.onDragEnd, onDragStart = _a.onDragStart, cssStartingTrack = _a.cssStartingTrack, cssEndingTrack = _a.cssEndingTrack, cssKnob = _a.cssKnob, cssLabel = _a.cssLabel, props = __rest(_a, ["id", "className", "isInverted", "isTrackInteractive", "onlyDispatchesOnDragEnd", "trackPadding", "knobHeight", "knobWidth", "orientation", "labelProvider", "steps", "index", "onIndexChange", "onPositionChange", "onDragEnd", "onDragStart", "cssStartingTrack", "cssEndingTrack", "cssKnob", "cssLabel"]);
145
- function transform(currentPosition, dx, dy) {
145
+ var mapDragPositionToPosition = function (currentPosition, dx, dy) {
146
146
  var _a;
147
147
  var rect = (_a = spase_1.Rect.from(rootRef.current)) !== null && _a !== void 0 ? _a : new spase_1.Rect();
148
148
  var naturalPosition = isInverted ? 1 - currentPosition : currentPosition;
@@ -151,8 +151,8 @@ function StepwiseSlider(_a) {
151
151
  var naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width));
152
152
  var newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition;
153
153
  return newPosition;
154
- }
155
- function onTrackClick(event) {
154
+ };
155
+ var onTrackClick = function (event) {
156
156
  var _a;
157
157
  if (!isTrackInteractive)
158
158
  return;
@@ -171,13 +171,13 @@ function StepwiseSlider(_a) {
171
171
  break;
172
172
  }
173
173
  }
174
- }
174
+ };
175
175
  var rootRef = (0, react_1.useRef)(null);
176
176
  var knobRef = (0, react_1.useRef)(null);
177
177
  var _l = __read((0, react_1.useState)(externalIndex), 2), index = _l[0], setIndex = _l[1];
178
178
  var _m = (0, useDragEffect_1.default)(knobRef, {
179
179
  initialValue: getPositionAt(externalIndex, steps),
180
- transform: transform,
180
+ transform: mapDragPositionToPosition,
181
181
  onDragStart: onDragStart,
182
182
  onDragEnd: onDragEnd,
183
183
  }), _o = __read(_m.isDragging, 1), isDragging = _o[0], _p = __read(_m.value, 2), position = _p[0], setPosition = _p[1];
@@ -1 +1 @@
1
- {"version":3,"file":"StepwiseSlider.js","sourceRoot":"/","sources":["StepwiseSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef, useState } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:stepwise-slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position/index change events are dispatched only when dragging ends. When\n * disabled, aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position and closest step\n * index (if steps are provided).\n *\n * @param position - The current slider position.\n * @param index - The nearest step index (if steps are provided), or -1 if no steps are provided.\n *\n * @returns The label.\n */\n labelProvider?: (position: number, index: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * An array of step descriptors. A step is a position (0 - 1 inclusive) on the track where the\n * knob should snap to if dragging stops near it. Ensure that there are at least two steps: one\n * for the start of the track and one for the end.\n */\n steps?: readonly number[]\n\n /**\n * The current index.\n */\n index?: number\n\n /**\n * Handler invoked when index changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right after `onPositionChange`.\n *\n * @param index - The current slider index.\n * @param isDragging - Specifies if the index change is due to dragging.\n */\n onIndexChange?: (index: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right before `onIndexChange`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * Generates a set of steps compatible with this component.\n *\n * @param length - The number of steps. This must be at least 2 because you must include the\n * starting and ending points.\n *\n * @returns An array of steps.\n */\nexport function generateSteps(length: number): readonly number[] {\n if (length <= 1) throw new Error('`length` value must be greater than or equal to 2')\n if (Math.round(length) !== length) throw new Error('`length` value must be an integer')\n\n const interval = 1 / (length - 1)\n\n return Array(length).fill(null).map((v, i) => {\n const position = interval * i\n return position\n })\n}\n\n/**\n * Gets the index of the step of which the specified position is closest to. If for whatever\n * reason the index cannot be computed, -1 is returned.\n *\n * @param position - The position (0 - 1, inclusive).\n * @param steps - The steps.\n *\n * @returns The nearest index.\n */\nfunction getNearestIndexByPosition(position: number, steps: readonly number[]): number {\n let index = -1\n let minDelta = NaN\n\n for (let i = 0, n = steps.length; i < n; i++) {\n const step = getPositionAt(i, steps)\n\n if (isNaN(step)) continue\n\n const delta = Math.abs(position - step)\n\n if (isNaN(minDelta) || (delta < minDelta)) {\n minDelta = delta\n index = i\n }\n }\n\n return index\n}\n\n/**\n * Gets the position by step index. This value ranges between 0 - 1, inclusive.\n *\n * @param index - The step index.\n * @param steps - The steps.\n *\n * @returns The position. If for whatever reason the position cannot be determined, `NaN` is\n * returned.\n */\nfunction getPositionAt(index: number, steps: readonly number[]): number {\n if (index >= steps.length) return NaN\n return steps[index]\n}\n\n/**\n * A \"stepwise\" slider component supporting both horizontal and vertical orientations that\n * automatically snaps to a set of predefined points on the slider when dragged. These points are\n * referred to as \"steps\", indexed by an integer referred to as \"index\". This index can be two-way\n * binded. The component consists of four customizable elements: a draggable knob, a label on the\n * knob, a scroll track before the knob and a scroll track after the knob. While the width and\n * height of the slider is inferred from its CSS rules, the width and height of the knob are set via\n * props (`knobWidth` and `knobHeight`, respectively). The size of the knob does not impact the size\n * of the slider. While dragging, the slider still emits a position change event, where the position\n * is a decimal ranging between 0.0 and 1.0, inclusive.\n */\nexport default function StepwiseSlider({\n id,\n className,\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n labelProvider,\n steps = generateSteps(10),\n index: externalIndex = 0,\n onIndexChange,\n onPositionChange,\n onDragEnd,\n onDragStart,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number) {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const [index, setIndex] = useState(externalIndex)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: getPositionAt(externalIndex, steps),\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging) return\n\n const newPosition = getPositionAt(externalIndex, steps)\n\n if (position !== newPosition) {\n debug('Updating drag effect value from index prop...', 'OK', `prop=${newPosition}, effect=${position}`)\n setPosition(newPosition)\n }\n\n if (externalIndex !== index) {\n setIndex(externalIndex)\n }\n }, [externalIndex])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n\n onPositionChange?.(position, isDragging)\n\n const newIndex = getNearestIndexByPosition(position, steps)\n if (index !== newIndex) setIndex(newIndex)\n }, [position])\n\n useEffect(() => {\n onIndexChange?.(index, isDragging)\n }, [index])\n\n useEffect(() => {\n if (isDragging) return\n\n const nearestIndex = getNearestIndexByPosition(position, steps)\n const nearestPosition = getPositionAt(nearestIndex, steps)\n\n if (nearestPosition !== position || onlyDispatchesOnDragEnd) {\n setPosition(nearestPosition)\n onPositionChange?.(nearestPosition, true)\n }\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {steps && labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position, getNearestIndexByPosition(position, steps))}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
1
+ {"version":3,"file":"StepwiseSlider.js","sourceRoot":"/","sources":["StepwiseSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef, useState } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:stepwise-slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position/index change events are dispatched only when dragging ends. When\n * disabled, aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position and closest step\n * index (if steps are provided).\n *\n * @param position - The current slider position.\n * @param index - The nearest step index (if steps are provided), or -1 if no steps are provided.\n *\n * @returns The label.\n */\n labelProvider?: (position: number, index: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * An array of step descriptors. A step is a position (0 - 1 inclusive) on the track where the\n * knob should snap to if dragging stops near it. Ensure that there are at least two steps: one\n * for the start of the track and one for the end.\n */\n steps?: readonly number[]\n\n /**\n * The current index.\n */\n index?: number\n\n /**\n * Handler invoked when index changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right after `onPositionChange`.\n *\n * @param index - The current slider index.\n * @param isDragging - Specifies if the index change is due to dragging.\n */\n onIndexChange?: (index: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right before `onIndexChange`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * Generates a set of steps compatible with this component.\n *\n * @param length - The number of steps. This must be at least 2 because you must include the\n * starting and ending points.\n *\n * @returns An array of steps.\n */\nexport function generateSteps(length: number): readonly number[] {\n if (length <= 1) throw new Error('`length` value must be greater than or equal to 2')\n if (Math.round(length) !== length) throw new Error('`length` value must be an integer')\n\n const interval = 1 / (length - 1)\n\n return Array(length).fill(null).map((v, i) => {\n const position = interval * i\n return position\n })\n}\n\n/**\n * Gets the index of the step of which the specified position is closest to. If for whatever\n * reason the index cannot be computed, -1 is returned.\n *\n * @param position - The position (0 - 1, inclusive).\n * @param steps - The steps.\n *\n * @returns The nearest index.\n */\nfunction getNearestIndexByPosition(position: number, steps: readonly number[]): number {\n let index = -1\n let minDelta = NaN\n\n for (let i = 0, n = steps.length; i < n; i++) {\n const step = getPositionAt(i, steps)\n\n if (isNaN(step)) continue\n\n const delta = Math.abs(position - step)\n\n if (isNaN(minDelta) || (delta < minDelta)) {\n minDelta = delta\n index = i\n }\n }\n\n return index\n}\n\n/**\n * Gets the position by step index. This value ranges between 0 - 1, inclusive.\n *\n * @param index - The step index.\n * @param steps - The steps.\n *\n * @returns The position. If for whatever reason the position cannot be determined, `NaN` is\n * returned.\n */\nfunction getPositionAt(index: number, steps: readonly number[]): number {\n if (index >= steps.length) return NaN\n return steps[index]\n}\n\n/**\n * A \"stepwise\" slider component supporting both horizontal and vertical orientations that\n * automatically snaps to a set of predefined points on the slider when dragged. These points are\n * referred to as \"steps\", indexed by an integer referred to as \"index\". This index can be two-way\n * binded. The component consists of four customizable elements: a draggable knob, a label on the\n * knob, a scroll track before the knob and a scroll track after the knob. While the width and\n * height of the slider is inferred from its CSS rules, the width and height of the knob are set via\n * props (`knobWidth` and `knobHeight`, respectively). The size of the knob does not impact the size\n * of the slider. While dragging, the slider still emits a position change event, where the position\n * is a decimal ranging between 0.0 and 1.0, inclusive.\n */\nexport default function StepwiseSlider({\n id,\n className,\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n labelProvider,\n steps = generateSteps(10),\n index: externalIndex = 0,\n onIndexChange,\n onPositionChange,\n onDragEnd,\n onDragStart,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n const mapDragPositionToPosition = (currentPosition: number, dx: number, dy: number) => {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n const onTrackClick = (event: MouseEvent) => {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n const [index, setIndex] = useState(externalIndex)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: getPositionAt(externalIndex, steps),\n transform: mapDragPositionToPosition,\n onDragStart,\n onDragEnd,\n })\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging) return\n\n const newPosition = getPositionAt(externalIndex, steps)\n\n if (position !== newPosition) {\n debug('Updating drag effect value from index prop...', 'OK', `prop=${newPosition}, effect=${position}`)\n setPosition(newPosition)\n }\n\n if (externalIndex !== index) {\n setIndex(externalIndex)\n }\n }, [externalIndex])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n\n onPositionChange?.(position, isDragging)\n\n const newIndex = getNearestIndexByPosition(position, steps)\n if (index !== newIndex) setIndex(newIndex)\n }, [position])\n\n useEffect(() => {\n onIndexChange?.(index, isDragging)\n }, [index])\n\n useEffect(() => {\n if (isDragging) return\n\n const nearestIndex = getNearestIndexByPosition(position, steps)\n const nearestPosition = getPositionAt(nearestIndex, steps)\n\n if (nearestPosition !== position || onlyDispatchesOnDragEnd) {\n setPosition(nearestPosition)\n onPositionChange?.(nearestPosition, true)\n }\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {steps && labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position, getNearestIndexByPosition(position, steps))}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
@@ -13,14 +13,14 @@ declare type Props = PropsWithChildren<HTMLAttributes<HTMLElement>> & {
13
13
  * Specifies if the tooltip should be disabled in touch devices (i.e. `html` has class `.touch`).
14
14
  */
15
15
  disabledOnTouch?: boolean;
16
- /**
17
- * The offset (in pixels) between the target element and the tooltip, defaults to zero.
18
- */
19
- offset?: number;
20
16
  /**
21
17
  * The hint string to display in the tooltip.
22
18
  */
23
19
  hint: string;
20
+ /**
21
+ * The gap (in pixels) between the target element and the tooltip, defaults to zero.
22
+ */
23
+ gap?: number;
24
24
  /**
25
25
  * Color of the dialog text, same format as a CSS color string (i.e. '#000').
26
26
  */
@@ -36,5 +36,5 @@ declare type Props = PropsWithChildren<HTMLAttributes<HTMLElement>> & {
36
36
  */
37
37
  cssDialog?: CSSProp<any>;
38
38
  };
39
- export default function WithTooltip({ arrowHeight, backgroundColor, cssDialog, disabledOnTouch, hint, offset, textColor, threshold, ...props }: Props): JSX.Element;
39
+ export default function WithTooltip({ arrowHeight, backgroundColor, cssDialog, disabledOnTouch, hint, gap, textColor, threshold, ...props }: Props): JSX.Element;
40
40
  export {};
@@ -67,19 +67,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
67
67
  var react_1 = __importStar(require("react"));
68
68
  var spase_1 = require("spase");
69
69
  var styled_components_1 = __importStar(require("styled-components"));
70
- var ExtractChildren_1 = __importDefault(require("./ExtractChildren"));
70
+ var ExtractChild_1 = __importDefault(require("./ExtractChild"));
71
71
  function WithTooltip(_a) {
72
- var _b = _a.arrowHeight, arrowHeight = _b === void 0 ? 8 : _b, _c = _a.backgroundColor, backgroundColor = _c === void 0 ? '#000' : _c, cssDialog = _a.cssDialog, _d = _a.disabledOnTouch, disabledOnTouch = _d === void 0 ? true : _d, hint = _a.hint, _e = _a.offset, offset = _e === void 0 ? 5 : _e, _f = _a.textColor, textColor = _f === void 0 ? '#fff' : _f, _g = _a.threshold, threshold = _g === void 0 ? 100 : _g, props = __rest(_a, ["arrowHeight", "backgroundColor", "cssDialog", "disabledOnTouch", "hint", "offset", "textColor", "threshold"]);
73
- var _h = __read((0, react_1.useState)(new spase_1.Size()), 2), textSize = _h[0], setTextSize = _h[1];
74
- var _j = __read((0, react_1.useState)('bc'), 2), position = _j[0], setPosition = _j[1];
75
- function computePosition(target, threshold) {
72
+ var _b = _a.arrowHeight, arrowHeight = _b === void 0 ? 8 : _b, _c = _a.backgroundColor, backgroundColor = _c === void 0 ? '#000' : _c, cssDialog = _a.cssDialog, _d = _a.disabledOnTouch, disabledOnTouch = _d === void 0 ? true : _d, hint = _a.hint, _e = _a.gap, gap = _e === void 0 ? 5 : _e, _f = _a.textColor, textColor = _f === void 0 ? '#fff' : _f, _g = _a.threshold, threshold = _g === void 0 ? 100 : _g, props = __rest(_a, ["arrowHeight", "backgroundColor", "cssDialog", "disabledOnTouch", "hint", "gap", "textColor", "threshold"]);
73
+ var computePosition = function (target, threshold) {
76
74
  var vrect = spase_1.Rect.fromViewport();
77
75
  var rect = spase_1.Rect.intersecting(target);
78
76
  if (rect) {
79
- var leftBound = (rect.center.x - vrect.left) < threshold;
80
- var rightBound = (vrect.center.x - rect.right) < threshold;
81
- var topBound = (rect.center.y - vrect.top) < threshold;
82
- var bottomBound = (vrect.center.y - rect.bottom) < threshold;
77
+ var leftBound = (rect.left - vrect.left) < threshold;
78
+ var rightBound = (vrect.right - rect.right) < threshold;
79
+ var topBound = (rect.top - vrect.top) < threshold;
80
+ var bottomBound = (vrect.bottom - rect.bottom) < threshold;
83
81
  if (leftBound && topBound)
84
82
  return 'br';
85
83
  if (leftBound && bottomBound)
@@ -96,8 +94,8 @@ function WithTooltip(_a) {
96
94
  return 'tc';
97
95
  }
98
96
  return 'bc';
99
- }
100
- function computeTextSize(target) {
97
+ };
98
+ var computeTextSize = function (target, threshold) {
101
99
  var computedStyle = window.getComputedStyle(target, '::after');
102
100
  var div = document.createElement('div');
103
101
  div.innerHTML = hint;
@@ -106,51 +104,61 @@ function WithTooltip(_a) {
106
104
  div.style.fontStyle = computedStyle.getPropertyValue('font-style');
107
105
  div.style.fontVariant = computedStyle.getPropertyValue('font-variant');
108
106
  div.style.fontWeight = computedStyle.getPropertyValue('font-weight');
109
- div.style.height = '30px';
110
107
  div.style.left = '0';
111
108
  div.style.position = 'absolute';
112
109
  div.style.top = '0';
113
110
  div.style.visibility = 'hidden';
114
- div.style.whiteSpace = 'no-wrap';
111
+ div.style.whiteSpace = 'pre';
115
112
  document.body.appendChild(div);
116
- var width = div.clientWidth;
117
- var height = div.clientHeight;
113
+ // Add 1px as buffer to mitigate precision discrepancies.
114
+ var width = div.clientWidth + 1;
115
+ var height = div.clientHeight + 1;
118
116
  document.body.removeChild(div);
119
117
  return new spase_1.Size([width, height]);
120
- }
121
- function onMouseOver(event) {
122
- setTextSize(computeTextSize(event.currentTarget));
118
+ };
119
+ var onMouseOver = function (event) {
123
120
  setPosition(computePosition(event.currentTarget, threshold));
124
- }
125
- return (react_1.default.createElement(StyledRoot, __assign({ position: position, arrowHeight: arrowHeight, backgroundColor: backgroundColor, cssDialog: cssDialog, disabledOnTouch: disabledOnTouch, hint: hint, offset: offset, onMouseOver: function (event) { return onMouseOver(event); }, textColor: textColor, textSize: textSize }, props)));
121
+ setTextSize(computeTextSize(event.currentTarget, threshold));
122
+ };
123
+ var _h = __read((0, react_1.useState)(new spase_1.Size()), 2), textSize = _h[0], setTextSize = _h[1];
124
+ var _j = __read((0, react_1.useState)(undefined), 2), position = _j[0], setPosition = _j[1];
125
+ var childRef = (0, react_1.useRef)(null);
126
+ (0, react_1.useEffect)(function () {
127
+ var childNode = childRef.current;
128
+ if (!childNode)
129
+ return;
130
+ setPosition(computePosition(childNode, threshold));
131
+ setTextSize(computeTextSize(childNode, threshold));
132
+ }, []);
133
+ return (react_1.default.createElement(StyledRoot, __assign({ arrowHeight: arrowHeight, backgroundColor: backgroundColor, ref: childRef, cssDialog: cssDialog, disabledOnTouch: disabledOnTouch, hint: hint, gap: gap, onMouseOver: function (event) { return onMouseOver(event); }, position: position, textColor: textColor, textSize: textSize }, props)));
126
134
  }
127
135
  exports.default = WithTooltip;
128
- function _cssDisplacement(position, arrowHeight, offset) {
136
+ function makeDisplacementCSS(position, arrowHeight, gap) {
129
137
  switch (position) {
130
- case 'tl': return (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["top: ", "px; left: 100%;"], ["top: ", "px; left: 100%;"])), -arrowHeight);
138
+ case 'tl': return (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["top: ", "px; left: calc(50% + ", "px);"], ["top: ", "px; left: calc(50% + ", "px);"])), -arrowHeight, arrowHeight * 2.5);
131
139
  case 'tc': return (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["top: ", "px; left: 50%;"], ["top: ", "px; left: 50%;"])), -arrowHeight);
132
- case 'tr': return (0, styled_components_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["top: ", "px; right: 100%;"], ["top: ", "px; right: 100%;"])), -arrowHeight);
140
+ case 'tr': return (0, styled_components_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["top: ", "px; right: calc(50% + ", "px);"], ["top: ", "px; right: calc(50% + ", "px);"])), -arrowHeight, arrowHeight * 2.5);
133
141
  case 'cl': return (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["top: 50%; left: ", "px;"], ["top: 50%; left: ", "px;"])), -arrowHeight);
134
142
  case 'cr': return (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["top: 50%; right: ", "px;"], ["top: 50%; right: ", "px;"])), -arrowHeight);
135
- case 'bl': return (0, styled_components_1.css)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["bottom: ", "px; left: 100%;"], ["bottom: ", "px; left: 100%;"])), -arrowHeight);
143
+ case 'bl': return (0, styled_components_1.css)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["bottom: ", "px; left: calc(50% + ", "px);"], ["bottom: ", "px; left: calc(50% + ", "px);"])), -arrowHeight, arrowHeight * 2.5);
136
144
  case 'bc': return (0, styled_components_1.css)(templateObject_7 || (templateObject_7 = __makeTemplateObject(["bottom: ", "px; left: 50%;"], ["bottom: ", "px; left: 50%;"])), -arrowHeight);
137
- case 'br': return (0, styled_components_1.css)(templateObject_8 || (templateObject_8 = __makeTemplateObject(["bottom: ", "px; right: 100%;"], ["bottom: ", "px; right: 100%;"])), -arrowHeight);
145
+ case 'br': return (0, styled_components_1.css)(templateObject_8 || (templateObject_8 = __makeTemplateObject(["bottom: ", "px; right: calc(50% + ", "px);"], ["bottom: ", "px; right: calc(50% + ", "px);"])), -arrowHeight, arrowHeight * 2.5);
138
146
  }
139
147
  }
140
- function _cssDialog(position, arrowHeight, offset) {
148
+ function makeDialogPositionCSS(position, arrowHeight, gap) {
141
149
  switch (position) {
142
- case 'tl': return (0, styled_components_1.css)(templateObject_9 || (templateObject_9 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), calc(-100% - ", "px), 0);"], ["transform: translate3d(calc(-100% - ", "px), calc(-100% - ", "px), 0);"])), offset, offset);
143
- case 'tc': return (0, styled_components_1.css)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["transform: translate3d(-50%, calc(-100% - ", "px), 0);"], ["transform: translate3d(-50%, calc(-100% - ", "px), 0);"])), offset);
144
- case 'tr': return (0, styled_components_1.css)(templateObject_11 || (templateObject_11 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), calc(-100% - ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px), calc(-100% - ", "px), 0);"])), offset, offset);
145
- case 'cl': return (0, styled_components_1.css)(templateObject_12 || (templateObject_12 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), -50%, 0);"], ["transform: translate3d(calc(-100% - ", "px), -50%, 0);"])), offset);
146
- case 'cr': return (0, styled_components_1.css)(templateObject_13 || (templateObject_13 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), -50%, 0);"], ["transform: translate3d(calc(100% + ", "px), -50%, 0);"])), offset);
147
- case 'bl': return (0, styled_components_1.css)(templateObject_14 || (templateObject_14 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), calc(100% + ", "px), 0);"], ["transform: translate3d(calc(-100% - ", "px), calc(100% + ", "px), 0);"])), offset, offset);
148
- case 'bc': return (0, styled_components_1.css)(templateObject_15 || (templateObject_15 = __makeTemplateObject(["transform: translate3d(-50%, calc(100% + ", "px), 0);"], ["transform: translate3d(-50%, calc(100% + ", "px), 0);"])), offset);
149
- case 'br': return (0, styled_components_1.css)(templateObject_16 || (templateObject_16 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), calc(100% + ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px), calc(100% + ", "px), 0);"])), offset, offset);
150
+ case 'tl': return (0, styled_components_1.css)(templateObject_9 || (templateObject_9 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), calc(-100% - ", "px), 0);"], ["transform: translate3d(calc(-100% - ", "px), calc(-100% - ", "px), 0);"])), gap, gap);
151
+ case 'tc': return (0, styled_components_1.css)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["transform: translate3d(-50%, calc(-100% - ", "px), 0);"], ["transform: translate3d(-50%, calc(-100% - ", "px), 0);"])), gap);
152
+ case 'tr': return (0, styled_components_1.css)(templateObject_11 || (templateObject_11 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), calc(-100% - ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px), calc(-100% - ", "px), 0);"])), gap, gap);
153
+ case 'cl': return (0, styled_components_1.css)(templateObject_12 || (templateObject_12 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), -50%, 0);"], ["transform: translate3d(calc(-100% - ", "px), -50%, 0);"])), gap);
154
+ case 'cr': return (0, styled_components_1.css)(templateObject_13 || (templateObject_13 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), -50%, 0);"], ["transform: translate3d(calc(100% + ", "px), -50%, 0);"])), gap);
155
+ case 'bl': return (0, styled_components_1.css)(templateObject_14 || (templateObject_14 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), calc(100% + ", "px), 0);"], ["transform: translate3d(calc(-100% - ", "px), calc(100% + ", "px), 0);"])), gap, gap);
156
+ case 'bc': return (0, styled_components_1.css)(templateObject_15 || (templateObject_15 = __makeTemplateObject(["transform: translate3d(-50%, calc(100% + ", "px), 0);"], ["transform: translate3d(-50%, calc(100% + ", "px), 0);"])), gap);
157
+ case 'br': return (0, styled_components_1.css)(templateObject_16 || (templateObject_16 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), calc(100% + ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px), calc(100% + ", "px), 0);"])), gap, gap);
150
158
  }
151
159
  }
152
- function _cssArrow(position, arrowHeight, offset, color) {
153
- return (0, styled_components_1.css)(templateObject_33 || (templateObject_33 = __makeTemplateObject(["\n ", "\n ", "\n "], ["\n ", "\n ", "\n "])), function () {
160
+ function makeArrowPositionCSS(position, arrowHeight, gap, color) {
161
+ return (0, styled_components_1.css)(templateObject_33 || (templateObject_33 = __makeTemplateObject(["\n ", "\n\n ", "\n "], ["\n ", "\n\n ", "\n "])), function () {
154
162
  switch (position) {
155
163
  case 'tl': return (0, styled_components_1.css)(templateObject_17 || (templateObject_17 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
156
164
  case 'tc': return (0, styled_components_1.css)(templateObject_18 || (templateObject_18 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
@@ -163,17 +171,17 @@ function _cssArrow(position, arrowHeight, offset, color) {
163
171
  }
164
172
  }, function () {
165
173
  switch (position) {
166
- case 'tl': return (0, styled_components_1.css)(templateObject_25 || (templateObject_25 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% - ", "px), 0);"], ["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% - ", "px), 0);"])), offset, arrowHeight * 3, offset);
167
- case 'tc': return (0, styled_components_1.css)(templateObject_26 || (templateObject_26 = __makeTemplateObject(["transform: translate3d(-50%, calc(0% - ", "px), 0);"], ["transform: translate3d(-50%, calc(0% - ", "px), 0);"])), offset);
168
- case 'tr': return (0, styled_components_1.css)(templateObject_27 || (templateObject_27 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% - ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% - ", "px), 0);"])), offset, arrowHeight, offset);
169
- case 'cl': return (0, styled_components_1.css)(templateObject_28 || (templateObject_28 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px), -50%, 0);"], ["transform: translate3d(calc(0% - ", "px), -50%, 0);"])), offset);
170
- case 'cr': return (0, styled_components_1.css)(templateObject_29 || (templateObject_29 = __makeTemplateObject(["transform: translate3d(calc(0% + ", "px), -50%, 0);"], ["transform: translate3d(calc(0% + ", "px), -50%, 0);"])), offset);
171
- case 'bl': return (0, styled_components_1.css)(templateObject_30 || (templateObject_30 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% + ", "px), 0);"], ["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% + ", "px), 0);"])), offset, arrowHeight * 3, offset);
172
- case 'bc': return (0, styled_components_1.css)(templateObject_31 || (templateObject_31 = __makeTemplateObject(["transform: translate3d(-50%, calc(0% + ", "px), 0);"], ["transform: translate3d(-50%, calc(0% + ", "px), 0);"])), offset);
173
- case 'br': return (0, styled_components_1.css)(templateObject_32 || (templateObject_32 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% + ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% + ", "px), 0);"])), offset, arrowHeight, offset);
174
+ case 'tl': return (0, styled_components_1.css)(templateObject_25 || (templateObject_25 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% - ", "px), 0);"], ["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% - ", "px), 0);"])), gap, arrowHeight * 3, gap);
175
+ case 'tc': return (0, styled_components_1.css)(templateObject_26 || (templateObject_26 = __makeTemplateObject(["transform: translate3d(-50%, calc(0% - ", "px), 0);"], ["transform: translate3d(-50%, calc(0% - ", "px), 0);"])), gap);
176
+ case 'tr': return (0, styled_components_1.css)(templateObject_27 || (templateObject_27 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% - ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% - ", "px), 0);"])), gap, arrowHeight, gap);
177
+ case 'cl': return (0, styled_components_1.css)(templateObject_28 || (templateObject_28 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px), -50%, 0);"], ["transform: translate3d(calc(0% - ", "px), -50%, 0);"])), gap);
178
+ case 'cr': return (0, styled_components_1.css)(templateObject_29 || (templateObject_29 = __makeTemplateObject(["transform: translate3d(calc(0% + ", "px), -50%, 0);"], ["transform: translate3d(calc(0% + ", "px), -50%, 0);"])), gap);
179
+ case 'bl': return (0, styled_components_1.css)(templateObject_30 || (templateObject_30 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% + ", "px), 0);"], ["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% + ", "px), 0);"])), gap, arrowHeight * 3, gap);
180
+ case 'bc': return (0, styled_components_1.css)(templateObject_31 || (templateObject_31 = __makeTemplateObject(["transform: translate3d(-50%, calc(0% + ", "px), 0);"], ["transform: translate3d(-50%, calc(0% + ", "px), 0);"])), gap);
181
+ case 'br': return (0, styled_components_1.css)(templateObject_32 || (templateObject_32 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% + ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% + ", "px), 0);"])), gap, arrowHeight, gap);
174
182
  }
175
183
  });
176
184
  }
177
- var StyledRoot = (0, styled_components_1.default)(ExtractChildren_1.default)(templateObject_34 || (templateObject_34 = __makeTemplateObject(["\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ", "px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ", "\n ", "\n ", "\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 240px;\n padding: 10px 14px;\n text-align: left;\n\n ", "\n\n background: ", ";\n color: ", ";\n content: '", "';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n width: ", ";\n z-index: 10000;\n\n ", "\n ", "\n ", "\n }\n\n ", " {\n opacity: 1;\n }\n\n ", " {\n opacity: 1;\n }\n"], ["\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ", "px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ", "\n ", "\n ", "\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 240px;\n padding: 10px 14px;\n text-align: left;\n\n ", "\n\n background: ", ";\n color: ", ";\n content: '", "';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n width: ", ";\n z-index: 10000;\n\n ", "\n ", "\n ", "\n }\n\n ", " {\n opacity: 1;\n }\n\n ", " {\n opacity: 1;\n }\n"])), function (props) { return props.arrowHeight; }, function (props) { return _cssDisplacement(props.position, props.arrowHeight, props.offset); }, function (props) { return _cssArrow(props.position, props.arrowHeight, props.offset, props.backgroundColor); }, function (props) { return props.disabledOnTouch ? 'html.touch & { display: none; }' : ''; }, function (props) { return props.cssDialog; }, function (props) { return props.backgroundColor; }, function (props) { return props.textColor; }, function (props) { return props.hint; }, function (props) { return props.textSize.width > 0 ? props.textSize.width : 'auto'; }, function (props) { return _cssDisplacement(props.position, props.arrowHeight, props.offset); }, function (props) { return _cssDialog(props.position, props.arrowHeight, props.offset); }, function (props) { return props.disabledOnTouch ? 'html.touch & { display: none; }' : ''; }, function (props) { return props.disabledOnTouch ? 'html:not(.touch) &:hover::before' : '&:hover::before'; }, function (props) { return props.disabledOnTouch ? 'html:not(.touch) &:hover::after' : '&:hover::after'; });
178
- var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27, templateObject_28, templateObject_29, templateObject_30, templateObject_31, templateObject_32, templateObject_33, templateObject_34;
185
+ var StyledRoot = (0, styled_components_1.default)(ExtractChild_1.default)(templateObject_36 || (templateObject_36 = __makeTemplateObject(["\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ", "px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ", "\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 200px;\n padding: 10px 14px;\n text-align: left;\n\n ", "\n\n background: ", ";\n color: ", ";\n content: '", "';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n z-index: 10000;\n\n ", "\n }\n\n ", " {\n &::before { opacity: 1; }\n &::after { opacity: 1; }\n }\n"], ["\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ", "px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ", "\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 200px;\n padding: 10px 14px;\n text-align: left;\n\n ", "\n\n background: ", ";\n color: ", ";\n content: '", "';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n z-index: 10000;\n\n ", "\n }\n\n ", " {\n &::before { opacity: 1; }\n &::after { opacity: 1; }\n }\n"])), function (props) { return props.arrowHeight; }, function (props) { return props.position && props.textSize && (0, styled_components_1.css)(templateObject_34 || (templateObject_34 = __makeTemplateObject(["\n ", "\n ", "\n ", "\n "], ["\n ", "\n ", "\n ", "\n "])), makeDisplacementCSS(props.position, props.arrowHeight, props.gap), makeArrowPositionCSS(props.position, props.arrowHeight, props.gap, props.backgroundColor), props.disabledOnTouch ? 'html.touch & { display: none; }' : ''); }, function (props) { return props.cssDialog; }, function (props) { return props.backgroundColor; }, function (props) { return props.textColor; }, function (props) { return props.hint; }, function (props) { return props.position && props.textSize && (0, styled_components_1.css)(templateObject_35 || (templateObject_35 = __makeTemplateObject(["\n width: ", ";\n ", "\n ", "\n ", "\n "], ["\n width: ", ";\n ", "\n ", "\n ", "\n "])), props.textSize.width > 0 ? "".concat(props.textSize.width, "px") : 'auto', makeDisplacementCSS(props.position, props.arrowHeight, props.gap), makeDialogPositionCSS(props.position, props.arrowHeight, props.gap), props.disabledOnTouch ? 'html.touch & { display: none; }' : ''); }, function (props) { return props.disabledOnTouch ? 'html:not(.touch) &:hover' : '&:hover'; });
186
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27, templateObject_28, templateObject_29, templateObject_30, templateObject_31, templateObject_32, templateObject_33, templateObject_34, templateObject_35, templateObject_36;
179
187
  //# sourceMappingURL=WithTooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WithTooltip.js","sourceRoot":"/","sources":["WithTooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { HTMLAttributes, MouseEvent, PropsWithChildren, useState } from 'react'\nimport { Rect, Size } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport ExtractChildren from './ExtractChildren'\n\ntype Props = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * The height of the arrow. The width (longest edge) of the arrow is always twice its height.\n */\n arrowHeight?: number\n\n /**\n * Color of the dialog background, same format as a CSS color string (i.e. '#000').\n */\n backgroundColor?: string\n\n /**\n * Specifies if the tooltip should be disabled in touch devices (i.e. `html` has class `.touch`).\n */\n disabledOnTouch?: boolean\n\n /**\n * The offset (in pixels) between the target element and the tooltip, defaults to zero.\n */\n offset?: number\n\n /**\n * The hint string to display in the tooltip.\n */\n hint: string\n\n /**\n * Color of the dialog text, same format as a CSS color string (i.e. '#000').\n */\n textColor?: string\n\n /**\n * The minimum space (in pixels) between the target element and the edge of the window required to\n * trigger an alignment change, defaults to `100px`.\n */\n threshold?: number\n\n /**\n * Custom CSS provided to the dialog. Not all CSS rules will take effect as they will be\n * overridden by internal rules.\n */\n cssDialog?: CSSProp<any>\n}\n\ntype Position = 'tl' | 'tc' | 'tr' | 'cl' | 'cr' | 'bl' | 'bc' | 'br'\n\nexport default function WithTooltip({\n arrowHeight = 8,\n backgroundColor = '#000',\n cssDialog,\n disabledOnTouch = true,\n hint,\n offset = 5,\n textColor = '#fff',\n threshold = 100,\n ...props\n}: Props) {\n const [textSize, setTextSize] = useState<Size>(new Size())\n const [position, setPosition] = useState<Position>('bc')\n\n function computePosition(target: Element, threshold: number): Position {\n const vrect = Rect.fromViewport()\n const rect = Rect.intersecting(target)\n\n if (rect) {\n const leftBound = (rect.center.x - vrect.left) < threshold\n const rightBound = (vrect.center.x - rect.right) < threshold\n const topBound = (rect.center.y - vrect.top) < threshold\n const bottomBound = (vrect.center.y - rect.bottom) < threshold\n\n if (leftBound && topBound) return 'br'\n if (leftBound && bottomBound) return 'tr'\n if (rightBound && topBound) return 'bl'\n if (rightBound && bottomBound) return 'tl'\n if (leftBound) return 'cr'\n if (rightBound) return 'cl'\n if (bottomBound) return 'tc'\n }\n\n return 'bc'\n }\n\n function computeTextSize(target: Element): Size {\n const computedStyle = window.getComputedStyle(target, '::after')\n const div = document.createElement('div')\n div.innerHTML = hint\n div.style.fontFamily = computedStyle.getPropertyValue('font-family')\n div.style.fontSize = computedStyle.getPropertyValue('font-size')\n div.style.fontStyle = computedStyle.getPropertyValue('font-style')\n div.style.fontVariant = computedStyle.getPropertyValue('font-variant')\n div.style.fontWeight = computedStyle.getPropertyValue('font-weight')\n div.style.height = '30px'\n div.style.left = '0'\n div.style.position = 'absolute'\n div.style.top = '0'\n div.style.visibility = 'hidden'\n div.style.whiteSpace = 'no-wrap'\n\n document.body.appendChild(div)\n const width = div.clientWidth\n const height = div.clientHeight\n document.body.removeChild(div)\n\n return new Size([width, height])\n }\n\n function onMouseOver(event: MouseEvent) {\n setTextSize(computeTextSize(event.currentTarget))\n setPosition(computePosition(event.currentTarget, threshold))\n }\n\n return (\n <StyledRoot\n position={position}\n arrowHeight={arrowHeight}\n backgroundColor={backgroundColor}\n cssDialog={cssDialog}\n disabledOnTouch={disabledOnTouch}\n hint={hint}\n offset={offset}\n onMouseOver={event => onMouseOver(event)}\n textColor={textColor}\n textSize={textSize}\n {...props}\n />\n )\n}\n\nfunction _cssDisplacement(position: Position, arrowHeight: number, offset: number): CSSProp {\n switch (position) {\n case 'tl': return css`top: ${-arrowHeight}px; left: 100%;`\n case 'tc': return css`top: ${-arrowHeight}px; left: 50%;`\n case 'tr': return css`top: ${-arrowHeight}px; right: 100%;`\n case 'cl': return css`top: 50%; left: ${-arrowHeight}px;`\n case 'cr': return css`top: 50%; right: ${-arrowHeight}px;`\n case 'bl': return css`bottom: ${-arrowHeight}px; left: 100%;`\n case 'bc': return css`bottom: ${-arrowHeight}px; left: 50%;`\n case 'br': return css`bottom: ${-arrowHeight}px; right: 100%;`\n }\n}\n\nfunction _cssDialog(position: Position, arrowHeight: number, offset: number): CSSProp {\n switch (position) {\n case 'tl': return css`transform: translate3d(calc(-100% - ${offset}px), calc(-100% - ${offset}px), 0);`\n case 'tc': return css`transform: translate3d(-50%, calc(-100% - ${offset}px), 0);`\n case 'tr': return css`transform: translate3d(calc(100% + ${offset}px), calc(-100% - ${offset}px), 0);`\n case 'cl': return css`transform: translate3d(calc(-100% - ${offset}px), -50%, 0);`\n case 'cr': return css`transform: translate3d(calc(100% + ${offset}px), -50%, 0);`\n case 'bl': return css`transform: translate3d(calc(-100% - ${offset}px), calc(100% + ${offset}px), 0);`\n case 'bc': return css`transform: translate3d(-50%, calc(100% + ${offset}px), 0);`\n case 'br': return css`transform: translate3d(calc(100% + ${offset}px), calc(100% + ${offset}px), 0);`\n }\n}\n\nfunction _cssArrow(position: Position, arrowHeight: number, offset: number, color: string): CSSProp {\n return css`\n ${() => {\n switch (position) {\n case 'tl': return css`border-color: ${color} transparent transparent transparent;`\n case 'tc': return css`border-color: ${color} transparent transparent transparent;`\n case 'tr': return css`border-color: ${color} transparent transparent transparent;`\n case 'cl': return css`border-color: transparent transparent transparent ${color};`\n case 'cr': return css`border-color: transparent ${color} transparent transparent;`\n case 'bl': return css`border-color: transparent transparent ${color} transparent;`\n case 'bc': return css`border-color: transparent transparent ${color} transparent;`\n case 'br': return css`border-color: transparent transparent ${color} transparent;`\n }\n }}\n ${() => {\n switch (position) {\n case 'tl': return css`transform: translate3d(calc(0% - ${offset}px - ${arrowHeight*3}px), calc(0% - ${offset}px), 0);`\n case 'tc': return css`transform: translate3d(-50%, calc(0% - ${offset}px), 0);`\n case 'tr': return css`transform: translate3d(calc(100% + ${offset}px + ${arrowHeight}px), calc(0% - ${offset}px), 0);`\n case 'cl': return css`transform: translate3d(calc(0% - ${offset}px), -50%, 0);`\n case 'cr': return css`transform: translate3d(calc(0% + ${offset}px), -50%, 0);`\n case 'bl': return css`transform: translate3d(calc(0% - ${offset}px - ${arrowHeight*3}px), calc(0% + ${offset}px), 0);`\n case 'bc': return css`transform: translate3d(-50%, calc(0% + ${offset}px), 0);`\n case 'br': return css`transform: translate3d(calc(100% + ${offset}px + ${arrowHeight}px), calc(0% + ${offset}px), 0);`\n }\n }}\n `\n}\n\nconst StyledRoot = styled(ExtractChildren)<{\n arrowHeight: number\n backgroundColor: string\n cssDialog?: CSSProp\n disabledOnTouch: boolean\n hint: string\n offset: number\n position: Position\n textColor: string\n textSize: Size\n}>`\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ${props => props.arrowHeight}px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ${props => _cssDisplacement(props.position, props.arrowHeight, props.offset)}\n ${props => _cssArrow(props.position, props.arrowHeight, props.offset, props.backgroundColor)}\n ${props => props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 240px;\n padding: 10px 14px;\n text-align: left;\n\n ${props => props.cssDialog}\n\n background: ${props => props.backgroundColor};\n color: ${props => props.textColor};\n content: '${props => props.hint}';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n width: ${props => props.textSize.width > 0 ? props.textSize.width : 'auto'};\n z-index: 10000;\n\n ${props => _cssDisplacement(props.position, props.arrowHeight, props.offset)}\n ${props => _cssDialog(props.position, props.arrowHeight, props.offset)}\n ${props => props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n }\n\n ${props => props.disabledOnTouch ? 'html:not(.touch) &:hover::before' : '&:hover::before'} {\n opacity: 1;\n }\n\n ${props => props.disabledOnTouch ? 'html:not(.touch) &:hover::after' : '&:hover::after'} {\n opacity: 1;\n }\n`\n"]}
1
+ {"version":3,"file":"WithTooltip.js","sourceRoot":"/","sources":["WithTooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { HTMLAttributes, MouseEvent, PropsWithChildren, RefObject, useEffect, useRef, useState } from 'react'\nimport { Rect, Size } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport ExtractChild from './ExtractChild'\n\ntype Props = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * The height of the arrow. The width (longest edge) of the arrow is always twice its height.\n */\n arrowHeight?: number\n\n /**\n * Color of the dialog background, same format as a CSS color string (i.e. '#000').\n */\n backgroundColor?: string\n\n /**\n * Specifies if the tooltip should be disabled in touch devices (i.e. `html` has class `.touch`).\n */\n disabledOnTouch?: boolean\n\n /**\n * The hint string to display in the tooltip.\n */\n hint: string\n\n /**\n * The gap (in pixels) between the target element and the tooltip, defaults to zero.\n */\n gap?: number\n\n /**\n * Color of the dialog text, same format as a CSS color string (i.e. '#000').\n */\n textColor?: string\n\n /**\n * The minimum space (in pixels) between the target element and the edge of the window required to\n * trigger an alignment change, defaults to `100px`.\n */\n threshold?: number\n\n /**\n * Custom CSS provided to the dialog. Not all CSS rules will take effect as they will be\n * overridden by internal rules.\n */\n cssDialog?: CSSProp<any>\n}\n\ntype Position = 'tl' | 'tc' | 'tr' | 'cl' | 'cr' | 'bl' | 'bc' | 'br'\n\nexport default function WithTooltip({\n arrowHeight = 8,\n backgroundColor = '#000',\n cssDialog,\n disabledOnTouch = true,\n hint,\n gap = 5,\n textColor = '#fff',\n threshold = 100,\n ...props\n}: Props) {\n const computePosition = (target: Element, threshold: number): Position => {\n const vrect = Rect.fromViewport()\n const rect = Rect.intersecting(target)\n\n if (rect) {\n const leftBound = (rect.left - vrect.left) < threshold\n const rightBound = (vrect.right - rect.right) < threshold\n const topBound = (rect.top - vrect.top) < threshold\n const bottomBound = (vrect.bottom - rect.bottom) < threshold\n\n if (leftBound && topBound) return 'br'\n if (leftBound && bottomBound) return 'tr'\n if (rightBound && topBound) return 'bl'\n if (rightBound && bottomBound) return 'tl'\n if (leftBound) return 'cr'\n if (rightBound) return 'cl'\n if (bottomBound) return 'tc'\n }\n\n return 'bc'\n }\n\n const computeTextSize = (target: Element, threshold: number): Size => {\n const computedStyle = window.getComputedStyle(target, '::after')\n const div = document.createElement('div')\n div.innerHTML = hint\n div.style.fontFamily = computedStyle.getPropertyValue('font-family')\n div.style.fontSize = computedStyle.getPropertyValue('font-size')\n div.style.fontStyle = computedStyle.getPropertyValue('font-style')\n div.style.fontVariant = computedStyle.getPropertyValue('font-variant')\n div.style.fontWeight = computedStyle.getPropertyValue('font-weight')\n div.style.left = '0'\n div.style.position = 'absolute'\n div.style.top = '0'\n div.style.visibility = 'hidden'\n div.style.whiteSpace = 'pre'\n\n document.body.appendChild(div)\n\n // Add 1px as buffer to mitigate precision discrepancies.\n const width = div.clientWidth + 1\n const height = div.clientHeight + 1\n\n document.body.removeChild(div)\n\n return new Size([width, height])\n }\n\n const onMouseOver = (event: MouseEvent) => {\n setPosition(computePosition(event.currentTarget, threshold))\n setTextSize(computeTextSize(event.currentTarget, threshold))\n }\n\n const [textSize, setTextSize] = useState<Size | undefined>(new Size())\n const [position, setPosition] = useState<Position | undefined>(undefined)\n\n const childRef = useRef<HTMLElement>(null)\n\n useEffect(() => {\n const childNode = childRef.current\n if (!childNode) return\n setPosition(computePosition(childNode, threshold))\n setTextSize(computeTextSize(childNode, threshold))\n }, [])\n\n return (\n <StyledRoot\n arrowHeight={arrowHeight}\n backgroundColor={backgroundColor}\n ref={childRef}\n cssDialog={cssDialog}\n disabledOnTouch={disabledOnTouch}\n hint={hint}\n gap={gap}\n onMouseOver={event => onMouseOver(event)}\n position={position}\n textColor={textColor}\n textSize={textSize}\n {...props}\n />\n )\n}\n\nfunction makeDisplacementCSS(position: Position, arrowHeight: number, gap: number): CSSProp {\n switch (position) {\n case 'tl': return css`top: ${-arrowHeight}px; left: calc(50% + ${arrowHeight*2.5}px);`\n case 'tc': return css`top: ${-arrowHeight}px; left: 50%;`\n case 'tr': return css`top: ${-arrowHeight}px; right: calc(50% + ${arrowHeight*2.5}px);`\n case 'cl': return css`top: 50%; left: ${-arrowHeight}px;`\n case 'cr': return css`top: 50%; right: ${-arrowHeight}px;`\n case 'bl': return css`bottom: ${-arrowHeight}px; left: calc(50% + ${arrowHeight*2.5}px);`\n case 'bc': return css`bottom: ${-arrowHeight}px; left: 50%;`\n case 'br': return css`bottom: ${-arrowHeight}px; right: calc(50% + ${arrowHeight*2.5}px);`\n }\n}\n\nfunction makeDialogPositionCSS(position: Position, arrowHeight: number, gap: number): CSSProp {\n switch (position) {\n case 'tl': return css`transform: translate3d(calc(-100% - ${gap}px), calc(-100% - ${gap}px), 0);`\n case 'tc': return css`transform: translate3d(-50%, calc(-100% - ${gap}px), 0);`\n case 'tr': return css`transform: translate3d(calc(100% + ${gap}px), calc(-100% - ${gap}px), 0);`\n case 'cl': return css`transform: translate3d(calc(-100% - ${gap}px), -50%, 0);`\n case 'cr': return css`transform: translate3d(calc(100% + ${gap}px), -50%, 0);`\n case 'bl': return css`transform: translate3d(calc(-100% - ${gap}px), calc(100% + ${gap}px), 0);`\n case 'bc': return css`transform: translate3d(-50%, calc(100% + ${gap}px), 0);`\n case 'br': return css`transform: translate3d(calc(100% + ${gap}px), calc(100% + ${gap}px), 0);`\n }\n}\n\nfunction makeArrowPositionCSS(position: Position, arrowHeight: number, gap: number, color: string): CSSProp {\n return css`\n ${() => {\n switch (position) {\n case 'tl': return css`border-color: ${color} transparent transparent transparent;`\n case 'tc': return css`border-color: ${color} transparent transparent transparent;`\n case 'tr': return css`border-color: ${color} transparent transparent transparent;`\n case 'cl': return css`border-color: transparent transparent transparent ${color};`\n case 'cr': return css`border-color: transparent ${color} transparent transparent;`\n case 'bl': return css`border-color: transparent transparent ${color} transparent;`\n case 'bc': return css`border-color: transparent transparent ${color} transparent;`\n case 'br': return css`border-color: transparent transparent ${color} transparent;`\n }\n }}\n\n ${() => {\n switch (position) {\n case 'tl': return css`transform: translate3d(calc(0% - ${gap}px - ${arrowHeight*3}px), calc(0% - ${gap}px), 0);`\n case 'tc': return css`transform: translate3d(-50%, calc(0% - ${gap}px), 0);`\n case 'tr': return css`transform: translate3d(calc(100% + ${gap}px + ${arrowHeight}px), calc(0% - ${gap}px), 0);`\n case 'cl': return css`transform: translate3d(calc(0% - ${gap}px), -50%, 0);`\n case 'cr': return css`transform: translate3d(calc(0% + ${gap}px), -50%, 0);`\n case 'bl': return css`transform: translate3d(calc(0% - ${gap}px - ${arrowHeight*3}px), calc(0% + ${gap}px), 0);`\n case 'bc': return css`transform: translate3d(-50%, calc(0% + ${gap}px), 0);`\n case 'br': return css`transform: translate3d(calc(100% + ${gap}px + ${arrowHeight}px), calc(0% + ${gap}px), 0);`\n }\n }}\n `\n}\n\nconst StyledRoot = styled(ExtractChild)<{\n arrowHeight: number\n backgroundColor: string\n ref: RefObject<HTMLElement>\n cssDialog?: CSSProp\n disabledOnTouch: boolean\n hint: string\n gap: number\n position?: Position\n textColor: string\n textSize?: Size\n}>`\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ${props => props.arrowHeight}px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ${props => props.position && props.textSize && css`\n ${makeDisplacementCSS(props.position, props.arrowHeight, props.gap)}\n ${makeArrowPositionCSS(props.position, props.arrowHeight, props.gap, props.backgroundColor)}\n ${props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n `}\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 200px;\n padding: 10px 14px;\n text-align: left;\n\n ${props => props.cssDialog}\n\n background: ${props => props.backgroundColor};\n color: ${props => props.textColor};\n content: '${props => props.hint}';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n z-index: 10000;\n\n ${props => props.position && props.textSize && css`\n width: ${props.textSize.width > 0 ? `${props.textSize.width}px` : 'auto'};\n ${makeDisplacementCSS(props.position, props.arrowHeight, props.gap)}\n ${makeDialogPositionCSS(props.position, props.arrowHeight, props.gap)}\n ${props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n `}\n }\n\n ${props => props.disabledOnTouch ? 'html:not(.touch) &:hover' : '&:hover'} {\n &::before { opacity: 1; }\n &::after { opacity: 1; }\n }\n`\n"]}
@@ -64,9 +64,6 @@ var react_1 = require("react");
64
64
  */
65
65
  function useDragEffect(targetRef, _a, deps) {
66
66
  var onDragStart = _a.onDragStart, onDragMove = _a.onDragMove, onDragEnd = _a.onDragEnd, initialValue = _a.initialValue, transform = _a.transform, options = __rest(_a, ["onDragStart", "onDragMove", "onDragEnd", "initialValue", "transform"]);
67
- var valueRef = (0, react_1.useRef)(initialValue);
68
- var _b = __read((0, react_1.useState)(false), 2), isDragging = _b[0], setIsDragging = _b[1];
69
- var _c = __read((0, react_1.useState)(valueRef.current), 2), value = _c[0], setValue = _c[1];
70
67
  /**
71
68
  * Sets the current associated value reference. This reference object is equal to the `value`
72
69
  * state but differs slightly in how they are set. Because states are asynchronous by nature, this
@@ -76,12 +73,15 @@ function useDragEffect(targetRef, _a, deps) {
76
73
  *
77
74
  * @returns `true` if the value was set, `false` otherwise.
78
75
  */
79
- function setValueRef(value) {
76
+ var setValueRef = function (value) {
80
77
  if (lodash_1.default.isEqual(valueRef.current, value))
81
78
  return false;
82
79
  valueRef.current = value;
83
80
  return true;
84
- }
81
+ };
82
+ var valueRef = (0, react_1.useRef)(initialValue);
83
+ var _b = __read((0, react_1.useState)(false), 2), isDragging = _b[0], setIsDragging = _b[1];
84
+ var _c = __read((0, react_1.useState)(valueRef.current), 2), value = _c[0], setValue = _c[1];
85
85
  (0, react_1.useEffect)(function () {
86
86
  // debug(`Using drag effect for element ${targetRef.current}...`, 'OK', `value=${valueRef.current}`)
87
87
  if (targetRef.current && !interactjs_1.default.isSet(targetRef.current)) {
@@ -1 +1 @@
1
- {"version":3,"file":"useDragEffect.js","sourceRoot":"/","sources":["hooks/useDragEffect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAAiC;AACjC,kDAAsB;AACtB,+BAAwG;AA6CxG;;;;;;;;GAQG;AACH,SAAwB,aAAa,CAAuB,SAAiC,EAAE,EAAuF,EAAE,IAAqB;IAA5G,IAAA,WAAW,iBAAA,EAAE,UAAU,gBAAA,EAAE,SAAS,eAAA,EAAE,YAAY,kBAAA,EAAE,SAAS,eAAA,EAAK,OAAO,cAAzE,uEAA2E,CAAF;IACtK,IAAM,QAAQ,GAAG,IAAA,cAAM,EAAI,YAAY,CAAC,CAAA;IAClC,IAAA,KAAA,OAA8B,IAAA,gBAAQ,EAAU,KAAK,CAAC,IAAA,EAArD,UAAU,QAAA,EAAE,aAAa,QAA4B,CAAA;IACtD,IAAA,KAAA,OAAoB,IAAA,gBAAQ,EAAC,QAAQ,CAAC,OAAO,CAAC,IAAA,EAA7C,KAAK,QAAA,EAAE,QAAQ,QAA8B,CAAA;IAEpD;;;;;;;;OAQG;IACH,SAAS,WAAW,CAAC,KAAQ;QAC3B,IAAI,gBAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QACpD,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAA;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAA,iBAAS,EAAC;QACR,oGAAoG;QAEpG,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,oBAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;YAC3D,2FAA2F;YAC3F,8BAA8B;YAC9B,IAAA,oBAAQ,EAAC,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,qBACnC,OAAO,EAAE,IAAI,IACV,OAAO,KACV,OAAO,EAAE;oBACP,aAAa,CAAC,IAAI,CAAC,CAAA;oBACnB,WAAW,aAAX,WAAW,uBAAX,WAAW,EAAI,CAAA;gBACjB,CAAC,EACD,MAAM,EAAE,UAAC,EAAU;;wBAAR,EAAE,QAAA,EAAE,EAAE,QAAA;oBACf,IAAM,QAAQ,GAAG,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,mCAAI,CAAC,EAAE,EAAE,EAAE,CAAiB,CAAA;oBAElF,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE;wBACzB,2DAA2D;wBAC3D,QAAQ,CAAC,QAAQ,CAAC,CAAA;qBACnB;oBAED,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,EAAE,EAAE,EAAE,CAAC,CAAA;gBACtB,CAAC,EACD,KAAK,EAAE;oBACL,aAAa,CAAC,KAAK,CAAC,CAAA;oBACpB,SAAS,aAAT,SAAS,uBAAT,SAAS,EAAI,CAAA;gBACf,CAAC,IACD,CAAA;SACH;QAED,OAAO;YACL,uGAAuG;YAEvG,IAAI,SAAS,CAAC,OAAO,IAAI,oBAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;gBAC1D,IAAA,oBAAQ,EAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAA;aACpC;QACH,CAAC,CAAA;IACH,CAAC,2BAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAE,CAAA;IAEzB,IAAA,iBAAS,EAAC;QACR,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE;YACtB,0DAA0D;SAC3D;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,OAAO;QACL,UAAU,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC;QACvC,KAAK,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;KACzB,CAAA;AACH,CAAC;AArED,gCAqEC","sourcesContent":["import interact from 'interactjs'\nimport _ from 'lodash'\nimport { DependencyList, Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react'\n\n// const debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : () => {}\n\ntype ReturnedStates<T> = {\n isDragging: [boolean, Dispatch<SetStateAction<boolean>>]\n value: [T, Dispatch<SetStateAction<T>>]\n}\n\ntype Options<T> = Omit<Interact.DraggableOptions, 'onstart' | 'onmove' | 'onend'> & {\n /**\n * The initial associated value of this hook.\n */\n initialValue: T\n\n /**\n * Handler invoked when dragging starts.\n */\n onDragStart?: () => void\n\n /**\n * Handler invoked when dragging.\n *\n * @param dx - The displacement on the x-axis (in pixels) since the last emitted drag move event.\n * @param dy - The displacement on the y-axis (in pixels) since the last emitted drag move event.\n */\n onDragMove?: (dx: number, dy: number) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * A function that transforms the drag move delta values to the associated value of this hook.\n *\n * @param currentValue - The current associated value.\n * @param dx - The displacement on the x-axis (in pixels) since the last emitted drag move event.\n * @param dy - The displacement on the y-axis (in pixels) since the last emitted drag move event.\n *\n * @returns The transformed value.\n */\n transform?: (currentValue: T, dx: number, dy: number) => T\n}\n\n/**\n * Hook for adding effectful dragging interaction to an element.\n *\n * @param targetRef - The reference to the target element to add drag interaction to.\n * @param options - Additional options which include options for `module:interactjs.draggable`.\n * @param deps - Dependencies that trigger this effect.\n *\n * @returns The states created for this effect.\n */\nexport default function useDragEffect<T = [number, number]>(targetRef: RefObject<HTMLElement>, { onDragStart, onDragMove, onDragEnd, initialValue, transform, ...options }: Options<T>, deps?: DependencyList): ReturnedStates<T> {\n const valueRef = useRef<T>(initialValue)\n const [isDragging, setIsDragging] = useState<boolean>(false)\n const [value, setValue] = useState(valueRef.current)\n\n /**\n * Sets the current associated value reference. This reference object is equal to the `value`\n * state but differs slightly in how they are set. Because states are asynchronous by nature, this\n * reference object is used to cache time-sensitive value changes while drag event happens.\n *\n * @param value - The value to set the associated value to.\n *\n * @returns `true` if the value was set, `false` otherwise.\n */\n function setValueRef(value: T): boolean {\n if (_.isEqual(valueRef.current, value)) return false\n valueRef.current = value\n return true\n }\n\n useEffect(() => {\n // debug(`Using drag effect for element ${targetRef.current}...`, 'OK', `value=${valueRef.current}`)\n\n if (targetRef.current && !interact.isSet(targetRef.current)) {\n // Do not consume states in these listeners as they will remain their initial values within\n // the scope of the listeners.\n interact(targetRef.current).draggable({\n inertia: true,\n ...options,\n onstart: () => {\n setIsDragging(true)\n onDragStart?.()\n },\n onmove: ({ dx, dy }) => {\n const newValue = transform?.(valueRef.current, dx, dy) ?? [dx, dy] as unknown as T\n\n if (setValueRef(newValue)) {\n // debug('Updating value from dragging...', 'OK', newValue)\n setValue(newValue)\n }\n\n onDragMove?.(dx, dy)\n },\n onend: () => {\n setIsDragging(false)\n onDragEnd?.()\n },\n })\n }\n\n return () => {\n // debug(`Removing drag effect for element ${targetRef.current}...`, 'OK', `value=${valueRef.current}`)\n\n if (targetRef.current && interact.isSet(targetRef.current)) {\n interact(targetRef.current).unset()\n }\n }\n }, [...deps ? deps : []])\n\n useEffect(() => {\n if (setValueRef(value)) {\n // debug('Updating value from externally...', 'OK', value)\n }\n }, [value])\n\n return {\n isDragging: [isDragging, setIsDragging],\n value: [value, setValue],\n }\n}\n"]}
1
+ {"version":3,"file":"useDragEffect.js","sourceRoot":"/","sources":["hooks/useDragEffect.ts"],"names":[],"mappings":"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","sourcesContent":["import interact from 'interactjs'\nimport _ from 'lodash'\nimport { DependencyList, Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react'\n\n// const debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : () => {}\n\ntype ReturnedStates<T> = {\n isDragging: [boolean, Dispatch<SetStateAction<boolean>>]\n value: [T, Dispatch<SetStateAction<T>>]\n}\n\ntype Options<T> = Omit<Interact.DraggableOptions, 'onstart' | 'onmove' | 'onend'> & {\n /**\n * The initial associated value of this hook.\n */\n initialValue: T\n\n /**\n * Handler invoked when dragging starts.\n */\n onDragStart?: () => void\n\n /**\n * Handler invoked when dragging.\n *\n * @param dx - The displacement on the x-axis (in pixels) since the last emitted drag move event.\n * @param dy - The displacement on the y-axis (in pixels) since the last emitted drag move event.\n */\n onDragMove?: (dx: number, dy: number) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * A function that transforms the drag move delta values to the associated value of this hook.\n *\n * @param currentValue - The current associated value.\n * @param dx - The displacement on the x-axis (in pixels) since the last emitted drag move event.\n * @param dy - The displacement on the y-axis (in pixels) since the last emitted drag move event.\n *\n * @returns The transformed value.\n */\n transform?: (currentValue: T, dx: number, dy: number) => T\n}\n\n/**\n * Hook for adding effectful dragging interaction to an element.\n *\n * @param targetRef - The reference to the target element to add drag interaction to.\n * @param options - Additional options which include options for `module:interactjs.draggable`.\n * @param deps - Dependencies that trigger this effect.\n *\n * @returns The states created for this effect.\n */\nexport default function useDragEffect<T = [number, number]>(targetRef: RefObject<HTMLElement>, { onDragStart, onDragMove, onDragEnd, initialValue, transform, ...options }: Options<T>, deps?: DependencyList): ReturnedStates<T> {\n /**\n * Sets the current associated value reference. This reference object is equal to the `value`\n * state but differs slightly in how they are set. Because states are asynchronous by nature, this\n * reference object is used to cache time-sensitive value changes while drag event happens.\n *\n * @param value - The value to set the associated value to.\n *\n * @returns `true` if the value was set, `false` otherwise.\n */\n const setValueRef = (value: T): boolean => {\n if (_.isEqual(valueRef.current, value)) return false\n valueRef.current = value\n return true\n }\n\n const valueRef = useRef<T>(initialValue)\n const [isDragging, setIsDragging] = useState<boolean>(false)\n const [value, setValue] = useState(valueRef.current)\n\n useEffect(() => {\n // debug(`Using drag effect for element ${targetRef.current}...`, 'OK', `value=${valueRef.current}`)\n\n if (targetRef.current && !interact.isSet(targetRef.current)) {\n // Do not consume states in these listeners as they will remain their initial values within\n // the scope of the listeners.\n interact(targetRef.current).draggable({\n inertia: true,\n ...options,\n onstart: () => {\n setIsDragging(true)\n onDragStart?.()\n },\n onmove: ({ dx, dy }) => {\n const newValue = transform?.(valueRef.current, dx, dy) ?? [dx, dy] as unknown as T\n\n if (setValueRef(newValue)) {\n // debug('Updating value from dragging...', 'OK', newValue)\n setValue(newValue)\n }\n\n onDragMove?.(dx, dy)\n },\n onend: () => {\n setIsDragging(false)\n onDragEnd?.()\n },\n })\n }\n\n return () => {\n // debug(`Removing drag effect for element ${targetRef.current}...`, 'OK', `value=${valueRef.current}`)\n\n if (targetRef.current && interact.isSet(targetRef.current)) {\n interact(targetRef.current).unset()\n }\n }\n }, [...deps ? deps : []])\n\n useEffect(() => {\n if (setValueRef(value)) {\n // debug('Updating value from externally...', 'OK', value)\n }\n }, [value])\n\n return {\n isDragging: [isDragging, setIsDragging],\n value: [value, setValue],\n }\n}\n"]}
@@ -33,8 +33,8 @@ var resize_observer_polyfill_1 = __importDefault(require("resize-observer-polyfi
33
33
  var spase_1 = require("spase");
34
34
  function useResizeEffect(targetRef, _a, deps) {
35
35
  var _b = _a === void 0 ? {} : _a, onResize = _b.onResize;
36
- var _c = __read((0, react_1.useState)(new spase_1.Size()), 2), size = _c[0], setSize = _c[1];
37
36
  var observerRef = (0, react_1.useRef)(undefined);
37
+ var _c = __read((0, react_1.useState)(new spase_1.Size()), 2), size = _c[0], setSize = _c[1];
38
38
  (0, react_1.useEffect)(function () {
39
39
  // debug(`Using resize effect for element ${targetRef.current}...`, 'OK')
40
40
  observerRef.current = new resize_observer_polyfill_1.default(function () {
@@ -1 +1 @@
1
- {"version":3,"file":"useResizeEffect.js","sourceRoot":"/","sources":["hooks/useResizeEffect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAwG;AACxG,sFAAqD;AACrD,+BAAkC;AAQlC,SAAwB,eAAe,CAAC,SAA6B,EAAE,EAA0B,EAAE,IAAqB;QAAjD,qBAAwB,EAAE,KAAA,EAAxB,QAAQ,cAAA;IACzE,IAAA,KAAA,OAAkB,IAAA,gBAAQ,EAAO,IAAI,YAAI,EAAE,CAAC,IAAA,EAA3C,IAAI,QAAA,EAAE,OAAO,QAA8B,CAAA;IAClD,IAAM,WAAW,GAAG,IAAA,cAAM,EAA6B,SAAS,CAAC,CAAA;IAEjE,IAAA,iBAAS,EAAC;QACR,yEAAyE;QAEzE,WAAW,CAAC,OAAO,GAAG,IAAI,kCAAc,CAAC;YACvC,IAAM,IAAI,GAAG,YAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAEzC,IAAI,CAAC,IAAI;gBAAE,OAAM;YAEjB,IAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;YAEtB,iFAAiF;YAEjF,OAAO,CAAC,IAAI,CAAC,CAAA;YACb,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,IAAI,CAAC,CAAA;QAClB,CAAC,CAAC,CAAA;QAEF,IAAI,WAAW,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE;YAC5C,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;SAC/C;QAED,OAAO;YACL,4EAA4E;YAE5E,IAAI,WAAW,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE;gBAC5C,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;aACjD;QACH,CAAC,CAAA;IACH,CAAC,iBAAG,SAAS,UAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAE,CAAA;IAEpC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AACxB,CAAC;AAlCD,kCAkCC","sourcesContent":["import { DependencyList, Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react'\nimport ResizeObserver from 'resize-observer-polyfill'\nimport { Rect, Size } from 'spase'\n\n// const debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : () => {}\n\ntype Options = {\n onResize?: (size: Size) => void\n}\n\nexport default function useResizeEffect(targetRef: RefObject<Element>, { onResize }: Options = {}, deps?: DependencyList): [Size, Dispatch<SetStateAction<Size>>] {\n const [size, setSize] = useState<Size>(new Size())\n const observerRef = useRef<ResizeObserver | undefined>(undefined)\n\n useEffect(() => {\n // debug(`Using resize effect for element ${targetRef.current}...`, 'OK')\n\n observerRef.current = new ResizeObserver(() => {\n const rect = Rect.from(targetRef.current)\n\n if (!rect) return\n\n const size = rect.size\n\n // debug(`Observing size change for element ${targetRef.current}...`, 'OK', size)\n\n setSize(size)\n onResize?.(size)\n })\n\n if (observerRef.current && targetRef.current) {\n observerRef.current.observe(targetRef.current)\n }\n\n return () => {\n // debug(`Removing resize effect for element ${targetRef.current}...`, 'OK')\n\n if (observerRef.current && targetRef.current) {\n observerRef.current.unobserve(targetRef.current)\n }\n }\n }, [targetRef, ...deps ? deps : []])\n\n return [size, setSize]\n}\n"]}
1
+ {"version":3,"file":"useResizeEffect.js","sourceRoot":"/","sources":["hooks/useResizeEffect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAwG;AACxG,sFAAqD;AACrD,+BAAkC;AAQlC,SAAwB,eAAe,CAAC,SAA6B,EAAE,EAA0B,EAAE,IAAqB;QAAjD,qBAAwB,EAAE,KAAA,EAAxB,QAAQ,cAAA;IAC/E,IAAM,WAAW,GAAG,IAAA,cAAM,EAA6B,SAAS,CAAC,CAAA;IAC3D,IAAA,KAAA,OAAkB,IAAA,gBAAQ,EAAO,IAAI,YAAI,EAAE,CAAC,IAAA,EAA3C,IAAI,QAAA,EAAE,OAAO,QAA8B,CAAA;IAElD,IAAA,iBAAS,EAAC;QACR,yEAAyE;QAEzE,WAAW,CAAC,OAAO,GAAG,IAAI,kCAAc,CAAC;YACvC,IAAM,IAAI,GAAG,YAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAEzC,IAAI,CAAC,IAAI;gBAAE,OAAM;YAEjB,IAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;YAEtB,iFAAiF;YAEjF,OAAO,CAAC,IAAI,CAAC,CAAA;YACb,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,IAAI,CAAC,CAAA;QAClB,CAAC,CAAC,CAAA;QAEF,IAAI,WAAW,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE;YAC5C,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;SAC/C;QAED,OAAO;YACL,4EAA4E;YAE5E,IAAI,WAAW,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE;gBAC5C,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;aACjD;QACH,CAAC,CAAA;IACH,CAAC,iBAAG,SAAS,UAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAE,CAAA;IAEpC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AACxB,CAAC;AAlCD,kCAkCC","sourcesContent":["import { DependencyList, Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react'\nimport ResizeObserver from 'resize-observer-polyfill'\nimport { Rect, Size } from 'spase'\n\n// const debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : () => {}\n\ntype Options = {\n onResize?: (size: Size) => void\n}\n\nexport default function useResizeEffect(targetRef: RefObject<Element>, { onResize }: Options = {}, deps?: DependencyList): [Size, Dispatch<SetStateAction<Size>>] {\n const observerRef = useRef<ResizeObserver | undefined>(undefined)\n const [size, setSize] = useState<Size>(new Size())\n\n useEffect(() => {\n // debug(`Using resize effect for element ${targetRef.current}...`, 'OK')\n\n observerRef.current = new ResizeObserver(() => {\n const rect = Rect.from(targetRef.current)\n\n if (!rect) return\n\n const size = rect.size\n\n // debug(`Observing size change for element ${targetRef.current}...`, 'OK', size)\n\n setSize(size)\n onResize?.(size)\n })\n\n if (observerRef.current && targetRef.current) {\n observerRef.current.observe(targetRef.current)\n }\n\n return () => {\n // debug(`Removing resize effect for element ${targetRef.current}...`, 'OK')\n\n if (observerRef.current && targetRef.current) {\n observerRef.current.unobserve(targetRef.current)\n }\n }\n }, [targetRef, ...deps ? deps : []])\n\n return [size, setSize]\n}\n"]}
@@ -21,7 +21,7 @@ var react_router_dom_1 = require("react-router-dom");
21
21
  var debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : function () { };
22
22
  function useSearchParamState(param, initialState, _a) {
23
23
  var _b = _a === void 0 ? {} : _a, mapSearchParamToState = _b.mapSearchParamToState, mapStateToSearchParam = _b.mapStateToSearchParam;
24
- function _mapSearchParamToState(value, initialState) {
24
+ var _mapSearchParamToState = function (value, initialState) {
25
25
  if (mapSearchParamToState) {
26
26
  return mapSearchParamToState(value);
27
27
  }
@@ -31,8 +31,8 @@ function useSearchParamState(param, initialState, _a) {
31
31
  else {
32
32
  return value;
33
33
  }
34
- }
35
- function _mapStateToSearchParam(state) {
34
+ };
35
+ var _mapStateToSearchParam = function (state) {
36
36
  if (mapStateToSearchParam) {
37
37
  return mapStateToSearchParam(state);
38
38
  }
@@ -42,7 +42,7 @@ function useSearchParamState(param, initialState, _a) {
42
42
  else {
43
43
  return "".concat(state);
44
44
  }
45
- }
45
+ };
46
46
  var _c = __read((0, react_router_dom_1.useSearchParams)(), 2), searchParams = _c[0], setSearchParams = _c[1];
47
47
  var currentState = _mapSearchParamToState(searchParams.get(param), initialState);
48
48
  var _d = __read((0, react_1.useState)(currentState), 2), state = _d[0], setState = _d[1];
@@ -1 +1 @@
1
- {"version":3,"file":"useSearchParamState.js","sourceRoot":"/","sources":["hooks/useSearchParamState.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,+BAAqE;AACrE,qDAAkD;AAElD,IAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAO,CAAC,CAAA;AAOlG,SAAwB,mBAAmB,CAAI,KAAa,EAAE,YAAuB,EAAE,EAAiE;QAAjE,qBAA+D,EAAE,KAAA,EAA/D,qBAAqB,2BAAA,EAAE,qBAAqB,2BAAA;IACnI,SAAS,sBAAsB,CAAC,KAAoB,EAAE,YAAuB;QAC3E,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,KAAK,KAAK,IAAI,EAAE;YACvB,OAAO,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,IAAI,CAAA;SAC5B;aACI;YACH,OAAO,KAAkC,CAAA;SAC1C;IACH,CAAC;IAED,SAAS,sBAAsB,CAAC,KAAe;QAC7C,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,KAAK,KAAK,IAAI,EAAE;YACvB,OAAO,IAAI,CAAA;SACZ;aACI;YACH,OAAO,UAAG,KAAK,CAAE,CAAA;SAClB;IACH,CAAC;IAEK,IAAA,KAAA,OAAkC,IAAA,kCAAe,GAAE,IAAA,EAAlD,YAAY,QAAA,EAAE,eAAe,QAAqB,CAAA;IACzD,IAAM,YAAY,GAAG,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAA;IAC5E,IAAA,KAAA,OAAoB,IAAA,gBAAQ,EAAC,YAAY,CAAC,IAAA,EAAzC,KAAK,QAAA,EAAE,QAAQ,QAA0B,CAAA;IAEhD,KAAK,CAAC,6BAA6B,EAAE,IAAI,EAAE,gBAAS,KAAK,4BAAkB,YAAY,CAAE,CAAC,CAAA;IAE1F,IAAA,iBAAS,EAAC;QACR,IAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrC,IAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAE9C,IAAI,QAAQ,KAAK,KAAK;YAAE,OAAM;QAE9B,IAAI,QAAQ,KAAK,IAAI,EAAE;YACrB,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;SAC3B;aACI;YACH,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;SAClC;QAED,KAAK,CAAC,0BAA0B,EAAE,IAAI,EAAE,gBAAS,KAAK,wBAAc,KAAK,wBAAc,QAAQ,CAAE,CAAC,CAAA;QAElG,eAAe,CAAC,YAAY,CAAC,CAAA;IAC/B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AAC1B,CAAC;AAlDD,sCAkDC","sourcesContent":["import { Dispatch, SetStateAction, useEffect, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : () => {}\n\nexport type Options<T> = {\n mapSearchParamToState?: (value: string | null) => NonNullable<T> | null\n mapStateToSearchParam?: (state: T | null) => string | null\n}\n\nexport default function useSearchParamState<T>(param: string, initialState?: T | null, { mapSearchParamToState, mapStateToSearchParam }: Options<T> = {}): [NonNullable<T> | null, Dispatch<SetStateAction<NonNullable<T> | null>>] {\n function _mapSearchParamToState(value: string | null, initialState?: T | null): NonNullable<T> | null {\n if (mapSearchParamToState) {\n return mapSearchParamToState(value)\n }\n else if (value === null) {\n return initialState ?? null\n }\n else {\n return value as unknown as NonNullable<T>\n }\n }\n\n function _mapStateToSearchParam(state: T | null): string | null {\n if (mapStateToSearchParam) {\n return mapStateToSearchParam(state)\n }\n else if (state === null) {\n return null\n }\n else {\n return `${state}`\n }\n }\n\n const [searchParams, setSearchParams] = useSearchParams()\n const currentState = _mapSearchParamToState(searchParams.get(param), initialState)\n const [state, setState] = useState(currentState)\n\n debug('Using search param state...', 'OK', `param=${param}, initialState=${currentState}`)\n\n useEffect(() => {\n const value = searchParams.get(param)\n const newValue = _mapStateToSearchParam(state)\n\n if (newValue === value) return\n\n if (newValue === null) {\n searchParams.delete(param)\n }\n else {\n searchParams.set(param, newValue)\n }\n\n debug('Handling state change...', 'OK', `state=${state}, oldValue=${value}, newValue=${newValue}`)\n\n setSearchParams(searchParams)\n }, [state])\n\n return [state, setState]\n}\n"]}
1
+ {"version":3,"file":"useSearchParamState.js","sourceRoot":"/","sources":["hooks/useSearchParamState.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,+BAAqE;AACrE,qDAAkD;AAElD,IAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAO,CAAC,CAAA;AAOlG,SAAwB,mBAAmB,CAAI,KAAa,EAAE,YAAuB,EAAE,EAAiE;QAAjE,qBAA+D,EAAE,KAAA,EAA/D,qBAAqB,2BAAA,EAAE,qBAAqB,2BAAA;IACnI,IAAM,sBAAsB,GAAG,UAAC,KAAoB,EAAE,YAAuB;QAC3E,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,KAAK,KAAK,IAAI,EAAE;YACvB,OAAO,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,IAAI,CAAA;SAC5B;aACI;YACH,OAAO,KAAkC,CAAA;SAC1C;IACH,CAAC,CAAA;IAED,IAAM,sBAAsB,GAAG,UAAC,KAAe;QAC7C,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,KAAK,KAAK,IAAI,EAAE;YACvB,OAAO,IAAI,CAAA;SACZ;aACI;YACH,OAAO,UAAG,KAAK,CAAE,CAAA;SAClB;IACH,CAAC,CAAA;IAEK,IAAA,KAAA,OAAkC,IAAA,kCAAe,GAAE,IAAA,EAAlD,YAAY,QAAA,EAAE,eAAe,QAAqB,CAAA;IACzD,IAAM,YAAY,GAAG,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAA;IAC5E,IAAA,KAAA,OAAoB,IAAA,gBAAQ,EAAC,YAAY,CAAC,IAAA,EAAzC,KAAK,QAAA,EAAE,QAAQ,QAA0B,CAAA;IAEhD,KAAK,CAAC,6BAA6B,EAAE,IAAI,EAAE,gBAAS,KAAK,4BAAkB,YAAY,CAAE,CAAC,CAAA;IAE1F,IAAA,iBAAS,EAAC;QACR,IAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrC,IAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAE9C,IAAI,QAAQ,KAAK,KAAK;YAAE,OAAM;QAE9B,IAAI,QAAQ,KAAK,IAAI,EAAE;YACrB,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;SAC3B;aACI;YACH,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;SAClC;QAED,KAAK,CAAC,0BAA0B,EAAE,IAAI,EAAE,gBAAS,KAAK,wBAAc,KAAK,wBAAc,QAAQ,CAAE,CAAC,CAAA;QAElG,eAAe,CAAC,YAAY,CAAC,CAAA;IAC/B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AAC1B,CAAC;AAlDD,sCAkDC","sourcesContent":["import { Dispatch, SetStateAction, useEffect, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:hooks') : () => {}\n\nexport type Options<T> = {\n mapSearchParamToState?: (value: string | null) => NonNullable<T> | null\n mapStateToSearchParam?: (state: T | null) => string | null\n}\n\nexport default function useSearchParamState<T>(param: string, initialState?: T | null, { mapSearchParamToState, mapStateToSearchParam }: Options<T> = {}): [NonNullable<T> | null, Dispatch<SetStateAction<NonNullable<T> | null>>] {\n const _mapSearchParamToState = (value: string | null, initialState?: T | null): NonNullable<T> | null => {\n if (mapSearchParamToState) {\n return mapSearchParamToState(value)\n }\n else if (value === null) {\n return initialState ?? null\n }\n else {\n return value as unknown as NonNullable<T>\n }\n }\n\n const _mapStateToSearchParam = (state: T | null): string | null => {\n if (mapStateToSearchParam) {\n return mapStateToSearchParam(state)\n }\n else if (state === null) {\n return null\n }\n else {\n return `${state}`\n }\n }\n\n const [searchParams, setSearchParams] = useSearchParams()\n const currentState = _mapSearchParamToState(searchParams.get(param), initialState)\n const [state, setState] = useState(currentState)\n\n debug('Using search param state...', 'OK', `param=${param}, initialState=${currentState}`)\n\n useEffect(() => {\n const value = searchParams.get(param)\n const newValue = _mapStateToSearchParam(state)\n\n if (newValue === value) return\n\n if (newValue === null) {\n searchParams.delete(param)\n }\n else {\n searchParams.set(param, newValue)\n }\n\n debug('Handling state change...', 'OK', `state=${state}, oldValue=${value}, newValue=${newValue}`)\n\n setSearchParams(searchParams)\n }, [state])\n\n return [state, setState]\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "etudes",
3
- "version": "0.46.0",
3
+ "version": "0.50.0",
4
4
  "description": "A study of styled React components",
5
5
  "main": "lib",
6
6
  "scripts": {