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,
)