1
0
mirror of https://github.com/coreui/coreui-icons.git synced 2025-08-08 17:56:33 +02:00

refactor: add Vue component to monorepo

This commit is contained in:
Łukasz Holeczek
2021-10-19 00:03:52 +02:00
parent dc22c6d5e3
commit a599c291d3
13 changed files with 615 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
/dist/**
/docs/**
.eslintrc.js

View File

@@ -0,0 +1,30 @@
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
parserOptions: {
ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
extraFileExtensions: ['.vue'],
ecmaFeatures: {
jsx: true,
},
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended',
'@vue/prettier',
'@vue/prettier/@typescript-eslint',
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
},
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
env: {
jest: true,
},
},
],
}

View File

@@ -0,0 +1 @@
build/

View File

@@ -0,0 +1,7 @@
module.exports = {
semi: false,
trailingComma: "all",
singleQuote: true,
printWidth: 100,
tabWidth: 2
};

View File

@@ -0,0 +1,81 @@
<p align="center">
<a href="https://coreui.io/">
<img src="https://coreui.io/images/brand/coreui-icons.svg" alt="CoreUI Icons logo" height="50">
</a>
</p>
<p align="center">
Official Vue.js component for CoreUI Icons and CoreUI Icons PRO.
<br>
<a href="https://coreui.io/vue/docs/components/icon.html"><strong>Explore CoreUI Icons for Vue docs »</strong></a>
<br>
<br>
<a href="https://github.com/coreui/coreui-icons/issues/new?template=bug_report.md">Report bug</a>
·
<a href="https://github.com/coreui/coreui-icons/issues/new?template=feature_request.md">Request feature</a>
·
<a href="https://community.coreui.io/">Community</a>
·
<a href="https://blog.coreui.io/">Blog</a>
</p>
## Status
[![NPM](https://img.shields.io/npm/v/@coreui/icons-vue/latest?style=flat-square&color=brightgreen)][coreui]
[![Downloads](https://img.shields.io/npm/dm/@coreui/icons-vue.svg?style=flat-square)][coreui]
[![License](https://img.shields.io/npm/l/@coreui/vue?style=flat-square)][coreui]
[coreui]: https://coreui.io/icons
## Installation
```bash
npm install @coreui/icons
npm install @coreui/icons-vue@next
```
or
```bash
yarn add @coreui/icons
yarn add @coreui/icons-vue@next
```
## Use
### Single icon
```jsx
import { CIcon } from '@coreui/icons-vue';
import { cifAu } from '@coreui/icons';
...
<CIcon :icon="cilAu" size="xxl"/>
...
```
### All icons
```jsx
import { CIcon } from '@coreui/icons-vue';
import * as icon from '@coreui/icons';
...
<CIcon :icon="icon.cilList" size="xxl"/>
...
```
## API
| property | type | description |
| --- | --- | --- |
| customClassName | `string` \| `object` \| `string[]` | Use for replacing default CIcon component classes. Prop is overriding the 'size' prop. |
| icon | `string` \| `string[]` | Name of the icon placed in React object or SVG content. |
| height | `number` | The height attribute defines the vertical length of an icon. |
| size | `sm` \| `md` \|`lg` \| `xl` \| `xxl` \| `3xl` \| `4xl` \| `5xl` \| `6xl` \| `7xl` \| `8xl` \| `9xl` | Size of the icon. |
| use | `string` | If defined component will be rendered using `use` tag. |
| title | `string` | Title tag content. |
| width | `number` | The width attribute defines the horizontal length of an icon. |

View File

@@ -0,0 +1,97 @@
{
"name": "@coreui/icons-vue",
"description": "Official Vue component for CoreUI Icons",
"version": "2.0.0-rc.0",
"license": "MIT",
"homepage": "https://icons.coreui.io",
"author": {
"name": "CoreUI",
"url": "https://coreui.io",
"github": "https://github.com/coreui",
"twitter": "https://twitter.com/core_ui"
},
"contributors": [
{
"name": "CoreUI Team",
"url": "https://github.com/orgs/coreui/people"
}
],
"repository": {
"type": "git",
"url": "https://github.com/coreui/coreui-icons.git"
},
"bugs": {
"url": "https://github.com/coreui/coreui-icons/issues"
},
"main": "dist/index.js",
"module": "dist/index.es.js",
"jsnext:main": "dist/index.es.js",
"files": [
"src",
"dist"
],
"keywords": [
"coreui",
"coreui-icons",
"coreui-vue",
"icons",
"svg",
"svg-icons",
"layout",
"component",
"vue"
],
"scripts": {
"build": "rollup -c",
"lint": "eslint 'src/**/*.{js,ts,tsx}'",
"test": "jest",
"test:u": "jest -u",
"test:clear": "jest --clearCache",
"test:coverage": "jest --coverage"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-node-resolve": "^13.0.5",
"@rollup/plugin-typescript": "^8.2.5",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@vue/compiler-sfc": "^3.2.20",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^2.0.0-0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^7.19.1",
"jest": "^27.3.0",
"prettier": "^2.4.1",
"rollup": "^2.58.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-vue": "^6.0.0",
"ts-jest": "^27.0.7",
"typescript": "^4.4.3",
"vue": "^3.2.20"
},
"peerDependencies": {
"vue": "^3.2.20"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"jest": {
"preset": "ts-jest",
"testEnvironment": "jsdom",
"moduleFileExtensions": [
"tsx",
"js",
"ts",
"json",
"vue"
],
"transform": {
".*\\.(ts)$": "ts-jest"
}
}
}

