Custom Component: Tagify

Hello! I’ve made some custom components on dash, and am having a bit of trouble with a Tagify component (based on the MixedTags variant here from this repo).

This Tagify component allows users to mix tags and free text, for things like comment fields, etc. so quite a useful and versatile one!

I don’t have much React experience, so might be missing something, but the Tagify component seems to be having issues with setProps.

I’m using my Tagify component inside a Stepper, and have noticed that the Tagify will clear (despite the value still being retrievable) when I switch to a different step and come back. If I apply setProps on the value, then the dropdown that appears inside the Tagify to select tags is no longer clickable.

Here is my Tagify code so far. Would love some feedback if anyone has ideas!

import React, { useCallback } from "react";
import PropTypes from "prop-types";
import { MixedTags } from "@yaireo/tagify/react";
import "@yaireo/tagify/dist/tagify.css";

/** 
 * A Tagify Component
 * Based on: https://codesandbox.io/p/sandbox/tagify-react-wrapper-forked-sgd5xv?file=%2Fsrc%2FMixedModeTagify.jsx
 */

const TagifyTextField = ({ id, whitelist, active_value, value, enforceWhitelist, dropdown, pattern, setProps}) => {
  const onChange = useCallback((e) => {
    setProps({ active_value: e.detail.value }); // This provides a value that can be accessed in callbacks
    setProps({ value: e.detail.value}); // This shows the populated field, but doesn't let dropdown work
  }, [setProps]);

  const settings = {
      enforceWhitelist: enforceWhitelist,
      dropdown: dropdown,
      pattern: pattern,
  };

  return (
      <MixedTags
        id={id}
        autoFocus={true}
        settings={{ ...settings }}
        className="myTags"
        onChange={onChange}
        whitelist= {whitelist}
        value={value}
      />
  );
};

TagifyTextField.defaultProps = {
  enforceWhitelist: true,
  whitelist: [],
  value: "",
  pattern: /@/, // <- must define "patten" in mixed mode
  dropdown: {
    enabled: 1,
    position: "text",
  },
};

TagifyTextField.propTypes = {
  /**
   * The id used by dash to identify the component
   */
  id: PropTypes.node,

  /**
   * The value to access in read callbacks. You must output to this 
   * property AND value to update the value of the Tagify!
   */
  active_value: PropTypes.string,

  /**
   * The dropdown settings
   */
  dropdown: PropTypes.shape({
    enabled: PropTypes.number,
    position: PropTypes.string,
  }),

  /**
   * Whether only whitelist tags are allowed
   */
  enforceWhitelist: PropTypes.bool,

  /**
   * The pattern to use for the tags
   */
  pattern: PropTypes.instanceOf(RegExp),

  /**
   * Dash-assigned callback that should be called whenever any of the
   * properties change
   */
  setProps: PropTypes.func,

  /**
   * The value of the Tagify
   */
  value: PropTypes.string,

  /**
   * The allowed tags
   */
  whitelist: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number.isRequired,
      value: PropTypes.string.isRequired,
      details: PropTypes.string
    })
  )
};

export default TagifyTextField;

Here’s an example usage:

my_library.TagifyTextField(
    id="tagify",
    whitelist=[
        { "id": 1, "value": "a", "details": "a"},
        { "id": 2, "value": "b", "details": "b"},
        { "id": 3, "value": "c type", "details": "c"},
        { "id": 4, "value": "d", "details": "d"},
    ],
    enforceWhitelist=True,
)

@PipInstallPython - just saw your post about all your custom components! Any tips?

I’d would personally just use Dash mantine components and save myself the struggle of making a new component. :sweat_smile: But if you are on a mission to make MixedTags an actual component, I’ll encourage your madness.

I have this support video thats ~1h long that covers this topic in depth, recommend watching at 2x speed.

But my suggestions for making a component boil down to using the right tool, I use claude.ai to help me build all of the dash components I’ve released so far.

From a glance the const TagifyTextField looks relatively small and could be built out further, also i checked the repo you included and their is many more props in Settings, Hooks, Events and Methods which are just not addressed in your code. I’d recommend taking as many files from the github repo like that README file and examples of how it works like in Tagify - Tags input Component and feed that into an Ai as project knowledge and just ask the right questions. Test out the response. Fix an aspect of it. Test again. Ask the Ai… and so on until you get it resolved.

Hope this helps and GL,
Pip

1 Like