From 7876f0d9a7c26bec499971404a0417c5062deb5c Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 22 Jan 2023 19:27:04 -0800 Subject: [PATCH] Add RadixPopover and refactor TranscendencePopover --- components/Popover/index.scss | 6 ++ components/Popover/index.tsx | 37 +++++++++ components/TranscendencePopover/index.scss | 15 ++-- components/TranscendencePopover/index.tsx | 84 ++++++++++++++----- components/TranscendenceStar/index.tsx | 4 +- components/UncapIndicator/index.tsx | 35 ++++---- package-lock.json | 93 ++++++++++++++++++++++ package.json | 1 + 8 files changed, 226 insertions(+), 49 deletions(-) create mode 100644 components/Popover/index.scss create mode 100644 components/Popover/index.tsx diff --git a/components/Popover/index.scss b/components/Popover/index.scss new file mode 100644 index 00000000..52440b41 --- /dev/null +++ b/components/Popover/index.scss @@ -0,0 +1,6 @@ +.Popover { + background: var(--dialog-bg); + border-radius: $card-corner; + border: 0.5px solid rgba(0, 0, 0, 0.18); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24); +} diff --git a/components/Popover/index.tsx b/components/Popover/index.tsx new file mode 100644 index 00000000..b38e4985 --- /dev/null +++ b/components/Popover/index.tsx @@ -0,0 +1,37 @@ +import React, { PropsWithChildren } from 'react' +import classnames from 'classnames' +import * as PopoverPrimitive from '@radix-ui/react-popover' + +import './index.scss' + +interface Props + extends React.DetailedHTMLProps< + React.DialogHTMLAttributes, + HTMLDivElement + > {} + +export const Popover = PopoverPrimitive.Root +export const PopoverAnchor = PopoverPrimitive.Anchor +export const PopoverTrigger = PopoverPrimitive.Trigger + +export const PopoverContent = React.forwardRef( + ({ children, ...props }: PropsWithChildren, forwardedRef) => { + const classes = classnames(props.className, { + Popover: true, + }) + + return ( + + + {children} + + + + ) + } +) diff --git a/components/TranscendencePopover/index.scss b/components/TranscendencePopover/index.scss index ce52370f..f92b6393 100644 --- a/components/TranscendencePopover/index.scss +++ b/components/TranscendencePopover/index.scss @@ -1,21 +1,16 @@ .Transcendence.Popover { align-items: center; - background: var(--dialog-bg); - border-radius: $card-corner; - border: 0.5px solid rgba(0, 0, 0, 0.18); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24); - display: none; flex-direction: column; gap: $unit-half; + display: flex; width: 80px; height: 80px; padding: $unit; justify-content: center; - position: absolute; - opacity: 0; - z-index: 31; - top: -32px; - right: -40px; + // position: absolute; + z-index: 32; + // top: -32px; + // right: -40px; &.open { opacity: 1; diff --git a/components/TranscendencePopover/index.tsx b/components/TranscendencePopover/index.tsx index 88647c8f..0b41ac92 100644 --- a/components/TranscendencePopover/index.tsx +++ b/components/TranscendencePopover/index.tsx @@ -1,8 +1,10 @@ -import React, { useEffect, useState } from 'react' +import React, { PropsWithChildren, useEffect, useState } from 'react' import { useTranslation } from 'next-i18next' import classNames from 'classnames' +import { Popover, PopoverAnchor, PopoverContent } from '~components/Popover' import TranscendenceStar from '~components/TranscendenceStar' + import './index.scss' interface Props @@ -10,7 +12,6 @@ interface Props React.DialogHTMLAttributes, HTMLDivElement > { - className?: string open: boolean stage: number onOpenChange?: (open: boolean) => void @@ -18,36 +19,71 @@ interface Props } const TranscendencePopover = ({ - className, + children, open: popoverOpen, stage, tabIndex, onOpenChange, sendValue, -}: Props) => { +}: PropsWithChildren) => { const { t } = useTranslation('common') const [open, setOpen] = useState(false) const [currentStage, setCurrentStage] = useState(0) + const popoverRef = React.createRef() + const classes = classNames({ Transcendence: true, - Popover: true, - open: open, }) const levelClasses = classNames({ Pending: stage != currentStage, }) + useEffect(() => { + const handleClickOutside = (event: Event) => { + const target = event.target instanceof Element ? event.target : null + + console.log('Handling click outside...?') + + console.log(popoverRef.current) + console.log(open) + + if ( + popoverRef.current && + target && + !popoverRef.current.contains(target) && + open && + onOpenChange + ) { + onOpenChange(false) + } + } + + document.addEventListener('click', handleClickOutside, true) + + return () => { + document.removeEventListener('click', handleClickOutside, true) + } + }, [onOpenChange]) + + useEffect(() => { + if (open) popoverRef.current?.focus() + }, []) + useEffect(() => { setCurrentStage(stage) }, [stage]) useEffect(() => { - console.log(`Setting popover state to ${popoverOpen}`) setOpen(popoverOpen) + + if (popoverOpen) { + console.log(popoverRef.current) + popoverRef.current?.focus() + } }, [popoverOpen]) function handleFragmentClicked(newStage: number) { @@ -59,28 +95,32 @@ const TranscendencePopover = ({ setCurrentStage(newStage) } - function handleKeyPress(event: React.KeyboardEvent) { + function handleKeyDown(event: React.KeyboardEvent) { console.log(`Key pressed, ${event.key}`) + console.log(window.event) if (event.key === 'Escape') { if (onOpenChange) onOpenChange(false) } } return ( -
- -