View File

@@ -0,0 +1,46 @@
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
import external from 'rollup-plugin-peer-deps-external'
import resolve from '@rollup/plugin-node-resolve'
import vue from 'rollup-plugin-vue'
import pkg from './package.json'
const plugins = [
external(),
resolve({
dedupe: ['vue'],
extensions: ['.ts', '.json', '.vue'],
}),
typescript({
exclude: ['**/__tests__/**'],
tsconfig: './tsconfig.json',
}),
commonjs({
include: ['node_modules/**'],
}),
]
export default [
// ESM build to be used with webpack/rollup.
{
input: 'src/index.ts',
output: {
format: 'es',
file: pkg.module,
exports: 'named',
sourcemap: true,
},
plugins: [...plugins, vue()],
},
// SSR build.
{
input: 'src/index.ts',
output: {
format: 'cjs',
file: pkg.main,
exports: 'named',
sourcemap: true,
},
plugins: [...plugins, vue({ template: { optimizeSSR: true } })],
},
]

View File

@@ -0,0 +1,147 @@
import { computed, defineComponent, h, inject, PropType } from 'vue'
const CIcon = defineComponent({
name: 'CIcon',
props: {
/**
* Use `:icon="..."` instead of
*
* @deprecated since version 3.0
*/
content: {
type: [String, Array],
default: undefined,
required: false,
},
/**
* Use for replacing default CIcon component classes. Prop is overriding the 'size' prop.
*/
customClassName: {
type: [String, Array, Object],
default: undefined,
required: false,
},
/**
* Name of the icon placed in React object or SVG content.
*/
icon: {
type: [String, Array] as PropType<string | string[]>,
default: undefined,
required: false,
},
/**
* Use `icon="..."` instead of
*
* @deprecated since version 3.0
*/
name: {
type: String,
default: undefined,
required: false,
},
/**
* Size of the icon. Available sizes: 'sm', 'lg', 'xl', 'xxl', '3xl...9xl', 'custom', 'custom-size'.
*/
size: {
type: String,
default: undefined,
required: false,
validator: (value: string) => {
return [
'custom',
'custom-size',
'sm',
'lg',
'xl',
'2xl',
'3xl',
'4xl',
'5xl',
'6xl',
'7xl',
'8xl',
'9xl',
].includes(value)
},
},
/**
* Title tag content.
*/
title: {
type: String,
default: undefined,
required: false,
},
/**
* If defined component will be rendered using 'use' tag.
*/
use: {
type: String,
default: undefined,
required: false,
},
},
setup(props, { attrs }) {
const icons: any = inject('icons')
const _icon = props.icon || props.content || props.name
const toCamelCase = (str: string) => {
return str
.replace(/([-_][a-z0-9])/gi, ($1) => {
return $1.toUpperCase()
})
.replace(/-/gi, '')
}
const iconName = computed(() =>
_icon && typeof _icon === 'string' ? (_icon.includes('-') ? toCamelCase(_icon) : _icon) : '',
)
const titleCode = props.title ? `<title>${props.title}</title>` : 'undefined'
const code = computed(() =>
Array.isArray(_icon)
? _icon
: typeof _icon === 'string' && iconName.value && icons[iconName.value]
? icons[iconName.value]
: 'undefined',
)
const iconCode = Array.isArray(code.value) ? code.value[1] || code.value[0] : code.value
const scale = Array.isArray(code.value) && code.value.length > 1 ? code.value[0] : '64 64'
const viewBox = attrs.viewBox || `0 0 ${scale}`
const size = () => {
const addCustom = !props.size && (attrs.width || attrs.height)
return props.size === 'custom' || addCustom ? 'custom-size' : props.size
}
const classNames = (() => {
return [props.customClassName || ['icon', { [`icon-${size()}`]: size() }], attrs.class]
})()
return () =>
props.use
? h(
'svg',
{
...attrs,
xmlns: 'http://www.w3.org/2000/svg',
class: classNames,
role: 'img',
},
h('use', { href: props.use }),
)
: h('svg', {
...attrs,
xmlns: 'http://www.w3.org/2000/svg',
class: classNames,
viewBox: viewBox,
innerHTML: `${titleCode}${iconCode}`,
role: 'img',
})
},
})
export { CIcon }

