wip tailwind

This commit is contained in:
Viktor Rådberg
2024-01-07 19:02:07 +01:00
parent 1013914cdf
commit 3cd982c643
11 changed files with 210 additions and 410 deletions

View File

@@ -5,40 +5,44 @@ import { Player, Rotation } from '../../Types/Player';
import { OutlinedText } from '../Misc/OutlinedText'; import { OutlinedText } from '../Misc/OutlinedText';
import { TwcComponentProps, twc } from 'react-twc'; import { TwcComponentProps, twc } from 'react-twc';
type RotationDivProps = TwcComponentProps<'div'> & { export type RotationDivProps = TwcComponentProps<'div'> & {
$rotation?: number; $rotation?: number;
}; };
type RotationButtonProps = TwcComponentProps<'button'> & { export type RotationSpanProps = TwcComponentProps<'span'> & {
$rotation?: number;
};
export type RotationButtonProps = TwcComponentProps<'button'> & {
$rotation?: number; $rotation?: number;
}; };
const CommanderDamageContainer = twc.div<RotationDivProps>((props) => [ const CommanderDamageContainer = twc.div<RotationDivProps>((props) => [
'flex flex-row flex-grow w-full', 'flex flex-grow',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'flex-col' ? 'flex-col'
: '', : 'flex-row',
]); ]);
const CommanderDamageButton = twc.button<RotationButtonProps>((props) => [ const CommanderDamageButton = twc.button<RotationButtonProps>((props) => [
'flex flex-grow border-none h-[10vmin] w-1/2 outline-none cursor-pointer m-0 p-0', 'flex flex-grow border-none outline-none cursor-pointer m-0 p-0 webkit-user-select-none',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'w-[6vmax] h-auto' ? 'w-[6vmax] h-auto'
: '', : 'h-[10vmin] w-1/2',
]); ]);
const CommanderDamageTextContainer = twc.div<RotationDivProps>((props) => [ const CommanderDamageTextContainer = twc.div<RotationDivProps>((props) => [
'relative top-1/2 left-1/2 tabular-nums pointer-events-none select-none', 'relative top-1/2 left-1/2 tabular-nums pointer-events-none select-none webkit-user-select-none',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'rotate-[270deg]' ? 'rotate-[270deg]'
: '', : '',
]); ]);
const PartnerDamageSeperator = twc.div<RotationDivProps>((props) => [ const PartnerDamageSeperator = twc.div<RotationDivProps>((props) => [
'w-px bg-black', 'bg-black',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'w-[5.999vmax] h-px' ? 'w-full h-px'
: '', : 'w-px',
]); ]);
type CommanderDamageButtonComponentProps = { type CommanderDamageButtonComponentProps = {

View File

@@ -1,60 +1,45 @@
import { ReactNode, useRef, useState } from 'react'; import { ReactNode, useRef, useState } from 'react';
import styled from 'styled-components';
import { css } from 'styled-components';
import { decrementTimeoutMs } from '../../Data/constants'; import { decrementTimeoutMs } from '../../Data/constants';
import { CounterType, Rotation } from '../../Types/Player'; import { CounterType, Rotation } from '../../Types/Player';
import { OutlinedText } from '../Misc/OutlinedText'; import { OutlinedText } from '../Misc/OutlinedText';
import { twc } from 'react-twc';
import { RotationDivProps } from './CommanderDamage';
const ExtraCounterContainer = styled.div` const ExtraCounterContainer = twc.div`
display: flex; flex
justify-content: center; justify-center
align-items: center; items-center
pointer-events: all; pointer-events-all
flex-grow: 1; flex-grow
`; `;
export const StyledExtraCounterButton = styled.button` const StyledExtraCounterButton = twc.button`
display: flex; flex
justify-content: center; justify-center
align-items: center; items-center
position: relative; relative
flex-grow: 1; flex-grow
border: none; border-none
outline: none; outline-none
cursor: pointer; cursor-pointer
background-color: transparent; bg-transparent
user-select: none; select-none
-webkit-touch-callout: none; h-full
-webkit-tap-highlight-color: transparent; webkit-user-select-none
-moz-user-select: -moz-none; `;
-webkit-user-select: none;
-ms-user-select: none;
height: 100%;
`;
const IconContainer = styled.div<{ const IconContainer = twc.div<RotationDivProps>((props) => [
$rotation: number; 'w-auto',
}>` props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
width: auto; ? 'rotate-[-90deg]'
: '',
]);
${(props) => { const TextContainer = twc.div`
if ( absolute
props.$rotation === Rotation.SideFlipped || top-1/2
props.$rotation === Rotation.Side left-1/2
) { `;
return css`
rotate: -90deg;
`;
}
}}
`;
const TextContainer = styled.div`
position: absolute;
translate: -50%;
top: 50%;
left: 50%;
`;
type ExtraCounterProps = { type ExtraCounterProps = {
Icon: ReactNode; Icon: ReactNode;

View File

@@ -1,64 +1,43 @@
import { useRef, useState } from 'react'; import { useRef, useState } from 'react';
import styled from 'styled-components';
import { css } from 'styled-components';
import { lifeLongPressMultiplier } from '../../Data/constants'; import { lifeLongPressMultiplier } from '../../Data/constants';
import { TwcComponentProps, twc } from 'react-twc';
import { Rotation } from '../../Types/Player'; import { Rotation } from '../../Types/Player';
export const StyledLifeCounterButton = styled.button` type RotationButtonProps = TwcComponentProps<'div'> & {
width: 100%;
height: 100%;
color: rgba(0, 0, 0, 0.4);
font-weight: 600;
background-color: transparent;
border: none;
outline: none;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
`;
const TextContainer = styled.div<{
$align?: string; $align?: string;
$rotation: number; $rotation?: number;
}>` };
position: relative;
${(props) => { const StyledLifeCounterButton = twc.button`
if ( h-full
props.$rotation === Rotation.SideFlipped || w-full
props.$rotation === Rotation.Side flex
) { text-lifeCounter-text
if (props.$align === 'right') { font-semibold
return css` bg-transparent
rotate: -90deg; border-none
bottom: 25%; outline-none
top: auto; cursor-pointer
`; justify-center
} items-center
return css` select-none
rotate: -90deg; webkit-user-select-none
top: 25%; `;
`;
}
if (props.$align === 'right') { const TextContainer = twc.div<RotationButtonProps>((props) => [
return css` 'relative',
left: 25%; props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
`; ? props.$align === 'right'
} ? '-rotate-90 bottom-1/4 top-auto'
return css` : '-rotate-90 top-1/4'
right: 25%; : 'top-auto',
`; props.$rotation === Rotation.Flipped || props.$rotation === Rotation.Normal
}} ? props.$align === 'right'
`; ? 'left-1/4'
: 'right-1/4'
: '',
]);
type LifeCounterButtonProps = { type LifeCounterButtonProps = {
lifeTotal: number; lifeTotal: number;

View File

@@ -1,43 +1,17 @@
import styled, { css } from 'styled-components'; import { twc } from 'react-twc';
import { Skull } from '../../Icons/generated'; import { Skull } from '../../Icons/generated';
import { Rotation } from '../../Types/Player'; import { Rotation } from '../../Types/Player';
import { RotationDivProps } from './CommanderDamage';
export const LoseButton = styled.button<{ $rotation: Rotation }>` const LoseButton = twc.div<RotationDivProps>((props) => [
position: absolute; 'absolute flex-grow border-none outline-none cursor-pointer bg-interface-loseButton-background rounded-lg select-none z-[1] webkit-user-select-none',
flex-grow: 1;
border: none;
outline: none;
cursor: pointer;
top: 25%;
right: 15%;
background-color: #43434380;
border-radius: 8px;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
user-select: none;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
z-index: 1;
${(props) => { props.$rotation === Rotation.SideFlipped
if (props.$rotation === Rotation.SideFlipped) { ? `right-auto top-[15%] left-[27%] rotate-[${props.$rotation}deg]`
return css` : props.$rotation === Rotation.Side
right: auto; ? `right-auto top-[15%] left-[27%] rotate-[${props.$rotation - 180}deg]`
top: 15%; : 'right-[15%] top-1/4',
left: 27%; ]);
rotate: ${props.$rotation}deg;
`;
} else if (props.$rotation === Rotation.Side) {
return css`
right: auto;
top: 15%;
left: 27%;
rotate: ${props.$rotation - 180}deg;
`;
}
}}
`;
type LoseButtonProps = { type LoseButtonProps = {
onClick: () => void; onClick: () => void;

View File

@@ -1,37 +1,14 @@
import styled from 'styled-components'; import { twc } from 'react-twc';
import { css } from 'styled-components';
import { Rotation } from '../../Types/Player';
import { Cog } from '../../Icons/generated'; import { Cog } from '../../Icons/generated';
import { Rotation } from '../../Types/Player';
import { RotationButtonProps } from './CommanderDamage';
export const StyledSettingsButton = styled.button<{ $rotation: Rotation }>` const StyledSettingsButton = twc.button<RotationButtonProps>((props) => [
position: absolute; 'absolute flex-grow border-none outline-none cursor-pointer bg-transparent z-[1] select-none webkit-user-select-none',
flex-grow: 1; props.$rotation === Rotation.Side || props.$rotation === Rotation.SideFlipped
border: none; ? `right-auto top-[1vmax] left-[27%]`
outline: none; : 'top-1/4 right-[1vmax]',
cursor: pointer; ]);
top: 25%;
right: 1vmax;
background-color: transparent;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
z-index: 1;
${(props) => {
if (
props.$rotation === Rotation.Side ||
props.$rotation === Rotation.SideFlipped
) {
return css`
right: auto;
top: 1vmax;
left: 27%;
`;
}
}}
`;
type SettingsButtonProps = { type SettingsButtonProps = {
onClick: () => void; onClick: () => void;

View File

@@ -1,27 +1,13 @@
import { twc } from 'react-twc';
import { Player, Rotation } from '../../Types/Player'; import { Player, Rotation } from '../../Types/Player';
import styled from 'styled-components'; import { CommanderDamage, RotationDivProps } from '../Buttons/CommanderDamage';
import { css } from 'styled-components';
import { CommanderDamage } from '../Buttons/CommanderDamage';
const CommanderDamageGrid = styled.div<{ $rotation: number }>` const CommanderDamageGrid = twc.div<RotationDivProps>((props) => [
display: flex; 'flex flex-grow',
flex-direction: row; props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
flex-grow: 1; ? 'flex-col h-full w-auto'
width: 100%; : 'flex-row w-full',
]);
${(props) => {
if (
props.$rotation === Rotation.SideFlipped ||
props.$rotation === Rotation.Side
) {
return css`
flex-direction: column;
height: 100%;
width: auto;
`;
}
}}
`;
type CommanderDamageBarProps = { type CommanderDamageBarProps = {
opponents: Player[]; opponents: Player[];

View File

@@ -1,59 +0,0 @@
import styled from 'styled-components';
import { usePlayers } from '../../Hooks/usePlayers';
import LifeCounter from '../LifeCounter/LifeCounter';
export const CountersWrapper = styled.div`
width: 100%;
height: 100%;
background-color: black;
`;
export const CountersGrid = styled.div<{ $gridTemplateAreas: string }>`
display: grid;
gap: 4px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
height: 100%;
grid-template-areas: ${({ $gridTemplateAreas }) => $gridTemplateAreas};
`;
export const GridItemContainer = styled.div<{
$gridArea: string;
}>`
display: flex;
justify-content: center;
align-items: center;
grid-area: ${(props) => props.$gridArea};
`;
type CountersProps = {
gridAreas: string;
};
const Counters = ({ gridAreas }: CountersProps) => {
const { players } = usePlayers();
return (
<CountersWrapper>
<CountersGrid $gridTemplateAreas={gridAreas}>
{players.map((player) => {
return (
<GridItemContainer
key={player.index}
$gridArea={`player${player.index}`}
>
<LifeCounter
player={player}
opponents={players.filter(
(opponent) => opponent.index !== player.index
)}
/>
</GridItemContainer>
);
})}
</CountersGrid>
</CountersWrapper>
);
};
export default Counters;

View File

@@ -1,8 +1,5 @@
import { CounterType, Player } from '../../Types/Player'; import { twc } from 'react-twc';
import ExtraCounter from '../Buttons/ExtraCounter'; import { usePlayers } from '../../Hooks/usePlayers';
import styled from 'styled-components';
import { css } from 'styled-components';
import { Rotation } from '../../Types/Player';
import { import {
CommanderTax, CommanderTax,
Energy, Energy,
@@ -10,49 +7,23 @@ import {
PartnerTax, PartnerTax,
Poison, Poison,
} from '../../Icons/generated'; } from '../../Icons/generated';
import { usePlayers } from '../../Hooks/usePlayers'; import { CounterType, Player, Rotation } from '../../Types/Player';
import { RotationDivProps } from '../Buttons/CommanderDamage';
import ExtraCounter from '../Buttons/ExtraCounter';
const Container = styled.div<{ $rotation: Rotation }>` const Container = twc.div<RotationDivProps>((props) => [
width: 100%; 'flex',
height: 20vmin; props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
display: flex; ? 'h-full w-[8vmax]'
: 'h-[20vmin] w-full',
]);
${(props) => { export const ExtraCountersGrid = twc.div<RotationDivProps>((props) => [
if ( 'flex absolute flex-row flex-grow pointer-events-none',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
props.$rotation === Rotation.Side ? 'flex-col-reverse h-full w-auto bottom-auto'
) { : 'w-full bottom-0',
return css` ]);
height: 100%;
width: 9.3vmax;
`;
}
}}
`;
export const ExtraCountersGrid = styled.div<{ $rotation: Rotation }>`
display: flex;
position: absolute;
width: 100%;
flex-direction: row;
flex-grow: 1;
bottom: 0;
pointer-events: none;
${(props) => {
if (
props.$rotation === Rotation.SideFlipped ||
props.$rotation === Rotation.Side
) {
return css`
flex-direction: column-reverse;
height: 100%;
width: auto;
bottom: auto;
`;
}
}}
`;
type ExtraCountersBarProps = { type ExtraCountersBarProps = {
player: Player; player: Player;

View File

@@ -1,115 +1,43 @@
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import styled, { css, keyframes } from 'styled-components'; import { twc } from 'react-twc';
import { Player, Rotation } from '../../Types/Player'; import { Player, Rotation } from '../../Types/Player';
import {
RotationDivProps,
RotationSpanProps,
} from '../Buttons/CommanderDamage';
import LifeCounterButton from '../Buttons/LifeCounterButton'; import LifeCounterButton from '../Buttons/LifeCounterButton';
import { OutlinedText } from '../Misc/OutlinedText'; import { OutlinedText } from '../Misc/OutlinedText';
const LifeCountainer = styled.div<{ const LifeCountainer = twc.div<RotationDivProps>((props) => [
$rotation: Rotation; 'flex flex-grow relative w-full h-full justify-between items-center',
}>` props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
position: relative; ? 'flex-col-reverse'
display: flex; : 'flex-row',
flex-direction: row; ]);
flex-grow: 1;
width: 100%;
height: 100%;
justify-content: space-between;
align-items: center;
${(props) => { const LifeCounterTextContainer = twc.div<RotationDivProps>((props) => [
if ( 'absolute m-0 p-0 pointer-events-none select-none webkit-user-select-none',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
props.$rotation === Rotation.Side ? 'w-full h-2/3'
) { : 'w-2/3 h-full',
return css` ]);
flex-direction: column-reverse;
`; const TextWrapper = twc.div`
} flex
}} absolute
justify-center
items-center
w-full
h-full
z-[-1]
`; `;
const LifeCounterTextContainer = styled.div<{ const RecentDifference = twc.div<RotationSpanProps>((props) => [
$rotation: Rotation; 'absolute min-w-[20vmin] drop-shadow-none text-center bg-interface-recentDifference-background tabular-nums rounded-full p-[6px 12px] text-[8vmin] text-interface-recentDifference-text animate-fadeOut',
}>` props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
position: absolute; ? 'top-1/3 translate-x-1/4 translate-y-1/2 rotate-[270deg]'
width: 60%; : 'top-1/4 left-[50%] -translate-x-1/2',
height: 100%; ]);
margin: 0;
padding: 0;
pointer-events: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
user-select: none;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
${(props) => {
if (
props.$rotation === Rotation.SideFlipped ||
props.$rotation === Rotation.Side
) {
return css`
width: 100%;
height: 60%;
`;
}
}}
`;
const TextWrapper = styled.div`
display: flex;
position: absolute;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
z-index: -1;
`;
const fadeOut = keyframes`
0% {
opacity: 1;
}
33% {
opacity: 0.6;
}
100% {
opacity: 0;
}
`;
export const RecentDifference = styled.span<{ $rotation: Rotation }>`
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 15vmin;
text-shadow: none;
text-align: center;
background-color: rgba(255, 255, 255, 0.6);
font-variant-numeric: tabular-nums;
border-radius: 10vmin;
padding: 5px 10px;
font-size: 8vmin;
color: #333333;
animation: ${fadeOut} 3s 1s ease-out forwards;
${(props) => {
if (
props.$rotation === Rotation.SideFlipped ||
props.$rotation === Rotation.Side
) {
return css`
top: 27%;
left: 30%;
transform: translate(-50%, -50%);
rotate: 270deg;
`;
}
}}
`;
type HealthProps = { type HealthProps = {
player: Player; player: Player;

View File

@@ -20,3 +20,17 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace; monospace;
} }
@layer utilities {
.pointer-events-all {
pointer-events: all;
}
.webkit-user-select-none {
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
}
}

View File

@@ -59,8 +59,49 @@ export default {
white: '#F9FFE3', white: '#F9FFE3',
black: '#000000', black: '#000000',
}, },
lifeCounter: {
text: 'rgba(0, 0, 0, 0.4)',
lostWrapper: '#00000070',
},
interface: {
loseButton: {
background: '#43434380',
},
recentDifference: {
background: 'rgba(255, 255, 255, 0.6);',
text: '#333333',
},
},
},
keyframes: {
fadeOut: {
'0%': {
opacity: '1',
},
'33%': {
opacity: '0.6',
},
'100%': {
opacity: '0',
},
},
},
animation: {
fadeOut: 'fadeOut 3s 1s ease-out forwards',
}, },
}, },
}, },
plugins: [tailwindcssGridAreas], plugins: [tailwindcssGridAreas],
} satisfies Config; } satisfies Config;
// const fadeOut = keyframes`
// 0% {
// opacity: 1;
// }
// 33% {
// opacity: 0.6;
// }
// 100% {
// opacity: 0;
// }
// `;