@obosbbl/grunnmuren-react 2.3.4 → 3.0.1

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
@@ -1,8 +1,8 @@
1
- import { RouterProvider, ButtonProps as ButtonProps$1, LinkProps, ContextValue, CheckboxProps as CheckboxProps$1, CheckboxGroupProps as CheckboxGroupProps$1, ListBoxItemProps, ListBoxSectionProps, HeadingProps as HeadingProps$1, ComboBoxProps, RadioGroupProps as RadioGroupProps$1, RadioProps as RadioProps$1, SelectProps as SelectProps$1, TextFieldProps as TextFieldProps$1, NumberFieldProps as NumberFieldProps$1, BreadcrumbProps as BreadcrumbProps$1, BreadcrumbsProps as BreadcrumbsProps$1, DisclosureProps as DisclosureProps$1, FileTriggerProps as FileTriggerProps$1, TextProps, LabelProps, DialogTriggerProps as DialogTriggerProps$1, ModalOverlayProps, DialogProps as DialogProps$1, TagGroupProps as TagGroupProps$1, TagListProps as TagListProps$1, TagProps as TagProps$1 } from 'react-aria-components';
1
+ import { RouterProvider, ButtonProps as ButtonProps$1, LinkProps, ContextValue, CheckboxProps as CheckboxProps$1, CheckboxGroupProps as CheckboxGroupProps$1, ListBoxItemProps, ListBoxSectionProps, HeadingProps as HeadingProps$1, ComboBoxProps, RadioGroupProps as RadioGroupProps$1, RadioProps as RadioProps$1, SelectProps as SelectProps$1, TextFieldProps as TextFieldProps$1, NumberFieldProps as NumberFieldProps$1, BreadcrumbProps as BreadcrumbProps$1, BreadcrumbsProps as BreadcrumbsProps$1, DisclosureProps as DisclosureProps$1, FileTriggerProps as FileTriggerProps$1, TextProps, LabelProps, DialogTriggerProps as DialogTriggerProps$1, ModalOverlayProps, DialogProps as DialogProps$1, TagGroupProps as TagGroupProps$1, TagListProps as TagListProps$1, TagProps as TagProps$1, TabsProps as TabsProps$1, TabListProps as TabListProps$1, TabProps as TabProps$1, TabPanelProps as TabPanelProps$1 } from 'react-aria-components';
2
2
  export { ListBoxItemProps as ComboboxItemProps, Form, Group, LabelProps, ListBoxItemProps as SelectItemProps, DisclosureGroup as UNSAFE_DisclosureGroup, DisclosureGroupProps as UNSAFE_DisclosureGroupProps } from 'react-aria-components';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
- import { Ref, HTMLProps, ReactNode, RefAttributes, HTMLAttributes, RefObject, Dispatch, SetStateAction, ComponentProps } from 'react';
5
+ import { Ref, HTMLProps, ReactNode, RefAttributes, HTMLAttributes, RefObject, Dispatch, SetStateAction, ComponentProps, JSX } from 'react';
6
6
  import * as cva from 'cva';
7
7
  import { VariantProps } from 'cva';
8
8
  import { DateFormatterOptions } from 'react-aria';
@@ -80,7 +80,7 @@ declare function Badge(props: BadgeProps): react_jsx_runtime.JSX.Element;
80
80
  */
