import styled, { css } from 'styled-components' type FragmentType = 'index' | 'property' export const QueryMatchContainer = styled.div` padding: 4px 8px; border: 1px solid #b9b9b9; border-radius: 8px; background: #f0f0f0; ` export const KeyPathFragment = styled.span<{ fragmentType: FragmentType }>` ${({ fragmentType }) => fragmentType === 'index' && css` &::before { content: '['; } &::after { content: ']'; } `} ${({ fragmentType }) => fragmentType === 'property' && css` &:not(:first-child)::before { content: '.'; } `} &::before, &::after { color: #959595; } &:last-child { color: #004b7c; } ` export const Breadcrumbs = styled.div` font-family: monospace; font-size: 10px; margin-bottom: 2px; &::before { content: '@'; color: #7e7e7e; } ` export const MatchPreview = styled.div` display: flex; font-size: 12px; align-items: center; ` export const HighlightedText = styled.mark` background: #1cd59d; color: inherit; border: 1px solid #08b580; border-radius: 4px; box-sizing: border-box; margin-top: -1px; ` export const Key = styled.div<{ type: FragmentType }>` display: inline; font-family: monospace; padding: 4px 0; color: #004b7c; ${({ type }) => type === 'index' && css` &::before { content: '['; } &::after { content: ']'; } `} ` export const ColonSeparator = styled.span` &::after { content: ':'; font-family: monospace; margin-right: 1ch; } ` /** * This component has been designed to display long text values gracefully. By splitting long * strings into 3 sections *(as spans)*, namely, "head", "body", and "tail", where "body" would * contain the text we wish to highlight, we can have the long string render like this when * the parent container width is limited: * * `"Be not angry... since they ...wish to be"` * * In the example above, "since they" forms the body, assuming we wanted to hightlight the * words "since they". */ export const TextLikeValue = styled.div<{ formatAs: string }>` display: flex; font-family: monospace; overflow: hidden; flex: 1; padding: 4px 0; /* all fragments not being highighted should be clippable */ span:not(${HighlightedText}) { white-space: pre; overflow: hidden; /* "head" must have ellipsis (if too long to fit in viewport) */ &:first-child { text-overflow: ellipsis; } /* "tail" must be in rtl so text clips to the left (if too long to fit in viewport) */ &:last-child { direction: rtl; } } /* show ellipsis on the tail only when it's succeeded by a highlighted fragment */ ${HighlightedText} + span { text-overflow: ellipsis; } ${({ formatAs }) => formatAs === 'number' && css` color: #015dd2; `} ${({ formatAs }) => formatAs === 'boolean' && css` color: #7c01b7; `} ${({ formatAs }) => formatAs === 'string' && css` color: #8b3f00; &::before, &::after { content: '"'; color: #c9986a; } `} ` export const NonTextValue = styled.span<{ rawValue: unknown }>` font-family: monospace; font-style: italic; &::after { color: #969696; margin-left: 1ch; } ${({ rawValue }) => Array.isArray(rawValue) ? css` &::before { content: '[]'; } &::after { content: 'Array'; } ` : css` &::before { content: '{}'; } &::after { content: 'Object'; } `} `