View File

@@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'
import { CIcon } from './../'
describe('CIcon', () => {
it('renders svg with class="icon"', () => {
const container = mount(CIcon)
expect(container.find('svg').classes('icon')).toBe(true)
})
// it('renders svg with icon', () => {
// const { container } = mount(<CIcon icon={cifAu} />)
// expect(container.firstChild).toContain(cifAu[1])
// // expect(render()).toContain(cifAu)
// })
it('renders svg with size', () => {
const container = mount(CIcon, { props: { size: 'xl' }})
expect(container.find('svg').classes('icon-xl')).toBe(true)
})
it('renders svg with custom size', () => {
const container = mount(CIcon, { props: { height: 20 }})
expect(container.find('svg').classes('icon-custom-size')).toBe(true)
})
it('renders svg with className', () => {
const container = mount(CIcon, { props: { class: 'icon-test' }})
expect(container.find('svg').classes('icon-test')).toBe(true)
})
// it('renders <svg> with <use>', () => {
// const { container } = mount(<CIcon use="xxx" />)
// expect(container.firstChild?.firstChild).toContain('<use href="xxx" />')
// })
})

View File

@@ -0,0 +1,2 @@
import { CIcon } from './CIcon'
export { CIcon }

View File

@@ -0,0 +1,27 @@
{
"compilerOptions": {
"jsx": "preserve",
"outDir": "dist",
"module": "esnext",
"target": "esnext",
"strict": true,
"lib": ["es6", "dom", "es2016", "es2017"],
"sourceMap": true,
"allowJs": false,
"declaration": true,
"declarationDir": ".",
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,12 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "dist/types",
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true
},
"include": [
"src/interfaces/index.ts"
]
}

View File

@@ -0,0 +1,127 @@
Arguments:
/usr/local/bin/node /usr/local/bin/yarn test
PATH:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:/opt/homebrew/sbin
Yarn version:
1.22.10
Node version:
16.6.1
Platform:
darwin arm64
Trace:
SyntaxError: /Users/lukaszholeczek/CoreUI/@coreui/icons/packages/icons-vue/package.json: Unexpected token } in JSON at position 2287
at JSON.parse (<anonymous>)
at /usr/local/lib/node_modules/yarn/lib/cli.js:1625:59
at Generator.next (<anonymous>)
at step (/usr/local/lib/node_modules/yarn/lib/cli.js:310:30)
at /usr/local/lib/node_modules/yarn/lib/cli.js:321:13
npm manifest:
{
"name": "@coreui/icons-vue",
"description": "Official Vue component for CoreUI Icons",
"version": "2.0.0-rc.0",
"license": "MIT",
"homepage": "https://icons.coreui.io",
"author": {
"name": "CoreUI",
"url": "https://coreui.io",
"github": "https://github.com/coreui",
"twitter": "https://twitter.com/core_ui"
},
"contributors": [
{
"name": "CoreUI Team",
"url": "https://github.com/orgs/coreui/people"
}
],
"repository": {
"type": "git",
"url": "https://github.com/coreui/coreui-icons.git"
},
"bugs": {
"url": "https://github.com/coreui/coreui-icons/issues"
},
"main": "dist/index.js",
"module": "dist/index.es.js",
"jsnext:main": "dist/index.es.js",
"files": [
"src",
"dist"
],
"keywords": [
"coreui",
"coreui-icons",
"coreui-vue",
"icons",
"svg",
"svg-icons",
"layout",
"component",
"vue"
],
"scripts": {
"build": "rollup -c",
"lint": "eslint 'src/**/*.{js,ts,tsx}'",
"test": "jest",
"test:u": "jest -u",
"test:clear": "jest --clearCache",
"test:coverage": "jest --coverage"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-node-resolve": "^13.0.5",
"@rollup/plugin-typescript": "^8.2.5",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@vue/compiler-sfc": "^3.2.20",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^1.2.2",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^7.19.1",
"jest": "^27.3.0",
"prettier": "^2.4.1",
"rollup": "^2.58.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-vue": "^6.0.0",
"ts-jest": "^27.0.7",
"typescript": "^4.4.3",
"vue": "^3.2.20"
},
"peerDependencies": {
"vue": "^3.2.20"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"jest": {
"preset": "ts-jest",
"testEnvironment": "jsdom",
"moduleFileExtensions": [
"tsx",
"js",
"ts",
"json",
"vue"
],
"transform": {
".*\\.(ts)$": "ts-jest"
}
},
}
yarn manifest:
No manifest
Lockfile:
No lockfile