mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-03-21 21:29:20 +01:00
Beautify poll
This commit is contained in:
parent
c2ee8c55d3
commit
d2214c59be
2 changed files with 104 additions and 74 deletions
|
@ -843,34 +843,48 @@ a.card:is(:hover, :focus) {
|
||||||
.poll.read-only {
|
.poll.read-only {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.poll-options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 16px;
|
||||||
|
border: 1px solid var(--outline-color);
|
||||||
|
background-color: var(--bg-faded-color);
|
||||||
|
}
|
||||||
.poll-option {
|
.poll-option {
|
||||||
padding: 8px;
|
padding: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: var(--bg-faded-color);
|
|
||||||
background-image: linear-gradient(
|
|
||||||
to right,
|
|
||||||
var(--link-faded-color),
|
|
||||||
var(--link-faded-color) var(--percentage),
|
|
||||||
transparent var(--percentage),
|
|
||||||
transparent
|
|
||||||
);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
/* border-radius: 8px; */
|
|
||||||
border: 1px solid var(--outline-color);
|
|
||||||
border-bottom: 0;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-shadow: 0 1px var(--bg-blur-color);
|
position: relative;
|
||||||
}
|
}
|
||||||
.poll-option:first-child {
|
.poll-option:after {
|
||||||
border-top-left-radius: 8px;
|
content: '';
|
||||||
border-top-right-radius: 8px;
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--link-faded-color);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
mix-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
.poll-option:last-of-type {
|
.poll-option:first-child:after {
|
||||||
border-bottom: 1px solid var(--outline-color);
|
border-top-left-radius: 12px;
|
||||||
border-bottom-left-radius: 8px;
|
border-top-right-radius: 12px;
|
||||||
border-bottom-right-radius: 8px;
|
}
|
||||||
|
.poll-option:last-child:after {
|
||||||
|
border-bottom-left-radius: 12px;
|
||||||
|
border-bottom-right-radius: 12px;
|
||||||
|
}
|
||||||
|
.poll-option:hover:after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.poll-option.poll-result:after {
|
||||||
|
width: var(--percentage);
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.poll-label {
|
.poll-label {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -897,6 +911,9 @@ a.card:is(:hover, :focus) {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
.poll-option-title {
|
||||||
|
text-shadow: 0 1px var(--bg-color);
|
||||||
|
}
|
||||||
.poll-option-title .icon {
|
.poll-option-title .icon {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1309,15 +1309,22 @@ function Poll({
|
||||||
roundPrecision = 2;
|
roundPrecision = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [showResults, setShowResults] = useState(false);
|
||||||
|
const optionsHaveVoteCounts = options.every((o) => o.votesCount !== null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
lang={lang}
|
lang={lang}
|
||||||
class={`poll ${readOnly ? 'read-only' : ''} ${
|
class={`poll ${readOnly ? 'read-only' : ''} ${
|
||||||
uiState === 'loading' ? 'loading' : ''
|
uiState === 'loading' ? 'loading' : ''
|
||||||
}`}
|
}`}
|
||||||
|
onDblClick={() => {
|
||||||
|
setShowResults(!showResults);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{voted || expired ? (
|
{(showResults && optionsHaveVoteCounts) || voted || expired ? (
|
||||||
options.map((option, i) => {
|
<div class="poll-options">
|
||||||
|
{options.map((option, i) => {
|
||||||
const { title, votesCount: optionVotesCount } = option;
|
const { title, votesCount: optionVotesCount } = option;
|
||||||
const percentage = pollVotesCount
|
const percentage = pollVotesCount
|
||||||
? ((optionVotesCount / pollVotesCount) * 100).toFixed(
|
? ((optionVotesCount / pollVotesCount) * 100).toFixed(
|
||||||
|
@ -1327,11 +1334,14 @@ function Poll({
|
||||||
// check if current poll choice is the leading one
|
// check if current poll choice is the leading one
|
||||||
const isLeading =
|
const isLeading =
|
||||||
optionVotesCount > 0 &&
|
optionVotesCount > 0 &&
|
||||||
optionVotesCount === Math.max(...options.map((o) => o.votesCount));
|
optionVotesCount ===
|
||||||
|
Math.max(...options.map((o) => o.votesCount));
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${i}-${title}-${optionVotesCount}`}
|
key={`${i}-${title}-${optionVotesCount}`}
|
||||||
class={`poll-option ${isLeading ? 'poll-option-leading' : ''}`}
|
class={`poll-option poll-result ${
|
||||||
|
isLeading ? 'poll-option-leading' : ''
|
||||||
|
}`}
|
||||||
style={{
|
style={{
|
||||||
'--percentage': `${percentage}%`,
|
'--percentage': `${percentage}%`,
|
||||||
}}
|
}}
|
||||||
|
@ -1355,7 +1365,8 @@ function Poll({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<form
|
<form
|
||||||
onSubmit={async (e) => {
|
onSubmit={async (e) => {
|
||||||
|
@ -1374,6 +1385,7 @@ function Poll({
|
||||||
setUIState('default');
|
setUIState('default');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<div class="poll-options">
|
||||||
{options.map((option, i) => {
|
{options.map((option, i) => {
|
||||||
const { title } = option;
|
const { title } = option;
|
||||||
return (
|
return (
|
||||||
|
@ -1391,6 +1403,7 @@ function Poll({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
</div>
|
||||||
{!readOnly && (
|
{!readOnly && (
|
||||||
<button
|
<button
|
||||||
class="poll-vote-button"
|
class="poll-vote-button"
|
||||||
|
|
Loading…
Reference in a new issue