- {t('level')}  - {100 + 10 * currentStage} -

-
+ + {children} + + +

+ {t('level')}  + {100 + 10 * currentStage} +

+
+
) } diff --git a/components/TranscendenceStar/index.tsx b/components/TranscendenceStar/index.tsx index 9c32c571..8954d4b1 100644 --- a/components/TranscendenceStar/index.tsx +++ b/components/TranscendenceStar/index.tsx @@ -82,7 +82,7 @@ const TranscendenceStar = ({ } return ( -
  • {}} onMouseLeave={interactive ? handleMouseLeave : () => {}} @@ -106,7 +106,7 @@ const TranscendenceStar = ({ })} -
  • + ) } diff --git a/components/UncapIndicator/index.tsx b/components/UncapIndicator/index.tsx index f90a4d19..dc86836d 100644 --- a/components/UncapIndicator/index.tsx +++ b/components/UncapIndicator/index.tsx @@ -1,9 +1,9 @@ import React, { useState } from 'react' import UncapStar from '~components/UncapStar' +import TranscendencePopover from '~components/TranscendencePopover' import TranscendenceStar from '~components/TranscendenceStar' import './index.scss' -import TranscendencePopover from '~components/TranscendencePopover' interface Props { type: 'character' | 'weapon' | 'summon' @@ -76,7 +76,24 @@ const UncapIndicator = (props: Props) => { } const transcendence = (i: number) => { - return ( + return props.type === 'character' || props.type === 'summon' ? ( + + togglePopover(true)} + tabIndex={props.position * 7 + i + 1} + /> + + ) : ( { ) } - const transcendencePopover = () => { - return props.type === 'character' || props.type === 'summon' ? ( - - ) : ( - '' - ) - } + const transcendencePopover = () => {} return (
    diff --git a/package-lock.json b/package-lock.json index 520ded8a..2f4f81e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "@radix-ui/react-dialog": "^1.0.2", "@radix-ui/react-dropdown-menu": "^2.0.1", "@radix-ui/react-hover-card": "^1.0.2", + "@radix-ui/react-popover": "^1.0.3", "@radix-ui/react-select": "^1.1.2", "@radix-ui/react-switch": "^1.0.1", "@radix-ui/react-toast": "^1.1.2", @@ -2325,6 +2326,55 @@ "react-dom": "^16.8 || ^17.0 || ^18.0" } }, + "node_modules/@radix-ui/react-popover": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.3.tgz", + "integrity": "sha512-YwedSukfWsyJs3/yP3yXUq44k4/JBe3jqU63Z8v2i19qZZ3dsx32oma17ztgclWPNuqp3A+Xa9UiDlZHyVX8Vg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.1", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.1.0", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.0.tgz", + "integrity": "sha512-07U7jpI0dZcLRAxT7L9qs6HecSoPhDSJybF7mEGHJDBDv+ZoGCvIlva0s+WxMXwJEav+ckX3hAlXBtnHmuvlCQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz", @@ -8809,6 +8859,49 @@ "react-remove-scroll": "2.5.5" } }, + "@radix-ui/react-popover": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.3.tgz", + "integrity": "sha512-YwedSukfWsyJs3/yP3yXUq44k4/JBe3jqU63Z8v2i19qZZ3dsx32oma17ztgclWPNuqp3A+Xa9UiDlZHyVX8Vg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.1", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.1.0", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "dependencies": { + "@radix-ui/react-popper": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.0.tgz", + "integrity": "sha512-07U7jpI0dZcLRAxT7L9qs6HecSoPhDSJybF7mEGHJDBDv+ZoGCvIlva0s+WxMXwJEav+ckX3hAlXBtnHmuvlCQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + } + } + } + }, "@radix-ui/react-popper": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz", diff --git a/package.json b/package.json index 4771dae9..0d880a01 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@radix-ui/react-dialog": "^1.0.2", "@radix-ui/react-dropdown-menu": "^2.0.1", "@radix-ui/react-hover-card": "^1.0.2", + "@radix-ui/react-popover": "^1.0.3", "@radix-ui/react-select": "^1.1.2", "@radix-ui/react-switch": "^1.0.1", "@radix-ui/react-toast": "^1.1.2",