-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfield-type.tsx
More file actions
140 lines (131 loc) · 4.11 KB
/
field-type.tsx
File metadata and controls
140 lines (131 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { spacing, color } from '@leafygreen-ui/tokens';
import { Select, Option } from '@leafygreen-ui/select';
import Icon from '@leafygreen-ui/icon';
import { useEffect, useRef, useState } from 'react';
import { ellipsisTruncation } from '@/styles/styles';
import { FieldTypeContent } from '@/components/field/field-type-content';
import { FieldId } from '@/types';
import { useEditableDiagramInteractions } from '@/hooks/use-editable-diagram-interactions';
const FieldTypeWrapper = styled.div<{ color: string; placeholderCollapse?: boolean }>`
color: ${props => props.color};
font-weight: normal;
padding-left: ${spacing[100]}px;
padding-right: ${props => (props.placeholderCollapse ? spacing[600] : spacing[50])}px;
flex: 0 0 100px;
display: flex;
justify-content: flex-end;
align-items: center;
`;
const FieldContentWrapper = styled.div`
max-width: ${spacing[200] * 10}px;
${ellipsisTruncation}
`;
const CaretIconWrapper = styled.div`
display: flex;
`;
const StyledSelect = styled(Select)`
visibility: hidden;
height: 0;
width: 0;
& > button {
height: 0;
width: 0;
border: none;
box-shadow: none;
}
`;
export function FieldType({
id,
type,
nodeId,
isEditing,
isDisabled,
onChange,
placeholderCollapse,
}: {
id: FieldId;
nodeId: string;
type: string | string[] | undefined;
isEditing: boolean;
isDisabled: boolean;
onChange: (newType: string[]) => void;
placeholderCollapse?: boolean;
}) {
const internalTheme = useTheme();
const { theme } = useDarkMode();
const { fieldTypes } = useEditableDiagramInteractions();
const [isSelectOpen, setIsSelectOpen] = useState(false);
const fieldTypeRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!isEditing) {
setIsSelectOpen(false);
}
}, [isEditing]);
const getSecondaryTextColor = () => {
if (isDisabled) {
return internalTheme.node.disabledColor;
}
return color[theme].text.secondary.default;
};
return (
<FieldTypeWrapper
ref={fieldTypeRef}
{...(isEditing
? {
onClick: () => setIsSelectOpen(!isSelectOpen),
}
: undefined)}
color={getSecondaryTextColor()}
placeholderCollapse={placeholderCollapse}
>
{/**
* Rendering hidden select first so that whenever popover shows it, its relative
* to the field type position. LG Select does not provide a way to set the
* position of the popover using refs.
*/}
{isEditing && (
<StyledSelect
aria-label="Select field type"
size="xsmall"
renderMode="portal"
open={isSelectOpen}
onChange={val => {
if (val) {
// Currently its a single select, so we are returning it as an array.
// That way once we have multi-select support, we don't need to change
// the API and it should work seemlessly for clients.
// Trigger onChange only if the value is different
if (type !== val) {
onChange([val]);
}
setIsSelectOpen(false);
}
}}
// As its not multi-select, we can just use the first value. Once LG-5657
// is implemented, we can use ComboBox component for multi-select support
value={Array.isArray(type) ? type[0] : type || ''}
allowDeselect={false}
dropdownWidthBasis="option"
tabIndex={0}
>
{fieldTypes!.map(fieldType => (
<Option key={fieldType} value={fieldType}>
{fieldType}
</Option>
))}
</StyledSelect>
)}
<FieldContentWrapper>
<FieldTypeContent type={type} nodeId={nodeId} id={id} isAddFieldToObjectDisabled={isEditing} />
</FieldContentWrapper>
{isEditing && (
<CaretIconWrapper title="Select field type" aria-label="Select field type">
<Icon glyph="CaretDown" />
</CaretIconWrapper>
)}
</FieldTypeWrapper>
);
}