# isComposing

> Predicate that returns true while an input method is composing — the guard that keeps Enter, Escape and the arrows with the IME's candidate window instead of your component.

Source: https://ngwr.dev/reference/utils/is-composing  
Kind: Util

## Usage

A Japanese or Chinese user reaches every character through a conversion. Between `compositionstart` and `compositionend` a candidate window is open, and Enter accepts a candidate, Escape cancels the reading back to kana, and the arrows walk the candidate list. A handler that acts on those keys anyway takes them from the input method mid-word.

```angular-ts
import { isComposing } from 'ngwr/utils';

// The first line of every keydown handler over a field that accepts typed text.
onKeydown(event: KeyboardEvent): void {
  if (isComposing(event)) return;

  switch (event.key) {
    case 'Enter': this.commit(); break;
    case 'Escape': this.close(); break;
  }
}
```

## Why ngwr provides this

`event.isComposing` alone is the guard everyone writes, and it has a hole. Safari fires `compositionend` before the `keydown` of the keystroke that commits a candidate, so the one press that most needs guarding arrives with the flag already false — carrying only the legacy `keyCode` of 229, the sentinel every engine sets on a key it handed to the input method.

```angular-ts
// Native — the standard flag, and it misses Safari.
if (event.isComposing) return;
// → Safari fires `compositionend` BEFORE the keydown of the Enter that accepts
//   a candidate, so that one arrives with isComposing === false and commits the
//   half-composed word anyway.

// ngwr — the flag plus the 229 sentinel every engine sets on an IME's key.
if (isComposing(event)) return;
```

## Knowing the state between events

This predicate is scoped to `keydown`. It does not answer “is a composition in progress” for an `input` or `blur` handler — on the committing keystroke the key flag and the composition state disagree by design. A component that needs the state between events tracks the `compositionstart` / `compositionend` pair, which is what `wr-mention` and `wr-input-otp` do.

```angular-ts
// `isComposing` answers "did the input method take this KEY". For "is a
// conversion open right now" — which is what an `input` or `blur` handler needs
// — track the pair instead: on the committing keystroke the two disagree.
@Component({
  host: {
    '(compositionstart)': 'composing = true',
    '(compositionend)': 'composing = false; onSettledInput()',
    '(input)': 'composing ? null : onSettledInput()',
  },
})
```

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `isComposing(event)` | True while an input method is composing, so the key belongs to the IME rather than to your handler. Return early on it in every keydown handler that reads Enter, Escape or an arrow over a field that accepts typed text. | `(e: KeyboardEvent) => boolean` | `—` |

## See also

- [Keyboard](https://ngwr.dev/guides/keyboard) — How chords, keycaps and key primitives fit together in one task.
- [hasModifier](https://ngwr.dev/reference/utils/has-modifier) — Skip the browser’s own chords before acting on a key.
- [isPrintableKey](https://ngwr.dev/reference/utils/is-printable-key) — Single printable characters, for type-to-search buffers.
