@helsenorge/designsystem-react 7.13.4 → 7.14.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.
- package/components/Tabs/TabList/TabItem.d.ts +13 -0
- package/components/Tabs/TabList/TabItem.js +45 -0
- package/components/Tabs/TabList/TabItem.js.map +1 -0
- package/components/Tabs/TabList/TabList.js +23 -50
- package/components/Tabs/TabList/TabList.js.map +1 -1
- package/components/Tabs/Tabs.d.ts +3 -0
- package/components/Tabs/Tabs.js +45 -39
- package/components/Tabs/Tabs.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TabProps } from '../Tab';
|
|
3
|
+
import { TabsColors } from '../Tabs';
|
|
4
|
+
interface TabItemProps {
|
|
5
|
+
tabProps: TabProps;
|
|
6
|
+
index: number;
|
|
7
|
+
color: TabsColors;
|
|
8
|
+
selectedTab: number;
|
|
9
|
+
tabRefs: React.MutableRefObject<React.RefObject<HTMLButtonElement>[] | null | undefined>;
|
|
10
|
+
onTabListClick: (index: number) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const TabItem: React.FC<TabItemProps>;
|
|
13
|
+
export default TabItem;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import a, { useRef as R, useEffect as E } from "react";
|
|
2
|
+
import T from "classnames";
|
|
3
|
+
import { useIsVisible as y } from "../../../hooks/useIsVisible.js";
|
|
4
|
+
import { palette as i } from "../../../theme/palette.js";
|
|
5
|
+
import { Icon as C } from "../../Icon/Icon.js";
|
|
6
|
+
import { IconSize as f } from "../../../constants.js";
|
|
7
|
+
import { LazyIcon as z } from "../../LazyIcon/LazyIcon.js";
|
|
8
|
+
import l from "../../Tabs/TabList/styles.module.scss";
|
|
9
|
+
const w = (e) => {
|
|
10
|
+
const t = e.index === e.selectedTab, { title: d, onTabClick: o, icon: n, testId: u } = e.tabProps, _ = () => {
|
|
11
|
+
o && o(e.index), e.onTabListClick(e.index), s(e.index);
|
|
12
|
+
}, x = T(l["tab-list__tab"], l[`tab-list__tab--${e.color}`], {
|
|
13
|
+
[l["tab-list__tab--selected"]]: t,
|
|
14
|
+
[l["tab-list__tab--first"]]: e.index == 0
|
|
15
|
+
}), I = e.tabRefs.current && e.tabRefs.current[e.index], s = (k) => {
|
|
16
|
+
var m;
|
|
17
|
+
const c = e.tabRefs.current && e.tabRefs.current[k];
|
|
18
|
+
(m = c == null ? void 0 : c.current) == null || m.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest" });
|
|
19
|
+
}, r = R(null), b = y(r);
|
|
20
|
+
return E(() => {
|
|
21
|
+
t && b && s(e.index);
|
|
22
|
+
}, [t && b]), /* @__PURE__ */ a.createElement("li", { role: "presentation", ref: r }, /* @__PURE__ */ a.createElement(
|
|
23
|
+
"button",
|
|
24
|
+
{
|
|
25
|
+
role: "tab",
|
|
26
|
+
"aria-selected": t,
|
|
27
|
+
onClick: _,
|
|
28
|
+
className: x,
|
|
29
|
+
"data-testid": u,
|
|
30
|
+
ref: I
|
|
31
|
+
},
|
|
32
|
+
/* @__PURE__ */ a.createElement("span", { className: l["tab-list__tab__title-and-icon"] }, n && (typeof n == "string" ? /* @__PURE__ */ a.createElement(
|
|
33
|
+
z,
|
|
34
|
+
{
|
|
35
|
+
iconName: n,
|
|
36
|
+
size: f.XSmall,
|
|
37
|
+
color: t ? i.black : i.blueberry500
|
|
38
|
+
}
|
|
39
|
+
) : /* @__PURE__ */ a.createElement(C, { svgIcon: n, size: f.XSmall, color: t ? i.black : i.blueberry500 })), d)
|
|
40
|
+
));
|
|
41
|
+
};
|
|
42
|
+
export {
|
|
43
|
+
w as default
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=TabItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabItem.js","sources":["../../../../src/components/Tabs/TabList/TabItem.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport { useIsVisible } from '../../../hooks/useIsVisible';\nimport { palette } from '../../../theme/palette';\nimport Icon, { IconSize } from '../../Icon';\nimport { IconName } from '../../Icons/IconNames';\nimport LazyIcon from '../../LazyIcon';\nimport { TabProps } from '../Tab';\nimport { TabsColors } from '../Tabs';\n\nimport styles from './styles.module.scss';\n\ninterface TabItemProps {\n tabProps: TabProps;\n index: number;\n color: TabsColors;\n selectedTab: number;\n tabRefs: React.MutableRefObject<React.RefObject<HTMLButtonElement>[] | null | undefined>;\n onTabListClick: (index: number) => void;\n}\n\nconst TabItem: React.FC<TabItemProps> = props => {\n const isSelected = props.index === props.selectedTab;\n const { title, onTabClick, icon, testId } = props.tabProps;\n const handleClick = (): void => {\n onTabClick && onTabClick(props.index);\n props.onTabListClick(props.index);\n scrollToTab(props.index);\n };\n const tabButtonClasses = classNames(styles['tab-list__tab'], styles[`tab-list__tab--${props.color}`], {\n [styles['tab-list__tab--selected']]: isSelected,\n [styles['tab-list__tab--first']]: props.index == 0,\n });\n\n const currentRef = props.tabRefs.current && props.tabRefs.current[props.index];\n\n const scrollToTab = (index: number): void => {\n const currentRef = props.tabRefs.current && props.tabRefs.current[index];\n currentRef?.current?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' });\n };\n\n const itemRef = useRef<HTMLLIElement>(null);\n const isVisible = useIsVisible(itemRef);\n\n useEffect(() => {\n if (isSelected && isVisible) {\n scrollToTab(props.index);\n }\n }, [isSelected && isVisible]);\n\n return (\n <li role=\"presentation\" ref={itemRef}>\n <button\n role=\"tab\"\n aria-selected={isSelected}\n onClick={handleClick}\n className={tabButtonClasses}\n data-testid={testId}\n ref={currentRef as React.RefObject<HTMLButtonElement>}\n >\n <span className={styles['tab-list__tab__title-and-icon']}>\n {icon &&\n (typeof icon === 'string' ? (\n <LazyIcon\n iconName={icon as IconName}\n size={IconSize.XSmall}\n color={isSelected ? palette[`black`] : palette['blueberry500']}\n />\n ) : (\n <Icon svgIcon={icon} size={IconSize.XSmall} color={isSelected ? palette[`black`] : palette['blueberry500']} />\n ))}\n {title}\n </span>\n </button>\n </li>\n );\n};\n\nexport default TabItem;\n"],"names":["TabItem","props","isSelected","title","onTabClick","icon","testId","handleClick","scrollToTab","tabButtonClasses","classNames","styles","currentRef","index","itemRef","useRef","isVisible","useIsVisible","useEffect","React","LazyIcon","IconSize","palette","Icon"],"mappings":";;;;;;;;AAuBA,MAAMA,IAAkC,CAASC,MAAA;AACzC,QAAAC,IAAaD,EAAM,UAAUA,EAAM,aACnC,EAAE,OAAAE,GAAO,YAAAC,GAAY,MAAAC,GAAM,QAAAC,MAAWL,EAAM,UAC5CM,IAAc,MAAY;AAChB,IAAAH,KAAAA,EAAWH,EAAM,KAAK,GAC9BA,EAAA,eAAeA,EAAM,KAAK,GAChCO,EAAYP,EAAM,KAAK;AAAA,EAAA,GAEnBQ,IAAmBC,EAAWC,EAAO,eAAe,GAAGA,EAAO,kBAAkBV,EAAM,KAAK,EAAE,GAAG;AAAA,IACpG,CAACU,EAAO,yBAAyB,CAAC,GAAGT;AAAA,IACrC,CAACS,EAAO,sBAAsB,CAAC,GAAGV,EAAM,SAAS;AAAA,EAAA,CAClD,GAEKW,IAAaX,EAAM,QAAQ,WAAWA,EAAM,QAAQ,QAAQA,EAAM,KAAK,GAEvEO,IAAc,CAACK,MAAwB;;AAC3C,UAAMD,IAAaX,EAAM,QAAQ,WAAWA,EAAM,QAAQ,QAAQY,CAAK;AACvED,KAAAA,IAAAA,KAAAA,gBAAAA,EAAY,YAAZA,QAAAA,EAAqB,eAAe,EAAE,UAAU,UAAU,QAAQ,UAAU,OAAO,UAAA;AAAA,EAAW,GAG1FE,IAAUC,EAAsB,IAAI,GACpCC,IAAYC,EAAaH,CAAO;AAEtC,SAAAI,EAAU,MAAM;AACd,IAAIhB,KAAcc,KAChBR,EAAYP,EAAM,KAAK;AAAA,EACzB,GACC,CAACC,KAAcc,CAAS,CAAC,GAGzBG,gBAAAA,EAAA,cAAA,MAAA,EAAG,MAAK,gBAAe,KAAKL,KAC3BK,gBAAAA,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,iBAAejB;AAAA,MACf,SAASK;AAAA,MACT,WAAWE;AAAA,MACX,eAAaH;AAAA,MACb,KAAKM;AAAA,IAAA;AAAA,IAELO,gBAAAA,EAAA,cAAC,UAAK,WAAWR,EAAO,+BAA+B,EACpD,GAAAN,MACE,OAAOA,KAAS,WACfc,gBAAAA,EAAA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,UAAUf;AAAA,QACV,MAAMgB,EAAS;AAAA,QACf,OAAOnB,IAAaoB,EAAQ,QAAWA,EAAQ;AAAA,MAAc;AAAA,IAAA,IAG9DH,gBAAAA,EAAA,cAAAI,GAAA,EAAK,SAASlB,GAAM,MAAMgB,EAAS,QAAQ,OAAOnB,IAAaoB,EAAQ,QAAWA,EAAQ,aAAc,CAAG,IAE/GnB,CACH;AAAA,EAAA,CAEJ;AAEJ;"}
|
|
@@ -1,55 +1,28 @@
|
|
|
1
|
-
import t, { useRef as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { useRovingFocus as
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
[o["tab-list__tab--first"]]: e == 0
|
|
23
|
-
}), $ = r.current && r.current[e], u = (g) => {
|
|
24
|
-
var _;
|
|
25
|
-
const c = r.current && r.current[g];
|
|
26
|
-
(_ = c == null ? void 0 : c.current) == null || _.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest" });
|
|
27
|
-
};
|
|
28
|
-
return s && R && u(e), /* @__PURE__ */ t.createElement("li", { role: "presentation", key: `${n}` }, /* @__PURE__ */ t.createElement(
|
|
29
|
-
"button",
|
|
30
|
-
{
|
|
31
|
-
role: "tab",
|
|
32
|
-
"aria-selected": s,
|
|
33
|
-
onClick: N,
|
|
34
|
-
className: S,
|
|
35
|
-
key: `${n}`,
|
|
36
|
-
"data-testid": z,
|
|
37
|
-
ref: $
|
|
38
|
-
},
|
|
39
|
-
/* @__PURE__ */ t.createElement("span", { className: o["tab-list__tab__title-and-icon"] }, l && (typeof l == "string" ? /* @__PURE__ */ t.createElement(
|
|
40
|
-
X,
|
|
41
|
-
{
|
|
42
|
-
iconName: l,
|
|
43
|
-
size: y.XSmall,
|
|
44
|
-
color: s ? a.black : a.blueberry500
|
|
45
|
-
}
|
|
46
|
-
) : /* @__PURE__ */ t.createElement(w, { svgIcon: l, size: y.XSmall, color: s ? a.black : a.blueberry500 })), n)
|
|
47
|
-
));
|
|
1
|
+
import t, { useRef as l } from "react";
|
|
2
|
+
import b from "classnames";
|
|
3
|
+
import R from "./TabItem.js";
|
|
4
|
+
import { useRovingFocus as C } from "../../../hooks/useRovingFocus.js";
|
|
5
|
+
import { isComponent as T } from "../../../utils/component.js";
|
|
6
|
+
import d from "../Tab.js";
|
|
7
|
+
import i from "../../Tabs/TabList/styles.module.scss";
|
|
8
|
+
const g = (m) => {
|
|
9
|
+
const { selectedTab: n, onTabListClick: r, children: o, color: p = "white", type: f = "normal" } = m, s = l(null), a = l(t.Children.map(o, () => t.createRef()));
|
|
10
|
+
C(r, a, s, !0);
|
|
11
|
+
const c = b(i["tab-list"], i[`tab-list--${f}`]);
|
|
12
|
+
return /* @__PURE__ */ t.createElement("ul", { className: c, ref: s, role: "tablist", "aria-orientation": "horizontal" }, t.Children.map(o, (e, u) => T(e, d) ? /* @__PURE__ */ t.createElement(
|
|
13
|
+
R,
|
|
14
|
+
{
|
|
15
|
+
tabRefs: a,
|
|
16
|
+
key: e.props.title,
|
|
17
|
+
index: u,
|
|
18
|
+
selectedTab: n,
|
|
19
|
+
onTabListClick: r,
|
|
20
|
+
tabProps: e.props,
|
|
21
|
+
color: p
|
|
48
22
|
}
|
|
49
|
-
|
|
50
|
-
}));
|
|
23
|
+
) : null));
|
|
51
24
|
};
|
|
52
25
|
export {
|
|
53
|
-
|
|
26
|
+
g as default
|
|
54
27
|
};
|
|
55
28
|
//# sourceMappingURL=TabList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.js","sources":["../../../../src/components/Tabs/TabList/TabList.tsx"],"sourcesContent":["import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport
|
|
1
|
+
{"version":3,"file":"TabList.js","sources":["../../../../src/components/Tabs/TabList/TabList.tsx"],"sourcesContent":["import React, { useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport TabItem from './TabItem';\nimport { useRovingFocus } from '../../../hooks/useRovingFocus';\nimport { isComponent } from '../../../utils/component';\nimport Tab, { TabProps } from '../Tab';\nimport { TabsColors, TabsType } from '../Tabs';\n\nimport styles from './styles.module.scss';\ninterface TabListProps {\n children: React.ReactNode;\n onTabListClick: (index: number) => void;\n selectedTab: number;\n color?: TabsColors;\n type?: TabsType;\n}\n\nconst TabList: React.FC<TabListProps> = props => {\n const { selectedTab, onTabListClick, children, color = 'white', type = 'normal' } = props;\n\n const listRef = useRef<HTMLUListElement>(null);\n\n const tabRefs = useRef(React.Children.map(children, () => React.createRef<HTMLButtonElement>()));\n useRovingFocus(onTabListClick, tabRefs, listRef, true);\n\n const tablistClasses = classNames(styles['tab-list'], styles[`tab-list--${type}`]);\n\n return (\n <ul className={tablistClasses} ref={listRef} role=\"tablist\" aria-orientation=\"horizontal\">\n {React.Children.map(children, (child, index) => {\n if (isComponent<TabProps>(child, Tab)) {\n return (\n <TabItem\n tabRefs={tabRefs}\n key={child.props.title}\n index={index}\n selectedTab={selectedTab}\n onTabListClick={onTabListClick}\n tabProps={child.props}\n color={color}\n />\n );\n }\n return null;\n })}\n </ul>\n );\n};\n\nexport default TabList;\n"],"names":["TabList","props","selectedTab","onTabListClick","children","color","type","listRef","useRef","tabRefs","React","useRovingFocus","tablistClasses","classNames","styles","child","index","isComponent","Tab","TabItem"],"mappings":";;;;;;;AAmBA,MAAMA,IAAkC,CAASC,MAAA;AACzC,QAAA,EAAE,aAAAC,GAAa,gBAAAC,GAAgB,UAAAC,GAAU,OAAAC,IAAQ,SAAS,MAAAC,IAAO,SAAa,IAAAL,GAE9EM,IAAUC,EAAyB,IAAI,GAEvCC,IAAUD,EAAOE,EAAM,SAAS,IAAIN,GAAU,MAAMM,EAAM,UAA8B,CAAA,CAAC;AAChF,EAAAC,EAAAR,GAAgBM,GAASF,GAAS,EAAI;AAE/C,QAAAK,IAAiBC,EAAWC,EAAO,UAAU,GAAGA,EAAO,aAAaR,CAAI,EAAE,CAAC;AAEjF,yCACG,MAAG,EAAA,WAAWM,GAAgB,KAAKL,GAAS,MAAK,WAAU,oBAAiB,aAAA,GAC1EG,EAAM,SAAS,IAAIN,GAAU,CAACW,GAAOC,MAChCC,EAAsBF,GAAOG,CAAG,IAEhCR,gBAAAA,EAAA;AAAA,IAACS;AAAA,IAAA;AAAA,MACC,SAAAV;AAAA,MACA,KAAKM,EAAM,MAAM;AAAA,MACjB,OAAAC;AAAA,MACA,aAAAd;AAAA,MACA,gBAAAC;AAAA,MACA,UAAUY,EAAM;AAAA,MAChB,OAAAV;AAAA,IAAA;AAAA,EAAA,IAIC,IACR,CACH;AAEJ;"}
|
|
@@ -4,6 +4,7 @@ import { PaletteNames } from '../../theme/palette';
|
|
|
4
4
|
export type { TabProps } from './Tab';
|
|
5
5
|
export type TabsColors = Extract<PaletteNames, 'blueberry' | 'neutral' | 'white'>;
|
|
6
6
|
export type TabsType = 'normal' | 'framed';
|
|
7
|
+
export type TabsTouchBehaviour = 'swipe' | 'none';
|
|
7
8
|
export interface TabsProps {
|
|
8
9
|
/** Controlled state for Tabs component */
|
|
9
10
|
activeTab?: number;
|
|
@@ -13,6 +14,8 @@ export interface TabsProps {
|
|
|
13
14
|
color?: TabsColors;
|
|
14
15
|
/** Whether the tab list should be sticky */
|
|
15
16
|
sticky?: boolean;
|
|
17
|
+
/** Determines how Tabs respons to touch events. */
|
|
18
|
+
touchBehaviour?: TabsTouchBehaviour;
|
|
16
19
|
/** Sets the data-testid attribute. */
|
|
17
20
|
testId?: string;
|
|
18
21
|
/** Sets the visual type of the tabs */
|
package/components/Tabs/Tabs.js
CHANGED
|
@@ -1,53 +1,59 @@
|
|
|
1
|
-
import r, { useState as c, useRef as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import { isMobileUA as z } from "../../utils/mobile.js";
|
|
1
|
+
import r, { useState as c, useRef as E, useEffect as C } from "react";
|
|
2
|
+
import S from "classnames";
|
|
3
|
+
import j from "./Tab.js";
|
|
4
|
+
import q from "./TabList/TabList.js";
|
|
5
|
+
import z from "./TabPanel/TabPanel.js";
|
|
6
|
+
import { isMobileUA as G } from "../../utils/mobile.js";
|
|
8
7
|
import l from "../Tabs/styles.module.scss";
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
const H = 75, J = ({
|
|
9
|
+
activeTab: w,
|
|
10
|
+
children: m,
|
|
11
|
+
className: M,
|
|
12
|
+
color: f = "white",
|
|
13
|
+
sticky: N = !0,
|
|
14
|
+
testId: g,
|
|
15
|
+
type: u = "normal",
|
|
16
|
+
touchBehaviour: L = "swipe"
|
|
17
|
+
}) => {
|
|
18
|
+
const X = w !== void 0, [x, y] = c(0), [d, D] = c(0), [p, P] = c(0), [k, a] = c(0), [U, h] = c(null), R = G(), n = E(null), s = E(null), _ = E(null), T = (t, o) => {
|
|
19
|
+
X || (y(t), t > o ? (a(0), I()) : t < o && (a(0), F()));
|
|
14
20
|
}, F = () => {
|
|
15
|
-
|
|
21
|
+
R && h("right");
|
|
16
22
|
}, I = () => {
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
|
|
23
|
+
R && h("left");
|
|
24
|
+
}, $ = () => {
|
|
25
|
+
h(null);
|
|
26
|
+
}, e = X ? w : x;
|
|
27
|
+
return C(() => {
|
|
20
28
|
const t = (i) => {
|
|
21
|
-
k(i.touches[0].clientX);
|
|
22
|
-
}, o = (i) => {
|
|
23
29
|
D(i.touches[0].clientX);
|
|
30
|
+
}, o = (i) => {
|
|
31
|
+
P(i.touches[0].clientX);
|
|
24
32
|
const b = i.touches[0].clientX - d;
|
|
25
33
|
e === 0 && b > 0 || e === r.Children.count(m) - 1 && b < 0 ? a(0) : a(b);
|
|
26
|
-
},
|
|
27
|
-
Math.abs(
|
|
34
|
+
}, A = () => {
|
|
35
|
+
Math.abs(p - d) >= H && (p > d ? T(Math.max(0, e - 1), e) : T(Math.min(r.Children.count(m) - 1, e + 1), e)), a(0);
|
|
28
36
|
};
|
|
29
|
-
return n.current && (n.current.addEventListener("touchstart", t), n.current.addEventListener("touchmove", o), n.current.addEventListener("touchend",
|
|
30
|
-
n.current && (n.current.removeEventListener("touchstart", t), n.current.removeEventListener("touchmove", o), n.current.removeEventListener("touchend",
|
|
37
|
+
return L === "swipe" && n.current && (n.current.addEventListener("touchstart", t), n.current.addEventListener("touchmove", o), n.current.addEventListener("touchend", A)), () => {
|
|
38
|
+
n.current && (n.current.removeEventListener("touchstart", t), n.current.removeEventListener("touchmove", o), n.current.removeEventListener("touchend", A));
|
|
31
39
|
};
|
|
32
|
-
}, [d,
|
|
40
|
+
}, [L, d, p, e]), C(() => {
|
|
33
41
|
const t = () => {
|
|
34
|
-
|
|
42
|
+
$();
|
|
35
43
|
};
|
|
36
44
|
return s.current && s.current.addEventListener("animationend", t), () => {
|
|
37
45
|
s.current && s.current.removeEventListener("animationend", t);
|
|
38
46
|
};
|
|
39
|
-
}, [])
|
|
40
|
-
const { isOutsideWindow: O } = q(R, n);
|
|
41
|
-
return /* @__PURE__ */ r.createElement("div", { className: M, "data-testid": g }, /* @__PURE__ */ r.createElement(
|
|
47
|
+
}, []), /* @__PURE__ */ r.createElement("div", { className: M, "data-testid": g }, /* @__PURE__ */ r.createElement(
|
|
42
48
|
"div",
|
|
43
49
|
{
|
|
44
|
-
ref:
|
|
45
|
-
className:
|
|
46
|
-
[l["tab-list-wrapper--sticky"]]: N
|
|
50
|
+
ref: _,
|
|
51
|
+
className: S(l["tab-list-wrapper"], {
|
|
52
|
+
[l["tab-list-wrapper--sticky"]]: N
|
|
47
53
|
})
|
|
48
54
|
},
|
|
49
55
|
/* @__PURE__ */ r.createElement(
|
|
50
|
-
|
|
56
|
+
q,
|
|
51
57
|
{
|
|
52
58
|
onTabListClick: (t) => T(t, e),
|
|
53
59
|
selectedTab: e,
|
|
@@ -59,28 +65,28 @@ const B = 75, G = ({ activeTab: L, children: m, className: M, color: f = "white"
|
|
|
59
65
|
/* @__PURE__ */ r.createElement(
|
|
60
66
|
"div",
|
|
61
67
|
{
|
|
62
|
-
className:
|
|
68
|
+
className: S(l["panel-wrapper"], l[`panel-wrapper--${f}`], {
|
|
63
69
|
[l["panel-wrapper--framed"]]: u == "framed"
|
|
64
70
|
})
|
|
65
71
|
}
|
|
66
72
|
)
|
|
67
73
|
), /* @__PURE__ */ r.createElement("div", { ref: n, style: { marginTop: u == "framed" ? "-40px" : "" } }, /* @__PURE__ */ r.createElement(
|
|
68
|
-
|
|
74
|
+
z,
|
|
69
75
|
{
|
|
70
76
|
ref: s,
|
|
71
77
|
color: f,
|
|
72
78
|
type: u,
|
|
73
79
|
isFirst: e == 0,
|
|
74
|
-
translateX:
|
|
80
|
+
translateX: k,
|
|
75
81
|
animate: U
|
|
76
82
|
},
|
|
77
83
|
r.Children.toArray(m)[e]
|
|
78
84
|
)));
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
}, v = J;
|
|
86
|
+
v.displayName = "Tabs";
|
|
87
|
+
v.Tab = j;
|
|
88
|
+
v.Tab.displayName = "Tabs.Tab";
|
|
83
89
|
export {
|
|
84
|
-
|
|
90
|
+
v as default
|
|
85
91
|
};
|
|
86
92
|
//# sourceMappingURL=Tabs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport Tab from './Tab';\nimport TabList from './TabList';\nimport TabPanel from './TabPanel';\nimport {
|
|
1
|
+
{"version":3,"file":"Tabs.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\n\nimport classNames from 'classnames';\n\nimport Tab from './Tab';\nimport TabList from './TabList';\nimport TabPanel from './TabPanel';\nimport { PaletteNames } from '../../theme/palette';\nimport { isMobileUA } from '../../utils/mobile';\n\nimport styles from './styles.module.scss';\n\nexport type { TabProps } from './Tab';\nexport type TabsColors = Extract<PaletteNames, 'blueberry' | 'neutral' | 'white'>;\nexport type TabsType = 'normal' | 'framed';\nexport type TabsTouchBehaviour = 'swipe' | 'none';\n\nexport interface TabsProps {\n /** Controlled state for Tabs component */\n activeTab?: number;\n /** Adds custom classes to the element. */\n className?: string;\n /** Sets the color of the tabs. Default: white */\n color?: TabsColors;\n /** Whether the tab list should be sticky */\n sticky?: boolean;\n /** Determines how Tabs respons to touch events. */\n touchBehaviour?: TabsTouchBehaviour;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the visual type of the tabs */\n type?: TabsType;\n}\n\nconst swipeDistanceThreshold = 75;\n\nconst TabsRoot: React.FC<TabsProps> = ({\n activeTab,\n children,\n className,\n color = 'white',\n sticky = true,\n testId,\n type = 'normal',\n touchBehaviour = 'swipe',\n}) => {\n const isControlled = activeTab !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(0);\n const [touchStartX, setTouchStartX] = useState(0);\n const [touchEndX, setTouchEndX] = useState(0);\n const [translateX, setTranslateX] = useState(0);\n const [panelAnimation, setPanelAnimation] = useState<'left' | 'right' | null>(null);\n const mobile = isMobileUA();\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabPanelRef = useRef<HTMLDivElement>(null);\n const tabListRef = useRef<HTMLDivElement>(null);\n\n const onValueChange = (newValue: number, oldValue: number): void => {\n if (!isControlled) {\n setUncontrolledValue(newValue);\n if (newValue > oldValue) {\n // make sure that the translateX is reset so the animation does not go outside the screen\n setTranslateX(0);\n onLeftSwipe();\n } else if (newValue < oldValue) {\n // make sure that the translateX is reset so the animation does not go outside the screen\n setTranslateX(0);\n onRightSwipe();\n }\n }\n };\n\n const onRightSwipe = (): void => {\n mobile && setPanelAnimation('right');\n };\n\n const onLeftSwipe = (): void => {\n mobile && setPanelAnimation('left');\n };\n\n const resetAnimation = (): void => {\n setPanelAnimation(null);\n };\n\n const activeTabIndex = isControlled ? activeTab : uncontrolledValue;\n\n useEffect(() => {\n const handleTouchStart = (event: TouchEvent): void => {\n setTouchStartX(event.touches[0].clientX);\n };\n\n const handleTouchMove = (event: TouchEvent): void => {\n setTouchEndX(event.touches[0].clientX);\n const newTranslateX = event.touches[0].clientX - touchStartX;\n\n if (activeTabIndex === 0 && newTranslateX > 0) {\n setTranslateX(0);\n } else if (activeTabIndex === React.Children.count(children) - 1 && newTranslateX < 0) {\n setTranslateX(0);\n } else {\n setTranslateX(newTranslateX);\n }\n };\n\n const handleTouchEnd = (): void => {\n const swipeDistance = Math.abs(touchEndX - touchStartX);\n if (swipeDistance >= swipeDistanceThreshold) {\n if (touchEndX > touchStartX) {\n // User swiped right\n onValueChange(Math.max(0, activeTabIndex - 1), activeTabIndex);\n } else {\n // User swiped left\n onValueChange(Math.min(React.Children.count(children) - 1, activeTabIndex + 1), activeTabIndex);\n }\n }\n setTranslateX(0);\n };\n\n if (touchBehaviour === 'swipe' && tabsRef.current) {\n tabsRef.current.addEventListener('touchstart', handleTouchStart);\n tabsRef.current.addEventListener('touchmove', handleTouchMove);\n tabsRef.current.addEventListener('touchend', handleTouchEnd);\n }\n return () => {\n if (tabsRef.current) {\n tabsRef.current.removeEventListener('touchstart', handleTouchStart);\n tabsRef.current.removeEventListener('touchmove', handleTouchMove);\n tabsRef.current.removeEventListener('touchend', handleTouchEnd);\n }\n };\n }, [touchBehaviour, touchStartX, touchEndX, activeTabIndex]);\n\n useEffect(() => {\n const handleAnimationEnd = (): void => {\n resetAnimation();\n };\n\n if (tabPanelRef.current) {\n tabPanelRef.current.addEventListener('animationend', handleAnimationEnd);\n }\n\n return () => {\n if (tabPanelRef.current) {\n tabPanelRef.current.removeEventListener('animationend', handleAnimationEnd);\n }\n };\n }, []);\n\n return (\n <div className={className} data-testid={testId}>\n <div\n ref={tabListRef}\n className={classNames(styles['tab-list-wrapper'], {\n [styles['tab-list-wrapper--sticky']]: sticky,\n })}\n >\n <TabList\n onTabListClick={(index: number) => onValueChange(index, activeTabIndex)}\n selectedTab={activeTabIndex}\n color={color}\n type={type}\n >\n {children}\n </TabList>\n <div\n className={classNames(styles['panel-wrapper'], styles[`panel-wrapper--${color}`], {\n [styles['panel-wrapper--framed']]: type == 'framed',\n })}\n ></div>\n </div>\n <div ref={tabsRef} style={{ marginTop: type == 'framed' ? '-40px' : '' }}>\n <TabPanel\n ref={tabPanelRef}\n color={color}\n type={type}\n isFirst={activeTabIndex == 0}\n translateX={translateX}\n animate={panelAnimation}\n >\n {React.Children.toArray(children)[activeTabIndex]}\n </TabPanel>\n </div>\n </div>\n );\n};\n\ntype TabsComponent = typeof TabsRoot & {\n Tab: typeof Tab;\n};\nconst Tabs = TabsRoot as TabsComponent;\nTabs.displayName = 'Tabs';\nTabs.Tab = Tab;\nTabs.Tab.displayName = 'Tabs.Tab';\n\nexport default Tabs;\n"],"names":["swipeDistanceThreshold","TabsRoot","activeTab","children","className","color","sticky","testId","type","touchBehaviour","isControlled","uncontrolledValue","setUncontrolledValue","useState","touchStartX","setTouchStartX","touchEndX","setTouchEndX","translateX","setTranslateX","panelAnimation","setPanelAnimation","mobile","isMobileUA","tabsRef","useRef","tabPanelRef","tabListRef","onValueChange","newValue","oldValue","onLeftSwipe","onRightSwipe","resetAnimation","activeTabIndex","useEffect","handleTouchStart","event","handleTouchMove","newTranslateX","React","handleTouchEnd","handleAnimationEnd","classNames","styles","TabList","index","TabPanel","Tabs","Tab"],"mappings":"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"}
|