diff --git a/packages/varlet-eslint-config/index.js b/packages/varlet-eslint-config/index.js index 34343e3590d..9e82f8d00a7 100644 --- a/packages/varlet-eslint-config/index.js +++ b/packages/varlet-eslint-config/index.js @@ -1,64 +1,65 @@ module.exports = { - extends: [ - 'airbnb-base', - 'plugin:@typescript-eslint/recommended', - 'plugin:vue/vue3-recommended', - 'prettier', - 'prettier/vue', - ], - parserOptions: { - parser: '@typescript-eslint/parser', - ecmaVersion: 2020, - sourceType: 'module', - extraFileExtensions: ['.vue'], - }, - plugins: ['@typescript-eslint'], - env: { - es6: true, - node: true, - browser: true, - }, - rules: { - 'no-new': 'off', - 'no-shadow': 'off', - 'no-bitwise': 'off', - 'func-names': 'off', - 'no-console': 'off', - 'no-plusplus': 'off', - 'default-case': 'off', - 'prefer-template': 'off', - 'consistent-return': 'off', - 'no-param-reassign': 'off', - 'no-nested-ternary': 'off', - 'no-underscore-dangle': 'off', - 'no-unused-expressions': 'off', - 'no-restricted-globals': 'off', - 'no-use-before-define': 'off', - 'class-methods-use-this': 'off', - 'global-require': 'off', - 'prefer-destructuring': ['error', { object: true, array: false }], - // eslint-plugin-import - 'import/order': 'off', - 'import/extensions': 'off', - 'import/no-unresolved': 'off', - 'import/prefer-default-export': 'off', - 'import/no-extraneous-dependencies': 'off', - 'import/no-dynamic-require': 'off', - // eslint-plugin-vue - 'vue/comment-directive': 'off', - 'vue/no-v-html': 'off', - 'vue/attributes-order': 'off', - 'vue/require-default-prop': 'off', - 'vue/no-unused-components': 'off', - 'vue/require-explicit-emits': 'off', - // typescript-eslint - '@typescript-eslint/camelcase': 'off', - '@typescript-eslint/ban-ts-ignore': 'off', - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off' - }, -}; + extends: [ + 'airbnb-base', + 'plugin:@typescript-eslint/recommended', + 'plugin:vue/vue3-recommended', + 'prettier', + 'prettier/vue', + ], + parserOptions: { + parser: '@typescript-eslint/parser', + ecmaVersion: 2020, + sourceType: 'module', + extraFileExtensions: ['.vue'], + }, + plugins: ['@typescript-eslint'], + env: { + es6: true, + node: true, + browser: true, + }, + rules: { + 'no-new': 'off', + 'no-shadow': 'off', + 'no-bitwise': 'off', + 'func-names': 'off', + 'no-console': 'off', + 'no-plusplus': 'off', + 'default-case': 'off', + 'prefer-template': 'off', + 'consistent-return': 'off', + 'no-param-reassign': 'off', + 'no-nested-ternary': 'off', + 'no-underscore-dangle': 'off', + 'no-unused-expressions': 'off', + 'no-restricted-globals': 'off', + 'no-use-before-define': 'off', + 'class-methods-use-this': 'off', + 'global-require': 'off', + 'prefer-destructuring': ['error', { object: true, array: false }], + // eslint-plugin-import + 'import/order': 'off', + 'import/extensions': 'off', + 'import/no-unresolved': 'off', + 'import/prefer-default-export': 'off', + 'import/no-extraneous-dependencies': 'off', + 'import/no-dynamic-require': 'off', + // eslint-plugin-vue + 'vue/comment-directive': 'off', + 'vue/no-v-html': 'off', + 'vue/attributes-order': 'off', + 'vue/require-default-prop': 'off', + 'vue/no-unused-components': 'off', + 'vue/require-explicit-emits': 'off', + // typescript-eslint + '@typescript-eslint/camelcase': 'off', + '@typescript-eslint/ban-ts-ignore': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-extra-semi': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + }, +} diff --git a/packages/varlet-icons/svg/uF007-chevron-down.svg b/packages/varlet-icons/svg/uF007-chevron-down.svg new file mode 100644 index 00000000000..fc32cf83eec --- /dev/null +++ b/packages/varlet-icons/svg/uF007-chevron-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/varlet-ui/src/expansion-panel/ExpansionPanel.vue b/packages/varlet-ui/src/expansion-panel/ExpansionPanel.vue new file mode 100644 index 00000000000..55b63c0ac1a --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/ExpansionPanel.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/packages/varlet-ui/src/expansion-panel/__tests__/index.spec.js b/packages/varlet-ui/src/expansion-panel/__tests__/index.spec.js new file mode 100644 index 00000000000..d6da60b479c --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/__tests__/index.spec.js @@ -0,0 +1,7 @@ +const ExpansionPanel = require('../../../cjs/expansion-panel').default +const { render } = require('@testing-library/vue') + +test('test expansionPanel', async () => { + const wrapper = render(ExpansionPanel) + console.log(wrapper) +}) diff --git a/packages/varlet-ui/src/expansion-panel/docs/en_US.md b/packages/varlet-ui/src/expansion-panel/docs/en_US.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/varlet-ui/src/expansion-panel/docs/zh_CN.md b/packages/varlet-ui/src/expansion-panel/docs/zh_CN.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/varlet-ui/src/expansion-panel/example/index.vue b/packages/varlet-ui/src/expansion-panel/example/index.vue new file mode 100644 index 00000000000..90eb4fa08a4 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/example/index.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/packages/varlet-ui/src/expansion-panel/expansionPanel.less b/packages/varlet-ui/src/expansion-panel/expansionPanel.less new file mode 100644 index 00000000000..35e947764f9 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/expansionPanel.less @@ -0,0 +1,75 @@ +@import '../styles/var'; + +.var-expansion-panel { + box-sizing: border-box; + position: relative; + margin-top: 0; + background: #fff; + color: rgba(0, 0, 0, 0.87); + transition: margin-top 0.4s, color 0.4s; + + &:before { + bottom: 0; + content: ''; + left: 0; + position: absolute; + right: 0; + top: 0; + z-index: -1; + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + } + + &:not(:first-child):after { + border-top: thin solid rgba(0, 0, 0, 0.12); + content: ''; + left: 0; + position: absolute; + right: 0; + top: 0; + } + + &-header { + align-items: center; + display: flex; + font-size: @font-size-md; + outline: none; + padding: 10px 16px; + justify-content: space-between; + position: relative; + width: 100%; + + &__icon { + transform: rotate(0deg); + opacity: 1; + } + + &__disable { + opacity: 0; + } + + &__open { + transform: rotate(-180deg); + } + } + + &-content { + transition: height 0.4s; + display: flex; + overflow: hidden; + } + + &__wrap { + padding: 0 16px 10px; + word-break: break-all; + flex: 1; + } + + &__active + &, + &__active:not(:first-child) { + margin-top: 16px; + } + + &__disable { + color: rgba(0, 0, 0, 0.38); + } +} diff --git a/packages/varlet-ui/src/expansion-panel/index.ts b/packages/varlet-ui/src/expansion-panel/index.ts new file mode 100644 index 00000000000..4a3f42c59c8 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/index.ts @@ -0,0 +1,8 @@ +import { App } from 'vue' +import ExpansionPanel from './ExpansionPanel.vue' + +ExpansionPanel.install = function (app: App) { + app.component(ExpansionPanel.name, ExpansionPanel) +} + +export default ExpansionPanel diff --git a/packages/varlet-ui/src/expansion-panel/props.ts b/packages/varlet-ui/src/expansion-panel/props.ts new file mode 100644 index 00000000000..f089ccf4294 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/props.ts @@ -0,0 +1,16 @@ +export const props = { + name: { + type: [String, Number], + }, + title: { + type: String, + }, + icon: { + type: String, + default: 'chevron-down', + }, + disabled: { + type: Boolean, + default: false, + }, +} diff --git a/packages/varlet-ui/src/expansion-panel/provide.ts b/packages/varlet-ui/src/expansion-panel/provide.ts new file mode 100644 index 00000000000..9c1efe3b766 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panel/provide.ts @@ -0,0 +1,8 @@ +import { ComputedRef } from 'vue' + +export interface ExpansionPanelProvider { + index: ComputedRef + name: ComputedRef + init(accordion: boolean): void + toggle(isShow?: boolean, initOrAccordion?: boolean): void +} diff --git a/packages/varlet-ui/src/expansion-panels/ExpansionPanels.vue b/packages/varlet-ui/src/expansion-panels/ExpansionPanels.vue new file mode 100644 index 00000000000..495b1524764 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/ExpansionPanels.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/packages/varlet-ui/src/expansion-panels/__tests__/index.spec.js b/packages/varlet-ui/src/expansion-panels/__tests__/index.spec.js new file mode 100644 index 00000000000..6bfd743ddc8 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/__tests__/index.spec.js @@ -0,0 +1,7 @@ +const ExpansionPanels = require('../../../cjs/expansion-panels').default +const { render } = require('@testing-library/vue') + +test('test expansionPanels', async () => { + const wrapper = render(ExpansionPanels) + console.log(wrapper) +}) diff --git a/packages/varlet-ui/src/expansion-panels/docs/en_US.md b/packages/varlet-ui/src/expansion-panels/docs/en_US.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/varlet-ui/src/expansion-panels/docs/zh_CN.md b/packages/varlet-ui/src/expansion-panels/docs/zh_CN.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/varlet-ui/src/expansion-panels/example/index.vue b/packages/varlet-ui/src/expansion-panels/example/index.vue new file mode 100644 index 00000000000..105b1147d12 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/example/index.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/packages/varlet-ui/src/expansion-panels/expansionPanels.less b/packages/varlet-ui/src/expansion-panels/expansionPanels.less new file mode 100644 index 00000000000..63a48bb7819 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/expansionPanels.less @@ -0,0 +1,5 @@ +@import '../styles/elevation'; + +.var-expansion-panels { + position: relative; +} diff --git a/packages/varlet-ui/src/expansion-panels/index.ts b/packages/varlet-ui/src/expansion-panels/index.ts new file mode 100644 index 00000000000..e5f19e550e0 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/index.ts @@ -0,0 +1,8 @@ +import { App } from 'vue' +import ExpansionPanels from './ExpansionPanels.vue' + +ExpansionPanels.install = function (app: App) { + app.component(ExpansionPanels.name, ExpansionPanels) +} + +export default ExpansionPanels diff --git a/packages/varlet-ui/src/expansion-panels/props.ts b/packages/varlet-ui/src/expansion-panels/props.ts new file mode 100644 index 00000000000..ea98202ef3c --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/props.ts @@ -0,0 +1,17 @@ +import { PropType } from 'vue' + +export const props = { + modelValue: { + type: [Array, String, Number] as PropType>, + }, + accordion: { + type: Boolean, + default: false, + }, + onChange: { + type: Function, + }, + 'onUpdate:modelValue': { + type: Function, + }, +} diff --git a/packages/varlet-ui/src/expansion-panels/provide.ts b/packages/varlet-ui/src/expansion-panels/provide.ts new file mode 100644 index 00000000000..d7132e4f7d1 --- /dev/null +++ b/packages/varlet-ui/src/expansion-panels/provide.ts @@ -0,0 +1,9 @@ +import { ComputedRef } from 'vue' + +export interface ExpansionPanelsProvider { + active: ComputedRef | undefined> + updateItem: (value: number | string | undefined, isExpand: boolean) => void +} + +export const EXPANSION_PANELS_BIND_EXPANSION_PANEL_KEY = Symbol('EXPANSION_PANELS_BIND_EXPANSION_PANEL_KEY') +export const EXPANSION_PANELS_COUNT_EXPANSION_PANEL_KEY = Symbol('EXPANSION_PANELS_COUNT_EXPANSION_PANEL_KEY') diff --git a/packages/varlet-ui/src/icon/Icon.vue b/packages/varlet-ui/src/icon/Icon.vue index 05ac7e90de7..22058d1c405 100644 --- a/packages/varlet-ui/src/icon/Icon.vue +++ b/packages/varlet-ui/src/icon/Icon.vue @@ -3,7 +3,7 @@ class="var-icon" :class="[`${namespace}--set`, `${namespace}-${nextName}`, tickTransition ? 'var-icon--hidden' : null]" :style="{ - transition: `transform ${transition}ms`, + transition: `all ${transition}ms`, }" v-bind="$attrs" /> diff --git a/packages/varlet-ui/src/icon/icon.less b/packages/varlet-ui/src/icon/icon.less index 10ef6955705..b48df41d367 100644 --- a/packages/varlet-ui/src/icon/icon.less +++ b/packages/varlet-ui/src/icon/icon.less @@ -1,11 +1,11 @@ -@import "~@varlet/icons/dist/css/varlet-icons.less"; -@import "../styles/var"; +@import '~@varlet/icons/dist/css/varlet-icons.less'; +@import '../styles/var'; .var-icon { - //font-size: @icon-size-md; - color: inherit; + font-size: @icon-size-md; + color: inherit; - &--hidden { - transform: scale(0); - } + &--hidden { + transform: scale(0); + } } diff --git a/packages/varlet-ui/src/utils/elements.ts b/packages/varlet-ui/src/utils/elements.ts index ee2bb57e743..3be338f79fd 100644 --- a/packages/varlet-ui/src/utils/elements.ts +++ b/packages/varlet-ui/src/utils/elements.ts @@ -1,3 +1,7 @@ +import { inBrowser } from './shared' + +const root = (inBrowser ? window : global) as Window + export function getTop(element: HTMLElement): number { const { top } = element.getBoundingClientRect() @@ -82,3 +86,7 @@ export function remToPx(rem: string | number): number { return value * parseFloat(rootFontSize) } + +export function requestAnimationFrame(fn: FrameRequestCallback): number { + return root.requestAnimationFrame ? root.requestAnimationFrame(fn) : root.setTimeout(fn, 16) +} diff --git a/packages/varlet-ui/src/utils/shared.ts b/packages/varlet-ui/src/utils/shared.ts index e0767153198..4db0881275f 100644 --- a/packages/varlet-ui/src/utils/shared.ts +++ b/packages/varlet-ui/src/utils/shared.ts @@ -8,12 +8,16 @@ export interface CacheInstance { remove(key: T): void } +export const inBrowser = typeof window !== 'undefined' + export const isString = (val: unknown): val is string => typeof val === 'string' export const isNumber = (val: unknown): val is number => typeof val === 'number' export const isBaseObject = (val: unknown) => Object.prototype.toString.call(val) === '[object Object]' +export const isArray = (val: unknown): val is Array => Array.isArray(val) + export const removeItem = (arr: Array, item: unknown) => { if (arr.length) { const index: number = arr.indexOf(item)