@teamturing/react-kit 2.16.3 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import styled from 'styled-components';
2
+ import { forcePixelValue } from '../../utils/forcePixelValue.js';
2
3
  import { sx } from '../../utils/styled-system/index.js';
3
4
  import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js';
4
5
 
@@ -10,6 +11,14 @@ const DatagridBody = ({
10
11
  const BaseDatagridBody = styled.div`
11
12
  width: inherit;
12
13
 
14
+ & > div:not(:last-child) {
15
+ border-bottom-width: ${forcePixelValue(1)};
16
+ border-bottom-style: solid;
17
+ border-bottom-color: ${({
18
+ theme
19
+ }) => theme.colors['border/neutral']};
20
+ }
21
+
13
22
  ${sx}
14
23
  `;
15
24
 
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components';
2
+ import { forcePixelValue } from '../../utils/forcePixelValue.js';
3
+ import { sx } from '../../utils/styled-system/index.js';
4
+ import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js';
5
+
6
+ const DatagridSubheader = ({
7
+ ...props
8
+ }) => /*#__PURE__*/jsxRuntimeExports.jsx(DataGridSubheaderWrapper, {
9
+ ...props
10
+ });
11
+ const DataGridSubheaderWrapper = styled.div`
12
+ padding: ${({
13
+ theme
14
+ }) => `${forcePixelValue(theme.space[2])} ${forcePixelValue(theme.space[4])}`};
15
+ background-color: ${({
16
+ theme
17
+ }) => theme.colors.surface};
18
+
19
+ border-bottom-width: ${forcePixelValue(1)};
20
+ border-bottom-style: solid;
21
+ border-bottom-color: ${({
22
+ theme
23
+ }) => theme.colors['border/neutral']};
24
+
25
+ ${sx};
26
+ `;
27
+
28
+ export { DatagridSubheader as default };
@@ -6,6 +6,7 @@ import DatagridBody from './DatagridBody.js';
6
6
  import DatagridCell from './DatagridCell.js';
7
7
  import DatagridHeader from './DatagridHeader.js';
8
8
  import DatagridRow from './DatagridRow.js';
9
+ import DatagridSubheader from './DatagridSubheader.js';
9
10
  import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js';
10
11
 
11
12
  const Datagrid = ({
@@ -16,12 +17,13 @@ const Datagrid = ({
16
17
  const [relocatableComponentsObject, restConmponents] = useRelocation({
17
18
  children,
18
19
  config: {
19
- header: DatagridHeader
20
+ header: DatagridHeader,
21
+ subHeader: DatagridSubheader
20
22
  }
21
23
  });
22
24
  return /*#__PURE__*/jsxRuntimeExports.jsxs(DatagridWrapper, {
23
25
  sx: sx,
24
- children: [relocatableComponentsObject.header, /*#__PURE__*/jsxRuntimeExports.jsx(BaseDatagrid, {
26
+ children: [relocatableComponentsObject.header, relocatableComponentsObject.subHeader, /*#__PURE__*/jsxRuntimeExports.jsx(BaseDatagrid, {
25
27
  ...props,
26
28
  children: restConmponents
27
29
  })]
@@ -48,6 +50,7 @@ const BaseDatagrid = styled.div`
48
50
  `;
49
51
  var index = Object.assign(Datagrid, {
50
52
  Header: DatagridHeader,
53
+ Subheader: DatagridSubheader,
51
54
  Body: DatagridBody,
52
55
  Row: DatagridRow,
53
56
  Cell: DatagridCell
@@ -0,0 +1,117 @@
1
+ import 'react';
2
+ import SvgDocument from '../../packages/icons/esm/Document.js';
3
+ import styled from 'styled-components';
4
+ import '../../node_modules/styled-system/dist/index.esm.js';
5
+ import { sx } from '../../utils/styled-system/index.js';
6
+ import Button from '../Button/index.js';
7
+ import Text from '../Text/index.js';
8
+ import View from '../View/index.js';
9
+ import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js';
10
+ import { variant } from '../../node_modules/@styled-system/variant/dist/index.esm.js';
11
+
12
+ const EmptyState = ({
13
+ title,
14
+ icon: Icon = SvgDocument,
15
+ description,
16
+ action,
17
+ renderAction = ({
18
+ ...buttonProps
19
+ }, emptyStateProps) => /*#__PURE__*/jsxRuntimeExports.jsx(Button, {
20
+ size: emptyStateProps.size,
21
+ ...buttonProps
22
+ }),
23
+ size = 'm',
24
+ sx
25
+ }) => {
26
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(BaseEmptyState, {
27
+ size: size,
28
+ sx: sx,
29
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(Icon, {}), /*#__PURE__*/jsxRuntimeExports.jsx(Text, {
30
+ as: 'p',
31
+ children: title
32
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(Text, {
33
+ children: description
34
+ }), action ? /*#__PURE__*/jsxRuntimeExports.jsx(View, {
35
+ children: renderAction(action, {
36
+ size
37
+ })
38
+ }) : null]
39
+ });
40
+ };
41
+ const BaseEmptyState = styled.div`
42
+ display: flex;
43
+ flex-direction: column;
44
+ align-items: center;
45
+
46
+ & > svg {
47
+ color: ${({
48
+ theme
49
+ }) => theme.colors['icon/neutral']};
50
+ }
51
+ & > p {
52
+ color: ${({
53
+ theme
54
+ }) => theme.colors['text/neutral']};
55
+ font-weight: ${({
56
+ theme
57
+ }) => theme.fontWeights.bold};
58
+ line-height: ${({
59
+ theme
60
+ }) => theme.lineHeights[2]};
61
+ }
62
+ & > span {
63
+ color: ${({
64
+ theme
65
+ }) => theme.colors['text/neutral/subtler']};
66
+ font-weight: ${({
67
+ theme
68
+ }) => theme.fontWeights.medium};
69
+ line-height: ${({
70
+ theme
71
+ }) => theme.lineHeights[2]};
72
+ }
73
+
74
+ ${variant({
75
+ prop: 'size',
76
+ variants: {
77
+ m: {
78
+ '& > svg': {
79
+ width: 64,
80
+ height: 64
81
+ },
82
+ '& > p': {
83
+ fontSize: 'm',
84
+ mt: 2
85
+ },
86
+ '& > span': {
87
+ fontSize: 's',
88
+ mt: 1
89
+ },
90
+ '& > div': {
91
+ mt: 6
92
+ }
93
+ },
94
+ s: {
95
+ '& > svg': {
96
+ width: 32,
97
+ height: 32
98
+ },
99
+ '& > p': {
100
+ fontSize: 's',
101
+ mt: 3
102
+ },
103
+ '& > span': {
104
+ fontSize: 'xs',
105
+ mt: 0.5
106
+ },
107
+ '& > div': {
108
+ mt: 3
109
+ }
110
+ }
111
+ }
112
+ })}
113
+
114
+ ${sx}
115
+ `;
116
+
117
+ export { EmptyState as default };
@@ -35,11 +35,9 @@ const Overlay = ({
35
35
  }
36
36
  }, [handleDismiss, overlayRef]);
37
37
  const handleKeyDown = useCallback(event => {
38
- switch (event.key) {
39
- case 'Escape':
40
- handleDismiss?.();
41
- event.stopPropagation();
42
- break;
38
+ if (event.key === 'Escape') {
39
+ handleDismiss?.();
40
+ event.stopPropagation();
43
41
  }
44
42
  }, [handleDismiss]);
45
43
  useEffect(() => {
@@ -92,13 +90,16 @@ const BaseOverlay = styled.div`
92
90
  prop: 'size',
93
91
  variants: {
94
92
  s: {
95
- width: forcePixelValue(256)
93
+ width: forcePixelValue(180)
96
94
  },
97
95
  m: {
98
- width: forcePixelValue(320)
96
+ width: forcePixelValue(256)
99
97
  },
100
98
  l: {
101
- width: forcePixelValue(480)
99
+ width: forcePixelValue(320)
100
+ },
101
+ auto: {
102
+ width: 'auto'
102
103
  }
103
104
  }
104
105
  })}
@@ -5,7 +5,7 @@ import { Children, cloneElement } from 'react';
5
5
  import useFocusTrap from '../../hook/useFocusTrap.js';
6
6
  import useFocusZone from '../../hook/useFocusZone.js';
7
7
  import useToggleHandler from '../../hook/useToggleHandler.js';
8
- import Overlay from '../Overlay/index.js';
8
+ import { isFunction } from '../../utils/isFunction.js';
9
9
  import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js';
10
10
  import { autoUpdate } from '../../node_modules/@floating-ui/dom/dist/floating-ui.dom.js';
11
11
  import { offset, flip, shift } from '../../node_modules/@floating-ui/core/dist/floating-ui.core.js';
@@ -13,13 +13,13 @@ import { offset, flip, shift } from '../../node_modules/@floating-ui/core/dist/f
13
13
  const OverlayPopper = ({
14
14
  children: propChildren,
15
15
  renderOverlay,
16
- overlayProps,
17
16
  placement = 'bottom-start',
18
17
  focusZoneSettings,
19
18
  focusTrapSettings
20
19
  }) => {
21
20
  const {
22
21
  refs,
22
+ elements,
23
23
  floatingStyles,
24
24
  isPositioned
25
25
  } = useFloating({
@@ -31,20 +31,28 @@ const OverlayPopper = ({
31
31
  const {
32
32
  state: isOpen,
33
33
  toggle: toggleOverlay,
34
+ on: openOverlay,
34
35
  off: closeOverlay
35
36
  } = useToggleHandler({
36
37
  initialState: false
37
38
  });
38
39
  const handleDismiss = () => {
39
- overlayProps?.onDismiss?.();
40
40
  closeOverlay();
41
41
  };
42
- const children = Children.map(propChildren, child => /*#__PURE__*/cloneElement(child, {
42
+ const defaultPopperProps = {
43
43
  onClick: toggleOverlay,
44
44
  tabIndex: 0,
45
45
  ...{
46
46
  ref: refs.setReference
47
47
  }
48
+ };
49
+ const children = isFunction(propChildren) ? propChildren({
50
+ ...defaultPopperProps
51
+ }, {
52
+ isOpen,
53
+ openOverlay
54
+ }) : Children.map(propChildren, child => /*#__PURE__*/cloneElement(child, {
55
+ ...defaultPopperProps
48
56
  }));
49
57
  useFocusZone({
50
58
  containerRef: refs.floating,
@@ -57,18 +65,20 @@ const OverlayPopper = ({
57
65
  ...focusTrapSettings
58
66
  });
59
67
  return /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
60
- children: [children, /*#__PURE__*/jsxRuntimeExports.jsx(Overlay, {
68
+ children: [children, renderOverlay({
61
69
  ref: refs.setFloating,
62
- isOpen: isOpen,
70
+ isOpen,
63
71
  dismissFocusRef: refs.reference,
64
72
  ignoreOutsideClickRefs: [refs.reference],
65
- ...overlayProps,
66
- style: floatingStyles,
67
- onDismiss: handleDismiss,
68
- children: renderOverlay({
69
- isOpen,
70
- closeOverlay
71
- })
73
+ style: {
74
+ ...floatingStyles
75
+ },
76
+ onDismiss: handleDismiss
77
+ }, {
78
+ isOpen,
79
+ closeOverlay
80
+ }, {
81
+ elements
72
82
  })]
73
83
  });
74
84
  };
@@ -0,0 +1,237 @@
1
+ import { forwardRef } from 'react';
2
+ import SvgChevronDown from '../../packages/icons/esm/ChevronDown.js';
3
+ import { noop } from '../../packages/utils/esm/noop.js';
4
+ import { r as reactIsExports } from '../../node_modules/react-is/index.js';
5
+ import styled, { css } from 'styled-components';
6
+ import useProvidedOrCreatedRef from '../../hook/useProvidedOrCreatedRef.js';
7
+ import { forcePixelValue } from '../../utils/forcePixelValue.js';
8
+ import { isFunction } from '../../utils/isFunction.js';
9
+ import { isNullable } from '../../utils/isNullable.js';
10
+ import Overlay from '../Overlay/index.js';
11
+ import OverlayPopper from '../OverlayPopper/index.js';
12
+ import StyledIcon from '../StyledIcon/index.js';
13
+ import View from '../View/index.js';
14
+ import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js';
15
+
16
+ const OverlaySelectInput = ({
17
+ validationStatus,
18
+ leadingVisual: LeadingVisual,
19
+ children,
20
+ ...props
21
+ }, ref) => {
22
+ const inputRef = useProvidedOrCreatedRef(ref);
23
+ const focusInput = () => {
24
+ inputRef.current?.focus();
25
+ };
26
+ const {
27
+ disabled
28
+ } = props;
29
+ return /*#__PURE__*/jsxRuntimeExports.jsx(OverlayPopper, {
30
+ renderOverlay: (overlayProps, _, {
31
+ elements
32
+ }) => /*#__PURE__*/jsxRuntimeExports.jsx(Overlay, {
33
+ ...overlayProps,
34
+ style: {
35
+ ...overlayProps.style,
36
+ width: elements?.reference?.getBoundingClientRect().width
37
+ },
38
+ children: children
39
+ }),
40
+ children: (popperProps, {
41
+ openOverlay
42
+ }) => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
43
+ ...popperProps,
44
+ tabIndex: disabled ? -1 : 0,
45
+ disabled: disabled,
46
+ onClick: focusInput,
47
+ hasLeadingVisual: !isNullable(LeadingVisual),
48
+ validationStatus: validationStatus,
49
+ onKeyDown: e => {
50
+ if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
51
+ e.preventDefault();
52
+ openOverlay();
53
+ }
54
+ },
55
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
56
+ sx: {
57
+ 'flexShrink': 0,
58
+ 'fontSize': 'xxs',
59
+ 'fontWeight': 'medium',
60
+ 'color': 'text/neutral',
61
+ '& > svg': {
62
+ display: 'block',
63
+ width: 16,
64
+ height: 16,
65
+ color: 'icon/neutral/bold'
66
+ }
67
+ },
68
+ children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
69
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
70
+ ref: e => {
71
+ isFunction(ref) ? ref(e) : null;
72
+ inputRef.current = e;
73
+ },
74
+ value: '',
75
+ onChange: noop,
76
+ ...props,
77
+ tabIndex: -1,
78
+ onClick: e => {
79
+ popperProps.onClick?.(e);
80
+ props.onClick?.(e);
81
+ }
82
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
83
+ sx: {
84
+ position: 'absolute',
85
+ top: '50%',
86
+ transform: 'translateY(-50%)',
87
+ right: 5,
88
+ pointerEvents: 'none'
89
+ },
90
+ icon: SvgChevronDown,
91
+ color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
92
+ size: 16
93
+ })]
94
+ })
95
+ });
96
+ };
97
+ const TextInputWrapper = styled.div`
98
+ position: relative;
99
+ width: ${forcePixelValue('100%')};
100
+ border-width: ${forcePixelValue(1)};
101
+ border-style: solid;
102
+ border-radius: ${({
103
+ theme
104
+ }) => forcePixelValue(theme.radii.xs)};
105
+ border-color: ${({
106
+ theme
107
+ }) => theme.colors['border/input']};
108
+ background-color: ${({
109
+ theme
110
+ }) => theme.colors['bg/input']};
111
+ cursor: default;
112
+ input {
113
+ cursor: default;
114
+ }
115
+ display: inline-flex;
116
+ align-items: center;
117
+
118
+ font-size: ${({
119
+ theme
120
+ }) => forcePixelValue(theme.fontSizes.xs)};
121
+ font-weight: ${({
122
+ theme
123
+ }) => theme.fontWeights.medium};
124
+ line-height: ${({
125
+ theme
126
+ }) => theme.lineHeights[2]};
127
+ color: ${({
128
+ theme
129
+ }) => theme.colors['text/neutral']};
130
+ input::placeholder {
131
+ color: ${({
132
+ theme
133
+ }) => theme.colors['text/neutral/subtlest']};
134
+ }
135
+
136
+ &:after {
137
+ content: '';
138
+ position: absolute;
139
+ top: ${forcePixelValue(-1)};
140
+ right: ${forcePixelValue(-1)};
141
+ bottom: ${forcePixelValue(-1)};
142
+ left: ${forcePixelValue(-1)};
143
+
144
+ border: ${forcePixelValue(2)} solid transparent;
145
+ border-radius: ${({
146
+ theme
147
+ }) => forcePixelValue(theme.radii.xs)};
148
+ pointer-events: none;
149
+ }
150
+
151
+ ${props => props.validationStatus !== 'error' && !props.disabled && css`
152
+ &:hover:not(:focus-within) {
153
+ &:after {
154
+ border-color: ${({
155
+ theme
156
+ }) => theme.colors['border/hovered']};
157
+ }
158
+ }
159
+ `}
160
+
161
+ ${props => props.validationStatus === 'error' && css`
162
+ &:after {
163
+ border-color: ${({
164
+ theme
165
+ }) => theme.colors['border/danger']};
166
+ }
167
+ `}
168
+
169
+ ${props => props.validationStatus !== 'error' && !props.disabled && css`
170
+ &:focus-within {
171
+ &:after {
172
+ border-color: ${({
173
+ theme
174
+ }) => theme.colors['border/focused']};
175
+ }
176
+ }
177
+ `}
178
+
179
+ ${props => props.disabled && css`
180
+ border-color: ${props.theme.colors['border/input']};
181
+ background-color: ${props.theme.colors['bg/disabled']};
182
+ color: ${props.theme.colors['text/disabled']};
183
+
184
+ input::placeholder {
185
+ color: ${props.theme.colors['text/disabled']};
186
+ }
187
+
188
+ input {
189
+ cursor: not-allowed;
190
+ }
191
+ `};
192
+
193
+ ${props => props.hasLeadingVisual && css`
194
+ padding-left: ${forcePixelValue(props.theme.space[5])};
195
+ input {
196
+ padding-left: ${forcePixelValue(props.theme.space[2])};
197
+ }
198
+ `}
199
+
200
+ transition: color 100ms, background-color 100ms;
201
+ &:after {
202
+ transition: border-color 100ms;
203
+ }
204
+ `;
205
+ const UnstyledInput = styled.input`
206
+ font-size: inherit;
207
+ font-weight: inherit;
208
+ line-height: inherit;
209
+ font-family: inherit;
210
+ border-radius: inherit;
211
+ color: inherit;
212
+ transition: inherit;
213
+
214
+ border: 0;
215
+ background-color: transparent;
216
+ width: 100%;
217
+ &:focus {
218
+ outline: 0;
219
+ }
220
+ `;
221
+ const BaseInput = styled(UnstyledInput)`
222
+ padding-top: ${({
223
+ theme
224
+ }) => forcePixelValue(theme.space['4'])};
225
+ padding-right: ${({
226
+ theme
227
+ }) => forcePixelValue(theme.space['5'])};
228
+ padding-bottom: ${({
229
+ theme
230
+ }) => forcePixelValue(theme.space['4'])};
231
+ padding-left: ${({
232
+ theme
233
+ }) => forcePixelValue(theme.space['5'])};
234
+ `;
235
+ var index = /*#__PURE__*/forwardRef(OverlaySelectInput);
236
+
237
+ export { index as default };