From 0dcd9b8eaacc13b7deeadf595e7568659f03b304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 10 Jan 2022 11:16:32 +0300 Subject: [PATCH 01/11] Add ResizeObserver support and refactor project --- package.json | 1 - src/components/Wowerlay.tsx | 2 +- src/components/WowerlayRenderer.tsx | 56 +++++++++++++++---- src/event/index.ts | 10 +--- src/{lib.tsx => lib.ts} | 0 src/plugin/index.ts | 16 ++++-- .../WowerlayUtils => utils}/index.ts | 8 ++- tsconfig.json | 14 +++-- vite.config.ts | 9 ++- 9 files changed, 81 insertions(+), 35 deletions(-) rename src/{lib.tsx => lib.ts} (100%) rename src/{components/WowerlayUtils => utils}/index.ts (92%) diff --git a/package.json b/package.json index c92ae31..e3f0046 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "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", - "release": "ts-node -T --project tsconfig-build.json scripts/release.ts", "script:build": "tsc --project tsconfig-build.json && cross-env MODE=production vite build", "watch": "cross-env MODE=production vite build --watch" }, diff --git a/src/components/Wowerlay.tsx b/src/components/Wowerlay.tsx index 9211300..a7f330b 100644 --- a/src/components/Wowerlay.tsx +++ b/src/components/Wowerlay.tsx @@ -15,7 +15,7 @@ import { WowerlayBaseProps, wowerlayBaseProps } from './WowerlayReusables'; import { cWowerlayAnimEnter, cWowerlayAnimLeave, cWowerlayBackground } from '../consts'; import { WowerlayRenderer } from './WowerlayRenderer'; -import { useWowerlayContext } from '../event'; +import { useWowerlayContext } from '../plugin'; export interface WowerlayProps extends WowerlayBaseProps { visible: boolean; diff --git a/src/components/WowerlayRenderer.tsx b/src/components/WowerlayRenderer.tsx index 81fff24..956a58a 100644 --- a/src/components/WowerlayRenderer.tsx +++ b/src/components/WowerlayRenderer.tsx @@ -18,13 +18,16 @@ import { getRightStart, getTop, getTopEnd, - getTopStart -} from './WowerlayUtils'; + getTopStart, + isBrowser, + isElement, + isResizeObserverSupported +} from '../utils'; import { cWowerlay, sWowerlayX, sWowerlayY, scrollbarGap } from '../consts'; -import { computed, defineComponent, onMounted, ref, watch } from 'vue'; +import { computed, defineComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { WowerlayProps } from './Wowerlay'; -import { useWowerlayContext } from '../event'; +import { useWowerlayContext } from '../plugin/index'; import { wowerlayBaseProps } from './WowerlayReusables'; type Handlers = { @@ -93,7 +96,7 @@ export const WowerlayRenderer = defineComponent({ inheritAttrs: false, props: wowerlayBaseProps, emits: { - click: (e: MouseEvent): any => e.isTrusted + click: (_e: MouseEvent): any => true }, setup(props, { emit }) { const { onRecalculate } = useWowerlayContext(); @@ -111,9 +114,9 @@ export const WowerlayRenderer = defineComponent({ const handleClick = (e: MouseEvent) => emit('click', e); const fixPosition = (pos: number, direction: Direction) => { - if (props.canLeaveViewport) return pos; + if (props.canLeaveViewport || !wowerlayElement.value) return pos; - const { width, height } = wowerlayElement.value!.getBoundingClientRect(); + const { width, height } = wowerlayElement.value.getBoundingClientRect(); switch (direction) { case Direction.Horizontal: { @@ -128,8 +131,8 @@ export const WowerlayRenderer = defineComponent({ } }; - const updateOverlayPosition = () => { - if (!props.target || !wowerlayElement.value) return; + const updateWowerlayPosition = () => { + if (!isBrowser() || !props.target || !wowerlayElement.value) return; const targetRect = props.target.getBoundingClientRect(); const wowerlayRect = wowerlayElement.value.getBoundingClientRect(); @@ -168,13 +171,42 @@ export const WowerlayRenderer = defineComponent({ posY.value = fixPosition(newPosition.y, Direction.Vertical); }; + let observer: ResizeObserver | undefined; + if (isResizeObserverSupported()) { + observer = new ResizeObserver(() => { + if (props.fixed) return; + updateWowerlayPosition(); + }); + + watch( + () => props.target, + (newEl, oldEl) => { + if (isElement(oldEl)) observer?.unobserve(oldEl); + if (isElement(newEl)) observer?.observe(newEl); + }, + { immediate: true } + ); + } + watch( () => [props.position, props.target, props.verticalGap, props.horizontalGap], - updateOverlayPosition + updateWowerlayPosition ); - onRecalculate(() => !props.fixed && updateOverlayPosition()); - onMounted(() => props.target instanceof HTMLElement && updateOverlayPosition()); + onRecalculate(() => { + if (props.fixed) return; + updateWowerlayPosition(); + }); + + onMounted(() => { + if (isElement(props.target)) updateWowerlayPosition(); + if (wowerlayElement.value) observer?.observe(wowerlayElement.value); + }); + + onBeforeUnmount(() => { + if (!isElement(wowerlayElement.value)) return; + observer?.unobserve(wowerlayElement.value); + }); return { handleClick, diff --git a/src/event/index.ts b/src/event/index.ts index 40850a5..812f5a7 100644 --- a/src/event/index.ts +++ b/src/event/index.ts @@ -1,4 +1,4 @@ -import { InjectionKey, inject, onBeforeUnmount } from 'vue'; +import { onBeforeUnmount } from 'vue'; export type Handler = (event: T) => any; export interface EventsStore { @@ -6,14 +6,12 @@ export interface EventsStore { handler: Handler; } export interface WowerlayContext { - onRecalculate: (handler: Handler) => void; + onRecalculate: (handler: Handler) => void; onWindowClick: (handler: Handler) => void; calculateAll: (event: WheelEvent | Event) => void; clickAll: (event: PointerEvent) => void; } -export const injectionKey: InjectionKey = Symbol(); - export const createEvent = (store: EventsStore[], handler: Handler) => { const id = Symbol(); store.push({ id, handler }); @@ -32,7 +30,3 @@ export const runEvents = (store: EventsStore[], e?: any) => { }; export const createEventStore = () => [] as EventsStore[]; - -export const useWowerlayContext = () => { - return inject(injectionKey)!; -}; diff --git a/src/lib.tsx b/src/lib.ts similarity index 100% rename from src/lib.tsx rename to src/lib.ts diff --git a/src/plugin/index.ts b/src/plugin/index.ts index 1eddc44..074a57a 100644 --- a/src/plugin/index.ts +++ b/src/plugin/index.ts @@ -1,13 +1,17 @@ -import { Handler, createEvent, createEventStore, injectionKey, runEvents } from '../event'; +import { Handler, createEvent, createEventStore, runEvents } from '../event'; +import { InjectionKey, Plugin, inject } from 'vue'; -import { Plugin } from 'vue'; +import { WowerlayContext } from '../event'; +import { isBrowser } from '../utils'; + +const WowerlayInjectionKey: InjectionKey = Symbol(); export const createWowerlay = (): Plugin => ({ install(app) { const calculateEvents = createEventStore(); const clickEvents = createEventStore(); - const onRecalculate = (handler: Handler) => { + const onRecalculate = (handler: Handler) => { createEvent(calculateEvents, handler); }; const onWindowClick = (handler: Handler) => createEvent(clickEvents, handler); @@ -15,7 +19,7 @@ export const createWowerlay = (): Plugin => ({ const calculateAll = (e: WheelEvent | Event) => runEvents(calculateEvents, e); const clickAll = (e: MouseEvent) => runEvents(clickEvents, e); - if (typeof window !== 'undefined' && 'addEventListener' in window) { + if (isBrowser()) { const wa = window.addEventListener; wa('scroll', calculateAll); wa('wheel', calculateAll); @@ -23,7 +27,7 @@ export const createWowerlay = (): Plugin => ({ wa('click', clickAll); } - app.provide(injectionKey, { + app.provide(WowerlayInjectionKey, { calculateAll, clickAll, onWindowClick, @@ -31,3 +35,5 @@ export const createWowerlay = (): Plugin => ({ }); } }); + +export const useWowerlayContext = () => inject(WowerlayInjectionKey)!; diff --git a/src/components/WowerlayUtils/index.ts b/src/utils/index.ts similarity index 92% rename from src/components/WowerlayUtils/index.ts rename to src/utils/index.ts index bffd7bf..1e95c74 100644 --- a/src/components/WowerlayUtils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,4 @@ -import { scrollbarGap } from '../../consts'; +import { scrollbarGap } from '../consts'; export interface PositionHandlerParameters { wowerlayRect: DOMRect; @@ -141,3 +141,9 @@ export const checkOutOfScreenRight: OutOfScreenHandler = ( ) => targetRect.x + targetRect.width + wowerlayRect.width + scrollbarGap + horizontalGap > window.innerWidth; + +export const isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined'; + +export const isResizeObserverSupported = () => isBrowser() && 'ResizeObserver' in window; + +export const isElement = (el: any): el is HTMLElement => isBrowser() && el instanceof HTMLElement; diff --git a/tsconfig.json b/tsconfig.json index 6d29c82..018dec7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,12 @@ { "compilerOptions": { "target": "ESNext", - "useDefineForClassFields": true, "module": "ESNext", "moduleResolution": "node", "strict": true, "jsx": "preserve", "types": ["vite/client"], - "sourceMap": true, "outDir": "dist", - "declaration": true, - "declarationDir": "dist/types", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, @@ -22,6 +18,14 @@ "alwaysStrict": false, "noImplicitReturns": true }, - "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "demo/**/*"], + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "demo/**/*", + "scripts/**/*", + "vite.config.ts" + ], "exclude": ["node_modules"] } diff --git a/vite.config.ts b/vite.config.ts index 1b8894e..abec645 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -17,12 +17,17 @@ const productionConfig = defineConfig({ build: { target: 'es2020', lib: { - entry: path.resolve(root, 'src', 'lib.tsx'), + entry: path.resolve(root, 'src', 'lib.ts'), name: 'wowerlay', formats: ['es', 'umd'] }, rollupOptions: { - external: ['vue'] + external: ['vue'], + output: { + globals: { + vue: 'Vue' + } + } } } }); From 8b9a6d4fdf6769003dc405099152d7b6a3633398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 10 Jan 2022 11:16:37 +0300 Subject: [PATCH 02/11] Refactor scripts --- scripts/modules/functions.ts | 33 +----- scripts/release.ts | 201 ----------------------------------- 2 files changed, 5 insertions(+), 229 deletions(-) delete mode 100644 scripts/release.ts diff --git a/scripts/modules/functions.ts b/scripts/modules/functions.ts index 99a2cdc..466d267 100644 --- a/scripts/modules/functions.ts +++ b/scripts/modules/functions.ts @@ -1,10 +1,10 @@ -import chalk, { BackgroundColor, ForegroundColor } from 'chalk'; -import execa, { Options } from 'execa'; - +import chalk, { type BackgroundColor, type ForegroundColor } from 'chalk'; +import execa, { type Options as ExecaOptions } from 'execa'; import fse from 'fs-extra'; + import { join } from 'path'; -export function execute(command: string, commandArguments: string[], options?: Options) { +export function execute(command: string, commandArguments: string[], options?: ExecaOptions) { return execa(command, commandArguments, { stdio: 'inherit', ...options @@ -29,22 +29,6 @@ export function sleep(ms: number): Promise { }); } -export function indent(msg: string) { - const indentValue = ' '; - return indentValue + msg; -} - -export async function readGitignore() { - const root = process.cwd(); - return await fse.readFile(join(root, '.gitignore'), 'utf8'); -} - -export async function writeNewPackageJson(newPKG: typeof import('../../package.json')) { - const root = process.cwd(); - const stringifiedPackageJSON = JSON.stringify(newPKG, undefined, 2); - return await fse.writeFile(join(root, 'package.json'), stringifiedPackageJSON); -} - export async function refactorTypes() { const dist = join(process.cwd(), 'dist'); const basePath = join(dist, 'src'); @@ -53,7 +37,7 @@ export async function refactorTypes() { const toBeRemovedTypes = [ 'consts.d.ts', // 'event', - join('components', 'WowerlayUtils') + 'utils' ]; if (await fse.pathExists(basePath)) { @@ -66,10 +50,3 @@ export async function refactorTypes() { } throw new Error('types folder does not exist'); } - -export async function getCurrentBranchName() { - const { stdout: branchName } = await execute('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { - stdio: 'pipe' - }); - return branchName.trim(); -} diff --git a/scripts/release.ts b/scripts/release.ts deleted file mode 100644 index 69fcc51..0000000 --- a/scripts/release.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { - execute, - getCurrentBranchName, - indent, - log, - readGitignore, - sleep, - writeNewPackageJson -} from './modules/functions'; -import prompt, { Choice } from 'prompts'; - -import chalk from 'chalk'; -import fg from 'fast-glob'; -import pkgJSON from '../package.json'; - -const root = process.cwd(); - -interface PromptVal { - value: T; -} - -enum SelectType { - ByHand, - SelectFromList -} - -enum Purpose { - OnlyPublish, - GithubAndMaybePublish -} - -async function main() { - const { value: purpose }: PromptVal = await prompt({ - type: 'select', - message: 'What do you want to do?', - name: 'value', - choices: [ - { - title: 'Commit and maybe publish.', - value: Purpose.GithubAndMaybePublish - }, - { title: 'Only publish.', value: Purpose.OnlyPublish } - ] - }); - - if (purpose === Purpose.OnlyPublish) { - return publish(true); - } - - const gitignore = await readGitignore(); - const ignoredList = gitignore.split('\n').filter(Boolean); - - const allFiles = await fg('./**/*', { - cwd: process.cwd(), - ignore: ignoredList - }); - - const fileChoices: Choice[] = allFiles.map((v) => { - return { title: v, value: v }; - }); - - const newVersion = await input('Type new version, default:', pkgJSON.version); - - const { value: selectionType }: PromptVal = await prompt({ - type: 'select', - message: 'How do you want to add files?', - name: 'value', - choices: [ - { title: 'Type By Hand', value: SelectType.ByHand }, - { title: 'Select Files From List', value: SelectType.SelectFromList } - ] - }); - - let gitAddFiles: string[] = []; - if (selectionType === SelectType.SelectFromList) { - let { value: files }: PromptVal = await prompt({ - type: 'multiselect', - name: 'value', - message: `Select files to be pushed`, - choices: [{ title: 'All Files', value: '.' }, ...fileChoices] - }); - if (files.length > 1 && files.includes('.')) { - files = ['.']; - } - gitAddFiles = files; - } else { - const files = await input('Type files to be pushed'); - gitAddFiles = [files]; - } - - const commitMessage = await input('Type git commit message', undefined, 3); - - const currentBranch = await getCurrentBranchName(); - const branchName = await input('Type branch name you want to push', currentBranch); - - log('Choices you made:', 'yellow'); - - log('Version:', 'magenta'); - log(indent(newVersion), 'blue'); - - log('Files:', 'magenta'); - for (const file of gitAddFiles) { - if (file === '.') log(indent('All Files'), 'blue'); - else log(indent(file), 'blue'); - } - - log('Commit Message:', 'magenta'); - log(indent(commitMessage), 'blue'); - - log('Branch:', 'magenta'); - log(indent(branchName), 'blue'); - - const willBePublished = await ask('Publish to npm?'); - - const isSure = await ask('Are you sure to add these changes?'); - if (!isSure) { - return askForReset(); - } - - const newPkgJson = { ...pkgJSON, version: newVersion }; - await writeNewPackageJson(newPkgJson); - - const coloredBranchName = chalk.magentaBright('[', currentBranch + ']'); - log(`Pulling latest state of ${coloredBranchName}`, 'cyan'); - await sleep(300); - try { - await execute('git', ['pull', 'origin', currentBranch]); - } catch (error) { - log( - `Failed to pull ${coloredBranchName}, guessing the branch does not exist, skipped pulling`, - 'cyan' - ); - } - - log('Adding selected files to current commit', 'cyan'); - await sleep(300); - await execute('git', ['add', ...gitAddFiles]); - - log('Commiting changes', 'cyan'); - await sleep(300); - await execute('git', ['commit', '-m', commitMessage]); - - log(`Pushing changes to ${coloredBranchName}`, 'cyan'); - await sleep(300); - await execute('git', ['push', 'origin', branchName]); - - if (willBePublished) { - await publish(); - } -} - -async function publish(askForSure = false) { - if (askForSure) { - const isSure = await ask('Are you sure to publish?'); - if (!isSure) { - return askForReset(); - } - } - - log(`Publishing to npm`, 'cyan'); - await sleep(500); - await execute('npm', ['run', 'build']); - await sleep(300); - await execute('npm', ['publish']); -} - -async function ask(msg: string, initial = false): Promise { - const { value }: PromptVal = await prompt({ - type: 'toggle', - name: 'value', - message: msg, - active: 'yes', - inactive: 'no', - initial - }); - return value; -} - -async function input(msg: string, initial?: any, min?: number, max?: number) { - const { value }: PromptVal = await prompt({ - name: 'value', - message: msg, - type: 'text', - initial, - min, - max - }); - return value; -} - -async function askForReset() { - const willReset = await ask('Do you want to select again?'); - if (willReset) { - log('Restarting CLI', 'cyan'); - await sleep(500); - return main(); - } - process.exit(); -} - -main(); From 80127cc45cb90098b8cc3a9a926c3f5b665f3ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 11:46:40 +0300 Subject: [PATCH 03/11] Update version and changelog --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4349b94..5d08538 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.2 + +- `(Add)` [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) support for supporting browsers. + +
+ ## 0.4.1 - `(Fix)` Clicking Wowerlay's container causes all Wowerlays to close. diff --git a/package.json b/package.json index e3f0046..e27f234 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wowerlay", - "version": "0.4.1", + "version": "0.4.2", "main": "./dist/wowerlay.umd.js", "module": "./dist/wowerlay.es.js", "types": "./dist/types/lib.d.ts", From 0140fc865f4b2b8167358450f9f7806815a0c8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 11:53:16 +0300 Subject: [PATCH 04/11] Use px functions for position styles --- src/components/WowerlayRenderer.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/WowerlayRenderer.tsx b/src/components/WowerlayRenderer.tsx index 956a58a..9e22110 100644 --- a/src/components/WowerlayRenderer.tsx +++ b/src/components/WowerlayRenderer.tsx @@ -27,6 +27,7 @@ import { cWowerlay, sWowerlayX, sWowerlayY, scrollbarGap } from '../consts'; import { computed, defineComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { WowerlayProps } from './Wowerlay'; +import { px } from '../../demo/helpers/css'; import { useWowerlayContext } from '../plugin/index'; import { wowerlayBaseProps } from './WowerlayReusables'; @@ -107,8 +108,8 @@ export const WowerlayRenderer = defineComponent({ const alignment = computed(() => props.position.split('-')[0] as Alignment); const positionStyle = computed>(() => ({ - [sWowerlayY]: posY.value + 'px', - [sWowerlayX]: posX.value + 'px' + [sWowerlayX]: px(posX.value), + [sWowerlayY]: px(posY.value) })); const handleClick = (e: MouseEvent) => emit('click', e); From fb8e996c927b98eec3043317db462fcc3afbffe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 11:53:23 +0300 Subject: [PATCH 05/11] Add anchor element style --- demo/demo.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/demo/demo.scss b/demo/demo.scss index 1191580..667b280 100644 --- a/demo/demo.scss +++ b/demo/demo.scss @@ -155,6 +155,16 @@ select { } } +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; From 0cf393db85a3f45d780aa100046248f06c0cba70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 11:53:46 +0300 Subject: [PATCH 06/11] Add css helpers and resizeObserver demo --- demo/demos/dynamicBounds.tsx | 123 +++++++++++++++++++++++++++++++++++ demo/helpers/css.ts | 2 + demo/helpers/index.ts | 2 +- 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 demo/demos/dynamicBounds.tsx create mode 100644 demo/helpers/css.ts diff --git a/demo/demos/dynamicBounds.tsx b/demo/demos/dynamicBounds.tsx new file mode 100644 index 0000000..e3ed6b9 --- /dev/null +++ b/demo/demos/dynamicBounds.tsx @@ -0,0 +1,123 @@ +import { CSSProperties, defineComponent, ref, watch } from 'vue'; +import { defineDemo, html } from '../helpers'; +import { percent, px } from '../helpers/css'; + +import { Wowerlay } from '../../src/lib'; + +const fruits = ['Banana', 'Apple', 'Strawberry', 'Orange', 'Peach', 'Pear', 'Apricot']; +const searchFruit = (name: string) => { + return fruits.filter((fruitName) => { + return fruitName.trim().toLowerCase().includes(name.toLowerCase()); + }); +}; + +const sFruitItem: CSSProperties = { + width: percent(100), + padding: px(5) +}; + +const sFruitInput: CSSProperties = { + padding: px(5), + marginBottom: px(5) +}; + +const Component = defineComponent({ + name: 'PopoverFollow', + setup() { + const targetEl = ref(); + const isOpen = ref(false); + const fruitQuery = ref(''); + const input = ref(); + + const handleVisibleChange = (state: boolean) => (isOpen.value = state); + const toggleVisible = () => (isOpen.value = !isOpen.value); + + watch( + isOpen, + () => { + input.value?.focus(); + }, + { flush: 'post' } + ); + + return { + isOpen, + targetEl, + fruitQuery, + input, + handleVisibleChange, + toggleVisible + }; + }, + render() { + return ( + <> + + This only works if your browser supports{' '} + + ResizeObserver + + + +
+
+ + + + ); + } +}); + +export const Demo = defineDemo({ + name: 'Dynamic Bounds', + component: Component, + template: html` + + `, + script: html` + + ` +}); diff --git a/demo/helpers/css.ts b/demo/helpers/css.ts new file mode 100644 index 0000000..75881bc --- /dev/null +++ b/demo/helpers/css.ts @@ -0,0 +1,2 @@ +export const px = (value: T): `${T}px` => `${value}px`; +export const percent = (value: T): `${T}%` => `${value}%`; diff --git a/demo/helpers/index.ts b/demo/helpers/index.ts index db77d4a..58fbde4 100644 --- a/demo/helpers/index.ts +++ b/demo/helpers/index.ts @@ -9,7 +9,7 @@ export interface IDemo { const removeBeginningIndent = (code: string) => { // 4 spaces always thanks to prettier - return code.replace(/\n /g, '\n'); + return code.replace(/\n\s{4}/g, '\n'); }; export const defineDemo = (demo: IDemo) => { From 0734c7bcdcccc476ed027e4191f4fe1ba427d41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 12:00:16 +0300 Subject: [PATCH 07/11] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d08538..61eaa0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ - `(Add)` [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) support for supporting browsers. +### Demo + +- `(Add)` Dynamic Bounds sample. +
## 0.4.1 From 36890682258c0c1a0d72cd8552a5c248c62f2d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 14:21:37 +0300 Subject: [PATCH 08/11] Optimize visibility condition --- src/components/Wowerlay.tsx | 8 ++++++-- src/components/WowerlayRenderer.tsx | 22 ++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/components/Wowerlay.tsx b/src/components/Wowerlay.tsx index a7f330b..09859f8 100644 --- a/src/components/Wowerlay.tsx +++ b/src/components/Wowerlay.tsx @@ -3,6 +3,7 @@ import { PropType, Teleport, Transition, + computed, defineComponent, inject, onBeforeUnmount, @@ -15,6 +16,7 @@ import { WowerlayBaseProps, wowerlayBaseProps } from './WowerlayReusables'; import { cWowerlayAnimEnter, cWowerlayAnimLeave, cWowerlayBackground } from '../consts'; import { WowerlayRenderer } from './WowerlayRenderer'; +import { isElement } from '../utils'; import { useWowerlayContext } from '../plugin'; export interface WowerlayProps extends WowerlayBaseProps { @@ -51,6 +53,7 @@ export const Wowerlay = defineComponent({ const childrenWowerlayHooks = reactive([]) as Function[]; const canClose = ref(false); + const isVisible = computed(() => isElement(props.target) && props.visible); const closeChildWowerlays = () => { childrenWowerlayHooks.forEach((v) => v()); @@ -102,6 +105,7 @@ export const Wowerlay = defineComponent({ return { canClose, + isVisible, handleWowerlayClick, handleContainerClick }; @@ -112,13 +116,13 @@ export const Wowerlay = defineComponent({
{/*Todo: Add user made animation support.*/} - {this.visible && ( + {this.isVisible && ( - {this.$slots.default?.()} - - ) + + {this.$slots.default?.()} + ); } }); From 88f5fdfa30e4f5d89d8d1171b2fa264de488b8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 14:32:04 +0300 Subject: [PATCH 09/11] Use immediate instead of new frame --- src/components/Wowerlay.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Wowerlay.tsx b/src/components/Wowerlay.tsx index 09859f8..23b6928 100644 --- a/src/components/Wowerlay.tsx +++ b/src/components/Wowerlay.tsx @@ -88,12 +88,12 @@ export const Wowerlay = defineComponent({ () => props.visible, (state) => { if (state) { - requestAnimationFrame(() => { + setTimeout(() => { canClose.value = true; - }); - return; + }, 0); + } else { + canClose.value = false; } - canClose.value = false; } ); From 2da52a587f9a9601b0b3e709a429a08c129b2a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Mon, 17 Jan 2022 16:09:21 +0300 Subject: [PATCH 10/11] Format code --- src/components/Wowerlay.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Wowerlay.tsx b/src/components/Wowerlay.tsx index 23b6928..8c1c5c4 100644 --- a/src/components/Wowerlay.tsx +++ b/src/components/Wowerlay.tsx @@ -88,9 +88,7 @@ export const Wowerlay = defineComponent({ () => props.visible, (state) => { if (state) { - setTimeout(() => { - canClose.value = true; - }, 0); + setTimeout(() => (canClose.value = true), 0); } else { canClose.value = false; } From c57d43db614e23fcdfedf8ba6449d2f261fd7041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Yaz=C4=B1c=C4=B1?= Date: Wed, 19 Jan 2022 10:04:56 +0300 Subject: [PATCH 11/11] Remove css helpers --- demo/demos/dynamicBounds.tsx | 9 ++++----- demo/helpers/css.ts | 2 -- src/components/WowerlayRenderer.tsx | 5 ++--- 3 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 demo/helpers/css.ts diff --git a/demo/demos/dynamicBounds.tsx b/demo/demos/dynamicBounds.tsx index e3ed6b9..806f4ed 100644 --- a/demo/demos/dynamicBounds.tsx +++ b/demo/demos/dynamicBounds.tsx @@ -1,6 +1,5 @@ import { CSSProperties, defineComponent, ref, watch } from 'vue'; import { defineDemo, html } from '../helpers'; -import { percent, px } from '../helpers/css'; import { Wowerlay } from '../../src/lib'; @@ -12,13 +11,13 @@ const searchFruit = (name: string) => { }; const sFruitItem: CSSProperties = { - width: percent(100), - padding: px(5) + width: '100%', + padding: '5px' }; const sFruitInput: CSSProperties = { - padding: px(5), - marginBottom: px(5) + padding: '5px', + marginBottom: '5px' }; const Component = defineComponent({ diff --git a/demo/helpers/css.ts b/demo/helpers/css.ts deleted file mode 100644 index 75881bc..0000000 --- a/demo/helpers/css.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const px = (value: T): `${T}px` => `${value}px`; -export const percent = (value: T): `${T}%` => `${value}%`; diff --git a/src/components/WowerlayRenderer.tsx b/src/components/WowerlayRenderer.tsx index baf96e4..8d5621d 100644 --- a/src/components/WowerlayRenderer.tsx +++ b/src/components/WowerlayRenderer.tsx @@ -27,7 +27,6 @@ import { cWowerlay, sWowerlayX, sWowerlayY, scrollbarGap } from '../consts'; import { computed, defineComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { WowerlayProps } from './Wowerlay'; -import { px } from '../../demo/helpers/css'; import { useWowerlayContext } from '../plugin/index'; import { wowerlayBaseProps } from './WowerlayReusables'; @@ -108,8 +107,8 @@ export const WowerlayRenderer = defineComponent({ const alignment = computed(() => props.position.split('-')[0] as Alignment); const positionStyle = computed>(() => ({ - [sWowerlayX]: px(posX.value), - [sWowerlayY]: px(posY.value) + [sWowerlayX]: `${posX.value}px`, + [sWowerlayY]: `${posY.value}px` })); const handleClick = (e: MouseEvent) => emit('click', e);