xmlui 0.9.93 → 0.9.94

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xmlui",
3
- "version": "0.9.93",
3
+ "version": "0.9.94",
4
4
  "sideEffects": false,
5
5
  "scripts": {
6
6
  "start-test-bed": "cd src/testing/infrastructure && xmlui start",
@@ -11,7 +11,7 @@ const immer_1 = __importDefault(require("immer"));
11
11
  const constants_1 = require("../../components-core/constants");
12
12
  exports.TabContext = (0, react_1.createContext)({
13
13
  register: (tabItem) => { },
14
- unRegister: (id) => { },
14
+ unRegister: (innerId) => { },
15
15
  activeTabId: "",
16
16
  });
17
17
  function useTabContextValue() {
@@ -19,20 +19,20 @@ function useTabContextValue() {
19
19
  const [activeTabId, setActiveTabId] = (0, react_1.useState)("");
20
20
  const tabContextValue = (0, react_1.useMemo)(() => {
21
21
  return {
22
- register: (column) => {
22
+ register: (tabItem) => {
23
23
  setTabItems((0, immer_1.default)((draft) => {
24
- const existing = draft.findIndex((col) => col.id === column.id);
24
+ const existing = draft.findIndex((col) => col.innerId === tabItem.innerId);
25
25
  if (existing < 0) {
26
- draft.push(column);
26
+ draft.push(tabItem);
27
27
  }
28
28
  else {
29
- draft[existing] = column;
29
+ draft[existing] = tabItem;
30
30
  }
31
31
  }));
32
32
  },
33
- unRegister: (id) => {
33
+ unRegister: (innerId) => {
34
34
  setTabItems((0, immer_1.default)((draft) => {
35
- return draft.filter((col) => col.id !== id);
35
+ return draft.filter((col) => col.innerId !== innerId);
36
36
  }));
37
37
  },
38
38
  activeTabId,
@@ -16,18 +16,23 @@ exports.TabItemMd = (0, metadata_helpers_1.createMetadata)({
16
16
  docFolder: "Tabs",
17
17
  props: {
18
18
  label: (0, metadata_helpers_1.dLabel)(),
19
- labelTemplate: (0, metadata_helpers_1.dComponent)("This property allows the customization of the TabItem label."),
19
+ headerTemplate: (0, metadata_helpers_1.dComponent)("This property allows the customization of the TabItem header."),
20
20
  },
21
21
  contextVars: {
22
- $item: (0, metadata_helpers_1.d)("This context value represents an item when you define a tab item template."),
22
+ $header: (0, metadata_helpers_1.d)("This context value represents the header context with props: id (optional), index, label, isActive."),
23
23
  },
24
24
  });
25
25
  exports.tabItemComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.TabItemMd, (rendererContext) => {
26
26
  const { node, renderChild, extractValue } = rendererContext;
27
- return ((0, jsx_runtime_1.jsx)(TabItemNative_1.TabItemComponent, { label: extractValue(node.props.label), labelRenderer: node.props.labelTemplate
27
+ return ((0, jsx_runtime_1.jsx)(TabItemNative_1.TabItemComponent, { id: extractValue(node.uid), label: extractValue(node.props.label), headerRenderer: node.props.headerTemplate
28
28
  ? (item) => {
29
- return ((0, jsx_runtime_1.jsx)(container_helpers_1.MemoizedItem, { node: node.props.labelTemplate, item: item, context: {
30
- $item: item,
29
+ return ((0, jsx_runtime_1.jsx)(container_helpers_1.MemoizedItem, { node: node.props.headerTemplate, itemKey: "$header", contextVars: {
30
+ $header: {
31
+ id: item.id,
32
+ index: item.index,
33
+ label: item.label,
34
+ isActive: item.isActive,
35
+ },
31
36
  }, renderChild: renderChild }));
32
37
  }
33
38
  : undefined, children: renderChild(node.children) }));
@@ -9,22 +9,23 @@ const react_1 = require("react");
9
9
  const react_tabs_1 = require("@radix-ui/react-tabs");
10
10
  const Tabs_module_scss_1 = __importDefault(require("../Tabs/Tabs.module.scss"));
11
11
  const TabContext_1 = require("./TabContext");
12
- exports.TabItemComponent = (0, react_1.forwardRef)(function TabItemComponent({ children, label, labelRenderer, style }, forwardedRef) {
13
- const id = (0, react_1.useId)();
12
+ exports.TabItemComponent = (0, react_1.forwardRef)(function TabItemComponent({ children, label, headerRenderer, style, id }, forwardedRef) {
13
+ const innerId = (0, react_1.useId)();
14
14
  const { register, unRegister, activeTabId } = (0, TabContext_1.useTabContext)();
15
15
  (0, react_1.useEffect)(() => {
16
16
  register({
17
17
  label,
18
- labelRenderer,
19
- id,
18
+ headerRenderer,
19
+ innerId,
20
+ id, // Store the external id (can be undefined)
20
21
  });
21
- }, [id, label, labelRenderer, register]);
22
+ }, [innerId, id, label, headerRenderer, register]);
22
23
  (0, react_1.useEffect)(() => {
23
24
  return () => {
24
- unRegister(id);
25
+ unRegister(innerId);
25
26
  };
26
- }, [id, unRegister]);
27
- if (activeTabId !== id)
27
+ }, [innerId, unRegister]);
28
+ if (activeTabId !== innerId)
28
29
  return null;
29
- return ((0, jsx_runtime_1.jsx)(react_tabs_1.Content, { value: id, className: Tabs_module_scss_1.default.tabsContent, ref: forwardedRef, style: style, children: children }, id));
30
+ return ((0, jsx_runtime_1.jsx)(react_tabs_1.Content, { value: innerId, className: Tabs_module_scss_1.default.tabsContent, ref: forwardedRef, style: style, children: children }, innerId));
30
31
  });
@@ -29,13 +29,25 @@ exports.TabsMd = (0, metadata_helpers_1.createMetadata)({
29
29
  defaultValue: TabsNative_1.defaultProps.orientation,
30
30
  valueType: "string",
31
31
  },
32
- tabTemplate: Object.assign(Object.assign({}, (0, metadata_helpers_1.dComponent)(`This property declares the template for the clickable tab area.`)), { isInternal: true }),
32
+ headerTemplate: Object.assign({}, (0, metadata_helpers_1.dComponent)(`This property declares the template for the clickable tab area.`)),
33
33
  },
34
34
  apis: {
35
35
  next: {
36
36
  description: `This method selects the next tab. If the current tab is the last one, it wraps around to the first tab.`,
37
37
  signature: "next(): void",
38
38
  },
39
+ prev: {
40
+ description: `This method selects the previous tab. If the current tab is the first one, it wraps around to the last tab.`,
41
+ signature: "prev(): void",
42
+ },
43
+ setActiveTabIndex: {
44
+ description: `This method sets the active tab by index (0-based).`,
45
+ signature: "setActiveTabIndex(index: number): void",
46
+ },
47
+ setActiveTabById: {
48
+ description: `This method sets the active tab by its ID.`,
49
+ signature: "setActiveTabById(id: string): void",
50
+ },
39
51
  },
40
52
  themeVars: (0, themeVars_1.parseScssVar)(Tabs_module_scss_1.default.themeVars),
41
53
  defaultThemeVars: {
@@ -53,7 +65,9 @@ exports.TabsMd = (0, metadata_helpers_1.createMetadata)({
53
65
  });
54
66
  exports.tabsComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.TabsMd, ({ extractValue, node, renderChild, layoutCss, registerComponentApi }) => {
55
67
  var _a, _b, _c;
56
- return ((0, jsx_runtime_1.jsx)(TabsNative_1.Tabs, { id: node === null || node === void 0 ? void 0 : node.uid, style: layoutCss, tabRenderer: !!((_a = node === null || node === void 0 ? void 0 : node.props) === null || _a === void 0 ? void 0 : _a.tabTemplate)
57
- ? (item) => ((0, jsx_runtime_1.jsx)(container_helpers_1.MemoizedItem, { node: node.props.tabTemplate, item: item, renderChild: renderChild }))
68
+ return ((0, jsx_runtime_1.jsx)(TabsNative_1.Tabs, { id: node === null || node === void 0 ? void 0 : node.uid, style: layoutCss, headerRenderer: !!((_a = node === null || node === void 0 ? void 0 : node.props) === null || _a === void 0 ? void 0 : _a.headerTemplate)
69
+ ? (item) => ((0, jsx_runtime_1.jsx)(container_helpers_1.MemoizedItem, { node: node.props.headerTemplate, itemKey: "$header", contextVars: {
70
+ $header: item,
71
+ }, renderChild: renderChild }))
58
72
  : undefined, activeTab: extractValue((_b = node.props) === null || _b === void 0 ? void 0 : _b.activeTab), orientation: extractValue((_c = node.props) === null || _c === void 0 ? void 0 : _c.orientation), registerComponentApi: registerComponentApi, children: renderChild(node.children) }));
59
73
  });
@@ -16,8 +16,9 @@ exports.defaultProps = {
16
16
  orientation: "horizontal",
17
17
  distributeEvenly: false,
18
18
  };
19
- exports.Tabs = (0, react_1.forwardRef)(function Tabs({ activeTab = exports.defaultProps.activeTab, orientation = exports.defaultProps.orientation, tabRenderer, style, children, id, registerComponentApi, className, distributeEvenly = exports.defaultProps.distributeEvenly, }, forwardedRef) {
19
+ exports.Tabs = (0, react_1.forwardRef)(function Tabs({ activeTab = exports.defaultProps.activeTab, orientation = exports.defaultProps.orientation, headerRenderer, style, children, id, registerComponentApi, className, distributeEvenly = exports.defaultProps.distributeEvenly, }, forwardedRef) {
20
20
  const { tabItems, tabContextValue } = (0, TabContext_1.useTabContextValue)();
21
+ const tabsId = id || (0, react_1.useId)();
21
22
  // Ensure activeTab is within valid bounds
22
23
  const validActiveTab = (0, react_1.useMemo)(() => {
23
24
  if (tabItems.length === 0)
@@ -31,7 +32,7 @@ exports.Tabs = (0, react_1.forwardRef)(function Tabs({ activeTab = exports.defau
31
32
  const [activeIndex, setActiveIndex] = (0, react_1.useState)(validActiveTab);
32
33
  const currentTab = (0, react_1.useMemo)(() => {
33
34
  var _a;
34
- return (_a = tabItems[activeIndex]) === null || _a === void 0 ? void 0 : _a.id;
35
+ return (_a = tabItems[activeIndex]) === null || _a === void 0 ? void 0 : _a.innerId;
35
36
  }, [activeIndex, tabItems]);
36
37
  (0, react_1.useEffect)(() => {
37
38
  tabContextValue.setActiveTabId(currentTab);
@@ -51,20 +52,44 @@ exports.Tabs = (0, react_1.forwardRef)(function Tabs({ activeTab = exports.defau
51
52
  return prevIndex >= maxIndex ? 0 : prevIndex + 1;
52
53
  });
53
54
  });
55
+ const prev = (0, misc_1.useEvent)(() => {
56
+ setActiveIndex((prevIndex) => {
57
+ const maxIndex = tabItems.length - 1;
58
+ return prevIndex <= 0 ? maxIndex : prevIndex - 1;
59
+ });
60
+ });
61
+ const setActiveTabIndex = (0, misc_1.useEvent)((index) => {
62
+ if (index >= 0 && index < tabItems.length) {
63
+ setActiveIndex(index);
64
+ }
65
+ });
66
+ const setActiveTabById = (0, misc_1.useEvent)((tabId) => {
67
+ // First try to find by external id, then by innerId
68
+ let index = tabItems.findIndex((item) => item.id === tabId);
69
+ if (index === -1) {
70
+ index = tabItems.findIndex((item) => item.innerId === tabId);
71
+ }
72
+ if (index !== -1) {
73
+ setActiveIndex(index);
74
+ }
75
+ });
54
76
  (0, react_1.useEffect)(() => {
55
77
  registerComponentApi === null || registerComponentApi === void 0 ? void 0 : registerComponentApi({
56
78
  next,
79
+ prev,
80
+ setActiveTabIndex,
81
+ setActiveTabById,
57
82
  });
58
- }, [next, registerComponentApi]);
59
- return ((0, jsx_runtime_1.jsx)(TabContext_1.TabContext.Provider, { value: tabContextValue, children: (0, jsx_runtime_1.jsxs)(react_tabs_1.Root, { id: id, ref: forwardedRef, className: (0, classnames_1.default)(Tabs_module_scss_1.default.tabs, className), value: `${currentTab}`, onValueChange: (tab) => {
60
- const newIndex = tabItems.findIndex((item) => item.id === tab);
83
+ }, [next, prev, setActiveTabIndex, setActiveTabById, registerComponentApi]);
84
+ return ((0, jsx_runtime_1.jsx)(TabContext_1.TabContext.Provider, { value: tabContextValue, children: (0, jsx_runtime_1.jsxs)(react_tabs_1.Root, { id: tabsId, ref: forwardedRef, className: (0, classnames_1.default)(Tabs_module_scss_1.default.tabs, className), value: `${currentTab}`, onValueChange: (tab) => {
85
+ const newIndex = tabItems.findIndex((item) => item.innerId === tab);
61
86
  if (newIndex !== activeIndex) {
62
87
  tabContextValue.setActiveTabId(tab);
63
88
  setActiveIndex(newIndex);
64
89
  }
65
- }, orientation: orientation, style: style, children: [(0, jsx_runtime_1.jsxs)(react_tabs_1.List, { className: Tabs_module_scss_1.default.tabsList, children: [tabItems.map((tab) => tab.labelRenderer ? ((0, jsx_runtime_1.jsx)(react_tabs_1.Trigger, { role: "tab", className: (0, classnames_1.default)(Tabs_module_scss_1.default.tabTrigger, {
90
+ }, orientation: orientation, style: style, children: [(0, jsx_runtime_1.jsxs)(react_tabs_1.List, { className: Tabs_module_scss_1.default.tabsList, role: "tablist", children: [tabItems.map((tab, index) => tab.headerRenderer ? ((0, jsx_runtime_1.jsx)(react_tabs_1.Trigger, { role: "tab", "aria-label": tab.label, className: (0, classnames_1.default)(Tabs_module_scss_1.default.tabTrigger, {
66
91
  [Tabs_module_scss_1.default.distributeEvenly]: distributeEvenly,
67
- }), value: tab.id, children: tab.labelRenderer(Object.assign(Object.assign({}, tab), { isActive: tab.id === currentTab })) }, tab.id)) : tabRenderer ? ((0, jsx_runtime_1.jsx)(react_tabs_1.Trigger, { value: tab.id, asChild: true, role: "tab", children: tabRenderer(Object.assign(Object.assign({}, tab), { isActive: tab.id === currentTab })) }, tab.id)) : ((0, jsx_runtime_1.jsx)(react_tabs_1.Trigger, { role: "tab", className: (0, classnames_1.default)(Tabs_module_scss_1.default.tabTrigger, {
92
+ }), value: tab.innerId, children: tab.headerRenderer(Object.assign(Object.assign({}, (tab.id !== undefined && { id: tab.id })), { index, label: tab.label, isActive: tab.innerId === currentTab })) }, tab.innerId)) : headerRenderer ? ((0, jsx_runtime_1.jsx)(react_tabs_1.Trigger, { value: tab.innerId, role: "tab", "aria-label": tab.label, children: headerRenderer(Object.assign(Object.assign({}, (tab.id !== undefined && { id: tab.id })), { index, label: tab.label, isActive: tab.innerId === currentTab })) }, tab.innerId)) : ((0, jsx_runtime_1.jsx)(react_tabs_1.Trigger, { role: "tab", "aria-label": tab.label, className: (0, classnames_1.default)(Tabs_module_scss_1.default.tabTrigger, {
68
93
  [Tabs_module_scss_1.default.distributeEvenly]: distributeEvenly,
69
- }), value: tab.id, children: tab.label }, tab.id))), !distributeEvenly && !tabRenderer && ((0, jsx_runtime_1.jsx)("div", { className: Tabs_module_scss_1.default.filler, "data-orientation": orientation }))] }), children] }) }));
94
+ }), value: tab.innerId, children: tab.label }, tab.innerId))), !distributeEvenly && !headerRenderer && ((0, jsx_runtime_1.jsx)("div", { className: Tabs_module_scss_1.default.filler, "data-orientation": orientation }))] }), children] }) }));
70
95
  });
@@ -1079,7 +1079,9 @@ declare type Props_3 = {
1079
1079
  id?: string;
1080
1080
  activeTab?: number;
1081
1081
  orientation?: "horizontal" | "vertical";
1082
- tabRenderer?: (item: {
1082
+ headerRenderer?: (item: {
1083
+ id?: string;
1084
+ index: number;
1083
1085
  label: string;
1084
1086
  isActive: boolean;
1085
1087
  }) => ReactNode;
@@ -1362,7 +1364,9 @@ declare const standaloneExports: {
1362
1364
  id?: string;
1363
1365
  activeTab?: number;
1364
1366
  orientation?: "horizontal" | "vertical";
1365
- tabRenderer?: (item: {
1367
+ headerRenderer?: (item: {
1368
+ id?: string;
1369
+ index: number;
1366
1370
  label: string;
1367
1371
  isActive: boolean;
1368
1372
  }) => default_2.ReactNode;
@@ -1631,8 +1635,9 @@ declare const T_VAR_STATEMENT: number;
1631
1635
  declare const T_WHILE_STATEMENT: number;
1632
1636
 
1633
1637
  declare type Tab = {
1638
+ id?: string;
1634
1639
  label: string;
1635
- labelRenderer?: (contextVars: any) => ReactNode;
1640
+ headerRenderer?: (contextVars: any) => ReactNode;
1636
1641
  children?: ReactNode;
1637
1642
  style?: CSSProperties;
1638
1643
  };