omii-ui
Version:
使用OMII开发的WebComponents库,样式采用bootstrap。可以作为标准的esmodule使用
148 lines (139 loc) • 3.49 kB
JSX
const { define, h, Component } = omii;
import uiBase from "../uiBase";
import { MODES, TYPES } from "./constants";
let MODE = MODES.SINGLE;
let TYPE = TYPES.FILLED;
const iconsCache = new Map();
const loadIcon = async (name, type, mode) => {
type = type ?? TYPE;
if (type == TYPES.FILE_TYPE) {
mode = MODES.BUNDLE;
}
try {
if ((mode ?? MODE) == MODES.BUNDLE) {
let { default: icons } = await import(`./icons/${type}.js`);
return icons[name];
} else {
// const { default: icon } = await import(`./icons/${type}/${name}.js`)
// return icon;
const key = `${type}:${name}`;
let cachedIcon = iconsCache.get(key);
if (cachedIcon == undefined) {
cachedIcon = {
icon: false,
resolves: [],
};
iconsCache.set(key, cachedIcon);
try {
const { default: icon } = await import(`./icons/${type}/${name}.js`);
cachedIcon.icon = icon;
} catch {
// console.info("icon load error", type, name)
cachedIcon.icon = null;
}
for (let resolve of cachedIcon.resolves) {
resolve(cachedIcon.icon);
}
cachedIcon.resolves = [];
return cachedIcon.icon;
}
if (cachedIcon.icon === false) {
return new Promise((resolve, reject) => {
cachedIcon.resolves.push(resolve);
});
}
return cachedIcon.icon;
}
} catch (exc) {
console.error("load icon error", name, type, exc);
return null;
}
};
const createSvg = async (name, type, mode, props = {}) => {
let icon = await loadIcon(name, type, mode);
return h(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24",
...props,
},
icon
);
};
export default class extends uiBase {
static updateOnAttributeChanged = true;
static propTypes = {
name: String,
type: String,
viewBox: Number,
size: Number,
color: String,
};
static defaultProps = {
name: null,
type: TYPES.FILLED,
viewBox: 24,
size: null,
color: null,
};
static createSvg = createSvg;
static loadIcon = loadIcon;
static css = `
:host{
vertical-align:var(--oi-icon-valign,middle) ;
}
svg{
vertical-align:var(--oi-icon-valign,middle) ;
}
`;
static useBundleMode() {
MODE = MODES.BUNDLE;
}
static useSingleMode() {
MODE = MODES.SINGLE;
}
static get MODES() {
return MODES;
}
static get TYPES() {
return TYPES;
}
static get Mode() {
return MODE;
}
static set Mode(val) {
MODE = val;
}
static get Type() {
return TYPE;
}
static set Type(val) {
TYPE = val;
}
css() {
let { size, color } = this.$props;
let fill = color ? color : "var(--oi-icon-color)";
let width = size ? `${size}rem` : "var(--oi-icon-width, 1rem)";
let height = size ? `${size}rem` : "var(--oi-icon-height, 1rem);";
return `
:host svg{
fill: ${fill} ;
width: ${width};
height: ${height};
}
`;
}
async render() {
let { name, type, viewBox } = this.$props;
let $icon = await loadIcon(name, type);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox={`0 0 ${viewBox} ${viewBox}`}
>
{$icon}
</svg>
);
}
}