@situaction/traq-ui-ste 1.2.7 → 1.2.8

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.
@@ -3,21 +3,22 @@ import { FC, ReactNode } from 'react';
3
3
  export interface TabsProps {
4
4
  /** select the type of data text or icon that we put in tabs */
5
5
  type: 'text' | 'icon' | 'button';
6
- /** Array of strings representing the labels of the tabs */
6
+ /** Array of strings or nodes representing the labels of the tabs */
7
7
  listItems: (string | ReactNode)[];
8
- /** Index of the tab that should be active by default */
8
+ /** Active tab (controlled) */
9
+ activeTab?: number;
10
+ /** Index of the tab that should be active by default (uncontrolled) */
9
11
  defaultActiveTab?: number;
10
12
  /** Position Tabs */
11
13
  position?: 'center' | 'right' | 'left';
12
- /** Callback function to handle tab selection, receiving the selected tab's label */
13
- onTabSelect: (selectedItem: string | ReactNode) => void;
14
- /** Full width*/
14
+ /** Callback on selection (label + index) */
15
+ onTabSelect: (selectedItem: string | ReactNode, index?: number) => void;
16
+ /** Full width */
15
17
  fullWidth?: boolean;
16
- /** tabs disabled */
18
+ /** Disabled tabs indices */
17
19
  disabledTabs?: number[];
18
20
  }
19
21
  /**
20
- * Tabs component that allows tab navigation with text, icons, or buttons.
21
- * It includes a dynamic underline to show the active tab.
22
+ * Tabs with dynamic underline. Works controlled (activeTab) or uncontrolled (defaultActiveTab).
22
23
  */
23
24
  export declare const Tabs: FC<TabsProps>;
