@tsed/react-formio 3.0.0-alpha.10 → 3.0.0-alpha.12
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/dist/atoms/icon/Icon.js.map +1 -1
- package/dist/chunks/index.js +33 -30
- package/dist/chunks/index.js.map +1 -1
- package/dist/chunks/index.module.js +16 -16
- package/dist/chunks/index.module.js.map +1 -1
- package/dist/chunks/react-select-animated.esm.js +1204 -1101
- package/dist/chunks/react-select-animated.esm.js.map +1 -1
- package/dist/hooks/keyboard.constants.d.ts +38 -0
- package/dist/hooks/keyboard.constants.js +7 -0
- package/dist/hooks/keyboard.constants.js.map +1 -0
- package/dist/hooks/useKeyboardControls.d.ts +12 -0
- package/dist/hooks/useKeyboardControls.js +35 -0
- package/dist/hooks/useKeyboardControls.js.map +1 -0
- package/dist/hooks/useTooltip.js.map +1 -1
- package/dist/interfaces/Operation.d.ts +12 -2
- package/dist/molecules/alert/Alert.js.map +1 -1
- package/dist/molecules/button/Button.d.ts +18 -5
- package/dist/molecules/button/Button.js +22 -26
- package/dist/molecules/button/Button.js.map +1 -1
- package/dist/molecules/card/Card.js +7 -5
- package/dist/molecules/card/Card.js.map +1 -1
- package/dist/molecules/forms/form-control/FormControl.js.map +1 -1
- package/dist/molecules/forms/input-tags/InputTags.js +14 -14
- package/dist/molecules/forms/input-tags/InputTags.js.map +1 -1
- package/dist/molecules/forms/input-tags/components/ChoicesTags.js +26 -26
- package/dist/molecules/forms/input-tags/components/ChoicesTags.js.map +1 -1
- package/dist/molecules/forms/input-tags/components/ReactTags.js +289 -300
- package/dist/molecules/forms/input-tags/components/ReactTags.js.map +1 -1
- package/dist/molecules/forms/input-text/InputText.js +3 -3
- package/dist/molecules/forms/input-text/InputText.js.map +1 -1
- package/dist/molecules/forms/select/Select.js.map +1 -1
- package/dist/molecules/forms/select/components/ChoicesSelect.js +71 -73
- package/dist/molecules/forms/select/components/ChoicesSelect.js.map +1 -1
- package/dist/molecules/forms/select/components/HtmlSelect.js.map +1 -1
- package/dist/molecules/forms/select/components/ReactSelect.js +13 -14
- package/dist/molecules/forms/select/components/ReactSelect.js.map +1 -1
- package/dist/molecules/forms/select/components/choices.template.js +2340 -2257
- package/dist/molecules/forms/select/components/choices.template.js.map +1 -1
- package/dist/molecules/forms/select/hooks/useOptions.js.map +1 -1
- package/dist/molecules/loader/Loader.js.map +1 -1
- package/dist/molecules/modal/Modal.js +23 -24
- package/dist/molecules/modal/Modal.js.map +1 -1
- package/dist/molecules/pagination/Pagination.js +19 -19
- package/dist/molecules/pagination/Pagination.js.map +1 -1
- package/dist/molecules/pagination/PaginationButton.js.map +1 -1
- package/dist/molecules/pagination/utils/getPageNumbers.js.map +1 -1
- package/dist/molecules/table/Table.d.ts +11 -3
- package/dist/molecules/table/Table.js +31 -32
- package/dist/molecules/table/Table.js.map +1 -1
- package/dist/molecules/table/components/DefaultArrowSort.js.map +1 -1
- package/dist/molecules/table/components/DefaultCell.js.map +1 -1
- package/dist/molecules/table/components/DefaultCellFooter.js.map +1 -1
- package/dist/molecules/table/components/DefaultCellHeader.js.map +1 -1
- package/dist/molecules/table/components/DefaultCellOperations.d.ts +12 -4
- package/dist/molecules/table/components/DefaultCellOperations.js +13 -7
- package/dist/molecules/table/components/DefaultCellOperations.js.map +1 -1
- package/dist/molecules/table/components/DefaultFilter.js.map +1 -1
- package/dist/molecules/table/components/DefaultOperationButton.d.ts +12 -4
- package/dist/molecules/table/components/DefaultOperationButton.js +1 -1
- package/dist/molecules/table/components/DefaultOperationButton.js.map +1 -1
- package/dist/molecules/table/filters/RangeFilter.js +23 -24
- package/dist/molecules/table/filters/RangeFilter.js.map +1 -1
- package/dist/molecules/table/filters/SelectFilter.js +11 -13
- package/dist/molecules/table/filters/SelectFilter.js.map +1 -1
- package/dist/molecules/table/filters/TextFieldFilter.js.map +1 -1
- package/dist/molecules/table/hooks/useTable.d.ts +12 -4
- package/dist/molecules/table/hooks/useTable.js +7 -7
- package/dist/molecules/table/hooks/useTable.js.map +1 -1
- package/dist/molecules/table/hooks/useUniqValues.js.map +1 -1
- package/dist/molecules/table/utils/mapFormToColumns.js +20 -21
- package/dist/molecules/table/utils/mapFormToColumns.js.map +1 -1
- package/dist/molecules/tabs/Tab.d.ts +13 -0
- package/dist/molecules/tabs/Tab.js +66 -0
- package/dist/molecules/tabs/Tab.js.map +1 -0
- package/dist/molecules/tabs/TabList.d.ts +2 -0
- package/dist/molecules/tabs/TabList.js +23 -0
- package/dist/molecules/tabs/TabList.js.map +1 -0
- package/dist/molecules/tabs/TabPanel.d.ts +9 -0
- package/dist/molecules/tabs/TabPanel.js +27 -0
- package/dist/molecules/tabs/TabPanel.js.map +1 -0
- package/dist/molecules/tabs/Tabs.d.ts +4 -16
- package/dist/molecules/tabs/Tabs.js +7 -67
- package/dist/molecules/tabs/Tabs.js.map +1 -1
- package/dist/molecules/tabs/TabsBody.d.ts +1 -0
- package/dist/molecules/tabs/TabsBody.js +10 -0
- package/dist/molecules/tabs/TabsBody.js.map +1 -0
- package/dist/molecules/tabs/TabsLegacy.d.ts +17 -0
- package/dist/molecules/tabs/TabsLegacy.js +49 -0
- package/dist/molecules/tabs/TabsLegacy.js.map +1 -0
- package/dist/molecules/tabs/all.d.ts +5 -0
- package/dist/molecules/tabs/all.js +13 -0
- package/dist/molecules/tabs/all.js.map +1 -0
- package/dist/molecules/tabs/context/TabControl.d.ts +52 -0
- package/dist/molecules/tabs/context/TabControl.js +85 -0
- package/dist/molecules/tabs/context/TabControl.js.map +1 -0
- package/dist/molecules/tabs/hooks/tabControl.d.ts +44 -0
- package/dist/molecules/tabs/hooks/tabControl.js +34 -0
- package/dist/molecules/tabs/hooks/tabControl.js.map +1 -0
- package/dist/organisms/form/Form.js.map +1 -1
- package/dist/organisms/form/access/FormAccess.js +41 -41
- package/dist/organisms/form/access/FormAccess.js.map +1 -1
- package/dist/organisms/form/access/FormAccess.schema.js.map +1 -1
- package/dist/organisms/form/access/FormAccess.utils.js +2 -2
- package/dist/organisms/form/access/FormAccess.utils.js.map +1 -1
- package/dist/organisms/form/{action → actions}/FormAction.js +7 -8
- package/dist/organisms/form/actions/FormAction.js.map +1 -0
- package/dist/organisms/form/builder/FormBuilder.js.map +1 -1
- package/dist/organisms/form/builder/FormEdit.d.ts +3 -1
- package/dist/organisms/form/builder/FormEdit.js +38 -35
- package/dist/organisms/form/builder/FormEdit.js.map +1 -1
- package/dist/organisms/form/builder/FormEdit.reducer.js.map +1 -1
- package/dist/organisms/form/builder/FormEditCtas.js +34 -34
- package/dist/organisms/form/builder/FormEditCtas.js.map +1 -1
- package/dist/organisms/form/builder/FormParameters.js.map +1 -1
- package/dist/organisms/form/builder/useFormBuilder.js +41 -38
- package/dist/organisms/form/builder/useFormBuilder.js.map +1 -1
- package/dist/organisms/form/builder/useFormEdit.js +1 -1
- package/dist/organisms/form/builder/useFormEdit.js.map +1 -1
- package/dist/organisms/form/exports/FormExport.d.ts +5 -0
- package/dist/organisms/form/exports/FormExport.js +55 -0
- package/dist/organisms/form/exports/FormExport.js.map +1 -0
- package/dist/organisms/form/preview/FormPreview.d.ts +6 -0
- package/dist/organisms/form/preview/FormPreview.js +11 -0
- package/dist/organisms/form/preview/FormPreview.js.map +1 -0
- package/dist/organisms/form/settings/FormSettings.js +24 -24
- package/dist/organisms/form/settings/FormSettings.js.map +1 -1
- package/dist/organisms/form/settings/FormSettings.schema.js.map +1 -1
- package/dist/organisms/form/settings/FormSettings.utils.js.map +1 -1
- package/dist/organisms/form/useForm.js +664 -661
- package/dist/organisms/form/useForm.js.map +1 -1
- package/dist/organisms/modal/RemoveModal.js +16 -17
- package/dist/organisms/modal/RemoveModal.js.map +1 -1
- package/dist/organisms/table/actions/ActionsTable.js.map +1 -1
- package/dist/organisms/table/forms/FormsTable.js.map +1 -1
- package/dist/organisms/table/forms/components/FormsCell.js.map +1 -1
- package/dist/organisms/table/submissions/SubmissionsTable.d.ts +11 -3
- package/dist/organisms/table/submissions/SubmissionsTable.js +4 -1
- package/dist/organisms/table/submissions/SubmissionsTable.js.map +1 -1
- package/dist/organisms/views/FormViews.d.ts +24 -0
- package/dist/organisms/views/FormViews.js +96 -0
- package/dist/organisms/views/FormViews.js.map +1 -0
- package/dist/registries/components.js.map +1 -1
- package/dist/utils/getEventValue.js.map +1 -1
- package/dist/utils/iconClass.js.map +1 -1
- package/dist/utils/mapPagination.js.map +1 -1
- package/dist/utils/stopPropagationWrapper.js.map +1 -1
- package/package.json +7 -7
- package/src/atoms/icon/Icon.stories.tsx +1 -1
- package/src/hooks/keyboard.constants.ts +40 -0
- package/src/hooks/useKeyboardControls.spec.tsx +208 -0
- package/src/hooks/useKeyboardControls.ts +84 -0
- package/src/interfaces/Operation.ts +9 -3
- package/src/molecules/button/Button.stories.tsx +1 -1
- package/src/molecules/button/Button.tsx +43 -24
- package/src/molecules/card/Card.tsx +4 -0
- package/src/molecules/forms/form-control/FormControl.stories.tsx +1 -1
- package/src/molecules/forms/input-tags/InputTags.tsx +1 -1
- package/src/molecules/forms/input-tags/components/ChoicesTags.stories.tsx +1 -1
- package/src/molecules/forms/input-tags/components/ReactTags.stories.tsx +1 -1
- package/src/molecules/forms/input-text/InputText.stories.tsx +2 -2
- package/src/molecules/forms/select/components/ChoicesSelect.stories.tsx +2 -2
- package/src/molecules/forms/select/components/HtmlSelect.stories.tsx +2 -2
- package/src/molecules/forms/select/components/ReactSelect.stories.tsx +2 -2
- package/src/molecules/loader/Loader.stories.tsx +1 -1
- package/src/molecules/modal/Modal.stories.tsx +1 -1
- package/src/molecules/pagination/Pagination.stories.tsx +1 -8
- package/src/molecules/pagination/Pagination.tsx +0 -1
- package/src/molecules/table/Table.stories.tsx +36 -3
- package/src/molecules/table/Table.tsx +12 -6
- package/src/molecules/table/components/DefaultCellOperations.tsx +13 -7
- package/src/molecules/table/components/DefaultOperationButton.tsx +5 -4
- package/src/molecules/table/filters/SelectFilter.tsx +1 -1
- package/src/molecules/table/hooks/useTable.tsx +5 -5
- package/src/molecules/tabs/Tab.tsx +106 -0
- package/src/molecules/tabs/TabList.tsx +37 -0
- package/src/molecules/tabs/TabPanel.tsx +37 -0
- package/src/molecules/tabs/Tabs.spec.tsx +126 -73
- package/src/molecules/tabs/Tabs.stories.tsx +298 -65
- package/src/molecules/tabs/Tabs.tsx +10 -81
- package/src/molecules/tabs/TabsBody.tsx +11 -0
- package/src/molecules/tabs/TabsLegacy.stories.tsx +103 -0
- package/src/molecules/tabs/TabsLegacy.tsx +84 -0
- package/src/molecules/tabs/all.ts +5 -0
- package/src/molecules/tabs/context/TabControl.tsx +166 -0
- package/src/molecules/tabs/hooks/tabControl.spec.tsx +388 -0
- package/src/molecules/tabs/hooks/tabControl.ts +52 -0
- package/src/organisms/__fixtures__/form-firstname.fixture.json +1 -0
- package/src/organisms/__fixtures__/form.fixture.json +1 -0
- package/src/organisms/form/Form.stories.tsx +94 -118
- package/src/organisms/form/access/FormAccess.stories.tsx +2 -2
- package/src/organisms/form/actions/FormAction.stories.tsx +422 -0
- package/src/organisms/form/builder/FormBuilder.stories.tsx +4 -1
- package/src/organisms/form/builder/FormEdit.stories.tsx +1 -1
- package/src/organisms/form/builder/FormEdit.tsx +7 -1
- package/src/organisms/form/builder/useFormBuilder.ts +5 -1
- package/src/organisms/form/builder/useFormEdit.ts +1 -1
- package/src/organisms/form/exports/FormExport.stories.tsx +71 -0
- package/src/organisms/form/exports/FormExport.tsx +58 -0
- package/src/organisms/form/preview/FormPreview.stories.tsx +61 -0
- package/src/organisms/form/preview/FormPreview.tsx +21 -0
- package/src/organisms/modal/RemoveModal.stories.tsx +1 -1
- package/src/organisms/table/actions/ActionsTable.stories.tsx +38 -36
- package/src/organisms/table/submissions/SubmissionsTable.stories.tsx +103 -57
- package/src/organisms/table/submissions/SubmissionsTable.tsx +10 -4
- package/src/organisms/views/FormViews.stories.tsx +224 -0
- package/src/organisms/views/FormViews.tsx +146 -0
- package/vite.config.mts +2 -2
- package/dist/organisms/form/action/FormAction.js.map +0 -1
- package/src/organisms/form/action/FormAction.stories.tsx +0 -364
- package/tsconfig.app.json +0 -11
- package/tsconfig.json +0 -21
- package/tsconfig.node.json +0 -13
- package/tsconfig.spec.json +0 -14
- /package/dist/organisms/form/{action → actions}/FormAction.d.ts +0 -0
- /package/src/organisms/form/{action → actions}/FormAction.tsx +0 -0
|
@@ -1,92 +1,21 @@
|
|
|
1
1
|
import classnames from "classnames";
|
|
2
|
-
import { PropsWithChildren } from "react";
|
|
2
|
+
import type { CSSProperties, PropsWithChildren } from "react";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export function ButtonTab({ icon, back, onClick, isActive, reverse, children, className, after }: PropsWithChildren<any>) {
|
|
7
|
-
return (
|
|
8
|
-
<div
|
|
9
|
-
title={"button-wrapper"}
|
|
10
|
-
className={classnames("tw-tabs__button-wrapper", isActive ? "-active" : "", back ? "-back" : "", className)}
|
|
11
|
-
>
|
|
12
|
-
<button
|
|
13
|
-
title={"button-tab"}
|
|
14
|
-
className={classnames("tw-tabs__button", reverse ? "-reverse" : "", isActive ? "-active" : "", back ? "-back" : "")}
|
|
15
|
-
onClick={onClick}
|
|
16
|
-
>
|
|
17
|
-
{icon && <i className={classnames(iconClass(undefined, icon), "tw-tabs__button-icon")} />}
|
|
18
|
-
<span className={"tw-tabs__button-label"}>{children}</span>
|
|
19
|
-
{after}
|
|
20
|
-
</button>
|
|
21
|
-
<div className={classnames("tw-tabs__button-border", isActive ? "-active" : "")} />
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface TabsItemProps extends Record<string, any> {
|
|
27
|
-
label?: string;
|
|
28
|
-
icon?: string;
|
|
29
|
-
}
|
|
4
|
+
import { registerComponent } from "../../registries/components.js";
|
|
5
|
+
import { TabsProvider } from "./context/TabControl.js";
|
|
30
6
|
|
|
31
7
|
export interface TabsProps extends Record<string, any> {
|
|
32
|
-
|
|
33
|
-
AddButton?: any;
|
|
34
|
-
current?: TabsItemProps;
|
|
35
|
-
items?: TabsItemProps[];
|
|
36
|
-
style?: any;
|
|
8
|
+
style?: CSSProperties;
|
|
37
9
|
className?: string;
|
|
38
|
-
|
|
39
|
-
Button?: any;
|
|
40
|
-
onClick?: (item: TabsItemProps) => void;
|
|
41
|
-
i18n?: (f: string) => string;
|
|
10
|
+
selected?: number;
|
|
42
11
|
}
|
|
43
12
|
|
|
44
|
-
export function Tabs({
|
|
45
|
-
style,
|
|
46
|
-
current,
|
|
47
|
-
items = [],
|
|
48
|
-
children,
|
|
49
|
-
HeaderChildren,
|
|
50
|
-
AddButton,
|
|
51
|
-
Button = ButtonTab,
|
|
52
|
-
className,
|
|
53
|
-
onClick,
|
|
54
|
-
i18n = (f) => f,
|
|
55
|
-
...additionalProps
|
|
56
|
-
}: PropsWithChildren<TabsProps>) {
|
|
13
|
+
export function Tabs({ style, selected, children, className }: PropsWithChildren<TabsProps>) {
|
|
57
14
|
return (
|
|
58
|
-
<div data-testid={"
|
|
59
|
-
<
|
|
60
|
-
<nav className='tw-tabs__header'>
|
|
61
|
-
<div className='tw-tabs__header-wrapper'>
|
|
62
|
-
<div className='tw-tabs__header-border' />
|
|
63
|
-
{items
|
|
64
|
-
.filter((item) => item.label || item.icon)
|
|
65
|
-
.map((item, index) => {
|
|
66
|
-
return (
|
|
67
|
-
<Button
|
|
68
|
-
key={index}
|
|
69
|
-
back={item.back}
|
|
70
|
-
isActive={current?.action === item.action}
|
|
71
|
-
exact={item.exact}
|
|
72
|
-
onClick={() => {
|
|
73
|
-
onClick && onClick(item);
|
|
74
|
-
}}
|
|
75
|
-
{...additionalProps}
|
|
76
|
-
{...item}
|
|
77
|
-
>
|
|
78
|
-
{i18n(item.label || "")}
|
|
79
|
-
</Button>
|
|
80
|
-
);
|
|
81
|
-
})}
|
|
82
|
-
{AddButton && <AddButton {...additionalProps} current={current} />}
|
|
83
|
-
</div>
|
|
84
|
-
</nav>
|
|
85
|
-
{HeaderChildren && <HeaderChildren {...additionalProps} current={current} />}
|
|
86
|
-
</div>
|
|
87
|
-
<div title={"tab-body"} className={"tw-tabs__body"}>
|
|
88
|
-
{children}
|
|
89
|
-
</div>
|
|
15
|
+
<div data-testid={"Tabs"} className={classnames("tw-tabs", className)} style={style}>
|
|
16
|
+
<TabsProvider selected={selected}>{children}</TabsProvider>
|
|
90
17
|
</div>
|
|
91
18
|
);
|
|
92
19
|
}
|
|
20
|
+
|
|
21
|
+
registerComponent("Tabs", Tabs);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { registerComponent } from "../../registries/components.js";
|
|
2
|
+
|
|
3
|
+
export function TabsBody(props: React.PropsWithChildren<{}>) {
|
|
4
|
+
return (
|
|
5
|
+
<div title={"tabs-body"} data-testid={"TabsBody"} className={"tw-tabs__body"}>
|
|
6
|
+
{props.children}
|
|
7
|
+
</div>
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
registerComponent("TabsBody", TabsBody);
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import "./all.js";
|
|
2
|
+
|
|
3
|
+
import { Meta, StoryObj } from "@storybook/react-vite";
|
|
4
|
+
|
|
5
|
+
import { TabsLegacy } from "./TabsLegacy.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* TabsLegacy component.
|
|
9
|
+
*
|
|
10
|
+
* You can import this component and use it like:
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import {Tabs} from "@tsed/react-formio/molecules/tabs/TabsLegacy";
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* TabsLegacy component support DI container and can be used with custom component. Here is the list of components that you can override:
|
|
17
|
+
*
|
|
18
|
+
* - Tab
|
|
19
|
+
* - TabList
|
|
20
|
+
* - TabPanel
|
|
21
|
+
* - Tabs
|
|
22
|
+
* - TabsBody
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* function CustomTab() {
|
|
26
|
+
*
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* registerComponent("Tab", CustomTab);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export default {
|
|
33
|
+
title: "TabsLegacy",
|
|
34
|
+
component: TabsLegacy,
|
|
35
|
+
argTypes: {},
|
|
36
|
+
parameters: {},
|
|
37
|
+
render: (args: any) => {
|
|
38
|
+
return (
|
|
39
|
+
<div className={"border-gray-300 border-1 shadow"}>
|
|
40
|
+
<TabsLegacy {...args} i18n={(f) => f} />
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
} satisfies Meta<typeof TabsLegacy>;
|
|
45
|
+
|
|
46
|
+
type Story = StoryObj<typeof TabsLegacy>;
|
|
47
|
+
|
|
48
|
+
export const Sandbox: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
items: [
|
|
51
|
+
{
|
|
52
|
+
action: "edit",
|
|
53
|
+
exact: true,
|
|
54
|
+
icon: "edit",
|
|
55
|
+
label: "Edit",
|
|
56
|
+
children: <div className='bg-red-100 p-5'>Edit</div>
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
action: "submissions",
|
|
60
|
+
exact: false,
|
|
61
|
+
icon: "data",
|
|
62
|
+
label: "Data",
|
|
63
|
+
children: <div className='bg-orange-100 p-5'>Data</div>
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
action: "preview",
|
|
67
|
+
exact: true,
|
|
68
|
+
icon: "test-tube",
|
|
69
|
+
label: "Preview",
|
|
70
|
+
children: <div className='bg-yellow-100 p-5'>Preview</div>
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
action: "actions",
|
|
74
|
+
exact: false,
|
|
75
|
+
icon: "paper-plane",
|
|
76
|
+
label: "Actions",
|
|
77
|
+
children: <div className='bg-green-100 p-5'>Actions</div>
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
action: "access",
|
|
81
|
+
exact: true,
|
|
82
|
+
icon: "lock",
|
|
83
|
+
label: "Access",
|
|
84
|
+
children: <div className='bg-blue-100 p-5'>Access</div>
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
action: "export",
|
|
88
|
+
exact: true,
|
|
89
|
+
icon: "download",
|
|
90
|
+
label: "Export",
|
|
91
|
+
children: <div className='bg-purple-100 p-5'>Export</div>
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
action: "delete",
|
|
95
|
+
exact: true,
|
|
96
|
+
icon: "trash",
|
|
97
|
+
label: "Delete",
|
|
98
|
+
roles: ["administrator", "owner"],
|
|
99
|
+
children: <div className='bg-gray-100 p-5'>Trash</div>
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import "./all.js";
|
|
2
|
+
|
|
3
|
+
import { CSSProperties, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
import { getComponent } from "../../registries/components.js";
|
|
6
|
+
import type { Tab as DefaultTab } from "./Tab.js";
|
|
7
|
+
import type { TabList as DefaultTabList } from "./TabList.js";
|
|
8
|
+
import type { TabPanel as DefaultTabPanel } from "./TabPanel.js";
|
|
9
|
+
import type { Tabs as DefaultTabs } from "./Tabs.js";
|
|
10
|
+
import type { TabsBody as DefaultTabsBody } from "./TabsBody.js";
|
|
11
|
+
|
|
12
|
+
export interface TabsItemProps extends Record<string, any> {
|
|
13
|
+
label?: string;
|
|
14
|
+
icon?: string;
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TabsLegacyProps extends Record<string, any> {
|
|
19
|
+
AddButton?: any;
|
|
20
|
+
current?: TabsItemProps;
|
|
21
|
+
items?: TabsItemProps[];
|
|
22
|
+
style?: CSSProperties;
|
|
23
|
+
className?: string;
|
|
24
|
+
reverse?: boolean;
|
|
25
|
+
onClick?: (item: TabsItemProps) => void;
|
|
26
|
+
i18n?: (f: string) => string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function TabsLegacy({
|
|
30
|
+
style,
|
|
31
|
+
current,
|
|
32
|
+
items = [],
|
|
33
|
+
HeaderChildren,
|
|
34
|
+
AddButton,
|
|
35
|
+
className,
|
|
36
|
+
onClick,
|
|
37
|
+
i18n = (f) => f,
|
|
38
|
+
reverse,
|
|
39
|
+
after,
|
|
40
|
+
...additionalProps
|
|
41
|
+
}: TabsLegacyProps) {
|
|
42
|
+
const Tab = getComponent<typeof DefaultTab>("Tab");
|
|
43
|
+
const TabsBody = getComponent<typeof DefaultTabsBody>("TabsBody");
|
|
44
|
+
const TabList = getComponent<typeof DefaultTabList>("TabList");
|
|
45
|
+
const TabPanel = getComponent<typeof DefaultTabPanel>("TabPanel");
|
|
46
|
+
const Tabs = getComponent<typeof DefaultTabs>("Tabs");
|
|
47
|
+
const tabs = items.filter((item) => item.label || item.icon);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Tabs className={className} style={style}>
|
|
51
|
+
<div>
|
|
52
|
+
<TabList>
|
|
53
|
+
{tabs.map((item, index) => {
|
|
54
|
+
return (
|
|
55
|
+
<Tab
|
|
56
|
+
key={index}
|
|
57
|
+
onClick={() => {
|
|
58
|
+
onClick && onClick(item);
|
|
59
|
+
}}
|
|
60
|
+
icon={item.icon}
|
|
61
|
+
value={index}
|
|
62
|
+
className={reverse ? "-reverse" : ""}
|
|
63
|
+
after={after}
|
|
64
|
+
>
|
|
65
|
+
{i18n(item.label || "")}
|
|
66
|
+
</Tab>
|
|
67
|
+
);
|
|
68
|
+
})}
|
|
69
|
+
{AddButton && <AddButton {...additionalProps} current={current} />}
|
|
70
|
+
</TabList>
|
|
71
|
+
{HeaderChildren && <HeaderChildren {...additionalProps} current={current} />}
|
|
72
|
+
</div>
|
|
73
|
+
<TabsBody>
|
|
74
|
+
{tabs.map((item, index) => {
|
|
75
|
+
return (
|
|
76
|
+
<TabPanel key={index} value={index}>
|
|
77
|
+
{item.children || item.content}
|
|
78
|
+
</TabPanel>
|
|
79
|
+
);
|
|
80
|
+
})}
|
|
81
|
+
</TabsBody>
|
|
82
|
+
</Tabs>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, type Dispatch, type PropsWithChildren, type RefObject, useCallback, useId, useReducer } from "react";
|
|
4
|
+
|
|
5
|
+
type RefTab<T extends HTMLElement = HTMLElement> = RefObject<T>;
|
|
6
|
+
type RefTabs<T extends HTMLElement = HTMLElement> = Map<number, RefTab<T>>;
|
|
7
|
+
|
|
8
|
+
type TabsUpdateAction = {
|
|
9
|
+
type: "update";
|
|
10
|
+
payload: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type TabsRegisterAction<T extends HTMLElement = HTMLElement> = {
|
|
14
|
+
type: "register";
|
|
15
|
+
payload: { value: number; ref: RefObject<T> };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type TabsUnregisterAction = {
|
|
19
|
+
type: "unregister";
|
|
20
|
+
payload: { value: number };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type TabsAction<T extends HTMLElement = HTMLElement> =
|
|
24
|
+
| { type: "start" | "end" | "previous" | "next" }
|
|
25
|
+
| TabsUpdateAction
|
|
26
|
+
| TabsRegisterAction<T>
|
|
27
|
+
| TabsUnregisterAction;
|
|
28
|
+
|
|
29
|
+
interface TabsState<T extends HTMLElement = HTMLElement> {
|
|
30
|
+
uid: string;
|
|
31
|
+
value: number;
|
|
32
|
+
refs: RefTabs<T>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface TabControl<T extends HTMLElement = HTMLElement> extends TabsState<T> {
|
|
36
|
+
uid: string;
|
|
37
|
+
value: number;
|
|
38
|
+
refs: RefTabs<T>;
|
|
39
|
+
dispatch: Dispatch<TabsAction>;
|
|
40
|
+
register: (value: number, ref: RefTab<T>) => void;
|
|
41
|
+
unregister: (value: number) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function next(state: TabsState) {
|
|
45
|
+
const keys = [...state.refs.keys()];
|
|
46
|
+
const index = keys.findIndex((value) => value === state.value);
|
|
47
|
+
const nextIndex = (index + 1) % keys.length;
|
|
48
|
+
|
|
49
|
+
return { ...state, value: keys[nextIndex] };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function previous(state: TabsState) {
|
|
53
|
+
const keys = [...state.refs.keys()];
|
|
54
|
+
const index = keys.findIndex((value) => value === state.value);
|
|
55
|
+
const previousIndex = (index - 1 + keys.length) % keys.length;
|
|
56
|
+
|
|
57
|
+
return { ...state, value: keys[previousIndex] };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function start(state: TabsState) {
|
|
61
|
+
const keys = [...state.refs.keys()];
|
|
62
|
+
const firstIndex = keys[0];
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
...state,
|
|
66
|
+
value: firstIndex
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function end(state: TabsState) {
|
|
71
|
+
const keys = [...state.refs.keys()];
|
|
72
|
+
const lastIndex = keys[keys.length - 1];
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...state,
|
|
76
|
+
value: lastIndex
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function unregister(state: TabsState, action: TabsUnregisterAction) {
|
|
81
|
+
const deletedRefs = new Map(state.refs);
|
|
82
|
+
deletedRefs.delete(action.payload.value);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
...state,
|
|
86
|
+
refs: deletedRefs
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function register(state: TabsState, action: TabsRegisterAction) {
|
|
91
|
+
return {
|
|
92
|
+
...state,
|
|
93
|
+
refs: new Map(state.refs).set(action.payload.value, action.payload.ref)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function update(state: TabsState, action: TabsUpdateAction) {
|
|
98
|
+
return { ...state, value: action.payload };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const actions = {
|
|
102
|
+
next,
|
|
103
|
+
previous,
|
|
104
|
+
start,
|
|
105
|
+
end,
|
|
106
|
+
register,
|
|
107
|
+
unregister,
|
|
108
|
+
update
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
function tabsReducer(state: TabsState, action: TabsAction): TabsState {
|
|
112
|
+
if (action.type in actions) {
|
|
113
|
+
const actionFunction = actions[action.type as keyof typeof actions] as (state: TabsState, action: TabsAction) => TabsState;
|
|
114
|
+
|
|
115
|
+
return actionFunction(state, action);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return state;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const TabControlContext = createContext<TabControl>({
|
|
122
|
+
uid: "",
|
|
123
|
+
value: 0,
|
|
124
|
+
refs: new Map(),
|
|
125
|
+
dispatch: () => {
|
|
126
|
+
console.warn("Tab Controller Context dispatch used outside of Provider");
|
|
127
|
+
},
|
|
128
|
+
register: () => {
|
|
129
|
+
console.warn("Tab Controller Context register used outside of Provider");
|
|
130
|
+
},
|
|
131
|
+
unregister: () => {
|
|
132
|
+
console.warn("Tab Controller Context unregister used outside of Provider");
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
TabControlContext.displayName = "TabControlContext";
|
|
137
|
+
|
|
138
|
+
export interface TabsProviderProps {
|
|
139
|
+
selected?: number;
|
|
140
|
+
/**
|
|
141
|
+
* The selected tab value
|
|
142
|
+
* @deprecated Min props as no effect on the Tabs component and will be removed in future versions
|
|
143
|
+
*/
|
|
144
|
+
min?: number;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The selected tab value
|
|
148
|
+
* @deprecated Max props as no effect on the Tabs component and will be removed in future versions
|
|
149
|
+
*/
|
|
150
|
+
max?: number;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function TabsProvider({ selected = 0, children }: PropsWithChildren<TabsProviderProps>) {
|
|
154
|
+
const uid = useId();
|
|
155
|
+
const [state, dispatch] = useReducer(tabsReducer, { uid, value: selected, refs: new Map() });
|
|
156
|
+
|
|
157
|
+
const register = useCallback(<T extends HTMLElement>(value: number, ref: RefTab<T>) => {
|
|
158
|
+
dispatch({ type: "register", payload: { value, ref } });
|
|
159
|
+
}, []);
|
|
160
|
+
|
|
161
|
+
const unregister = useCallback((value: number) => {
|
|
162
|
+
dispatch({ type: "unregister", payload: { value } });
|
|
163
|
+
}, []);
|
|
164
|
+
|
|
165
|
+
return <TabControlContext.Provider value={{ ...state, dispatch, register, unregister }}>{children}</TabControlContext.Provider>;
|
|
166
|
+
}
|