@uxf/ui 11.21.5 → 11.22.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/css/tabs.css CHANGED
@@ -1,107 +1,154 @@
1
+ :root {
2
+ --uxf-tabs-spacing: theme("spacing.4");
3
+
4
+ /** button list */
5
+ --uxf-tabs-button-list-border-radius: theme("borderRadius.lg");
6
+ --uxf-tabs-button-list-border-width: 1px;
7
+ --uxf-tabs-button-list-background-color: unset;
8
+ --uxf-tabs-button-list-font-size: theme("fontSize.base");
9
+ --uxf-tabs-button-list-font-weight: theme("fontWeight.semibold");
10
+ --uxf-tabs-button-list-padding: theme("spacing.1");
11
+
12
+ /** button */
13
+ --uxf-tabs-button-cursor: pointer;
14
+ --uxf-tabs-button-padding: theme("spacing.3");
15
+ --uxf-tabs-button-color: theme("colors.lightHigh");
16
+ --uxf-tabs-button-border: unset;
17
+ --uxf-tabs-button-border-radius: theme("borderRadius.md");
18
+
19
+ /** button active */
20
+ --uxf-tabs-button-active-color: theme("colors.lightHigh");
21
+ --uxf-tabs-button-active-border: unset;
22
+ --uxf-tabs-button-active-background-color: theme("colors.white");
23
+ --uxf-tabs-button-underline-color: theme("colors.primary.500");
24
+ --uxf-tabs-button-underline-width: 2px;
25
+
26
+ /** button hover */
27
+ --uxf-tabs-button-hover-color: theme("colors.lightHigh");
28
+ --uxf-tabs-button-hover-background-color: theme("colors.neutral.100");
29
+
30
+ /** button disabled */
31
+ --uxf-tabs-button-disabled-cursor: not-allowed;
32
+ --uxf-tabs-button-disabled-color: theme("colors.lightLow");
33
+ --uxf-tabs-button-disabled-background-color: none;
34
+ }
35
+
1
36
  .uxf-tabs {
2
- @apply w-full;
37
+ display: flex;
38
+ gap: var(--uxf-tabs-spacing);
3
39
 
4
- &--grow {
5
- .uxf-tabs__tab {
6
- @apply grow;
7
- }
40
+ &--variant-segmented {
41
+ --uxf-tabs-button-list-background-color: theme("colors.neutral.100");
42
+ --uxf-tabs-button-active-border: 1px solid theme("colors.neutral.200");
43
+ --uxf-tabs-button-border: 1px solid theme("colors.neutral.100");
8
44
  }
9
45
 
10
- &__tab-list__wrapper {
11
- @apply mb-6 w-full overflow-auto;
46
+ &--horizontal {
47
+ flex-direction: column;
48
+ }
12
49
 
13
- &--default {
14
- @apply relative before:pointer-events-none before:absolute before:bottom-0 before:w-full before:border-b-2
15
- before:border-b-gray-100;
50
+ &__button-list {
51
+ background-color: var(--uxf-tabs-button-list-background-color);
52
+ display: flex;
53
+ font-size: var(--uxf-tabs-button-list-font-size);
54
+ font-weight: var(--uxf-tabs-button-list-font-weight);
55
+ padding: var(--uxf-tabs-button-list-padding);
56
+ scrollbar-width: none;
57
+ white-space: nowrap;
16
58
 
17
- :root .dark & {
18
- @apply before:border-b-gray-800;
19
- }
20
- }
59
+ &--variant-default {
60
+ border-color: theme("colors.neutral.200");
61
+ border-style: solid;
21
62
 
22
- &--segmented {
23
- @apply rounded-lg bg-gray-100;
63
+ &.uxf-tabs__button-list--horizontal {
64
+ border-bottom-width: var(--uxf-tabs-button-list-border-width);
65
+ overflow-x: auto;
66
+ }
24
67
 
25
- :root .dark & {
26
- @apply bg-gray-700;
68
+ &.uxf-tabs__button-list--vertical {
69
+ border-left-width: var(--uxf-tabs-button-list-border-width);
70
+ flex-direction: column;
27
71
  }
28
72
  }
29
- }
30
73
 
31
- &__tab-list {
32
- @apply flex w-full items-center overflow-x-auto whitespace-nowrap text-base font-semibold;
74
+ &--variant-segmented {
75
+ border: 1px solid theme("colors.neutral.200");
76
+ border-radius: var(--uxf-tabs-button-list-border-radius);
33
77
 
34
- scrollbar-width: none;
35
-
36
- &::-webkit-scrollbar {
37
- display: none;
38
- }
39
-
40
- &--default {
41
- @apply space-x-2 px-1 py-1.5;
42
- }
78
+ &.uxf-tabs__button-list--horizontal {
79
+ overflow-x: auto;
80
+ }
43
81
 
44
- &--segmented {
45
- @apply space-x-1 p-1;
82
+ &.uxf-tabs__button-list--vertical {
83
+ flex-direction: column;
84
+ }
46
85
  }
47
86
  }
48
87
 
49
- &__tab {
50
- @apply is-disabled:pointer-events-none inline-flex cursor-pointer items-center justify-center overflow-visible whitespace-nowrap px-2
51
- py-2 text-center outline-none
52
- transition-colors focus-visible:ring-2 focus-visible:ring-offset-1;
88
+ &__button {
89
+ border: var(--uxf-tabs-button-border);
90
+ border-radius: var(--uxf-tabs-button-border-radius);
91
+ color: var(--uxf-tabs-button-color);
92
+ cursor: var(--uxf-tabs-button-cursor);
93
+ padding: var(--uxf-tabs-button-padding);
53
94
 
54
- &--default {
55
- @apply text-lightMedium focus-visible:ring-primary relative rounded-lg before:absolute before:bottom-[-6px]
56
- before:w-full before:border-b-2
57
- before:opacity-0 before:transition hover:bg-gray-100;
95
+ &--vertical {
96
+ text-align: left;
97
+ }
58
98
 
59
- :root .dark & {
60
- @apply text-darkMedium focus-visible:ring-primary hover:bg-gray-800
61
- focus-visible:ring-offset-gray-900;
62
- }
99
+ &--variant-default {
100
+ position: relative;
63
101
 
64
102
  &.is-active {
65
- @apply text-lightHigh before:border-b-primary before:opacity-100 hover:bg-transparent;
103
+ &::before {
104
+ border-color: var(--uxf-tabs-button-underline-color);
105
+ content: "";
106
+ position: absolute;
107
+ }
66
108
 
67
- :root .dark & {
68
- @apply text-darkHigh before:border-b-primary hover:bg-transparent;
109
+ &.uxf-tabs__button--horizontal {
110
+ &::before {
111
+ border-bottom-style: solid;
112
+ border-bottom-width: var(--uxf-tabs-button-underline-width);
113
+ bottom: calc(-1 * var(--uxf-tabs-button-list-padding));
114
+ left: 0;
115
+ width: 100%;
116
+ }
69
117
  }
70
- }
71
118
 
72
- &.is-disabled {
73
- @apply text-lightLow;
119
+ &.uxf-tabs__button--vertical {
120
+ text-align: left;
74
121
 
75
- :root .dark & {
76
- @apply text-darkLow;
122
+ &::before {
123
+ border-left-style: solid;
124
+ border-left-width: var(--uxf-tabs-button-underline-width);
125
+ height: 100%;
126
+ left: calc(-1 * var(--uxf-tabs-button-list-padding));
127
+ top: 0;
128
+ }
77
129
  }
78
130
  }
79
131
  }
80
132
 
81
- &--segmented {
82
- @apply text-lightMedium hover:bg-primary-100 hover:text-primary-600 focus-visible:ring-primary rounded
83
- bg-gray-100 focus-visible:ring-offset-gray-100;
84
-
85
- :root .dark & {
86
- @apply text-darkMedium focus-visible:ring-primary bg-gray-700 hover:bg-gray-800
87
- focus-visible:ring-offset-gray-700;
88
- }
89
-
90
- &.is-active {
91
- @apply bg-primary text-white;
133
+ &:hover {
134
+ background-color: var(--uxf-tabs-button-hover-background-color);
135
+ }
92
136
 
93
- :root .dark & {
94
- @apply bg-primary text-white;
95
- }
96
- }
137
+ &.is-active {
138
+ background-color: var(--uxf-tabs-button-active-background-color);
139
+ border: var(--uxf-tabs-button-active-border);
140
+ color: var(--uxf-tabs-button-active-color);
141
+ }
97
142
 
98
- &.is-disabled {
99
- @apply text-gray-400;
143
+ &.is-disabled {
144
+ color: var(--uxf-tabs-button-disabled-color);
145
+ cursor: var(--uxf-tabs-button-disabled-cursor);
146
+ }
147
+ }
100
148
 
101
- :root .dark & {
102
- @apply text-gray-500;
103
- }
104
- }
149
+ &__panel {
150
+ &--is-hidden {
151
+ display: none;
105
152
  }
106
153
  }
107
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/ui",
3
- "version": "11.21.5",
3
+ "version": "11.22.1",
4
4
  "description": "",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,10 +17,10 @@
17
17
  "dependencies": {
18
18
  "@floating-ui/react": "0.26.9",
19
19
  "@headlessui/react": "1.7.14",
20
- "@uxf/core": "11.21.5",
21
- "@uxf/core-react": "11.21.5",
20
+ "@uxf/core": "11.22.0",
21
+ "@uxf/core-react": "11.22.0",
22
22
  "@uxf/datepicker": "11.11.3",
23
- "@uxf/styles": "11.21.5",
23
+ "@uxf/styles": "11.22.0",
24
24
  "color2k": "2.0.3",
25
25
  "dayjs": "1.11.10",
26
26
  "jump.js": "1.0.2",
package/tabs/README.md CHANGED
@@ -3,5 +3,44 @@
3
3
  ## CSS dependencies
4
4
 
5
5
  ```css
6
- @import url("@uxf/ui/tabs/tabs.css");
6
+ @import url("@uxf/ui/css/tabs.css");
7
+ ```
8
+
9
+ ## Usage
10
+
11
+ ### Basic tabs
12
+
13
+ ```tsx
14
+ import { Tabs } from "@uxf/ui/tabs";
15
+
16
+ function Example() {
17
+ const [activeTab, setActiveTab] = useState("tab-1");
18
+
19
+ return (
20
+ <Tabs value={activeTab} onChange={setActiveTab}>
21
+ <Tabs.Panel name="tab-1" label="Default panel">...</Tabs.Panel>
22
+ <Tabs.Panel name="tab-2" label="Disabled panel" isDisabled>...</Tabs.Panel>
23
+ <Tabs.Panel name="tab-3" label="Hidden panel" isHidden>...</Tabs.Panel>
24
+ <Tabs.Panel name="tab-4" label="Always mounted panel" isAlwaysMounted>...</Tabs.Panel>
25
+ <Tabs.Panel name="tab-5" label={({isActive}) => <div>custom button</div>}>...</Tabs.Panel>
26
+ </Tabs>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ### Only buttons
32
+
33
+ ```tsx
34
+ import { Tabs } from "@uxf/ui/tabs";
35
+
36
+ function Example() {
37
+ const [activeTab, setActiveTab] = useState("tab-1");
38
+
39
+ return (
40
+ <Tabs value={activeTab} onChange={setActiveTab}>
41
+ <Tabs.Panel name="tab-1" label="Tab 1" />
42
+ <Tabs.Panel name="tab-2" label="Tab 2" />
43
+ </Tabs>
44
+ );
45
+ }
7
46
  ```
@@ -0,0 +1,12 @@
1
+ import React, { CSSProperties, ForwardedRef, ReactNode } from "react";
2
+ interface TabsButtonListProps {
3
+ className?: string;
4
+ isVertical?: boolean;
5
+ children: ReactNode;
6
+ onKeyDown: React.KeyboardEventHandler<HTMLDivElement>;
7
+ variant?: string;
8
+ style?: CSSProperties;
9
+ }
10
+ export declare function Component(props: TabsButtonListProps, ref: ForwardedRef<HTMLDivElement>): React.JSX.Element;
11
+ export declare const TabsButtonList: React.ForwardRefExoticComponent<TabsButtonListProps & React.RefAttributes<HTMLDivElement>>;
12
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.TabsButtonList = exports.Component = void 0;
27
+ const cx_1 = require("@uxf/core/utils/cx");
28
+ const react_1 = __importStar(require("react"));
29
+ function Component(props, ref) {
30
+ var _a;
31
+ return (
32
+ // eslint-disable-next-line jsx-a11y/interactive-supports-focus
33
+ react_1.default.createElement("div", { ref: ref, className: (0, cx_1.cx)("uxf-tabs__button-list", props.isVertical ? "uxf-tabs__button-list--vertical" : "uxf-tabs__button-list--horizontal", `uxf-tabs__button-list--variant-${(_a = props.variant) !== null && _a !== void 0 ? _a : "default"}`, props.className), role: "tablist", onKeyDown: props.onKeyDown, style: props.style }, props.children));
34
+ }
35
+ exports.Component = Component;
36
+ exports.TabsButtonList = (0, react_1.forwardRef)(Component);
@@ -0,0 +1,17 @@
1
+ import { Nullish } from "@uxf/core/types";
2
+ import { TabsVariant } from "@uxf/ui/tabs/theme";
3
+ import React, { ForwardedRef, ReactNode } from "react";
4
+ interface TabsButtonProps {
5
+ className?: string;
6
+ id: string;
7
+ isActive: boolean;
8
+ isDisabled: boolean | Nullish;
9
+ isHidden: boolean | Nullish;
10
+ isVertical: boolean | Nullish;
11
+ onClick: () => void;
12
+ children: ReactNode;
13
+ variant?: TabsVariant;
14
+ }
15
+ export declare function Component(props: TabsButtonProps, ref: ForwardedRef<HTMLButtonElement>): React.JSX.Element | null;
16
+ export declare const TabsButton: React.ForwardRefExoticComponent<TabsButtonProps & React.RefAttributes<HTMLButtonElement>>;
17
+ export {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.TabsButton = exports.Component = void 0;
27
+ const classes_1 = require("@uxf/core/constants/classes");
28
+ const cx_1 = require("@uxf/core/utils/cx");
29
+ const react_1 = __importStar(require("react"));
30
+ function Component(props, ref) {
31
+ var _a;
32
+ if (props.isHidden) {
33
+ return null;
34
+ }
35
+ const className = (0, cx_1.cx)("uxf-tabs__button", `uxf-tabs__button--variant-${(_a = props.variant) !== null && _a !== void 0 ? _a : "default"}`, props.isVertical ? "uxf-tabs__button--vertical" : "uxf-tabs__button--horizontal", props.isActive && `uxf-tabs__button--${classes_1.CLASSES.IS_ACTIVE} ${classes_1.CLASSES.IS_ACTIVE}`, props.isDisabled && `uxf-tabs__button--${classes_1.CLASSES.IS_DISABLED} ${classes_1.CLASSES.IS_DISABLED}`, props.className);
36
+ return (react_1.default.createElement("button", { id: props.id, ref: ref, className: className, onClick: props.isDisabled ? undefined : props.onClick, role: "tab", tabIndex: props.isActive ? undefined : -1, "aria-selected": props.isActive }, props.children));
37
+ }
38
+ exports.Component = Component;
39
+ exports.TabsButton = (0, react_1.forwardRef)(Component);
@@ -0,0 +1,11 @@
1
+ import { Nullish } from "@uxf/core/types";
2
+ import React, { ReactNode } from "react";
3
+ interface TabsButtonProps {
4
+ className?: string;
5
+ isActive: boolean;
6
+ isHidden: boolean | Nullish;
7
+ isAlwaysMounted: boolean | Nullish;
8
+ children?: ReactNode;
9
+ }
10
+ export declare function TabsPanel(props: TabsButtonProps): React.JSX.Element | null;
11
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TabsPanel = void 0;
7
+ const classes_1 = require("@uxf/core/constants/classes");
8
+ const cx_1 = require("@uxf/core/utils/cx");
9
+ const react_1 = __importDefault(require("react"));
10
+ function TabsPanel(props) {
11
+ return props.isAlwaysMounted || props.isActive ? (react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-tabs__panel", !props.isActive && `uxf-tabs__panel--${classes_1.CLASSES.IS_HIDDEN} ${classes_1.CLASSES.IS_HIDDEN}`, props.className) }, props.children)) : null;
12
+ }
13
+ exports.TabsPanel = TabsPanel;
@@ -0,0 +1,2 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ export declare function TabsPanels(props: PropsWithChildren): React.JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TabsPanels = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ function TabsPanels(props) {
9
+ return react_1.default.createElement("div", { className: "uxf-tabs__panels" }, props.children);
10
+ }
11
+ exports.TabsPanels = TabsPanels;
@@ -0,0 +1,10 @@
1
+ import { TabsVariant } from "@uxf/ui/tabs/theme";
2
+ import React, { ReactNode } from "react";
3
+ interface TabsRootProps {
4
+ className?: string;
5
+ isVertical?: boolean;
6
+ children: ReactNode;
7
+ variant?: TabsVariant;
8
+ }
9
+ export declare function TabsRoot(props: TabsRootProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TabsRoot = void 0;
7
+ const cx_1 = require("@uxf/core/utils/cx");
8
+ const react_1 = __importDefault(require("react"));
9
+ function TabsRoot(props) {
10
+ var _a;
11
+ return (react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-tabs", `uxf-tabs--variant-${(_a = props.variant) !== null && _a !== void 0 ? _a : "default"}`, props.isVertical ? "uxf-tabs--vertical" : "uxf-tabs--horizontal", props.className) }, props.children));
12
+ }
13
+ exports.TabsRoot = TabsRoot;
package/tabs/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- export { Tabs } from "./tabs";
2
- export type { TabsPanelProps, TabsProps } from "./tabs";
1
+ export * from "./tabs";
package/tabs/index.js CHANGED
@@ -1,5 +1,17 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Tabs = void 0;
4
- var tabs_1 = require("./tabs");
5
- Object.defineProperty(exports, "Tabs", { enumerable: true, get: function () { return tabs_1.Tabs; } });
17
+ __exportStar(require("./tabs"), exports);
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from "react";
2
+ type ButtonRendererProps = {
3
+ isActive: boolean;
4
+ };
5
+ type ButtonRenderer = (props: ButtonRendererProps) => ReactNode;
6
+ export interface PanelProps {
7
+ label: ReactNode | ButtonRenderer;
8
+ classNameButton?: string;
9
+ classNamePanel?: string;
10
+ name: string;
11
+ isDisabled?: boolean;
12
+ isHidden?: boolean;
13
+ isAlwaysMounted?: boolean;
14
+ children?: ReactNode;
15
+ }
16
+ export declare function Panel(props: PanelProps): null;
17
+ export declare namespace Panel {
18
+ var displayName: string;
19
+ }
20
+ export declare const TABS_PANEL_DISPLAY_NAME = "UxfUiTabPanel";
21
+ export {};
package/tabs/panel.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TABS_PANEL_DISPLAY_NAME = exports.Panel = void 0;
4
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
+ function Panel(props) {
6
+ // this is never rendered
7
+ return null;
8
+ }
9
+ exports.Panel = Panel;
10
+ exports.TABS_PANEL_DISPLAY_NAME = "UxfUiTabPanel";
11
+ Panel.displayName = exports.TABS_PANEL_DISPLAY_NAME;
package/tabs/tabs.d.ts CHANGED
@@ -1,23 +1,20 @@
1
- import React, { CSSProperties, ReactNode } from "react";
2
- export interface TabsPanelProps {
1
+ import { TabsVariant } from "@uxf/ui/tabs/theme";
2
+ import React, { ReactNode } from "react";
3
+ import { Panel } from "./panel";
4
+ export interface TabsProps<TValue> {
3
5
  className?: string;
4
- disabled?: boolean;
5
- style?: CSSProperties;
6
- title: ReactNode;
7
- unmount?: boolean;
6
+ classNameButtonList?: string;
7
+ children: ReactNode;
8
+ value: TValue;
9
+ onChange: (value: TValue) => void;
10
+ isVertical?: boolean;
11
+ variant?: TabsVariant;
8
12
  }
9
- export interface TabsProps {
10
- className?: string;
11
- customTabListContent?: ReactNode;
12
- defaultIndex?: number;
13
- grow?: boolean;
14
- onChange?: (index: number) => void;
15
- selectedIndex?: number;
16
- tabListClassName?: string;
17
- variant?: "default" | "segmented";
13
+ declare function Root<TValue>(props: TabsProps<TValue>): React.JSX.Element;
14
+ declare namespace Root {
15
+ var displayName: string;
18
16
  }
19
- export declare const Tabs: React.ForwardRefExoticComponent<TabsProps & {
20
- children?: React.ReactNode;
21
- } & React.RefAttributes<HTMLDivElement>> & {
22
- Panel: React.FC<React.PropsWithChildren<TabsPanelProps>>;
17
+ export declare const Tabs: typeof Root & {
18
+ Panel: typeof Panel;
23
19
  };
20
+ export {};
package/tabs/tabs.js CHANGED
@@ -24,47 +24,50 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Tabs = void 0;
27
- const react_1 = require("@headlessui/react");
28
27
  const use_mouse_drag_to_scroll_1 = require("@uxf/core-react/hooks/use-mouse-drag-to-scroll");
29
- const classes_1 = require("@uxf/core/constants/classes");
30
- const cx_1 = require("@uxf/core/utils/cx");
31
- const react_2 = __importStar(require("react"));
32
- const Panel = (props) => (react_2.default.createElement("div", { className: props.className, style: props.style }, props.children));
33
- Panel.displayName = "UxfUiTabPanel";
34
- const TabsRoot = (0, react_2.forwardRef)((props, ref) => {
35
- var _a, _b;
36
- const tabsClassName = (0, cx_1.cx)("uxf-tabs", props.grow && "uxf-tabs--grow", props.className);
37
- const containerRef = (0, react_2.useRef)(null);
38
- const dragStyle = (0, use_mouse_drag_to_scroll_1.useMouseDragToScroll)(containerRef);
39
- const [hasOverflow, setHasOverflow] = (0, react_2.useState)();
40
- (0, react_2.useEffect)(() => {
41
- const node = containerRef.current;
42
- if (!node) {
43
- return;
28
+ const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
29
+ const react_1 = __importStar(require("react"));
30
+ const tabs_button_1 = require("./components/tabs-button");
31
+ const tabs_button_list_1 = require("./components/tabs-button-list");
32
+ const tabs_panel_1 = require("./components/tabs-panel");
33
+ const tabs_panels_1 = require("./components/tabs-panels");
34
+ const tabs_root_1 = require("./components/tabs-root");
35
+ const panel_1 = require("./panel");
36
+ function createId(containerId, tabName) {
37
+ return `${containerId}-${tabName}`;
38
+ }
39
+ function Root(props) {
40
+ const id = (0, react_1.useId)();
41
+ const buttonListRef = (0, react_1.useRef)(null);
42
+ const buttonListStyle = (0, use_mouse_drag_to_scroll_1.useMouseDragToScroll)(buttonListRef);
43
+ const tabPanels = react_1.Children.toArray(props.children).filter((child) => (0, react_1.isValidElement)(child) && child.type.displayName === panel_1.TABS_PANEL_DISPLAY_NAME);
44
+ const allowedTabPanels = tabPanels.filter((panel) => !panel.props.isDisabled && !panel.props.isHidden);
45
+ const tabRefs = (0, react_1.useRef)([]);
46
+ const getAllowedTabRefs = () => tabRefs.current.filter((_, index) => { var _a, _b; return !((_a = tabPanels.at(index)) === null || _a === void 0 ? void 0 : _a.props.isDisabled) && !((_b = tabPanels.at(index)) === null || _b === void 0 ? void 0 : _b.props.isHidden); });
47
+ const selectTab = (newTabIndex) => {
48
+ var _a, _b;
49
+ const newTabName = (_a = allowedTabPanels.at(newTabIndex)) === null || _a === void 0 ? void 0 : _a.props.name;
50
+ if ((0, is_not_nil_1.isNotNil)(newTabName)) {
51
+ props.onChange(newTabName);
52
+ (_b = getAllowedTabRefs().at(newTabIndex)) === null || _b === void 0 ? void 0 : _b.focus();
44
53
  }
45
- const handler = () => setHasOverflow(node.scrollWidth > node.clientWidth);
46
- handler();
47
- window.addEventListener("resize", handler);
48
- return () => {
49
- window.removeEventListener("resize", handler);
50
- };
51
- }, []);
52
- if (react_2.Children.count(props.children) === 0) {
53
- return react_2.default.createElement("div", { className: tabsClassName, ref: ref });
54
- }
55
- const tabPanels = react_2.Children.toArray(props.children).filter((child) => (0, react_2.isValidElement)(child) && child.props.title);
56
- const tabs = tabPanels.map((c) => ({
57
- title: c.props.title,
58
- disabled: c.props.disabled,
59
- }));
60
- return (react_2.default.createElement(react_1.Tab.Group, { as: "div", className: tabsClassName, defaultIndex: props.defaultIndex, onChange: props.onChange, ref: ref, selectedIndex: props.selectedIndex },
61
- react_2.default.createElement(react_1.Tab.List, { className: (0, cx_1.cx)("uxf-tabs__tab-list__wrapper", `uxf-tabs__tab-list__wrapper--${(_a = props.variant) !== null && _a !== void 0 ? _a : "default"}`, props.tabListClassName) },
62
- react_2.default.createElement("div", { className: (0, cx_1.cx)("uxf-tabs__tab-list", `uxf-tabs__tab-list--${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`), ref: containerRef, style: { justifyContent: hasOverflow ? "flex-start" : undefined, ...dragStyle } }, tabs.map((tab, index) => (react_2.default.createElement(react_1.Tab, { disabled: tab.disabled, className: ({ selected }) => {
63
- var _a;
64
- return (0, cx_1.cx)("uxf-tabs__tab", selected && classes_1.CLASSES.IS_ACTIVE, tab.disabled && classes_1.CLASSES.IS_DISABLED, `uxf-tabs__tab--${(_a = props.variant) !== null && _a !== void 0 ? _a : "default"}`);
65
- }, key: `${tab.title}--${index}` }, tab.title)))),
66
- props.customTabListContent),
67
- react_2.default.createElement(react_1.Tab.Panels, { className: "uxf-tabs__panels" }, tabPanels.map((tabPanel, index) => (react_2.default.createElement(react_1.Tab.Panel, { className: "outline-none", key: `${tabPanel}--${index}`, unmount: tabPanel.props.unmount }, tabPanel))))));
68
- });
69
- TabsRoot.displayName = "UxfUiTabs";
70
- exports.Tabs = Object.assign(TabsRoot, { Panel });
54
+ };
55
+ const onKeyDown = (event) => {
56
+ const currentTabIndex = allowedTabPanels.findIndex((panel) => panel.props.name === props.value);
57
+ if ((event.code === "ArrowRight" && !props.isVertical) || (event.code === "ArrowDown" && props.isVertical)) {
58
+ selectTab((currentTabIndex + 1) % allowedTabPanels.length);
59
+ }
60
+ else if ((event.code === "ArrowLeft" && !props.isVertical) ||
61
+ (event.code === "ArrowUp" && props.isVertical)) {
62
+ selectTab((currentTabIndex - 1) % allowedTabPanels.length);
63
+ }
64
+ };
65
+ const hasPanelWithChildren = (0, is_not_nil_1.isNotNil)(tabPanels.find((panel) => (0, is_not_nil_1.isNotNil)(panel.props.children)));
66
+ return (react_1.default.createElement(tabs_root_1.TabsRoot, { className: props.className, isVertical: props.isVertical, variant: props.variant },
67
+ react_1.default.createElement(tabs_button_list_1.TabsButtonList, { isVertical: props.isVertical, variant: props.variant, onKeyDown: onKeyDown, ref: buttonListRef, style: buttonListStyle, className: props.classNameButtonList }, tabPanels.map((panel, index) => (react_1.default.createElement(tabs_button_1.TabsButton, { key: panel.props.name, ref: (ref) => (tabRefs.current[index] = ref), className: panel.props.classNameButton, id: createId(id, panel.props.name), isActive: panel.props.name === props.value, isDisabled: panel.props.isDisabled, isHidden: panel.props.isHidden, isVertical: props.isVertical, onClick: () => props.onChange(panel.props.name), variant: props.variant }, typeof panel.props.label === "function"
68
+ ? panel.props.label({ isActive: panel.props.name === props.value })
69
+ : panel.props.label)))),
70
+ hasPanelWithChildren && (react_1.default.createElement(tabs_panels_1.TabsPanels, null, tabPanels.map((panel) => (react_1.default.createElement(tabs_panel_1.TabsPanel, { key: panel.props.name, className: panel.props.classNamePanel, isActive: panel.props.name === props.value, isHidden: panel.props.isHidden, isAlwaysMounted: panel.props.isAlwaysMounted }, panel.props.children)))))));
71
+ }
72
+ Root.displayName = "UxfUiTabs";
73
+ exports.Tabs = Object.assign(Root, { Panel: panel_1.Panel });
package/tabs/tabs.spec.js CHANGED
@@ -6,4 +6,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const snap_test_1 = require("../utils/snap-test");
8
8
  const tabs_stories_1 = require("./tabs.stories");
9
- (0, snap_test_1.snapTest)("render stories", react_1.default.createElement(tabs_stories_1.Default, null));
9
+ (0, snap_test_1.snapTest)("render story Default", react_1.default.createElement(tabs_stories_1.Default, null));
10
+ (0, snap_test_1.snapTest)("render story Segmented", react_1.default.createElement(tabs_stories_1.Segmented, null));
@@ -1,11 +1,3 @@
1
1
  import React from "react";
2
- declare const _default: {
3
- title: string;
4
- component: React.ForwardRefExoticComponent<import("./tabs").TabsProps & {
5
- children?: React.ReactNode;
6
- } & React.RefAttributes<HTMLDivElement>> & {
7
- Panel: React.FC<React.PropsWithChildren<import("./tabs").TabsPanelProps>>;
8
- };
9
- };
10
- export default _default;
11
2
  export declare function Default(): React.JSX.Element;
3
+ export declare function Segmented(): React.JSX.Element;
@@ -1,47 +1,69 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ "use client";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
4
25
  };
5
26
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Default = void 0;
7
- const react_1 = __importDefault(require("react"));
27
+ exports.Segmented = exports.Default = void 0;
28
+ const react_1 = __importStar(require("react"));
29
+ const icon_1 = require("../icon");
30
+ const toggle_1 = require("../toggle");
8
31
  const tabs_1 = require("./tabs");
9
- exports.default = {
10
- title: "UI/Tabs",
11
- component: tabs_1.Tabs,
12
- };
32
+ var TabEnum;
33
+ (function (TabEnum) {
34
+ TabEnum["Basic"] = "tab-basic";
35
+ TabEnum["Disabled"] = "tab-disabled";
36
+ TabEnum["Hidden"] = "tab-hidden";
37
+ TabEnum["AlwaysMounted"] = "tab-always-mounted";
38
+ TabEnum["Custom"] = "tab-custom";
39
+ })(TabEnum || (TabEnum = {}));
13
40
  function Default() {
14
- const testTabs = (react_1.default.createElement(react_1.default.Fragment, null,
15
- react_1.default.createElement("div", { className: "flex items-center gap-6" },
16
- react_1.default.createElement("div", null,
17
- react_1.default.createElement("p", { className: "mb-4 text-gray-500" }, "Default"),
18
- react_1.default.createElement(tabs_1.Tabs, null,
19
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 1 title", className: "grid h-12 w-56 place-items-center bg-red-300" }, "content of the Tab 1"),
20
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 2 title", className: "grid h-12 w-56 place-items-center bg-green-300" }, "content of the Tab 2"),
21
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 3 title", className: "grid h-12 w-56 place-items-center bg-amber-300" }, "content of the Tab 3"),
22
- react_1.default.createElement(tabs_1.Tabs.Panel, { className: "grid h-12 w-56 place-items-center bg-gray-300", disabled: true, title: "Tab 4 title - disabled" }, "content of the Tab 4 which is disabled"))),
23
- react_1.default.createElement("div", null,
24
- react_1.default.createElement("p", { className: "mb-4 text-gray-500" }, "Segmented"),
25
- react_1.default.createElement(tabs_1.Tabs, { variant: "segmented" },
26
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 1 title", className: "grid h-12 w-56 place-items-center bg-red-300" }, "content of the Tab 1"),
27
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 2 title", className: "grid h-12 w-56 place-items-center bg-green-300" }, "content of the Tab 2"),
28
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 3 title", className: "grid h-12 w-56 place-items-center bg-amber-300" }, "content of the Tab 3"),
29
- react_1.default.createElement(tabs_1.Tabs.Panel, { className: "grid h-12 w-56 place-items-center bg-gray-300", disabled: true, title: "Tab 4 title - disabled" }, "content of the Tab 4 which is disabled")))),
30
- react_1.default.createElement("div", { className: "w-[600px]" },
31
- react_1.default.createElement("p", { className: "mb-4 text-gray-500" }, "Default grow"),
32
- react_1.default.createElement(tabs_1.Tabs, { grow: true },
33
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 1 title", className: "grid h-12 w-56 place-items-center bg-red-300" }, "content of the Tab 1"),
34
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 2 title", className: "grid h-12 w-56 place-items-center bg-green-300" }, "content of the Tab 2"),
35
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 3 title", className: "grid h-12 w-56 place-items-center bg-amber-300" }, "content of the Tab 3"),
36
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 4 title", className: "grid h-12 w-56 place-items-center bg-gray-300" }, "content of the Tab 4"))),
37
- react_1.default.createElement("div", { className: "w-[600px]" },
38
- react_1.default.createElement("p", { className: "mb-4 text-gray-500" }, "Segmented grow"),
39
- react_1.default.createElement(tabs_1.Tabs, { variant: "segmented", grow: true },
40
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 1 title", className: "grid h-12 w-56 place-items-center bg-red-300" }, "content of the Tab 1"),
41
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 2 title", className: "grid h-12 w-56 place-items-center bg-green-300" }, "content of the Tab 2"),
42
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 3 title", className: "grid h-12 w-56 place-items-center bg-amber-300" }, "content of the Tab 3"),
43
- react_1.default.createElement(tabs_1.Tabs.Panel, { title: "Tab 4 title", className: "grid h-12 w-56 place-items-center bg-gray-300" }, "content of the Tab 4")))));
41
+ const [activeTab, setActiveTab] = (0, react_1.useState)(TabEnum.Basic);
42
+ const [isVertical, setIsVertical] = (0, react_1.useState)(false);
44
43
  return (react_1.default.createElement(react_1.default.Fragment, null,
45
- react_1.default.createElement("div", { className: "rounded p-8" }, testTabs)));
44
+ react_1.default.createElement(toggle_1.Toggle, { label: "Vertical", value: isVertical, onChange: setIsVertical, name: "isVertical", className: "mb-5" }),
45
+ react_1.default.createElement(tabs_1.Tabs, { value: activeTab, onChange: setActiveTab, isVertical: isVertical },
46
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: TabEnum.Basic, label: "Basic" }, "Basic tab"),
47
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: TabEnum.Disabled, label: "Disabled", isDisabled: true }, "Disabled tab"),
48
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: TabEnum.Hidden, label: "Hidden", isHidden: true }, "Hidden"),
49
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: TabEnum.AlwaysMounted, label: "Always mounted", isAlwaysMounted: true }, "Always mounted tab"),
50
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: TabEnum.Custom, label: () => (react_1.default.createElement("span", { className: "flex items-center gap-2" },
51
+ react_1.default.createElement(icon_1.Icon, { name: "camera", className: "size-4" }),
52
+ " Custom button")) }, "Custom button tab"))));
46
53
  }
47
54
  exports.Default = Default;
55
+ function Segmented() {
56
+ const [activeTab, setActiveTab] = (0, react_1.useState)("tab-basic");
57
+ const [isVertical, setIsVertical] = (0, react_1.useState)(false);
58
+ return (react_1.default.createElement(react_1.default.Fragment, null,
59
+ react_1.default.createElement(toggle_1.Toggle, { label: "Vertical", value: isVertical, onChange: setIsVertical, name: "isVertical", className: "mb-5" }),
60
+ react_1.default.createElement(tabs_1.Tabs, { value: activeTab, onChange: setActiveTab, variant: "segmented", isVertical: isVertical },
61
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: "tab-basic", label: "Basic" }, "Basic tab"),
62
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: "tab-disabled", label: "Disabled", isDisabled: true }, "Disabled tab"),
63
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: "tab-hidden", label: "Hidden", isHidden: true }, "Hidden"),
64
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: "tab-always-mounted", label: "Always mounted", isAlwaysMounted: true }, "Always mounted tab"),
65
+ react_1.default.createElement(tabs_1.Tabs.Panel, { name: "tab-custom", label: () => (react_1.default.createElement("span", { className: "flex items-center gap-2" },
66
+ react_1.default.createElement(icon_1.Icon, { name: "camera", className: "size-4" }),
67
+ " Custom button")) }, "Custom button tab"))));
68
+ }
69
+ exports.Segmented = Segmented;
@@ -0,0 +1,5 @@
1
+ export interface TabsVariants {
2
+ default: true;
3
+ segmented: true;
4
+ }
5
+ export type TabsVariant = keyof TabsVariants;
package/tabs/theme.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });