Add reset function

This commit is contained in:
Eric Fennis
2023-04-26 10:24:09 +02:00
parent 350d2c955f
commit 9a2fc75a9a
8 changed files with 116 additions and 58 deletions
+66 -16
View File
@@ -1,44 +1,60 @@
<script setup>
import { useCssVar, syncRef } from '@vueuse/core'
import { useIconSizeContext } from '../composables/useSharedSize'
import { useIconStyleContext } from '../composables/useIconStyle'
import RangeSlider from './RangeSlider.vue'
import IconButton from './IconButton.vue'
import { rotateCw } from '../../iconNodes'
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
const { color, strokeWidth, size } = useIconStyleContext()
const { size } = useIconSizeContext()
const color = useCssVar(
const colorCssVar = useCssVar(
'--customize-color',
document.documentElement,
typeof document !== 'undefined' ? document?.documentElement : undefined,
{
initialValue: 'default'
}
)
const strokeWidth = useCssVar(
const strokeWidthCssVar = useCssVar(
'--customize-strokeWidth',
document.documentElement,
typeof document !== 'undefined' ? document?.documentElement : undefined,
{
initialValue: '2'
}
)
const iconSize = useCssVar(
const sizeCssVar = useCssVar(
'--customize-size',
document.documentElement,
typeof document !== 'undefined' ? document?.documentElement : undefined,
{
initialValue: '24'
}
)
syncRef(size, iconSize)
syncRef(color, colorCssVar)
syncRef(strokeWidth, strokeWidthCssVar)
syncRef(size, sizeCssVar)
const RotateIcon = createLucideIcon('RotateIcon', rotateCw)
function resetStyle () {
color.value = 'currentColor'
strokeWidth.value = '2'
size.value = '24'
}
</script>
<template>
<div class="card">
<h2 class="card-title">
Customizer
</h2>
<div class="card-header">
<h2 class="card-title">
Customizer
</h2>
<IconButton class="reset-button" @click="resetStyle">
<RotateIcon size="20"/>
</IconButton>
</div>
<div class="input-field">
<div class="input-label">
<label for="icon-color" class="customize-label">
@@ -88,13 +104,13 @@ syncRef(size, iconSize)
Size
</label>
<div class="display-value">
<span class="customize-label">{{ iconSize }}px</span>
<span class="customize-label">{{ size }}px</span>
</div>
</div>
<RangeSlider
id="size"
name="size"
v-model="iconSize"
v-model="size"
:min="16"
:max="48"
/>
@@ -112,12 +128,19 @@ syncRef(size, iconSize)
display: block;
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.card-title {
font-weight: 700;
color: var(--vp-c-text-1);
line-height: 32px;
font-size: 16px;
margin-bottom: 12px;
/* margin-bottom: 12px; */
}
.card {
background: var(--vp-c-bg);
@@ -189,4 +212,31 @@ syncRef(size, iconSize)
margin-bottom: 8px;
gap: 12px;
}
.reset-button {
background: none;
padding: 0;
transition: ease-in-out 0.1s transform;
}
.reset-button:hover {
background: none;
border-color: transparent;
}
/* a rotate css animation keyframes */
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
.reset-button:active {
transform: rotate(45deg);
}
</style>
+1 -1
View File
@@ -44,7 +44,7 @@ function navigateToIcon() {
:aria-label="name"
>
<KeepAlive>
<component :is="icon" class="lucide-icon" :class="{ customizable }" size="auto"/>
<component :is="icon" class="lucide-icon" :class="{ customizable }" />
</KeepAlive>
</button>
</template>
+6 -4
View File
@@ -2,7 +2,7 @@
import type { IconEntity } from '../types'
import { computed } from 'vue'
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
import { useIconSizeContext } from '../composables/useSharedSize';
import { useIconStyleContext } from '../composables/useIconStyle';
const props = defineProps<{
name: IconEntity['name']
@@ -10,7 +10,7 @@ const props = defineProps<{
customizable?: boolean
}>()
const { size } = useIconSizeContext()
const { size, color, strokeWidth } = useIconStyleContext()
const gridLines = computed(() => Array.from({ length:(size.value - 1) }))
@@ -27,6 +27,8 @@ const iconComponent = computed(() => {
class="icon-component"
:class="{ customizable }"
:size="size"
:color="color"
:stroke-width="strokeWidth"
/>
<svg class="icon-grid" :viewBox="`0 0 ${size} ${size}`" fill="none" stroke-width="0.1" xmlns="http://www.w3.org/2000/svg">
<g :key="`grid-${i}`" v-for="(_, i) in gridLines">
@@ -64,7 +66,7 @@ const iconComponent = computed(() => {
.icon-component.customizable {
will-change: width, height, stroke-width, stroke;
color: var(--customize-color, currentColor);
stroke-width: var(--customize-strokeWidth, 2);
/* color: var(--customize-color, currentColor);
stroke-width: var(--customize-strokeWidth, 2); */
}
</style>
@@ -0,0 +1,35 @@
/* eslint-disable no-console */
import {
ref, provide, inject, Ref
} from 'vue';
export const ICON_STYLE_CONTEXT = Symbol('size');
interface IconSizeContext {
size: Ref<number>
strokeWidth: Ref<number>
color: Ref<string>
}
export const context = {
size: ref(24),
strokeWidth: ref(2),
color: ref('currentColor'),
};
export function useIconStyleProvider(): IconSizeContext {
provide(ICON_STYLE_CONTEXT, context);
return context;
}
export function useIconStyleContext(): IconSizeContext{
const context = inject<IconSizeContext>(ICON_STYLE_CONTEXT);
if (!context) {
throw new Error('useIconStyleContext must be used with useIconStyleProvider');
}
return context;
}
@@ -1,31 +0,0 @@
/* eslint-disable no-console */
import {
ref, provide, inject, Ref
} from 'vue';
export const SIZE_CONTEXT_NAME = Symbol('size');
interface IconSizeContext {
size: Ref<number>
}
export const context = {
size: ref(24),
};
export function useIconSizeProvider(): IconSizeContext {
provide(SIZE_CONTEXT_NAME, context);
return context;
}
export function useIconSizeContext(): IconSizeContext{
const context = inject<IconSizeContext>(SIZE_CONTEXT_NAME);
if (!context) {
throw new Error('useIconSizeContext must be used with useIconSizeProvider');
}
return context;
}
+2 -2
View File
@@ -4,7 +4,7 @@ import './style.css'
import { Theme } from 'vitepress'
import IconsSidebarNavAfter from './layouts/IconsSidebarNavAfter.vue'
import HomeHeroIconsCard from '../components/HomeHeroIconsCard.vue'
import { SIZE_CONTEXT_NAME, context } from '../composables/useSharedSize'
import { ICON_STYLE_CONTEXT, context } from '../composables/useIconStyle'
const theme: Partial<Theme> = {
extends: DefaultTheme,
@@ -15,7 +15,7 @@ const theme: Partial<Theme> = {
})
},
enhanceApp({ app }) {
app.provide(SIZE_CONTEXT_NAME,context)
app.provide(ICON_STYLE_CONTEXT, context)
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ export default defineNitroConfig({
preset: 'vercel-edge',
srcDir: '.vitepress',
routeRules: {
'/api/**': { cors: false, swr: true },
'/api/**': { cors: false },
},
esbuild: {
options: {
+5 -3
View File
@@ -10,14 +10,16 @@ const icons = renderIconsObject(svgFiles, ICONS_DIR, true);
const iconNodesDirectory = path.resolve(currentDir, 'iconNodes');
fs.unlinkSync(path.resolve(currentDir, 'iconNodes/index.ts'));
if (fs.existsSync(iconNodesDirectory)) {
fs.unlinkSync(path.resolve(currentDir, 'iconNodes'));
}
if (!fs.existsSync(iconNodesDirectory)) {
fs.mkdirSync(iconNodesDirectory);
}
const writeIconFiles = Object.entries(icons).map(async ([iconName, { children }]) => {
const location = path.resolve(iconNodesDirectory, `${iconName}.json`);
const location = path.resolve(iconNodesDirectory, `${iconName}.node.json`);
const iconNode = children.map(({ name, attributes }) => [name, attributes]);
const output = JSON.stringify(iconNode, null, 2);
@@ -26,7 +28,7 @@ const writeIconFiles = Object.entries(icons).map(async ([iconName, { children }]
const indexFile = path.resolve(iconNodesDirectory, `index.ts`);
await fs.promises.appendFile(
indexFile,
`export { default as ${toCamelCase(iconName)} } from './${iconName}.json';\n`,
`export { default as ${toCamelCase(iconName)} } from './${iconName}.node.json';\n`,
'utf-8',
);
});