mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-14 13:58:21 +00:00
Add reset function
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ export default defineNitroConfig({
|
||||
preset: 'vercel-edge',
|
||||
srcDir: '.vitepress',
|
||||
routeRules: {
|
||||
'/api/**': { cors: false, swr: true },
|
||||
'/api/**': { cors: false },
|
||||
},
|
||||
esbuild: {
|
||||
options: {
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user