fix: Fix ColorCircles and Sizes initial render (no-changelog) (#9780)

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
Tomi Turtiainen
2024-06-17 15:51:00 +03:00
committed by GitHub
parent 12604fe1da
commit a484862576
8 changed files with 145 additions and 20 deletions

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted, reactive } from 'vue';
import { ref, onMounted, onUnmounted } from 'vue';
import type { PropType } from 'vue';
import { getHex, resolveHSLCalc } from './ColorCircles.utils';
@@ -10,23 +10,28 @@ const props = defineProps({
},
});
const hsl = reactive<{ [color: string]: string }>({});
const observer = ref<MutationObserver | null>(null);
const getColors = () => {
const style = getComputedStyle(document.body);
const setColors = () => {
const hslColors: Record<string, string> = {};
for (const color of props.colors) {
const style = getComputedStyle(document.body);
hsl[color] = style.getPropertyValue(color);
const colorValue = style.getPropertyValue(color);
if (colorValue) {
hslColors[color] = colorValue;
}
}
return hslColors;
};
onMounted(() => {
setColors();
const hsl = ref<{ [color: string]: string }>(getColors());
const observer = ref<MutationObserver | null>(null);
onMounted(() => {
observer.value = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes') {
setColors();
hsl.value = getColors();
}
}
});
@@ -42,8 +47,8 @@ onUnmounted(() => {
});
// Expose functions for template usage
const getHexValue = (color: string) => getHex(hsl[color]);
const getHSLValue = (color: string) => resolveHSLCalc(hsl[color]);
const getHexValue = (color: string) => getHex(hsl.value[color]);
const getHSLValue = (color: string) => resolveHSLCalc(hsl.value[color]);
</script>
<template>

View File

@@ -1,6 +1,11 @@
<script setup lang="ts">
import type { PropType } from 'vue';
import { ref, onMounted, onUnmounted, reactive } from 'vue';
import { ref, onMounted, onUnmounted } from 'vue';
type Size = {
rem: string;
px: number;
};
// Define props with their types
const props = defineProps({
@@ -14,27 +19,29 @@ const props = defineProps({
},
});
const sizes = reactive<Record<string, { rem: string; px: number }>>({});
const observer = ref<MutationObserver | null>(null);
const getSizes = () => {
const style = getComputedStyle(document.body);
const setSizes = () => {
const sizeByVariableName: Record<string, Size> = {};
for (const variable of props.variables) {
const style = getComputedStyle(document.body);
const rem = style.getPropertyValue(variable);
const px = parseFloat(rem.replace('rem', '')) * 16; // Assuming default font-size is 16px
sizes[variable] = { rem, px };
sizeByVariableName[variable] = { rem, px };
}
return sizeByVariableName;
};
onMounted(() => {
setSizes();
const sizes = ref<Record<string, Size>>(getSizes());
const observer = ref<MutationObserver | null>(null);
onMounted(() => {
// Observing attributes changes in body to recompute sizes
const mutationObserverCallback = (mutationsList: MutationRecord[]) => {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes') {
setSizes();
sizes.value = getSizes();
}
}
};

View File

@@ -0,0 +1,32 @@
import { render } from '@testing-library/vue';
import { mock, mockClear } from 'vitest-mock-extended';
import ColorCircles from '../ColorCircles.vue';
describe('ColorCircles', () => {
const mockCssDeclaration = mock<CSSStyleDeclaration>();
window.getComputedStyle = () => mockCssDeclaration;
beforeEach(() => {
mockClear(mockCssDeclaration);
});
it('should render an empty section with empty colors', () => {
const wrapper = render(ColorCircles, {
props: {
colors: [],
},
});
expect(wrapper.html()).toMatchSnapshot();
});
it('should render a section with two colors', () => {
mockCssDeclaration.getPropertyValue.mockReturnValue('#663399');
const wrapper = render(ColorCircles, {
props: {
colors: ['--color-primary-shade-1', '--color-primary'],
},
});
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,23 @@
import { render } from '@testing-library/vue';
import { mock, mockClear } from 'vitest-mock-extended';
import Sizes from '../Sizes.vue';
describe('Sizes', () => {
const mockCssDeclaration = mock<CSSStyleDeclaration>();
window.getComputedStyle = () => mockCssDeclaration;
beforeEach(() => {
mockClear(mockCssDeclaration);
});
it('should render a section with a variable', () => {
mockCssDeclaration.getPropertyValue.mockReturnValue('400');
const wrapper = render(Sizes, {
props: {
variables: ['--font-weight-regular'],
},
});
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,14 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`ColorCircles > should render a section with two colors 1`] = `
"<div class="section">
<div class="container">
<div class="circle"></div><span>--color-primary-shade-1</span><span class="hsl">#663399</span><span class="color">#NaNNaNNaN</span>
</div>
<div class="container">
<div class="circle"></div><span>--color-primary</span><span class="hsl">#663399</span><span class="color">#NaNNaNNaN</span>
</div>
</div>"
`;
exports[`ColorCircles > should render an empty section with empty colors 1`] = `"<div class="section"></div>"`;

View File

@@ -0,0 +1,16 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Sizes > should render a section with a variable 1`] = `
"<table class="table">
<tr>
<th class="row">Name</th>
<th class="row">rem</th>
<th class="row">px</th>
</tr>
<tr>
<td>--font-weight-regular</td>
<td>400</td>
<td>6400</td>
</tr>
</table>"
`;