@sproutsocial/seeds-react-token-input 1.4.30 → 1.4.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,14 +8,14 @@ $ tsup --dts
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.js 15.11 KB
12
- CJS dist/index.js.map 27.20 KB
13
- CJS ⚡️ Build success in 36ms
14
- ESM dist/esm/index.js 12.41 KB
15
- ESM dist/esm/index.js.map 27.01 KB
16
- ESM ⚡️ Build success in 36ms
11
+ CJS dist/index.js 15.36 KB
12
+ CJS dist/index.js.map 28.27 KB
13
+ CJS ⚡️ Build success in 20ms
14
+ ESM dist/esm/index.js 12.68 KB
15
+ ESM dist/esm/index.js.map 28.06 KB
16
+ ESM ⚡️ Build success in 21ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 3061ms
19
- DTS dist/index.d.ts 5.12 KB
20
- DTS dist/index.d.mts 5.12 KB
21
- Done in 4.13s.
18
+ DTS ⚡️ Build success in 3772ms
19
+ DTS dist/index.d.ts 4.51 KB
20
+ DTS dist/index.d.mts 4.51 KB
21
+ Done in 5.17s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @sproutsocial/seeds-react-token-input
2
2
 
3
+ ## 1.4.31
4
+
5
+ ### Patch Changes
6
+
7
+ - d7658f1: Fix React crash when MultiAutocomplete is used inside Radix-based containers
8
+
9
+ **seeds-react-token-input**: Wrap TokenInput class component with `React.forwardRef` so the standard `ref` prop resolves to the root Container DOM node instead of the class instance. This fixes a `TypeError: contains is not a function` crash in Radix UI's `onInteractOutside` handler, which expects `triggerRef` to be a DOM element. The existing `innerRef` prop continues to forward to the underlying `<input>`.
10
+
11
+ **seeds-react-menu**: Add `{ suppressRefError: true }` to all `getMenuProps` calls in v2 `ComboboxContent` (virtualized, normal, and grouped variants). This suppresses false-positive dev-mode errors from downshift when the menu popout is closed and the menu ref is not attached to a DOM node. This matches the existing pattern used in v1 menu components.
12
+
3
13
  ## 1.4.30
4
14
 
5
15
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/index.ts
2
+ import * as React4 from "react";
3
+
1
4
  // src/TokenInput.tsx
2
5
  import * as React2 from "react";
3
6
  import styled3 from "styled-components";
