160 lines
3.4 KiB
TypeScript
160 lines
3.4 KiB
TypeScript
import { define } from '@because/forge'
|
|
import { theme } from '../themes'
|
|
import type { AppState } from '../../shared/types'
|
|
|
|
export const StatusDotLink = define('StatusDotLink', {
|
|
base: 'a',
|
|
position: 'relative',
|
|
cursor: 'pointer',
|
|
textDecoration: 'none',
|
|
selectors: {
|
|
'&::after': {
|
|
content: 'attr(data-tooltip)',
|
|
position: 'absolute',
|
|
bottom: '100%',
|
|
left: '50%',
|
|
transform: 'translateX(-50%)',
|
|
marginBottom: 6,
|
|
padding: '2px 6px',
|
|
fontSize: 10,
|
|
fontFamily: theme('fonts-mono'),
|
|
color: theme('colors-text'),
|
|
background: theme('colors-bgElement'),
|
|
border: `1px solid ${theme('colors-border')}`,
|
|
borderRadius: 4,
|
|
whiteSpace: 'pre',
|
|
opacity: 0,
|
|
pointerEvents: 'none',
|
|
transition: 'opacity 0.15s',
|
|
},
|
|
'&:hover::after': {
|
|
opacity: 1,
|
|
},
|
|
},
|
|
})
|
|
|
|
export const StatusDotsRow = define('StatusDotsRow', {
|
|
display: 'flex',
|
|
gap: 8,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
})
|
|
|
|
export const StatusDot = define('StatusDot', {
|
|
width: 8,
|
|
height: 8,
|
|
borderRadius: '50%',
|
|
flexShrink: 0,
|
|
variants: {
|
|
state: {
|
|
invalid: { background: theme('colors-statusInvalid') },
|
|
stopped: { background: theme('colors-statusStopped') },
|
|
starting: { background: theme('colors-statusStarting') },
|
|
running: { background: theme('colors-statusRunning') },
|
|
stopping: { background: theme('colors-statusStarting') },
|
|
},
|
|
inline: {
|
|
display: 'inline'
|
|
}
|
|
},
|
|
})
|
|
|
|
export const Section = define('Section', {
|
|
marginBottom: 32,
|
|
})
|
|
|
|
export const SectionTitle = define('SectionTitle', {
|
|
fontSize: 12,
|
|
fontWeight: 600,
|
|
color: theme('colors-textFaint'),
|
|
textTransform: 'uppercase',
|
|
letterSpacing: '0.05em',
|
|
marginBottom: 12,
|
|
paddingBottom: 8,
|
|
borderBottom: `1px solid ${theme('colors-border')}`,
|
|
})
|
|
|
|
export const InfoRow = define('InfoRow', {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: 12,
|
|
marginBottom: 12,
|
|
fontSize: 14,
|
|
})
|
|
|
|
export const InfoLabel = define('InfoLabel', {
|
|
color: theme('colors-textFaint'),
|
|
width: 80,
|
|
flexShrink: 0,
|
|
})
|
|
|
|
export const InfoValue = define('InfoValue', {
|
|
color: theme('colors-text'),
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: 8,
|
|
})
|
|
|
|
export const Link = define('Link', {
|
|
base: 'a',
|
|
color: theme('colors-link'),
|
|
textDecoration: 'none',
|
|
selectors: {
|
|
'&:hover': { textDecoration: 'underline' },
|
|
},
|
|
})
|
|
|
|
export const EmptyState = define('EmptyState', {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
height: '100%',
|
|
color: theme('colors-textFaint'),
|
|
fontSize: 14,
|
|
})
|
|
|
|
export const TabBar = define('TabBar', {
|
|
display: 'flex',
|
|
gap: 24,
|
|
marginBottom: 20,
|
|
})
|
|
|
|
export const Tab = define('Tab', {
|
|
base: 'button',
|
|
padding: '6px 0',
|
|
background: 'none',
|
|
border: 'none',
|
|
borderBottom: '2px solid transparent',
|
|
cursor: 'pointer',
|
|
fontSize: 14,
|
|
color: theme('colors-textMuted'),
|
|
selectors: {
|
|
'&:hover': { color: theme('colors-text') },
|
|
},
|
|
variants: {
|
|
active: {
|
|
color: theme('colors-text'),
|
|
borderBottomColor: theme('colors-primary'),
|
|
fontWeight: 500,
|
|
},
|
|
},
|
|
})
|
|
|
|
export const TabContent = define('TabContent', {
|
|
display: 'none',
|
|
|
|
variants: {
|
|
active: {
|
|
display: 'block'
|
|
}
|
|
}
|
|
})
|
|
|
|
export const stateLabels: Record<AppState, string> = {
|
|
invalid: 'Invalid',
|
|
stopped: 'Stopped',
|
|
starting: 'Starting',
|
|
running: 'Running',
|
|
stopping: 'Stopping',
|
|
}
|