<commit_before>import {DefaultProps, Plugin, Props, ReferenceElement, Tippy} from './types';
import {
  hasOwnProperty,
  removeProperties,
  invokeWithArgsOrReturn,
} from './utils';
import {warnWhen} from './validation';
import {TIPPY_DEFAULT_APPEND_TO} from './constants';

const pluginProps = {
  animateFill: false,
  followCursor: false,
  inlinePositioning: false,
  sticky: false,
};

const renderProps = {
  allowHTML: false,
  animation: 'fade',
  arrow: true,
  content: '',
  inertia: false,
  maxWidth: 350,
  role: 'tooltip',
  theme: '',
  zIndex: 9999,
};

export const defaultProps: DefaultProps = {
  appendTo: TIPPY_DEFAULT_APPEND_TO,
  aria: {
    content: 'auto',
    expanded: 'auto',
  },
  delay: 0,
  duration: [300, 250],
  getReferenceClientRect: null,
  hideOnClick: true,
  ignoreAttributes: false,
  interactive: false,
  interactiveBorder: 2,
  interactiveDebounce: 0,
  moveTransition: '',
  offset: [0, 10],
  onAfterUpdate() {},
  onBeforeUpdate() {},
  onCreate() {},
  onDestroy() {},
  onHidden() {},
  onHide() {},
  onMount() {},
  onShow() {},
  onShown() {},
  onTrigger() {},
  onUntrigger() {},
  onClickOutside() {},
  placement: 'top',
  plugins: [],
  popperOptions: {},
  render: null,
  showOnCreate: false,
  touch: true,
  trigger: 'mouseenter focus',
  triggerTarget: null,
  ...pluginProps,
  ...renderProps,
};

const defaultKeys = Object.keys(defaultProps);

export const setDefaultProps: Tippy['setDefaultProps'] = (partialProps) => {
  /* istanbul ignore else */
  if (__DEV__) {
    validateProps(partialProps, []);
  }

  const keys = Object.keys(partialProps) as Array<keyof DefaultProps>;
  keys.forEach((key) => {
    (defaultProps as any)[key] = partialProps[key];
  });
};

export function getExtendedPassedProps(
  passedProps: Partial<Props> & Record<string, unknown>
): Partial<Props> {
  const plugins = passedProps.plugins || [];
  const pluginProps = plugins.reduce<Record<string, unknown>>((acc, plugin) => {
    const {name, defaultValue} = plugin;

    if (name) {
      acc[name] =
        passedProps[name] !== undefined
          ? passedProps[name]
          : (defaultProps as any)[name] ?? defaultValue;
    }

    return acc;
  }, {});

  return {
    ...passedProps,
    ...pluginProps,
  };
}<commit_msg>fix: pass plugins to `validateProps` in `setDefaultProps` (#1025)<commit_after>import {DefaultProps, Plugin, Props, ReferenceElement, Tippy} from './types';
import {
  hasOwnProperty,
  removeProperties,
  invokeWithArgsOrReturn,
} from './utils';
import {warnWhen} from './validation';
import {TIPPY_DEFAULT_APPEND_TO} from './constants';

const pluginProps = {
  animateFill: false,
  followCursor: false,
  inlinePositioning: false,
  sticky: false,
};

const renderProps = {
  allowHTML: false,
  animation: 'fade',
  arrow: true,
  content: '',
  inertia: false,
  maxWidth: 350,
  role: 'tooltip',
  theme: '',
  zIndex: 9999,
};

export const defaultProps: DefaultProps = {
  appendTo: TIPPY_DEFAULT_APPEND_TO,
  aria: {
    content: 'auto',
    expanded: 'auto',
  },
  delay: 0,
  duration: [300, 250],
  getReferenceClientRect: null,
  hideOnClick: true,
  ignoreAttributes: false,
  interactive: false,
  interactiveBorder: 2,
  interactiveDebounce: 0,
  moveTransition: '',
  offset: [0, 10],
  onAfterUpdate() {},
  onBeforeUpdate() {},
  onCreate() {},
  onDestroy() {},
  onHidden() {},
  onHide() {},
  onMount() {},
  onShow() {},
  onShown() {},
  onTrigger() {},
  onUntrigger() {},
  onClickOutside() {},
  placement: 'top',
  plugins: [],
  popperOptions: {},
  render: null,
  showOnCreate: false,
  touch: true,
  trigger: 'mouseenter focus',
  triggerTarget: null,
  ...pluginProps,
  ...renderProps,
};

const defaultKeys = Object.keys(defaultProps);

export const setDefaultProps: Tippy['setDefaultProps'] = (partialProps) => {
  /* istanbul ignore else */
  if (__DEV__) {
    const plugins = defaultProps.plugins.concat(partialProps.plugins || []);
    validateProps(partialProps, plugins);
  }

  const keys = Object.keys(partialProps) as Array<keyof DefaultProps>;
  keys.forEach((key) => {
    (defaultProps as any)[key] = partialProps[key];
  });
};

export function getExtendedPassedProps(
  passedProps: Partial<Props> & Record<string, unknown>
): Partial<Props> {
  const plugins = passedProps.plugins || [];
  const pluginProps = plugins.reduce<Record<string, unknown>>((acc, plugin) => {
    const {name, defaultValue} = plugin;

    if (name) {
      acc[name] =
        passedProps[name] !== undefined
          ? passedProps[name]
          : (defaultProps as any)[name] ?? defaultValue;
    }

    return acc;
  }, {});

  return {
    ...passedProps,
    ...pluginProps,
  };
}
{'fraction_non_alphanumeric': 0.15539965986394558, 'fraction_numerical': 0.008928571428571428, 'mean_word_length': 3.855521155830753, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6108088', 'n_tokens_mistral': 1561, 'n_tokens_neox': 1515, 'n_words': 353}