Closed 2Pacalypse- closed 2 years ago
Can you post the complete text of the file up to the point of the screenshot, and also your preferences?
Sure, here you go:
import React, { useCallback, useMemo } from 'react'
import styled from 'styled-components'
import { amberA400, colorDividers, colorTextFaint, colorTextSecondary } from '../styles/colors'
import { buttonText, singleLine } from '../styles/typography'
import { useButtonState } from './button'
import { buttonReset } from './button-reset'
import { Ripple } from './ripple'
const Container = styled.div`
position: relative;
height: 48px;
margin: 0;
/* 36px + 12px = 48px total height */
padding: 6px 24px;
display: flex;
flex-direction: row;
contain: content;
`
export const TabTitle = styled.span`
${buttonText};
${singleLine};
`
export const TabItemContainer = styled.button<{ $isActiveTab: boolean }>`
${buttonReset};
flex: 1 1 auto;
min-width: 64px;
height: 36px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0 16px;
color: ${props => (props.$isActiveTab ? amberA400 : colorTextSecondary)};
background-color: ${props => (props.$isActiveTab ? 'rgba(255, 255, 255, 0.08)' : 'transparent')};
border-radius: 4px;
transition: background-color 15ms linear, color 15ms linear;
&:disabled {
color: ${colorTextFaint};
background-color: transparent;
}
`
export const TabSpacer = styled.div`
height: 1px;
min-width: 0px;
max-width: 24px;
flex: 1 1 0;
`
const BottomDivider = styled.div`
position: absolute;
height: 1px;
bottom: 0;
left: 0;
right: 0;
background-color: ${colorDividers};
`
export interface TabItemProps<T> {
text: string
value: T
disabled?: boolean
className?: string
/**
* Whether or not the tab is the active one. This will be set by the containing Tabs component and
* should not be passed directly.
*/
active?: boolean
/**
* Called whenever this tab is selected. This will be set by the containing Tabs component and
* should not be passed directly.
*/
onSelected?: (value: T) => void
}
export const TabItem = React.memo(
React.forwardRef(
<T,>(
{ text, value, active, disabled, onSelected, className }: TabItemProps<T>,
ref: React.ForwardedRef<HTMLButtonElement>,
) => {
const onClick = useCallback(() => {
if (!disabled && onSelected) {
onSelected(value)
}
}, [disabled, value, onSelected])
const [buttonProps, rippleRef] = useButtonState({
disabled,
onClick,
})
return (
<TabItemContainer
ref={ref}
className={className}
$isActiveTab={active ?? false}
title={text}
{...buttonProps}>
<TabTitle>{text}</TabTitle>
<Ripple ref={rippleRef} disabled={disabled} />
</TabItemContainer>
)
},
),
)
export interface TabsProps<T> {
children: ReturnType<typeof TabItem>[]
activeTab: T
onChange?: (value: T) => void
bottomDivider?: boolean
className?: string
}
export function Tabs<T>({ children, activeTab, onChange, bottomDivider, className }: TabsProps<T>) {
const tabElems = useMemo(() => {
const tabs = React.Children.map(children, (child, i) => {
const isActive = activeTab === (child!.props as TabItemProps<T>).value
return React.cloneElement(child!, {
key: `tab-${i}`,
active: isActive,
onSelected: onChange,
})
})
const tabElems: React.ReactNode[] = []
for (let i = 0; i < tabs!.length; i++) {
tabElems.push(tabs![i])
tabElems.push(<TabSpacer key={`spacer-${i}`} />)
}
// Remove the last spacer since we don't want spacers on the outside
tabElems.pop()
return tabElems
}, [activeTab, children, onChange])
return (
<Container className={className}>
{tabElems}
{bottomDivider ? <BottomDivider /> : null}
</Container>
)
}
Preferences:
{
// Each configuration will be compiled into a custom syntax definition.
// The keys are the names of the configurations,
// and the values are objects specifying syntax options.
"configurations": {
"Default": {},
"React": {
"file_extensions": [ "js", "jsx" ],
"flow_types": true,
"jsx": true,
"custom_templates": {
"styled_components": true,
"tags": {
"css": "scope:source.js.css",
"createGlobalStyle": "scope:source.css", // v4 and above
"injectGlobal": "scope:source.css", // before v4
}
}
},
"TypeScript": {
"scope": "source.ts",
"file_extensions": [ "ts" ],
"typescript": true,
"custom_templates": {
"styled_components": true,
"tags": {
"css": "scope:source.js.css",
"createGlobalStyle": "scope:source.css", // v4 and above
"injectGlobal": "scope:source.css", // before v4
}
}
},
"TypeScript (JSX)": {
"scope": "source.tsx",
"file_extensions": [ "tsx" ],
"typescript": true,
"jsx": true,
"custom_templates": {
"styled_components": true,
"tags": {
"css": "scope:source.js.css",
"createGlobalStyle": "scope:source.css", // v4 and above
"injectGlobal": "scope:source.css", // before v4
}
}
},
},
// These options will be used for all of your configurations, unless you override them.
"defaults": {
"custom_template_tags": false,
"flow_types": false,
"jsx": false,
},
// A special configuration that will be used when other syntaxes embed the `source.js` scope.
// This exists to prevent infinite embedding loops in certain situations.
"embed_configuration": {
"name": "JS Custom (Embedded)",
"scope": "source.js",
"hidden": true,
"file_extensions": [],
"custom_template_tags": false,
"custom_templates": false,
},
// Whenever you change one or more configurations, automatically rebuild those configurations.
"auto_build": true,
// Whenever you run the close_tag command in these scopes, run jsx_close_tag instead.
// Set to `false` to disable.
"jsx_close_tag": "source.js, source.jsx, source.ts, source.tsx",
// When you remove a configuration, reassign all views from that syntax to this one.
// Set to `false` to disable.
"reassign_when_deleting": "scope:source.js",
}
At first glance it looks like it's parsing the arrow function type parameters as a JSX element. I think this actually might not be supported yet. I probably need to add this to core.
See https://github.com/sublimehq/Packages/pull/2923. I've verified that fix with your code.
Once that's merged, it will take a bit more work to integrate it, but it hopefully shouldn't be too long.
Fixed in v4.2.0.
I don't really know what's the issue here and how to make the minimum reproducible example, but removing the generics argument here fixes the styling:
Version: 4.1.0 Sublime Text 4, Build 4113