@@ -1,8 +1,8 @@
1
- import { jsxs as w, jsx as l } from "react/jsx-runtime";
2
- import { useState as f, useRef as u, useLayoutEffect as B } from "react";
3
- import { Button as p } from "../button/Button.js";
4
- import { IconButton as S } from "../icon-button/IconButton.js";
5
- import '../../styles/Tabs.css';const j = "_underline_6o3gh_70", e = {
1
+ import { jsxs as j, jsx as s } from "react/jsx-runtime";
2
+ import { useState as R, useRef as $, useEffect as u, useLayoutEffect as k } from "react";
3
+ import { Button as q } from "../button/Button.js";
4
+ import { IconButton as B } from "../icon-button/IconButton.js";
5
+ import '../../styles/Tabs.css';const L = "_underline_6o3gh_70", n = {
6
6
  "tab-container": "_tab-container_6o3gh_30",
7
7
  "tab-container-button": "_tab-container-button_6o3gh_34",
8
8
  "tab-container-icon": "_tab-container-icon_6o3gh_39",
@@ -12,85 +12,114 @@ import '../../styles/Tabs.css';const j = "_underline_6o3gh_70", e = {
12
12
  "tab-full-width": "_tab-full-width_6o3gh_51",
13
13
  "selected-button": "_selected-button_6o3gh_57",
14
14
  "selected-text": "_selected-text_6o3gh_63",
15
- underline: j,
15
+ underline: L,
16
16
  "flexHorizontal-center": "_flexHorizontal-center_6o3gh_78",
17
17
  "flexHorizontal-left": "_flexHorizontal-left_6o3gh_84",
18
18
  "flexHorizontal-right": "_flexHorizontal-right_6o3gh_90"
19
- }, q = ({
20
- listItems: c,
21
- type: o,
22
- onTabSelect: h,
23
- defaultActiveTab: g = 0,
19
+ }, C = (o, r) => {
20
+ if (!Number.isFinite(o)) return 0;
21
+ const b = Math.max(0, r);
22
+ return Math.min(Math.max(o, 0), b);
23
+ }, D = ({
24
+ listItems: o,
25
+ type: r,
26
+ onTabSelect: b,
27
+ activeTab: _,
28
+ defaultActiveTab: f = 0,
24
29
  position: m = "left",
25
- fullWidth: x = !1,
26
- disabledTabs: b = []
27
- // ✅ par défaut vide
30
+ fullWidth: H = !1,
31
+ disabledTabs: g = []
28
32
  }) => {
29
- const [s, v] = f(g), [z, $] = f({}), r = u(null), R = u(null), _ = u([]), d = (t) => {
30
- b.includes(t) || (v(t), h(c[t]));
31
- }, H = (t) => {
32
- if (r.current && t) {
33
- const n = t.getBoundingClientRect(), i = r.current.getBoundingClientRect();
34
- $({
35
- left: `${n.left - i.left}px`,
36
- width: `${n.width}px`
37
- });
33
+ const c = _ !== void 0, [N, x] = R(f), h = C(
34
+ c ? _ : N,
35
+ (o.length || 1) - 1
36
+ ), [A, E] = R({}), l = $(null), z = $([]), v = (t) => {
37
+ g.includes(t) || (c || x(t), b(o[t], t));
38
+ }, w = (t) => {
39
+ if (!l.current || !t || r === "button") return;
40
+ const e = l.current.getBoundingClientRect();
41
+ if (e.width === 0) {
42
+ requestAnimationFrame(() => w(t));
43
+ return;
38
44
  }
39
- }, C = [
40
- e[`flexHorizontal-${m}`],
41
- o === "button" ? e["tab-items-button"] : e["tab-items"]
42
- ].filter(Boolean).join(" ");
43
- return B(() => {
44
- const t = _.current[s];
45
- t && requestAnimationFrame(() => {
46
- H(t);
45
+ const i = t.getBoundingClientRect();
46
+ E({
47
+ left: `${i.left - e.left}px`,
48
+ width: `${i.width}px`
47
49
  });
48
- }, [s, c.length]), /* @__PURE__ */ w(
50
+ }, a = () => {
51
+ const t = z.current[h] ?? null;
52
+ requestAnimationFrame(
53
+ () => requestAnimationFrame(() => w(t))
54
+ );
55
+ };
56
+ u(() => {
57
+ c && a();
58
+ }, [_]), k(() => {
59
+ a();
60
+ }, [h, m, o.length]), u(() => {
61
+ c || x(C(f, (o.length || 1) - 1));
62
+ }, [f, o.length, c]), u(() => {
63
+ var t, e;
64
+ (e = (t = document.fonts) == null ? void 0 : t.ready) == null || e.then(() => a());
65
+ }, []), u(() => {
66
+ const t = () => a();
67
+ return window.addEventListener("resize", t), () => window.removeEventListener("resize", t);
68
+ }, []), u(() => {
69
+ if (!l.current) return;
70
+ const t = new ResizeObserver(() => a());
71
+ return t.observe(l.current), () => t.disconnect();
72
+ }, []);
73
+ const F = [
74
+ n[`flexHorizontal-${m}`],
75
+ r === "button" ? n["tab-items-button"] : n["tab-items"]
76
+ ].filter(Boolean).join(" ");
77
+ return /* @__PURE__ */ j(
49
78
  "div",
50
79
  {
51
- className: `tab ${e["tab-container"]} ${e[`tab-container-${o}`]} ${x && e["tab-full-width"]}`,
52
- ref: r,
80
+ className: `tab ${n["tab-container"]} ${n[`tab-container-${r}`]} ${H && n["tab-full-width"]}`,
81
+ ref: l,
53
82
  children: [
54
- /* @__PURE__ */ l("div", { className: C, children: c.map((t, n) => {
55
- const i = b.includes(n), a = n === s;
56
- return /* @__PURE__ */ l(
83
+ /* @__PURE__ */ s("div", { className: F, children: o.map((t, e) => {
84
+ const i = g.includes(e), d = e === h;
85
+ return /* @__PURE__ */ s(
57
86
  "div",
58
87
  {
59
- ref: (N) => _.current[n] = N,
88
+ ref: (S) => z.current[e] = S,
60
89
  className: `
61
- ${o === "button" && a ? e["selected-button"] : ""}
62
- ${i ? e["tab-disabled"] : ""}
90
+ ${r === "button" && d ? n["selected-button"] : ""}
91
+ ${i ? n["tab-disabled"] : ""}
63
92
  `,
64
- children: o === "icon" ? /* @__PURE__ */ l(
65
- S,
93
+ children: r === "icon" ? /* @__PURE__ */ s(
94
+ B,
66
95
  {
67
96
  mode: "icon",
68
97
  size: "s",
69
- selected: a,
70
- onClick: () => d(n),
98
+ selected: d,
99
+ onClick: () => v(e),
71
100
  disabled: i,
72
101
  children: t
73
102
  }
74
- ) : /* @__PURE__ */ l("div", { className: a ? e["selected-text"] : void 0, children: /* @__PURE__ */ l(
75
- p,
103
+ ) : /* @__PURE__ */ s("div", { className: d ? n["selected-text"] : void 0, children: /* @__PURE__ */ s(
104
+ q,
76
105
  {
77
106
  size: "s",
78
107
  label: t,
79
- mode: o === "text" ? "text" : "ghost",
80
- selected: a,
81
- onClick: () => d(n),
108
+ mode: r === "text" ? "text" : "ghost",
109
+ selected: d,
110
+ onClick: () => v(e),
82
111
  disabled: i
83
112
  }
84
113
  ) })
85
114
  },
86
- n
115
+ e
87
116
  );
88
117
  }) }),
89
- o !== "button" && /* @__PURE__ */ l("div", { ref: R, className: e.underline, style: z })
118
+ r !== "button" && /* @__PURE__ */ s("div", { className: n.underline, style: A })
90
119
  ]
91
120
  }
92
121
  );
93
122
  };
94
123
  export {
95
- q as Tabs
124
+ D as Tabs
96
125
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@situaction/traq-ui-ste",
3
- "version": "1.2.7",
3
+ "version": "1.2.8",
4
4
  "description": "library react component Situaction",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",