Zum Inhalt

src/ui/InteractionMatrixGrid.tsx

import { type Component, For, Index } from 'solid-js';
import type { InteractionMatrix } from '~/engine/types';
import { MatrixCell } from './MatrixCell';

interface Props {
  matrix: InteractionMatrix;
  colors: readonly [string, string, string]; // CSS colour per species
  onChange: (row: number, col: number, value: number) => void;
}

const Dot: Component<{ color: string }> = (p) => (
  <span
    style={{
      width: '8px',
      height: '8px',
      'border-radius': '50%',
      background: p.color,
      'box-shadow': `0 0 6px ${p.color}`,
      display: 'inline-block',
    }}
  />
);

export const InteractionMatrixGrid: Component<Props> = (props) => {
  return (
    <div
      style={{
        display: 'grid',
        'grid-template-columns': '46px 1fr 1fr 1fr',
        gap: '4px',
        'align-items': 'center',
      }}
    >
      {/* header row: corner + one tinted dot per channel */}
      <span />
      <For each={[0, 1, 2]}>
        {(c) => (
          <div style={{ display: 'flex', 'justify-content': 'center' }}>
            <Dot color={props.colors[c] ?? ''} />
          </div>
        )}
      </For>

      {/* one row per sensing species */}
      <Index each={props.matrix}>
        {(row, r) => (
          <>
            <div style={{ display: 'flex', 'justify-content': 'flex-end', 'padding-right': '4px' }}>
              <Dot color={props.colors[r] ?? ''} />
            </div>
            <For each={[0, 1, 2]}>
              {(c) => (
                <MatrixCell
                  value={row()[c] ?? 0}
                  tint={props.colors[r] ?? ''}
                  onChange={(v) => props.onChange(r, c, v)}
                />
              )}
            </For>
          </>
        )}
      </Index>
    </div>
  );
};