mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
refactor: Migrate ColorCircles to composition api (no-changelog) (#9747)
This commit is contained in:
parent
db1cc24414
commit
e293683234
44
packages/design-system/src/styleguide/ColorCircles.utils.ts
Normal file
44
packages/design-system/src/styleguide/ColorCircles.utils.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Convert an HSL color to a Hex color
|
||||
*/
|
||||
export function hslToHex(h: number, s: number, l: number): string {
|
||||
l /= 100;
|
||||
const a = (s * Math.min(l, 1 - l)) / 100;
|
||||
const f = (n: number) => {
|
||||
const k = (n + h / 30) % 12;
|
||||
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
return Math.round(255 * color)
|
||||
.toString(16)
|
||||
.padStart(2, '0');
|
||||
};
|
||||
return `#${f(0)}${f(8)}${f(4)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve calc() expressions in HSL strings
|
||||
*/
|
||||
export function resolveHSLCalc(hslString: string): string {
|
||||
const calcRegex = /calc\(([^)]+)\)/;
|
||||
const matchCalc = hslString.match(calcRegex);
|
||||
if (!matchCalc) {
|
||||
return hslString;
|
||||
}
|
||||
const expression = matchCalc[1].replace(/%/g, '');
|
||||
const evaluation: number = eval(expression);
|
||||
const finalPercentage = `${evaluation}%`;
|
||||
return hslString.replace(calcRegex, finalPercentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Hex color from an HSL color string
|
||||
*/
|
||||
export function getHex(hsl: string): string {
|
||||
hsl = resolveHSLCalc(hsl);
|
||||
const colors = hsl
|
||||
.replace('hsl(', '')
|
||||
.replace(')', '')
|
||||
.replace(/%/g, '')
|
||||
.split(',')
|
||||
.map(parseFloat);
|
||||
return hslToHex(colors[0], colors[1], colors[2]);
|
||||
}
|
|
@ -1,3 +1,51 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import { getHex, resolveHSLCalc } from './ColorCircles.utils';
|
||||
|
||||
const props = defineProps({
|
||||
colors: {
|
||||
type: Array as PropType<string[]>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const hsl = reactive<{ [color: string]: string }>({});
|
||||
const observer = ref<MutationObserver | null>(null);
|
||||
|
||||
const setColors = () => {
|
||||
for (const color of props.colors) {
|
||||
const style = getComputedStyle(document.body);
|
||||
hsl[color] = style.getPropertyValue(color);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
setColors();
|
||||
|
||||
observer.value = new MutationObserver((mutationsList) => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'attributes') {
|
||||
setColors();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const body = document.querySelector('body');
|
||||
if (body) {
|
||||
observer.value.observe(body, { attributes: true });
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
observer.value?.disconnect();
|
||||
});
|
||||
|
||||
// Expose functions for template usage
|
||||
const getHexValue = (color: string) => getHex(hsl[color]);
|
||||
const getHSLValue = (color: string) => resolveHSLCalc(hsl[color]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="$style.section">
|
||||
<div v-for="color in colors" :key="color" :class="$style.container">
|
||||
|
@ -9,106 +57,6 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
function hslToHex(h: number, s: number, l: number): string {
|
||||
l /= 100;
|
||||
const a = (s * Math.min(l, 1 - l)) / 100;
|
||||
const f = (n: number) => {
|
||||
const k = (n + h / 30) % 12;
|
||||
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
return Math.round(255 * color)
|
||||
.toString(16)
|
||||
.padStart(2, '0'); // convert to Hex and prefix "0" if needed
|
||||
};
|
||||
return `#${f(0)}${f(8)}${f(4)}`;
|
||||
}
|
||||
|
||||
function resolveHSLCalc(hslString: string): string {
|
||||
const calcRegex = /calc\(([^)]+)\)/;
|
||||
const matchCalc = hslString.match(calcRegex);
|
||||
if (!matchCalc) {
|
||||
return hslString;
|
||||
}
|
||||
const expression = matchCalc[1];
|
||||
const noPercentageExpression = expression.replace(/%/g, '');
|
||||
const evaluation: number = eval(noPercentageExpression);
|
||||
const finalPercentage = evaluation.toString() + '%';
|
||||
const resolvedHslString = hslString.replace(calcRegex, finalPercentage);
|
||||
return resolvedHslString;
|
||||
}
|
||||
|
||||
function getHex(hsl: string): string {
|
||||
hsl = resolveHSLCalc(hsl);
|
||||
const colors = hsl
|
||||
.replace('hsl(', '')
|
||||
.replace(')', '')
|
||||
.replace(/%/g, '')
|
||||
.split(',')
|
||||
.map((n: string) => parseFloat(n));
|
||||
|
||||
return hslToHex(colors[0], colors[1], colors[2]);
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ColorCircles',
|
||||
props: {
|
||||
colors: {
|
||||
type: Array as PropType<string[]>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
hsl: {} as { [color: string]: string },
|
||||
};
|
||||
},
|
||||
created() {
|
||||
const setColors = () => {
|
||||
this.colors.forEach((color) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
|
||||
this.hsl = {
|
||||
...this.hsl,
|
||||
[color]: style.getPropertyValue(color),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
setColors();
|
||||
|
||||
// when theme class is added or removed, reset color values
|
||||
this.observer = new MutationObserver((mutationsList) => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'attributes') {
|
||||
setColors();
|
||||
}
|
||||
}
|
||||
});
|
||||
const body = document.querySelector('body');
|
||||
if (body) {
|
||||
this.observer.observe(body, { attributes: true });
|
||||
}
|
||||
},
|
||||
unmounted() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getHexValue(color: string) {
|
||||
return getHex(this.hsl[color]);
|
||||
},
|
||||
getHSLValue(color: string) {
|
||||
return resolveHSLCalc(this.hsl[color]);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.section {
|
||||
display: flex;
|
||||
|
|
Loading…
Reference in a new issue