diff --git a/src/components/layout.scss b/src/components/layout.scss index f9b36fb3..a14762de 100644 --- a/src/components/layout.scss +++ b/src/components/layout.scss @@ -881,6 +881,7 @@ $call-names-cell-width-column: 190px; position: sticky; top: 0; left: 0; + z-index: 1; } th, @@ -921,10 +922,32 @@ $call-names-cell-width-column: 190px; flex-direction: column; justify-content: center; + position: relative; + + // コピーボタン + .icon { + @extend .m-1; + + visibility: hidden; + position: absolute; + height: 1rem; + width: 1rem; + top: 0; + right: 0; + + &.selected { + visibility: visible; + } + } + &:hover { // NOTE: ちらつくので border ではなく outline outline: 2px solid; border-radius: $radius; + + .icon { + visibility: visible; + } } } } @@ -939,7 +962,7 @@ $call-names-cell-width-column: 190px; // 左上のセル &.origin { width: $call-names-cell-width-column; - z-index: 1; + z-index: 2; border-right: $call-names-border; } diff --git a/src/pages/dormitory.tsx b/src/pages/dormitory.tsx index 1c5a13b2..872822dc 100644 --- a/src/pages/dormitory.tsx +++ b/src/pages/dormitory.tsx @@ -258,7 +258,7 @@ const Dormitory: React.FC = ({ setShowingHeader }) => {

関連コンテンツ

- ) + const [selectedCallName, setSelectedCallName] = useState() + const [showCopiedIcon, setShowCopiedIcon] = useState(false) + + const callNameInfo = callNameInfos[characterKey] + const characterInfo = characterInfos[characterKey] + const outlineStyle: CSSProperties = { + outlineColor: characterInfo.color, } - function getColumn(characterKey: CharacterKey): ReactElement { - const callNameInfo = callNameInfos[characterKey] - const characterInfo = characterInfos[characterKey] + useEffect(() => { + if (selectedCallName == undefined) return + + const timer = setTimeout(() => { + setShowCopiedIcon(false) + }, 1500) - const outlineStyle: CSSProperties = { - outlineColor: characterInfo.color, + return () => { + clearTimeout(timer) } + }, [showCopiedIcon, selectedCallName]) + + function copyToClipboard(event: MouseEvent): void { + const callName = event.currentTarget.innerText + + setSelectedCallName(callName) + navigator.clipboard.writeText(callName) + setShowCopiedIcon(true) + } + + function Cell({ + callName, + externalClassName, + }: { + callName: string + externalClassName?: string + }): ReactElement { + const isSelected = selectedCallName === callName && showCopiedIcon return ( - <> - {characterKeys.map(_characterKey => { - const callName = callNameInfo[_characterKey] - - return ( - -
- {(() => { - if (characterKey === _characterKey) { - return callNameInfo.me.map(part => ( -

- {part} -

- )) - } - - if (callName == undefined) { - return ( -

- ? -

- ) - } - - return callName.split("/").map(part => ( -

- {part} +

+ + + + {callName} +

+ ) + } + + return ( + <> + {characterKeys.map(_characterKey => { + const callName = callNameInfo[_characterKey] + + return ( + +
+ {(() => { + if (_characterKey === characterKey) { + return callNameInfo.me.map(part => ( + + )) + } + + if (callName == undefined) { + return ( +

+ ?

+ ) + } + + return callName + .split("/") + .map(part => ( + )) - })()} -
- - ) - })} - -
- {callNameInfo.you.map(part => ( -

- {part} -

- ))} -
- - + })()} +
+ + ) + })} + +
+ {callNameInfo.you.map(part => ( + + ))} +
+ + + ) +} + +export default function CallNamesPage() { + const { characterInfos } = useDetailedCharacterInfo() + const { characterKeys } = useContext(CharacterContext) + + function CharacterImage({ + characterKey, + }: { + characterKey: CharacterKey + }): ReactElement { + const characterInfo = characterInfos[characterKey] + return ( + {characterInfo.name} ) } @@ -138,7 +211,7 @@ export default function CallNamesPage() { return ( - {getCharacterImage(characterKey)} +

+ - {getCharacterImage(characterKey)} +

- {getColumn(characterKey)} + ) })}