index.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import React from 'react';
  2. import { Node, mergeAttributes } from '@tiptap/core';
  3. import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react';
  4. import type { NodeViewProps } from '@tiptap/react';
  5. import { useCallback } from 'react';
  6. import { Select } from '../../../index';
  7. import { getCustomSlotAttribute } from '@douyinfe/semi-foundation/aiChatInput/utils';
  8. import { strings } from '@douyinfe/semi-foundation/aiChatInput/constants';
  9. function SelectSlotComponent(props: NodeViewProps) {
  10. const { node, updateAttributes } = props;
  11. const value: string = node.attrs.value ?? '';
  12. const options: Array<{ value: string; label: string }> = JSON.parse(node.attrs.options || '[]').
  13. map((option: string) => ({ value: option, label: option }));
  14. const handleChange = useCallback(
  15. (val: string | number | any[] | Record<string, any> | undefined) => {
  16. if (typeof val === 'string') {
  17. updateAttributes({ value: val });
  18. }
  19. },
  20. [updateAttributes],
  21. );
  22. return (
  23. <NodeViewWrapper className="select-slot-wrapper">
  24. <Select
  25. className="select-slot"
  26. optionList={options}
  27. value={value}
  28. onChange={handleChange}
  29. />
  30. </NodeViewWrapper>
  31. );
  32. }
  33. const SelectSlot = Node.create({
  34. name: 'selectSlot',
  35. inline: true,
  36. group: 'inline',
  37. atom: true,
  38. selectable: false,
  39. addAttributes() {
  40. return {
  41. value: {
  42. default: strings.ZERO_WIDTH_CHAR,
  43. parseHTML: (element: HTMLElement) =>
  44. element.getAttribute('value'),
  45. renderHTML: (attrs: Record<string, any>) => ({ value: attrs.value }),
  46. },
  47. options: {
  48. default: '',
  49. parseHTML: (element: HTMLElement) =>
  50. element.getAttribute('options') || '',
  51. renderHTML: (attrs: Record<string, any>) => attrs.options ? { options: attrs.options } : {},
  52. },
  53. isCustomSlot: getCustomSlotAttribute(),
  54. };
  55. },
  56. parseHTML() {
  57. return [ {
  58. tag: 'select-slot',
  59. }];
  60. },
  61. renderHTML({ HTMLAttributes }) {
  62. return ['select-slot', mergeAttributes(HTMLAttributes)];
  63. },
  64. addNodeView() {
  65. return ReactNodeViewRenderer(SelectSlotComponent);
  66. },
  67. });
  68. export default SelectSlot;