@obosbbl/grunnmuren-react 3.3.1 → 3.3.3

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
@@ -27,7 +27,7 @@ type DisclosureProps = DisclosureProps$1 & RefAttributes<HTMLDivElement> & {
27
27
  className?: string;
28
28
  };
29
29
  declare const DisclosureStateContext: react.Context<DisclosureState | null>;
30
- declare const Disclosure: ({ ref: _ref, children, ..._props }: DisclosureProps) => react_jsx_runtime.JSX.Element;
30
+ declare const Disclosure: ({ ref: _ref, ..._props }: DisclosureProps) => react_jsx_runtime.JSX.Element;
31
31
  type DisclosurePanelProps = Omit<HTMLAttributes<HTMLDivElement>, 'role'> & {
32
32
  children: React.ReactNode;
33
33
  role?: 'group' | 'region' | 'none';
@@ -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
@@ -136,10 +136,10 @@ const DisclosureButton = ({ className, withChevron, isIconOnly, children, ref: _
136
136
  });
137
137
  };
138
138
  const DisclosureStateContext = /*#__PURE__*/ createContext(null);
139
- const Disclosure = ({ ref: _ref, children, ..._props })=>{
139
+ const Disclosure = ({ ref: _ref, ..._props })=>{
140
140
  const [props, ref] = useContextProps(_props, _ref, DisclosureContext);
141
141
  const groupState = useContext(DisclosureGroupStateContext);
142
- let { id, ...otherProps } = props;
142
+ let { id, children, ...otherProps } = props;
143
143
  const defaultId = useId();
144
144
  id ||= defaultId;
145
145
  const isExpanded = groupState ? groupState.expandedKeys.has(id) : props.isExpanded;
@@ -377,13 +377,15 @@ const iconMap = {
377
377
  };
378
378
  const alertVariants = cva({
379
379
  base: [
380
- 'grid grid-cols-[auto_1fr_auto] items-center gap-2 rounded-md border-2 px-3 py-2',
380
+ 'grid grid-cols-[auto_1fr_auto] gap-2 rounded-md border-2 px-3 py-2',
381
+ // Icon styles:
382
+ '[&:has([data-slot="heading"])>svg]:mt-0.5',
381
383
  // Heading styles:
382
- '[&_[data-slot="heading"]]:font-medium [&_[data-slot="heading"]]:text-base [&_[data-slot="heading"]]:leading-7',
384
+ '**:data-[slot="heading"]:font-medium **:data-[slot="heading"]:text-base **:data-[slot="heading"]:leading-7',
383
385
  // Content styles:
384
- '[&:has([data-slot="heading"])_[data-slot="content"]]:col-span-full [&_[data-slot="content"]]:text-sm [&_[data-slot="content"]]:leading-6',
386
+ '**:data-[slot="content"]:text-sm **:data-[slot="content"]:leading-6 [&:has([data-slot="heading"])_[data-slot="content"]]:col-span-full',
385
387
  // Footer styles:
386
- '[&_[data-slot="footer"]]:col-span-full [&_[data-slot="footer"]]:font-light [&_[data-slot="footer"]]:text-xs [&_[data-slot="footer"]]:leading-6'
388
+ '**:data-[slot="footer"]:col-span-full **:data-[slot="footer"]:font-light **:data-[slot="footer"]:text-xs **:data-[slot="footer"]:leading-6'
387
389
  ],
388
390
  variants: {
389
391
  /**
@@ -442,7 +444,7 @@ const Alertbox = ({ children, role, className, icon, variant = 'info', isDismiss
442
444
  }),
443
445
  isExpandable && /*#__PURE__*/ jsxs("button", {
444
446
  className: cx('-my-3 relative col-span-full row-start-2 inline-flex max-w-fit cursor-pointer items-center gap-1 py-3 text-sm leading-6', // Focus styles:
445
- 'outline-none after:absolute after:right-0 after:bottom-3 after:left-0 after:h-0', 'focus-visible:after:h-[2px] focus-visible:after:bg-black'),
447
+ 'outline-none after:absolute after:right-0 after:bottom-3 after:left-0 after:h-0', 'focus-visible:after:h-0.5 focus-visible:after:bg-black'),
446
448
  onClick: ()=>setIsExpanded((prevState)=>!prevState),
447
449
  "aria-expanded": isExpanded,
448
450
  "aria-controls": id,
@@ -975,6 +977,27 @@ const cardLinkVariants = cva({
975
977
  });
976
978
  };
977
979
 
980
+ /**
981
+ * Hook that detects the user's preference for reduced motion.
982
+ *
983
+ * Keep in mind that this hook relies on a browser API's and doesn't run on the server.
984
+ * You can supply an initial value that will be used for server side rendering.
985
+ */ function usePrefersReducedMotion(initialValue = true) {
986
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(initialValue);
987
+ useEffect(()=>{
988
+ const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
989
+ setPrefersReducedMotion(mediaQuery.matches);
990
+ const changeListener = (event)=>{
991
+ setPrefersReducedMotion(event.matches);
992
+ };
993
+ mediaQuery.addEventListener('change', changeListener);
994
+ return ()=>{
995
+ mediaQuery.removeEventListener('change', changeListener);
996
+ };
997
+ }, []);
998
+ return prefersReducedMotion;
999
+ }
1000
+
978
1001
  const Carousel = ({ className, children, onChange, ...rest })=>{
979
1002
  const carouselRef = useRef(null);
980
1003
  const carouselItemsRef = useRef(null);
@@ -986,6 +1009,7 @@ const Carousel = ({ className, children, onChange, ...rest })=>{
986
1009
  const scrollQueue = useRef([]);
987
1010
  const [hasReachedScrollStart, setHasReachedScrollStart] = useState(scrollTargetIndex === 0);
988
1011
  const [hasReachedScrollEnd, setHasReachedScrollEnd] = useState(!carouselItemsRef.current || carouselItemsRef.current.children.length - 1 === scrollTargetIndex);
1012
+ const prefersReducedMotion = usePrefersReducedMotion();
989
1013
  useEffect(()=>{
990
1014
  setHasReachedScrollStart(scrollTargetIndex === 0);
991
1015
  setHasReachedScrollEnd(!carouselItemsRef.current || carouselItemsRef.current.children.length - 1 === scrollTargetIndex);
@@ -1017,7 +1041,6 @@ const Carousel = ({ className, children, onChange, ...rest })=>{
1017
1041
  }
1018
1042
  isScrollingProgrammatically.current = true;
1019
1043
  const elementWithFocusVisible = carouselRef.current?.querySelector(':focus-visible');
1020
- const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
1021
1044
  carouselItemsRef.current.children[scrollTargetIndex]?.scrollIntoView({
1022
1045
  behavior: prefersReducedMotion ? 'instant' : 'smooth',
1023
1046
  inline: 'start',
@@ -1066,7 +1089,8 @@ const Carousel = ({ className, children, onChange, ...rest })=>{
1066
1089
  processQueue(); // Process any queued scrolls
1067
1090
  }, 500);
1068
1091
  }, [
1069
- scrollTargetIndex
1092
+ scrollTargetIndex,
1093
+ prefersReducedMotion
1070
1094
  ]);
1071
1095
  // Clean up timeout on unmount
1072
1096
  useEffect(()=>{
@@ -1221,16 +1245,7 @@ const CarouselItemsContext = /*#__PURE__*/ createContext({
1221
1245
  });
1222
1246
  const CarouselItems = ({ className, children })=>{
1223
1247
  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
- }, []);
1248
+ const prefersReducedMotion = usePrefersReducedMotion();
1234
1249
  const handleKeyDown = (event)=>{
1235
1250
  // Prevent default behavior when holding down arrow keys (when repeat is true)
1236
1251
  // The default behavior in scroll snapping causes a staggering scroll effect that feels janky
@@ -1239,7 +1254,7 @@ const CarouselItems = ({ className, children })=>{
1239
1254
  return;
1240
1255
  }
1241
1256
  // For users with prefers-reduced-motion, trigger button click behavior instead of native scroll
1242
- if (prefersReducedMotion.current) {
1257
+ if (prefersReducedMotion) {
1243
1258
  if (event.key === 'ArrowLeft' && handlePrevious) {
1244
1259
  event.preventDefault();
1245
1260
  handlePrevious();
@@ -2868,15 +2883,14 @@ const VideoLoop = ({ src, format, alt, className })=>{
2868
2883
  const [shouldPlay, setShouldPlay] = useState(false);
2869
2884
  // 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
2885
  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);
2886
+ const prefersReducedMotion = usePrefersReducedMotion(null);
2873
2887
  const videoRef = useRef(null);
2874
2888
  useEffect(()=>{
2875
- const { matches: userPrefersReducedMotion } = matchMedia('(prefers-reduced-motion: reduce)');
2876
- setUserPrefersReducedMotion(userPrefersReducedMotion);
2877
2889
  // Autoplay the video if the user does not prefer reduced motion
2878
- setShouldPlay(!userPrefersReducedMotion);
2879
- }, []);
2890
+ setShouldPlay(!prefersReducedMotion);
2891
+ }, [
2892
+ prefersReducedMotion
2893
+ ]);
2880
2894
  // Follow google's autoplay policy: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
2881
2895
  // "Don't assume a video will play, and don't show a pause button when the video is not actually playing."
2882
2896
  // "You should always look at the Promise returned by the play function to see if it was rejected:"
@@ -2893,7 +2907,7 @@ const VideoLoop = ({ src, format, alt, className })=>{
2893
2907
  shouldPlay
2894
2908
  ]);
2895
2909
  return /*#__PURE__*/ jsxs("div", {
2896
- className: cx(className, 'relative', userPrefersReducedMotion === null && 'opacity-0'),
2910
+ className: cx(className, 'relative', prefersReducedMotion === null && 'opacity-0'),
2897
2911
  children: [
2898
2912
  /*#__PURE__*/ jsx("video", {
2899
2913
  "aria-hidden": true,
@@ -2901,11 +2915,11 @@ const VideoLoop = ({ src, format, alt, className })=>{
2901
2915
  // cursor-pointer is not working on the button below, so we add it here for the same effect
2902
2916
  className: "h-full max-h-[inherit] w-full cursor-pointer rounded-[inherit] object-cover",
2903
2917
  playsInline: true,
2904
- loop: userPrefersReducedMotion === false,
2905
- autoPlay: userPrefersReducedMotion === false,
2918
+ loop: prefersReducedMotion === false,
2919
+ autoPlay: prefersReducedMotion === false,
2906
2920
  muted: true,
2907
2921
  onEnded: (event)=>{
2908
- if (userPrefersReducedMotion) {
2922
+ if (prefersReducedMotion) {
2909
2923
  // Reset the video to the beginning if the user prefers reduced motion, since the video will not loop
2910
2924
  event.currentTarget.currentTime = 0;
2911
2925
  setShouldPlay(false);
@@ -2917,7 +2931,7 @@ const VideoLoop = ({ src, format, alt, className })=>{
2917
2931
  type: `video/${format}`
2918
2932
  })
2919
2933
  }),
2920
- userPrefersReducedMotion !== null && /*#__PURE__*/ jsx("button", {
2934
+ prefersReducedMotion !== null && /*#__PURE__*/ jsx("button", {
2921
2935
  "data-slot": "video-loop-button",
2922
2936
  "aria-hidden": true,
2923
2937
  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.3",
4
4
  "description": "Grunnmuren components in React",
5
5
  "repository": {
6
6
  "url": "https://github.com/code-obos/grunnmuren"