• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 8536869866

03 Apr 2024 10:05AM CUT coverage: 21.234% (-0.3%) from 21.535%
8536869866

Pull #514

github

web-flow
Merge 91a25d710 into 45ee7ebb3
Pull Request #514: refactor: user and link selector

1394 of 2532 branches covered (55.06%)

27 of 1620 new or added lines in 60 files covered. (1.67%)

4 existing lines in 2 files now uncovered.

14588 of 68702 relevant lines covered (21.23%)

2.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/sdk/src/components/editor/select/Editor.tsx
1
import { X } from '@teable/icons';
×
2
import { Button, Popover, PopoverContent, PopoverTrigger, cn } from '@teable/ui-lib';
×
3
import { keyBy } from 'lodash';
×
4
import type { ForwardRefRenderFunction } from 'react';
×
5
import { forwardRef, useImperativeHandle, useMemo, useRef, useState } from 'react';
×
6
import type { IEditorRef } from '../type';
×
7
import type { ISelectEditorMain, ISelectValue } from './EditorMain';
×
8
import { SelectEditorMain } from './EditorMain';
×
9
import { SelectTag } from './SelectTag';
×
10

×
11
const SelectEditorBase: ForwardRefRenderFunction<
×
12
  IEditorRef<string | string[] | undefined>,
×
13
  ISelectEditorMain<boolean> & { onOptionAdd?: (name: string) => Promise<void> }
×
14
> = (props, ref) => {
×
15
  const { value, options = [], isMultiple, onChange, className, style, readonly } = props;
×
16
  const [open, setOpen] = useState(false);
×
17
  const selectRef = useRef<HTMLButtonElement>(null);
×
18
  const editorRef = useRef<IEditorRef<string | string[] | undefined>>(null);
×
19

×
20
  const optionsMap = useMemo(() => keyBy(options, 'value'), [options]);
×
21
  const arrayValue = isMultiple ? (value as string[]) : value ? [value] : [];
×
22

×
23
  const displayOptions = arrayValue?.map((value) => optionsMap[value as string]).filter(Boolean);
×
24

×
25
  useImperativeHandle(ref, () => ({
×
26
    focus: () => editorRef.current?.focus?.(),
×
27
    setValue: (value?: string | string[]) => {
×
28
      editorRef.current?.setValue?.(value);
×
29
    },
×
30
  }));
×
31

×
32
  const onDelete = (val: string) => {
×
33
    const newValue = isMultiple ? (value as string[])?.filter((v) => v !== val) : undefined;
×
34
    onChange?.(newValue as ISelectValue<boolean>);
×
35
  };
×
36

×
37
  const onChangeInner = (val?: string | string[]) => {
×
38
    onChange?.(val as ISelectValue<boolean>);
×
39
    if (!isMultiple) {
×
40
      setOpen(false);
×
41
    }
×
42
  };
×
43

×
44
  const triggerContent = (
×
45
    <Button
×
46
      style={style}
×
47
      variant="outline"
×
48
      role="combobox"
×
49
      aria-expanded={open}
×
50
      className={cn(
×
NEW
51
        'w-full h-auto min-h-[32px] flex py-1 flex-wrap justify-start hover:bg-transparent gap-1.5',
×
52
        className
×
53
      )}
×
54
    >
×
55
      {displayOptions?.map(({ value, label, backgroundColor, color }) => (
×
56
        <SelectTag
×
57
          className="flex items-center"
×
58
          key={value}
×
59
          label={label}
×
60
          color={color}
×
61
          backgroundColor={backgroundColor}
×
62
        >
×
63
          {!readonly && (
×
64
            <X
×
65
              className="cursor-pointer opacity-50 hover:opacity-100"
×
66
              onClick={(e) => {
×
67
                e.preventDefault();
×
68
                onDelete(value);
×
69
              }}
×
70
            />
×
71
          )}
×
72
        </SelectTag>
×
73
      ))}
×
74
    </Button>
×
75
  );
×
76

×
77
  return (
×
78
    <>
×
79
      {readonly ? (
×
80
        triggerContent
×
81
      ) : (
×
82
        <Popover open={open} onOpenChange={setOpen} modal>
×
83
          <PopoverTrigger ref={selectRef} asChild>
×
84
            {triggerContent}
×
85
          </PopoverTrigger>
×
86
          <PopoverContent className="p-0" style={{ width: selectRef.current?.offsetWidth || 0 }}>
×
87
            <SelectEditorMain ref={editorRef} {...props} onChange={onChangeInner} />
×
88
          </PopoverContent>
×
89
        </Popover>
×
90
      )}
×
91
    </>
×
92
  );
×
93
};
×
94

×
95
export const SelectEditor = forwardRef(SelectEditorBase);
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc