* A Dash component that lets you render pages with tabs - the Tabs component's children * can be dcc.Tab components, which can hold a label that will be displayed as a tab, and can in turn hold * children components that will be that tab's content.
({
// eslint-disable-next-line no-magic-numbers
mobile_breakpoint = 800,
colors = {
border: 'var(--Dash-Stroke-Weak)',
primary: 'var(--Dash-Fill-Interactive-Strong)',
background: 'var(--Dash-Fill-Interactive-Weak)',
},
vertical = false,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
persisted_props = [PersistedProps.value],
// eslint-disable-next-line @typescript-eslint/no-unused-vars
persistence_type = PersistenceTypes.local,
children,
...props
}: TabsProps)
| 97 | * children components that will be that tab's content. |
| 98 | */ |
| 99 | function Tabs({ |
| 100 | // eslint-disable-next-line no-magic-numbers |
| 101 | mobile_breakpoint = 800, |
| 102 | colors = { |
| 103 | border: 'var(--Dash-Stroke-Weak)', |
| 104 | primary: 'var(--Dash-Fill-Interactive-Strong)', |
| 105 | background: 'var(--Dash-Fill-Interactive-Weak)', |
| 106 | }, |
| 107 | vertical = false, |
| 108 | // eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 109 | persisted_props = [PersistedProps.value], |
| 110 | // eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 111 | persistence_type = PersistenceTypes.local, |
| 112 | children, |
| 113 | ...props |
| 114 | }: TabsProps) { |
| 115 | const initializedRef = useRef(false); |
| 116 | const [isAboveBreakpoint, setIsAboveBreakpoint] = useState(false); |
| 117 | |
| 118 | const parseChildrenToArray = useCallback((): DashComponent[] => { |
| 119 | if (!children) { |
| 120 | return []; |
| 121 | } |
| 122 | if (children instanceof Array) { |
| 123 | return children; |
| 124 | } |
| 125 | return [children]; |
| 126 | }, [children]); |
| 127 | |
| 128 | const valueOrDefault = (): string | undefined => { |
| 129 | if (has('value', props)) { |
| 130 | return props.value; |
| 131 | } |
| 132 | const children = parseChildrenToArray(); |
| 133 | if (children && children.length && children[0].props.componentPath) { |
| 134 | const firstChildren: TabProps = window.dash_component_api.getLayout( |
| 135 | [...children[0].props.componentPath, 'props'] |
| 136 | ); |
| 137 | return firstChildren.value ?? 'tab-1'; |
| 138 | } |
| 139 | return 'tab-1'; |
| 140 | }; |
| 141 | |
| 142 | // Initialize value on mount if not set |
| 143 | useEffect(() => { |
| 144 | if (!initializedRef.current && !has('value', props)) { |
| 145 | props.setProps({ |
| 146 | value: `${valueOrDefault()}`, |
| 147 | }); |
| 148 | initializedRef.current = true; |
| 149 | } |
| 150 | }, []); |
| 151 | |
| 152 | // Setup matchMedia for responsive breakpoint |
| 153 | useEffect(() => { |
| 154 | const mediaQuery = window.matchMedia( |
| 155 | `(min-width: ${mobile_breakpoint}px)` |
| 156 | ); |
nothing calls this directly
no test coverage detected
searching dependent graphs…