@redocly/theme 0.58.0 → 0.59.0-next.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.
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.js +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.js +1 -1
- package/lib/components/Panel/variables.js +1 -0
- package/lib/components/Tag/Tag.d.ts +3 -2
- package/lib/components/Tag/Tag.js +21 -5
- package/lib/components/Tag/variables.dark.js +135 -0
- package/lib/components/Tag/variables.js +120 -58
- package/lib/core/hooks/use-tabs.d.ts +11 -6
- package/lib/core/hooks/use-tabs.js +117 -207
- package/lib/core/utils/index.d.ts +1 -0
- package/lib/core/utils/index.js +1 -0
- package/lib/core/utils/tabs.d.ts +1 -0
- package/lib/core/utils/tabs.js +8 -0
- package/lib/markdoc/components/Tabs/Tab.js +1 -1
- package/lib/markdoc/components/Tabs/TabList.d.ts +2 -14
- package/lib/markdoc/components/Tabs/TabList.js +63 -16
- package/lib/markdoc/components/Tabs/Tabs.d.ts +2 -2
- package/lib/markdoc/components/Tabs/Tabs.js +11 -87
- package/lib/markdoc/tags/tabs.js +5 -0
- package/package.json +3 -3
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations.tsx +1 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations.tsx +1 -1
- package/src/components/Panel/variables.ts +1 -0
- package/src/components/Tag/Tag.tsx +33 -8
- package/src/components/Tag/variables.dark.ts +135 -0
- package/src/components/Tag/variables.ts +120 -58
- package/src/core/hooks/use-tabs.ts +160 -238
- package/src/core/utils/index.ts +1 -0
- package/src/core/utils/tabs.ts +4 -0
- package/src/markdoc/components/Tabs/Tab.tsx +1 -0
- package/src/markdoc/components/Tabs/TabList.tsx +84 -30
- package/src/markdoc/components/Tabs/Tabs.tsx +12 -125
- package/src/markdoc/tags/tabs.ts +5 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import styled
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { useActiveTab } from '@redocly/theme/core/hooks';
|
|
7
7
|
import { TabList } from '@redocly/theme/markdoc/components/Tabs/TabList';
|
|
8
|
+
import { getTabId } from '@redocly/theme/core/utils';
|
|
8
9
|
|
|
9
10
|
export enum TabsSize {
|
|
10
11
|
SMALL = 'small',
|
|
@@ -20,140 +21,38 @@ export type TabItemProps = {
|
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
type TabsProps = {
|
|
24
|
+
id?: string;
|
|
23
25
|
children: React.ReactElement<TabItemProps>[];
|
|
24
26
|
className?: string;
|
|
25
27
|
size: TabsSize;
|
|
26
|
-
forceReady?: boolean;
|
|
27
28
|
initialTab?: string;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
export function Tabs({
|
|
32
|
+
id,
|
|
31
33
|
children,
|
|
32
34
|
className,
|
|
33
35
|
size,
|
|
34
|
-
forceReady = false,
|
|
35
36
|
initialTab: propInitialTab,
|
|
36
37
|
}: TabsProps): JSX.Element {
|
|
37
38
|
const [childrenArray, setChildrenArray] = useState<React.ReactElement<TabItemProps>[]>(
|
|
38
39
|
React.Children.toArray(children) as React.ReactElement<TabItemProps>[],
|
|
39
40
|
);
|
|
40
41
|
|
|
42
|
+
const initialTab = propInitialTab ?? childrenArray[0]?.props.label ?? '';
|
|
43
|
+
const { activeTab, setActiveTab } = useActiveTab({ tabsId: id, initialTab });
|
|
44
|
+
|
|
41
45
|
useEffect(() => {
|
|
42
46
|
setChildrenArray(React.Children.toArray(children) as React.ReactElement<TabItemProps>[]);
|
|
43
47
|
}, [children]);
|
|
44
|
-
const tabsContainerRef = useRef<HTMLUListElement>(null);
|
|
45
|
-
const [isAnimating, setIsAnimating] = useState<boolean>(false);
|
|
46
|
-
const defaultInitialTab = childrenArray[0]?.props.label ?? '';
|
|
47
|
-
const initialTab = propInitialTab ?? defaultInitialTab;
|
|
48
|
-
const {
|
|
49
|
-
activeTab,
|
|
50
|
-
setTabRef,
|
|
51
|
-
onTabClick,
|
|
52
|
-
handleKeyboard,
|
|
53
|
-
getTabId,
|
|
54
|
-
visibleTabs,
|
|
55
|
-
overflowTabs,
|
|
56
|
-
ready,
|
|
57
|
-
allTabsHidden,
|
|
58
|
-
} = useTabs({
|
|
59
|
-
initialTab,
|
|
60
|
-
totalTabs: childrenArray.length,
|
|
61
|
-
containerRef: tabsContainerRef,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const [prevTab, setPrevTab] = React.useState(initialTab);
|
|
65
|
-
const [highlightStyle, setHighlightStyle] = React.useState<{ left: number; width: number }>({
|
|
66
|
-
left: 0,
|
|
67
|
-
width: 0,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
setPrevTab(activeTab);
|
|
72
|
-
setIsAnimating(true);
|
|
73
|
-
|
|
74
|
-
const activeIndex = childrenArray.findIndex((child) => child.props.label === activeTab);
|
|
75
|
-
const container = tabsContainerRef.current;
|
|
76
|
-
|
|
77
|
-
if (container) {
|
|
78
|
-
container.querySelectorAll('[data-label]').forEach((el) => {
|
|
79
|
-
el.classList.remove('active');
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
container.getBoundingClientRect();
|
|
83
|
-
|
|
84
|
-
requestAnimationFrame(() => {
|
|
85
|
-
if (activeIndex >= 0) {
|
|
86
|
-
let activeTabElement: HTMLElement | null = null;
|
|
87
|
-
let startPosition = { left: 0, width: 0 };
|
|
88
|
-
|
|
89
|
-
if (visibleTabs.includes(activeIndex)) {
|
|
90
|
-
activeTabElement = container.querySelector(
|
|
91
|
-
`[data-label="${activeTab}"]`,
|
|
92
|
-
) as HTMLElement;
|
|
93
|
-
} else if (overflowTabs.includes(activeIndex)) {
|
|
94
|
-
const moreButton = container.querySelector('button') as HTMLElement;
|
|
95
|
-
if (moreButton) {
|
|
96
|
-
const moreButtonRect = moreButton.getBoundingClientRect();
|
|
97
|
-
const containerRect = container.getBoundingClientRect();
|
|
98
|
-
startPosition = {
|
|
99
|
-
left: moreButtonRect.left - containerRect.left,
|
|
100
|
-
width: moreButtonRect.width,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (activeTabElement) {
|
|
106
|
-
const { offsetLeft, offsetWidth } = activeTabElement;
|
|
107
|
-
|
|
108
|
-
if (overflowTabs.includes(activeIndex)) {
|
|
109
|
-
setHighlightStyle(startPosition);
|
|
110
|
-
requestAnimationFrame(() => {
|
|
111
|
-
setHighlightStyle({ left: offsetLeft, width: offsetWidth });
|
|
112
|
-
});
|
|
113
|
-
} else {
|
|
114
|
-
setHighlightStyle({ left: offsetLeft, width: offsetWidth });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (visibleTabs.includes(activeIndex)) {
|
|
118
|
-
activeTabElement?.classList.add('active');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return () => {
|
|
122
|
-
container.querySelectorAll('[data-label]').forEach((el) => {
|
|
123
|
-
el.classList.remove('active');
|
|
124
|
-
});
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
setHighlightStyle({ left: 0, width: 0 });
|
|
129
|
-
setIsAnimating(false);
|
|
130
|
-
});
|
|
131
|
-
} else {
|
|
132
|
-
setHighlightStyle({ left: 0, width: 0 });
|
|
133
|
-
setIsAnimating(false);
|
|
134
|
-
}
|
|
135
|
-
}, [activeTab, prevTab, childrenArray, visibleTabs, overflowTabs]);
|
|
136
48
|
|
|
137
49
|
return (
|
|
138
|
-
<TabsContainer
|
|
139
|
-
data-component-name="Markdoc/Tabs/Tabs"
|
|
140
|
-
className={className}
|
|
141
|
-
isReady={ready || forceReady}
|
|
142
|
-
>
|
|
50
|
+
<TabsContainer data-component-name="Markdoc/Tabs/Tabs" className={className} key={id}>
|
|
143
51
|
<TabList
|
|
144
52
|
size={size}
|
|
145
53
|
childrenArray={childrenArray}
|
|
146
|
-
overflowTabs={overflowTabs}
|
|
147
|
-
setTabRef={setTabRef}
|
|
148
|
-
onTabClick={onTabClick}
|
|
149
|
-
handleKeyboard={handleKeyboard}
|
|
150
|
-
getTabId={getTabId}
|
|
151
54
|
activeTab={activeTab}
|
|
152
|
-
|
|
153
|
-
highlightStyle={highlightStyle}
|
|
154
|
-
visibleTabs={visibleTabs}
|
|
155
|
-
allTabsHidden={allTabsHidden}
|
|
156
|
-
tabsContainerRef={tabsContainerRef}
|
|
55
|
+
onTabChange={setActiveTab}
|
|
157
56
|
/>
|
|
158
57
|
{childrenArray.map((child, index) => {
|
|
159
58
|
const { label } = child.props;
|
|
@@ -173,8 +72,7 @@ export function Tabs({
|
|
|
173
72
|
</TabsContainer>
|
|
174
73
|
);
|
|
175
74
|
}
|
|
176
|
-
|
|
177
|
-
const TabsContainer = styled.div<{ isReady: boolean }>`
|
|
75
|
+
const TabsContainer = styled.div`
|
|
178
76
|
position: relative;
|
|
179
77
|
color: var(--md-tabs-container-text-color);
|
|
180
78
|
font-size: var(--md-tabs-container-font-size);
|
|
@@ -186,17 +84,6 @@ const TabsContainer = styled.div<{ isReady: boolean }>`
|
|
|
186
84
|
padding: var(--md-tabs-container-padding);
|
|
187
85
|
border: var(--md-tabs-container-border);
|
|
188
86
|
|
|
189
|
-
${({ isReady }) =>
|
|
190
|
-
!isReady
|
|
191
|
-
? css`
|
|
192
|
-
visibility: hidden;
|
|
193
|
-
overflow: hidden;
|
|
194
|
-
`
|
|
195
|
-
: css`
|
|
196
|
-
visibility: visible;
|
|
197
|
-
overflow: visible;
|
|
198
|
-
`}
|
|
199
|
-
|
|
200
87
|
ol[class^='Tabs__TabList'] {
|
|
201
88
|
margin: 0;
|
|
202
89
|
padding: 0;
|
package/src/markdoc/tags/tabs.ts
CHANGED
|
@@ -22,6 +22,11 @@ export const tabs: MarkdocSchemaWrapper = {
|
|
|
22
22
|
return new markdoc.Tag('Tabs', attributes, tabsContent);
|
|
23
23
|
},
|
|
24
24
|
attributes: {
|
|
25
|
+
/*
|
|
26
|
+
A unique persistent identifier assigned to a component.
|
|
27
|
+
This value is used as a key for the query parameter that stores the active tab to enable deep linking.
|
|
28
|
+
*/
|
|
29
|
+
id: { type: String },
|
|
25
30
|
size: { type: String, matches: ['small', 'medium'], default: 'medium' },
|
|
26
31
|
},
|
|
27
32
|
},
|