@@ -366,6 +369,7 @@ var TokenInput = class extends React2.Component {
366
369
  ariaDescribedby,
367
370
  ariaLabel,
368
371
  innerRef,
372
+ containerRef,
369
373
  // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct
370
374
  /* eslint-disable @typescript-eslint/no-unused-vars */
371
375
  value,
@@ -389,6 +393,7 @@ var TokenInput = class extends React2.Component {
389
393
  return /* @__PURE__ */ jsxs(
390
394
  styles_default,
391
395
  {
396
+ ref: containerRef,
392
397
  hasBeforeElement: !!elemBefore,
393
398
  hasAfterElement: !!elemAfter,
394
399
  disabled,
@@ -441,9 +446,13 @@ var TokenInput = class extends React2.Component {
441
446
  import "react";
442
447
 
443
448
  // src/index.ts
444
- var index_default = TokenInput;
449
+ var TokenInput2 = React4.forwardRef(
450
+ (props, ref) => React4.createElement(TokenInput, { ...props, containerRef: ref })
451
+ );
452
+ TokenInput2.displayName = "TokenInput";
453
+ var index_default = TokenInput2;
445
454
  export {
446
- TokenInput,
455
+ TokenInput2 as TokenInput,
447
456
  index_default as default
448
457
  };
449
458
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/TokenInput.tsx","../../src/styles.ts","../../src/util.ts","../../src/TokenScreenReaderStatus.tsx","../../../seeds-react-visually-hidden/src/VisuallyHidden.tsx","../../src/TokenInputTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { Accessory } from \"@sproutsocial/seeds-react-input\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport Token from \"@sproutsocial/seeds-react-token\";\nimport Container from \"./styles\";\nimport { asTokenSpec, delimitersAsRegExp } from \"./util\";\nimport type { TypeTokenInputProps, TypeTokenSpec } from \"./TokenInputTypes\";\nimport { TokenScreenReaderStatus } from \"./TokenScreenReaderStatus\";\n\ntype TypeState = {\n prevProps: TypeTokenInputProps;\n hasFocus: boolean;\n activeToken: string | null | undefined;\n value: string;\n};\n\n// Simply using a styled input to allow passing the `as` prop\nconst StyledInput = styled(\"input\")``;\n\nconst DefaultDelimiters = [\",\", \"Enter\"];\nconst ControlledPropNames: (keyof TypeState)[] = [\n \"value\",\n \"hasFocus\",\n \"activeToken\",\n];\n\nexport default class TokenInput extends React.Component<\n TypeTokenInputProps,\n TypeState\n> {\n delimiterMatcher: RegExp;\n\n constructor(props: TypeTokenInputProps) {\n super(props);\n const { hasFocus, activeToken, value, delimiters } = props;\n this.delimiterMatcher = delimitersAsRegExp(delimiters || DefaultDelimiters);\n this.state = {\n prevProps: props,\n hasFocus: hasFocus || false,\n activeToken: activeToken,\n value: value || \"\",\n };\n }\n\n static getDerivedStateFromProps(\n props: Readonly<TypeTokenInputProps>,\n state: TypeState\n ) {\n const { prevProps } = state;\n const modifiedState: Partial<TypeState> = { prevProps: props };\n ControlledPropNames.forEach((propName) => {\n const currentProp = props[propName as keyof TypeTokenInputProps];\n\n // @ts-ignore: TODO - fix state types for prevProps\n if (currentProp !== prevProps[propName]) {\n modifiedState[propName] = currentProp;\n }\n });\n modifiedState.prevProps = props;\n return modifiedState;\n }\n\n isDelimiter(keyName: string) {\n const { delimiters = DefaultDelimiters } = this.props;\n return delimiters.includes(keyName);\n }\n\n spawnNewTokens(texts: string[]) {\n const {\n onAddToken,\n onChangeTokens,\n tokenMaxLength: max = Infinity,\n tokens = [],\n } = this.props;\n const tokenSpecs = texts.map((text) => asTokenSpec(text.slice(0, max)));\n\n if (onAddToken) {\n tokenSpecs.forEach(onAddToken);\n } else if (onChangeTokens) {\n onChangeTokens(tokens.concat(tokenSpecs));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n deleteToken(tokenId?: string) {\n const { onRemoveToken, onChangeTokens, tokens = [] } = this.props;\n const count = tokens.length;\n if (count === 0) return;\n const id = tokenId ?? tokens[count - 1]?.id;\n\n if (onRemoveToken) {\n onRemoveToken(id ? id : \"\");\n } else if (onChangeTokens) {\n onChangeTokens(tokens.filter((tokenSpec) => tokenSpec.id !== id));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n handleChangeText = (e: React.SyntheticEvent<HTMLInputElement>) => {\n const { value } = e.currentTarget;\n const { onChange } = this.props;\n this.setState({\n value,\n });\n onChange?.(e, value);\n };\n\n handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onFocus } = this.props;\n this.setState({\n hasFocus: true,\n });\n onFocus?.(e);\n };\n\n handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onBlur } = this.props;\n if (onBlur) onBlur(e);\n this.setState({\n hasFocus: false,\n });\n };\n\n handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {\n this.props.onKeyUp?.(e, e.currentTarget.value);\n };\n\n handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n const { onKeyDown } = this.props;\n const { key, currentTarget } = e;\n const text = currentTarget.value;\n if (onKeyDown) onKeyDown(e, text);\n\n // keyPress event runs before change\n // Prevent event from bubbling up and calling change, which can lead to comma in value\n if (this.isDelimiter(key)) {\n if (text) {\n this.spawnNewTokens([text]);\n e.preventDefault();\n }\n } else if (key === \"Backspace\") {\n if (text === \"\") {\n this.deleteToken();\n }\n }\n };\n\n handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData.getData(\"text\");\n const { onPaste } = this.props;\n if (onPaste) onPaste(e, text);\n const subtexts = text.split(this.delimiterMatcher);\n const texts = subtexts.filter((subtext) => subtext.length);\n\n if (texts.length > 1) {\n this.spawnNewTokens(texts);\n e.preventDefault();\n }\n };\n\n handleClickToken = (\n e: React.SyntheticEvent<Element, Event>,\n token: TypeTokenSpec\n ) => {\n const { onClickToken, disabled } = this.props;\n if (onClickToken) onClickToken(e, token.id);\n\n if (!disabled) {\n this.deleteToken(token.id);\n }\n };\n\n renderToken(token: TypeTokenSpec): React.ReactNode {\n const { iconName: defaultIconName, disabled } = this.props;\n const activeId = this.state.activeToken;\n const {\n id,\n iconName: tokenIconName,\n iconProps = { \"aria-hidden\": true },\n value,\n valid,\n hasWarning,\n tokenProps: { onClick, ...restTokenProps } = {},\n } = token;\n const iconName = tokenIconName || defaultIconName;\n const isActive = activeId === id;\n return (\n <Token\n id={id}\n onClick={(e) => {\n this.handleClickToken(e, token);\n onClick?.(e);\n }}\n valid={valid}\n hasWarning={hasWarning}\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n active={isActive}\n disabled={disabled}\n {...restTokenProps}\n >\n <Box display=\"flex\" alignItems=\"center\">\n {iconName && (\n <Icon name={iconName} size=\"mini\" pr={300} {...iconProps} />\n )}\n {value}\n </Box>\n </Token>\n );\n }\n\n renderTokens(tokens: TypeTokenSpec[]): React.ReactNode {\n return tokens.map<React.ReactNode>((token) => (\n <div key={token.id} className=\"TokenInput-token\">\n {this.renderToken(token)}\n </div>\n ));\n }\n\n override render() {\n const {\n autoFocus,\n autocomplete,\n disabled,\n isInvalid,\n hasWarning,\n id,\n name,\n placeholder,\n required,\n elemBefore,\n elemAfter,\n maxLength,\n ariaDescribedby,\n ariaLabel,\n innerRef,\n // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct\n /* eslint-disable @typescript-eslint/no-unused-vars */\n value,\n onAddToken,\n onRemoveToken,\n onChangeTokens,\n onClickToken,\n onBlur,\n onChange,\n onFocus,\n onKeyDown,\n onKeyUp,\n onPaste,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n inputProps = {},\n qa = {},\n tokens,\n ...rest\n } = this.props;\n const { state } = this;\n return (\n <Container\n hasBeforeElement={!!elemBefore}\n hasAfterElement={!!elemAfter}\n disabled={disabled}\n invalid={!!isInvalid}\n warning={hasWarning}\n focused={state.hasFocus}\n {...rest}\n >\n {elemBefore && <Accessory before>{elemBefore}</Accessory>}\n\n {tokens && this.renderTokens(tokens)}\n\n <TokenScreenReaderStatus tokens={tokens} />\n\n <StyledInput\n aria-describedby={ariaDescribedby}\n aria-invalid={!!isInvalid}\n aria-label={ariaLabel}\n autoFocus={autoFocus}\n autoComplete={autocomplete}\n disabled={disabled}\n id={id}\n name={name}\n placeholder={placeholder}\n type=\"text\"\n required={required}\n value={state.value}\n maxLength={maxLength}\n onBlur={this.handleBlur}\n onChange={this.handleChangeText}\n onFocus={this.handleFocus}\n onKeyDown={this.handleKeyDown}\n onKeyUp={this.handleKeyUp}\n onPaste={this.handlePaste}\n ref={innerRef}\n data-qa-input={name || \"\"}\n data-qa-input-isdisabled={!!disabled}\n data-qa-input-isrequired={!!required}\n {...qa}\n {...inputProps}\n />\n\n {elemAfter && <Accessory after>{elemAfter}</Accessory>}\n </Container>\n );\n }\n}\n","import styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport type { TypeInputContainerProps } from \"@sproutsocial/seeds-react-input\";\n\ninterface TypeTokenInputContainerProps\n extends Pick<\n TypeInputContainerProps,\n \"hasBeforeElement\" | \"hasAfterElement\" | \"disabled\" | \"invalid\" | \"warning\"\n > {\n focused?: boolean;\n}\n\nconst Container = styled.div<TypeTokenInputContainerProps>`\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n align-content: center;\n cursor: text;\n width: 100%;\n border: 1px solid ${(props) => props.theme.colors.form.border.base};\n border-radius: ${(props) => props.theme.radii[500]};\n margin: 0;\n padding: ${(props) => props.theme.space[300]};\n padding-top: ${(props) => props.theme.space[200]};\n background-color: ${(props) => props.theme.colors.form.background.base};\n color: ${(props) => props.theme.colors.text.body};\n transition: border-color ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in},\n box-shadow ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in};\n ${(props) => props.theme.typography[200]};\n font-family: ${(props) => props.theme.fontFamily};\n font-weight: ${(props) => props.theme.fontWeights.normal};\n appearance: none;\n\n button {\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[200]} 0 0;\n }\n\n input,\n textarea {\n ${(props) => props.theme.typography[200]};\n outline: none;\n border: none;\n flex: 1;\n padding: 0;\n padding-top: ${(props) => props.theme.space[100]};\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[300]} ${(props) => props.theme.space[100]}\n 0;\n color: ${(props) => props.theme.colors.text.body};\n background-color: ${(props) => props.theme.colors.form.background.base};\n /** This matches the height of the token so size does not change as tokens are added */\n min-height: 20px;\n\n &::-webkit-search-cancel-button {\n appearance: none;\n }\n\n /* Explicitly removes double focus ring in environments where box-shadow focus styles have been specified (Seeds). Focus is passed up from the input to the parent container. */\n &:focus {\n box-shadow: none;\n }\n\n /* https://stackoverflow.com/questions/14007655/remove-ie10s-clear-field-x-button-on-certain-inputs */\n &::-ms-clear {\n display: none;\n }\n\n /* Fix for red ring when input is marked required in Firefox */\n &:not(output):not(:focus):-moz-ui-invalid {\n box-shadow: none;\n }\n\n &::placeholder {\n color: ${(props) => props.theme.colors.form.placeholder.base};\n font-style: italic;\n }\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n }\n\n textarea {\n font-family: ${(props) => props.theme.fontFamily};\n }\n\n ${(props) =>\n props.hasBeforeElement &&\n css`\n padding-left: 40px;\n `}\n\n ${(props) =>\n props.hasAfterElement &&\n css`\n padding-right: 40px;\n `}\n\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n\n ${(props) =>\n props.focused &&\n css`\n ${focusRing}\n `}\n\n ${(props) =>\n props.invalid &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.error};\n `}\n\n\t${(props) =>\n props.warning &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.warning};\n `}\n\n ${COMMON}\n`;\n\nContainer.displayName = \"TokenInputContainer\";\n\nexport default Container;\n","import uniqueId from \"lodash.uniqueid\";\nimport type { TypeTokenSpec } from \"./\";\n\nexport const asTokenSpec = (text: string): TypeTokenSpec => ({\n id: uniqueId(`${text}-`),\n value: text.trim(),\n});\n\nconst KeyNameToRegExpChar: { [key: string]: string } = {\n Enter: \"\\\\n\",\n};\n\nexport const delimitersAsRegExp = (delimiters: string[] | null | undefined) => {\n if (!delimiters) return /[,\\n]/;\n const chars = delimiters\n .map(\n (key) =>\n KeyNameToRegExpChar[key as keyof typeof KeyNameToRegExpChar] || key\n )\n .join(\"\");\n return RegExp(`[${chars}]`);\n};\n","import React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\nimport type { TypeTokenInputProps } from \"./\";\n\nfunction usePrevious(value: TypeTokenInputProps[\"tokens\"]) {\n const ref = useRef<TypeTokenInputProps[\"tokens\"]>();\n\n useEffect(() => {\n ref.current = value;\n });\n\n return ref.current;\n}\n\nexport const TokenScreenReaderStatus = ({\n tokens,\n}: {\n tokens: TypeTokenInputProps[\"tokens\"];\n}) => {\n const prevTokens = usePrevious(tokens);\n const [tokenStatus, setTokenStatus] = useState(\"\");\n\n // TODO: Use callbacks so consumers can pass localized messaging to the screen reader\n useEffect(() => {\n if (prevTokens && tokens) {\n if (prevTokens.length > tokens.length) {\n setTokenStatus(\n `${\n prevTokens.filter((item) => tokens.indexOf(item) === -1)[0]?.value\n } has been removed`\n );\n }\n\n if (prevTokens.length < tokens.length) {\n setTokenStatus(`${tokens[tokens.length - 1]?.value} has been added.`);\n }\n }\n }, [prevTokens, tokens, tokenStatus]);\n\n return (\n <VisuallyHidden as=\"div\" role=\"status\">\n {tokenStatus}\n </VisuallyHidden>\n );\n};\n","import styled from \"styled-components\";\nimport { visuallyHidden } from \"@sproutsocial/seeds-react-mixins\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst StyledVisuallyHidden = styled.span`\n ${visuallyHidden}\n`;\n\nexport type VisuallyHiddenProps = ComponentPropsWithRef<\n typeof StyledVisuallyHidden\n>;\n\n// This wrapper component is needed for react-docgen to work.\n// It has issues with generating docs for the styled component directly.\nexport const VisuallyHidden = (props: VisuallyHiddenProps) => {\n return <StyledVisuallyHidden {...props} />;\n};\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type {\n TypeIconProps,\n TypeIconName,\n} from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeTokenProps } from \"@sproutsocial/seeds-react-token\";\n\nexport interface TypeTokenSpec {\n id: string;\n iconName?: TypeIconName;\n iconProps?: Omit<TypeIconProps, \"name\">;\n value: string;\n valid?: boolean;\n hasWarning?: boolean;\n tokenProps?: Partial<TypeTokenProps>;\n}\n\nexport interface TypeBaseTokenInputProps {\n /** ID of the form element, should match the \"for\" value of the associated label */\n id: string;\n name: string;\n iconName?: TypeIconName;\n\n /** Array of delimiter key names */\n delimiters?: string[];\n\n /** Current input text. Required when controlling the input text */\n value?: string;\n\n /** Current focus state. Required when controlling the focus via onFocus and onBlur */\n hasFocus?: boolean;\n\n /** Id of the currently selected token */\n activeToken?: string;\n\n /** Array of current tokens */\n tokens?: TypeTokenSpec[];\n\n /** Standard control of changing tokens. For fine-grain control use onAddToken and onRemoveToken, instead */\n onChangeTokens?: (tokens: TypeTokenSpec[]) => void;\n\n /** Fine-grained control of adding tokens. Use with onRemoveToken instead of onChangeTokens */\n onAddToken?: (tokenSpec: TypeTokenSpec) => void;\n\n /** Fine-grained control of removing tokens. Use with onAddToken instead of onChangeTokens */\n onRemoveToken?: (tokenId: string) => void;\n\n /** Controls clicking on a token. When absent, clicking a token removes itself */\n onClickToken?(e: React.SyntheticEvent<Element, Event>, tokenId: string): void;\n\n /** Fine-grained control of the input text used to create tokens */\n onChange?: (e: React.SyntheticEvent<HTMLInputElement>, value: string) => void;\n\n /** Fine-grained control of pasted text */\n onPaste?: (e: React.ClipboardEvent<HTMLInputElement>, value: string) => void;\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n\n /** Attribute used to associate other elements that describe the Input, like an error */\n ariaDescribedby?: string;\n\n /** Label used to describe the input if not used with an accompanying visual label */\n ariaLabel?: string;\n\n /** Placeholder text for when value is undefined or empty */\n placeholder?: string;\n\n /** Will autofocus the element when mounted to the DOM */\n autoFocus?: boolean;\n\n /** HTML disabled attribute */\n disabled?: boolean;\n\n /** Whether or not the current contents of the input are invalid */\n isInvalid?: boolean;\n\n /** Whether or not the current contents of the input has any warnings */\n hasWarning?: boolean;\n\n /** HTML required attribute */\n required?: boolean;\n\n /** 16x16 element, such as an icon */\n elemBefore?: React.ReactNode;\n\n /** 16x16 element, such as an icon */\n elemAfter?: React.ReactNode;\n\n /** Max input text length */\n maxLength?: number;\n\n /** Max length of the token */\n tokenMaxLength?: number;\n\n /** Props to spread onto the underlying input element */\n inputProps?: React.ComponentPropsWithoutRef<\"input\">;\n\n /** Used to get a reference to the underlying element */\n innerRef?: React.Ref<HTMLInputElement>;\n qa?: object;\n\n /** Browser autocomplete support */\n autocomplete?: string;\n}\n\nexport interface TypeTokenInputProps\n extends TypeBaseTokenInputProps,\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n keyof TypeBaseTokenInputProps | \"color\"\n > {}\n","import TokenInput from \"./TokenInput\";\n\nexport default TokenInput;\nexport { TokenInput };\nexport * from \"./TokenInputTypes\";\n"],"mappings":"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","names":["React","styled","props","styled","jsx","jsx","styled"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/TokenInput.tsx","../../src/styles.ts","../../src/util.ts","../../src/TokenScreenReaderStatus.tsx","../../../seeds-react-visually-hidden/src/VisuallyHidden.tsx","../../src/TokenInputTypes.ts"],"sourcesContent":["import * as React from \"react\";\nimport TokenInputClass from \"./TokenInput\";\nimport type { TypeTokenInputProps } from \"./TokenInputTypes\";\n\n/**\n * Wraps the class-based TokenInput with forwardRef so that the standard React\n * `ref` prop resolves to the root Container DOM node. This is required for\n * Radix UI's `asChild` pattern (used by seeds-react-menu's Popout) which\n * expects triggerRef to be a DOM element for `.contains()` checks.\n *\n * The existing `innerRef` prop still forwards to the underlying `<input>`.\n */\nconst TokenInput = React.forwardRef<HTMLDivElement, TypeTokenInputProps>(\n (props, ref) =>\n React.createElement(TokenInputClass, { ...props, containerRef: ref })\n);\n\nTokenInput.displayName = \"TokenInput\";\n\nexport default TokenInput;\nexport { TokenInput };\nexport * from \"./TokenInputTypes\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { Accessory } from \"@sproutsocial/seeds-react-input\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport Token from \"@sproutsocial/seeds-react-token\";\nimport Container from \"./styles\";\nimport { asTokenSpec, delimitersAsRegExp } from \"./util\";\nimport type { TypeTokenInputProps, TypeTokenSpec } from \"./TokenInputTypes\";\nimport { TokenScreenReaderStatus } from \"./TokenScreenReaderStatus\";\n\ntype TypeState = {\n prevProps: TypeTokenInputProps;\n hasFocus: boolean;\n activeToken: string | null | undefined;\n value: string;\n};\n\n// Simply using a styled input to allow passing the `as` prop\nconst StyledInput = styled(\"input\")``;\n\nconst DefaultDelimiters = [\",\", \"Enter\"];\nconst ControlledPropNames: (keyof TypeState)[] = [\n \"value\",\n \"hasFocus\",\n \"activeToken\",\n];\n\nexport default class TokenInput extends React.Component<\n TypeTokenInputProps,\n TypeState\n> {\n delimiterMatcher: RegExp;\n\n constructor(props: TypeTokenInputProps) {\n super(props);\n const { hasFocus, activeToken, value, delimiters } = props;\n this.delimiterMatcher = delimitersAsRegExp(delimiters || DefaultDelimiters);\n this.state = {\n prevProps: props,\n hasFocus: hasFocus || false,\n activeToken: activeToken,\n value: value || \"\",\n };\n }\n\n static getDerivedStateFromProps(\n props: Readonly<TypeTokenInputProps>,\n state: TypeState\n ) {\n const { prevProps } = state;\n const modifiedState: Partial<TypeState> = { prevProps: props };\n ControlledPropNames.forEach((propName) => {\n const currentProp = props[propName as keyof TypeTokenInputProps];\n\n // @ts-ignore: TODO - fix state types for prevProps\n if (currentProp !== prevProps[propName]) {\n modifiedState[propName] = currentProp;\n }\n });\n modifiedState.prevProps = props;\n return modifiedState;\n }\n\n isDelimiter(keyName: string) {\n const { delimiters = DefaultDelimiters } = this.props;\n return delimiters.includes(keyName);\n }\n\n spawnNewTokens(texts: string[]) {\n const {\n onAddToken,\n onChangeTokens,\n tokenMaxLength: max = Infinity,\n tokens = [],\n } = this.props;\n const tokenSpecs = texts.map((text) => asTokenSpec(text.slice(0, max)));\n\n if (onAddToken) {\n tokenSpecs.forEach(onAddToken);\n } else if (onChangeTokens) {\n onChangeTokens(tokens.concat(tokenSpecs));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n deleteToken(tokenId?: string) {\n const { onRemoveToken, onChangeTokens, tokens = [] } = this.props;\n const count = tokens.length;\n if (count === 0) return;\n const id = tokenId ?? tokens[count - 1]?.id;\n\n if (onRemoveToken) {\n onRemoveToken(id ? id : \"\");\n } else if (onChangeTokens) {\n onChangeTokens(tokens.filter((tokenSpec) => tokenSpec.id !== id));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n handleChangeText = (e: React.SyntheticEvent<HTMLInputElement>) => {\n const { value } = e.currentTarget;\n const { onChange } = this.props;\n this.setState({\n value,\n });\n onChange?.(e, value);\n };\n\n handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onFocus } = this.props;\n this.setState({\n hasFocus: true,\n });\n onFocus?.(e);\n };\n\n handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onBlur } = this.props;\n if (onBlur) onBlur(e);\n this.setState({\n hasFocus: false,\n });\n };\n\n handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {\n this.props.onKeyUp?.(e, e.currentTarget.value);\n };\n\n handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n const { onKeyDown } = this.props;\n const { key, currentTarget } = e;\n const text = currentTarget.value;\n if (onKeyDown) onKeyDown(e, text);\n\n // keyPress event runs before change\n // Prevent event from bubbling up and calling change, which can lead to comma in value\n if (this.isDelimiter(key)) {\n if (text) {\n this.spawnNewTokens([text]);\n e.preventDefault();\n }\n } else if (key === \"Backspace\") {\n if (text === \"\") {\n this.deleteToken();\n }\n }\n };\n\n handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData.getData(\"text\");\n const { onPaste } = this.props;\n if (onPaste) onPaste(e, text);\n const subtexts = text.split(this.delimiterMatcher);\n const texts = subtexts.filter((subtext) => subtext.length);\n\n if (texts.length > 1) {\n this.spawnNewTokens(texts);\n e.preventDefault();\n }\n };\n\n handleClickToken = (\n e: React.SyntheticEvent<Element, Event>,\n token: TypeTokenSpec\n ) => {\n const { onClickToken, disabled } = this.props;\n if (onClickToken) onClickToken(e, token.id);\n\n if (!disabled) {\n this.deleteToken(token.id);\n }\n };\n\n renderToken(token: TypeTokenSpec): React.ReactNode {\n const { iconName: defaultIconName, disabled } = this.props;\n const activeId = this.state.activeToken;\n const {\n id,\n iconName: tokenIconName,\n iconProps = { \"aria-hidden\": true },\n value,\n valid,\n hasWarning,\n tokenProps: { onClick, ...restTokenProps } = {},\n } = token;\n const iconName = tokenIconName || defaultIconName;\n const isActive = activeId === id;\n return (\n <Token\n id={id}\n onClick={(e) => {\n this.handleClickToken(e, token);\n onClick?.(e);\n }}\n valid={valid}\n hasWarning={hasWarning}\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n active={isActive}\n disabled={disabled}\n {...restTokenProps}\n >\n <Box display=\"flex\" alignItems=\"center\">\n {iconName && (\n <Icon name={iconName} size=\"mini\" pr={300} {...iconProps} />\n )}\n {value}\n </Box>\n </Token>\n );\n }\n\n renderTokens(tokens: TypeTokenSpec[]): React.ReactNode {\n return tokens.map<React.ReactNode>((token) => (\n <div key={token.id} className=\"TokenInput-token\">\n {this.renderToken(token)}\n </div>\n ));\n }\n\n override render() {\n const {\n autoFocus,\n autocomplete,\n disabled,\n isInvalid,\n hasWarning,\n id,\n name,\n placeholder,\n required,\n elemBefore,\n elemAfter,\n maxLength,\n ariaDescribedby,\n ariaLabel,\n innerRef,\n containerRef,\n // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct\n /* eslint-disable @typescript-eslint/no-unused-vars */\n value,\n onAddToken,\n onRemoveToken,\n onChangeTokens,\n onClickToken,\n onBlur,\n onChange,\n onFocus,\n onKeyDown,\n onKeyUp,\n onPaste,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n inputProps = {},\n qa = {},\n tokens,\n ...rest\n } = this.props;\n const { state } = this;\n return (\n <Container\n ref={containerRef}\n hasBeforeElement={!!elemBefore}\n hasAfterElement={!!elemAfter}\n disabled={disabled}\n invalid={!!isInvalid}\n warning={hasWarning}\n focused={state.hasFocus}\n {...rest}\n >\n {elemBefore && <Accessory before>{elemBefore}</Accessory>}\n\n {tokens && this.renderTokens(tokens)}\n\n <TokenScreenReaderStatus tokens={tokens} />\n\n <StyledInput\n aria-describedby={ariaDescribedby}\n aria-invalid={!!isInvalid}\n aria-label={ariaLabel}\n autoFocus={autoFocus}\n autoComplete={autocomplete}\n disabled={disabled}\n id={id}\n name={name}\n placeholder={placeholder}\n type=\"text\"\n required={required}\n value={state.value}\n maxLength={maxLength}\n onBlur={this.handleBlur}\n onChange={this.handleChangeText}\n onFocus={this.handleFocus}\n onKeyDown={this.handleKeyDown}\n onKeyUp={this.handleKeyUp}\n onPaste={this.handlePaste}\n ref={innerRef}\n data-qa-input={name || \"\"}\n data-qa-input-isdisabled={!!disabled}\n data-qa-input-isrequired={!!required}\n {...qa}\n {...inputProps}\n />\n\n {elemAfter && <Accessory after>{elemAfter}</Accessory>}\n </Container>\n );\n }\n}\n","import styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport type { TypeInputContainerProps } from \"@sproutsocial/seeds-react-input\";\n\ninterface TypeTokenInputContainerProps\n extends Pick<\n TypeInputContainerProps,\n \"hasBeforeElement\" | \"hasAfterElement\" | \"disabled\" | \"invalid\" | \"warning\"\n > {\n focused?: boolean;\n}\n\nconst Container = styled.div<TypeTokenInputContainerProps>`\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n align-content: center;\n cursor: text;\n width: 100%;\n border: 1px solid ${(props) => props.theme.colors.form.border.base};\n border-radius: ${(props) => props.theme.radii[500]};\n margin: 0;\n padding: ${(props) => props.theme.space[300]};\n padding-top: ${(props) => props.theme.space[200]};\n background-color: ${(props) => props.theme.colors.form.background.base};\n color: ${(props) => props.theme.colors.text.body};\n transition: border-color ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in},\n box-shadow ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in};\n ${(props) => props.theme.typography[200]};\n font-family: ${(props) => props.theme.fontFamily};\n font-weight: ${(props) => props.theme.fontWeights.normal};\n appearance: none;\n\n button {\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[200]} 0 0;\n }\n\n input,\n textarea {\n ${(props) => props.theme.typography[200]};\n outline: none;\n border: none;\n flex: 1;\n padding: 0;\n padding-top: ${(props) => props.theme.space[100]};\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[300]} ${(props) => props.theme.space[100]}\n 0;\n color: ${(props) => props.theme.colors.text.body};\n background-color: ${(props) => props.theme.colors.form.background.base};\n /** This matches the height of the token so size does not change as tokens are added */\n min-height: 20px;\n\n &::-webkit-search-cancel-button {\n appearance: none;\n }\n\n /* Explicitly removes double focus ring in environments where box-shadow focus styles have been specified (Seeds). Focus is passed up from the input to the parent container. */\n &:focus {\n box-shadow: none;\n }\n\n /* https://stackoverflow.com/questions/14007655/remove-ie10s-clear-field-x-button-on-certain-inputs */\n &::-ms-clear {\n display: none;\n }\n\n /* Fix for red ring when input is marked required in Firefox */\n &:not(output):not(:focus):-moz-ui-invalid {\n box-shadow: none;\n }\n\n &::placeholder {\n color: ${(props) => props.theme.colors.form.placeholder.base};\n font-style: italic;\n }\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n }\n\n textarea {\n font-family: ${(props) => props.theme.fontFamily};\n }\n\n ${(props) =>\n props.hasBeforeElement &&\n css`\n padding-left: 40px;\n `}\n\n ${(props) =>\n props.hasAfterElement &&\n css`\n padding-right: 40px;\n `}\n\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n\n ${(props) =>\n props.focused &&\n css`\n ${focusRing}\n `}\n\n ${(props) =>\n props.invalid &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.error};\n `}\n\n\t${(props) =>\n props.warning &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.warning};\n `}\n\n ${COMMON}\n`;\n\nContainer.displayName = \"TokenInputContainer\";\n\nexport default Container;\n","import uniqueId from \"lodash.uniqueid\";\nimport type { TypeTokenSpec } from \"./\";\n\nexport const asTokenSpec = (text: string): TypeTokenSpec => ({\n id: uniqueId(`${text}-`),\n value: text.trim(),\n});\n\nconst KeyNameToRegExpChar: { [key: string]: string } = {\n Enter: \"\\\\n\",\n};\n\nexport const delimitersAsRegExp = (delimiters: string[] | null | undefined) => {\n if (!delimiters) return /[,\\n]/;\n const chars = delimiters\n .map(\n (key) =>\n KeyNameToRegExpChar[key as keyof typeof KeyNameToRegExpChar] || key\n )\n .join(\"\");\n return RegExp(`[${chars}]`);\n};\n","import React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\nimport type { TypeTokenInputProps } from \"./\";\n\nfunction usePrevious(value: TypeTokenInputProps[\"tokens\"]) {\n const ref = useRef<TypeTokenInputProps[\"tokens\"]>();\n\n useEffect(() => {\n ref.current = value;\n });\n\n return ref.current;\n}\n\nexport const TokenScreenReaderStatus = ({\n tokens,\n}: {\n tokens: TypeTokenInputProps[\"tokens\"];\n}) => {\n const prevTokens = usePrevious(tokens);\n const [tokenStatus, setTokenStatus] = useState(\"\");\n\n // TODO: Use callbacks so consumers can pass localized messaging to the screen reader\n useEffect(() => {\n if (prevTokens && tokens) {\n if (prevTokens.length > tokens.length) {\n setTokenStatus(\n `${\n prevTokens.filter((item) => tokens.indexOf(item) === -1)[0]?.value\n } has been removed`\n );\n }\n\n if (prevTokens.length < tokens.length) {\n setTokenStatus(`${tokens[tokens.length - 1]?.value} has been added.`);\n }\n }\n }, [prevTokens, tokens, tokenStatus]);\n\n return (\n <VisuallyHidden as=\"div\" role=\"status\">\n {tokenStatus}\n </VisuallyHidden>\n );\n};\n","import styled from \"styled-components\";\nimport { visuallyHidden } from \"@sproutsocial/seeds-react-mixins\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst StyledVisuallyHidden = styled.span`\n ${visuallyHidden}\n`;\n\nexport type VisuallyHiddenProps = ComponentPropsWithRef<\n typeof StyledVisuallyHidden\n>;\n\n// This wrapper component is needed for react-docgen to work.\n// It has issues with generating docs for the styled component directly.\nexport const VisuallyHidden = (props: VisuallyHiddenProps) => {\n return <StyledVisuallyHidden {...props} />;\n};\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type {\n TypeIconProps,\n TypeIconName,\n} from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeTokenProps } from \"@sproutsocial/seeds-react-token\";\n\nexport interface TypeTokenSpec {\n id: string;\n iconName?: TypeIconName;\n iconProps?: Omit<TypeIconProps, \"name\">;\n value: string;\n valid?: boolean;\n hasWarning?: boolean;\n tokenProps?: Partial<TypeTokenProps>;\n}\n\nexport interface TypeBaseTokenInputProps {\n /** ID of the form element, should match the \"for\" value of the associated label */\n id: string;\n name: string;\n iconName?: TypeIconName;\n\n /** Array of delimiter key names */\n delimiters?: string[];\n\n /** Current input text. Required when controlling the input text */\n value?: string;\n\n /** Current focus state. Required when controlling the focus via onFocus and onBlur */\n hasFocus?: boolean;\n\n /** Id of the currently selected token */\n activeToken?: string;\n\n /** Array of current tokens */\n tokens?: TypeTokenSpec[];\n\n /** Standard control of changing tokens. For fine-grain control use onAddToken and onRemoveToken, instead */\n onChangeTokens?: (tokens: TypeTokenSpec[]) => void;\n\n /** Fine-grained control of adding tokens. Use with onRemoveToken instead of onChangeTokens */\n onAddToken?: (tokenSpec: TypeTokenSpec) => void;\n\n /** Fine-grained control of removing tokens. Use with onAddToken instead of onChangeTokens */\n onRemoveToken?: (tokenId: string) => void;\n\n /** Controls clicking on a token. When absent, clicking a token removes itself */\n onClickToken?(e: React.SyntheticEvent<Element, Event>, tokenId: string): void;\n\n /** Fine-grained control of the input text used to create tokens */\n onChange?: (e: React.SyntheticEvent<HTMLInputElement>, value: string) => void;\n\n /** Fine-grained control of pasted text */\n onPaste?: (e: React.ClipboardEvent<HTMLInputElement>, value: string) => void;\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n\n /** Attribute used to associate other elements that describe the Input, like an error */\n ariaDescribedby?: string;\n\n /** Label used to describe the input if not used with an accompanying visual label */\n ariaLabel?: string;\n\n /** Placeholder text for when value is undefined or empty */\n placeholder?: string;\n\n /** Will autofocus the element when mounted to the DOM */\n autoFocus?: boolean;\n\n /** HTML disabled attribute */\n disabled?: boolean;\n\n /** Whether or not the current contents of the input are invalid */\n isInvalid?: boolean;\n\n /** Whether or not the current contents of the input has any warnings */\n hasWarning?: boolean;\n\n /** HTML required attribute */\n required?: boolean;\n\n /** 16x16 element, such as an icon */\n elemBefore?: React.ReactNode;\n\n /** 16x16 element, such as an icon */\n elemAfter?: React.ReactNode;\n\n /** Max input text length */\n maxLength?: number;\n\n /** Max length of the token */\n tokenMaxLength?: number;\n\n /** Props to spread onto the underlying input element */\n inputProps?: React.ComponentPropsWithoutRef<\"input\">;\n\n /** Used to get a reference to the underlying input element */\n innerRef?: React.Ref<HTMLInputElement>;\n\n /** Ref forwarded to the root container element (used by Radix asChild) */\n containerRef?: React.Ref<HTMLDivElement>;\n qa?: object;\n\n /** Browser autocomplete support */\n autocomplete?: string;\n}\n\nexport interface TypeTokenInputProps\n extends TypeBaseTokenInputProps,\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n keyof TypeBaseTokenInputProps | \"color\"\n > {}\n"],"mappings":"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","names":["React","React","styled","props","styled","jsx","jsx","styled","TokenInput"]}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,3 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as React from 'react';
3
2
  import { TypeStyledComponentsCommonProps, TypeSystemCommonProps } from '@sproutsocial/seeds-react-system-props';
4
3
  import { TypeIconName, TypeIconProps } from '@sproutsocial/seeds-react-icon';
@@ -70,8 +69,10 @@ interface TypeBaseTokenInputProps {
70
69
  tokenMaxLength?: number;
71
70
  /** Props to spread onto the underlying input element */
72
71
  inputProps?: React.ComponentPropsWithoutRef<"input">;
73
- /** Used to get a reference to the underlying element */
72
+ /** Used to get a reference to the underlying input element */
74
73
  innerRef?: React.Ref<HTMLInputElement>;
74
+ /** Ref forwarded to the root container element (used by Radix asChild) */
75
+ containerRef?: React.Ref<HTMLDivElement>;
75
76
  qa?: object;
76
77
  /** Browser autocomplete support */
77
78
  autocomplete?: string;
@@ -79,29 +80,14 @@ interface TypeBaseTokenInputProps {
79
80
  interface TypeTokenInputProps extends TypeBaseTokenInputProps, TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"div">, keyof TypeBaseTokenInputProps | "color"> {
80
81
  }
81
82
 
82
- type TypeState = {
83
- prevProps: TypeTokenInputProps;
84
- hasFocus: boolean;
85
- activeToken: string | null | undefined;
86
- value: string;
87
- };
88
- declare class TokenInput extends React.Component<TypeTokenInputProps, TypeState> {
89
- delimiterMatcher: RegExp;
90
- constructor(props: TypeTokenInputProps);
91
- static getDerivedStateFromProps(props: Readonly<TypeTokenInputProps>, state: TypeState): Partial<TypeState>;
92
- isDelimiter(keyName: string): boolean;
93
- spawnNewTokens(texts: string[]): void;
94
- deleteToken(tokenId?: string): void;
95
- handleChangeText: (e: React.SyntheticEvent<HTMLInputElement>) => void;
96
- handleFocus: (e: React.FocusEvent<HTMLInputElement>) => void;
97
- handleBlur: (e: React.FocusEvent<HTMLInputElement>) => void;
98
- handleKeyUp: (e: React.KeyboardEvent<HTMLInputElement>) => void;
99
- handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
100
- handlePaste: (e: React.ClipboardEvent<HTMLInputElement>) => void;
101
- handleClickToken: (e: React.SyntheticEvent<Element, Event>, token: TypeTokenSpec) => void;
102
- renderToken(token: TypeTokenSpec): React.ReactNode;
103
- renderTokens(tokens: TypeTokenSpec[]): React.ReactNode;
104
- render(): react_jsx_runtime.JSX.Element;
105
- }
83
+ /**
84
+ * Wraps the class-based TokenInput with forwardRef so that the standard React
85
+ * `ref` prop resolves to the root Container DOM node. This is required for
86
+ * Radix UI's `asChild` pattern (used by seeds-react-menu's Popout) which
87
+ * expects triggerRef to be a DOM element for `.contains()` checks.
88
+ *
89
+ * The existing `innerRef` prop still forwards to the underlying `<input>`.
90
+ */
91
+ declare const TokenInput: React.ForwardRefExoticComponent<Omit<TypeTokenInputProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
106
92
 
107
93
  export { TokenInput, type TypeBaseTokenInputProps, type TypeTokenInputProps, type TypeTokenSpec, TokenInput as default };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as React from 'react';
3
2
  import { TypeStyledComponentsCommonProps, TypeSystemCommonProps } from '@sproutsocial/seeds-react-system-props';
4
3
  import { TypeIconName, TypeIconProps } from '@sproutsocial/seeds-react-icon';
@@ -70,8 +69,10 @@ interface TypeBaseTokenInputProps {
70
69
  tokenMaxLength?: number;
71
70
  /** Props to spread onto the underlying input element */
72
71
  inputProps?: React.ComponentPropsWithoutRef<"input">;
73
- /** Used to get a reference to the underlying element */
72
+ /** Used to get a reference to the underlying input element */
74
73
  innerRef?: React.Ref<HTMLInputElement>;
74
+ /** Ref forwarded to the root container element (used by Radix asChild) */
75
+ containerRef?: React.Ref<HTMLDivElement>;
75
76
  qa?: object;
76
77
  /** Browser autocomplete support */
77
78
  autocomplete?: string;
@@ -79,29 +80,14 @@ interface TypeBaseTokenInputProps {
79
80
  interface TypeTokenInputProps extends TypeBaseTokenInputProps, TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"div">, keyof TypeBaseTokenInputProps | "color"> {
80
81
  }
81
82
 
82
- type TypeState = {
83
- prevProps: TypeTokenInputProps;
84
- hasFocus: boolean;
85
- activeToken: string | null | undefined;
86
- value: string;
87
- };
88
- declare class TokenInput extends React.Component<TypeTokenInputProps, TypeState> {
89
- delimiterMatcher: RegExp;
90
- constructor(props: TypeTokenInputProps);
91
- static getDerivedStateFromProps(props: Readonly<TypeTokenInputProps>, state: TypeState): Partial<TypeState>;
92
- isDelimiter(keyName: string): boolean;
93
- spawnNewTokens(texts: string[]): void;
94
- deleteToken(tokenId?: string): void;
95
- handleChangeText: (e: React.SyntheticEvent<HTMLInputElement>) => void;
96
- handleFocus: (e: React.FocusEvent<HTMLInputElement>) => void;
97
- handleBlur: (e: React.FocusEvent<HTMLInputElement>) => void;
98
- handleKeyUp: (e: React.KeyboardEvent<HTMLInputElement>) => void;
99
- handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
100
- handlePaste: (e: React.ClipboardEvent<HTMLInputElement>) => void;
101
- handleClickToken: (e: React.SyntheticEvent<Element, Event>, token: TypeTokenSpec) => void;
102
- renderToken(token: TypeTokenSpec): React.ReactNode;
103
- renderTokens(tokens: TypeTokenSpec[]): React.ReactNode;
104
- render(): react_jsx_runtime.JSX.Element;
105
- }
83
+ /**
84
+ * Wraps the class-based TokenInput with forwardRef so that the standard React
85
+ * `ref` prop resolves to the root Container DOM node. This is required for
86
+ * Radix UI's `asChild` pattern (used by seeds-react-menu's Popout) which
87
+ * expects triggerRef to be a DOM element for `.contains()` checks.
88
+ *
89
+ * The existing `innerRef` prop still forwards to the underlying `<input>`.
90
+ */
91
+ declare const TokenInput: React.ForwardRefExoticComponent<Omit<TypeTokenInputProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
106
92
 
107
93
  export { TokenInput, type TypeBaseTokenInputProps, type TypeTokenInputProps, type TypeTokenSpec, TokenInput as default };
package/dist/index.js CHANGED
@@ -30,10 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- TokenInput: () => TokenInput,
33
+ TokenInput: () => TokenInput2,
34
34
  default: () => index_default
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
+ var React4 = __toESM(require("react"));
37
38
 
38
39
  // src/TokenInput.tsx
39
40
  var React2 = __toESM(require("react"));
@@ -403,6 +404,7 @@ var TokenInput = class extends React2.Component {
403
404
  ariaDescribedby,
404
405
  ariaLabel,
405
406
  innerRef,
407
+ containerRef,
406
408
  // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct
407
409
  /* eslint-disable @typescript-eslint/no-unused-vars */
408
410
  value,
@@ -426,6 +428,7 @@ var TokenInput = class extends React2.Component {
426
428
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
427
429
  styles_default,
428
430
  {
431
+ ref: containerRef,
429
432
  hasBeforeElement: !!elemBefore,
430
433
  hasAfterElement: !!elemAfter,
431
434
  disabled,
@@ -478,7 +481,11 @@ var TokenInput = class extends React2.Component {
478
481
  var React3 = require("react");
479
482
 
480
483
  // src/index.ts
481
- var index_default = TokenInput;
484
+ var TokenInput2 = React4.forwardRef(
485
+ (props, ref) => React4.createElement(TokenInput, { ...props, containerRef: ref })
486
+ );
487
+ TokenInput2.displayName = "TokenInput";
488
+ var index_default = TokenInput2;
482
489
  // Annotate the CommonJS export names for ESM import in node:
483
490
  0 && (module.exports = {
484
491
  TokenInput
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/TokenInput.tsx","../src/styles.ts","../src/util.ts","../src/TokenScreenReaderStatus.tsx","../../seeds-react-visually-hidden/src/VisuallyHidden.tsx","../src/TokenInputTypes.ts"],"sourcesContent":["import TokenInput from \"./TokenInput\";\n\nexport default TokenInput;\nexport { TokenInput };\nexport * from \"./TokenInputTypes\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { Accessory } from \"@sproutsocial/seeds-react-input\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport Token from \"@sproutsocial/seeds-react-token\";\nimport Container from \"./styles\";\nimport { asTokenSpec, delimitersAsRegExp } from \"./util\";\nimport type { TypeTokenInputProps, TypeTokenSpec } from \"./TokenInputTypes\";\nimport { TokenScreenReaderStatus } from \"./TokenScreenReaderStatus\";\n\ntype TypeState = {\n prevProps: TypeTokenInputProps;\n hasFocus: boolean;\n activeToken: string | null | undefined;\n value: string;\n};\n\n// Simply using a styled input to allow passing the `as` prop\nconst StyledInput = styled(\"input\")``;\n\nconst DefaultDelimiters = [\",\", \"Enter\"];\nconst ControlledPropNames: (keyof TypeState)[] = [\n \"value\",\n \"hasFocus\",\n \"activeToken\",\n];\n\nexport default class TokenInput extends React.Component<\n TypeTokenInputProps,\n TypeState\n> {\n delimiterMatcher: RegExp;\n\n constructor(props: TypeTokenInputProps) {\n super(props);\n const { hasFocus, activeToken, value, delimiters } = props;\n this.delimiterMatcher = delimitersAsRegExp(delimiters || DefaultDelimiters);\n this.state = {\n prevProps: props,\n hasFocus: hasFocus || false,\n activeToken: activeToken,\n value: value || \"\",\n };\n }\n\n static getDerivedStateFromProps(\n props: Readonly<TypeTokenInputProps>,\n state: TypeState\n ) {\n const { prevProps } = state;\n const modifiedState: Partial<TypeState> = { prevProps: props };\n ControlledPropNames.forEach((propName) => {\n const currentProp = props[propName as keyof TypeTokenInputProps];\n\n // @ts-ignore: TODO - fix state types for prevProps\n if (currentProp !== prevProps[propName]) {\n modifiedState[propName] = currentProp;\n }\n });\n modifiedState.prevProps = props;\n return modifiedState;\n }\n\n isDelimiter(keyName: string) {\n const { delimiters = DefaultDelimiters } = this.props;\n return delimiters.includes(keyName);\n }\n\n spawnNewTokens(texts: string[]) {\n const {\n onAddToken,\n onChangeTokens,\n tokenMaxLength: max = Infinity,\n tokens = [],\n } = this.props;\n const tokenSpecs = texts.map((text) => asTokenSpec(text.slice(0, max)));\n\n if (onAddToken) {\n tokenSpecs.forEach(onAddToken);\n } else if (onChangeTokens) {\n onChangeTokens(tokens.concat(tokenSpecs));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n deleteToken(tokenId?: string) {\n const { onRemoveToken, onChangeTokens, tokens = [] } = this.props;\n const count = tokens.length;\n if (count === 0) return;\n const id = tokenId ?? tokens[count - 1]?.id;\n\n if (onRemoveToken) {\n onRemoveToken(id ? id : \"\");\n } else if (onChangeTokens) {\n onChangeTokens(tokens.filter((tokenSpec) => tokenSpec.id !== id));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n handleChangeText = (e: React.SyntheticEvent<HTMLInputElement>) => {\n const { value } = e.currentTarget;\n const { onChange } = this.props;\n this.setState({\n value,\n });\n onChange?.(e, value);\n };\n\n handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onFocus } = this.props;\n this.setState({\n hasFocus: true,\n });\n onFocus?.(e);\n };\n\n handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onBlur } = this.props;\n if (onBlur) onBlur(e);\n this.setState({\n hasFocus: false,\n });\n };\n\n handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {\n this.props.onKeyUp?.(e, e.currentTarget.value);\n };\n\n handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n const { onKeyDown } = this.props;\n const { key, currentTarget } = e;\n const text = currentTarget.value;\n if (onKeyDown) onKeyDown(e, text);\n\n // keyPress event runs before change\n // Prevent event from bubbling up and calling change, which can lead to comma in value\n if (this.isDelimiter(key)) {\n if (text) {\n this.spawnNewTokens([text]);\n e.preventDefault();\n }\n } else if (key === \"Backspace\") {\n if (text === \"\") {\n this.deleteToken();\n }\n }\n };\n\n handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData.getData(\"text\");\n const { onPaste } = this.props;\n if (onPaste) onPaste(e, text);\n const subtexts = text.split(this.delimiterMatcher);\n const texts = subtexts.filter((subtext) => subtext.length);\n\n if (texts.length > 1) {\n this.spawnNewTokens(texts);\n e.preventDefault();\n }\n };\n\n handleClickToken = (\n e: React.SyntheticEvent<Element, Event>,\n token: TypeTokenSpec\n ) => {\n const { onClickToken, disabled } = this.props;\n if (onClickToken) onClickToken(e, token.id);\n\n if (!disabled) {\n this.deleteToken(token.id);\n }\n };\n\n renderToken(token: TypeTokenSpec): React.ReactNode {\n const { iconName: defaultIconName, disabled } = this.props;\n const activeId = this.state.activeToken;\n const {\n id,\n iconName: tokenIconName,\n iconProps = { \"aria-hidden\": true },\n value,\n valid,\n hasWarning,\n tokenProps: { onClick, ...restTokenProps } = {},\n } = token;\n const iconName = tokenIconName || defaultIconName;\n const isActive = activeId === id;\n return (\n <Token\n id={id}\n onClick={(e) => {\n this.handleClickToken(e, token);\n onClick?.(e);\n }}\n valid={valid}\n hasWarning={hasWarning}\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n active={isActive}\n disabled={disabled}\n {...restTokenProps}\n >\n <Box display=\"flex\" alignItems=\"center\">\n {iconName && (\n <Icon name={iconName} size=\"mini\" pr={300} {...iconProps} />\n )}\n {value}\n </Box>\n </Token>\n );\n }\n\n renderTokens(tokens: TypeTokenSpec[]): React.ReactNode {\n return tokens.map<React.ReactNode>((token) => (\n <div key={token.id} className=\"TokenInput-token\">\n {this.renderToken(token)}\n </div>\n ));\n }\n\n override render() {\n const {\n autoFocus,\n autocomplete,\n disabled,\n isInvalid,\n hasWarning,\n id,\n name,\n placeholder,\n required,\n elemBefore,\n elemAfter,\n maxLength,\n ariaDescribedby,\n ariaLabel,\n innerRef,\n // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct\n /* eslint-disable @typescript-eslint/no-unused-vars */\n value,\n onAddToken,\n onRemoveToken,\n onChangeTokens,\n onClickToken,\n onBlur,\n onChange,\n onFocus,\n onKeyDown,\n onKeyUp,\n onPaste,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n inputProps = {},\n qa = {},\n tokens,\n ...rest\n } = this.props;\n const { state } = this;\n return (\n <Container\n hasBeforeElement={!!elemBefore}\n hasAfterElement={!!elemAfter}\n disabled={disabled}\n invalid={!!isInvalid}\n warning={hasWarning}\n focused={state.hasFocus}\n {...rest}\n >\n {elemBefore && <Accessory before>{elemBefore}</Accessory>}\n\n {tokens && this.renderTokens(tokens)}\n\n <TokenScreenReaderStatus tokens={tokens} />\n\n <StyledInput\n aria-describedby={ariaDescribedby}\n aria-invalid={!!isInvalid}\n aria-label={ariaLabel}\n autoFocus={autoFocus}\n autoComplete={autocomplete}\n disabled={disabled}\n id={id}\n name={name}\n placeholder={placeholder}\n type=\"text\"\n required={required}\n value={state.value}\n maxLength={maxLength}\n onBlur={this.handleBlur}\n onChange={this.handleChangeText}\n onFocus={this.handleFocus}\n onKeyDown={this.handleKeyDown}\n onKeyUp={this.handleKeyUp}\n onPaste={this.handlePaste}\n ref={innerRef}\n data-qa-input={name || \"\"}\n data-qa-input-isdisabled={!!disabled}\n data-qa-input-isrequired={!!required}\n {...qa}\n {...inputProps}\n />\n\n {elemAfter && <Accessory after>{elemAfter}</Accessory>}\n </Container>\n );\n }\n}\n","import styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport type { TypeInputContainerProps } from \"@sproutsocial/seeds-react-input\";\n\ninterface TypeTokenInputContainerProps\n extends Pick<\n TypeInputContainerProps,\n \"hasBeforeElement\" | \"hasAfterElement\" | \"disabled\" | \"invalid\" | \"warning\"\n > {\n focused?: boolean;\n}\n\nconst Container = styled.div<TypeTokenInputContainerProps>`\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n align-content: center;\n cursor: text;\n width: 100%;\n border: 1px solid ${(props) => props.theme.colors.form.border.base};\n border-radius: ${(props) => props.theme.radii[500]};\n margin: 0;\n padding: ${(props) => props.theme.space[300]};\n padding-top: ${(props) => props.theme.space[200]};\n background-color: ${(props) => props.theme.colors.form.background.base};\n color: ${(props) => props.theme.colors.text.body};\n transition: border-color ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in},\n box-shadow ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in};\n ${(props) => props.theme.typography[200]};\n font-family: ${(props) => props.theme.fontFamily};\n font-weight: ${(props) => props.theme.fontWeights.normal};\n appearance: none;\n\n button {\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[200]} 0 0;\n }\n\n input,\n textarea {\n ${(props) => props.theme.typography[200]};\n outline: none;\n border: none;\n flex: 1;\n padding: 0;\n padding-top: ${(props) => props.theme.space[100]};\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[300]} ${(props) => props.theme.space[100]}\n 0;\n color: ${(props) => props.theme.colors.text.body};\n background-color: ${(props) => props.theme.colors.form.background.base};\n /** This matches the height of the token so size does not change as tokens are added */\n min-height: 20px;\n\n &::-webkit-search-cancel-button {\n appearance: none;\n }\n\n /* Explicitly removes double focus ring in environments where box-shadow focus styles have been specified (Seeds). Focus is passed up from the input to the parent container. */\n &:focus {\n box-shadow: none;\n }\n\n /* https://stackoverflow.com/questions/14007655/remove-ie10s-clear-field-x-button-on-certain-inputs */\n &::-ms-clear {\n display: none;\n }\n\n /* Fix for red ring when input is marked required in Firefox */\n &:not(output):not(:focus):-moz-ui-invalid {\n box-shadow: none;\n }\n\n &::placeholder {\n color: ${(props) => props.theme.colors.form.placeholder.base};\n font-style: italic;\n }\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n }\n\n textarea {\n font-family: ${(props) => props.theme.fontFamily};\n }\n\n ${(props) =>\n props.hasBeforeElement &&\n css`\n padding-left: 40px;\n `}\n\n ${(props) =>\n props.hasAfterElement &&\n css`\n padding-right: 40px;\n `}\n\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n\n ${(props) =>\n props.focused &&\n css`\n ${focusRing}\n `}\n\n ${(props) =>\n props.invalid &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.error};\n `}\n\n\t${(props) =>\n props.warning &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.warning};\n `}\n\n ${COMMON}\n`;\n\nContainer.displayName = \"TokenInputContainer\";\n\nexport default Container;\n","import uniqueId from \"lodash.uniqueid\";\nimport type { TypeTokenSpec } from \"./\";\n\nexport const asTokenSpec = (text: string): TypeTokenSpec => ({\n id: uniqueId(`${text}-`),\n value: text.trim(),\n});\n\nconst KeyNameToRegExpChar: { [key: string]: string } = {\n Enter: \"\\\\n\",\n};\n\nexport const delimitersAsRegExp = (delimiters: string[] | null | undefined) => {\n if (!delimiters) return /[,\\n]/;\n const chars = delimiters\n .map(\n (key) =>\n KeyNameToRegExpChar[key as keyof typeof KeyNameToRegExpChar] || key\n )\n .join(\"\");\n return RegExp(`[${chars}]`);\n};\n","import React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\nimport type { TypeTokenInputProps } from \"./\";\n\nfunction usePrevious(value: TypeTokenInputProps[\"tokens\"]) {\n const ref = useRef<TypeTokenInputProps[\"tokens\"]>();\n\n useEffect(() => {\n ref.current = value;\n });\n\n return ref.current;\n}\n\nexport const TokenScreenReaderStatus = ({\n tokens,\n}: {\n tokens: TypeTokenInputProps[\"tokens\"];\n}) => {\n const prevTokens = usePrevious(tokens);\n const [tokenStatus, setTokenStatus] = useState(\"\");\n\n // TODO: Use callbacks so consumers can pass localized messaging to the screen reader\n useEffect(() => {\n if (prevTokens && tokens) {\n if (prevTokens.length > tokens.length) {\n setTokenStatus(\n `${\n prevTokens.filter((item) => tokens.indexOf(item) === -1)[0]?.value\n } has been removed`\n );\n }\n\n if (prevTokens.length < tokens.length) {\n setTokenStatus(`${tokens[tokens.length - 1]?.value} has been added.`);\n }\n }\n }, [prevTokens, tokens, tokenStatus]);\n\n return (\n <VisuallyHidden as=\"div\" role=\"status\">\n {tokenStatus}\n </VisuallyHidden>\n );\n};\n","import styled from \"styled-components\";\nimport { visuallyHidden } from \"@sproutsocial/seeds-react-mixins\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst StyledVisuallyHidden = styled.span`\n ${visuallyHidden}\n`;\n\nexport type VisuallyHiddenProps = ComponentPropsWithRef<\n typeof StyledVisuallyHidden\n>;\n\n// This wrapper component is needed for react-docgen to work.\n// It has issues with generating docs for the styled component directly.\nexport const VisuallyHidden = (props: VisuallyHiddenProps) => {\n return <StyledVisuallyHidden {...props} />;\n};\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type {\n TypeIconProps,\n TypeIconName,\n} from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeTokenProps } from \"@sproutsocial/seeds-react-token\";\n\nexport interface TypeTokenSpec {\n id: string;\n iconName?: TypeIconName;\n iconProps?: Omit<TypeIconProps, \"name\">;\n value: string;\n valid?: boolean;\n hasWarning?: boolean;\n tokenProps?: Partial<TypeTokenProps>;\n}\n\nexport interface TypeBaseTokenInputProps {\n /** ID of the form element, should match the \"for\" value of the associated label */\n id: string;\n name: string;\n iconName?: TypeIconName;\n\n /** Array of delimiter key names */\n delimiters?: string[];\n\n /** Current input text. Required when controlling the input text */\n value?: string;\n\n /** Current focus state. Required when controlling the focus via onFocus and onBlur */\n hasFocus?: boolean;\n\n /** Id of the currently selected token */\n activeToken?: string;\n\n /** Array of current tokens */\n tokens?: TypeTokenSpec[];\n\n /** Standard control of changing tokens. For fine-grain control use onAddToken and onRemoveToken, instead */\n onChangeTokens?: (tokens: TypeTokenSpec[]) => void;\n\n /** Fine-grained control of adding tokens. Use with onRemoveToken instead of onChangeTokens */\n onAddToken?: (tokenSpec: TypeTokenSpec) => void;\n\n /** Fine-grained control of removing tokens. Use with onAddToken instead of onChangeTokens */\n onRemoveToken?: (tokenId: string) => void;\n\n /** Controls clicking on a token. When absent, clicking a token removes itself */\n onClickToken?(e: React.SyntheticEvent<Element, Event>, tokenId: string): void;\n\n /** Fine-grained control of the input text used to create tokens */\n onChange?: (e: React.SyntheticEvent<HTMLInputElement>, value: string) => void;\n\n /** Fine-grained control of pasted text */\n onPaste?: (e: React.ClipboardEvent<HTMLInputElement>, value: string) => void;\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n\n /** Attribute used to associate other elements that describe the Input, like an error */\n ariaDescribedby?: string;\n\n /** Label used to describe the input if not used with an accompanying visual label */\n ariaLabel?: string;\n\n /** Placeholder text for when value is undefined or empty */\n placeholder?: string;\n\n /** Will autofocus the element when mounted to the DOM */\n autoFocus?: boolean;\n\n /** HTML disabled attribute */\n disabled?: boolean;\n\n /** Whether or not the current contents of the input are invalid */\n isInvalid?: boolean;\n\n /** Whether or not the current contents of the input has any warnings */\n hasWarning?: boolean;\n\n /** HTML required attribute */\n required?: boolean;\n\n /** 16x16 element, such as an icon */\n elemBefore?: React.ReactNode;\n\n /** 16x16 element, such as an icon */\n elemAfter?: React.ReactNode;\n\n /** Max input text length */\n maxLength?: number;\n\n /** Max length of the token */\n tokenMaxLength?: number;\n\n /** Props to spread onto the underlying input element */\n inputProps?: React.ComponentPropsWithoutRef<\"input\">;\n\n /** Used to get a reference to the underlying element */\n innerRef?: React.Ref<HTMLInputElement>;\n qa?: object;\n\n /** Browser autocomplete support */\n autocomplete?: string;\n}\n\nexport interface TypeTokenInputProps\n extends TypeBaseTokenInputProps,\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n keyof TypeBaseTokenInputProps | \"color\"\n > {}\n"],"mappings":"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","names":["React","import_styled_components","styled","props","uniqueId","import_react","import_styled_components","import_seeds_react_mixins","styled","import_jsx_runtime","import_jsx_runtime","styled","Token","Box","Icon","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/TokenInput.tsx","../src/styles.ts","../src/util.ts","../src/TokenScreenReaderStatus.tsx","../../seeds-react-visually-hidden/src/VisuallyHidden.tsx","../src/TokenInputTypes.ts"],"sourcesContent":["import * as React from \"react\";\nimport TokenInputClass from \"./TokenInput\";\nimport type { TypeTokenInputProps } from \"./TokenInputTypes\";\n\n/**\n * Wraps the class-based TokenInput with forwardRef so that the standard React\n * `ref` prop resolves to the root Container DOM node. This is required for\n * Radix UI's `asChild` pattern (used by seeds-react-menu's Popout) which\n * expects triggerRef to be a DOM element for `.contains()` checks.\n *\n * The existing `innerRef` prop still forwards to the underlying `<input>`.\n */\nconst TokenInput = React.forwardRef<HTMLDivElement, TypeTokenInputProps>(\n (props, ref) =>\n React.createElement(TokenInputClass, { ...props, containerRef: ref })\n);\n\nTokenInput.displayName = \"TokenInput\";\n\nexport default TokenInput;\nexport { TokenInput };\nexport * from \"./TokenInputTypes\";\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { Accessory } from \"@sproutsocial/seeds-react-input\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Icon from \"@sproutsocial/seeds-react-icon\";\nimport Token from \"@sproutsocial/seeds-react-token\";\nimport Container from \"./styles\";\nimport { asTokenSpec, delimitersAsRegExp } from \"./util\";\nimport type { TypeTokenInputProps, TypeTokenSpec } from \"./TokenInputTypes\";\nimport { TokenScreenReaderStatus } from \"./TokenScreenReaderStatus\";\n\ntype TypeState = {\n prevProps: TypeTokenInputProps;\n hasFocus: boolean;\n activeToken: string | null | undefined;\n value: string;\n};\n\n// Simply using a styled input to allow passing the `as` prop\nconst StyledInput = styled(\"input\")``;\n\nconst DefaultDelimiters = [\",\", \"Enter\"];\nconst ControlledPropNames: (keyof TypeState)[] = [\n \"value\",\n \"hasFocus\",\n \"activeToken\",\n];\n\nexport default class TokenInput extends React.Component<\n TypeTokenInputProps,\n TypeState\n> {\n delimiterMatcher: RegExp;\n\n constructor(props: TypeTokenInputProps) {\n super(props);\n const { hasFocus, activeToken, value, delimiters } = props;\n this.delimiterMatcher = delimitersAsRegExp(delimiters || DefaultDelimiters);\n this.state = {\n prevProps: props,\n hasFocus: hasFocus || false,\n activeToken: activeToken,\n value: value || \"\",\n };\n }\n\n static getDerivedStateFromProps(\n props: Readonly<TypeTokenInputProps>,\n state: TypeState\n ) {\n const { prevProps } = state;\n const modifiedState: Partial<TypeState> = { prevProps: props };\n ControlledPropNames.forEach((propName) => {\n const currentProp = props[propName as keyof TypeTokenInputProps];\n\n // @ts-ignore: TODO - fix state types for prevProps\n if (currentProp !== prevProps[propName]) {\n modifiedState[propName] = currentProp;\n }\n });\n modifiedState.prevProps = props;\n return modifiedState;\n }\n\n isDelimiter(keyName: string) {\n const { delimiters = DefaultDelimiters } = this.props;\n return delimiters.includes(keyName);\n }\n\n spawnNewTokens(texts: string[]) {\n const {\n onAddToken,\n onChangeTokens,\n tokenMaxLength: max = Infinity,\n tokens = [],\n } = this.props;\n const tokenSpecs = texts.map((text) => asTokenSpec(text.slice(0, max)));\n\n if (onAddToken) {\n tokenSpecs.forEach(onAddToken);\n } else if (onChangeTokens) {\n onChangeTokens(tokens.concat(tokenSpecs));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n deleteToken(tokenId?: string) {\n const { onRemoveToken, onChangeTokens, tokens = [] } = this.props;\n const count = tokens.length;\n if (count === 0) return;\n const id = tokenId ?? tokens[count - 1]?.id;\n\n if (onRemoveToken) {\n onRemoveToken(id ? id : \"\");\n } else if (onChangeTokens) {\n onChangeTokens(tokens.filter((tokenSpec) => tokenSpec.id !== id));\n }\n\n this.setState({\n value: \"\",\n });\n }\n\n handleChangeText = (e: React.SyntheticEvent<HTMLInputElement>) => {\n const { value } = e.currentTarget;\n const { onChange } = this.props;\n this.setState({\n value,\n });\n onChange?.(e, value);\n };\n\n handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onFocus } = this.props;\n this.setState({\n hasFocus: true,\n });\n onFocus?.(e);\n };\n\n handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { onBlur } = this.props;\n if (onBlur) onBlur(e);\n this.setState({\n hasFocus: false,\n });\n };\n\n handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {\n this.props.onKeyUp?.(e, e.currentTarget.value);\n };\n\n handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n const { onKeyDown } = this.props;\n const { key, currentTarget } = e;\n const text = currentTarget.value;\n if (onKeyDown) onKeyDown(e, text);\n\n // keyPress event runs before change\n // Prevent event from bubbling up and calling change, which can lead to comma in value\n if (this.isDelimiter(key)) {\n if (text) {\n this.spawnNewTokens([text]);\n e.preventDefault();\n }\n } else if (key === \"Backspace\") {\n if (text === \"\") {\n this.deleteToken();\n }\n }\n };\n\n handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData.getData(\"text\");\n const { onPaste } = this.props;\n if (onPaste) onPaste(e, text);\n const subtexts = text.split(this.delimiterMatcher);\n const texts = subtexts.filter((subtext) => subtext.length);\n\n if (texts.length > 1) {\n this.spawnNewTokens(texts);\n e.preventDefault();\n }\n };\n\n handleClickToken = (\n e: React.SyntheticEvent<Element, Event>,\n token: TypeTokenSpec\n ) => {\n const { onClickToken, disabled } = this.props;\n if (onClickToken) onClickToken(e, token.id);\n\n if (!disabled) {\n this.deleteToken(token.id);\n }\n };\n\n renderToken(token: TypeTokenSpec): React.ReactNode {\n const { iconName: defaultIconName, disabled } = this.props;\n const activeId = this.state.activeToken;\n const {\n id,\n iconName: tokenIconName,\n iconProps = { \"aria-hidden\": true },\n value,\n valid,\n hasWarning,\n tokenProps: { onClick, ...restTokenProps } = {},\n } = token;\n const iconName = tokenIconName || defaultIconName;\n const isActive = activeId === id;\n return (\n <Token\n id={id}\n onClick={(e) => {\n this.handleClickToken(e, token);\n onClick?.(e);\n }}\n valid={valid}\n hasWarning={hasWarning}\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n active={isActive}\n disabled={disabled}\n {...restTokenProps}\n >\n <Box display=\"flex\" alignItems=\"center\">\n {iconName && (\n <Icon name={iconName} size=\"mini\" pr={300} {...iconProps} />\n )}\n {value}\n </Box>\n </Token>\n );\n }\n\n renderTokens(tokens: TypeTokenSpec[]): React.ReactNode {\n return tokens.map<React.ReactNode>((token) => (\n <div key={token.id} className=\"TokenInput-token\">\n {this.renderToken(token)}\n </div>\n ));\n }\n\n override render() {\n const {\n autoFocus,\n autocomplete,\n disabled,\n isInvalid,\n hasWarning,\n id,\n name,\n placeholder,\n required,\n elemBefore,\n elemAfter,\n maxLength,\n ariaDescribedby,\n ariaLabel,\n innerRef,\n containerRef,\n // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct\n /* eslint-disable @typescript-eslint/no-unused-vars */\n value,\n onAddToken,\n onRemoveToken,\n onChangeTokens,\n onClickToken,\n onBlur,\n onChange,\n onFocus,\n onKeyDown,\n onKeyUp,\n onPaste,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n inputProps = {},\n qa = {},\n tokens,\n ...rest\n } = this.props;\n const { state } = this;\n return (\n <Container\n ref={containerRef}\n hasBeforeElement={!!elemBefore}\n hasAfterElement={!!elemAfter}\n disabled={disabled}\n invalid={!!isInvalid}\n warning={hasWarning}\n focused={state.hasFocus}\n {...rest}\n >\n {elemBefore && <Accessory before>{elemBefore}</Accessory>}\n\n {tokens && this.renderTokens(tokens)}\n\n <TokenScreenReaderStatus tokens={tokens} />\n\n <StyledInput\n aria-describedby={ariaDescribedby}\n aria-invalid={!!isInvalid}\n aria-label={ariaLabel}\n autoFocus={autoFocus}\n autoComplete={autocomplete}\n disabled={disabled}\n id={id}\n name={name}\n placeholder={placeholder}\n type=\"text\"\n required={required}\n value={state.value}\n maxLength={maxLength}\n onBlur={this.handleBlur}\n onChange={this.handleChangeText}\n onFocus={this.handleFocus}\n onKeyDown={this.handleKeyDown}\n onKeyUp={this.handleKeyUp}\n onPaste={this.handlePaste}\n ref={innerRef}\n data-qa-input={name || \"\"}\n data-qa-input-isdisabled={!!disabled}\n data-qa-input-isrequired={!!required}\n {...qa}\n {...inputProps}\n />\n\n {elemAfter && <Accessory after>{elemAfter}</Accessory>}\n </Container>\n );\n }\n}\n","import styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport type { TypeInputContainerProps } from \"@sproutsocial/seeds-react-input\";\n\ninterface TypeTokenInputContainerProps\n extends Pick<\n TypeInputContainerProps,\n \"hasBeforeElement\" | \"hasAfterElement\" | \"disabled\" | \"invalid\" | \"warning\"\n > {\n focused?: boolean;\n}\n\nconst Container = styled.div<TypeTokenInputContainerProps>`\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n align-content: center;\n cursor: text;\n width: 100%;\n border: 1px solid ${(props) => props.theme.colors.form.border.base};\n border-radius: ${(props) => props.theme.radii[500]};\n margin: 0;\n padding: ${(props) => props.theme.space[300]};\n padding-top: ${(props) => props.theme.space[200]};\n background-color: ${(props) => props.theme.colors.form.background.base};\n color: ${(props) => props.theme.colors.text.body};\n transition: border-color ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in},\n box-shadow ${(props) => props.theme.duration.fast}\n ${(props) => props.theme.easing.ease_in};\n ${(props) => props.theme.typography[200]};\n font-family: ${(props) => props.theme.fontFamily};\n font-weight: ${(props) => props.theme.fontWeights.normal};\n appearance: none;\n\n button {\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[200]} 0 0;\n }\n\n input,\n textarea {\n ${(props) => props.theme.typography[200]};\n outline: none;\n border: none;\n flex: 1;\n padding: 0;\n padding-top: ${(props) => props.theme.space[100]};\n margin: ${(props) => props.theme.space[200]}\n ${(props) => props.theme.space[300]} ${(props) => props.theme.space[100]}\n 0;\n color: ${(props) => props.theme.colors.text.body};\n background-color: ${(props) => props.theme.colors.form.background.base};\n /** This matches the height of the token so size does not change as tokens are added */\n min-height: 20px;\n\n &::-webkit-search-cancel-button {\n appearance: none;\n }\n\n /* Explicitly removes double focus ring in environments where box-shadow focus styles have been specified (Seeds). Focus is passed up from the input to the parent container. */\n &:focus {\n box-shadow: none;\n }\n\n /* https://stackoverflow.com/questions/14007655/remove-ie10s-clear-field-x-button-on-certain-inputs */\n &::-ms-clear {\n display: none;\n }\n\n /* Fix for red ring when input is marked required in Firefox */\n &:not(output):not(:focus):-moz-ui-invalid {\n box-shadow: none;\n }\n\n &::placeholder {\n color: ${(props) => props.theme.colors.form.placeholder.base};\n font-style: italic;\n }\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n }\n\n textarea {\n font-family: ${(props) => props.theme.fontFamily};\n }\n\n ${(props) =>\n props.hasBeforeElement &&\n css`\n padding-left: 40px;\n `}\n\n ${(props) =>\n props.hasAfterElement &&\n css`\n padding-right: 40px;\n `}\n\n\n ${(props) =>\n props.disabled &&\n css`\n opacity: 0.4;\n\n cursor: not-allowed;\n `}\n\n ${(props) =>\n props.focused &&\n css`\n ${focusRing}\n `}\n\n ${(props) =>\n props.invalid &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.error};\n `}\n\n\t${(props) =>\n props.warning &&\n css`\n border-color: ${(props) => props.theme.colors.form.border.warning};\n `}\n\n ${COMMON}\n`;\n\nContainer.displayName = \"TokenInputContainer\";\n\nexport default Container;\n","import uniqueId from \"lodash.uniqueid\";\nimport type { TypeTokenSpec } from \"./\";\n\nexport const asTokenSpec = (text: string): TypeTokenSpec => ({\n id: uniqueId(`${text}-`),\n value: text.trim(),\n});\n\nconst KeyNameToRegExpChar: { [key: string]: string } = {\n Enter: \"\\\\n\",\n};\n\nexport const delimitersAsRegExp = (delimiters: string[] | null | undefined) => {\n if (!delimiters) return /[,\\n]/;\n const chars = delimiters\n .map(\n (key) =>\n KeyNameToRegExpChar[key as keyof typeof KeyNameToRegExpChar] || key\n )\n .join(\"\");\n return RegExp(`[${chars}]`);\n};\n","import React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { VisuallyHidden } from \"@sproutsocial/seeds-react-visually-hidden\";\nimport type { TypeTokenInputProps } from \"./\";\n\nfunction usePrevious(value: TypeTokenInputProps[\"tokens\"]) {\n const ref = useRef<TypeTokenInputProps[\"tokens\"]>();\n\n useEffect(() => {\n ref.current = value;\n });\n\n return ref.current;\n}\n\nexport const TokenScreenReaderStatus = ({\n tokens,\n}: {\n tokens: TypeTokenInputProps[\"tokens\"];\n}) => {\n const prevTokens = usePrevious(tokens);\n const [tokenStatus, setTokenStatus] = useState(\"\");\n\n // TODO: Use callbacks so consumers can pass localized messaging to the screen reader\n useEffect(() => {\n if (prevTokens && tokens) {\n if (prevTokens.length > tokens.length) {\n setTokenStatus(\n `${\n prevTokens.filter((item) => tokens.indexOf(item) === -1)[0]?.value\n } has been removed`\n );\n }\n\n if (prevTokens.length < tokens.length) {\n setTokenStatus(`${tokens[tokens.length - 1]?.value} has been added.`);\n }\n }\n }, [prevTokens, tokens, tokenStatus]);\n\n return (\n <VisuallyHidden as=\"div\" role=\"status\">\n {tokenStatus}\n </VisuallyHidden>\n );\n};\n","import styled from \"styled-components\";\nimport { visuallyHidden } from \"@sproutsocial/seeds-react-mixins\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nconst StyledVisuallyHidden = styled.span`\n ${visuallyHidden}\n`;\n\nexport type VisuallyHiddenProps = ComponentPropsWithRef<\n typeof StyledVisuallyHidden\n>;\n\n// This wrapper component is needed for react-docgen to work.\n// It has issues with generating docs for the styled component directly.\nexport const VisuallyHidden = (props: VisuallyHiddenProps) => {\n return <StyledVisuallyHidden {...props} />;\n};\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type {\n TypeIconProps,\n TypeIconName,\n} from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeTokenProps } from \"@sproutsocial/seeds-react-token\";\n\nexport interface TypeTokenSpec {\n id: string;\n iconName?: TypeIconName;\n iconProps?: Omit<TypeIconProps, \"name\">;\n value: string;\n valid?: boolean;\n hasWarning?: boolean;\n tokenProps?: Partial<TypeTokenProps>;\n}\n\nexport interface TypeBaseTokenInputProps {\n /** ID of the form element, should match the \"for\" value of the associated label */\n id: string;\n name: string;\n iconName?: TypeIconName;\n\n /** Array of delimiter key names */\n delimiters?: string[];\n\n /** Current input text. Required when controlling the input text */\n value?: string;\n\n /** Current focus state. Required when controlling the focus via onFocus and onBlur */\n hasFocus?: boolean;\n\n /** Id of the currently selected token */\n activeToken?: string;\n\n /** Array of current tokens */\n tokens?: TypeTokenSpec[];\n\n /** Standard control of changing tokens. For fine-grain control use onAddToken and onRemoveToken, instead */\n onChangeTokens?: (tokens: TypeTokenSpec[]) => void;\n\n /** Fine-grained control of adding tokens. Use with onRemoveToken instead of onChangeTokens */\n onAddToken?: (tokenSpec: TypeTokenSpec) => void;\n\n /** Fine-grained control of removing tokens. Use with onAddToken instead of onChangeTokens */\n onRemoveToken?: (tokenId: string) => void;\n\n /** Controls clicking on a token. When absent, clicking a token removes itself */\n onClickToken?(e: React.SyntheticEvent<Element, Event>, tokenId: string): void;\n\n /** Fine-grained control of the input text used to create tokens */\n onChange?: (e: React.SyntheticEvent<HTMLInputElement>, value: string) => void;\n\n /** Fine-grained control of pasted text */\n onPaste?: (e: React.ClipboardEvent<HTMLInputElement>, value: string) => void;\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement>, value: string) => void;\n\n /** Attribute used to associate other elements that describe the Input, like an error */\n ariaDescribedby?: string;\n\n /** Label used to describe the input if not used with an accompanying visual label */\n ariaLabel?: string;\n\n /** Placeholder text for when value is undefined or empty */\n placeholder?: string;\n\n /** Will autofocus the element when mounted to the DOM */\n autoFocus?: boolean;\n\n /** HTML disabled attribute */\n disabled?: boolean;\n\n /** Whether or not the current contents of the input are invalid */\n isInvalid?: boolean;\n\n /** Whether or not the current contents of the input has any warnings */\n hasWarning?: boolean;\n\n /** HTML required attribute */\n required?: boolean;\n\n /** 16x16 element, such as an icon */\n elemBefore?: React.ReactNode;\n\n /** 16x16 element, such as an icon */\n elemAfter?: React.ReactNode;\n\n /** Max input text length */\n maxLength?: number;\n\n /** Max length of the token */\n tokenMaxLength?: number;\n\n /** Props to spread onto the underlying input element */\n inputProps?: React.ComponentPropsWithoutRef<\"input\">;\n\n /** Used to get a reference to the underlying input element */\n innerRef?: React.Ref<HTMLInputElement>;\n\n /** Ref forwarded to the root container element (used by Radix asChild) */\n containerRef?: React.Ref<HTMLDivElement>;\n qa?: object;\n\n /** Browser autocomplete support */\n autocomplete?: string;\n}\n\nexport interface TypeTokenInputProps\n extends TypeBaseTokenInputProps,\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n keyof TypeBaseTokenInputProps | \"color\"\n > {}\n"],"mappings":"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","names":["TokenInput","React","React","import_styled_components","styled","props","uniqueId","import_react","import_styled_components","import_seeds_react_mixins","styled","import_jsx_runtime","import_jsx_runtime","styled","Token","Box","Icon","React","TokenInput"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-token-input",
3
- "version": "1.4.30",
3
+ "version": "1.4.31",
4
4
  "description": "Seeds React TokenInput",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -242,6 +242,7 @@ export default class TokenInput extends React.Component<
242
242
  ariaDescribedby,
243
243
  ariaLabel,
244
244
  innerRef,
245
+ containerRef,
245
246
  // These functions are used in the class functions above, but need to be extracted in order for `rest` to be correct
246
247
  /* eslint-disable @typescript-eslint/no-unused-vars */
247
248
  value,
@@ -264,6 +265,7 @@ export default class TokenInput extends React.Component<
264
265
  const { state } = this;
265
266
  return (
266
267
  <Container
268
+ ref={containerRef}
267
269
  hasBeforeElement={!!elemBefore}
268
270
  hasAfterElement={!!elemAfter}
269
271
  disabled={disabled}
@@ -101,8 +101,11 @@ export interface TypeBaseTokenInputProps {
101
101
  /** Props to spread onto the underlying input element */
102
102
  inputProps?: React.ComponentPropsWithoutRef<"input">;
103
103
 
104
- /** Used to get a reference to the underlying element */
104
+ /** Used to get a reference to the underlying input element */
105
105
  innerRef?: React.Ref<HTMLInputElement>;
106
+
107
+ /** Ref forwarded to the root container element (used by Radix asChild) */
108
+ containerRef?: React.Ref<HTMLDivElement>;
106
109
  qa?: object;
107
110
 
108
111
  /** Browser autocomplete support */
package/src/index.ts CHANGED
@@ -1,4 +1,21 @@
1
- import TokenInput from "./TokenInput";
1
+ import * as React from "react";
2
+ import TokenInputClass from "./TokenInput";
3
+ import type { TypeTokenInputProps } from "./TokenInputTypes";
4
+
5
+ /**
6
+ * Wraps the class-based TokenInput with forwardRef so that the standard React
7
+ * `ref` prop resolves to the root Container DOM node. This is required for
8
+ * Radix UI's `asChild` pattern (used by seeds-react-menu's Popout) which
9
+ * expects triggerRef to be a DOM element for `.contains()` checks.
10
+ *
11
+ * The existing `innerRef` prop still forwards to the underlying `<input>`.
12
+ */
13
+ const TokenInput = React.forwardRef<HTMLDivElement, TypeTokenInputProps>(
14
+ (props, ref) =>
15
+ React.createElement(TokenInputClass, { ...props, containerRef: ref })
16
+ );
17
+
18
+ TokenInput.displayName = "TokenInput";
2
19
 
3
20
  export default TokenInput;
4
21
  export { TokenInput };