Skip to content

Commit

Permalink
- Update package.json
Browse files Browse the repository at this point in the history
- Check code
  • Loading branch information
meshareL committed Jul 23, 2024
1 parent b098c92 commit f008df7
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 263 deletions.
26 changes: 19 additions & 7 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,34 @@ export default [
quoteProps: 'as-needed',
braceStyle: '1tbs'
}),
{
files: [
'**/*.js',
'**/*.ts'
]
},
{
ignores: [
'node_modules/**',
'node_modules/**/',
'dist/**',
'test/template/**'
],
languageOptions: {
globals: { ...globals.browser, ...globals.nodeBuiltin }
}
]
},
{
languageOptions: {
globals: {
...globals.browser,
...globals.nodeBuiltin
}
},
rules: {
'@stylistic/jsx-indent': [ 'error', 2 ],
'@stylistic/arrow-parens': [ 'warn', 'as-needed' ],
'@stylistic/comma-style': [ 'warn', 'last', {
exceptions: { VariableDeclaration: true }
'@stylistic/indent': [ 'error', 4, {
VariableDeclarator: 'first',
FunctionDeclaration: { parameters: 'first' },
FunctionExpression: { parameters: 'first' },
CallExpression: { arguments: 'first' }
}],
'@stylistic/array-bracket-spacing': [ 'warn', 'always', {
singleValue: true,
Expand Down
16 changes: 8 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { VNode, VNodeArrayChildren, Plugin, FunctionalComponent, SVGAttributes } from 'vue';
import { VNode, Plugin, FunctionalComponent, SVGAttributes } from 'vue';
import type { KebabCasedProperties } from 'type-fest';

type Icon<W extends number = number, H extends number = number> = {
Expand All @@ -15,7 +15,7 @@ type Icon<W extends number = number, H extends number = number> = {
/** SVG 元素其他属性, 不包含 viewBox, width, height 属性 */
attributes?: Record<string, string>;
/** 子节点渲染函数 */
render: () => VNode | VNodeArrayChildren;
render: () => VNode | VNode[];
};

type Option = {
Expand Down Expand Up @@ -51,15 +51,15 @@ type Option = {

type A11yProp =
(
{ title: string; 'aria-label'?: never; }
| { title?: never; 'aria-label': string; }
| { title?: never; 'aria-label'?: never; }
{ title: string; 'aria-label'?: never }
| { title?: never; 'aria-label': string }
| { title?: never; 'aria-label'?: never }
)
&
(
{ desc: string; 'aria-description'?: never; }
| { desc?: never; 'aria-description': string; }
| { desc?: never; 'aria-description'?: never; }
{ desc: string; 'aria-description'?: never }
| { desc?: never; 'aria-description': string }
| { desc?: never; 'aria-description'?: never }
);

/**
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
"module": "dist/component/index.esm.min.js",
"types": "index.d.ts",
"exports": {
".": {
"import": "dist/component/index.esm.min.js",
"browser": "dist/component/index.umd.min.js",
"types": "index.d.ts"
}
"types": "./index.d.ts",
"import": "./dist/component/index.esm.min.js",
"browser": "./dist/component/index.umd.min.js"
},
"files": [
"bin",
Expand All @@ -44,7 +42,9 @@
"access": "public"
},
"scripts": {
"prebuild": "rimraf dist",
"clean": "rimraf dist",
"eslint": "eslint . --fix --debug",
"prebuild": "npm run clean && npm run eslint",
"build": "rollup -c",
"pretest": "npm run build",
"test": "vitest run",
Expand Down
12 changes: 6 additions & 6 deletions src/cli/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ function serializeChild(element: SVGElement, format: Format): string {
nodes.push(node);
});

const attrCode = serializeAttribute(element.attributes || {})
, nodeCode = nodes.length ? `[${nodes.join(', ')}]` : ''
, delimiter = attrCode && nodeCode ? ', ' : ''
, render = format === Format.UNIVERSAL_MODULE ? '_vue.h' : 'h';
const attrCode = serializeAttribute(element.attributes || {}),
nodeCode = nodes.length ? `[${nodes.join(', ')}]` : '',
delimiter = attrCode && nodeCode ? ', ' : '',
render = format === Format.UNIVERSAL_MODULE ? '_vue.h' : 'h';

return `${render}('${element.nodeName}', ${attrCode}${delimiter}${nodeCode})`;
}
Expand Down Expand Up @@ -86,10 +86,10 @@ function generateUniversalModule(elements: Map<string, SVGElement>): string {
}(this, function(_vue) {
'use strict';
${
Array.from(elements.entries())
Array.from(elements.entries())
.map(([ name, element ]) => serializeElement(name, element, Format.UNIVERSAL_MODULE))
.join('\n\n')
}
}
return {
default: ${defaultExport},
Expand Down
31 changes: 16 additions & 15 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { fileURLToPath } from 'node:url';
import { resolve, dirname } from 'node:path';
import { cwd } from 'node:process';
import chalk from 'chalk';
import { Command, createCommand } from 'commander';
import { createCommand } from 'commander';
import type { Command } from 'commander';
import type { SVGElement } from './parse';
import parse from './parse';
import generate, { Format } from './generate';
Expand All @@ -15,8 +16,8 @@ type OptionValue = {
name: string;
};

const pkg = JSON.parse(FS.readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../../package.json'), 'utf8'))
, formatOptionalValues = [ 'esm', 'umd', 'ts', 'type' ];
const pkg = JSON.parse(FS.readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../../package.json'), 'utf8')),
formatOptionalValues = [ 'esm', 'umd', 'ts', 'type' ];

async function commandAction(options: OptionValue, command: Command): Promise<void> {
const formats = options.format
Expand All @@ -37,18 +38,18 @@ async function commandAction(options: OptionValue, command: Command): Promise<vo
try {
for (const format of formats) {
switch (format) {
case 'umd':
codes.set(`${options.name}.umd.js`, await generate(elements, Format.UNIVERSAL_MODULE));
break;
case 'esm':
codes.set(`${options.name}.esm.js`, await generate(elements, Format.ECMA_SCRIPT_MODULE));
break;
case 'ts':
codes.set(`${options.name}.ts`, await generate(elements, Format.TYPESCRIPT));
break;
case 'type':
codes.set(`${options.name}.d.ts`, await generate(elements, Format.DECLARE));
break;
case 'umd':
codes.set(`${options.name}.umd.js`, await generate(elements, Format.UNIVERSAL_MODULE));
break;
case 'esm':
codes.set(`${options.name}.esm.js`, await generate(elements, Format.ECMA_SCRIPT_MODULE));
break;
case 'ts':
codes.set(`${options.name}.ts`, await generate(elements, Format.TYPESCRIPT));
break;
case 'type':
codes.set(`${options.name}.d.ts`, await generate(elements, Format.DECLARE));
break;
}
}
} catch (e) {
Expand Down
11 changes: 6 additions & 5 deletions src/cli/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { readFileSync, lstatSync, readdirSync } from 'node:fs';
import { parse as pathParse, join } from 'node:path';
import { optimize } from 'svgo';
import type { Config } from 'svgo';
import { Window, Element } from 'happy-dom';
import { Window } from 'happy-dom';
import type { Element } from 'happy-dom';

type SVGElement = {
nodeName: string;
Expand All @@ -25,8 +26,8 @@ const svgoConfig: Config = {
]
};

const window = new Window()
, document = window.document;
const window = new Window(),
document = window.document;

function loadFile(path: string): string[] {
const files: string[] = [];
Expand Down Expand Up @@ -75,8 +76,8 @@ function transform(element: Element): SVGElement {
}

function parse(path: string): Map<string, SVGElement> {
const paths = loadFile(path)
, elements = new Map<string, SVGElement>();
const paths = loadFile(path),
elements = new Map<string, SVGElement>();

for (const filePath of paths) {
document.body.innerHTML = optimize(readFileSync(filePath, 'utf8'), svgoConfig).data;
Expand Down
7 changes: 3 additions & 4 deletions src/component/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';
import type {Plugin} from 'vue';
import JIcon, {preset} from './j-icon';
import type {Icon, Option} from '../../index';
import type { Plugin } from 'vue';
import JIcon, { preset } from './j-icon';
import type { Icon, Option } from '../../index';

/**
* Vue plugin install function
Expand Down
68 changes: 32 additions & 36 deletions src/component/j-icon.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
'use strict';
import { h as createElement } from 'vue';
import type { PropType, ComponentPropsOptions, FunctionalComponent } from 'vue';
import IconNotFoundError from './not-found-error';
import type { Icon, _Prop } from '../../index';

interface Preset {
type Preset = {
classes: string[];
prefix: boolean | string;
icons: Record<string, Icon>;
}
};

const preset: Preset = {
classes: [],
prefix: false,
icons: {}
}
, jIconProp: ComponentPropsOptions<_Prop> = {
icon: {required: true, type: [String, Object] as PropType<string | Icon>},
width: {required: false, type: [Number, String] as PropType<number | string>},
height: {required: false, type: [Number, String] as PropType<number | string>},
tabindex: {required: false, type: [Number, String] as PropType<number | string>},
title: {required: false, type: String},
ariaLabel: {required: false, type: String},
desc: {required: false, type: String},
ariaDescription: {required: false, type: String}
}, jIconProp: ComponentPropsOptions<_Prop> = {
icon: { required: true, type: [ String, Object ] as PropType<string | Icon> },
width: { required: false, type: [ Number, String ] as PropType<number | string> },
height: { required: false, type: [ Number, String ] as PropType<number | string> },
tabindex: { required: false, type: [ Number, String ] as PropType<number | string> },
title: { required: false, type: String },
ariaLabel: { required: false, type: String },
desc: { required: false, type: String },
ariaDescription: { required: false, type: String }
};

function generateId(): string {
Expand All @@ -44,8 +42,8 @@ function findIcon(value: string | Icon): Icon {
}

function mergeClass(name: string): string[] {
const clazz = []
, {classes, prefix} = preset;
const clazz = [],
{ classes, prefix } = preset;

if (classes.length) {
clazz.push(...classes);
Expand All @@ -64,42 +62,41 @@ function mergeClass(name: string): string[] {
return clazz;
}

const component: FunctionalComponent<_Prop> = (props) => {
const component: FunctionalComponent<_Prop> = props => {
if (!props.icon) throw new Error('JIcon: You must pass in attributes for the icon parameter');

const detail = findIcon(props.icon)
, iconName = typeof props.icon === 'string' ? props.icon : detail.name
, viewBox = detail.viewBox;
const detail = findIcon(props.icon),
iconName = typeof props.icon === 'string' ? props.icon : detail.name,
viewBox = detail.viewBox;

if (!Array.isArray(viewBox) || viewBox.length != 4) {
throw new Error(`JIcon: The viewBox attribute must be an array and have four elements, icon: ${iconName}`);
}

const [width, height] = detail.size || [viewBox[2], viewBox[3]]
, data: Record<string, unknown> = {
...detail.attributes,
class: mergeClass(iconName),
width: props.width || width,
height: props.height || height,
viewBox: viewBox.join(' '),
role: 'img'
};
const [ width, height ] = detail.size || [ viewBox[2], viewBox[3] ],
data: Record<string, unknown> = {
...detail.attributes,
class: mergeClass(iconName),
width: props.width || width,
height: props.height || height,
viewBox: viewBox.join(' '),
role: 'img'
};

let children = detail.render();
if (!Array.isArray(children)) {
children = [children];
children = [ children ];
}

let elementId = undefined
, ariaHidden = true;
let elementId = undefined,
ariaHidden = true;
if (props.desc) {
ariaHidden = false;
elementId = generateId();

const id = elementId + '_desc'
children.unshift(createElement('desc', {id}, props.desc));
const id = elementId + '_desc';
children.unshift(createElement('desc', { id }, props.desc));
Reflect.set(data, 'aria-describedby', id);

} else if (props.ariaDescription) {
ariaHidden = false;
Reflect.set(data, 'aria-description', props.ariaDescription);
Expand All @@ -110,9 +107,8 @@ const component: FunctionalComponent<_Prop> = (props) => {
elementId ??= generateId();

const id = elementId + '_title';
children.unshift(createElement('title', {id}, props.title));
children.unshift(createElement('title', { id }, props.title));
Reflect.set(data, 'aria-labelledby', id);

} else if (props.ariaLabel) {
ariaHidden = false;
Reflect.set(data, 'aria-label', props.ariaLabel);
Expand Down
Loading

0 comments on commit f008df7

Please sign in to comment.