etudes 2.4.0 → 2.6.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.
Files changed (89) hide show
  1. package/lib/Accordion.d.ts +2 -2
  2. package/lib/Accordion.js.map +1 -1
  3. package/lib/BurgerButton.d.ts +2 -2
  4. package/lib/BurgerButton.js +1 -1
  5. package/lib/BurgerButton.js.map +1 -1
  6. package/lib/Conditional.d.ts +1 -1
  7. package/lib/Conditional.js.map +1 -1
  8. package/lib/DebugConsole.d.ts +1 -1
  9. package/lib/DebugConsole.js.map +1 -1
  10. package/lib/Dial.d.ts +1 -1
  11. package/lib/Dial.js.map +1 -1
  12. package/lib/Dropdown.d.ts +2 -2
  13. package/lib/Dropdown.js +1 -1
  14. package/lib/Dropdown.js.map +1 -1
  15. package/lib/Each.d.ts +1 -1
  16. package/lib/Each.js.map +1 -1
  17. package/lib/ExtractChild.d.ts +1 -1
  18. package/lib/ExtractChild.js.map +1 -1
  19. package/lib/ExtractChildren.d.ts +1 -1
  20. package/lib/ExtractChildren.js.map +1 -1
  21. package/lib/FlatSVG.d.ts +1 -1
  22. package/lib/FlatSVG.js +51 -72
  23. package/lib/FlatSVG.js.map +1 -1
  24. package/lib/List.d.ts +1 -1
  25. package/lib/List.js.map +1 -1
  26. package/lib/MasonryGrid.d.ts +1 -1
  27. package/lib/MasonryGrid.js +10 -10
  28. package/lib/MasonryGrid.js.map +1 -1
  29. package/lib/Panorama.d.ts +15 -15
  30. package/lib/Panorama.js.map +1 -1
  31. package/lib/PanoramaSlider.d.ts +8 -8
  32. package/lib/PanoramaSlider.js +6 -6
  33. package/lib/PanoramaSlider.js.map +1 -1
  34. package/lib/RangeSlider.d.ts +1 -1
  35. package/lib/RangeSlider.js.map +1 -1
  36. package/lib/Repeat.d.ts +1 -1
  37. package/lib/Repeat.js.map +1 -1
  38. package/lib/RotatingGallery.d.ts +5 -5
  39. package/lib/RotatingGallery.js +2 -2
  40. package/lib/RotatingGallery.js.map +1 -1
  41. package/lib/SelectableButton.d.ts +1 -1
  42. package/lib/SelectableButton.js.map +1 -1
  43. package/lib/Slider.d.ts +11 -11
  44. package/lib/Slider.js +4 -4
  45. package/lib/Slider.js.map +1 -1
  46. package/lib/StepwiseSlider.d.ts +18 -18
  47. package/lib/StepwiseSlider.js +9 -9
  48. package/lib/StepwiseSlider.js.map +1 -1
  49. package/lib/SwipeContainer.d.ts +1 -1
  50. package/lib/SwipeContainer.js.map +1 -1
  51. package/lib/TextField.d.ts +1 -1
  52. package/lib/TextField.js.map +1 -1
  53. package/lib/Video.d.ts +1 -1
  54. package/lib/Video.js.map +1 -1
  55. package/lib/WithTooltip.d.ts +1 -1
  56. package/lib/WithTooltip.js +2 -1
  57. package/lib/WithTooltip.js.map +1 -1
  58. package/lib/hooks/useDragEffect.d.ts +15 -15
  59. package/lib/hooks/useDragEffect.js +6 -6
  60. package/lib/hooks/useDragEffect.js.map +1 -1
  61. package/lib/hooks/useElementRect.d.ts +2 -2
  62. package/lib/hooks/useElementRect.js +1 -1
  63. package/lib/hooks/useElementRect.js.map +1 -1
  64. package/lib/hooks/useInterval.d.ts +5 -5
  65. package/lib/hooks/useInterval.js +4 -4
  66. package/lib/hooks/useInterval.js.map +1 -1
  67. package/lib/hooks/useLoadImageEffect.d.ts +6 -6
  68. package/lib/hooks/useLoadImageEffect.js +3 -3
  69. package/lib/hooks/useLoadImageEffect.js.map +1 -1
  70. package/lib/hooks/usePrevious.d.ts +1 -1
  71. package/lib/hooks/usePrevious.js +1 -1
  72. package/lib/hooks/usePrevious.js.map +1 -1
  73. package/lib/hooks/useResizeEffect.d.ts +5 -5
  74. package/lib/hooks/useResizeEffect.js +3 -3
  75. package/lib/hooks/useResizeEffect.js.map +1 -1
  76. package/lib/hooks/useSearchParamState.d.ts +7 -7
  77. package/lib/hooks/useSearchParamState.js +3 -3
  78. package/lib/hooks/useSearchParamState.js.map +1 -1
  79. package/lib/providers/ScrollPositionProvider.d.ts +1 -1
  80. package/lib/providers/ScrollPositionProvider.js.map +1 -1
  81. package/lib/utils/asComponentDict.d.ts +1 -1
  82. package/lib/utils/asComponentDict.js.map +1 -1
  83. package/lib/utils/asStyleDict.d.ts +1 -1
  84. package/lib/utils/asStyleDict.js.map +1 -1
  85. package/lib/utils/cloneStyledElement.d.ts +6 -6
  86. package/lib/utils/cloneStyledElement.js.map +1 -1
  87. package/lib/utils/styles.d.ts +1 -1
  88. package/lib/utils/styles.js.map +1 -1
  89. package/package.json +12 -10
@@ -1,4 +1,4 @@
1
- import { DependencyList, Dispatch, SetStateAction } from 'react';
1
+ import { type DependencyList, type Dispatch, type SetStateAction } from 'react';
2
2
  import { Size } from 'spase';
3
3
  type ReturnedStates = {
4
4
  /**
@@ -16,7 +16,7 @@ type Options = {
16
16
  /**
17
17
  * Handler invoked when the image is done loading.
18
18
  *
19
- * @param imageElement - The loaded image element.
19
+ * @param imageElement The loaded image element.
20
20
  */
21
21
  onImageLoadComplete?: (imageElement: HTMLImageElement) => void;
22
22
  /**
@@ -27,16 +27,16 @@ type Options = {
27
27
  * Handler invoked when the image size changes. If there is no loaded image,
28
28
  * the size is `undefined`.
29
29
  *
30
- * @param size - The original image size.
30
+ * @param size The original image size.
31
31
  */
32
32
  onImageSizeChange?: (size?: Size) => void;
33
33
  };
34
34
  /**
35
35
  * Hook for preloading an image.
36
36
  *
37
- * @param src - The image source.
38
- * @param options - See {@link Options}.
39
- * @param deps - Additional dependencies.
37
+ * @param src The image source.
38
+ * @param options See {@link Options}.
39
+ * @param deps Additional dependencies.
40
40
  *
41
41
  * @returns See {@link ReturnedStates}.
42
42
  */
