mirror of
https://github.com/lights0123/n-link.git
synced 2026-08-07 18:23:28 +00:00
feat(ui): add inline Icon component for themeable feather icons
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
92552f0d7f
commit
25fddd2afe
22
n-link-core/components/Icon.spec.ts
Normal file
22
n-link-core/components/Icon.spec.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { mount } from '@vue/test-utils';
|
||||||
|
import Icon from './Icon.vue';
|
||||||
|
|
||||||
|
describe('Icon', () => {
|
||||||
|
it('renders an inline svg that inherits currentColor', () => {
|
||||||
|
const wrapper = mount(Icon, { props: { name: 'refresh-cw' } });
|
||||||
|
expect(wrapper.html()).toContain('<svg');
|
||||||
|
expect(wrapper.html()).toContain('currentColor');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies the size to width and height', () => {
|
||||||
|
const wrapper = mount(Icon, { props: { name: 'chevron-right', size: 32 } });
|
||||||
|
expect(wrapper.html()).toContain('width="32"');
|
||||||
|
expect(wrapper.html()).toContain('height="32"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws for an unknown icon name', () => {
|
||||||
|
expect(() => mount(Icon, { props: { name: 'not-a-real-icon' } }))
|
||||||
|
.toThrow(/unknown feather icon/);
|
||||||
|
});
|
||||||
|
});
|
||||||
21
n-link-core/components/Icon.vue
Normal file
21
n-link-core/components/Icon.vue
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<template>
|
||||||
|
<span class="inline-flex items-center" v-html="svg"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import feather from 'feather-icons';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
name: string;
|
||||||
|
size?: number;
|
||||||
|
}>(), {
|
||||||
|
size: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
const svg = computed(() => {
|
||||||
|
const icon = feather.icons[props.name as keyof typeof feather.icons];
|
||||||
|
if (!icon) throw new Error(`unknown feather icon: ${props.name}`);
|
||||||
|
return icon.toSvg({ width: props.size, height: props.size });
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "n-link-core",
|
"name": "n-link-core",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"feather-icons": "^4.29.2"
|
||||||
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"element-plus": "^2.14.3",
|
"element-plus": "^2.14.3",
|
||||||
"vue": "^3.5.40"
|
"vue": "^3.5.40"
|
||||||
|
|
|
||||||
3
package-lock.json
generated
3
package-lock.json
generated
|
|
@ -41,6 +41,9 @@
|
||||||
},
|
},
|
||||||
"n-link-core": {
|
"n-link-core": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"feather-icons": "^4.29.2"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/forms": "^0.5.11",
|
"@tailwindcss/forms": "^0.5.11",
|
||||||
"tailwindcss": "^3.4.19"
|
"tailwindcss": "^3.4.19"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue