diff --git a/CHANGELOG.md b/CHANGELOG.md index 61eaa0a..fc16003 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.4.3 + +- `(Add)` Custom transition support. +### Demo + +- `(Add)` noTransition sample. +- `(Add)` customTransition sample. + +
+ ## 0.4.2 - `(Add)` [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) support for supporting browsers. diff --git a/README.md b/README.md index 4e24393..a3a50e5 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,12 @@ interface WowerlayProps { * @default false */ noBackground: boolean; + /** + * Disable or set custom transition for Wowerlay + * @set {false} to disable transition + * @set {string} to use your own transition name (enter-to, enter-from, enter-active class animation name) + */ + transition: string | boolean; } ``` diff --git a/demo/demo.scss b/demo/demo.scss index 667b280..0a2efc5 100644 --- a/demo/demo.scss +++ b/demo/demo.scss @@ -1,177 +1,194 @@ -@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap'); -@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@500&display=swap'); - -$accentColor: rgb(28, 179, 255); -$secondaryColor: #1a1a1a; - -html { - font-family: 'Roboto', sans-serif; - background-color: rgb(44, 44, 44); -} -* { - box-sizing: border-box; -} - -::-webkit-scrollbar { - width: 5px; - height: 5px; - - &-thumb { - background-color: gray; - } - &-track { - background-color: transparent; - } -} - -.wowerlay { - background-color: $secondaryColor; - border-radius: 3px; - color: #fff; - box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.25); - padding: 15px; -} - -.demo-container { - display: flex; - justify-content: center; - align-items: center; - height: 4000px; - width: 5000px; -} - -.demo-content { - text-align: center; - width: 100%; -} - -.demo-menu { - display: flex; - flex-flow: column nowrap; - position: fixed; - left: 10px; - top: 0; - bottom: 0; - margin: auto 0; - height: calc(100vh - 20px); - min-width: 200px; - border-radius: 10px; - box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.2); - background-color: $secondaryColor; - padding: 5px; - - .demo-show-code-button { - position: absolute; - white-space: nowrap; - left: calc(100% + 10px); - } - - .demo-menu-item { - width: 100%; - padding: 10px 10px; - border-radius: 10px; - font-size: 16px; - font-weight: 600; - color: rgb(121, 121, 121); - margin: 3px 0; - cursor: default; - - &:hover { - color: rgb(160, 160, 160); - background-color: rgba(68, 68, 68, 0.1); - } - - &.active { - background-color: rgba(68, 68, 68, 0.2); - text-shadow: 0px 0px 1px $accentColor; - font-weight: 900; - color: $accentColor; - } - } -} - -::-webkit-scrollbar { - width: 5px; -} -::-webkit-scrollbar-thumb { - background-color: gray; - border-radius: 10px; -} - -.hljs-tag { - color: #c9c9c9; -} - -.vier-sheet { - max-width: 100% !important; - width: min-content !important; - &::after { - max-width: 100% !important; - } -} - -.object { - display: inline-block; - background-color: $secondaryColor; - color: rgb(255, 255, 255); - box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.3); - border-radius: 5px; - padding: 7px; -} - -input { - background-color: lighten($secondaryColor, 5); - color: #fff; - border-radius: 10px; - border: 1px solid transparent; - outline: none; - padding: 3px; - - &[type='number'] { - width: 50px; - text-align: center; - appearance: none; - } - - &:focus { - border-color: $accentColor; - } -} - -button, -select { - border-radius: 5px; - padding: 7px; - background-color: $secondaryColor; - border: 1px solid $accentColor; - color: $accentColor; - font-size: 15px; - transition: all 0.25s; - outline: none; - - &:hover { - background-color: $accentColor; - color: $secondaryColor; - } -} - -a { - color: $accentColor; - transition: text-shadow 0.15s ease-in-out; - text-decoration: none; - - &:hover { - text-shadow: 0px 0px 4px $accentColor; - } -} - -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} - -/* Firefox */ -input[type='number'] { - -moz-appearance: textfield; -} +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@500&display=swap'); + +$accentColor: rgb(28, 179, 255); +$secondaryColor: #1a1a1a; + +html { + font-family: 'Roboto', sans-serif; + background-color: rgb(44, 44, 44); +} +* { + box-sizing: border-box; +} + +::-webkit-scrollbar { + width: 5px; + height: 5px; + + &-thumb { + background-color: gray; + } + &-track { + background-color: transparent; + } +} + +.wowerlay { + background-color: $secondaryColor; + border-radius: 3px; + color: #fff; + box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.25); + padding: 15px; +} + +.demo-container { + display: flex; + justify-content: center; + align-items: center; + height: 4000px; + width: 5000px; +} + +.demo-content { + text-align: center; + width: 100%; +} + +.demo-menu { + display: flex; + flex-flow: column nowrap; + position: fixed; + left: 10px; + top: 0; + bottom: 0; + margin: auto 0; + height: calc(100vh - 20px); + min-width: 200px; + border-radius: 10px; + box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.2); + background-color: $secondaryColor; + padding: 5px; + + .demo-show-code-button { + position: absolute; + white-space: nowrap; + left: calc(100% + 10px); + } + + .demo-menu-item { + width: 100%; + padding: 10px 10px; + border-radius: 10px; + font-size: 16px; + font-weight: 600; + color: rgb(121, 121, 121); + margin: 3px 0; + cursor: default; + + &:hover { + color: rgb(160, 160, 160); + background-color: rgba(68, 68, 68, 0.1); + } + + &.active { + background-color: rgba(68, 68, 68, 0.2); + text-shadow: 0px 0px 1px $accentColor; + font-weight: 900; + color: $accentColor; + } + } +} + +::-webkit-scrollbar { + width: 5px; +} +::-webkit-scrollbar-thumb { + background-color: gray; + border-radius: 10px; +} + +.hljs-tag { + color: #c9c9c9; +} + +.vier-sheet { + max-width: 100% !important; + width: min-content !important; + &::after { + max-width: 100% !important; + } +} + +.object { + display: inline-block; + background-color: $secondaryColor; + color: rgb(255, 255, 255); + box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.3); + border-radius: 5px; + padding: 7px; +} + +input { + background-color: lighten($secondaryColor, 5); + color: #fff; + border-radius: 10px; + border: 1px solid transparent; + outline: none; + padding: 3px; + + &[type='number'] { + width: 50px; + text-align: center; + appearance: none; + } + + &:focus { + border-color: $accentColor; + } +} + +button, +select { + border-radius: 5px; + padding: 7px; + background-color: $secondaryColor; + border: 1px solid $accentColor; + color: $accentColor; + font-size: 15px; + transition: all 0.25s; + outline: none; + + &:hover { + background-color: $accentColor; + color: $secondaryColor; + } +} + +a { + color: $accentColor; + transition: text-shadow 0.15s ease-in-out; + text-decoration: none; + + &:hover { + text-shadow: 0px 0px 4px $accentColor; + } +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox */ +input[type='number'] { + -moz-appearance: textfield; +} + +.skew-enter-active, +.skew-leave-active { + transition: transform 0.5s ease; + backface-visibility: hidden; + transform-origin: center top; +} + +.skew-enter-from, +.skew-leave-to { + transform: perspective(1000px) rotateX(180deg) +} + +.skew-enter-to, +.skew-leave-from { + transform: perspective(1000px) rotateX(0deg) +} diff --git a/demo/demos/customTransition.tsx b/demo/demos/customTransition.tsx new file mode 100644 index 0000000..f31a56b --- /dev/null +++ b/demo/demos/customTransition.tsx @@ -0,0 +1,76 @@ +import { defineComponent, ref } from 'vue'; +import { defineDemo, html } from '../helpers'; + +import { Wowerlay } from '../../src/lib'; + +const Component = defineComponent({ + setup() { + const targetEl = ref(); + const isOpen = ref(false); + + const handleVisibleChange = (state: boolean) => { + isOpen.value = state; + }; + const toggleVisible = () => { + isOpen.value = !isOpen.value; + }; + + return { + isOpen, + targetEl, + handleVisibleChange, + toggleVisible, + }; + }, + render() { + return ( + + ); + }, +}); + +export const Demo = defineDemo({ + name: 'Custom Transition', + component: Component, + template: html` + + `, + script: html` + + `, +}); diff --git a/demo/demos/noTransition.tsx b/demo/demos/noTransition.tsx new file mode 100644 index 0000000..36382f8 --- /dev/null +++ b/demo/demos/noTransition.tsx @@ -0,0 +1,76 @@ +import { defineComponent, ref } from 'vue'; +import { defineDemo, html } from '../helpers'; + +import { Wowerlay } from '../../src/lib'; + +const Component = defineComponent({ + setup() { + const targetEl = ref(); + const isOpen = ref(false); + + const handleVisibleChange = (state: boolean) => { + isOpen.value = state; + }; + const toggleVisible = () => { + isOpen.value = !isOpen.value; + }; + + return { + isOpen, + targetEl, + handleVisibleChange, + toggleVisible, + }; + }, + render() { + return ( + + ); + }, +}); + +export const Demo = defineDemo({ + name: 'No Transition', + component: Component, + template: html` + + `, + script: html` + + `, +}); diff --git a/package.json b/package.json index 0fd9965..13a1302 100644 --- a/package.json +++ b/package.json @@ -1,58 +1,58 @@ -{ - "name": "wowerlay", - "version": "0.4.2", - "main": "./dist/wowerlay.umd.js", - "module": "./dist/wowerlay.es.js", - "types": "./dist/types/lib.d.ts", - "repository": { - "url": "git+https://github.com/teamseodo/wowerlay.git", - "type": "git" - }, - "bugs": { - "url": "https://github.com/teamseodo/wowerlay/issues" - }, - "homepage": "https://github.com/teamseodo/wowerlay#readme", - "keywords": [ - "vue 3", - "wowerlay", - "popover" - ], - "license": "MIT", - "files": [ - "/dist", - "README.md" - ], - "scripts": { - "dev": "cross-env MODE=demo vite", - "build": "ts-node -T --project tsconfig-build.json scripts/build.ts", - "build:demo": "cross-env MODE=demo vite build", - "script:build": "tsc --project tsconfig-build.json && cross-env MODE=production vite build", - "watch": "cross-env MODE=production vite build --watch" - }, - "devDependencies": { - "@types/fs-extra": "^9.0.13", - "@types/node": "^16.10.3", - "@types/prompts": "^2.0.14", - "@vitejs/plugin-vue-jsx": "^1.2.0", - "bottom-sheet-vue3": "^1.0.2", - "chalk": "^4.1.2", - "cross-env": "^7.0.3", - "eslint": "8.7.0", - "eslint-config-airbnb-typescript-prettier": "5.0.0", - "execa": "^5.1.1", - "fast-glob": "^3.2.7", - "fs-extra": "^10.0.0", - "highlight.js": "^11.3.1", - "prettier": "2.5.1", - "prompts": "^2.4.2", - "sass": "^1.42.1", - "ts-node": "^10.2.1", - "typescript": "4.5.2", - "vite": "^2.6.4", - "vite-plugin-dts": "^0.8.3", - "vue": "^3.2.0" - }, - "peerDependencies": { - "vue": "^3.2.0" - } -} +{ + "name": "wowerlay", + "version": "0.4.3", + "main": "./dist/wowerlay.umd.js", + "module": "./dist/wowerlay.es.js", + "types": "./dist/types/lib.d.ts", + "repository": { + "url": "git+https://github.com/teamseodo/wowerlay.git", + "type": "git" + }, + "bugs": { + "url": "https://github.com/teamseodo/wowerlay/issues" + }, + "homepage": "https://github.com/teamseodo/wowerlay#readme", + "keywords": [ + "vue 3", + "wowerlay", + "popover" + ], + "license": "MIT", + "files": [ + "/dist", + "README.md" + ], + "scripts": { + "dev": "cross-env MODE=demo vite", + "build": "ts-node -T --project tsconfig-build.json scripts/build.ts", + "build:demo": "cross-env MODE=demo vite build", + "script:build": "tsc --project tsconfig-build.json && cross-env MODE=production vite build", + "watch": "cross-env MODE=production vite build --watch" + }, + "devDependencies": { + "@types/fs-extra": "^9.0.13", + "@types/node": "^16.10.3", + "@types/prompts": "^2.0.14", + "@vitejs/plugin-vue-jsx": "^1.2.0", + "bottom-sheet-vue3": "^1.0.2", + "chalk": "^4.1.2", + "cross-env": "^7.0.3", + "eslint": "8.7.0", + "eslint-config-airbnb-typescript-prettier": "5.0.0", + "execa": "^5.1.1", + "fast-glob": "^3.2.7", + "fs-extra": "^10.0.0", + "highlight.js": "^11.3.1", + "prettier": "2.5.1", + "prompts": "^2.4.2", + "sass": "^1.42.1", + "ts-node": "^10.2.1", + "typescript": "4.5.2", + "vite": "^2.6.4", + "vite-plugin-dts": "^0.8.3", + "vue": "^3.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } +} diff --git a/src/components/Wowerlay.tsx b/src/components/Wowerlay.tsx index 66f936a..adcaeca 100644 --- a/src/components/Wowerlay.tsx +++ b/src/components/Wowerlay.tsx @@ -111,6 +111,26 @@ export const Wowerlay = defineComponent({ }; }, render() { + let willBeRendered: null | JSX.Element = null; + + const Renderer = !this.isVisible ? null : ( + + {this.$slots.default?.()} + + ); + + if (this.transition === false) { + willBeRendered = Renderer; + } else if (typeof this.transition === 'string') { + willBeRendered = {Renderer}; + } else { + willBeRendered = ( + + {Renderer} + + ); + } + return (
- {/* Todo: Add user made animation support. */} - - {this.isVisible && ( - - {this.$slots.default?.()} - - )} - + {willBeRendered}
); diff --git a/src/components/WowerlayReusables/index.ts b/src/components/WowerlayReusables/index.ts index 24bd264..782f5b4 100644 --- a/src/components/WowerlayReusables/index.ts +++ b/src/components/WowerlayReusables/index.ts @@ -21,6 +21,7 @@ export interface WowerlayBaseProps { target?: HTMLElement; tag: string; noBackground: boolean; + transition: boolean | string; } export const wowerlayBaseProps = { @@ -56,4 +57,8 @@ export const wowerlayBaseProps = { default: 'div', type: String as PropType, }, + transition: { + default: true, + type: [Boolean, String] as PropType, + }, } as const;