Files
Dune/components/mixed-traitor-fields.tsx

54 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import type { GameView } from '@/game/engine';
import type { MixedActionExpression } from '@/game/mixed-action-question';
import {
MIXED_TRAITOR_MAX_DEPTH, MIXED_TRAITOR_MAX_LEAVES, parseTraitorActionClaim, type TraitorActionClaim,
} from '@/game/mixed-traitor-question';
import { MixedActionFields, mixedActionInputError, type MixedActionConfig } from './mixed-action-fields';
/** Question authors choose an original native declaration, never its private
* physical eligibility or the branch needed to honor the aggregate answer. */
const config: MixedActionConfig<TraitorActionClaim> = {
prefix: 'mixed-traitor',
legend: 'Mixed current-fact / this battle’s Traitor declaration',
actionLabel: 'Traitor declaration condition',
actionTiming: 'Traitor declaration · this revealed battle',
actionHelp: <>Traitor conditions concern the respondent’s one original Reveal or decline declaration in this revealed battle,
including a native Harkonnen declaration for an ally. Current facts are snapshotted at the answer.
An unknown current fact uses the conservative declaration commitment that guarantees the whole answer;
if no such answer is possible, the answer is I don’t know. A constant whole answer needs no declaration commitment.
The original declaration fulfills a remaining commitment before a later Karama or betrayal response can prevent its effect.
Native voter eligibility and physical Traitor rules still apply.</>,
fallbackError: 'Choose a current fact and a Traitor declaration condition.',
maxLeaves: MIXED_TRAITOR_MAX_LEAVES,
maxDepth: MIXED_TRAITOR_MAX_DEPTH,
newAction: () => ({ call: true }),
parseAction: value => parseTraitorActionClaim(value),
renderAction: ({ value, id, disabled, onChange }) => <>
<label htmlFor={`${id}-call`}>Traitor declaration</label>
<select id={`${id}-call`} value={value.call ? 'reveal' : 'decline'} disabled={disabled}
aria-invalid={typeof value.call !== 'boolean'} onChange={event => {
if (event.currentTarget.value === 'reveal') onChange({ call: true });
if (event.currentTarget.value === 'decline') onChange({ call: false });
}}>
<option value="reveal">Reveal traitor</option>
<option value="decline">Decline traitor</option>
</select>
</>,
};
export function mixedTraitorInputError(value: unknown, game: GameView, target: string): string | null {
return mixedActionInputError(value, game, target, config);
}
export function MixedTraitorFields(props: {
value: MixedActionExpression<TraitorActionClaim>;
game: GameView;
target: string;
disabled: boolean;
onChange: (expression: MixedActionExpression<TraitorActionClaim>) => void;
}) {
return MixedActionFields({ ...props, config });
}