@helsenorge/designsystem-react 8.0.2 → 8.1.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/CHANGELOG.md +29 -0
- package/components/Close/styles.module.scss +5 -6
- package/components/ExpanderList/styles.module.scss +5 -6
- package/components/EyebrowHeader/styles.module.scss +1 -1
- package/components/EyebrowHeader/styles.module.scss.d.ts +9 -0
- package/components/FormGroup/styles.module.scss +2 -2
- package/components/HighlightPanel/styles.module.scss +5 -0
- package/components/HorizontalScroll/HorizontalScroll.js +16 -15
- package/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/components/Input/Input.d.ts +2 -0
- package/components/Input/Input.js +63 -51
- package/components/Input/Input.js.map +1 -1
- package/components/Input/styles.module.scss +2 -2
- package/components/Loader/Loader.d.ts +3 -3
- package/components/Loader/Loader.js +19 -20
- package/components/Loader/Loader.js.map +1 -1
- package/components/Loader/styles.module.scss +7 -7
- package/components/Modal/Modal.d.ts +1 -12
- package/components/Modal/Modal.js +81 -78
- package/components/Modal/Modal.js.map +1 -1
- package/components/Modal/styles.module.scss +3 -3
- package/components/Panel/styles.module.scss +2 -2
- package/components/PopOver/styles.module.scss +4 -5
- package/components/Table/styles.module.scss +3 -3
- 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/components/Validation/ValidationSummary.js +20 -12
- package/components/Validation/ValidationSummary.js.map +1 -1
- package/hooks/usestopPropagation.d.ts +6 -0
- package/hooks/usestopPropagation.js +15 -0
- package/hooks/usestopPropagation.js.map +1 -0
- package/package.json +1 -1
- package/utils/refs.d.ts +1 -1
- package/utils/refs.js +5 -5
- package/utils/refs.js.map +1 -1
|
@@ -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
|
children?: React.ReactNode;
|
|
9
10
|
/** Controlled state for Tabs component */
|
|
@@ -14,6 +15,8 @@ export interface TabsProps {
|
|
|
14
15
|
color?: TabsColors;
|
|
15
16
|
/** Whether the tab list should be sticky */
|
|
16
17
|
sticky?: boolean;
|
|
18
|
+
/** Determines how Tabs respons to touch events. */
|
|
19
|
+
touchBehaviour?: TabsTouchBehaviour;
|
|
17
20
|
/** Sets the data-testid attribute. */
|
|
18
21
|
testId?: string;
|
|
19
22
|
/** 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 { useSticky } from '../../hooks/useSticky';\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';\n\nexport interface TabsProps {\n children?: React.ReactNode;\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 /** 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> = ({ activeTab, children, className, color = 'white', sticky = true, testId, type = 'normal' }) => {\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 (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 }, [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 const { isOutsideWindow } = useSticky(tabListRef, tabsRef);\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 && isOutsideWindow,\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","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","isOutsideWindow","useSticky","classNames","styles","TabList","index","TabPanel","Tabs","Tab"],"mappings":"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"}
|
|
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 children?: React.ReactNode;\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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"}
|
|
@@ -1,17 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { useUuid as
|
|
5
|
-
import { Title as
|
|
6
|
-
import
|
|
7
|
-
const
|
|
8
|
-
const { errorTitleHtmlMarkup:
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import e from "react";
|
|
2
|
+
import o from "classnames";
|
|
3
|
+
import n from "./ErrorList.js";
|
|
4
|
+
import { useUuid as s } from "../../hooks/useUuid.js";
|
|
5
|
+
import { Title as c } from "../Title/Title.js";
|
|
6
|
+
import l from "../Validation/styles.module.scss";
|
|
7
|
+
const T = (r) => {
|
|
8
|
+
const { errorTitleHtmlMarkup: i = "h2" } = r, a = s(), t = !!r.errors && Object.entries(r.errors).length > 0, m = o(l.validation__summary, t && l["validation__summary--visible"]);
|
|
9
|
+
return /* @__PURE__ */ e.createElement(
|
|
10
|
+
"div",
|
|
11
|
+
{
|
|
12
|
+
role: "alert",
|
|
13
|
+
"aria-live": "polite",
|
|
14
|
+
"aria-relevant": "all",
|
|
15
|
+
"aria-labelledby": t && r.errorTitle ? a : void 0,
|
|
16
|
+
className: m
|
|
17
|
+
},
|
|
18
|
+
t && /* @__PURE__ */ e.createElement(e.Fragment, null, r.errorTitle && /* @__PURE__ */ e.createElement(c, { appearance: "title4", id: a, htmlMarkup: i, margin: { marginTop: 0, marginBottom: 1 } }, r.errorTitle), /* @__PURE__ */ e.createElement(n, { errors: r.errors })),
|
|
19
|
+
r.children
|
|
11
20
|
);
|
|
12
|
-
return /* @__PURE__ */ r.createElement("div", { role: "alert", "aria-live": "polite", "aria-relevant": "all", "aria-labelledby": t, className: i }, !!e.errors && Object.entries(e.errors).length > 0 && /* @__PURE__ */ r.createElement(r.Fragment, null, /* @__PURE__ */ r.createElement(s, { appearance: "title4", id: t, htmlMarkup: l, margin: { marginTop: 0, marginBottom: 1 } }, e.errorTitle), /* @__PURE__ */ r.createElement(o, { errors: e.errors })), e.children);
|
|
13
21
|
};
|
|
14
22
|
export {
|
|
15
|
-
|
|
23
|
+
T as default
|
|
16
24
|
};
|
|
17
25
|
//# sourceMappingURL=ValidationSummary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidationSummary.js","sources":["../../../src/components/Validation/ValidationSummary.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport ErrorList from './ErrorList';\nimport { ValidationErrors } from './types';\nimport { useUuid } from '../../hooks/useUuid';\nimport Title, { TitleTags } from '../Title';\n\nimport styles from './styles.module.scss';\n\ninterface ValidationSummaryProps {\n /** Error summary title */\n errorTitle?: string;\n /** Error list */\n errors?: ValidationErrors;\n /** Markup props for error summary title. Default: h2 */\n errorTitleHtmlMarkup?: TitleTags;\n /** Will be shown last */\n children?: React.ReactNode;\n}\n\nconst ValidationSummary: React.FC<ValidationSummaryProps> = props => {\n const { errorTitleHtmlMarkup = 'h2' } = props;\n const titleId = useUuid();\n\n const
|
|
1
|
+
{"version":3,"file":"ValidationSummary.js","sources":["../../../src/components/Validation/ValidationSummary.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport ErrorList from './ErrorList';\nimport { ValidationErrors } from './types';\nimport { useUuid } from '../../hooks/useUuid';\nimport Title, { TitleTags } from '../Title';\n\nimport styles from './styles.module.scss';\n\ninterface ValidationSummaryProps {\n /** Error summary title */\n errorTitle?: string;\n /** Error list */\n errors?: ValidationErrors;\n /** Markup props for error summary title. Default: h2 */\n errorTitleHtmlMarkup?: TitleTags;\n /** Will be shown last */\n children?: React.ReactNode;\n}\n\nconst ValidationSummary: React.FC<ValidationSummaryProps> = props => {\n const { errorTitleHtmlMarkup = 'h2' } = props;\n const titleId = useUuid();\n\n const hasErrors = !!props.errors && Object.entries(props.errors).length > 0;\n\n const summaryClasses = classNames(styles['validation__summary'], hasErrors && styles['validation__summary--visible']);\n\n return (\n <div\n role={'alert'}\n aria-live={'polite'}\n aria-relevant={'all'}\n aria-labelledby={hasErrors && props.errorTitle ? titleId : undefined}\n className={summaryClasses}\n >\n {hasErrors && (\n <>\n {props.errorTitle && (\n <Title appearance=\"title4\" id={titleId} htmlMarkup={errorTitleHtmlMarkup} margin={{ marginTop: 0, marginBottom: 1 }}>\n {props.errorTitle}\n </Title>\n )}\n <ErrorList errors={props.errors!} />\n </>\n )}\n {props.children}\n </div>\n );\n};\n\nexport default ValidationSummary;\n"],"names":["ValidationSummary","props","errorTitleHtmlMarkup","titleId","useUuid","hasErrors","summaryClasses","classNames","styles","React","Title","ErrorList"],"mappings":";;;;;;AAsBA,MAAMA,IAAsD,CAASC,MAAA;AAC7D,QAAA,EAAE,sBAAAC,IAAuB,KAAS,IAAAD,GAClCE,IAAUC,KAEVC,IAAY,CAAC,CAACJ,EAAM,UAAU,OAAO,QAAQA,EAAM,MAAM,EAAE,SAAS,GAEpEK,IAAiBC,EAAWC,EAAO,qBAAwBH,KAAaG,EAAO,8BAA8B,CAAC;AAGlH,SAAAC,gBAAAA,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAM;AAAA,MACN,aAAW;AAAA,MACX,iBAAe;AAAA,MACf,mBAAiBJ,KAAaJ,EAAM,aAAaE,IAAU;AAAA,MAC3D,WAAWG;AAAA,IAAA;AAAA,IAEVD,KAEII,gBAAAA,EAAA,cAAAA,EAAA,UAAA,MAAAR,EAAM,cACLQ,gBAAAA,EAAA,cAACC,GAAM,EAAA,YAAW,UAAS,IAAIP,GAAS,YAAYD,GAAsB,QAAQ,EAAE,WAAW,GAAG,cAAc,EAAE,EAAA,GAC/GD,EAAM,UACT,GAEFQ,gBAAAA,EAAA,cAACE,GAAU,EAAA,QAAQV,EAAM,OAAA,CAAS,CACpC;AAAA,IAEDA,EAAM;AAAA,EAAA;AAGb;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect as a } from "react";
|
|
2
|
+
const p = (t, r) => {
|
|
3
|
+
const e = (o) => o.stopPropagation();
|
|
4
|
+
a(() => (r.forEach((o) => {
|
|
5
|
+
var n;
|
|
6
|
+
return (n = t == null ? void 0 : t.current) == null ? void 0 : n.addEventListener(o, e);
|
|
7
|
+
}), () => r.forEach((o) => {
|
|
8
|
+
var n;
|
|
9
|
+
return (n = t.current) == null ? void 0 : n.removeEventListener(o, e);
|
|
10
|
+
})), [t]);
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
p as useStopPropagation
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=usestopPropagation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usestopPropagation.js","sources":["../../src/hooks/usestopPropagation.ts"],"sourcesContent":["import { useEffect } from 'react';\n\n/**\n * Stopp eventer fra å boble opp videre i DOMen\n * @param ref Element som skal overvåkes\n * @param events Navn på eventer som ikke skal boble opp\n */\nexport const useStopPropagation = (ref: React.RefObject<HTMLElement>, events: string[]) => {\n const handleEvent = (e: Event): void => e.stopPropagation();\n\n useEffect(() => {\n events.forEach(name => ref?.current?.addEventListener(name, handleEvent));\n\n return (): void => events.forEach(name => ref.current?.removeEventListener(name, handleEvent));\n }, [ref]);\n};\n"],"names":["useStopPropagation","ref","events","handleEvent","e","useEffect","name","_a"],"mappings":";AAOa,MAAAA,IAAqB,CAACC,GAAmCC,MAAqB;AACzF,QAAMC,IAAc,CAACC,MAAmBA,EAAE,gBAAgB;AAE1D,EAAAC,EAAU,OACRH,EAAO,QAAQ,CAAQI;;AAAA,YAAAC,IAAAN,KAAA,gBAAAA,EAAK,YAAL,gBAAAM,EAAc,iBAAiBD,GAAMH;AAAA,GAAY,GAEjE,MAAYD,EAAO,QAAQ,CAAAI,MAAQ;;AAAA,YAAAC,IAAAN,EAAI,YAAJ,gBAAAM,EAAa,oBAAoBD,GAAMH;AAAA,GAAY,IAC5F,CAACF,CAAG,CAAC;AACV;"}
|
package/package.json
CHANGED
package/utils/refs.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @param refs array med refs som skal slås sammen
|
|
5
5
|
* @returns refcallback som kan brukes på komponent
|
|
6
6
|
*/
|
|
7
|
-
export declare const mergeRefs: <T>(refs: Array<React.MutableRefObject<T> | React.LegacyRef<T
|
|
7
|
+
export declare const mergeRefs: <T>(refs: Array<React.MutableRefObject<T> | React.LegacyRef<T> | null | undefined>) => React.RefCallback<T>;
|
|
8
8
|
/**
|
|
9
9
|
* Sjekker om ref er et objekt (og ikke en funksjon)
|
|
10
10
|
* @param ref
|
package/utils/refs.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
typeof
|
|
1
|
+
const e = (n) => (o) => {
|
|
2
|
+
n.forEach((t) => {
|
|
3
|
+
typeof t == "function" ? t(o) : t != null && t !== void 0 && (t.current = o);
|
|
4
4
|
});
|
|
5
|
-
}, c = (
|
|
5
|
+
}, c = (n) => typeof n != "function" && n !== null;
|
|
6
6
|
export {
|
|
7
7
|
c as isMutableRefObject,
|
|
8
|
-
|
|
8
|
+
e as mergeRefs
|
|
9
9
|
};
|
|
10
10
|
//# sourceMappingURL=refs.js.map
|
package/utils/refs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refs.js","sources":["../../src/utils/refs.ts"],"sourcesContent":["/**\n * Slår sammen refs fra forwardRef og useRef slik at begge deler kan brukes\n * Fra https://github.com/gregberge/react-merge-refs\n * @param refs array med refs som skal slås sammen\n * @returns refcallback som kan brukes på komponent\n */\nexport const mergeRefs = <T>(refs: Array<React.MutableRefObject<T> | React.LegacyRef<T
|
|
1
|
+
{"version":3,"file":"refs.js","sources":["../../src/utils/refs.ts"],"sourcesContent":["/**\n * Slår sammen refs fra forwardRef og useRef slik at begge deler kan brukes\n * Fra https://github.com/gregberge/react-merge-refs\n * @param refs array med refs som skal slås sammen\n * @returns refcallback som kan brukes på komponent\n */\nexport const mergeRefs = <T>(refs: Array<React.MutableRefObject<T> | React.LegacyRef<T> | null | undefined>): React.RefCallback<T> => {\n return value => {\n refs.forEach(ref => {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref != null && ref !== undefined) {\n (ref as React.MutableRefObject<T | null>).current = value;\n }\n });\n };\n};\n\n/**\n * Sjekker om ref er et objekt (og ikke en funksjon)\n * @param ref\n * @returns type predicate\n */\nexport const isMutableRefObject = <T>(ref: React.ForwardedRef<T>): ref is React.MutableRefObject<T> => {\n return typeof ref !== 'function' && ref !== null;\n};\n"],"names":["mergeRefs","refs","value","ref","isMutableRefObject"],"mappings":"AAMa,MAAAA,IAAY,CAAIC,MACpB,CAASC,MAAA;AACd,EAAAD,EAAK,QAAQ,CAAOE,MAAA;AACd,IAAA,OAAOA,KAAQ,aACjBA,EAAID,CAAK,IACAC,KAAO,QAAQA,MAAQ,WAC/BA,EAAyC,UAAUD;AAAA,EACtD,CACD;AAAA,GASQE,IAAqB,CAAID,MAC7B,OAAOA,KAAQ,cAAcA,MAAQ;"}
|