@@ -33,9 +33,9 @@ function getImageSize(imageElement) {
33
33
  /**
34
34
  * Hook for preloading an image.
35
35
  *
36
- * @param src - The image source.
37
- * @param options - See {@link Options}.
38
- * @param deps - Additional dependencies.
36
+ * @param src The image source.
37
+ * @param options See {@link Options}.
38
+ * @param deps Additional dependencies.
39
39
  *
40
40
  * @returns See {@link ReturnedStates}.
41
41
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useLoadImageEffect.js","sourceRoot":"/","sources":["hooks/useLoadImageEffect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA6F;AAC7F,+BAA4B;AAsC5B,SAAS,YAAY,CAAC,YAA8B;IAClD,OAAO,IAAI,YAAI,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;;;;GAQG;AACH,SAAwB,kBAAkB,CAAC,GAAY,EAAE,EAA0E,EAAE,IAAqB;QAAjG,qBAAwE,EAAE,KAAA,EAAxE,mBAAmB,yBAAA,EAAE,gBAAgB,sBAAA,EAAE,iBAAiB,uBAAA;IACjH,IAAM,wBAAwB,GAAG,UAAC,KAAY;QAC5C,IAAM,YAAY,GAAG,KAAK,CAAC,aAAiC,CAAA;QAC5D,IAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;QAE5C,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,YAAY,CAAC,SAAS,CAAC,CAAA;QAEvB,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAG,YAAY,CAAC,CAAA;IACrC,CAAC,CAAA;IAED,IAAM,qBAAqB,GAAG,UAAC,KAAY;QACzC,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,YAAY,CAAC,SAAS,CAAC,CAAA;QAEvB,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,EAAI,CAAA;IACtB,CAAC,CAAA;IAED,IAAM,QAAQ,GAAG,IAAA,cAAM,EAA+B,SAAS,CAAC,CAAA;IAC1D,IAAA,KAAA,OAA4B,IAAA,gBAAQ,EAAC,IAAI,CAAC,IAAA,EAAzC,SAAS,QAAA,EAAE,YAAY,QAAkB,CAAA;IAC1C,IAAA,KAAA,OAA4B,IAAA,gBAAQ,EAAmB,SAAS,CAAC,IAAA,EAAhE,SAAS,QAAA,EAAE,YAAY,QAAyC,CAAA;IAEvE,IAAA,iBAAS,EAAC;QACR,IAAI,CAAC,GAAG;YAAE,OAAM;QAEhB,YAAY,CAAC,IAAI,CAAC,CAAA;QAElB,QAAQ,CAAC,OAAO,GAAG,IAAI,KAAK,EAAE,CAAA;QAC9B,QAAQ,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAA;QAC1B,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;QACnE,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAA;QAEjE,OAAO;;YACL,MAAA,QAAQ,CAAC,OAAO,0CAAE,mBAAmB,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;YACvE,MAAA,QAAQ,CAAC,OAAO,0CAAE,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAA;YACrE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAA;QAC9B,CAAC,CAAA;IACH,CAAC,iBAAG,GAAG,UAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAE,CAAA;IAE9B,IAAA,iBAAS,EAAC;QACR,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAG,SAAS,CAAC,CAAA;IAChC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAEf,OAAO;QACL,SAAS,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;QACpC,SAAS,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;KACrC,CAAA;AACH,CAAC;AA/CD,qCA+CC","sourcesContent":["import { DependencyList, Dispatch, SetStateAction, useEffect, useRef, useState } from 'react'\nimport { Size } from 'spase'\n\ntype ReturnedStates = {\n /**\n * A tuple consisting of a stateful value indicating if the image is loading,\n * and a function that updates the loading state.\n */\n isLoading: [boolean, Dispatch<SetStateAction<boolean>>]\n\n /**\n * A tuple consisting of a stateful value representing the size of the image,\n * and a function that updates the size.\n */\n imageSize: [Size | undefined, Dispatch<SetStateAction<Size | undefined>>]\n}\n\ntype Options = {\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. If there is no loaded image,\n * the size is `undefined`.\n *\n * @param size - The original image size.\n */\n onImageSizeChange?: (size?: Size) => void\n}\n\nfunction getImageSize(imageElement: HTMLImageElement): Size {\n return new Size([imageElement.width, imageElement.height])\n}\n\n/**\n * Hook for preloading an image.\n *\n * @param src - The image source.\n * @param options - See {@link Options}.\n * @param deps - Additional dependencies.\n *\n * @returns See {@link ReturnedStates}.\n */\nexport default function useLoadImageEffect(src?: string, { onImageLoadComplete, onImageLoadError, onImageSizeChange }: Options = {}, deps?: DependencyList): ReturnedStates {\n const imageLoadCompleteHandler = (event: Event) => {\n const imageElement = event.currentTarget as HTMLImageElement\n const imageSize = getImageSize(imageElement)\n\n setIsLoading(false)\n setImageSize(imageSize)\n\n onImageLoadComplete?.(imageElement)\n }\n\n const imageLoadErrorHandler = (event: Event) => {\n setIsLoading(false)\n setImageSize(undefined)\n\n onImageLoadError?.()\n }\n\n const imageRef = useRef<HTMLImageElement | undefined>(undefined)\n const [isLoading, setIsLoading] = useState(true)\n const [imageSize, setImageSize] = useState<Size | undefined>(undefined)\n\n useEffect(() => {\n if (!src) return\n\n setIsLoading(true)\n\n imageRef.current = new Image()\n imageRef.current.src = src\n imageRef.current.addEventListener('load', imageLoadCompleteHandler)\n imageRef.current.addEventListener('error', imageLoadErrorHandler)\n\n return () => {\n imageRef.current?.removeEventListener('load', imageLoadCompleteHandler)\n imageRef.current?.removeEventListener('error', imageLoadErrorHandler)\n imageRef.current = undefined\n }\n }, [src, ...deps ? deps : []])\n\n useEffect(() => {\n onImageSizeChange?.(imageSize)\n }, [imageSize])\n\n return {\n isLoading: [isLoading, setIsLoading],\n imageSize: [imageSize, setImageSize],\n }\n}\n"]}
1
+ {"version":3,"file":"useLoadImageEffect.js","sourceRoot":"/","sources":["hooks/useLoadImageEffect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA4G;AAC5G,+BAA4B;AAsC5B,SAAS,YAAY,CAAC,YAA8B;IAClD,OAAO,IAAI,YAAI,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;;;;GAQG;AACH,SAAwB,kBAAkB,CAAC,GAAY,EAAE,EAA0E,EAAE,IAAqB;QAAjG,qBAAwE,EAAE,KAAA,EAAxE,mBAAmB,yBAAA,EAAE,gBAAgB,sBAAA,EAAE,iBAAiB,uBAAA;IACjH,IAAM,wBAAwB,GAAG,UAAC,KAAY;QAC5C,IAAM,YAAY,GAAG,KAAK,CAAC,aAAiC,CAAA;QAC5D,IAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;QAE5C,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,YAAY,CAAC,SAAS,CAAC,CAAA;QAEvB,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAG,YAAY,CAAC,CAAA;IACrC,CAAC,CAAA;IAED,IAAM,qBAAqB,GAAG,UAAC,KAAY;QACzC,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,YAAY,CAAC,SAAS,CAAC,CAAA;QAEvB,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,EAAI,CAAA;IACtB,CAAC,CAAA;IAED,IAAM,QAAQ,GAAG,IAAA,cAAM,EAA+B,SAAS,CAAC,CAAA;IAC1D,IAAA,KAAA,OAA4B,IAAA,gBAAQ,EAAC,IAAI,CAAC,IAAA,EAAzC,SAAS,QAAA,EAAE,YAAY,QAAkB,CAAA;IAC1C,IAAA,KAAA,OAA4B,IAAA,gBAAQ,EAAmB,SAAS,CAAC,IAAA,EAAhE,SAAS,QAAA,EAAE,YAAY,QAAyC,CAAA;IAEvE,IAAA,iBAAS,EAAC;QACR,IAAI,CAAC,GAAG;YAAE,OAAM;QAEhB,YAAY,CAAC,IAAI,CAAC,CAAA;QAElB,QAAQ,CAAC,OAAO,GAAG,IAAI,KAAK,EAAE,CAAA;QAC9B,QAAQ,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAA;QAC1B,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;QACnE,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAA;QAEjE,OAAO;;YACL,MAAA,QAAQ,CAAC,OAAO,0CAAE,mBAAmB,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;YACvE,MAAA,QAAQ,CAAC,OAAO,0CAAE,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAA;YACrE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAA;QAC9B,CAAC,CAAA;IACH,CAAC,iBAAG,GAAG,UAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAE,CAAA;IAE9B,IAAA,iBAAS,EAAC;QACR,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAG,SAAS,CAAC,CAAA;IAChC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAEf,OAAO;QACL,SAAS,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;QACpC,SAAS,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;KACrC,CAAA;AACH,CAAC;AA/CD,qCA+CC","sourcesContent":["import { useEffect, useRef, useState, type DependencyList, type Dispatch, type SetStateAction } from 'react'\nimport { Size } from 'spase'\n\ntype ReturnedStates = {\n /**\n * A tuple consisting of a stateful value indicating if the image is loading,\n * and a function that updates the loading state.\n */\n isLoading: [boolean, Dispatch<SetStateAction<boolean>>]\n\n /**\n * A tuple consisting of a stateful value representing the size of the image,\n * and a function that updates the size.\n */\n imageSize: [Size | undefined, Dispatch<SetStateAction<Size | undefined>>]\n}\n\ntype Options = {\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. If there is no loaded image,\n * the size is `undefined`.\n *\n * @param size The original image size.\n */\n onImageSizeChange?: (size?: Size) => void\n}\n\nfunction getImageSize(imageElement: HTMLImageElement): Size {\n return new Size([imageElement.width, imageElement.height])\n}\n\n/**\n * Hook for preloading an image.\n *\n * @param src The image source.\n * @param options See {@link Options}.\n * @param deps Additional dependencies.\n *\n * @returns See {@link ReturnedStates}.\n */\nexport default function useLoadImageEffect(src?: string, { onImageLoadComplete, onImageLoadError, onImageSizeChange }: Options = {}, deps?: DependencyList): ReturnedStates {\n const imageLoadCompleteHandler = (event: Event) => {\n const imageElement = event.currentTarget as HTMLImageElement\n const imageSize = getImageSize(imageElement)\n\n setIsLoading(false)\n setImageSize(imageSize)\n\n onImageLoadComplete?.(imageElement)\n }\n\n const imageLoadErrorHandler = (event: Event) => {\n setIsLoading(false)\n setImageSize(undefined)\n\n onImageLoadError?.()\n }\n\n const imageRef = useRef<HTMLImageElement | undefined>(undefined)\n const [isLoading, setIsLoading] = useState(true)\n const [imageSize, setImageSize] = useState<Size | undefined>(undefined)\n\n useEffect(() => {\n if (!src) return\n\n setIsLoading(true)\n\n imageRef.current = new Image()\n imageRef.current.src = src\n imageRef.current.addEventListener('load', imageLoadCompleteHandler)\n imageRef.current.addEventListener('error', imageLoadErrorHandler)\n\n return () => {\n imageRef.current?.removeEventListener('load', imageLoadCompleteHandler)\n imageRef.current?.removeEventListener('error', imageLoadErrorHandler)\n imageRef.current = undefined\n }\n }, [src, ...deps ? deps : []])\n\n useEffect(() => {\n onImageSizeChange?.(imageSize)\n }, [imageSize])\n\n return {\n isLoading: [isLoading, setIsLoading],\n imageSize: [imageSize, setImageSize],\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns the previous value of a state or prop.
3
3
  *
4
- * @param stateOrProp - The state or prop.
4
+ * @param stateOrProp The state or prop.
5
5
  */
6
6
  export default function usePrevious<T>(stateOrProp: T): T | undefined;
@@ -4,7 +4,7 @@ var react_1 = require("react");
4
4
  /**
5
5
  * Returns the previous value of a state or prop.
6
6
  *
7
- * @param stateOrProp - The state or prop.
7
+ * @param stateOrProp The state or prop.
8
8
  */
9
9
  function usePrevious(stateOrProp) {
10
10
  var ref = (0, react_1.useRef)();
@@ -1 +1 @@
1
- {"version":3,"file":"usePrevious.js","sourceRoot":"/","sources":["hooks/usePrevious.ts"],"names":[],"mappings":";;AAAA,+BAAyC;AAEzC;;;;GAIG;AACH,SAAwB,WAAW,CAAI,WAAc;IACnD,IAAM,GAAG,GAAG,IAAA,cAAM,GAAK,CAAA;IAEvB,IAAA,iBAAS,EAAC;QACR,GAAG,CAAC,OAAO,GAAG,WAAW,CAAA;IAC3B,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,OAAO,GAAG,CAAC,OAAO,CAAA;AACpB,CAAC;AARD,8BAQC","sourcesContent":["import { useEffect, useRef } from 'react'\n\n/**\n * Returns the previous value of a state or prop.\n *\n * @param stateOrProp - The state or prop.\n */\nexport default function usePrevious<T>(stateOrProp: T): T | undefined {\n const ref = useRef<T>()\n\n useEffect(() => {\n ref.current = stateOrProp\n }, [stateOrProp])\n\n return ref.current\n}\n"]}
1
+ {"version":3,"file":"usePrevious.js","sourceRoot":"/","sources":["hooks/usePrevious.ts"],"names":[],"mappings":";;AAAA,+BAAyC;AAEzC;;;;GAIG;AACH,SAAwB,WAAW,CAAI,WAAc;IACnD,IAAM,GAAG,GAAG,IAAA,cAAM,GAAK,CAAA;IAEvB,IAAA,iBAAS,EAAC;QACR,GAAG,CAAC,OAAO,GAAG,WAAW,CAAA;IAC3B,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,OAAO,GAAG,CAAC,OAAO,CAAA;AACpB,CAAC;AARD,8BAQC","sourcesContent":["import { useEffect, useRef } from 'react'\n\n/**\n * Returns the previous value of a state or prop.\n *\n * @param stateOrProp The state or prop.\n */\nexport default function usePrevious<T>(stateOrProp: T): T | undefined {\n const ref = useRef<T>()\n\n useEffect(() => {\n ref.current = stateOrProp\n }, [stateOrProp])\n\n return ref.current\n}\n"]}
@@ -1,19 +1,19 @@
1
- import { DependencyList, Dispatch, RefObject, SetStateAction } from 'react';
1
+ import { type DependencyList, type Dispatch, type RefObject, type SetStateAction } from 'react';
2
2
  import { Size } from 'spase';
3
3
  type Options = {
4
4
  /**
5
5
  * Handler invoked when the target element resizes.
6
6
  *
7
- * @param size - The current size of the target element.
7
+ * @param size The current size of the target element.
8
8
  */
9
9
  onResize?: (size: Size) => void;
10
10
  };
11
11
  /**
12
12
  * Hook for monitoring the resizing event of the target element.
13
13
  *
14
- * @param targetRef - Reference to the target element.
15
- * @param options - See {@link Options}.
16
- * @param deps - Additional dependencies.
14
+ * @param targetRef Reference to the target element.
15
+ * @param options See {@link Options}.
16
+ * @param deps Additional dependencies.
17
17
  *
18
18
  * @returns A tuple consisting of a stateful value indicating the size of the
19
19
  * target ref, and a function that sets its size.
@@ -34,9 +34,9 @@ var spase_1 = require("spase");
34
34
  /**
35
35
  * Hook for monitoring the resizing event of the target element.
36
36
  *
37
- * @param targetRef - Reference to the target element.
38
- * @param options - See {@link Options}.
39
- * @param deps - Additional dependencies.
37
+ * @param targetRef Reference to the target element.
38
+ * @param options See {@link Options}.
39
+ * @param deps Additional dependencies.
40
40
  *
41
41
  * @returns A tuple consisting of a stateful value indicating the size of the
42
42
  * target ref, and a function that sets its size.
@@ -1 +1 @@
1
- {"version":3,"file":"useResizeEffect.js","sourceRoot":"/","sources":["hooks/useResizeEffect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAwG;AACxG,sFAAqD;AACrD,+BAAkC;AAWlC;;;;;;;;;GASG;AACH,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,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,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;YAEzB,OAAO,CAAC,OAAO,CAAC,CAAA;YAChB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,OAAO,CAAC,CAAA;QACrB,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,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;AA5BD,kCA4BC","sourcesContent":["import { DependencyList, Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react'\nimport ResizeObserver from 'resize-observer-polyfill'\nimport { Rect, Size } from 'spase'\n\ntype Options = {\n /**\n * Handler invoked when the target element resizes.\n *\n * @param size - The current size of the target element.\n */\n onResize?: (size: Size) => void\n}\n\n/**\n * Hook for monitoring the resizing event of the target element.\n *\n * @param targetRef - Reference to the target element.\n * @param options - See {@link Options}.\n * @param deps - Additional dependencies.\n *\n * @returns A tuple consisting of a stateful value indicating the size of the\n * target ref, and a function that sets its size.\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 observerRef.current = new ResizeObserver(() => {\n const rect = Rect.from(targetRef.current)\n\n if (!rect) return\n\n const newSize = rect.size\n\n setSize(newSize)\n onResize?.(newSize)\n })\n\n if (observerRef.current && targetRef.current) {\n observerRef.current.observe(targetRef.current)\n }\n\n return () => {\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,+BAA4H;AAC5H,sFAAqD;AACrD,+BAAkC;AAWlC;;;;;;;;;GASG;AACH,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,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,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;YAEzB,OAAO,CAAC,OAAO,CAAC,CAAA;YAChB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,OAAO,CAAC,CAAA;QACrB,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,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;AA5BD,kCA4BC","sourcesContent":["import { useEffect, useRef, useState, type DependencyList, type Dispatch, type RefObject, type SetStateAction } from 'react'\nimport ResizeObserver from 'resize-observer-polyfill'\nimport { Rect, Size } from 'spase'\n\ntype Options = {\n /**\n * Handler invoked when the target element resizes.\n *\n * @param size The current size of the target element.\n */\n onResize?: (size: Size) => void\n}\n\n/**\n * Hook for monitoring the resizing event of the target element.\n *\n * @param targetRef Reference to the target element.\n * @param options See {@link Options}.\n * @param deps Additional dependencies.\n *\n * @returns A tuple consisting of a stateful value indicating the size of the\n * target ref, and a function that sets its size.\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 observerRef.current = new ResizeObserver(() => {\n const rect = Rect.from(targetRef.current)\n\n if (!rect) return\n\n const newSize = rect.size\n\n setSize(newSize)\n onResize?.(newSize)\n })\n\n if (observerRef.current && targetRef.current) {\n observerRef.current.observe(targetRef.current)\n }\n\n return () => {\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,11 +1,11 @@
1
- import { Dispatch, SetStateAction } from 'react';
1
+ import { type Dispatch, type SetStateAction } from 'react';
2
2
  export type Options<T> = {
3
3
  /**
4
4
  * Function for transforming the search param value to the value of the mapped
5
5
  * state.
6
6
  *
7
- * @param value - The search param value. `undefined` means the value is
8
- * unavailable.
7
+ * @param value The search param value. `undefined` means the value is
8
+ * unavailable.
9
9
  *
10
10
  * @returns The equivalent state value.
11
11
  */
@@ -14,7 +14,7 @@ export type Options<T> = {
14
14
  * Function for transforming the value of the mapped state to the search param
15
15
  * value.
16
16
  *
17
- * @param state - The state value.
17
+ * @param state The state value.
18
18
  *
19
19
  * @returns The equivalent search param value.
20
20
  */
@@ -24,9 +24,9 @@ export type Options<T> = {
24
24
  * Hook for mapping a search param to a state. Whenever the value of the target
25
25
  * search param changes, the mapped state will change as well, and vice versa.
26
26
  *
27
- * @param param - The search param key.
28
- * @param defaultValue - The default value of the state.
29
- * @param options - See {@link Options}.
27
+ * @param param The search param key.
28
+ * @param defaultValue The default value of the state.
29
+ * @param options See {@link Options}.
30
30
  *
31
31
  * @returns A tuple consisting of a stateful value representing the current
32
32
  * value of the mapped state and a function that updates it.
@@ -27,9 +27,9 @@ var debug = (0, useDebug_1.default)('hooks');
27
27
  * Hook for mapping a search param to a state. Whenever the value of the target
28
28
  * search param changes, the mapped state will change as well, and vice versa.
29
29
  *
30
- * @param param - The search param key.
31
- * @param defaultValue - The default value of the state.
32
- * @param options - See {@link Options}.
30
+ * @param param The search param key.
31
+ * @param defaultValue The default value of the state.
32
+ * @param options See {@link Options}.
33
33
  *
34
34
  * @returns A tuple consisting of a stateful value representing the current
35
35
  * value of the mapped state and a function that updates it.
@@ -1 +1 @@
1
- {"version":3,"file":"useSearchParamState.js","sourceRoot":"/","sources":["hooks/useSearchParamState.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,+BAAqE;AACrE,qDAAkD;AAClD,+DAAwC;AAExC,IAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,OAAO,CAAC,CAAA;AAyB/B;;;;;;;;;;GAUG;AACH,SAAwB,mBAAmB,CAAI,KAAa,EAAE,YAAe,EAAE,EAAiE;;QAAjE,qBAA+D,EAAE,KAAA,EAA/D,qBAAqB,2BAAA,EAAE,qBAAqB,2BAAA;IAC3H,IAAM,4BAA4B,GAAG,UAAC,KAAyB,EAAE,QAAW;QAC1E,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,CAAC,KAAK,EAAE;YACf,OAAO,QAAQ,CAAA;SAChB;aACI;YACH,OAAO,KAAkC,CAAA;SAC1C;IACH,CAAC,CAAA;IAED,IAAM,4BAA4B,GAAG,UAAC,KAAQ;QAC5C,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,KAAK,KAAK,YAAY,EAAE;YAC/B,OAAO,SAAS,CAAA;SACjB;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,4BAA4B,CAAC,MAAA,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI,SAAS,EAAE,YAAY,CAAC,CAAA;IAC/F,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,4BAA4B,CAAC,KAAK,CAAC,CAAA;QAEpD,IAAI,QAAQ,KAAK,KAAK;YAAE,OAAM;QAE9B,IAAI,CAAC,QAAQ,EAAE;YACb,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'\nimport useDebug from '../utils/useDebug'\n\nconst debug = useDebug('hooks')\n\nexport type Options<T> = {\n /**\n * Function for transforming the search param value to the value of the mapped\n * state.\n *\n * @param value - The search param value. `undefined` means the value is\n * unavailable.\n *\n * @returns The equivalent state value.\n */\n mapSearchParamToState?: (value?: string) => T\n\n /**\n * Function for transforming the value of the mapped state to the search param\n * value.\n *\n * @param state - The state value.\n *\n * @returns The equivalent search param value.\n */\n mapStateToSearchParam?: (state: T) => string | undefined\n}\n\n/**\n * Hook for mapping a search param to a state. Whenever the value of the target\n * search param changes, the mapped state will change as well, and vice versa.\n *\n * @param param - The search param key.\n * @param defaultValue - The default value of the state.\n * @param options - See {@link Options}.\n *\n * @returns A tuple consisting of a stateful value representing the current\n * value of the mapped state and a function that updates it.\n */\nexport default function useSearchParamState<T>(param: string, defaultValue: T, { mapSearchParamToState, mapStateToSearchParam }: Options<T> = {}): [T, Dispatch<SetStateAction<T>>] {\n const defaultMapSearchParamToState = (value: string | undefined, fallback: T): T => {\n if (mapSearchParamToState) {\n return mapSearchParamToState(value)\n }\n else if (!value) {\n return fallback\n }\n else {\n return value as unknown as NonNullable<T>\n }\n }\n\n const defaultMapStateToSearchParam = (state: T): string | undefined => {\n if (mapStateToSearchParam) {\n return mapStateToSearchParam(state)\n }\n else if (state === defaultValue) {\n return undefined\n }\n else {\n return `${state}`\n }\n }\n\n const [searchParams, setSearchParams] = useSearchParams()\n const currentState = defaultMapSearchParamToState(searchParams.get(param) ?? undefined, defaultValue)\n const [state, setState] = useState(currentState)\n\n debug('Using search param state...', 'OK', `param=${param}, defaultValue=${currentState}`)\n\n useEffect(() => {\n const value = searchParams.get(param)\n const newValue = defaultMapStateToSearchParam(state)\n\n if (newValue === value) return\n\n if (!newValue) {\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,+BAA+E;AAC/E,qDAAkD;AAClD,+DAAwC;AAExC,IAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,OAAO,CAAC,CAAA;AAyB/B;;;;;;;;;;GAUG;AACH,SAAwB,mBAAmB,CAAI,KAAa,EAAE,YAAe,EAAE,EAAiE;;QAAjE,qBAA+D,EAAE,KAAA,EAA/D,qBAAqB,2BAAA,EAAE,qBAAqB,2BAAA;IAC3H,IAAM,4BAA4B,GAAG,UAAC,KAAyB,EAAE,QAAW;QAC1E,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,CAAC,KAAK,EAAE;YACf,OAAO,QAAQ,CAAA;SAChB;aACI;YACH,OAAO,KAAkC,CAAA;SAC1C;IACH,CAAC,CAAA;IAED,IAAM,4BAA4B,GAAG,UAAC,KAAQ;QAC5C,IAAI,qBAAqB,EAAE;YACzB,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAA;SACpC;aACI,IAAI,KAAK,KAAK,YAAY,EAAE;YAC/B,OAAO,SAAS,CAAA;SACjB;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,4BAA4B,CAAC,MAAA,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI,SAAS,EAAE,YAAY,CAAC,CAAA;IAC/F,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,4BAA4B,CAAC,KAAK,CAAC,CAAA;QAEpD,IAAI,QAAQ,KAAK,KAAK;YAAE,OAAM;QAE9B,IAAI,CAAC,QAAQ,EAAE;YACb,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 { useEffect, useState, type Dispatch, type SetStateAction } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport useDebug from '../utils/useDebug'\n\nconst debug = useDebug('hooks')\n\nexport type Options<T> = {\n /**\n * Function for transforming the search param value to the value of the mapped\n * state.\n *\n * @param value The search param value. `undefined` means the value is\n * unavailable.\n *\n * @returns The equivalent state value.\n */\n mapSearchParamToState?: (value?: string) => T\n\n /**\n * Function for transforming the value of the mapped state to the search param\n * value.\n *\n * @param state The state value.\n *\n * @returns The equivalent search param value.\n */\n mapStateToSearchParam?: (state: T) => string | undefined\n}\n\n/**\n * Hook for mapping a search param to a state. Whenever the value of the target\n * search param changes, the mapped state will change as well, and vice versa.\n *\n * @param param The search param key.\n * @param defaultValue The default value of the state.\n * @param options See {@link Options}.\n *\n * @returns A tuple consisting of a stateful value representing the current\n * value of the mapped state and a function that updates it.\n */\nexport default function useSearchParamState<T>(param: string, defaultValue: T, { mapSearchParamToState, mapStateToSearchParam }: Options<T> = {}): [T, Dispatch<SetStateAction<T>>] {\n const defaultMapSearchParamToState = (value: string | undefined, fallback: T): T => {\n if (mapSearchParamToState) {\n return mapSearchParamToState(value)\n }\n else if (!value) {\n return fallback\n }\n else {\n return value as unknown as NonNullable<T>\n }\n }\n\n const defaultMapStateToSearchParam = (state: T): string | undefined => {\n if (mapStateToSearchParam) {\n return mapStateToSearchParam(state)\n }\n else if (state === defaultValue) {\n return undefined\n }\n else {\n return `${state}`\n }\n }\n\n const [searchParams, setSearchParams] = useSearchParams()\n const currentState = defaultMapSearchParamToState(searchParams.get(param) ?? undefined, defaultValue)\n const [state, setState] = useState(currentState)\n\n debug('Using search param state...', 'OK', `param=${param}, defaultValue=${currentState}`)\n\n useEffect(() => {\n const value = searchParams.get(param)\n const newValue = defaultMapStateToSearchParam(state)\n\n if (newValue === value) return\n\n if (!newValue) {\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,4 +1,4 @@
1
- import React, { PropsWithChildren, RefObject } from 'react';
1
+ import React, { type PropsWithChildren, type RefObject } from 'react';
2
2
  import { Point } from 'spase';
3
3
  type ScrollPosition = {
4
4
  pos: Point;
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollPositionProvider.js","sourceRoot":"/","sources":["providers/ScrollPositionProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, PropsWithChildren, RefObject, useContext, useEffect, useState } from 'react'\nimport { Point, Rect } from 'spase'\n\ntype ScrollPosition = {\n pos: Point\n step: Point\n}\n\ntype ScrollPositionContextValue = ScrollPosition & {\n minPos: Point\n maxPos: Point\n}\n\ntype ScrollPositionProviderProps = PropsWithChildren\n\nexport const ScrollPositionContext = createContext<ScrollPositionContextValue | undefined>(undefined)\n\nexport default function ScrollPositionProvider({\n children,\n}: ScrollPositionProviderProps) {\n const [value, setValue] = useState<ScrollPositionContextValue>({\n minPos: new Point(),\n maxPos: new Point(),\n pos: new Point(),\n step: new Point(),\n })\n\n useEffect(() => {\n const updateScrollPosition = () => {\n const refRect = Rect.fromViewport()\n const refRectMin = refRect.clone({ x: 0, y: 0 })\n const refRectFull = Rect.from(window, { overflow: true })\n\n if (!refRectFull) return\n\n const refRectMax = refRectMin.clone({ x: refRectFull.width - refRect.width, y: refRectFull.height - refRect.height })\n const step = new Point([refRect.left / refRectMax.left, refRect.top / refRectMax.top])\n\n setValue({\n minPos: new Point([refRectMin.left, refRectMin.top]),\n maxPos: new Point([refRectMax.left, refRectMax.top]),\n pos: new Point([refRect.left, refRect.top]),\n step,\n })\n }\n\n window.addEventListener('scroll', updateScrollPosition)\n window.addEventListener('resize', updateScrollPosition)\n window.addEventListener('orientationchange', updateScrollPosition)\n\n updateScrollPosition()\n\n return () => {\n window.removeEventListener('scroll', updateScrollPosition)\n window.removeEventListener('resize', updateScrollPosition)\n window.removeEventListener('orientationchange', updateScrollPosition)\n }\n }, [])\n\n return (\n <ScrollPositionContext.Provider value={value}>\n {children}\n </ScrollPositionContext.Provider>\n )\n}\n\nexport function useScrollPosition(targetRef?: RefObject<Element>): ScrollPosition {\n const context = useContext(ScrollPositionContext)\n if (!context) throw Error('Cannot fetch the current scroll position context, is the corresponding provider instated?')\n\n if (!targetRef) {\n return {\n pos: context.pos,\n step: context.step,\n }\n }\n\n const element = targetRef.current\n\n const refRect = Rect.fromViewport()\n const rect = Rect.from(element)\n\n if (!refRect || !rect) {\n return {\n pos: new Point(),\n step: new Point(),\n }\n }\n\n const posX = refRect.right - rect.left\n const posY = refRect.bottom - rect.top\n const stepX = posX / rect.width\n const stepY = posY / rect.height\n\n return {\n pos: new Point([posX, posY]),\n step: new Point([stepX, stepY]),\n }\n}\n"]}
1
+ {"version":3,"file":"ScrollPositionProvider.js","sourceRoot":"/","sources":["providers/ScrollPositionProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, useContext, useEffect, useState, type PropsWithChildren, type RefObject } from 'react'\nimport { Point, Rect } from 'spase'\n\ntype ScrollPosition = {\n pos: Point\n step: Point\n}\n\ntype ScrollPositionContextValue = ScrollPosition & {\n minPos: Point\n maxPos: Point\n}\n\ntype ScrollPositionProviderProps = PropsWithChildren\n\nexport const ScrollPositionContext = createContext<ScrollPositionContextValue | undefined>(undefined)\n\nexport default function ScrollPositionProvider({\n children,\n}: ScrollPositionProviderProps) {\n const [value, setValue] = useState<ScrollPositionContextValue>({\n minPos: new Point(),\n maxPos: new Point(),\n pos: new Point(),\n step: new Point(),\n })\n\n useEffect(() => {\n const updateScrollPosition = () => {\n const refRect = Rect.fromViewport()\n const refRectMin = refRect.clone({ x: 0, y: 0 })\n const refRectFull = Rect.from(window, { overflow: true })\n\n if (!refRectFull) return\n\n const refRectMax = refRectMin.clone({ x: refRectFull.width - refRect.width, y: refRectFull.height - refRect.height })\n const step = new Point([refRect.left / refRectMax.left, refRect.top / refRectMax.top])\n\n setValue({\n minPos: new Point([refRectMin.left, refRectMin.top]),\n maxPos: new Point([refRectMax.left, refRectMax.top]),\n pos: new Point([refRect.left, refRect.top]),\n step,\n })\n }\n\n window.addEventListener('scroll', updateScrollPosition)\n window.addEventListener('resize', updateScrollPosition)\n window.addEventListener('orientationchange', updateScrollPosition)\n\n updateScrollPosition()\n\n return () => {\n window.removeEventListener('scroll', updateScrollPosition)\n window.removeEventListener('resize', updateScrollPosition)\n window.removeEventListener('orientationchange', updateScrollPosition)\n }\n }, [])\n\n return (\n <ScrollPositionContext.Provider value={value}>\n {children}\n </ScrollPositionContext.Provider>\n )\n}\n\nexport function useScrollPosition(targetRef?: RefObject<Element>): ScrollPosition {\n const context = useContext(ScrollPositionContext)\n if (!context) throw Error('Cannot fetch the current scroll position context, is the corresponding provider instated?')\n\n if (!targetRef) {\n return {\n pos: context.pos,\n step: context.step,\n }\n }\n\n const element = targetRef.current\n\n const refRect = Rect.fromViewport()\n const rect = Rect.from(element)\n\n if (!refRect || !rect) {\n return {\n pos: new Point(),\n step: new Point(),\n }\n }\n\n const posX = refRect.right - rect.left\n const posY = refRect.bottom - rect.top\n const stepX = posX / rect.width\n const stepY = posY / rect.height\n\n return {\n pos: new Point([posX, posY]),\n step: new Point([stepX, stepY]),\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { JSXElementConstructor, ReactNode } from 'react';
1
+ import { type JSXElementConstructor, type ReactNode } from 'react';
2
2
  type ComponentTypeDict = Record<string, JSXElementConstructor<any>>;
3
3
  type ComponentElementDict<T extends ComponentTypeDict> = Record<keyof T, JSX.Element>;
4
4
  export default function asComponentDict<T extends ComponentTypeDict>(children?: ReactNode, typeDict?: T): Partial<ComponentElementDict<T>>;
@@ -1 +1 @@
1
- {"version":3,"file":"asComponentDict.js","sourceRoot":"/","sources":["utils/asComponentDict.ts"],"names":[],"mappings":";;AAAA,+BAAkF;AAMlF,SAAwB,eAAe,CAA8B,QAAoB,EAAE,QAAqB;IAArB,yBAAA,EAAA,WAAc,EAAO;IAC9G,IAAM,IAAI,GAAgB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC/C,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACrC,IAAM,UAAU,GAAqC,EAAE,CAAA;IAEvD,gBAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAA,KAAK;QAC9B,IAAI,CAAC,IAAA,sBAAc,EAAC,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAEjE,IAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAW,CAAC,CAAA;QAC9C,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,sEAA+D,KAAK,CAAE,CAAC,CAAA;QAElG,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QACvB,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,mBAAY,KAAK,CAAC,KAAK,CAAC,gCAA6B,CAAC,CAAA;QAEvF,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC;AAlBD,kCAkBC","sourcesContent":["import { Children, isValidElement, JSXElementConstructor, ReactNode } from 'react'\n\ntype ComponentTypeDict = Record<string, JSXElementConstructor<any>>\n\ntype ComponentElementDict<T extends ComponentTypeDict> = Record<keyof T, JSX.Element>\n\nexport default function asComponentDict<T extends ComponentTypeDict>(children?: ReactNode, typeDict: T = {} as T): Partial<ComponentElementDict<T>> {\n const keys: (keyof T)[] = Object.keys(typeDict)\n const types = Object.values(typeDict)\n const components: Partial<ComponentElementDict<T>> = {}\n\n Children.forEach(children, child => {\n if (!isValidElement(child)) throw Error('Invalid child detected')\n\n const index = types.indexOf(child.type as any)\n if (index < 0) throw Error(`Unsupported child, only the following children are allowed: ${types}`)\n\n const key = keys[index]\n if (components[key]) throw Error(`Only one ${types[index]} can be provided as a child`)\n\n components[key] = child\n })\n\n return components\n}\n"]}
1
+ {"version":3,"file":"asComponentDict.js","sourceRoot":"/","sources":["utils/asComponentDict.ts"],"names":[],"mappings":";;AAAA,+BAA4F;AAM5F,SAAwB,eAAe,CAA8B,QAAoB,EAAE,QAAqB;IAArB,yBAAA,EAAA,WAAc,EAAO;IAC9G,IAAM,IAAI,GAAgB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC/C,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACrC,IAAM,UAAU,GAAqC,EAAE,CAAA;IAEvD,gBAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAA,KAAK;QAC9B,IAAI,CAAC,IAAA,sBAAc,EAAC,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAEjE,IAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAW,CAAC,CAAA;QAC9C,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,sEAA+D,KAAK,CAAE,CAAC,CAAA;QAElG,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QACvB,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,mBAAY,KAAK,CAAC,KAAK,CAAC,gCAA6B,CAAC,CAAA;QAEvF,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC;AAlBD,kCAkBC","sourcesContent":["import { Children, isValidElement, type JSXElementConstructor, type ReactNode } from 'react'\n\ntype ComponentTypeDict = Record<string, JSXElementConstructor<any>>\n\ntype ComponentElementDict<T extends ComponentTypeDict> = Record<keyof T, JSX.Element>\n\nexport default function asComponentDict<T extends ComponentTypeDict>(children?: ReactNode, typeDict: T = {} as T): Partial<ComponentElementDict<T>> {\n const keys: (keyof T)[] = Object.keys(typeDict)\n const types = Object.values(typeDict)\n const components: Partial<ComponentElementDict<T>> = {}\n\n Children.forEach(children, child => {\n if (!isValidElement(child)) throw Error('Invalid child detected')\n\n const index = types.indexOf(child.type as any)\n if (index < 0) throw Error(`Unsupported child, only the following children are allowed: ${types}`)\n\n const key = keys[index]\n if (components[key]) throw Error(`Only one ${types[index]} can be provided as a child`)\n\n components[key] = child\n })\n\n return components\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { CSSProperties } from 'react';
1
+ import { type CSSProperties } from 'react';
2
2
  export default function asStyleDict<T>(dict: {
3
3
  [K in keyof T]: CSSProperties;
4
4
  }): { [K in keyof T]: CSSProperties; };
@@ -1 +1 @@
1
- {"version":3,"file":"asStyleDict.js","sourceRoot":"/","sources":["utils/asStyleDict.ts"],"names":[],"mappings":";;AAEA,SAAwB,WAAW,CAAI,IAAuC;IAC5E,OAAO,IAAI,CAAA;AACb,CAAC;AAFD,8BAEC","sourcesContent":["import { CSSProperties } from 'react'\n\nexport default function asStyleDict<T>(dict: { [K in keyof T]: CSSProperties }) {\n return dict\n}\n"]}
1
+ {"version":3,"file":"asStyleDict.js","sourceRoot":"/","sources":["utils/asStyleDict.ts"],"names":[],"mappings":";;AAEA,SAAwB,WAAW,CAAI,IAAuC;IAC5E,OAAO,IAAI,CAAA;AACb,CAAC;AAFD,8BAEC","sourcesContent":["import { type CSSProperties } from 'react'\n\nexport default function asStyleDict<T>(dict: { [K in keyof T]: CSSProperties }) {\n return dict\n}\n"]}
@@ -1,14 +1,14 @@
1
- import { Attributes, CElement, ClassAttributes, Component, ComponentState, FunctionComponentElement, ReactElement, ReactNode } from 'react';
1
+ import { type Attributes, type CElement, type ClassAttributes, type Component, type ComponentState, type FunctionComponentElement, type ReactElement, type ReactNode } from 'react';
2
2
  /**
3
3
  * Wrapper for {@link cloneElement} but instead of overwriting `className` and
4
4
  * `style` of the cloned element with the values specified in the `props`
5
5
  * argument, they are merged instead.
6
6
  *
7
- * @param element - The target element to clone.
8
- * @param props - The props to apply to the cloned element. Overlapping props
9
- * are overwritten with the exception of `className` and `style`,
10
- * which are merged.
11
- * @param children - Optional child elements add into the cloned element.
7
+ * @param element The target element to clone.
8
+ * @param props The props to apply to the cloned element. Overlapping props are
9
+ * overwritten with the exception of `className` and `style`, which
10
+ * are merged.
11
+ * @param children Optional child elements add into the cloned element.
12
12
  *
13
13
  * @returns The cloned element.
14
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cloneStyledElement.js","sourceRoot":"/","sources":["utils/cloneStyledElement.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAyJ;AAkBzJ,SAAS,kBAAkB,CACzB,OAAuE,EACvE,KAAqE;;IAArE,sBAAA,EAAA,UAAqE;IACrE,kBAAwB;SAAxB,UAAwB,EAAxB,qBAAwB,EAAxB,IAAwB;QAAxB,iCAAwB;;IAExB,IAAM,KAAsC,KAAY,EAAhD,SAAS,eAAA,EAAE,KAAK,WAAA,EAAK,UAAU,cAAjC,sBAAmC,CAAe,CAAA;IACxD,IAAM,YAAY,GAAG,OAAO,CAAC,KAAY,CAAA;IAEzC,OAAO,oBAAY,8BAAC,OAAO,EAAE,WAC3B,SAAS,EAAE,UAAG,MAAA,YAAY,CAAC,SAAS,mCAAI,EAAE,cAAI,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACpG,KAAK,wBACA,MAAA,YAAY,CAAC,KAAK,mCAAI,EAAE,GACxB,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,KAEb,UAAU,CACP,UAAK,QAAQ,WAAC;AACxB,CAAC;AAED,kBAAe,kBAAkB,CAAA","sourcesContent":["import { Attributes, CElement, ClassAttributes, cloneElement, Component, ComponentState, FunctionComponentElement, ReactElement, ReactNode } from 'react'\n\n/**\n * Wrapper for {@link cloneElement} but instead of overwriting `className` and\n * `style` of the cloned element with the values specified in the `props`\n * argument, they are merged instead.\n *\n * @param element - The target element to clone.\n * @param props - The props to apply to the cloned element. Overlapping props\n * are overwritten with the exception of `className` and `style`,\n * which are merged.\n * @param children - Optional child elements add into the cloned element.\n *\n * @returns The cloned element.\n */\nfunction cloneStyledElement<P>(element: FunctionComponentElement<P>, props?: Partial<P> & Attributes, ...children: ReactNode[]): FunctionComponentElement<P>\nfunction cloneStyledElement<P, T extends Component<P, ComponentState>>(element: CElement<P, T>, props?: Partial<P> & ClassAttributes<T>, ...children: ReactNode[]): CElement<P, T>\nfunction cloneStyledElement<P>(element: ReactElement<P>, props?: Partial<P> & Attributes, ...children: ReactNode[]): ReactElement<P>\nfunction cloneStyledElement<P, T extends Component<P, ComponentState> = never>(\n element: FunctionComponentElement<P> | CElement<P, T> | ReactElement<P>,\n props: Partial<P> & Attributes | Partial<P> & ClassAttributes<T> = {},\n ...children: ReactNode[]\n) {\n const { className, style, ...otherProps } = props as any\n const elementProps = element.props as any\n\n return cloneElement(element, {\n className: `${elementProps.className ?? ''} ${className ?? ''}`.split(' ').filter(Boolean).join(' '),\n style: {\n ...elementProps.style ?? {},\n ...style ?? {},\n },\n ...otherProps,\n } as any, ...children)\n}\n\nexport default cloneStyledElement\n"]}
1
+ {"version":3,"file":"cloneStyledElement.js","sourceRoot":"/","sources":["utils/cloneStyledElement.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAiM;AAkBjM,SAAS,kBAAkB,CACzB,OAAuE,EACvE,KAAqE;;IAArE,sBAAA,EAAA,UAAqE;IACrE,kBAAwB;SAAxB,UAAwB,EAAxB,qBAAwB,EAAxB,IAAwB;QAAxB,iCAAwB;;IAExB,IAAM,KAAsC,KAAY,EAAhD,SAAS,eAAA,EAAE,KAAK,WAAA,EAAK,UAAU,cAAjC,sBAAmC,CAAe,CAAA;IACxD,IAAM,YAAY,GAAG,OAAO,CAAC,KAAY,CAAA;IAEzC,OAAO,oBAAY,8BAAC,OAAO,EAAE,WAC3B,SAAS,EAAE,UAAG,MAAA,YAAY,CAAC,SAAS,mCAAI,EAAE,cAAI,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACpG,KAAK,wBACA,MAAA,YAAY,CAAC,KAAK,mCAAI,EAAE,GACxB,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,KAEb,UAAU,CACP,UAAK,QAAQ,WAAC;AACxB,CAAC;AAED,kBAAe,kBAAkB,CAAA","sourcesContent":["import { cloneElement, type Attributes, type CElement, type ClassAttributes, type Component, type ComponentState, type FunctionComponentElement, type ReactElement, type ReactNode } from 'react'\n\n/**\n * Wrapper for {@link cloneElement} but instead of overwriting `className` and\n * `style` of the cloned element with the values specified in the `props`\n * argument, they are merged instead.\n *\n * @param element The target element to clone.\n * @param props The props to apply to the cloned element. Overlapping props are\n * overwritten with the exception of `className` and `style`, which\n * are merged.\n * @param children Optional child elements add into the cloned element.\n *\n * @returns The cloned element.\n */\nfunction cloneStyledElement<P>(element: FunctionComponentElement<P>, props?: Partial<P> & Attributes, ...children: ReactNode[]): FunctionComponentElement<P>\nfunction cloneStyledElement<P, T extends Component<P, ComponentState>>(element: CElement<P, T>, props?: Partial<P> & ClassAttributes<T>, ...children: ReactNode[]): CElement<P, T>\nfunction cloneStyledElement<P>(element: ReactElement<P>, props?: Partial<P> & Attributes, ...children: ReactNode[]): ReactElement<P>\nfunction cloneStyledElement<P, T extends Component<P, ComponentState> = never>(\n element: FunctionComponentElement<P> | CElement<P, T> | ReactElement<P>,\n props: Partial<P> & Attributes | Partial<P> & ClassAttributes<T> = {},\n ...children: ReactNode[]\n) {\n const { className, style, ...otherProps } = props as any\n const elementProps = element.props as any\n\n return cloneElement(element, {\n className: `${elementProps.className ?? ''} ${className ?? ''}`.split(' ').filter(Boolean).join(' '),\n style: {\n ...elementProps.style ?? {},\n ...style ?? {},\n },\n ...otherProps,\n } as any, ...children)\n}\n\nexport default cloneStyledElement\n"]}
@@ -1,2 +1,2 @@
1
- import { CSSProperties } from 'react';
1
+ import { type CSSProperties } from 'react';
2
2
  export default function styles(...args: (CSSProperties | undefined | false)[]): CSSProperties;
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"/","sources":["utils/styles.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAEA,SAAwB,MAAM;IAAC,cAA8C;SAA9C,UAA8C,EAA9C,qBAA8C,EAA9C,IAA8C;QAA9C,yBAA8C;;IAC3E,OAAO,IAAI,CAAC,MAAM,CAAgB,UAAC,GAAG,EAAE,IAAI,IAAK,OAAA,uBAC5C,GAAG,GACH,IAAI,IAAI,EAAE,EACb,EAH+C,CAG/C,EAAE,EAAE,CAAC,CAAA;AACT,CAAC;AALD,yBAKC","sourcesContent":["import { CSSProperties } from 'react'\n\nexport default function styles(...args: (CSSProperties | undefined | false)[]): CSSProperties {\n return args.reduce<CSSProperties>((out, curr) => ({\n ...out,\n ...curr || {},\n }), {})\n}\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"/","sources":["utils/styles.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAEA,SAAwB,MAAM;IAAC,cAA8C;SAA9C,UAA8C,EAA9C,qBAA8C,EAA9C,IAA8C;QAA9C,yBAA8C;;IAC3E,OAAO,IAAI,CAAC,MAAM,CAAgB,UAAC,GAAG,EAAE,IAAI,IAAK,OAAA,uBAC5C,GAAG,GACH,IAAI,IAAI,EAAE,EACb,EAH+C,CAG/C,EAAE,EAAE,CAAC,CAAA;AACT,CAAC;AALD,yBAKC","sourcesContent":["import { type CSSProperties } from 'react'\n\nexport default function styles(...args: (CSSProperties | undefined | false)[]): CSSProperties {\n return args.reduce<CSSProperties>((out, curr) => ({\n ...out,\n ...curr || {},\n }), {})\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "etudes",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "A study of headless React components",
5
5
  "main": "lib",
6
6
  "scripts": {
@@ -29,11 +29,11 @@
29
29
  "lib"
30
30
  ],
31
31
  "devDependencies": {
32
- "@babel/core": "^7.22.11",
33
- "@babel/plugin-transform-runtime": "^7.22.10",
34
- "@babel/preset-env": "^7.22.14",
35
- "@babel/preset-react": "^7.22.5",
36
- "@babel/preset-typescript": "^7.22.11",
32
+ "@babel/core": "^7.22.17",
33
+ "@babel/plugin-transform-runtime": "^7.22.15",
34
+ "@babel/preset-env": "^7.22.15",
35
+ "@babel/preset-react": "^7.22.15",
36
+ "@babel/preset-typescript": "^7.22.15",
37
37
  "@types/debug": "^4.1.8",
38
38
  "@types/html-webpack-plugin": "^3.2.6",
39
39
  "@types/node-polyglot": "^2.4.2",
@@ -43,14 +43,15 @@
43
43
  "@types/styled-components": "^5.1.26",
44
44
  "@types/webpack": "^5.28.2",
45
45
  "@types/webpack-env": "^1.18.1",
46
- "@typescript-eslint/eslint-plugin": "^6.5.0",
47
- "@typescript-eslint/parser": "^6.5.0",
46
+ "@typescript-eslint/eslint-plugin": "^6.6.0",
47
+ "@typescript-eslint/parser": "^6.6.0",
48
48
  "babel-loader": "^9.1.3",
49
49
  "babel-plugin-styled-components": "^2.1.4",
50
50
  "concurrently": "^8.2.1",
51
51
  "cross-env": "^7.0.3",
52
52
  "debug": "^4.3.4",
53
- "eslint": "^8.48.0",
53
+ "eslint": "^8.49.0",
54
+ "fast-xml-parser": "^4.2.7",
54
55
  "html-webpack-plugin": "^5.5.3",
55
56
  "react": "^18.2.0",
56
57
  "react-dom": "^18.2.0",
@@ -71,12 +72,13 @@
71
72
  "interactjs": "^1.10.18",
72
73
  "react-transition-group": "^4.4.5",
73
74
  "resize-observer-polyfill": "^1.5.1",
74
- "spase": "^6.6.0"
75
+ "spase": "^7.0.0"
75
76
  },
76
77
  "peerDependencies": {
77
78
  "react": "^18.2.0"
78
79
  },
79
80
  "optionalDependencies": {
81
+ "fast-xml-parser": "^4.2.7",
80
82
  "react-router": "^6.15.0",
81
83
  "react-router-dom": "^6.15.0"
82
84
  }