@obosbbl/grunnmuren-react 3.3.1 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -165,7 +165,7 @@ declare function Breadcrumbs(props: BreadcrumbsProps): react_jsx_runtime.JSX.Ele
165
165
  */
166
166
  declare const buttonVariants: (props?: ({
167
167
  variant?: "primary" | "secondary" | "tertiary" | undefined;
168
- color?: "mint" | "white" | "blue" | undefined;
168
+ color?: "blue" | "mint" | "white" | undefined;
169
169
  isIconOnly?: boolean | undefined;
170
170
  isPending?: boolean | undefined;
171
171
  } & ({
@@ -192,7 +192,7 @@ type CardProps = VariantProps<typeof cardVariants> & HTMLAttributes<HTMLDivEleme
192
192
  };
193
193
  declare const cardVariants: (props?: ({
194
194
  variant?: "subtle" | "outlined" | undefined;
195
- layout?: "horizontal" | "vertical" | undefined;
195
+ layout?: "vertical" | "horizontal" | undefined;
196
196
  } & ({
197
197
  class?: cva.ClassValue;
198
198
  className?: never;
@@ -349,7 +349,7 @@ type MediaProps = HTMLProps<HTMLDivElement> & VariantProps<typeof mediaVariant>
349
349
  ref?: Ref<HTMLDivElement>;
350
350
  };
351
351
  declare const mediaVariant: (props?: ({
352
- fit?: "contain" | "cover" | undefined;
352
+ fit?: "cover" | "contain" | undefined;
353
353
  } & ({
354
354
  class?: cva.ClassValue;
355
355
  className?: never;
package/dist/index.mjs CHANGED
@@ -975,6 +975,27 @@ const cardLinkVariants = cva({
975
975
  });
976
976
  };
977
977
 
978
+ /**
979
+ * Hook that detects the user's preference for reduced motion.
980
+ *
981
+ * Keep in mind that this hook relies on a browser API's and doesn't run on the server.
982
+ * You can supply an initial value that will be used for server side rendering.
983
+ */ function usePrefersReducedMotion(initialValue = true) {
984
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(initialValue);
985
+ useEffect(()=>{
986
+ const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
987
+ setPrefersReducedMotion(mediaQuery.matches);
988
+ const changeListener = (event)=>{
989
+ setPrefersReducedMotion(event.matches);
990
+ };
991
+ mediaQuery.addEventListener('change', changeListener);
992
+ return ()=>{
993
+ mediaQuery.removeEventListener('change', changeListener);
994
+ };
995
+ }, []);
996
+ return prefersReducedMotion;
997
+ }
998
+
978
999
  const Carousel = ({ className, children, onChange, ...rest })=>{
979
1000
  const carouselRef = useRef(null);
980
1001
  const carouselItemsRef = useRef(null);
@@ -986,6 +1007,7 @@ const Carousel = ({ className, children, onChange, ...rest })=>{
986
1007
  const scrollQueue = useRef([]);
987
1008
  const [hasReachedScrollStart, setHasReachedScrollStart] = useState(scrollTargetIndex === 0);
988
1009
  const [hasReachedScrollEnd, setHasReachedScrollEnd] = useState(!carouselItemsRef.current || carouselItemsRef.current.children.length - 1 === scrollTargetIndex);
1010
+ const prefersReducedMotion = usePrefersReducedMotion();
989
1011
  useEffect(()=>{
990
1012
  setHasReachedScrollStart(scrollTargetIndex === 0);
991
1013
  setHasReachedScrollEnd(!carouselItemsRef.current || carouselItemsRef.current.children.length - 1 === scrollTargetIndex);
@@ -1017,7 +1039,6 @@ const Carousel = ({ className, children, onChange, ...rest })=>{
1017
1039
  }
1018
1040
  isScrollingProgrammatically.current = true;
1019
1041
  const elementWithFocusVisible = carouselRef.current?.querySelector(':focus-visible');
1020
- const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
1021
1042
  carouselItemsRef.current.children[scrollTargetIndex]?.scrollIntoView({
1022
1043
  behavior: prefersReducedMotion ? 'instant' : 'smooth',
1023
1044
  inline: 'start',
@@ -1066,7 +1087,8 @@ const Carousel = ({ className, children, onChange, ...rest })=>{
1066
1087
  processQueue(); // Process any queued scrolls
1067
1088
  }, 500);
1068
1089
  }, [
1069
- scrollTargetIndex
1090
+ scrollTargetIndex,
1091
+ prefersReducedMotion
1070
1092
  ]);
1071
1093
  // Clean up timeout on unmount
1072
1094
  useEffect(()=>{
@@ -1221,16 +1243,7 @@ const CarouselItemsContext = /*#__PURE__*/ createContext({
1221
1243
  });
1222
1244
  const CarouselItems = ({ className, children })=>{
1223
1245
  const { carouselItemsRef, onScroll, activeIndex, handlePrevious, handleNext } = useContext(CarouselItemsContext);
1224
- const prefersReducedMotion = useRef(window.matchMedia('(prefers-reduced-motion: reduce)').matches);
1225
- // Update the ref when the media query changes
1226
- useEffect(()=>{
1227
- const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
1228
- const handleChange = (e)=>{
1229
- prefersReducedMotion.current = e.matches;
1230
- };
1231
- mediaQuery.addEventListener('change', handleChange);
1232
- return ()=>mediaQuery.removeEventListener('change', handleChange);
1233
- }, []);
1246
+ const prefersReducedMotion = usePrefersReducedMotion();
1234
1247
  const handleKeyDown = (event)=>{
1235
1248
  // Prevent default behavior when holding down arrow keys (when repeat is true)
1236
1249
  // The default behavior in scroll snapping causes a staggering scroll effect that feels janky
@@ -1239,7 +1252,7 @@ const CarouselItems = ({ className, children })=>{
1239
1252
  return;
1240
1253
  }
1241
1254
  // For users with prefers-reduced-motion, trigger button click behavior instead of native scroll
1242
- if (prefersReducedMotion.current) {
1255
+ if (prefersReducedMotion) {
1243
1256
  if (event.key === 'ArrowLeft' && handlePrevious) {
1244
1257
  event.preventDefault();
1245
1258
  handlePrevious();
@@ -2868,15 +2881,14 @@ const VideoLoop = ({ src, format, alt, className })=>{
2868
2881
  const [shouldPlay, setShouldPlay] = useState(false);
2869
2882
  // Needed to show the pause button when the video is actually playing (refer to google's autoplay policy: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes)
2870
2883
  const [isPlaying, setIsPlaying] = useState(false);
2871
- // We need to check if the user prefers reduced motion, so that we can prevent the video from autoplaying if so
2872
- const [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(null);
2884
+ const prefersReducedMotion = usePrefersReducedMotion(null);
2873
2885
  const videoRef = useRef(null);
2874
2886
  useEffect(()=>{
2875
- const { matches: userPrefersReducedMotion } = matchMedia('(prefers-reduced-motion: reduce)');
2876
- setUserPrefersReducedMotion(userPrefersReducedMotion);
2877
2887
  // Autoplay the video if the user does not prefer reduced motion
2878
- setShouldPlay(!userPrefersReducedMotion);
2879
- }, []);
2888
+ setShouldPlay(!prefersReducedMotion);
2889
+ }, [
2890
+ prefersReducedMotion
2891
+ ]);
2880
2892
  // Follow google's autoplay policy: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
2881
2893
  // "Don't assume a video will play, and don't show a pause button when the video is not actually playing."
2882
2894
  // "You should always look at the Promise returned by the play function to see if it was rejected:"
@@ -2893,7 +2905,7 @@ const VideoLoop = ({ src, format, alt, className })=>{
2893
2905
  shouldPlay
2894
2906
  ]);
2895
2907
  return /*#__PURE__*/ jsxs("div", {
2896
- className: cx(className, 'relative', userPrefersReducedMotion === null && 'opacity-0'),
2908
+ className: cx(className, 'relative', prefersReducedMotion === null && 'opacity-0'),
2897
2909
  children: [
2898
2910
  /*#__PURE__*/ jsx("video", {
2899
2911
  "aria-hidden": true,
@@ -2901,11 +2913,11 @@ const VideoLoop = ({ src, format, alt, className })=>{
2901
2913
  // cursor-pointer is not working on the button below, so we add it here for the same effect
2902
2914
  className: "h-full max-h-[inherit] w-full cursor-pointer rounded-[inherit] object-cover",
2903
2915
  playsInline: true,
2904
- loop: userPrefersReducedMotion === false,
2905
- autoPlay: userPrefersReducedMotion === false,
2916
+ loop: prefersReducedMotion === false,
2917
+ autoPlay: prefersReducedMotion === false,
2906
2918
  muted: true,
2907
2919
  onEnded: (event)=>{
2908
- if (userPrefersReducedMotion) {
2920
+ if (prefersReducedMotion) {
2909
2921
  // Reset the video to the beginning if the user prefers reduced motion, since the video will not loop
2910
2922
  event.currentTarget.currentTime = 0;
2911
2923
  setShouldPlay(false);
@@ -2917,7 +2929,7 @@ const VideoLoop = ({ src, format, alt, className })=>{
2917
2929
  type: `video/${format}`
2918
2930
  })
2919
2931
  }),
2920
- userPrefersReducedMotion !== null && /*#__PURE__*/ jsx("button", {
2932
+ prefersReducedMotion !== null && /*#__PURE__*/ jsx("button", {
2921
2933
  "data-slot": "video-loop-button",
2922
2934
  "aria-hidden": true,
2923
2935
  type: "button",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obosbbl/grunnmuren-react",
3
- "version": "3.3.1",
3
+ "version": "3.3.2",
4
4
  "description": "Grunnmuren components in React",
5
5
  "repository": {
6
6
  "url": "https://github.com/code-obos/grunnmuren"