@icones/vue 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +82 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @icones/vue
|
|
2
|
+
|
|
3
|
+
Vue 3.5+ 图标组件,支持原生 SVG 属性/事件、响应式配置、异步数据、SSR 和 Vite 静态提取。
|
|
4
|
+
|
|
5
|
+
```vue
|
|
6
|
+
<script setup lang="ts">
|
|
7
|
+
import { ref } from "vue"
|
|
8
|
+
import { Icon, IconConfig } from "@icones/vue"
|
|
9
|
+
const selected = ref(false)
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<IconConfig default-size="lg">
|
|
14
|
+
<Icon
|
|
15
|
+
name="tabler:star"
|
|
16
|
+
alt-name="tabler:heart"
|
|
17
|
+
:show-alt="selected"
|
|
18
|
+
aria-label="收藏"
|
|
19
|
+
@click="selected = !selected"
|
|
20
|
+
>
|
|
21
|
+
<template #fallback>加载中</template>
|
|
22
|
+
</Icon>
|
|
23
|
+
</IconConfig>
|
|
24
|
+
</template>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
未配置 `api` 时,明确的 `set:name` 会从 `https://<set>.icones.go-slim.dev/data/<name>.json` 加载。Vite 静态收集和本地 `sources` 优先;使用 `:api="false"` 可关闭网络回退,也可通过 `api` 覆盖为自建数据或 symbol 服务。
|
|
28
|
+
|
|
29
|
+
`IconConfig`(别名 `IconProvider`)可嵌套,支持 `sources`、`api`、`store`、尺寸与线宽配置。只覆盖外观的子配置共享父缓存。`Icon` 也可传入 `scope={createIconScope(...)}`;`useIconScope()` 返回当前配置的只读 ref。备用内容可用 `fallback` 字符串或具名 slot,未提供时显示空 SVG 和 `data-state`。
|
|
30
|
+
|
|
31
|
+
SSR 不会在渲染期间自动请求网络。使用内联数据、symbol 引用、Vite 静态收集,或每请求创建 store 并预加载;客户端使用相同数据进行 hydration。
|
|
32
|
+
|
|
33
|
+
开发:`bun run --cwd packages/vue play`。测试:`bun run --cwd packages/vue test`(需 Chrome)。完整 API 见[项目文档](../../README.md)。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SVGAttributes, ShallowRef } from "vue";
|
|
2
|
+
import { IconOptions, IconScope, IconScopeOptions } from "@icones/core";
|
|
3
|
+
export * from "@icones/core";
|
|
4
|
+
//#region src/icon.d.ts
|
|
5
|
+
type IconProps = IconOptions & Omit<SVGAttributes, keyof IconOptions | "innerHTML"> & {
|
|
6
|
+
scope?: IconScope;
|
|
7
|
+
fallback?: string;
|
|
8
|
+
};
|
|
9
|
+
declare const Icon: import("vue").DefineSetupFnComponent<IconProps, {}, {}, IconProps & {}, import("vue").PublicProps>;
|
|
10
|
+
declare const IconConfig: import("vue").DefineSetupFnComponent<IconScopeOptions, {}, {}, import("@icones/core").IconAppearance & Pick<import("@icones/core").IconStoreOptions, "sources" | "api"> & {
|
|
11
|
+
store?: import("@icones/core").IconStore;
|
|
12
|
+
} & {}, import("vue").PublicProps>;
|
|
13
|
+
declare function useIconScope(): Readonly<ShallowRef<IconScope>>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { Icon, IconConfig, IconConfig as IconProvider, type IconProps, useIconScope };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, shallowRef, useId, watchEffect } from "vue";
|
|
2
|
+
import { createIconController, createIconScopeResolver, defaultIconScope, iconOptionKeys, renderIcon } from "@icones/core";
|
|
3
|
+
export * from "@icones/core";
|
|
4
|
+
//#region src/icon.ts
|
|
5
|
+
const scopeKey = Symbol("icones.scope");
|
|
6
|
+
const booleanProp = {
|
|
7
|
+
type: Boolean,
|
|
8
|
+
default: void 0
|
|
9
|
+
};
|
|
10
|
+
const iconProps = {
|
|
11
|
+
...Object.fromEntries(iconOptionKeys.filter((key) => !key.startsWith("aria-")).map((key) => [key, null])),
|
|
12
|
+
hFlip: booleanProp,
|
|
13
|
+
vFlip: booleanProp,
|
|
14
|
+
showAlt: booleanProp,
|
|
15
|
+
absoluteStrokeWidth: booleanProp,
|
|
16
|
+
scope: null,
|
|
17
|
+
fallback: String
|
|
18
|
+
};
|
|
19
|
+
const Icon = defineComponent((props, { attrs, slots }) => {
|
|
20
|
+
const parent = inject(scopeKey, shallowRef(defaultIconScope()));
|
|
21
|
+
const controller = createIconController(props, props.scope ?? parent.value);
|
|
22
|
+
const state = shallowRef(controller.getState());
|
|
23
|
+
const id = useId();
|
|
24
|
+
let unsubscribe;
|
|
25
|
+
watchEffect(() => {
|
|
26
|
+
controller.update({ ...props }, props.scope ?? parent.value);
|
|
27
|
+
state.value = controller.getState();
|
|
28
|
+
});
|
|
29
|
+
onMounted(() => {
|
|
30
|
+
unsubscribe = controller.subscribe(() => {
|
|
31
|
+
state.value = controller.getState();
|
|
32
|
+
});
|
|
33
|
+
state.value = controller.getState();
|
|
34
|
+
});
|
|
35
|
+
onBeforeUnmount(() => {
|
|
36
|
+
unsubscribe?.();
|
|
37
|
+
controller.destroy();
|
|
38
|
+
});
|
|
39
|
+
return () => {
|
|
40
|
+
const result = renderIcon(state.value, {
|
|
41
|
+
...props,
|
|
42
|
+
...attrs
|
|
43
|
+
}, (props.scope ?? parent.value).appearance, id);
|
|
44
|
+
if (!result.available && (slots.fallback || props.fallback !== void 0)) return slots.fallback?.() ?? props.fallback;
|
|
45
|
+
return h("svg", {
|
|
46
|
+
...attrs,
|
|
47
|
+
...result.attributes,
|
|
48
|
+
style: [result.style, attrs.style],
|
|
49
|
+
innerHTML: result.body
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
}, {
|
|
53
|
+
name: "Icon",
|
|
54
|
+
inheritAttrs: false,
|
|
55
|
+
props: iconProps
|
|
56
|
+
});
|
|
57
|
+
const IconConfig = defineComponent((props, { slots }) => {
|
|
58
|
+
const parent = inject(scopeKey, shallowRef(defaultIconScope()));
|
|
59
|
+
const resolveScope = createIconScopeResolver();
|
|
60
|
+
const scope = computed(() => resolveScope({ ...props }, parent.value));
|
|
61
|
+
provide(scopeKey, scope);
|
|
62
|
+
return () => slots.default?.();
|
|
63
|
+
}, {
|
|
64
|
+
name: "IconConfig",
|
|
65
|
+
props: {
|
|
66
|
+
sizeValues: null,
|
|
67
|
+
defaultSize: null,
|
|
68
|
+
strokeWidth: null,
|
|
69
|
+
absoluteStrokeWidth: {
|
|
70
|
+
type: [Boolean, Object],
|
|
71
|
+
default: void 0
|
|
72
|
+
},
|
|
73
|
+
sources: null,
|
|
74
|
+
api: null,
|
|
75
|
+
store: null
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
function useIconScope() {
|
|
79
|
+
return inject(scopeKey, shallowRef(defaultIconScope()));
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { Icon, IconConfig, IconConfig as IconProvider, useIconScope };
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@icones/vue",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"homepage": "https://icones.go-slim.dev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/tint/icones.git",
|
|
10
|
+
"directory": "packages/vue"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/tint/icones/issues"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@icones/core": "^0.0.1"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"vue": "^3.5.0"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
}
|
|
31
|
+
}
|