@helsenorge/designsystem-react 8.6.0-beta.1 → 9.0.0-beta.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.
Files changed (88) hide show
  1. package/Button.js +7 -7
  2. package/Button.js.map +1 -1
  3. package/CHANGELOG.md +1 -1
  4. package/Checkbox.js +42 -42
  5. package/Checkbox.js.map +1 -1
  6. package/ErrorWrapper.js.map +1 -1
  7. package/FormGroup.js +30 -30
  8. package/FormGroup.js.map +1 -1
  9. package/Icon.js +21 -21
  10. package/Icon.js.map +1 -1
  11. package/Input.js +98 -88
  12. package/Input.js.map +1 -1
  13. package/Label.js +9 -9
  14. package/Label.js.map +1 -1
  15. package/MaxCharacters.js +2 -2
  16. package/MaxCharacters.js.map +1 -1
  17. package/RadioButton.js +61 -61
  18. package/RadioButton.js.map +1 -1
  19. package/Select.js +34 -33
  20. package/Select.js.map +1 -1
  21. package/StatusDot.js +15 -15
  22. package/StatusDot.js.map +1 -1
  23. package/TabList.js +88 -53
  24. package/TabList.js.map +1 -1
  25. package/TabPanel.js +7 -7
  26. package/TabPanel.js.map +1 -1
  27. package/Textarea.js +59 -58
  28. package/Textarea.js.map +1 -1
  29. package/Trigger.js +33 -33
  30. package/Trigger.js.map +1 -1
  31. package/components/Button/Button.d.ts +2 -2
  32. package/components/Checkbox/Checkbox.d.ts +4 -3
  33. package/components/Checkbox/styles.module.scss +0 -14
  34. package/components/Checkbox/styles.module.scss.d.ts +0 -1
  35. package/components/Dropdown/Dropdown.d.ts +2 -2
  36. package/components/Dropdown/index.js +25 -25
  37. package/components/Dropdown/index.js.map +1 -1
  38. package/components/ErrorWrapper/ErrorWrapper.d.ts +3 -0
  39. package/components/ExpanderList/ExpanderList.d.ts +4 -6
  40. package/components/ExpanderList/index.js +118 -126
  41. package/components/ExpanderList/index.js.map +1 -1
  42. package/components/ExpanderList/styles.module.scss +164 -53
  43. package/components/ExpanderList/styles.module.scss.d.ts +29 -5
  44. package/components/FormGroup/FormGroup.d.ts +2 -2
  45. package/components/Icon/Icon.d.ts +4 -4
  46. package/components/Icons/NoAccess.js +7 -7
  47. package/components/Icons/NoAccess.js.map +1 -1
  48. package/components/Input/Input.d.ts +4 -3
  49. package/components/Label/Label.d.ts +4 -4
  50. package/components/Label/SubLabel.d.ts +2 -2
  51. package/components/MaxCharacters/MaxCharacters.d.ts +2 -2
  52. package/components/RadioButton/RadioButton.d.ts +5 -4
  53. package/components/RadioButton/styles.module.scss +0 -15
  54. package/components/RadioButton/styles.module.scss.d.ts +0 -1
  55. package/components/Select/Select.d.ts +4 -3
  56. package/components/SharingStatus/SharingStatus.d.ts +1 -1
  57. package/components/SharingStatus/index.js +5 -5
  58. package/components/SharingStatus/index.js.map +1 -1
  59. package/components/SharingStatus/styles.module.scss +0 -16
  60. package/components/SharingStatus/styles.module.scss.d.ts +0 -4
  61. package/components/StatusDot/StatusDot.d.ts +3 -3
  62. package/components/StatusDot/index.js +3 -3
  63. package/components/Tabs/TabList/TabList.d.ts +3 -3
  64. package/components/Tabs/TabList/styles.module.scss +63 -51
  65. package/components/Tabs/TabList/styles.module.scss.d.ts +7 -3
  66. package/components/Tabs/TabPanel/TabPanel.d.ts +1 -2
  67. package/components/Tabs/TabPanel/styles.module.scss +11 -26
  68. package/components/Tabs/TabPanel/styles.module.scss.d.ts +0 -2
  69. package/components/Tabs/Tabs.d.ts +3 -3
  70. package/components/Tabs/index.js +57 -72
  71. package/components/Tabs/index.js.map +1 -1
  72. package/components/Tabs/styles.module.scss +5 -9
  73. package/components/Tabs/styles.module.scss.d.ts +0 -1
  74. package/components/Textarea/Textarea.d.ts +4 -3
  75. package/components/Toggle/index.js +1222 -1180
  76. package/components/Toggle/index.js.map +1 -1
  77. package/components/Trigger/Trigger.d.ts +2 -2
  78. package/components/Validation/index.js +38 -32
  79. package/components/Validation/index.js.map +1 -1
  80. package/constants.d.ts +1 -1
  81. package/constants.js +1 -1
  82. package/constants.js.map +1 -1
  83. package/docs/FormExample/FormExample.d.ts +2 -1
  84. package/index.js +23 -23
  85. package/package.json +4 -4
  86. package/utils/component.d.ts +1 -0
  87. package/utils/component.js +7 -3
  88. package/utils/component.js.map +1 -1
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
- import { TabsColors, TabsType } from '../Tabs';
2
+ import { TabsColors } from '../Tabs';
3
3
  interface TabPanelProps {
4
4
  children?: React.ReactNode;
5
5
  color?: TabsColors;
6
- type?: TabsType;
7
6
  isFirst?: boolean;
8
7
  translateX?: number;
9
8
  style?: React.CSSProperties;
@@ -7,32 +7,23 @@
7
7
 
8
8
  .tab-panel {
9
9
  $tab-panel: &;
10
-
11
- padding: 2rem;
12
-
13
10
  $colors: 'blueberry', 'neutral', 'white';
14
11
 
12
+ padding: getSpacer(xl) getSpacer(l) getSpacer(2xl);
15
13
  width: 100%;
16
- padding-left: 0;
17
-
18
- @media (min-width: map.get($grid-breakpoints, md)) {
19
- width: 100%;
20
- }
14
+ border-bottom: 1px solid var(--color-action-border-onlight-focus);
21
15
 
22
- &--normal {
23
- padding: 0;
16
+ @each $color in $colors {
17
+ &#{$tab-panel}--#{$color} {
18
+ background-color: var(--color-base-background-#{$color});
19
+ }
24
20
  }
25
21
 
26
- &--framed {
27
- padding: 2rem;
28
- border-bottom: 1px solid var(--color-action-border-onlight-focus);
29
- border-radius: 0;
30
-
31
- @media (min-width: map.get($grid-breakpoints, md)) {
32
- border-radius: 0 0 0.5rem 0.5rem;
33
- border: 1px solid var(--color-action-border-onlight-focus);
34
- border-top: 0;
35
- }
22
+ @media (min-width: map.get($grid-breakpoints, md)) {
23
+ border-radius: 0 0 0.5rem 0.5rem;
24
+ border: 1px solid var(--color-action-border-onlight-focus);
25
+ border-top: 0;
26
+ padding: getSpacer(2xl) getSpacer(l) getSpacer(3xl);
36
27
 
37
28
  &#{$tab-panel}--first {
38
29
  border-radius: 0;
@@ -41,12 +32,6 @@
41
32
  border-radius: 0 0 0.5rem 0.5rem;
42
33
  }
43
34
  }
44
-
45
- @each $color in $colors {
46
- &#{$tab-panel}--#{$color} {
47
- background-color: var(--color-base-background-#{$color});
48
- }
49
- }
50
35
  }
51
36
  }
52
37
 
@@ -6,9 +6,7 @@ export type Styles = {
6
6
  'tab-panel--animate-right': string;
7
7
  'tab-panel--blueberry': string;
8
8
  'tab-panel--first': string;
9
- 'tab-panel--framed': string;
10
9
  'tab-panel--neutral': string;
11
- 'tab-panel--normal': string;
12
10
  'tab-panel--white': string;
13
11
  };
14
12
 
@@ -3,7 +3,7 @@ import Tab from './Tab';
3
3
  import { PaletteNames } from '../../theme/palette';
4
4
  export type { TabProps } from './Tab';
5
5
  export type TabsColors = Extract<PaletteNames, 'blueberry' | 'neutral' | 'white'>;
6
- export type TabsType = 'normal' | 'framed';
6
+ export type TabsOnColor = 'onblueberry' | 'onneutral' | 'onwhite';
7
7
  export type TabsTouchBehaviour = 'swipe' | 'none';
8
8
  export interface TabsProps {
9
9
  children?: React.ReactNode;
@@ -13,14 +13,14 @@ export interface TabsProps {
13
13
  className?: string;
14
14
  /** Sets the color of the tabs. Default: white */
15
15
  color?: TabsColors;
16
+ /** Sets the background color of the tabs. Can only be used when the color is set to white. Default: onwhite */
17
+ onColor?: TabsOnColor;
16
18
  /** Whether the tab list should be sticky */
17
19
  sticky?: boolean;
18
20
  /** Determines how Tabs respons to touch events. */
19
21
  touchBehaviour?: TabsTouchBehaviour;
20
22
  /** Sets the data-testid attribute. */
21
23
  testId?: string;
22
- /** Sets the visual type of the tabs */
23
- type?: TabsType;
24
24
  }
25
25
  declare const TabsRoot: React.FC<TabsProps>;
26
26
  type TabsComponent = typeof TabsRoot & {
@@ -1,95 +1,80 @@
1
- import { jsxs as C, jsx as m } from "react/jsx-runtime";
2
- import v, { useState as i, useRef as E, useEffect as S } from "react";
3
- import M from "classnames";
4
- import { a as G, T as H } from "../../TabList.js";
5
- import { T as J } from "../../TabPanel.js";
6
- import { isMobileUA as K } from "../../utils/mobile.js";
7
- import c from "./styles.module.scss";
8
- const O = 75, Q = ({
9
- activeTab: L,
10
- children: l,
11
- className: N,
12
- color: f = "white",
1
+ import { jsxs as y, jsx as d } from "react/jsx-runtime";
2
+ import b, { useState as i, useRef as v, useEffect as A } from "react";
3
+ import S from "classnames";
4
+ import { a as H, T as J } from "../../TabList.js";
5
+ import { T as K } from "../../TabPanel.js";
6
+ import { isMobileUA as O } from "../../utils/mobile.js";
7
+ import m from "./styles.module.scss";
8
+ const Q = 75, V = ({
9
+ activeTab: E,
10
+ children: c,
11
+ className: M,
12
+ color: l = "white",
13
+ onColor: N = "onwhite",
13
14
  sticky: g = !0,
14
- testId: y,
15
- type: d = "normal",
16
- touchBehaviour: X = "swipe"
15
+ testId: D,
16
+ touchBehaviour: L = "none"
17
17
  }) => {
18
- const R = L !== void 0, [D, P] = i(0), [u, j] = i(0), [h, k] = i(0), [U, s] = i(0), [F, p] = i(null), x = K(), n = E(null), r = E(null), I = E(null), T = (t, a) => {
19
- R || (P(t), t > a ? (s(0), q()) : t < a && (s(0), $()));
20
- }, $ = () => {
21
- x && p("right");
18
+ const X = E !== void 0, [P, U] = i(0), [u, j] = i(0), [h, k] = i(0), [F, s] = i(0), [I, f] = i(null), C = O(), n = v(null), r = v(null), $ = v(null);
19
+ let R = "onwhite";
20
+ l === "white" && (R = N);
21
+ const p = (e, o) => {
22
+ X || (U(e), e > o ? (s(0), z()) : e < o && (s(0), q()));
22
23
  }, q = () => {
23
- x && p("left");
24
+ C && f("right");
24
25
  }, z = () => {
25
- p(null);
26
- }, e = R ? L : D;
27
- return S(() => {
28
- const t = (o) => {
29
- j(o.touches[0].clientX);
30
- }, a = (o) => {
31
- k(o.touches[0].clientX);
32
- const b = o.touches[0].clientX - u;
33
- e === 0 && b > 0 || e === v.Children.count(l) - 1 && b < 0 ? s(0) : s(b);
34
- }, A = () => {
35
- Math.abs(h - u) >= O && (h > u ? T(Math.max(0, e - 1), e) : T(Math.min(v.Children.count(l) - 1, e + 1), e)), s(0);
26
+ C && f("left");
27
+ }, G = () => {
28
+ f(null);
29
+ }, t = X ? E : P;
30
+ return A(() => {
31
+ const e = (a) => {
32
+ j(a.touches[0].clientX);
33
+ }, o = (a) => {
34
+ k(a.touches[0].clientX);
35
+ const T = a.touches[0].clientX - u;
36
+ t === 0 && T > 0 || t === b.Children.count(c) - 1 && T < 0 ? s(0) : s(T);
37
+ }, x = () => {
38
+ Math.abs(h - u) >= Q && (h > u ? p(Math.max(0, t - 1), t) : p(Math.min(b.Children.count(c) - 1, t + 1), t)), s(0);
36
39
  };
37
- return X === "swipe" && n.current && (n.current.addEventListener("touchstart", t), n.current.addEventListener("touchmove", a), n.current.addEventListener("touchend", A)), () => {
38
- n.current && (n.current.removeEventListener("touchstart", t), n.current.removeEventListener("touchmove", a), n.current.removeEventListener("touchend", A));
40
+ return L === "swipe" && n.current && (n.current.addEventListener("touchstart", e), n.current.addEventListener("touchmove", o), n.current.addEventListener("touchend", x)), () => {
41
+ n.current && (n.current.removeEventListener("touchstart", e), n.current.removeEventListener("touchmove", o), n.current.removeEventListener("touchend", x));
39
42
  };
40
- }, [X, u, h, e]), S(() => {
41
- const t = () => {
42
- z();
43
+ }, [L, u, h, t]), A(() => {
44
+ const e = () => {
45
+ G();
43
46
  };
44
- return r.current && r.current.addEventListener("animationend", t), () => {
45
- r.current && r.current.removeEventListener("animationend", t);
47
+ return r.current && r.current.addEventListener("animationend", e), () => {
48
+ r.current && r.current.removeEventListener("animationend", e);
46
49
  };
47
- }, []), /* @__PURE__ */ C("div", { className: N, "data-testid": y, children: [
48
- /* @__PURE__ */ C(
50
+ }, []), /* @__PURE__ */ y("div", { className: M, "data-testid": D, children: [
51
+ /* @__PURE__ */ y(
49
52
  "div",
50
53
  {
51
- ref: I,
52
- className: M(c["tab-list-wrapper"], {
53
- [c["tab-list-wrapper--sticky"]]: g
54
+ ref: $,
55
+ className: S(m["tab-list-wrapper"], {
56
+ [m["tab-list-wrapper--sticky"]]: g
54
57
  }),
55
58
  children: [
56
- /* @__PURE__ */ m(
57
- H,
59
+ /* @__PURE__ */ d(
60
+ J,
58
61
  {
59
- onTabListClick: (t) => T(t, e),
60
- selectedTab: e,
61
- color: f,
62
- type: d,
63
- children: l
62
+ onTabListClick: (e) => p(e, t),
63
+ selectedTab: t,
64
+ color: l,
65
+ onColor: R,
66
+ children: c
64
67
  }
65
68
  ),
66
- /* @__PURE__ */ m(
67
- "div",
68
- {
69
- className: M(c["panel-wrapper"], c[`panel-wrapper--${f}`], {
70
- [c["panel-wrapper--framed"]]: d == "framed"
71
- })
72
- }
73
- )
69
+ /* @__PURE__ */ d("div", { className: S(m["panel-wrapper"], m[`panel-wrapper--${l}`]) })
74
70
  ]
75
71
  }
76
72
  ),
77
- /* @__PURE__ */ m("div", { ref: n, style: { marginTop: d == "framed" ? "-40px" : "" }, children: /* @__PURE__ */ m(
78
- J,
79
- {
80
- ref: r,
81
- color: f,
82
- type: d,
83
- isFirst: e == 0,
84
- translateX: U,
85
- animate: F,
86
- children: v.Children.toArray(l)[e]
87
- }
88
- ) })
73
+ /* @__PURE__ */ d("div", { ref: n, style: { marginTop: "-50px" }, children: /* @__PURE__ */ d(K, { ref: r, color: l, isFirst: t == 0, translateX: F, animate: I, children: b.Children.toArray(c)[t] }) })
89
74
  ] });
90
- }, w = Q;
75
+ }, w = V;
91
76
  w.displayName = "Tabs";
92
- w.Tab = G;
77
+ w.Tab = H;
93
78
  w.Tab.displayName = "Tabs.Tab";
94
79
  export {
95
80
  w as default
@@ -1 +1 @@
1
- {"version":3,"file":"index.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","jsxs","classNames","styles","jsx","TabList","index","TabPanel","Tabs","Tab"],"mappings":"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"}
1
+ {"version":3,"file":"index.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 TabsOnColor = 'onblueberry' | 'onneutral' | 'onwhite';\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 /** Sets the background color of the tabs. Can only be used when the color is set to white. Default: onwhite */\n onColor?: TabsOnColor;\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}\n\nconst swipeDistanceThreshold = 75;\n\nconst TabsRoot: React.FC<TabsProps> = ({\n activeTab,\n children,\n className,\n color = 'white',\n onColor = 'onwhite',\n sticky = true,\n testId,\n touchBehaviour = 'none',\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 let onColorUsed: TabsOnColor = 'onwhite';\n if (color === 'white') {\n onColorUsed = onColor;\n }\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 onColor={onColorUsed}\n >\n {children}\n </TabList>\n <div className={classNames(styles['panel-wrapper'], styles[`panel-wrapper--${color}`])}></div>\n </div>\n <div ref={tabsRef} style={{ marginTop: '-50px' }}>\n <TabPanel ref={tabPanelRef} color={color} isFirst={activeTabIndex == 0} translateX={translateX} animate={panelAnimation}>\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","onColor","sticky","testId","touchBehaviour","isControlled","uncontrolledValue","setUncontrolledValue","useState","touchStartX","setTouchStartX","touchEndX","setTouchEndX","translateX","setTranslateX","panelAnimation","setPanelAnimation","mobile","isMobileUA","tabsRef","useRef","tabPanelRef","tabListRef","onColorUsed","onValueChange","newValue","oldValue","onLeftSwipe","onRightSwipe","resetAnimation","activeTabIndex","useEffect","handleTouchStart","event","handleTouchMove","newTranslateX","React","handleTouchEnd","handleAnimationEnd","jsxs","classNames","styles","jsx","TabList","index","TabPanel","Tabs","Tab"],"mappings":";;;;;;;AAmCA,MAAMA,IAAyB,IAEzBC,IAAgC,CAAC;AAAA,EACrC,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,SAAAC,IAAU;AAAA,EACV,QAAAC,IAAS;AAAA,EACT,QAAAC;AAAA,EACA,gBAAAC,IAAiB;AACnB,MAAM;AACJ,QAAMC,IAAeR,MAAc,QAC7B,CAACS,GAAmBC,CAAoB,IAAIC,EAAS,CAAC,GACtD,CAACC,GAAaC,CAAc,IAAIF,EAAS,CAAC,GAC1C,CAACG,GAAWC,CAAY,IAAIJ,EAAS,CAAC,GACtC,CAACK,GAAYC,CAAa,IAAIN,EAAS,CAAC,GACxC,CAACO,GAAgBC,CAAiB,IAAIR,EAAkC,IAAI,GAC5ES,IAASC,KACTC,IAAUC,EAAuB,IAAI,GACrCC,IAAcD,EAAuB,IAAI,GACzCE,IAAaF,EAAuB,IAAI;AAE9C,MAAIG,IAA2B;AAC/B,EAAIvB,MAAU,YACEuB,IAAAtB;AAGV,QAAAuB,IAAgB,CAACC,GAAkBC,MAA2B;AAClE,IAAKrB,MACHE,EAAqBkB,CAAQ,GACzBA,IAAWC,KAEbZ,EAAc,CAAC,GACHa,OACHF,IAAWC,MAEpBZ,EAAc,CAAC,GACFc;EAEjB,GAGIA,IAAe,MAAY;AAC/B,IAAAX,KAAUD,EAAkB,OAAO;AAAA,EAAA,GAG/BW,IAAc,MAAY;AAC9B,IAAAV,KAAUD,EAAkB,MAAM;AAAA,EAAA,GAG9Ba,IAAiB,MAAY;AACjC,IAAAb,EAAkB,IAAI;AAAA,EAAA,GAGlBc,IAAiBzB,IAAeR,IAAYS;AAElD,SAAAyB,EAAU,MAAM;AACR,UAAAC,IAAmB,CAACC,MAA4B;AACpD,MAAAvB,EAAeuB,EAAM,QAAQ,CAAC,EAAE,OAAO;AAAA,IAAA,GAGnCC,IAAkB,CAACD,MAA4B;AACnD,MAAArB,EAAaqB,EAAM,QAAQ,CAAC,EAAE,OAAO;AACrC,YAAME,IAAgBF,EAAM,QAAQ,CAAC,EAAE,UAAUxB;AAE7C,MAAAqB,MAAmB,KAAKK,IAAgB,KAEjCL,MAAmBM,EAAM,SAAS,MAAMtC,CAAQ,IAAI,KAAKqC,IAAgB,IADlFrB,EAAc,CAAC,IAIfA,EAAcqB,CAAa;AAAA,IAC7B,GAGIE,IAAiB,MAAY;AAEjC,MADsB,KAAK,IAAI1B,IAAYF,CAAW,KACjCd,MACfgB,IAAYF,IAEde,EAAc,KAAK,IAAI,GAAGM,IAAiB,CAAC,GAAGA,CAAc,IAG/CN,EAAA,KAAK,IAAIY,EAAM,SAAS,MAAMtC,CAAQ,IAAI,GAAGgC,IAAiB,CAAC,GAAGA,CAAc,IAGlGhB,EAAc,CAAC;AAAA,IAAA;AAGb,WAAAV,MAAmB,WAAWe,EAAQ,YAChCA,EAAA,QAAQ,iBAAiB,cAAca,CAAgB,GACvDb,EAAA,QAAQ,iBAAiB,aAAae,CAAe,GACrDf,EAAA,QAAQ,iBAAiB,YAAYkB,CAAc,IAEtD,MAAM;AACX,MAAIlB,EAAQ,YACFA,EAAA,QAAQ,oBAAoB,cAAca,CAAgB,GAC1Db,EAAA,QAAQ,oBAAoB,aAAae,CAAe,GACxDf,EAAA,QAAQ,oBAAoB,YAAYkB,CAAc;AAAA,IAChE;AAAA,KAED,CAACjC,GAAgBK,GAAaE,GAAWmB,CAAc,CAAC,GAE3DC,EAAU,MAAM;AACd,UAAMO,IAAqB,MAAY;AACtB,MAAAT;IAAA;AAGjB,WAAIR,EAAY,WACFA,EAAA,QAAQ,iBAAiB,gBAAgBiB,CAAkB,GAGlE,MAAM;AACX,MAAIjB,EAAY,WACFA,EAAA,QAAQ,oBAAoB,gBAAgBiB,CAAkB;AAAA,IAC5E;AAAA,EAEJ,GAAG,CAAE,CAAA,GAGF,gBAAAC,EAAA,OAAA,EAAI,WAAAxC,GAAsB,eAAaI,GACtC,UAAA;AAAA,IAAA,gBAAAoC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKjB;AAAA,QACL,WAAWkB,EAAWC,EAAO,kBAAkB,GAAG;AAAA,UAChD,CAACA,EAAO,0BAA0B,CAAC,GAAGvC;AAAA,QAAA,CACvC;AAAA,QAED,UAAA;AAAA,UAAA,gBAAAwC;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,gBAAgB,CAACC,MAAkBpB,EAAcoB,GAAOd,CAAc;AAAA,cACtE,aAAaA;AAAA,cACb,OAAA9B;AAAA,cACA,SAASuB;AAAA,cAER,UAAAzB;AAAA,YAAA;AAAA,UACH;AAAA,UACC,gBAAA4C,EAAA,OAAA,EAAI,WAAWF,EAAWC,EAAO,eAAe,GAAGA,EAAO,kBAAkBzC,CAAK,EAAE,CAAC,EAAG,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAC1F;AAAA,IACA,gBAAA0C,EAAC,OAAI,EAAA,KAAKvB,GAAS,OAAO,EAAE,WAAW,QAAQ,GAC7C,UAAC,gBAAAuB,EAAAG,GAAA,EAAS,KAAKxB,GAAa,OAAArB,GAAc,SAAS8B,KAAkB,GAAG,YAAAjB,GAAwB,SAASE,GACtG,UAAAqB,EAAM,SAAS,QAAQtC,CAAQ,EAAEgC,CAAc,EAAA,CAClD,EACF,CAAA;AAAA,EACF,EAAA,CAAA;AAEJ,GAKMgB,IAAOlD;AACbkD,EAAK,cAAc;AACnBA,EAAK,MAAMC;AACXD,EAAK,IAAI,cAAc;"}
@@ -16,19 +16,15 @@
16
16
  $panel-wrapper: &;
17
17
  $colors: 'blueberry', 'neutral', 'white';
18
18
 
19
- border-top: 1px solid var(--color-action-border-onlight-focus);
20
19
  position: relative;
21
20
  width: 100%;
21
+ border-radius: 0;
22
+ height: 50px;
22
23
 
23
- &--framed {
24
- border-radius: 0;
24
+ @media (min-width: map.get($grid-breakpoints, md)) {
25
+ border-right: 1px solid var(--color-action-border-onlight-focus);
26
+ border-left: 1px solid var(--color-action-border-onlight-focus);
25
27
  height: 50px;
26
-
27
- @media (min-width: map.get($grid-breakpoints, md)) {
28
- border-radius: 0 0.5rem 0 0;
29
- border-right: 1px solid var(--color-action-border-onlight-focus);
30
- border-left: 1px solid var(--color-action-border-onlight-focus);
31
- }
32
28
  }
33
29
 
34
30
  @each $color in $colors {
@@ -1,7 +1,6 @@
1
1
  export type Styles = {
2
2
  'panel-wrapper': string;
3
3
  'panel-wrapper--blueberry': string;
4
- 'panel-wrapper--framed': string;
5
4
  'panel-wrapper--neutral': string;
6
5
  'panel-wrapper--white': string;
7
6
  'tab-list-wrapper': string;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
- import { FormMode } from '../../constants';
3
- export interface TextareaProps extends Pick<React.InputHTMLAttributes<HTMLTextAreaElement>, 'aria-describedby' | 'autoFocus' | 'disabled' | 'name' | 'autoComplete' | 'placeholder' | 'readOnly' | 'required' | 'defaultValue' | 'onChange'> {
2
+ import { FormOnColor } from '../../constants';
3
+ import { ErrorWrapperClassNameProps } from '../ErrorWrapper';
4
+ export interface TextareaProps extends ErrorWrapperClassNameProps, Pick<React.InputHTMLAttributes<HTMLTextAreaElement>, 'aria-describedby' | 'autoFocus' | 'disabled' | 'name' | 'autoComplete' | 'placeholder' | 'readOnly' | 'required' | 'defaultValue' | 'onChange'> {
4
5
  /** max character limit in textarea */
5
6
  maxCharacters?: number;
6
7
  /** The text is displayed in the end of the text-counter */
@@ -14,7 +15,7 @@ export interface TextareaProps extends Pick<React.InputHTMLAttributes<HTMLTextAr
14
15
  /** If true, the component will be transparent. */
15
16
  transparent?: boolean;
16
17
  /** Changes the visuals of the textarea */
17
- mode?: keyof typeof FormMode;
18
+ onColor?: keyof typeof FormOnColor;
18
19
  /** Label of the input */
19
20
  label?: React.ReactNode;
20
21
  /** id of the textarea */