@instructure/ui-tabs 8.13.1-snapshot.9 → 8.14.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/CHANGELOG.md +4 -0
- package/es/Tabs/Panel/index.js +3 -5
- package/es/Tabs/Panel/props.js +0 -8
- package/es/Tabs/Tab/index.js +17 -21
- package/es/Tabs/TabsLocator.js +2 -1
- package/es/Tabs/index.js +14 -13
- package/es/Tabs/props.js +0 -32
- package/lib/Tabs/Panel/index.js +3 -5
- package/lib/Tabs/Panel/props.js +0 -8
- package/lib/Tabs/Tab/index.js +19 -21
- package/lib/Tabs/TabsLocator.js +2 -1
- package/lib/Tabs/index.js +14 -13
- package/lib/Tabs/props.js +0 -32
- package/package.json +21 -22
- package/src/Tabs/Panel/index.tsx +5 -9
- package/src/Tabs/Panel/props.ts +10 -10
- package/src/Tabs/Tab/index.tsx +15 -19
- package/src/Tabs/Tab/props.ts +10 -3
- package/src/Tabs/index.tsx +55 -92
- package/src/Tabs/props.ts +41 -32
- package/tsconfig.build.json +25 -2
- package/tsconfig.build.tsbuildinfo +1 -0
- package/types/Tabs/Panel/index.d.ts +10 -12
- package/types/Tabs/Panel/index.d.ts.map +1 -1
- package/types/Tabs/Panel/props.d.ts +10 -3
- package/types/Tabs/Panel/props.d.ts.map +1 -1
- package/types/Tabs/Tab/index.d.ts +24 -19
- package/types/Tabs/Tab/index.d.ts.map +1 -1
- package/types/Tabs/Tab/props.d.ts +10 -3
- package/types/Tabs/Tab/props.d.ts.map +1 -1
- package/types/Tabs/TabsLocator.d.ts +381 -381
- package/types/Tabs/index.d.ts +38 -35
- package/types/Tabs/index.d.ts.map +1 -1
- package/types/Tabs/props.d.ts +40 -4
- package/types/Tabs/props.d.ts.map +1 -1
- package/LICENSE.md +0 -27
package/src/Tabs/Panel/index.tsx
CHANGED
|
@@ -41,6 +41,7 @@ import { allowedProps, propTypes } from './props'
|
|
|
41
41
|
parent: Tabs
|
|
42
42
|
id: Tabs.Panel
|
|
43
43
|
---
|
|
44
|
+
@tsProps
|
|
44
45
|
**/
|
|
45
46
|
@withStyle(generateStyle, generateComponentTheme)
|
|
46
47
|
class Panel extends Component<TabsPanelProps> {
|
|
@@ -50,29 +51,24 @@ class Panel extends Component<TabsPanelProps> {
|
|
|
50
51
|
static propTypes = propTypes
|
|
51
52
|
|
|
52
53
|
static defaultProps = {
|
|
53
|
-
children: null,
|
|
54
54
|
isDisabled: false,
|
|
55
55
|
textAlign: 'start',
|
|
56
56
|
variant: 'default',
|
|
57
|
-
labelledBy: null,
|
|
58
57
|
isSelected: false,
|
|
59
|
-
padding: 'small'
|
|
60
|
-
// @ts-expect-error ts-migrate(6133) FIXME: 'el' is declared but its value is never read.
|
|
61
|
-
elementRef: (el) => {}
|
|
58
|
+
padding: 'small'
|
|
62
59
|
}
|
|
63
60
|
|
|
64
61
|
componentDidMount() {
|
|
65
62
|
this.props.makeStyles?.()
|
|
66
63
|
}
|
|
67
64
|
|
|
68
|
-
|
|
69
|
-
componentDidUpdate(prevProps, prevState, snapshot) {
|
|
65
|
+
componentDidUpdate() {
|
|
70
66
|
this.props.makeStyles?.()
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
ref:
|
|
69
|
+
ref: HTMLDivElement | null = null
|
|
74
70
|
|
|
75
|
-
handleRef = (el:
|
|
71
|
+
handleRef = (el: HTMLDivElement | null) => {
|
|
76
72
|
const { elementRef } = this.props
|
|
77
73
|
|
|
78
74
|
this.ref = el
|
package/src/Tabs/Panel/props.ts
CHANGED
|
@@ -39,7 +39,12 @@ import type {
|
|
|
39
39
|
} from '@instructure/shared-types'
|
|
40
40
|
|
|
41
41
|
type TabsPanelOwnProps = {
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The content that will be rendered in the corresponding <Tab /> and will label
|
|
44
|
+
* this `<Tabs.Panel />` for screen readers
|
|
45
|
+
*/
|
|
46
|
+
renderTitle: React.ReactNode | (() => React.ReactNode)
|
|
47
|
+
children?: React.ReactNode
|
|
43
48
|
variant?: 'default' | 'secondary'
|
|
44
49
|
isSelected?: boolean
|
|
45
50
|
isDisabled?: boolean
|
|
@@ -49,8 +54,10 @@ type TabsPanelOwnProps = {
|
|
|
49
54
|
labelledBy?: string
|
|
50
55
|
padding?: Spacing
|
|
51
56
|
textAlign?: 'start' | 'center' | 'end'
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
/**
|
|
58
|
+
* provides a reference to the underlying html root element
|
|
59
|
+
*/
|
|
60
|
+
elementRef?: (element: HTMLDivElement | null) => void
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
type PropKeys = keyof TabsPanelOwnProps
|
|
@@ -64,10 +71,6 @@ type TabsPanelProps = TabsPanelOwnProps &
|
|
|
64
71
|
type TabsPanelStyle = ComponentStyle<'panel' | 'content'>
|
|
65
72
|
|
|
66
73
|
const propTypes: PropValidators<PropKeys> = {
|
|
67
|
-
/**
|
|
68
|
-
* The content that will be rendered in the corresponding <Tab /> and will label
|
|
69
|
-
* this `<Tabs.Panel />` for screen readers
|
|
70
|
-
*/
|
|
71
74
|
renderTitle: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
|
72
75
|
children: PropTypes.node,
|
|
73
76
|
variant: PropTypes.oneOf(['default', 'secondary']),
|
|
@@ -79,9 +82,6 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
79
82
|
labelledBy: PropTypes.string,
|
|
80
83
|
padding: ThemeablePropTypes.spacing,
|
|
81
84
|
textAlign: PropTypes.oneOf(['start', 'center', 'end']),
|
|
82
|
-
/**
|
|
83
|
-
* provides a reference to the underlying html root element
|
|
84
|
-
*/
|
|
85
85
|
elementRef: PropTypes.func
|
|
86
86
|
}
|
|
87
87
|
|
package/src/Tabs/Tab/index.tsx
CHANGED
|
@@ -23,15 +23,17 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
/** @jsx jsx */
|
|
26
|
-
import { Component } from 'react'
|
|
26
|
+
import React, { Component } from 'react'
|
|
27
27
|
|
|
28
28
|
import { passthroughProps, callRenderProp } from '@instructure/ui-react-utils'
|
|
29
29
|
import { View } from '@instructure/ui-view'
|
|
30
|
+
import type { ViewOwnProps } from '@instructure/ui-view'
|
|
30
31
|
|
|
31
32
|
import { withStyle, jsx } from '@instructure/emotion'
|
|
32
33
|
|
|
33
34
|
import generateStyle from './styles'
|
|
34
35
|
import generateComponentTheme from './theme'
|
|
36
|
+
|
|
35
37
|
import type { TabsTabProps } from './props'
|
|
36
38
|
import { allowedProps, propTypes } from './props'
|
|
37
39
|
|
|
@@ -40,6 +42,7 @@ import { allowedProps, propTypes } from './props'
|
|
|
40
42
|
parent: Tabs
|
|
41
43
|
id: Tabs.Tab
|
|
42
44
|
---
|
|
45
|
+
@tsProps
|
|
43
46
|
**/
|
|
44
47
|
@withStyle(generateStyle, generateComponentTheme)
|
|
45
48
|
class Tab extends Component<TabsTabProps> {
|
|
@@ -49,47 +52,41 @@ class Tab extends Component<TabsTabProps> {
|
|
|
49
52
|
static propTypes = propTypes
|
|
50
53
|
|
|
51
54
|
static defaultProps = {
|
|
52
|
-
children: null,
|
|
53
55
|
variant: 'default',
|
|
54
56
|
isDisabled: false,
|
|
55
|
-
isSelected: false
|
|
56
|
-
// @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
|
|
57
|
-
onClick: (event, { index, id }) => {},
|
|
58
|
-
// @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
|
|
59
|
-
onKeyDown: (event, { index, id }) => {}
|
|
57
|
+
isSelected: false
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
componentDidMount() {
|
|
63
61
|
this.props.makeStyles?.()
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
componentDidUpdate(prevProps, prevState, snapshot) {
|
|
64
|
+
componentDidUpdate() {
|
|
68
65
|
this.props.makeStyles?.()
|
|
69
66
|
}
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
handleClick = (event) => {
|
|
68
|
+
handleClick = (event: React.MouseEvent<ViewOwnProps>) => {
|
|
73
69
|
const { onClick, index, id, isDisabled } = this.props
|
|
74
70
|
|
|
75
71
|
if (isDisabled) {
|
|
76
72
|
return
|
|
77
73
|
}
|
|
78
74
|
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
if (typeof onClick === 'function') {
|
|
76
|
+
onClick(event, { index, id })
|
|
77
|
+
}
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
|
|
84
|
-
handleKeyDown = (event) => {
|
|
80
|
+
handleKeyDown = (event: React.KeyboardEvent<ViewOwnProps>) => {
|
|
85
81
|
const { onKeyDown, index, id, isDisabled } = this.props
|
|
86
82
|
|
|
87
83
|
if (isDisabled) {
|
|
88
84
|
return
|
|
89
85
|
}
|
|
90
86
|
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
if (typeof onKeyDown === 'function') {
|
|
88
|
+
onKeyDown(event, { index, id })
|
|
89
|
+
}
|
|
93
90
|
}
|
|
94
91
|
|
|
95
92
|
render() {
|
|
@@ -116,8 +113,7 @@ class Tab extends Component<TabsTabProps> {
|
|
|
116
113
|
aria-selected={isSelected ? 'true' : undefined}
|
|
117
114
|
aria-disabled={isDisabled ? 'true' : undefined}
|
|
118
115
|
aria-controls={controls}
|
|
119
|
-
|
|
120
|
-
tabIndex={isSelected && !isDisabled ? '0' : undefined}
|
|
116
|
+
tabIndex={isSelected && !isDisabled ? 0 : undefined}
|
|
121
117
|
position="relative"
|
|
122
118
|
focusPosition="inset"
|
|
123
119
|
>
|
package/src/Tabs/Tab/props.ts
CHANGED
|
@@ -31,6 +31,7 @@ import type {
|
|
|
31
31
|
TabsTabTheme
|
|
32
32
|
} from '@instructure/shared-types'
|
|
33
33
|
import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
|
|
34
|
+
import type { ViewOwnProps } from '@instructure/ui-view'
|
|
34
35
|
|
|
35
36
|
type TabsTabOwnProps = {
|
|
36
37
|
variant?: 'default' | 'secondary'
|
|
@@ -39,9 +40,15 @@ type TabsTabOwnProps = {
|
|
|
39
40
|
controls: string
|
|
40
41
|
isDisabled?: boolean
|
|
41
42
|
isSelected?: boolean
|
|
42
|
-
onClick?: (
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
onClick?: (
|
|
44
|
+
event: React.MouseEvent<ViewOwnProps>,
|
|
45
|
+
tabData: { index: number; id: string }
|
|
46
|
+
) => void
|
|
47
|
+
onKeyDown?: (
|
|
48
|
+
event: React.KeyboardEvent<ViewOwnProps>,
|
|
49
|
+
tabData: { index: number; id: string }
|
|
50
|
+
) => void
|
|
51
|
+
children?: React.ReactNode | (() => React.ReactNode)
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
type PropKeys = keyof TabsTabOwnProps
|
package/src/Tabs/index.tsx
CHANGED
|
@@ -27,13 +27,13 @@ import React, {
|
|
|
27
27
|
Component,
|
|
28
28
|
ComponentClass,
|
|
29
29
|
ComponentElement,
|
|
30
|
-
createElement
|
|
31
|
-
ReactElement
|
|
30
|
+
createElement
|
|
32
31
|
} from 'react'
|
|
33
32
|
|
|
34
33
|
import keycode from 'keycode'
|
|
35
34
|
|
|
36
35
|
import { View } from '@instructure/ui-view'
|
|
36
|
+
import type { ViewOwnProps } from '@instructure/ui-view'
|
|
37
37
|
import {
|
|
38
38
|
matchComponentTypes,
|
|
39
39
|
safeCloneElement,
|
|
@@ -44,7 +44,9 @@ import { uid } from '@instructure/uid'
|
|
|
44
44
|
import { testable } from '@instructure/ui-testable'
|
|
45
45
|
import { Focusable } from '@instructure/ui-focusable'
|
|
46
46
|
import { getBoundingClientRect } from '@instructure/ui-dom-utils'
|
|
47
|
+
import type { RectType } from '@instructure/ui-dom-utils'
|
|
47
48
|
import { debounce } from '@instructure/debounce'
|
|
49
|
+
import type { Debounced } from '@instructure/debounce'
|
|
48
50
|
import { px } from '@instructure/ui-utils'
|
|
49
51
|
import { textDirectionContextConsumer } from '@instructure/ui-i18n'
|
|
50
52
|
|
|
@@ -57,22 +59,24 @@ import { Tab } from './Tab'
|
|
|
57
59
|
import { Panel } from './Panel'
|
|
58
60
|
|
|
59
61
|
import { allowedProps, propTypes } from './props'
|
|
60
|
-
import type { TabsProps } from './props'
|
|
62
|
+
import type { TabsProps, TabsState } from './props'
|
|
63
|
+
|
|
61
64
|
import type { TabsTabProps } from './Tab/props'
|
|
62
65
|
import type { TabsPanelProps } from './Panel/props'
|
|
63
66
|
|
|
64
|
-
type TabChild =
|
|
65
|
-
type PanelChild =
|
|
67
|
+
type TabChild = ComponentElement<TabsTabProps, any>
|
|
68
|
+
type PanelChild = ComponentElement<TabsPanelProps, any>
|
|
66
69
|
|
|
67
70
|
/**
|
|
68
71
|
---
|
|
69
72
|
category: components
|
|
70
73
|
---
|
|
74
|
+
@tsProps
|
|
71
75
|
**/
|
|
72
76
|
@withStyle(generateStyle, generateComponentTheme)
|
|
73
77
|
@textDirectionContextConsumer()
|
|
74
78
|
@testable()
|
|
75
|
-
class Tabs extends Component<TabsProps> {
|
|
79
|
+
class Tabs extends Component<TabsProps, TabsState> {
|
|
76
80
|
static readonly componentId = 'Tabs'
|
|
77
81
|
|
|
78
82
|
static allowedProps = allowedProps
|
|
@@ -80,10 +84,6 @@ class Tabs extends Component<TabsProps> {
|
|
|
80
84
|
|
|
81
85
|
static defaultProps = {
|
|
82
86
|
variant: 'default',
|
|
83
|
-
// @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
|
|
84
|
-
onRequestTabChange: (event, { index, id }) => {},
|
|
85
|
-
children: null,
|
|
86
|
-
elementRef: () => {},
|
|
87
87
|
shouldFocusOnRender: false,
|
|
88
88
|
tabOverflow: 'stack'
|
|
89
89
|
}
|
|
@@ -91,6 +91,12 @@ class Tabs extends Component<TabsProps> {
|
|
|
91
91
|
static Panel = Panel
|
|
92
92
|
static Tab = Tab
|
|
93
93
|
|
|
94
|
+
private _tabList: Element | null = null
|
|
95
|
+
private _focusable: Focusable | null = null
|
|
96
|
+
private _tabListPosition?: RectType
|
|
97
|
+
private _debounced?: Debounced
|
|
98
|
+
private _resizeListener?: ResizeObserver
|
|
99
|
+
|
|
94
100
|
ref: Element | null = null
|
|
95
101
|
|
|
96
102
|
handleRef = (el: Element | null) => {
|
|
@@ -103,22 +109,15 @@ class Tabs extends Component<TabsProps> {
|
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
|
|
107
|
-
constructor(props) {
|
|
112
|
+
constructor(props: TabsProps) {
|
|
108
113
|
super(props)
|
|
109
114
|
|
|
110
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
111
|
-
this._tabList = null
|
|
112
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabListPosition' does not exist on type... Remove this comment to see the full error message
|
|
113
|
-
this._tabListPosition = null
|
|
114
|
-
|
|
115
115
|
this.state = {
|
|
116
116
|
withTabListOverflow: false
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
componentDidMount() {
|
|
121
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
122
121
|
if (this.props.tabOverflow === 'scroll' && this._tabList) {
|
|
123
122
|
this.startScrollOverflow()
|
|
124
123
|
}
|
|
@@ -130,8 +129,7 @@ class Tabs extends Component<TabsProps> {
|
|
|
130
129
|
this.props.makeStyles?.()
|
|
131
130
|
}
|
|
132
131
|
|
|
133
|
-
|
|
134
|
-
componentDidUpdate(prevProps, prevState, snapshot) {
|
|
132
|
+
componentDidUpdate(prevProps: TabsProps, prevState: TabsState) {
|
|
135
133
|
if (this.props.shouldFocusOnRender && !prevProps.shouldFocusOnRender) {
|
|
136
134
|
this.focus()
|
|
137
135
|
}
|
|
@@ -164,13 +162,10 @@ class Tabs extends Component<TabsProps> {
|
|
|
164
162
|
// make sure active tab is always visible
|
|
165
163
|
if (
|
|
166
164
|
this.props.tabOverflow === 'scroll' &&
|
|
167
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
168
165
|
this._tabList &&
|
|
169
166
|
!prevState.withTabListOverflow &&
|
|
170
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property 'withTabListOverflow' does not exist on t... Remove this comment to see the full error message
|
|
171
167
|
this.state.withTabListOverflow
|
|
172
168
|
) {
|
|
173
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
174
169
|
const activeTabEl = this._tabList.querySelector('[aria-selected="true"]')
|
|
175
170
|
this.showActiveTabIfOverlayed(activeTabEl)
|
|
176
171
|
}
|
|
@@ -185,72 +180,58 @@ class Tabs extends Component<TabsProps> {
|
|
|
185
180
|
startScrollOverflow() {
|
|
186
181
|
this.handleResize()
|
|
187
182
|
|
|
188
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_debounced' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
189
183
|
this._debounced = debounce(this.handleResize, 300, {
|
|
190
184
|
leading: true,
|
|
191
185
|
trailing: true
|
|
192
186
|
})
|
|
193
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabListPosition' does not exist on type... Remove this comment to see the full error message
|
|
194
187
|
this._tabListPosition = getBoundingClientRect(this._tabList)
|
|
195
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_resizeListener' does not exist on type ... Remove this comment to see the full error message
|
|
196
188
|
this._resizeListener = new ResizeObserver((entries) => {
|
|
197
189
|
for (const entry of entries) {
|
|
198
190
|
const { width: newWidth } = entry.contentRect
|
|
199
191
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_debounced' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
203
|
-
this._debounced()
|
|
192
|
+
if (this._tabListPosition!.width !== newWidth) {
|
|
193
|
+
this._debounced?.()
|
|
204
194
|
}
|
|
205
195
|
}
|
|
206
196
|
})
|
|
207
197
|
|
|
208
|
-
|
|
209
|
-
this._resizeListener.observe(this._tabList)
|
|
198
|
+
this._resizeListener.observe(this._tabList!)
|
|
210
199
|
}
|
|
211
200
|
|
|
212
201
|
cancelScrollOverflow() {
|
|
213
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_resizeListener' does not exist on type ... Remove this comment to see the full error message
|
|
214
202
|
if (this._resizeListener) {
|
|
215
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_resizeListener' does not exist on type ... Remove this comment to see the full error message
|
|
216
203
|
this._resizeListener.disconnect()
|
|
217
204
|
}
|
|
218
205
|
|
|
219
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_debounced' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
220
206
|
if (this._debounced) {
|
|
221
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_debounced' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
222
207
|
this._debounced.cancel()
|
|
223
208
|
}
|
|
224
209
|
}
|
|
225
210
|
|
|
226
|
-
// @ts-expect-error TODO: not all codepaths return a value!
|
|
227
211
|
getOverlayWidth() {
|
|
228
212
|
const { variant, tabOverflow, styles } = this.props
|
|
229
213
|
|
|
230
|
-
if (tabOverflow === 'scroll') {
|
|
214
|
+
if (styles && tabOverflow === 'scroll') {
|
|
231
215
|
if (variant === 'default') {
|
|
232
|
-
return px(styles?.scrollOverlayWidthDefault
|
|
216
|
+
return px(styles?.scrollOverlayWidthDefault)
|
|
233
217
|
} else {
|
|
234
|
-
return px(styles?.scrollOverlayWidthSecondary
|
|
218
|
+
return px(styles?.scrollOverlayWidthSecondary)
|
|
235
219
|
}
|
|
236
220
|
}
|
|
221
|
+
|
|
222
|
+
return 0
|
|
237
223
|
}
|
|
238
224
|
|
|
239
|
-
|
|
240
|
-
showActiveTabIfOverlayed(activeTabEl) {
|
|
225
|
+
showActiveTabIfOverlayed(activeTabEl: Element | null) {
|
|
241
226
|
if (
|
|
242
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
243
227
|
this._tabList &&
|
|
244
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabListPosition' does not exist on type... Remove this comment to see the full error message
|
|
245
228
|
this._tabListPosition &&
|
|
246
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
247
229
|
typeof this._tabList.scrollTo === 'function' // test for scrollTo support
|
|
248
230
|
) {
|
|
249
231
|
const { dir } = this.props
|
|
250
232
|
const isRtl = dir === textDirectionContextConsumer.DIRECTION.rtl
|
|
251
233
|
|
|
252
234
|
const tabPosition = getBoundingClientRect(activeTabEl)
|
|
253
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabListPosition' does not exist on type... Remove this comment to see the full error message
|
|
254
235
|
const tabListPosition = this._tabListPosition
|
|
255
236
|
|
|
256
237
|
const tabListBoundStart = isRtl
|
|
@@ -265,19 +246,15 @@ class Tabs extends Component<TabsProps> {
|
|
|
265
246
|
|
|
266
247
|
if (tabListBoundEnd > tabPositionEnd) {
|
|
267
248
|
const offset = Math.round(tabListBoundEnd - tabPositionEnd)
|
|
268
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
269
249
|
this._tabList.scrollTo({
|
|
270
250
|
top: 0,
|
|
271
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
272
251
|
left: this._tabList.scrollLeft + offset,
|
|
273
252
|
behavior: 'smooth'
|
|
274
253
|
})
|
|
275
254
|
} else if (tabListBoundStart > tabPositionStart) {
|
|
276
255
|
const offset = Math.round(tabListBoundStart - tabPositionStart)
|
|
277
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
278
256
|
this._tabList.scrollTo({
|
|
279
257
|
top: 0,
|
|
280
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
281
258
|
left: this._tabList.scrollLeft - offset,
|
|
282
259
|
behavior: 'smooth'
|
|
283
260
|
})
|
|
@@ -285,14 +262,12 @@ class Tabs extends Component<TabsProps> {
|
|
|
285
262
|
}
|
|
286
263
|
}
|
|
287
264
|
|
|
288
|
-
|
|
289
|
-
handleTabClick = (event, { index, id }) => {
|
|
265
|
+
handleTabClick: TabsTabProps['onClick'] = (event, { index }) => {
|
|
290
266
|
const nextTab = this.getNextTab(index, 0)
|
|
291
267
|
this.fireOnChange(event, nextTab)
|
|
292
268
|
}
|
|
293
269
|
|
|
294
|
-
|
|
295
|
-
handleTabKeyDown = (event, { index }) => {
|
|
270
|
+
handleTabKeyDown: TabsTabProps['onKeyDown'] = (event, { index }) => {
|
|
296
271
|
let nextTab
|
|
297
272
|
|
|
298
273
|
if (
|
|
@@ -316,19 +291,20 @@ class Tabs extends Component<TabsProps> {
|
|
|
316
291
|
|
|
317
292
|
handleResize = () => {
|
|
318
293
|
this.setState({
|
|
319
|
-
|
|
320
|
-
|
|
294
|
+
withTabListOverflow:
|
|
295
|
+
this._tabList!.scrollWidth > (this._tabList as HTMLElement).offsetWidth
|
|
321
296
|
})
|
|
322
297
|
|
|
323
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabListPosition' does not exist on type... Remove this comment to see the full error message
|
|
324
298
|
this._tabListPosition = getBoundingClientRect(this._tabList)
|
|
325
299
|
}
|
|
326
300
|
|
|
327
|
-
|
|
328
|
-
|
|
301
|
+
getNextTab(
|
|
302
|
+
startIndex: number,
|
|
303
|
+
step: -1 | 0 | 1
|
|
304
|
+
): { index: number; id?: string } {
|
|
329
305
|
const tabs = React.Children.toArray(this.props.children).map(
|
|
330
306
|
(child) => matchComponentTypes(child, [Panel]) && child
|
|
331
|
-
)
|
|
307
|
+
) as PanelChild[]
|
|
332
308
|
const count = tabs.length
|
|
333
309
|
const change = step < 0 ? step + count : step
|
|
334
310
|
|
|
@@ -338,32 +314,30 @@ class Tabs extends Component<TabsProps> {
|
|
|
338
314
|
)
|
|
339
315
|
|
|
340
316
|
let nextIndex = startIndex
|
|
341
|
-
let nextTab
|
|
317
|
+
let nextTab: PanelChild
|
|
342
318
|
|
|
343
319
|
do {
|
|
344
320
|
nextIndex = (nextIndex + change) % count
|
|
345
321
|
nextTab = tabs[nextIndex]
|
|
346
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property 'props' does not exist on type 'string | ... Remove this comment to see the full error message
|
|
347
322
|
} while (nextTab && nextTab.props && nextTab.props.isDisabled)
|
|
348
323
|
|
|
349
324
|
error(
|
|
350
325
|
nextIndex >= 0 && nextIndex < count,
|
|
351
326
|
`[Tabs] Invalid tab index: '${nextIndex}'.`
|
|
352
327
|
)
|
|
353
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property 'props' does not exist on type '{}'.
|
|
354
328
|
return { index: nextIndex, id: nextTab.props.id }
|
|
355
329
|
}
|
|
356
330
|
|
|
357
|
-
|
|
358
|
-
|
|
331
|
+
fireOnChange(
|
|
332
|
+
event: React.MouseEvent<ViewOwnProps> | React.KeyboardEvent<ViewOwnProps>,
|
|
333
|
+
{ index, id }: { index: number; id?: string }
|
|
334
|
+
) {
|
|
359
335
|
if (typeof this.props.onRequestTabChange === 'function') {
|
|
360
336
|
this.props.onRequestTabChange(event, { index, id })
|
|
361
337
|
}
|
|
362
338
|
|
|
363
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property 'withTabListOverflow' does not exist on t... Remove this comment to see the full error message
|
|
364
339
|
this.state.withTabListOverflow &&
|
|
365
|
-
|
|
366
|
-
this.showActiveTabIfOverlayed(this._tabList.querySelector(`#tab-${id}`))
|
|
340
|
+
this.showActiveTabIfOverlayed(this._tabList!.querySelector(`#tab-${id}`))
|
|
367
341
|
}
|
|
368
342
|
|
|
369
343
|
createTab(
|
|
@@ -409,33 +383,25 @@ class Tabs extends Component<TabsProps> {
|
|
|
409
383
|
textAlign: panel.props.textAlign || this.props.textAlign,
|
|
410
384
|
maxHeight: !hasFixedHeight ? this.props.maxHeight : undefined,
|
|
411
385
|
minHeight: !hasFixedHeight ? this.props.minHeight : '100%'
|
|
412
|
-
})
|
|
386
|
+
} as TabsPanelProps & { key: string }) as PanelChild
|
|
413
387
|
}
|
|
414
388
|
|
|
415
|
-
|
|
416
|
-
handleFocusableRef = (el) => {
|
|
417
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_focusable' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
389
|
+
handleFocusableRef = (el: Focusable | null) => {
|
|
418
390
|
this._focusable = el
|
|
419
391
|
}
|
|
420
392
|
|
|
421
|
-
|
|
422
|
-
handleTabListRef = (el) => {
|
|
423
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_tabList' does not exist on type 'Tabs'.
|
|
393
|
+
handleTabListRef = (el: Element | null) => {
|
|
424
394
|
this._tabList = el
|
|
425
395
|
}
|
|
426
396
|
|
|
427
397
|
focus() {
|
|
428
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_focusable' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
429
398
|
this._focusable &&
|
|
430
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_focusable' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
431
399
|
typeof this._focusable.focus === 'function' &&
|
|
432
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property '_focusable' does not exist on type 'Tabs... Remove this comment to see the full error message
|
|
433
400
|
this._focusable.focus()
|
|
434
401
|
}
|
|
435
402
|
|
|
436
403
|
render() {
|
|
437
|
-
|
|
438
|
-
const panels = []
|
|
404
|
+
const panels: PanelChild[] = []
|
|
439
405
|
const tabs: TabChild[] = []
|
|
440
406
|
const {
|
|
441
407
|
children,
|
|
@@ -450,23 +416,24 @@ class Tabs extends Component<TabsProps> {
|
|
|
450
416
|
...props
|
|
451
417
|
} = this.props
|
|
452
418
|
|
|
453
|
-
const selectedChildIndex =
|
|
419
|
+
const selectedChildIndex = (
|
|
420
|
+
React.Children.toArray(children) as PanelChild[]
|
|
421
|
+
)
|
|
454
422
|
.filter((child) => matchComponentTypes(child, [Panel]))
|
|
455
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property 'props' does not exist on type 'string | ... Remove this comment to see the full error message
|
|
456
423
|
.findIndex((child) => child.props.isSelected && !child.props.isDisabled)
|
|
457
424
|
|
|
458
425
|
let index = 0
|
|
459
426
|
const selectedIndex = selectedChildIndex >= 0 ? selectedChildIndex : 0
|
|
460
427
|
|
|
461
|
-
React.Children.forEach(children, (child) => {
|
|
428
|
+
React.Children.forEach(children as PanelChild[], (child) => {
|
|
462
429
|
if (matchComponentTypes(child, [Panel])) {
|
|
463
430
|
const selected =
|
|
464
|
-
!
|
|
465
|
-
(
|
|
431
|
+
!child.props.isDisabled &&
|
|
432
|
+
(child.props.isSelected || selectedIndex === index)
|
|
466
433
|
const id = uid()
|
|
467
434
|
|
|
468
|
-
tabs.push(this.createTab(index, id, selected, child
|
|
469
|
-
panels.push(this.clonePanel(index, id, selected, child
|
|
435
|
+
tabs.push(this.createTab(index, id, selected, child))
|
|
436
|
+
panels.push(this.clonePanel(index, id, selected, child))
|
|
470
437
|
|
|
471
438
|
index++
|
|
472
439
|
} else {
|
|
@@ -475,7 +442,6 @@ class Tabs extends Component<TabsProps> {
|
|
|
475
442
|
})
|
|
476
443
|
|
|
477
444
|
const withScrollFade =
|
|
478
|
-
// @ts-expect-error ts-migrate(2339) FIXME: Property 'withTabListOverflow' does not exist on t... Remove this comment to see the full error message
|
|
479
445
|
tabOverflow === 'scroll' && this.state.withTabListOverflow
|
|
480
446
|
|
|
481
447
|
// suppress overlay whenever final Tab is active, or Firefox will cover it
|
|
@@ -522,10 +488,7 @@ class Tabs extends Component<TabsProps> {
|
|
|
522
488
|
)}
|
|
523
489
|
</Focusable>
|
|
524
490
|
|
|
525
|
-
<div css={styles?.panelsContainer}>
|
|
526
|
-
{/* @ts-expect-error ts-migrate(7005) FIXME: Variable 'panels' implicitly has an 'any[]' type. */}
|
|
527
|
-
{panels}
|
|
528
|
-
</div>
|
|
491
|
+
<div css={styles?.panelsContainer}>{panels}</div>
|
|
529
492
|
</View>
|
|
530
493
|
)
|
|
531
494
|
}
|