Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 65 additions & 13 deletions src/plugin/composables/__tests__/styles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,71 @@ describe('Styles Composable', () => {
).toMatchSnapshot();
});

// TODO (fix): The border radius is not set correctly if using multiple units with tabs //
it('should return the set radius', () => {
expect(
usePreTagStyles({ copyTab, height, maxHeight, radius: '0 1em', runTab, tabs: true, useTheme: defaultTheme })
).toMatchInlineSnapshot(`
{
"borderRadius": "0 1em 0 0 1em 0 1em !important",
"display": "flex",
"height": "auto",
"maxHeight": "auto",
"overflow": "auto",
}
`);
describe('border radius', () => {
const getRadius = (value: string | undefined, withTabs: boolean) => usePreTagStyles({
copyTab: true,
height,
maxHeight,
radius: value,
runTab: false,
tabs: withTabs,
useTheme: defaultTheme,
}).borderRadius;

it.each([
['0.5rem', '0.5rem 0 0.5rem 0.5rem !important'],
['0 1em', '0 0 0 1em !important'],
['1px 2px 3px', '1px 0 3px 2px !important'],
['8px 4px 2px 1px', '8px 0 2px 1px !important'],
['10px 5px / 20px', '10px 0 10px 5px / 20px 0 20px 20px !important'],
['8', '8px 0 8px 8px !important'],
[' 0 1em ', '0 0 0 1em !important'],
])('should square only the top right corner with tabs (%s)', (value, expected) => {
expect(getRadius(value, true)).toBe(expected);
});

it.each([
['0.5rem', '0.5rem'],
['0 1em', '0 1em'],
['8px 4px 2px 1px', '8px 4px 2px 1px'],
['10px 5px / 20px', '10px 5px / 20px'],
['8', '8px'],
])('should keep the radius without tabs (%s)', (value, expected) => {
expect(getRadius(value, false)).toBe(expected);
});

it('should keep the radius when tabs are on but there is no copy or run tab', () => {
expect(usePreTagStyles({
copyTab: false,
height,
maxHeight,
radius: '0 1em',
runTab: false,
tabs: true,
useTheme: defaultTheme,
}).borderRadius).toBe('0 1em');
});

it('should square the top right corner with only a run tab', () => {
expect(usePreTagStyles({
copyTab: false,
height,
maxHeight,
radius: '0 1em',
runTab: true,
tabs: true,
useTheme: defaultTheme,
}).borderRadius).toBe('0 0 0 1em !important');
});

it('should not set a radius when the value is empty', () => {
expect(getRadius('', true)).toBeUndefined();
expect(getRadius(undefined, false)).toBeUndefined();
});

it('should leave a value with more than four corners unchanged', () => {
expect(getRadius('1px 2px 3px 4px 5px', true)).toBe('1px 2px 3px 4px 5px !important');
});
});

});
Expand Down
40 changes: 35 additions & 5 deletions src/plugin/composables/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,44 @@ export const useHeaderStyles: UseHeaderStyles = (options) => {
return styles as CSSProperties;
};

// TODO (fix): The border radius is not set correctly if using multiple units with tabs //
/**
* Formats a border-radius value, adding units to bare numbers.
* When squareTopRight is set (tabs sit on that corner), the value is expanded to its
* four corners (1-4 values, either side of an optional "/") and the top-right corner is set to 0.
*/
function formatBorderRadius(radius: string | undefined, squareTopRight: boolean): string | undefined {
const value = String(radius ?? '').trim();

if (!value) {
return undefined;
}

const sides = value.split('/').map((side) => side.trim().split(/\s+/)
.map((part) => useConvertToUnit({ str: part }) as string));

// Not a valid shorthand, leave it as it is //
if (sides.length > 2 || sides.some((corners) => corners.length > 4)) {
return value;
}

if (!squareTopRight) {
return sides.map((corners) => corners.join(' ')).join(' / ');
}

return sides.map((corners) => {
const [topLeft, topRight = topLeft, bottomRight = topLeft, bottomLeft = topRight] = corners;

return `${topLeft} 0 ${bottomRight} ${bottomLeft}`;
}).join(' / ');
}

export const usePreTagStyles: UsePreTagStyles = (options) => {
const { copyTab, height, maxHeight, radius, runTab, tabs, useTheme } = options;
const unrefRadius = unref(radius);
let borderRadius = `${unrefRadius} 0 ${unrefRadius} ${unrefRadius} !important`;
const hasTab = !!unref(tabs) && (!!unref(copyTab) || !!unref(runTab));
let borderRadius = formatBorderRadius(unref(radius), hasTab);

if (!unref(tabs) || (!unref(copyTab) && !unref(runTab))) {
borderRadius = unrefRadius as string;
if (hasTab && borderRadius) {
borderRadius = `${borderRadius} !important`;
}

const display = unref(useTheme) !== 'funky' ? 'flex' : 'block';
Expand Down
Loading