{"version":3,"file":"PillInputWidget.mjs","sources":["../../src/widgets/PillInputWidget.tsx"],"sourcesContent":["import { createErrors } from '@aokiapp/rjsf-mantine-theme';\nimport { Pill, PillsInput } from '@mantine/core';\nimport {\n  FormContextType,\n  RJSFSchema,\n  StrictRJSFSchema,\n  WidgetProps,\n  labelValue,\n  ariaDescribedByIds,\n} from '@rjsf/utils';\nimport { useCallback, useMemo, useState } from 'react';\n\n/**\n * The `PillInputWidget` is the special case of the array field where the user can enter a value and press enter to add\n * it to the array.\n * The schema of this widget must match the follwing criteria:\n * - type: array\n * - items: type: string\n * - uniqueItems: true\n */\nexport default function PillInputWidget<\n  T = any,\n  S extends StrictRJSFSchema = RJSFSchema,\n  F extends FormContextType = any,\n>({\n  id,\n  placeholder,\n  label,\n  hideLabel,\n  value,\n  required,\n  readonly,\n  disabled,\n  onChange: onChangeBase,\n  onChangeOverride,\n  autofocus,\n  rawErrors,\n  hideError,\n  schema,\n  options: { description, removeOnBackspace = false, punctuation = null },\n}: WidgetProps<T, S, F>) {\n  // check the schema criteria\n  if (\n    schema.type !== 'array' ||\n    typeof schema.items !== 'object' ||\n    Array.isArray(schema.items) ||\n    schema.items.type !== 'string'\n  ) {\n    throw new Error('The PillInputWidget is only compatible with a schema that is an array of unique strings');\n  }\n\n  // field-level controls start\n  const _value = useMemo(() => (Array.isArray(value) ? value : []), [value]);\n  const onChange = onChangeOverride || onChangeBase;\n  const onRemove = useCallback(\n    (i: number) => {\n      onChange(_value.filter((_, index) => index !== i));\n    },\n    [_value, onChange],\n  );\n\n  const onAdd = useCallback(\n    (value: string) => {\n      onChange([..._value, value]);\n    },\n    [_value, onChange],\n  );\n  // add multiple values at once\n  // I need this onAdd can be called within one render\n  const onBulkAdd = useCallback(\n    (values: string[]) => {\n      onChange([..._value, ...values]);\n    },\n    [_value, onChange],\n  );\n\n  const currentPills = _value.map((v, i) => (\n    <Pill\n      key={i}\n      withRemoveButton={!disabled && !readonly}\n      onRemove={() => {\n        onRemove(i);\n      }}\n    >\n      {v}\n    </Pill>\n  ));\n  // field-level controls end\n\n  // pill input start\n  const [tmpValue, setTmpValue] = useState('');\n  const handleChange = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      const v = e.target.value;\n      if (typeof punctuation === 'string' && punctuation.length) {\n        // split by punctuation\n        const split = v.split(punctuation);\n        // add all but the last one\n        onBulkAdd(split.slice(0, -1));\n        // set the last one as the tmp value\n        setTmpValue(split[split.length - 1]);\n      } else {\n        setTmpValue(v);\n      }\n    },\n    [onBulkAdd, punctuation],\n  );\n\n  // Japanese IME support\n  const [isComposing, setIsComposing] = useState(false);\n  const handleCompositionStart = useCallback(() => {\n    setIsComposing(true);\n  }, [setIsComposing]);\n  const handleCompositionEnd = useCallback(() => {\n    setIsComposing(false);\n  }, [setIsComposing]);\n\n  const handleBlur = useCallback(() => {\n    if (tmpValue) {\n      onAdd(tmpValue);\n      setTmpValue('');\n    }\n  }, [tmpValue, onAdd]);\n\n  const handleKeyDown = useCallback(\n    (e: React.KeyboardEvent<HTMLInputElement>) => {\n      // handle enter air shot\n      if (e.key === 'Enter' && !isComposing && tmpValue) {\n        e.preventDefault(); // without this, enter will trigger the form submit\n        onAdd(tmpValue);\n        setTmpValue('');\n      }\n      // handle backspace when empty\n      if (e.key === 'Backspace' && !tmpValue && _value.length > 0) {\n        e.preventDefault(); // without this, the last character also gets deleted\n        const last = _value[_value.length - 1];\n        onRemove(_value.length - 1);\n        if (!removeOnBackspace) {\n          setTmpValue(last);\n        }\n      }\n    },\n    [isComposing, tmpValue, _value, onAdd, onRemove, removeOnBackspace],\n  );\n  const pillInput = (\n    <PillsInput.Field\n      placeholder={placeholder}\n      id={id}\n      value={tmpValue}\n      onChange={handleChange}\n      onKeyDown={handleKeyDown}\n      onCompositionStart={handleCompositionStart}\n      onCompositionEnd={handleCompositionEnd}\n      autoFocus={autofocus}\n      disabled={disabled || readonly}\n      onBlur={handleBlur}\n    />\n  );\n  // pill input end\n  return (\n    <PillsInput\n      label={labelValue(label, hideLabel, undefined)}\n      description={description}\n      disabled={disabled || readonly}\n      error={createErrors<T>(rawErrors, hideError)}\n      aria-describedby={ariaDescribedByIds<T>(id)}\n      required={required}\n      className='armt-widget-pill-input'\n    >\n      <Pill.Group>\n        {currentPills}\n        {pillInput}\n      </Pill.Group>\n    </PillsInput>\n  );\n}\n"],"names":[],"mappings":"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"}