39 changed files with 367 additions and 456 deletions
@ -1,15 +1,14 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
import AppLogo from './src/AppLogo.vue'; |
import AppLogo from './src/AppLogo.vue'; |
||||
|
import AppProvider from './src/AppProvider.vue'; |
||||
|
import { withInstall } from '../util'; |
||||
|
|
||||
export const AppLocalePicker = createAsyncComponent(() => import('./src/AppLocalePicker.vue')); |
export const AppLocalePicker = createAsyncComponent(() => import('./src/AppLocalePicker.vue')); |
||||
export const AppProvider = createAsyncComponent(() => import('./src/AppProvider.vue')); |
|
||||
export const AppSearch = createAsyncComponent(() => import('./src/search/AppSearch.vue'), { |
export const AppSearch = createAsyncComponent(() => import('./src/search/AppSearch.vue'), { |
||||
loading: true, |
loading: true, |
||||
}); |
}); |
||||
// export const AppLogo = createAsyncComponent(() => import('./src/AppLogo.vue'));
|
|
||||
|
|
||||
withInstall(AppLocalePicker, AppLogo, AppProvider, AppSearch); |
|
||||
|
|
||||
export { useAppProviderContext } from './src/useAppContext'; |
export { useAppProviderContext } from './src/useAppContext'; |
||||
export { AppLogo }; |
export { AppLogo, AppProvider }; |
||||
|
|
||||
|
withInstall(AppLogo, AppProvider); |
||||
|
|||||
@ -1,6 +1,7 @@ |
|||||
import { withInstall } from '../util'; |
import { withInstall } from '../util'; |
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
|
||||
|
|
||||
export const Authority = createAsyncComponent(() => import('./src/index.vue')); |
import Authority from './src/index.vue'; |
||||
|
|
||||
withInstall(Authority); |
withInstall(Authority); |
||||
|
|
||||
|
export { Authority }; |
||||
|
|||||
@ -1,6 +1,7 @@ |
|||||
import { withInstall } from '../util'; |
import { withInstall } from '../util'; |
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
|
||||
|
|
||||
export const ClickOutSide = createAsyncComponent(() => import('./src/index.vue')); |
import ClickOutSide from './src/index.vue'; |
||||
|
|
||||
withInstall(ClickOutSide); |
withInstall(ClickOutSide); |
||||
|
|
||||
|
export { ClickOutSide }; |
||||
|
|||||
@ -1,14 +1,8 @@ |
|||||
import { withInstall } from '../util'; |
import { withInstall } from '../util'; |
||||
import CollapseContainer from './src/collapse/CollapseContainer.vue'; |
import CollapseContainer from './src/collapse/CollapseContainer.vue'; |
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import ScrollContainer from './src/ScrollContainer.vue'; |
||||
export const ScrollContainer = createAsyncComponent(() => import('./src/ScrollContainer.vue')); |
import LazyContainer from './src/LazyContainer.vue'; |
||||
|
|
||||
// export const CollapseContainer = createAsyncComponent(
|
|
||||
// () => import('./src/collapse/CollapseContainer.vue')
|
|
||||
// );
|
|
||||
export const LazyContainer = createAsyncComponent(() => import('./src/LazyContainer.vue')); |
|
||||
|
|
||||
withInstall(ScrollContainer, CollapseContainer, LazyContainer); |
withInstall(ScrollContainer, CollapseContainer, LazyContainer); |
||||
|
export { CollapseContainer, ScrollContainer, LazyContainer }; |
||||
export { CollapseContainer }; |
|
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|||||
@ -1,9 +1,5 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
export const Description = createAsyncComponent(() => import('./src/index')); |
export const Description = createAsyncComponent(() => import('./src/index')); |
||||
|
|
||||
withInstall(Description); |
|
||||
|
|
||||
export * from './src/types'; |
export * from './src/types'; |
||||
export { useDescription } from './src/useDescription'; |
export { useDescription } from './src/useDescription'; |
||||
|
|||||
@ -1,8 +1,9 @@ |
|||||
import { withInstall } from '../util'; |
import { withInstall } from '../util'; |
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import BasicDrawer from './src/BasicDrawer'; |
||||
export const BasicDrawer = createAsyncComponent(() => import('./src/BasicDrawer')); |
|
||||
|
|
||||
withInstall(BasicDrawer); |
export { BasicDrawer }; |
||||
export * from './src/types'; |
export * from './src/types'; |
||||
export { useDrawer, useDrawerInner } from './src/useDrawer'; |
export { useDrawer, useDrawerInner } from './src/useDrawer'; |
||||
|
|
||||
|
withInstall(BasicDrawer); |
||||
|
|||||
@ -1,57 +0,0 @@ |
|||||
import type { Trigger } from './types'; |
|
||||
|
|
||||
import { defineComponent, computed, unref } from 'vue'; |
|
||||
import { Dropdown, Menu } from 'ant-design-vue'; |
|
||||
import Icon from '/@/components/Icon/index'; |
|
||||
|
|
||||
import { basicDropdownProps } from './props'; |
|
||||
import { getSlot } from '/@/utils/helper/tsxHelper'; |
|
||||
|
|
||||
export default defineComponent({ |
|
||||
name: 'Dropdown', |
|
||||
props: basicDropdownProps, |
|
||||
emits: ['menuEvent'], |
|
||||
setup(props, { slots, emit, attrs }) { |
|
||||
const getMenuList = computed(() => props.dropMenuList); |
|
||||
|
|
||||
function handleClickMenu({ key }: any) { |
|
||||
const menu = unref(getMenuList).find((item) => `${item.event}` === `${key}`); |
|
||||
emit('menuEvent', menu); |
|
||||
} |
|
||||
|
|
||||
function renderMenus() { |
|
||||
return ( |
|
||||
<Menu onClick={handleClickMenu} selectedKeys={props.selectedKeys}> |
|
||||
{() => ( |
|
||||
<> |
|
||||
{unref(getMenuList).map((item) => { |
|
||||
const { disabled, icon, text, divider, event } = item; |
|
||||
return [ |
|
||||
<Menu.Item key={`${event}`} disabled={disabled}> |
|
||||
{() => ( |
|
||||
<> |
|
||||
{icon && <Icon icon={icon} />} |
|
||||
<span class="ml-1">{text}</span> |
|
||||
</> |
|
||||
)} |
|
||||
</Menu.Item>, |
|
||||
// @ts-ignore
|
|
||||
divider && <Menu.Divider key={`d-${event}`} />, |
|
||||
]; |
|
||||
})} |
|
||||
</> |
|
||||
)} |
|
||||
</Menu> |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
return () => ( |
|
||||
<Dropdown trigger={props.trigger as Trigger[]} {...attrs}> |
|
||||
{{ |
|
||||
default: () => <span>{getSlot(slots)}</span>, |
|
||||
overlay: () => renderMenus(), |
|
||||
}} |
|
||||
</Dropdown> |
|
||||
); |
|
||||
}, |
|
||||
}); |
|
||||
@ -0,0 +1,70 @@ |
|||||
|
<template> |
||||
|
<a-dropdown :trigger="trigger" v-bind="$attrs"> |
||||
|
<span> |
||||
|
<slot /> |
||||
|
</span> |
||||
|
<template #overlay> |
||||
|
<a-menu :selectedKeys="selectedKeys"> |
||||
|
<template v-for="item in getMenuList" :key="`${item.event}`"> |
||||
|
<a-menu-item @click="handleClickMenu({ key: item.event })" :disabled="item.disabled"> |
||||
|
<Icon :icon="item.icon" v-if="item.icon" /> |
||||
|
<span class="ml-1">{{ item.text }}</span> |
||||
|
</a-menu-item> |
||||
|
<a-menu-divider v-if="item.divider" :key="`d-${item.event}`" /> |
||||
|
</template> |
||||
|
</a-menu> |
||||
|
</template> |
||||
|
</a-dropdown> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import type { PropType } from 'vue'; |
||||
|
import type { DropMenu } from './types'; |
||||
|
|
||||
|
import { defineComponent, computed, unref } from 'vue'; |
||||
|
import { Dropdown, Menu } from 'ant-design-vue'; |
||||
|
import Icon from '/@/components/Icon/index'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'BasicDropdown', |
||||
|
components: { |
||||
|
[Dropdown.name]: Dropdown, |
||||
|
[Menu.name]: Menu, |
||||
|
[Menu.Item.name]: Menu.Item, |
||||
|
[Menu.Divider.name]: Menu.Divider, |
||||
|
Icon, |
||||
|
}, |
||||
|
props: { |
||||
|
/** |
||||
|
* the trigger mode which executes the drop-down action |
||||
|
* @default ['hover'] |
||||
|
* @type string[] |
||||
|
*/ |
||||
|
trigger: { |
||||
|
type: [Array] as PropType<string[]>, |
||||
|
default: () => { |
||||
|
return ['contextmenu']; |
||||
|
}, |
||||
|
}, |
||||
|
dropMenuList: { |
||||
|
type: Array as PropType<DropMenu[]>, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
selectedKeys: { |
||||
|
type: Array as PropType<string[]>, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
}, |
||||
|
emits: ['menuEvent'], |
||||
|
setup(props, { emit }) { |
||||
|
const getMenuList = computed(() => props.dropMenuList); |
||||
|
|
||||
|
function handleClickMenu({ key }: { key: string }) { |
||||
|
const menu = unref(getMenuList).find((item) => `${item.event}` === `${key}`); |
||||
|
emit('menuEvent', menu); |
||||
|
} |
||||
|
|
||||
|
return { handleClickMenu, getMenuList }; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
@ -1,26 +0,0 @@ |
|||||
import type { PropType } from 'vue'; |
|
||||
import type { DropMenu } from './types'; |
|
||||
|
|
||||
export const dropdownProps = { |
|
||||
/** |
|
||||
* the trigger mode which executes the drop-down action |
|
||||
* @default ['hover'] |
|
||||
* @type string[] |
|
||||
*/ |
|
||||
trigger: { |
|
||||
type: [Array] as PropType<string[]>, |
|
||||
default: () => { |
|
||||
return ['contextmenu']; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
export const basicDropdownProps = Object.assign({}, dropdownProps, { |
|
||||
dropMenuList: { |
|
||||
type: Array as PropType<DropMenu[]>, |
|
||||
default: () => [], |
|
||||
}, |
|
||||
selectedKeys: { |
|
||||
type: Array as PropType<string[]>, |
|
||||
default: () => [], |
|
||||
}, |
|
||||
}); |
|
||||
@ -1,12 +1,8 @@ |
|||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
|
|
||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
export const ImpExcel = createAsyncComponent(() => import('./src/ImportExcel.vue')); |
export const ImpExcel = createAsyncComponent(() => import('./src/ImportExcel.vue')); |
||||
export const ExpExcelModel = createAsyncComponent(() => import('./src/ExportExcelModel.vue')); |
export const ExpExcelModel = createAsyncComponent(() => import('./src/ExportExcelModel.vue')); |
||||
|
|
||||
withInstall(ImpExcel, ExpExcelModel); |
|
||||
|
|
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|
||||
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel'; |
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel'; |
||||
|
|||||
@ -1,14 +0,0 @@ |
|||||
@import (reference) '../../design/index.less'; |
|
||||
|
|
||||
.app-iconify { |
|
||||
display: inline-block; |
|
||||
vertical-align: middle; |
|
||||
} |
|
||||
|
|
||||
span.iconify { |
|
||||
display: block; |
|
||||
min-width: 1em; |
|
||||
min-height: 1em; |
|
||||
background: @iconify-bg-color; |
|
||||
border-radius: 100%; |
|
||||
} |
|
||||
@ -0,0 +1,7 @@ |
|||||
|
import { withInstall } from '../util'; |
||||
|
import Icon from './src/index.vue'; |
||||
|
|
||||
|
withInstall(Icon); |
||||
|
|
||||
|
export { Icon }; |
||||
|
export default Icon; |
||||
@ -1,83 +0,0 @@ |
|||||
import './index.less'; |
|
||||
|
|
||||
import type { PropType } from 'vue'; |
|
||||
import { |
|
||||
defineComponent, |
|
||||
ref, |
|
||||
watch, |
|
||||
onMounted, |
|
||||
nextTick, |
|
||||
unref, |
|
||||
computed, |
|
||||
CSSProperties, |
|
||||
} from 'vue'; |
|
||||
import Iconify from '@purge-icons/generated'; |
|
||||
import { isString } from '/@/utils/is'; |
|
||||
import { propTypes } from '/@/utils/propTypes'; |
|
||||
export default defineComponent({ |
|
||||
name: 'GIcon', |
|
||||
props: { |
|
||||
// icon name
|
|
||||
icon: propTypes.string, |
|
||||
// icon color
|
|
||||
color: propTypes.string, |
|
||||
// icon size
|
|
||||
size: { |
|
||||
type: [String, Number] as PropType<string | number>, |
|
||||
default: 16, |
|
||||
}, |
|
||||
prefix: propTypes.string.def(''), |
|
||||
}, |
|
||||
setup(props, { attrs }) { |
|
||||
const elRef = ref<ElRef>(null); |
|
||||
|
|
||||
const getIconRef = computed(() => { |
|
||||
const { icon, prefix } = props; |
|
||||
return `${prefix ? prefix + ':' : ''}${icon}`; |
|
||||
}); |
|
||||
|
|
||||
const update = async () => { |
|
||||
const el = unref(elRef); |
|
||||
if (el) { |
|
||||
await nextTick(); |
|
||||
const icon = unref(getIconRef); |
|
||||
|
|
||||
const svg = Iconify.renderSVG(icon, {}); |
|
||||
|
|
||||
if (svg) { |
|
||||
el.textContent = ''; |
|
||||
el.appendChild(svg); |
|
||||
} else { |
|
||||
const span = document.createElement('span'); |
|
||||
span.className = 'iconify'; |
|
||||
span.dataset.icon = icon; |
|
||||
el.textContent = ''; |
|
||||
el.appendChild(span); |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
const wrapStyleRef = computed( |
|
||||
(): CSSProperties => { |
|
||||
const { size, color } = props; |
|
||||
let fs = size; |
|
||||
if (isString(size)) { |
|
||||
fs = parseInt(size, 10); |
|
||||
} |
|
||||
return { |
|
||||
fontSize: `${fs}px`, |
|
||||
color, |
|
||||
display: 'inline-flex', |
|
||||
}; |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
watch(() => props.icon, update, { flush: 'post' }); |
|
||||
|
|
||||
onMounted(update); |
|
||||
|
|
||||
return () => ( |
|
||||
<span ref={elRef} class={[attrs.class, 'app-iconify anticon']} style={unref(wrapStyleRef)} /> |
|
||||
); |
|
||||
}, |
|
||||
}); |
|
||||
@ -0,0 +1,100 @@ |
|||||
|
<template> |
||||
|
<span ref="elRef" :class="[$attrs.class, 'app-iconify anticon']" :style="getWrapStyle" /> |
||||
|
</template> |
||||
|
<script lang="ts"> |
||||
|
import type { PropType } from 'vue'; |
||||
|
import { |
||||
|
defineComponent, |
||||
|
ref, |
||||
|
watch, |
||||
|
onMounted, |
||||
|
nextTick, |
||||
|
unref, |
||||
|
computed, |
||||
|
CSSProperties, |
||||
|
} from 'vue'; |
||||
|
import Iconify from '@purge-icons/generated'; |
||||
|
import { isString } from '/@/utils/is'; |
||||
|
import { propTypes } from '/@/utils/propTypes'; |
||||
|
export default defineComponent({ |
||||
|
name: 'GIcon', |
||||
|
props: { |
||||
|
// icon name |
||||
|
icon: propTypes.string, |
||||
|
// icon color |
||||
|
color: propTypes.string, |
||||
|
// icon size |
||||
|
size: { |
||||
|
type: [String, Number] as PropType<string | number>, |
||||
|
default: 16, |
||||
|
}, |
||||
|
prefix: propTypes.string.def(''), |
||||
|
}, |
||||
|
setup(props) { |
||||
|
const elRef = ref<ElRef>(null); |
||||
|
|
||||
|
const getIconRef = computed(() => { |
||||
|
const { icon, prefix } = props; |
||||
|
return `${prefix ? prefix + ':' : ''}${icon}`; |
||||
|
}); |
||||
|
|
||||
|
const update = async () => { |
||||
|
const el = unref(elRef); |
||||
|
if (el) { |
||||
|
await nextTick(); |
||||
|
const icon = unref(getIconRef); |
||||
|
|
||||
|
const svg = Iconify.renderSVG(icon, {}); |
||||
|
|
||||
|
if (svg) { |
||||
|
el.textContent = ''; |
||||
|
el.appendChild(svg); |
||||
|
} else { |
||||
|
const span = document.createElement('span'); |
||||
|
span.className = 'iconify'; |
||||
|
span.dataset.icon = icon; |
||||
|
el.textContent = ''; |
||||
|
el.appendChild(span); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getWrapStyle = computed( |
||||
|
(): CSSProperties => { |
||||
|
const { size, color } = props; |
||||
|
let fs = size; |
||||
|
if (isString(size)) { |
||||
|
fs = parseInt(size, 10); |
||||
|
} |
||||
|
return { |
||||
|
fontSize: `${fs}px`, |
||||
|
color, |
||||
|
display: 'inline-flex', |
||||
|
}; |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
watch(() => props.icon, update, { flush: 'post' }); |
||||
|
|
||||
|
onMounted(update); |
||||
|
|
||||
|
return { elRef, getWrapStyle }; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less"> |
||||
|
@import (reference) '../../../design/index.less'; |
||||
|
|
||||
|
.app-iconify { |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
span.iconify { |
||||
|
display: block; |
||||
|
min-width: 1em; |
||||
|
min-height: 1em; |
||||
|
background: @iconify-bg-color; |
||||
|
border-radius: 100%; |
||||
|
} |
||||
|
</style> |
||||
@ -1,9 +1,5 @@ |
|||||
import './src/indicator'; |
|
||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
export const Loading = createAsyncComponent(() => import('./src/index.vue')); |
export const Loading = createAsyncComponent(() => import('./src/index.vue')); |
||||
|
|
||||
withInstall(Loading); |
|
||||
export { useLoading } from './src/useLoading'; |
export { useLoading } from './src/useLoading'; |
||||
export { createLoading } from './src/createLoading'; |
export { createLoading } from './src/createLoading'; |
||||
|
|||||
@ -1,9 +0,0 @@ |
|||||
// If you need to modify the default icon, you can open the comment and modify it here
|
|
||||
|
|
||||
// import { Spin } from 'ant-design-vue';
|
|
||||
// import { LoadingOutlined } from '@ant-design/icons-vue';
|
|
||||
// Spin.setDefaultIndicator({
|
|
||||
// indicator: () => {
|
|
||||
// return <LoadingOutlined spin />;
|
|
||||
// },
|
|
||||
// });
|
|
||||
@ -1,8 +1,4 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
export const MarkDown = createAsyncComponent(() => import('./src/index.vue')); |
export const MarkDown = createAsyncComponent(() => import('./src/index.vue')); |
||||
|
|
||||
withInstall(MarkDown); |
|
||||
|
|
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|||||
@ -1,13 +1,5 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
|
|
||||
export const BasicMenu = createAsyncComponent(() => import('./src/BasicMenu.vue'), { |
export const BasicMenu = createAsyncComponent(() => import('./src/BasicMenu.vue')); |
||||
loading: false, |
|
||||
}); |
|
||||
|
|
||||
export const MenuTag = createAsyncComponent(() => import('./src/components/MenuItemTag.vue'), { |
|
||||
loading: false, |
|
||||
}); |
|
||||
|
|
||||
withInstall(BasicMenu); |
export const MenuTag = createAsyncComponent(() => import('./src/components/MenuItemTag.vue')); |
||||
|
|||||
@ -1,11 +1,10 @@ |
|||||
import './src/index.less'; |
import './src/index.less'; |
||||
import { withInstall } from '../util'; |
import { withInstall } from '../util'; |
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import BasicModal from './src/BasicModal'; |
||||
|
|
||||
export const BasicModal = createAsyncComponent(() => import('./src/BasicModal')); |
|
||||
|
|
||||
withInstall(BasicModal); |
withInstall(BasicModal); |
||||
|
|
||||
|
export { BasicModal }; |
||||
export { useModalContext } from './src/useModalContext'; |
export { useModalContext } from './src/useModalContext'; |
||||
export { useModal, useModalInner } from './src/useModal'; |
export { useModal, useModalInner } from './src/useModal'; |
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|||||
@ -1,7 +1,4 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
export const QrCode = createAsyncComponent(() => import('./src/index.vue')); |
export const QrCode = createAsyncComponent(() => import('./src/index.vue')); |
||||
|
|
||||
withInstall(QrCode); |
|
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|||||
@ -1,7 +1,3 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
|
|
||||
export const StrengthMeter = createAsyncComponent(() => import('./src/index')); |
export const StrengthMeter = createAsyncComponent(() => import('./src/index.vue')); |
||||
|
|
||||
withInstall(StrengthMeter); |
|
||||
@ -1,69 +0,0 @@ |
|||||
@import (reference) '../../../design/index.less'; |
|
||||
|
|
||||
.strength-meter { |
|
||||
position: relative; |
|
||||
|
|
||||
&-bar { |
|
||||
position: relative; |
|
||||
height: 4px; |
|
||||
margin: 10px auto 6px; |
|
||||
background: @disabled-color; |
|
||||
border-radius: 3px; |
|
||||
|
|
||||
&::before, |
|
||||
&::after { |
|
||||
position: absolute; |
|
||||
z-index: 10; |
|
||||
display: block; |
|
||||
width: 20%; |
|
||||
height: inherit; |
|
||||
background: transparent; |
|
||||
border-color: @white; |
|
||||
border-style: solid; |
|
||||
border-width: 0 5px 0 5px; |
|
||||
content: ''; |
|
||||
} |
|
||||
|
|
||||
&::before { |
|
||||
left: 20%; |
|
||||
} |
|
||||
|
|
||||
&::after { |
|
||||
right: 20%; |
|
||||
} |
|
||||
|
|
||||
&__fill { |
|
||||
position: absolute; |
|
||||
width: 0; |
|
||||
height: inherit; |
|
||||
background: transparent; |
|
||||
border-radius: inherit; |
|
||||
transition: width 0.5s ease-in-out, background 0.25s; |
|
||||
|
|
||||
&[data-score='0'] { |
|
||||
width: 20%; |
|
||||
background: darken(@error-color, 10%); |
|
||||
} |
|
||||
|
|
||||
&[data-score='1'] { |
|
||||
width: 40%; |
|
||||
background: @error-color; |
|
||||
} |
|
||||
|
|
||||
&[data-score='2'] { |
|
||||
width: 60%; |
|
||||
background: @warning-color; |
|
||||
} |
|
||||
|
|
||||
&[data-score='3'] { |
|
||||
width: 80%; |
|
||||
background: fade(@success-color, 50%); |
|
||||
} |
|
||||
|
|
||||
&[data-score='4'] { |
|
||||
width: 100%; |
|
||||
background: @success-color; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,77 +0,0 @@ |
|||||
import './index.less'; |
|
||||
|
|
||||
import { PropType } from 'vue'; |
|
||||
|
|
||||
import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue'; |
|
||||
|
|
||||
import { Input } from 'ant-design-vue'; |
|
||||
|
|
||||
import zxcvbn from 'zxcvbn'; |
|
||||
import { extendSlots } from '/@/utils/helper/tsxHelper'; |
|
||||
import { propTypes } from '/@/utils/propTypes'; |
|
||||
|
|
||||
const prefixCls = 'strength-meter'; |
|
||||
export default defineComponent({ |
|
||||
name: 'StrengthMeter', |
|
||||
props: { |
|
||||
value: propTypes.string, |
|
||||
|
|
||||
userInputs: { |
|
||||
type: Array as PropType<string[]>, |
|
||||
default: () => [], |
|
||||
}, |
|
||||
|
|
||||
showInput: propTypes.bool.def(true), |
|
||||
disabled: propTypes.bool, |
|
||||
}, |
|
||||
emits: ['score-change', 'change'], |
|
||||
setup(props, { emit, attrs, slots }) { |
|
||||
const innerValueRef = ref(''); |
|
||||
const getPasswordStrength = computed(() => { |
|
||||
const { userInputs, disabled } = props; |
|
||||
if (disabled) return null; |
|
||||
const innerValue = unref(innerValueRef); |
|
||||
const score = innerValue |
|
||||
? zxcvbn(unref(innerValueRef), (userInputs as string[]) || null).score |
|
||||
: null; |
|
||||
emit('score-change', score); |
|
||||
return score; |
|
||||
}); |
|
||||
|
|
||||
function handleChange(e: ChangeEvent) { |
|
||||
innerValueRef.value = e.target.value; |
|
||||
} |
|
||||
|
|
||||
watchEffect(() => { |
|
||||
innerValueRef.value = props.value || ''; |
|
||||
}); |
|
||||
watch( |
|
||||
() => unref(innerValueRef), |
|
||||
(val) => { |
|
||||
emit('change', val); |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
return () => { |
|
||||
const { showInput, disabled } = props; |
|
||||
return ( |
|
||||
<div class={prefixCls}> |
|
||||
{showInput && ( |
|
||||
<Input.Password |
|
||||
{...attrs} |
|
||||
allowClear={true} |
|
||||
value={unref(innerValueRef)} |
|
||||
onChange={handleChange} |
|
||||
disabled={disabled} |
|
||||
> |
|
||||
{extendSlots(slots)} |
|
||||
</Input.Password> |
|
||||
)} |
|
||||
<div class={`${prefixCls}-bar`}> |
|
||||
<div class={`${prefixCls}-bar__fill`} data-score={unref(getPasswordStrength)}></div> |
|
||||
</div> |
|
||||
</div> |
|
||||
); |
|
||||
}; |
|
||||
}, |
|
||||
}); |
|
||||
@ -0,0 +1,156 @@ |
|||||
|
<template> |
||||
|
<div :class="prefixCls"> |
||||
|
<InputPassword |
||||
|
v-if="showInput" |
||||
|
v-bind="$attrs" |
||||
|
allowClear |
||||
|
:value="innerValueRef" |
||||
|
@change="handleChange" |
||||
|
:disabled="disabled" |
||||
|
> |
||||
|
<template #[item]="data" v-for="item in Object.keys($slots)"> |
||||
|
<slot :name="item" v-bind="data" /> |
||||
|
</template> |
||||
|
</InputPassword> |
||||
|
<div :class="`${prefixCls}-bar`"> |
||||
|
<div :class="`${prefixCls}-bar--fill`" :data-score="getPasswordStrength"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { PropType } from 'vue'; |
||||
|
|
||||
|
import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue'; |
||||
|
|
||||
|
import { Input } from 'ant-design-vue'; |
||||
|
|
||||
|
import zxcvbn from 'zxcvbn'; |
||||
|
import { propTypes } from '/@/utils/propTypes'; |
||||
|
import { useDesign } from '/@/hooks/web/useDesign'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'StrengthMeter', |
||||
|
components: { InputPassword: Input.Password }, |
||||
|
props: { |
||||
|
value: propTypes.string, |
||||
|
|
||||
|
userInputs: { |
||||
|
type: Array as PropType<string[]>, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
|
||||
|
showInput: propTypes.bool.def(true), |
||||
|
disabled: propTypes.bool, |
||||
|
}, |
||||
|
emits: ['score-change', 'change'], |
||||
|
setup(props, { emit }) { |
||||
|
const innerValueRef = ref(''); |
||||
|
const { prefixCls } = useDesign('strength-meter'); |
||||
|
|
||||
|
const getPasswordStrength = computed(() => { |
||||
|
const { userInputs, disabled } = props; |
||||
|
if (disabled) return null; |
||||
|
const innerValue = unref(innerValueRef); |
||||
|
const score = innerValue |
||||
|
? zxcvbn(unref(innerValueRef), (userInputs as string[]) || null).score |
||||
|
: null; |
||||
|
emit('score-change', score); |
||||
|
return score; |
||||
|
}); |
||||
|
|
||||
|
function handleChange(e: ChangeEvent) { |
||||
|
innerValueRef.value = e.target.value; |
||||
|
} |
||||
|
|
||||
|
watchEffect(() => { |
||||
|
innerValueRef.value = props.value || ''; |
||||
|
}); |
||||
|
watch( |
||||
|
() => unref(innerValueRef), |
||||
|
(val) => { |
||||
|
emit('change', val); |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
return { |
||||
|
getPasswordStrength, |
||||
|
handleChange, |
||||
|
prefixCls, |
||||
|
innerValueRef, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
@import (reference) '../../../design/index.less'; |
||||
|
@prefix-cls: ~'@{namespace}-strength-meter'; |
||||
|
|
||||
|
.@{prefix-cls} { |
||||
|
position: relative; |
||||
|
|
||||
|
&-bar { |
||||
|
position: relative; |
||||
|
height: 4px; |
||||
|
margin: 10px auto 6px; |
||||
|
background: @disabled-color; |
||||
|
border-radius: 3px; |
||||
|
|
||||
|
&::before, |
||||
|
&::after { |
||||
|
position: absolute; |
||||
|
z-index: 10; |
||||
|
display: block; |
||||
|
width: 20%; |
||||
|
height: inherit; |
||||
|
background: transparent; |
||||
|
border-color: @white; |
||||
|
border-style: solid; |
||||
|
border-width: 0 5px 0 5px; |
||||
|
content: ''; |
||||
|
} |
||||
|
|
||||
|
&::before { |
||||
|
left: 20%; |
||||
|
} |
||||
|
|
||||
|
&::after { |
||||
|
right: 20%; |
||||
|
} |
||||
|
|
||||
|
&--fill { |
||||
|
position: absolute; |
||||
|
width: 0; |
||||
|
height: inherit; |
||||
|
background: transparent; |
||||
|
border-radius: inherit; |
||||
|
transition: width 0.5s ease-in-out, background 0.25s; |
||||
|
|
||||
|
&[data-score='0'] { |
||||
|
width: 20%; |
||||
|
background: darken(@error-color, 10%); |
||||
|
} |
||||
|
|
||||
|
&[data-score='1'] { |
||||
|
width: 40%; |
||||
|
background: @error-color; |
||||
|
} |
||||
|
|
||||
|
&[data-score='2'] { |
||||
|
width: 60%; |
||||
|
background: @warning-color; |
||||
|
} |
||||
|
|
||||
|
&[data-score='3'] { |
||||
|
width: 80%; |
||||
|
background: fade(@success-color, 50%); |
||||
|
} |
||||
|
|
||||
|
&[data-score='4'] { |
||||
|
width: 100%; |
||||
|
background: @success-color; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -1,9 +1,6 @@ |
|||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
export const BasicTree = createAsyncComponent(() => import('./src/BasicTree')); |
export const BasicTree = createAsyncComponent(() => import('./src/BasicTree')); |
||||
|
|
||||
withInstall(BasicTree); |
|
||||
|
|
||||
export type { ContextMenuItem } from '/@/hooks/web/useContextMenu'; |
export type { ContextMenuItem } from '/@/hooks/web/useContextMenu'; |
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|||||
@ -1,10 +1,6 @@ |
|||||
import { withInstall } from '../util'; |
|
||||
|
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
||||
|
|
||||
export const BasicDragVerify = createAsyncComponent(() => import('./src/DragVerify')); |
export const BasicDragVerify = createAsyncComponent(() => import('./src/DragVerify')); |
||||
export const RotateDragVerify = createAsyncComponent(() => import('./src/ImgRotate')); |
export const RotateDragVerify = createAsyncComponent(() => import('./src/ImgRotate')); |
||||
|
|
||||
withInstall(BasicDragVerify, RotateDragVerify); |
|
||||
|
|
||||
export * from './src/types'; |
export * from './src/types'; |
||||
|
|||||
Loading…
Reference in new issue