81
81
  declare const buttonVariants: (props?: ({
82
82
  variant?: "primary" | "secondary" | "tertiary" | undefined;
83
- color?: "mint" | "white" | "green" | undefined;
83
+ color?: "mint" | "white" | "blue" | undefined;
84
84
  isIconOnly?: boolean | undefined;
85
85
  isPending?: boolean | undefined;
86
86
  } & ({
@@ -93,12 +93,6 @@ declare const buttonVariants: (props?: ({
93
93
  type ButtonOrLinkProps$1 = VariantProps<typeof buttonVariants> & {
94
94
  children?: React.ReactNode;
95
95
  href?: LinkProps['href'];
96
- /**
97
- * Display the button in a loading state
98
- * @deprecated Use isPending instead.
99
- * @default false
100
- */
101
- isLoading?: boolean;
102
96
  /** Additional style properties for the element. */
103
97
  style?: React.CSSProperties;
104
98
  /** Ref to the element. */
@@ -158,11 +152,6 @@ type ComboboxProps<T extends object> = {
158
152
  description?: React.ReactNode;
159
153
  /** Error message for the form control. Automatically sets `isInvalid` to true */
160
154
  errorMessage?: React.ReactNode;
161
- /**
162
- * Display the dropdown button trigger in a pending state
163
- * @deprecated Use isPending instead.
164
- */
165
- isLoading?: boolean;
166
155
  /**
167
156
  * Display the dropdown button trigger in a pending state
168
157
  * @default false
@@ -653,7 +642,7 @@ type CarouselItemsProps = {
653
642
  declare const CarouselItems: ({ className, children }: CarouselItemsProps) => react_jsx_runtime.JSX.Element;
654
643
  type CarouselItemProps = {
655
644
  /** The component/components to display as the <CarouselItem/>. */
656
- children: React.ReactNode;
645
+ children: JSX.Element | JSX.Element[];
657
646
  /** Additional CSS className for the element. */
658
647
  className?: string;
659
648
  id?: string;
@@ -668,4 +657,49 @@ type CarouselItem = Pick<CarouselItemProps, 'id'> & {
668
657
  };
669
658
  declare const CarouselItem: ({ className, children, id }: CarouselItemProps) => react_jsx_runtime.JSX.Element;
670
659
 
671
- export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, Alertbox, type Props as AlertboxProps, Avatar, type AvatarProps, Backlink, type BacklinkProps, Badge, type BadgeProps, Breadcrumb, type BreadcrumbProps, Breadcrumbs, type BreadcrumbsProps, Button, ButtonContext, type ButtonProps, Caption, type CaptionProps, Card, CardLink, type CardLinkProps, type CardProps, Checkbox, CheckboxGroup, type CheckboxGroupProps, type CheckboxProps, Combobox, ListBoxHeader as ComboboxHeader, ListBoxItem as ComboboxItem, type ComboboxProps, ListBoxSection as ComboboxSection, Content, ContentContext, type ContentProps, DateFormatter, type DateFormatterProps, Description, type DescriptionProps, DisclosureStateContext, ErrorMessage, type ErrorMessageProps, Footer, type FooterProps, GrunnmurenProvider, type GrunnmurenProviderProps, Heading, HeadingContext, type HeadingProps, Label, type Locale, Media, MediaContext, type MediaProps, NumberField, type NumberFieldProps, Radio, RadioGroup, type RadioGroupProps, type RadioProps, Select, ListBoxHeader as SelectHeader, ListBoxItem as SelectItem, type SelectProps, ListBoxSection as SelectSection, type TagGroupProps, type TagListProps, type TagProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, Carousel as UNSAFE_Carousel, CarouselItem as UNSAFE_CarouselItem, type CarouselItemProps as UNSAFE_CarouselItemProps, CarouselItems as UNSAFE_CarouselItems, type CarouselItemsProps as UNSAFE_CarouselItemsProps, type CarouselProps as UNSAFE_CarouselProps, Dialog as UNSAFE_Dialog, type DialogProps as UNSAFE_DialogProps, DialogTrigger as UNSAFE_DialogTrigger, type DialogTriggerProps as UNSAFE_DialogTriggerProps, Disclosure as UNSAFE_Disclosure, DisclosureButton as UNSAFE_DisclosureButton, type DisclosureButtonProps as UNSAFE_DisclosureButtonProps, DisclosurePanel as UNSAFE_DisclosurePanel, type DisclosurePanelProps as UNSAFE_DisclosurePanelProps, type DisclosureProps as UNSAFE_DisclosureProps, FileUpload as UNSAFE_FileUpload, type FileUploadProps as UNSAFE_FileUploadProps, Hero as UNSAFE_Hero, type HeroProps as UNSAFE_HeroProps, Modal as UNSAFE_Modal, type ModalProps as UNSAFE_ModalProps, Tag as UNSAFE_Tag, TagGroup as UNSAFE_TagGroup, TagList as UNSAFE_TagList, VideoLoop, _useLocale as useLocale };
660
+ type TabsProps = Omit<TabsProps$1, 'className'> & RefAttributes<HTMLDivElement> & {
661
+ /**
662
+ * CSS classes to apply to the tabs container
663
+ */
664
+ className?: string;
665
+ orientation?: 'horizontal' | 'vertical';
666
+ };
667
+ type TabListProps = Omit<TabListProps$1<object>, 'className'> & RefAttributes<HTMLDivElement> & {
668
+ /**
669
+ * CSS classes to apply to the tab list
670
+ */
671
+ className?: string;
672
+ };
673
+ type TabProps = Omit<TabProps$1, 'className'> & RefAttributes<HTMLDivElement> & {
674
+ children: React.ReactNode;
675
+ /**
676
+ * CSS classes to apply to the tab
677
+ */
678
+ className?: string;
679
+ };
680
+ type TabPanelProps = Omit<TabPanelProps$1, 'className'> & RefAttributes<HTMLDivElement> & {
681
+ children: React.ReactNode;
682
+ /**
683
+ * CSS classes to apply to the tab panel
684
+ */
685
+ className?: string;
686
+ };
687
+ /**
688
+ * A container component that organizes content into multiple sections
689
+ * and allows users to navigate between them.
690
+ */
691
+ declare function Tabs(props: TabsProps): react_jsx_runtime.JSX.Element;
692
+ /**
693
+ * A container component for Tab components within Tabs.
694
+ */
695
+ declare function TabList({ className, children, ...restProps }: TabListProps): react_jsx_runtime.JSX.Element;
696
+ /**
697
+ * An individual tab that can be selected to display its associated content.
698
+ */
699
+ declare function Tab(props: TabProps): react_jsx_runtime.JSX.Element;
700
+ /**
701
+ * The content area that displays the selected tab's content.
702
+ */
703
+ declare function TabPanel(props: TabPanelProps): react_jsx_runtime.JSX.Element;
704
+
705
+ export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, Alertbox, type Props as AlertboxProps, Avatar, type AvatarProps, Backlink, type BacklinkProps, Badge, type BadgeProps, Breadcrumb, type BreadcrumbProps, Breadcrumbs, type BreadcrumbsProps, Button, ButtonContext, type ButtonProps, Caption, type CaptionProps, Card, CardLink, type CardLinkProps, type CardProps, Checkbox, CheckboxGroup, type CheckboxGroupProps, type CheckboxProps, Combobox, ListBoxHeader as ComboboxHeader, ListBoxItem as ComboboxItem, type ComboboxProps, ListBoxSection as ComboboxSection, Content, ContentContext, type ContentProps, DateFormatter, type DateFormatterProps, Description, type DescriptionProps, DisclosureStateContext, ErrorMessage, type ErrorMessageProps, Footer, type FooterProps, GrunnmurenProvider, type GrunnmurenProviderProps, Heading, HeadingContext, type HeadingProps, Label, type Locale, Media, MediaContext, type MediaProps, NumberField, type NumberFieldProps, Radio, RadioGroup, type RadioGroupProps, type RadioProps, Select, ListBoxHeader as SelectHeader, ListBoxItem as SelectItem, type SelectProps, ListBoxSection as SelectSection, type TagGroupProps, type TagListProps, type TagProps, TextArea, type TextAreaProps, TextField, type TextFieldProps, Carousel as UNSAFE_Carousel, CarouselItem as UNSAFE_CarouselItem, type CarouselItemProps as UNSAFE_CarouselItemProps, CarouselItems as UNSAFE_CarouselItems, type CarouselItemsProps as UNSAFE_CarouselItemsProps, type CarouselProps as UNSAFE_CarouselProps, Dialog as UNSAFE_Dialog, type DialogProps as UNSAFE_DialogProps, DialogTrigger as UNSAFE_DialogTrigger, type DialogTriggerProps as UNSAFE_DialogTriggerProps, Disclosure as UNSAFE_Disclosure, DisclosureButton as UNSAFE_DisclosureButton, type DisclosureButtonProps as UNSAFE_DisclosureButtonProps, DisclosurePanel as UNSAFE_DisclosurePanel, type DisclosurePanelProps as UNSAFE_DisclosurePanelProps, type DisclosureProps as UNSAFE_DisclosureProps, FileUpload as UNSAFE_FileUpload, type FileUploadProps as UNSAFE_FileUploadProps, Hero as UNSAFE_Hero, type HeroProps as UNSAFE_HeroProps, Modal as UNSAFE_Modal, type ModalProps as UNSAFE_ModalProps, Tab as UNSAFE_Tab, TabList as UNSAFE_TabList, type TabListProps as UNSAFE_TabListProps, TabPanel as UNSAFE_TabPanel, type TabPanelProps as UNSAFE_TabPanelProps, type TabProps as UNSAFE_TabProps, Tabs as UNSAFE_Tabs, type TabsProps as UNSAFE_TabsProps, Tag as UNSAFE_Tag, TagGroup as UNSAFE_TagGroup, TagList as UNSAFE_TagList, VideoLoop, _useLocale as useLocale };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { I18nProvider, RouterProvider, useLocale, useContextProps, Provider, Link, Button as Button$1, Text, CheckboxContext, Checkbox as Checkbox$1, FieldError, Label as Label$1, CheckboxGroup as CheckboxGroup$1, ListBoxItem as ListBoxItem$1, ListBoxSection as ListBoxSection$1, Header, ListBox as ListBox$1, ComboBox, Group, Input, Popover, RadioGroup as RadioGroup$1, Radio as Radio$1, Select as Select$1, SelectValue, TextField as TextField$1, TextArea as TextArea$1, NumberField as NumberField$1, Breadcrumbs as Breadcrumbs$1, Breadcrumb as Breadcrumb$1, ButtonContext as ButtonContext$1, DisclosureContext, DisclosureGroupStateContext, DEFAULT_SLOT, useSlottedContext, FormContext, FieldErrorContext, LabelContext, InputContext, DialogTrigger as DialogTrigger$1, Modal as Modal$1, Dialog as Dialog$1, ModalOverlay as ModalOverlay$1, TagGroup as TagGroup$1, TagList as TagList$1, Tag as Tag$1, GroupContext } from 'react-aria-components';
2
+ import { I18nProvider, RouterProvider, useLocale, useContextProps, Provider, Link, Button as Button$1, Text, CheckboxContext, Checkbox as Checkbox$1, FieldError, Label as Label$1, CheckboxGroup as CheckboxGroup$1, ListBoxItem as ListBoxItem$1, ListBoxSection as ListBoxSection$1, Header, ListBox as ListBox$1, ComboBox, Group, Input, Popover, RadioGroup as RadioGroup$1, Radio as Radio$1, Select as Select$1, SelectValue, TextField as TextField$1, TextArea as TextArea$1, NumberField as NumberField$1, Breadcrumbs as Breadcrumbs$1, Breadcrumb as Breadcrumb$1, ButtonContext as ButtonContext$1, DisclosureContext, DisclosureGroupStateContext, DEFAULT_SLOT, useSlottedContext, FormContext, FieldErrorContext, LabelContext, InputContext, DialogTrigger as DialogTrigger$1, Modal as Modal$1, Dialog as Dialog$1, ModalOverlay as ModalOverlay$1, TagGroup as TagGroup$1, TagList as TagList$1, Tag as Tag$1, GroupContext, Tabs as Tabs$1, TabListStateContext, TabList as TabList$1, Tab as Tab$1, TabPanel as TabPanel$1 } from 'react-aria-components';
3
3
  export { Form, Group, DisclosureGroup as UNSAFE_DisclosureGroup } from 'react-aria-components';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { ChevronDown, LoadingSpinner, Check, Close, InfoCircle, CheckCircle, Warning, Error, ChevronRight, ChevronLeft, PlayerPause, PlayerPlay, Trash, User } from '@obosbbl/grunnmuren-icons-react';
@@ -291,14 +291,14 @@ const translations$1 = {
291
291
  */ variant: {
292
292
  primary: 'no-underline',
293
293
  // by using an inset box-shadow to emulate a border instead of an actual border, the button size will be equal regardless of the variant
294
- secondary: 'no-underline shadow-[inset_0_0_0_2px]',
294
+ secondary: 'border-2 border-current no-underline hover:border-transparent',
295
295
  tertiary: 'underline hover:no-underline'
296
296
  },
297
297
  /**
298
298
  * Adjusts the color of the button for usage on different backgrounds.
299
- * @default green
299
+ * @default blue
300
300
  */ color: {
301
- green: 'focus-visible:outline-focus',
301
+ blue: 'focus-visible:outline-focus',
302
302
  mint: 'focus-visible:outline-focus focus-visible:outline-mint',
303
303
  white: 'focus-visible:outline-focus focus-visible:outline-white'
304
304
  },
@@ -317,18 +317,18 @@ const translations$1 = {
317
317
  },
318
318
  compoundVariants: [
319
319
  {
320
- color: 'green',
320
+ color: 'blue',
321
321
  variant: 'primary',
322
322
  // Darken bg by 20% on hover. The color is manually crafted
323
- className: 'bg-green text-white hover:bg-green-dark active:bg-[#007352] [&_[role="progressbar"]]:text-white'
323
+ className: 'bg-blue-dark text-white hover:bg-blue active:bg-[#0536A0] active:text-white [&_[role="progressbar"]]:text-white'
324
324
  },
325
325
  {
326
- color: 'green',
326
+ color: 'blue',
327
327
  variant: 'secondary',
328
- className: 'text-black shadow-green hover:bg-green hover:text-white active:bg-green [&:hover_[role="progressbar"]]:text-white [&_[role="progressbar"]]:text-black'
328
+ className: 'text-blue-dark hover:border-transparent hover:bg-blue hover:text-blue-dark hover:text-white active:bg-[#0536A0] [&:hover_[role="progressbar"]]:text-white [&_[role="progressbar"]]:text-blue-dark'
329
329
  },
330
330
  {
331
- color: 'green',
331
+ color: 'blue',
332
332
  variant: 'tertiary',
333
333
  className: '[&_[role="progressbar"]]:text-black'
334
334
  },
@@ -341,7 +341,7 @@ const translations$1 = {
341
341
  {
342
342
  color: 'mint',
343
343
  variant: 'secondary',
344
- className: 'text-mint shadow-mint hover:bg-mint hover:text-black [&:hover_[role="progressbar"]]:text-black [&_[role="progressbar"]]:text-mint'
344
+ className: 'text-mint hover:bg-mint hover:text-black [&:hover_[role="progressbar"]]:text-black [&_[role="progressbar"]]:text-mint'
345
345
  },
346
346
  {
347
347
  color: 'mint',
@@ -356,7 +356,7 @@ const translations$1 = {
356
356
  {
357
357
  color: 'white',
358
358
  variant: 'secondary',
359
- className: 'text-white shadow-white hover:bg-white hover:text-black [&:hover_[role="progressbar"]]:text-black [&_[role="progressbar"]]:text-white'
359
+ className: 'text-white hover:bg-white hover:text-black [&:hover_[role="progressbar"]]:text-black [&_[role="progressbar"]]:text-white'
360
360
  },
361
361
  {
362
362
  color: 'white',
@@ -366,7 +366,7 @@ const translations$1 = {
366
366
  ],
367
367
  defaultVariants: {
368
368
  variant: 'primary',
369
- color: 'green',
369
+ color: 'blue',
370
370
  isIconOnly: false,
371
371
  isPending: false
372
372
  }
@@ -377,8 +377,7 @@ function isLinkProps$1(props) {
377
377
  }
378
378
  function Button({ ref = null, ...props }) {
379
379
  [props, ref] = useContextProps(props, ref, ButtonContext);
380
- const { children: _children, color, isIconOnly, isLoading, variant, isPending: _isPending, ...restProps } = props;
381
- const isPending = _isPending || isLoading;
380
+ const { children: _children, color, isIconOnly, variant, isPending, ...restProps } = props;
382
381
  const className = buttonVariants({
383
382
  className: props.className,
384
383
  color,
@@ -402,7 +401,6 @@ function Button({ ref = null, ...props }) {
402
401
  }) : _children;
403
402
  return isLinkProps$1(restProps) ? /*#__PURE__*/ jsx(Link, {
404
403
  ...restProps,
405
- routerOptions: restProps.routerOptions,
406
404
  className: className,
407
405
  ref: ref,
408
406
  children: children
@@ -638,8 +636,7 @@ function InputAddonDivider() {
638
636
  }
639
637
 
640
638
  function Combobox(props) {
641
- const { className, children, description, errorMessage, isLoading, isPending: _isPending, label, isInvalid: _isInvalid, ref, ...restProps } = props;
642
- const isPending = _isPending || isLoading;
639
+ const { className, children, description, errorMessage, isPending, label, isInvalid: _isInvalid, ref, ...restProps } = props;
643
640
  // the order of the conditions matter here, because providing a value for isInvalid makes the validation state "controlled",
644
641
  // which will override any built in validation
645
642
  const isInvalid = !!errorMessage || _isInvalid;
@@ -1802,7 +1799,7 @@ const FileUpload = ({ children, files: _files, onChange, validate, isInvalid: _i
1802
1799
  children: children
1803
1800
  })
1804
1801
  }),
1805
- /*#__PURE__*/ jsx("ul", {
1802
+ controlledOrUncontrolledFiles.length > 0 && /*#__PURE__*/ jsx("ul", {
1806
1803
  className: "mt-4 grid gap-y-2",
1807
1804
  children: controlledOrUncontrolledFiles.map((file, fileIndex)=>{
1808
1805
  let fileName = file.name;
@@ -2292,4 +2289,199 @@ const CarouselItem = ({ className, children, id })=>{
2292
2289
  });
2293
2290
  };
2294
2291
 
2295
- export { Accordion, AccordionItem, Alertbox, Avatar, Backlink, Badge, Breadcrumb, Breadcrumbs, Button, ButtonContext, Caption, Card, CardLink, Checkbox, CheckboxGroup, Combobox, ListBoxHeader as ComboboxHeader, ListBoxItem as ComboboxItem, ListBoxSection as ComboboxSection, Content, ContentContext, DateFormatter, Description, DisclosureStateContext, ErrorMessage, Footer, GrunnmurenProvider, Heading, HeadingContext, Label, Media, MediaContext, NumberField, Radio, RadioGroup, Select, ListBoxHeader as SelectHeader, ListBoxItem as SelectItem, ListBoxSection as SelectSection, TextArea, TextField, Carousel as UNSAFE_Carousel, CarouselItem as UNSAFE_CarouselItem, CarouselItems as UNSAFE_CarouselItems, Dialog as UNSAFE_Dialog, DialogTrigger as UNSAFE_DialogTrigger, Disclosure as UNSAFE_Disclosure, DisclosureButton as UNSAFE_DisclosureButton, DisclosurePanel as UNSAFE_DisclosurePanel, FileUpload as UNSAFE_FileUpload, Hero as UNSAFE_Hero, Modal as UNSAFE_Modal, Tag as UNSAFE_Tag, TagGroup as UNSAFE_TagGroup, TagList as UNSAFE_TagList, VideoLoop, _useLocale as useLocale };
2292
+ const tabsVariants = cva({
2293
+ base: [
2294
+ 'grid gap-4'
2295
+ ],
2296
+ variants: {
2297
+ orientation: {
2298
+ horizontal: '',
2299
+ vertical: 'grid-cols-[auto_1fr]'
2300
+ }
2301
+ }
2302
+ });
2303
+ /**
2304
+ * A container component that organizes content into multiple sections
2305
+ * and allows users to navigate between them.
2306
+ */ function Tabs(props) {
2307
+ const { className, children, orientation = 'horizontal', ...restProps } = props;
2308
+ return /*#__PURE__*/ jsx(Tabs$1, {
2309
+ ...restProps,
2310
+ orientation: orientation,
2311
+ className: tabsVariants({
2312
+ className,
2313
+ orientation
2314
+ }),
2315
+ children: children
2316
+ });
2317
+ }
2318
+ /**
2319
+ * A container component for Tab components within Tabs.
2320
+ */ function TabList({ className, children, ...restProps }) {
2321
+ const scrollContainerRef = useRef(null);
2322
+ const [canScrollLeft, setCanScrollLeft] = useState(false);
2323
+ const [canScrollRight, setCanScrollRight] = useState(false);
2324
+ const checkScrollOverflow = useCallback(()=>{
2325
+ const container = scrollContainerRef.current;
2326
+ if (!container) return;
2327
+ const { scrollLeft, scrollWidth, clientWidth } = container;
2328
+ setCanScrollLeft(scrollLeft > 0);
2329
+ setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 1);
2330
+ }, []);
2331
+ const state = useContext(TabListStateContext);
2332
+ const prevKey = state?.selectedKey && state?.collection.getKeyBefore(state.selectedKey);
2333
+ const onPrev = prevKey ? ()=>state?.setSelectedKey(prevKey) : ()=>{
2334
+ if (canScrollLeft && state?.selectedKey === state?.collection.firstKey) {
2335
+ // Scroll to the start of the tab list if we are at the first tab but it is scrolled out of view
2336
+ scrollContainerRef.current?.scrollTo({
2337
+ left: 0,
2338
+ behavior: 'smooth'
2339
+ });
2340
+ }
2341
+ };
2342
+ const nextKey = state?.selectedKey && state?.collection.getKeyAfter(state.selectedKey);
2343
+ const onNext = nextKey ? ()=>state?.setSelectedKey(nextKey) : ()=>{
2344
+ if (canScrollRight && state?.selectedKey === state?.collection.lastKey) {
2345
+ // Scroll to the end of the tab list if we are at the last tab but it is scrolled out of view
2346
+ scrollContainerRef.current?.scrollTo({
2347
+ left: scrollContainerRef.current.scrollWidth,
2348
+ behavior: 'smooth'
2349
+ });
2350
+ }
2351
+ };
2352
+ // To controll if the animation for the scroll buttons and the scrolling behavior
2353
+ // This is used to prevent animations from running when the component mounts
2354
+ // We use a ref here to prevent redundant render cycles and potentially uninteded scrolling.
2355
+ const hasScrollingOccurredRef = useRef(false);
2356
+ // Debounce the scroll handler to avoid performance issues with frequent scroll events
2357
+ const scrollHandler = useDebouncedCallback(()=>{
2358
+ checkScrollOverflow();
2359
+ hasScrollingOccurredRef.current = true;
2360
+ }, 100);
2361
+ useEffect(()=>{
2362
+ const container = scrollContainerRef.current;
2363
+ if (!container) return;
2364
+ checkScrollOverflow();
2365
+ container.addEventListener('scroll', scrollHandler);
2366
+ const resizeObserver = new ResizeObserver(checkScrollOverflow);
2367
+ resizeObserver.observe(container);
2368
+ return ()=>{
2369
+ container.removeEventListener('scroll', scrollHandler);
2370
+ resizeObserver.disconnect();
2371
+ };
2372
+ }, [
2373
+ checkScrollOverflow,
2374
+ scrollHandler
2375
+ ]);
2376
+ // Scroll to the selected tab when the selected key changes
2377
+ // We use the state.selectedItem here instead of just the state.selectedKey, since state.selectedItem is set when the tab list is mounted
2378
+ // This way we can make sure the default selected tab is scrolled into view.
2379
+ useEffect(()=>{
2380
+ const container = scrollContainerRef.current;
2381
+ if (!container) return;
2382
+ const selectedKey = state?.selectedItem?.key;
2383
+ if (!selectedKey) return;
2384
+ // Scroll to the selected tab when it changes
2385
+ const selectedTab = container.querySelector(`[data-key="${selectedKey}"]`);
2386
+ if (!selectedTab) return;
2387
+ const offsetLeft = selectedTab.offsetLeft;
2388
+ const containerWidth = container.clientWidth;
2389
+ // Set the scroll position to try and ish center the selected tab
2390
+ const scrollLeft = offsetLeft - (containerWidth - selectedTab.clientWidth) / 2;
2391
+ // When the scroll is initiated by the user we want a smooth scroll
2392
+ if (hasScrollingOccurredRef.current) {
2393
+ // The RAC TabList component prevents us from using scroll snapping, so by using requestAnimationFrame, we can ensure the scroll position is set correctly.
2394
+ // We want the active tab to be centered in the view when navigating with the scroll buttons, selecting a tab with the keyboard, or clicking on a tab.
2395
+ requestAnimationFrame(()=>{
2396
+ container.scrollTo({
2397
+ left: scrollLeft,
2398
+ behavior: 'smooth'
2399
+ });
2400
+ });
2401
+ } else {
2402
+ // When the scroll is done to ensure the default selected tab is in view, we want instant scrolling
2403
+ container.scrollTo({
2404
+ left: scrollLeft,
2405
+ behavior: 'instant'
2406
+ });
2407
+ }
2408
+ }, [
2409
+ state?.selectedItem
2410
+ ]);
2411
+ return /*#__PURE__*/ jsxs("div", {
2412
+ className: "relative overflow-hidden",
2413
+ children: [
2414
+ /*#__PURE__*/ jsx(TabList$1, {
2415
+ ...restProps,
2416
+ ref: scrollContainerRef,
2417
+ "data-scroll-animation": false,
2418
+ className: cx(className, 'group/tablist', // Ensure the tab list is scrollable
2419
+ 'scrollbar-hidden overflow-x-auto', 'flex w-fit max-w-full', // Ensure tabs don't shrink and maintain min-width
2420
+ '[&>*]:min-w-fit [&>*]:flex-shrink-0', // Divider line
2421
+ 'border-gray-light', 'data-[orientation=horizontal]:border-b', 'data-[orientation=vertical]:border-r', // Selection highlight based on orientation
2422
+ 'data-[orientation=horizontal]:*:border-y-2', 'data-[orientation=horizontal]:*:data-selected:border-b-blue-dark', 'data-[orientation=vertical]:*:border-r-2', 'data-[orientation=vertical]:*:data-selected:border-r-blue-dark', // Flex direction based on orientation
2423
+ 'data-[orientation=vertical]:flex-col'),
2424
+ style: {
2425
+ WebkitOverflowScrolling: 'touch'
2426
+ },
2427
+ children: children
2428
+ }),
2429
+ // biome-ignore lint/a11y/useKeyWithClickEvents: These are just for scrolling, and not necessary for keyboard or screen reader users. They can use the tablist's keyboard navigation pattern to navigate the entire list the same way.
2430
+ /*#__PURE__*/ jsx("div", {
2431
+ onClick: onPrev,
2432
+ className: cx('cursor-pointer', 'flex items-center', // Ensure click are of 44px by 44px.
2433
+ 'size-11', // Position the button at the left of the tab list, with a small (left) offset to avoid overlap with the tabs.
2434
+ // The bottom offset is to avoid overlap with the tab lists bottom border.
2435
+ '-left-3 absolute bottom-0.25', // Creates a gradient background that fades to transparent on the right side, which creates a smooth overlay effect over the tabs that are scrolled out of view.
2436
+ 'bg-[linear-gradient(90deg,white,white_calc(100%-10px),transparent)]', // Slide in and out based on scroll position, match duration with the debounce delay of the scrollHandler function
2437
+ // Wait until user started scrolling until animation is applied, to prevent the animation from running on mount
2438
+ hasScrollingOccurredRef.current && 'duration-100 ease-in motion-safe:transition-transform', !canScrollLeft && '-translate-x-full pointer-events-none'),
2439
+ children: /*#__PURE__*/ jsx(ChevronLeft, {
2440
+ className: "mt-0.25 h-6 w-full text-black"
2441
+ })
2442
+ }),
2443
+ // biome-ignore lint/a11y/useKeyWithClickEvents: These are just for scrolling, and not necessary for keyboard or screen reader users. They can use the tablist's keyboard navigation pattern to navigate the entire list the same way.
2444
+ /*#__PURE__*/ jsx("div", {
2445
+ onClick: onNext,
2446
+ className: cx('cursor-pointer', 'flex items-center', // Ensure click are of 44px by 44px.
2447
+ 'size-11', // Position the button at the right of the tab list, with a small (right) offset to avoid overlap with the tabs.
2448
+ // The bottom offset is to avoid overlap with the tab lists bottom border.
2449
+ '-right-3 absolute bottom-0.25', // Creates a gradient background that fades to transparent on the left side, which creates a smooth overlay effect over the tabs that are scrolled out of view.
2450
+ 'bg-[linear-gradient(90deg,transparent,white_calc(10px),white)]', // Slide in and out based on scroll position, match duration with the debounce delay of the scrollHandler function
2451
+ // Wait until user started scrolling until animation is applied, to prevent the animation from running on mount
2452
+ hasScrollingOccurredRef.current && 'duration-100 ease-in motion-safe:transition-transform', !canScrollRight && 'pointer-events-none translate-x-full'),
2453
+ children: /*#__PURE__*/ jsx(ChevronRight, {
2454
+ className: "mt-0.25 h-6 w-full text-black "
2455
+ })
2456
+ })
2457
+ ]
2458
+ });
2459
+ }
2460
+ /**
2461
+ * An individual tab that can be selected to display its associated content.
2462
+ */ function Tab(props) {
2463
+ const { className, children, ...restProps } = props;
2464
+ return /*#__PURE__*/ jsx(Tab$1, {
2465
+ ...restProps,
2466
+ className: cx(className, 'data-focus-visible:-outline-offset-10 data-focus-visible:outline-2 data-focus-visible:outline-black', 'cursor-pointer border-transparent px-4 py-2 font-light text-sm', // Transition
2467
+ 'transition-colors duration-150 ease-out', // TODO: Should disabled tabs just be hidden?
2468
+ 'data-disabled:cursor-not-allowed data-disabled:opacity-50', // Selection
2469
+ 'data-selected:font-medium data-selected:text-blue-dark', // Hover with layout shift prevention using pseudo-element
2470
+ 'after:invisible after:block after:h-0 after:overflow-hidden after:font-medium after:content-[attr(data-text)]', 'data-hovered:font-medium', // Pressed
2471
+ 'data-pressed:font-medium data-pressed:text-blue-dark'),
2472
+ "data-text": typeof children === 'string' ? children : '',
2473
+ children: children
2474
+ });
2475
+ }
2476
+ /**
2477
+ * The content area that displays the selected tab's content.
2478
+ */ function TabPanel(props) {
2479
+ const { className, children, ...restProps } = props;
2480
+ return /*#__PURE__*/ jsx(TabPanel$1, {
2481
+ ...restProps,
2482
+ className: cx(className, 'flex-1 data-focus-visible:outline-focus-offset'),
2483
+ children: children
2484
+ });
2485
+ }
2486
+
2487
+ export { Accordion, AccordionItem, Alertbox, Avatar, Backlink, Badge, Breadcrumb, Breadcrumbs, Button, ButtonContext, Caption, Card, CardLink, Checkbox, CheckboxGroup, Combobox, ListBoxHeader as ComboboxHeader, ListBoxItem as ComboboxItem, ListBoxSection as ComboboxSection, Content, ContentContext, DateFormatter, Description, DisclosureStateContext, ErrorMessage, Footer, GrunnmurenProvider, Heading, HeadingContext, Label, Media, MediaContext, NumberField, Radio, RadioGroup, Select, ListBoxHeader as SelectHeader, ListBoxItem as SelectItem, ListBoxSection as SelectSection, TextArea, TextField, Carousel as UNSAFE_Carousel, CarouselItem as UNSAFE_CarouselItem, CarouselItems as UNSAFE_CarouselItems, Dialog as UNSAFE_Dialog, DialogTrigger as UNSAFE_DialogTrigger, Disclosure as UNSAFE_Disclosure, DisclosureButton as UNSAFE_DisclosureButton, DisclosurePanel as UNSAFE_DisclosurePanel, FileUpload as UNSAFE_FileUpload, Hero as UNSAFE_Hero, Modal as UNSAFE_Modal, Tab as UNSAFE_Tab, TabList as UNSAFE_TabList, TabPanel as UNSAFE_TabPanel, Tabs as UNSAFE_Tabs, Tag as UNSAFE_Tag, TagGroup as UNSAFE_TagGroup, TagList as UNSAFE_TagList, VideoLoop, _useLocale as useLocale };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obosbbl/grunnmuren-react",
3
- "version": "2.3.4",
3
+ "version": "3.0.1",
4
4
  "description": "Grunnmuren components in React",
5
5
  "repository": {
6
6
  "url": "https://github.com/code-obos/grunnmuren"