baseui 10.9.0 → 10.9.1
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.
- package/data-table/column-numerical.js +355 -307
- package/data-table/column-numerical.js.flow +287 -273
- package/data-table/constants.js +11 -17
- package/data-table/constants.js.flow +8 -11
- package/data-table/data-table.js +50 -53
- package/data-table/data-table.js.flow +13 -18
- package/data-table/filter-shell.js +4 -27
- package/data-table/filter-shell.js.flow +9 -33
- package/data-table/locale.js +2 -4
- package/data-table/locale.js.flow +2 -6
- package/data-table/measure-column-widths.js +121 -83
- package/data-table/measure-column-widths.js.flow +109 -87
- package/es/data-table/column-numerical.js +317 -245
- package/es/data-table/constants.js +8 -12
- package/es/data-table/data-table.js +16 -18
- package/es/data-table/filter-shell.js +4 -26
- package/es/data-table/locale.js +2 -4
- package/es/data-table/measure-column-widths.js +86 -75
- package/es/form-control/form-control.js +58 -7
- package/es/form-control/styled-components.js +27 -6
- package/es/popover/popover.js +1 -1
- package/esm/data-table/column-numerical.js +353 -304
- package/esm/data-table/constants.js +8 -12
- package/esm/data-table/data-table.js +50 -53
- package/esm/data-table/filter-shell.js +4 -26
- package/esm/data-table/locale.js +2 -4
- package/esm/data-table/measure-column-widths.js +121 -83
- package/esm/form-control/form-control.js +60 -9
- package/esm/form-control/styled-components.js +23 -3
- package/esm/popover/popover.js +1 -1
- package/form-control/form-control.js +61 -8
- package/form-control/form-control.js.flow +82 -10
- package/form-control/index.d.ts +1 -0
- package/form-control/styled-components.js +27 -5
- package/form-control/styled-components.js.flow +25 -3
- package/form-control/types.js.flow +20 -8
- package/package.json +1 -2
- package/popover/popover.js +1 -1
- package/popover/popover.js.flow +1 -1
|
@@ -17,8 +17,6 @@ import { LocaleContext } from '../locale/index.js'; // consider pulling this out
|
|
|
17
17
|
|
|
18
18
|
const HEADER_ROW_HEIGHT = 48;
|
|
19
19
|
|
|
20
|
-
const sum = ns => ns.reduce((s, n) => s + n, 0);
|
|
21
|
-
|
|
22
20
|
function CellPlacement({
|
|
23
21
|
columnIndex,
|
|
24
22
|
rowIndex,
|
|
@@ -257,7 +255,7 @@ function Header(props) {
|
|
|
257
255
|
}))));
|
|
258
256
|
}
|
|
259
257
|
|
|
260
|
-
function Headers() {
|
|
258
|
+
function Headers(props) {
|
|
261
259
|
const [css, theme] = useStyletron();
|
|
262
260
|
const locale = React.useContext(LocaleContext);
|
|
263
261
|
const ctx = React.useContext(HeaderContext);
|
|
@@ -267,7 +265,7 @@ function Headers() {
|
|
|
267
265
|
position: 'sticky',
|
|
268
266
|
top: 0,
|
|
269
267
|
left: 0,
|
|
270
|
-
width: `${
|
|
268
|
+
width: `${ctx.widths.reduce((sum, w) => sum + w, 0)}px`,
|
|
271
269
|
height: `${HEADER_ROW_HEIGHT}px`,
|
|
272
270
|
display: 'flex',
|
|
273
271
|
// this feels bad.. the absolutely positioned children elements
|
|
@@ -469,10 +467,8 @@ export function DataTable({
|
|
|
469
467
|
}
|
|
470
468
|
|
|
471
469
|
return rowHeight;
|
|
472
|
-
}, [rowHeight]);
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const [gridRef, setGridRef] = React.useState(null);
|
|
470
|
+
}, [rowHeight]);
|
|
471
|
+
const gridRef = React.useRef(null);
|
|
476
472
|
const [measuredWidths, setMeasuredWidths] = React.useState(columns.map(() => 0));
|
|
477
473
|
const [resizeDeltas, setResizeDeltas] = React.useState(columns.map(() => 0));
|
|
478
474
|
React.useEffect(() => {
|
|
@@ -484,11 +480,11 @@ export function DataTable({
|
|
|
484
480
|
});
|
|
485
481
|
}, [columns]);
|
|
486
482
|
const resetAfterColumnIndex = React.useCallback(columnIndex => {
|
|
487
|
-
if (gridRef) {
|
|
483
|
+
if (gridRef.current) {
|
|
488
484
|
// $FlowFixMe trigger react-window to layout the elements again
|
|
489
|
-
gridRef.resetAfterColumnIndex(columnIndex, true);
|
|
485
|
+
gridRef.current.resetAfterColumnIndex(columnIndex, true);
|
|
490
486
|
}
|
|
491
|
-
}, [gridRef]);
|
|
487
|
+
}, [gridRef.current]);
|
|
492
488
|
const handleWidthsChange = React.useCallback(nextWidths => {
|
|
493
489
|
setMeasuredWidths(nextWidths);
|
|
494
490
|
resetAfterColumnIndex(0);
|
|
@@ -598,10 +594,13 @@ export function DataTable({
|
|
|
598
594
|
}, [sortedIndices, filteredIndices, onIncludedRowsChange, allRows]);
|
|
599
595
|
const [browserScrollbarWidth, setBrowserScrollbarWidth] = React.useState(0);
|
|
600
596
|
const normalizedWidths = React.useMemo(() => {
|
|
597
|
+
const sum = ns => ns.reduce((s, n) => s + n, 0);
|
|
598
|
+
|
|
601
599
|
const resizedWidths = measuredWidths.map((w, i) => Math.floor(w) + Math.floor(resizeDeltas[i]));
|
|
602
600
|
|
|
603
|
-
if (gridRef) {
|
|
604
|
-
|
|
601
|
+
if (gridRef.current) {
|
|
602
|
+
// $FlowFixMe
|
|
603
|
+
const gridProps = gridRef.current.props;
|
|
605
604
|
let isContentTallerThanContainer = false;
|
|
606
605
|
let visibleRowHeight = 0;
|
|
607
606
|
|
|
@@ -636,7 +635,7 @@ export function DataTable({
|
|
|
636
635
|
}
|
|
637
636
|
|
|
638
637
|
return resizedWidths;
|
|
639
|
-
}, [
|
|
638
|
+
}, [measuredWidths, resizeDeltas, browserScrollbarWidth, rows.length, columns]);
|
|
640
639
|
const isSelectable = batchActions ? !!batchActions.length : false;
|
|
641
640
|
const isSelectedAll = React.useMemo(() => {
|
|
642
641
|
if (!selectedRowIds) {
|
|
@@ -685,10 +684,10 @@ export function DataTable({
|
|
|
685
684
|
function handleRowHighlightIndexChange(nextIndex) {
|
|
686
685
|
setRowHighlightIndex(nextIndex);
|
|
687
686
|
|
|
688
|
-
if (gridRef) {
|
|
687
|
+
if (gridRef.current) {
|
|
689
688
|
if (nextIndex >= 0) {
|
|
690
689
|
// $FlowFixMe - unable to get react-window types
|
|
691
|
-
gridRef.scrollToItem({
|
|
690
|
+
gridRef.current.scrollToItem({
|
|
692
691
|
rowIndex: nextIndex
|
|
693
692
|
});
|
|
694
693
|
}
|
|
@@ -777,9 +776,8 @@ export function DataTable({
|
|
|
777
776
|
}
|
|
778
777
|
}, /*#__PURE__*/React.createElement(VariableSizeGrid // eslint-disable-next-line flowtype/no-weak-types
|
|
779
778
|
, {
|
|
780
|
-
ref:
|
|
779
|
+
ref: gridRef,
|
|
781
780
|
overscanRowCount: 10,
|
|
782
|
-
overscanColumnCount: 5,
|
|
783
781
|
innerElementType: InnerTableElement,
|
|
784
782
|
columnCount: columns.length,
|
|
785
783
|
columnWidth: columnIndex => normalizedWidths[columnIndex],
|
|
@@ -9,26 +9,10 @@ import { Button, SIZE as BUTTON_SIZE } from '../button/index.js';
|
|
|
9
9
|
import { Checkbox, STYLE_TYPE } from '../checkbox/index.js';
|
|
10
10
|
import { useStyletron } from '../styles/index.js';
|
|
11
11
|
import { LocaleContext } from '../locale/index.js';
|
|
12
|
-
import { FILTER_SHELL_WIDTH } from './constants.js';
|
|
13
12
|
|
|
14
13
|
function FilterShell(props) {
|
|
15
14
|
const [css, theme] = useStyletron();
|
|
16
15
|
const locale = React.useContext(LocaleContext);
|
|
17
|
-
let excludeText;
|
|
18
|
-
|
|
19
|
-
switch (props.excludeKind) {
|
|
20
|
-
case 'value':
|
|
21
|
-
excludeText = locale.datatable.filterExcludeValue;
|
|
22
|
-
break;
|
|
23
|
-
|
|
24
|
-
case 'range':
|
|
25
|
-
excludeText = locale.datatable.filterExcludeRange;
|
|
26
|
-
break;
|
|
27
|
-
|
|
28
|
-
default:
|
|
29
|
-
excludeText = locale.datatable.filterExclude;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
16
|
return /*#__PURE__*/React.createElement("form", {
|
|
33
17
|
className: css({
|
|
34
18
|
backgroundColor: theme.colors.backgroundPrimary,
|
|
@@ -36,7 +20,7 @@ function FilterShell(props) {
|
|
|
36
20
|
paddingRight: theme.sizing.scale600,
|
|
37
21
|
paddingBottom: theme.sizing.scale600,
|
|
38
22
|
paddingLeft: theme.sizing.scale600,
|
|
39
|
-
width:
|
|
23
|
+
width: '320px'
|
|
40
24
|
}),
|
|
41
25
|
onSubmit: event => {
|
|
42
26
|
event.preventDefault();
|
|
@@ -44,23 +28,17 @@ function FilterShell(props) {
|
|
|
44
28
|
}
|
|
45
29
|
}, props.children, /*#__PURE__*/React.createElement("div", {
|
|
46
30
|
className: css({
|
|
31
|
+
alignItems: 'center',
|
|
47
32
|
display: 'flex',
|
|
48
|
-
flexDirection: 'column',
|
|
49
33
|
justifyContent: 'space-between',
|
|
50
|
-
|
|
51
|
-
marginTop: theme.sizing.scale600,
|
|
52
|
-
gap: theme.sizing.scale200
|
|
53
|
-
})
|
|
54
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
55
|
-
className: css({
|
|
56
|
-
alignSelf: 'flex-start'
|
|
34
|
+
marginTop: theme.sizing.scale600
|
|
57
35
|
})
|
|
58
36
|
}, /*#__PURE__*/React.createElement(Checkbox, {
|
|
59
37
|
checked: props.exclude,
|
|
60
38
|
onChange: props.onExcludeChange,
|
|
61
39
|
checkmarkType: STYLE_TYPE.toggle_round,
|
|
62
40
|
labelPlacement: "right"
|
|
63
|
-
},
|
|
41
|
+
}, locale.datatable.filterExclude), /*#__PURE__*/React.createElement(Button, {
|
|
64
42
|
size: BUTTON_SIZE.compact,
|
|
65
43
|
type: "submit"
|
|
66
44
|
}, locale.datatable.filterApply)));
|
package/es/data-table/locale.js
CHANGED
|
@@ -6,20 +6,18 @@ LICENSE file in the root directory of this source tree.
|
|
|
6
6
|
*/
|
|
7
7
|
const locale = {
|
|
8
8
|
emptyState: 'No rows match the filter criteria defined. Please remove one or more filters to view more data.',
|
|
9
|
-
loadingState: 'Loading
|
|
9
|
+
loadingState: 'Loading Rows.',
|
|
10
10
|
searchAriaLabel: 'Search by text',
|
|
11
11
|
filterAdd: 'Add Filter',
|
|
12
12
|
filterExclude: 'Exclude',
|
|
13
13
|
filterApply: 'Apply',
|
|
14
|
-
filterExcludeRange: 'Exclude range',
|
|
15
|
-
filterExcludeValue: 'Exclude value',
|
|
16
14
|
filterAppliedTo: 'filter applied to',
|
|
17
15
|
optionsLabel: 'Select column to filter by',
|
|
18
16
|
optionsSearch: 'Search for a column to filter by...',
|
|
19
17
|
optionsEmpty: 'No columns available.',
|
|
20
18
|
categoricalFilterSelectAll: 'Select All',
|
|
21
19
|
categoricalFilterSelectClear: 'Clear',
|
|
22
|
-
categoricalFilterEmpty: 'No
|
|
20
|
+
categoricalFilterEmpty: 'No Categories Found',
|
|
23
21
|
datetimeFilterRange: 'Range',
|
|
24
22
|
datetimeFilterRangeDatetime: 'Date, Time',
|
|
25
23
|
datetimeFilterRangeDate: 'Date',
|
|
@@ -7,59 +7,40 @@ LICENSE file in the root directory of this source tree.
|
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
import { useStyletron } from '../styles/index.js';
|
|
9
9
|
import HeaderCell from './header-cell.js';
|
|
10
|
-
import { useRef } from 'react'; // Measures the column header + sampled data
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}) {
|
|
20
|
-
const [css] = useStyletron();
|
|
21
|
-
const ref = useRef();
|
|
11
|
+
// https://github.com/Swizec/useDimensions
|
|
12
|
+
function useDimensions() {
|
|
13
|
+
const [dimensions, setDimensions] = React.useState({});
|
|
14
|
+
const [node, setNode] = React.useState(null);
|
|
15
|
+
const ref = React.useCallback(node => {
|
|
16
|
+
setNode(node);
|
|
17
|
+
}, []);
|
|
22
18
|
React.useEffect(() => {
|
|
23
|
-
if (
|
|
24
|
-
|
|
19
|
+
if (typeof document !== 'undefined') {
|
|
20
|
+
if (node) {
|
|
21
|
+
window.requestAnimationFrame(() => {
|
|
22
|
+
setDimensions(node.getBoundingClientRect());
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
25
|
}
|
|
26
|
-
}, []);
|
|
27
|
-
return
|
|
28
|
-
ref: ref,
|
|
29
|
-
className: css({
|
|
30
|
-
display: 'flex',
|
|
31
|
-
flexDirection: 'column',
|
|
32
|
-
width: 'fit-content'
|
|
33
|
-
})
|
|
34
|
-
}, /*#__PURE__*/React.createElement(HeaderCell, {
|
|
35
|
-
index: columnIndex,
|
|
36
|
-
isHovered: true,
|
|
37
|
-
isMeasured: true,
|
|
38
|
-
isSelectedAll: false,
|
|
39
|
-
isSelectedIndeterminate: false,
|
|
40
|
-
onMouseEnter: () => {},
|
|
41
|
-
onMouseLeave: () => {},
|
|
42
|
-
onSelectAll: () => {},
|
|
43
|
-
onSelectNone: () => {},
|
|
44
|
-
onSort: i => {},
|
|
45
|
-
sortable: column.sortable,
|
|
46
|
-
sortDirection: null,
|
|
47
|
-
title: column.title,
|
|
48
|
-
isSelectable: isSelectable
|
|
49
|
-
}), sampleIndexes.map((rowIndex, i) => {
|
|
50
|
-
const Cell = column.renderCell;
|
|
51
|
-
return /*#__PURE__*/React.createElement(Cell, {
|
|
52
|
-
key: `measure-${i}`,
|
|
53
|
-
value: column.mapDataToValue(rows[rowIndex].data),
|
|
54
|
-
isSelectable: isSelectable,
|
|
55
|
-
isMeasured: true,
|
|
56
|
-
sortable: column.sortable,
|
|
57
|
-
x: 0,
|
|
58
|
-
y: rowIndex
|
|
59
|
-
});
|
|
60
|
-
}));
|
|
26
|
+
}, [node]);
|
|
27
|
+
return [ref, dimensions];
|
|
61
28
|
}
|
|
62
29
|
|
|
30
|
+
function ElementMeasurer(props) {
|
|
31
|
+
const {
|
|
32
|
+
onDimensionsChange
|
|
33
|
+
} = props;
|
|
34
|
+
const [ref, dimensions] = useDimensions();
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
onDimensionsChange(dimensions);
|
|
37
|
+
}, [dimensions, onDimensionsChange]);
|
|
38
|
+
return /*#__PURE__*/React.cloneElement(props.item, {
|
|
39
|
+
ref
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// sample size could likely be generated based on row count, to have higher confidence
|
|
63
44
|
const MAX_SAMPLE_SIZE = 50;
|
|
64
45
|
|
|
65
46
|
function generateSampleIndices(inputMin, inputMax, maxSamples) {
|
|
@@ -96,35 +77,43 @@ export default function MeasureColumnWidths({
|
|
|
96
77
|
onWidthsChange
|
|
97
78
|
}) {
|
|
98
79
|
const [css] = useStyletron();
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
}, []);
|
|
80
|
+
const measurementCount = React.useRef(0);
|
|
81
|
+
const dimensionsCache = React.useRef(widths);
|
|
102
82
|
const sampleSize = rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
|
|
103
83
|
const finishedMeasurementCount = (sampleSize + 1) * columns.length;
|
|
104
|
-
const
|
|
105
|
-
|
|
84
|
+
const sampleRowIndicesByColumn = React.useMemo(() => {
|
|
85
|
+
measurementCount.current = 0;
|
|
86
|
+
dimensionsCache.current = widths;
|
|
87
|
+
const indices = generateSampleIndices(0, rows.length - 1, sampleSize);
|
|
88
|
+
return columns.map(() => indices);
|
|
106
89
|
}, [columns, rows, widths, sampleSize]);
|
|
107
|
-
const handleDimensionsChange = React.useCallback((columnIndex, dimensions) => {
|
|
108
|
-
|
|
90
|
+
const handleDimensionsChange = React.useCallback((columnIndex, rowIndex, dimensions) => {
|
|
91
|
+
if (dimensions.width === undefined) return;
|
|
92
|
+
|
|
93
|
+
if (columns[columnIndex] === undefined || dimensionsCache.current[columnIndex] === undefined) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
measurementCount.current += 1;
|
|
98
|
+
const nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, dimensionsCache.current[columnIndex], dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);
|
|
109
99
|
|
|
110
|
-
if (nextWidth !==
|
|
111
|
-
|
|
100
|
+
if (nextWidth !== dimensionsCache.current[columnIndex]) {
|
|
101
|
+
const nextWidths = [...dimensionsCache.current];
|
|
102
|
+
nextWidths[columnIndex] = nextWidth;
|
|
103
|
+
dimensionsCache.current = nextWidths;
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
widthMap.size === Math.floor(columns.length / 2) || // ...25%
|
|
117
|
-
widthMap.size === Math.floor(columns.length / 4)) {
|
|
118
|
-
onWidthsChange(Array.from(widthMap.values()));
|
|
106
|
+
if (measurementCount.current >= finishedMeasurementCount) {
|
|
107
|
+
onWidthsChange(dimensionsCache.current);
|
|
119
108
|
}
|
|
120
109
|
}, [columns, finishedMeasurementCount, onWidthsChange]);
|
|
121
110
|
const hiddenStyle = css({
|
|
122
111
|
position: 'absolute',
|
|
123
112
|
overflow: 'hidden',
|
|
124
113
|
height: 0
|
|
125
|
-
});
|
|
114
|
+
});
|
|
126
115
|
|
|
127
|
-
if (
|
|
116
|
+
if (measurementCount.current >= finishedMeasurementCount) {
|
|
128
117
|
return null;
|
|
129
118
|
}
|
|
130
119
|
|
|
@@ -135,16 +124,38 @@ export default function MeasureColumnWidths({
|
|
|
135
124
|
className: hiddenStyle,
|
|
136
125
|
"aria-hidden": true,
|
|
137
126
|
role: "none"
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
127
|
+
}, sampleRowIndicesByColumn.map((rowIndices, columnIndex) => {
|
|
128
|
+
const Cell = columns[columnIndex].renderCell;
|
|
129
|
+
return rowIndices.map(rowIndex => /*#__PURE__*/React.createElement(ElementMeasurer, {
|
|
130
|
+
key: `measure-${columnIndex}-${rowIndex}`,
|
|
131
|
+
onDimensionsChange: dimensions => handleDimensionsChange(columnIndex, rowIndex, dimensions),
|
|
132
|
+
item: /*#__PURE__*/React.createElement(Cell, {
|
|
133
|
+
value: columns[columnIndex].mapDataToValue(rows[rowIndex].data),
|
|
134
|
+
isMeasured: true,
|
|
135
|
+
onSelect: isSelectable && columnIndex === 0 ? () => {} : undefined,
|
|
136
|
+
x: columnIndex,
|
|
137
|
+
y: rowIndex
|
|
138
|
+
})
|
|
139
|
+
}));
|
|
140
|
+
}), columns.map((column, columnIndex) => /*#__PURE__*/React.createElement(ElementMeasurer, {
|
|
141
|
+
key: `measure-column-${columnIndex}`,
|
|
142
|
+
onDimensionsChange: dimensions => handleDimensionsChange(columnIndex, -1, dimensions),
|
|
143
|
+
item: /*#__PURE__*/React.createElement(HeaderCell, {
|
|
144
|
+
index: columnIndex,
|
|
145
|
+
isHovered: true,
|
|
146
|
+
isMeasured: true,
|
|
147
|
+
isSelectable: isSelectable && columnIndex === 0,
|
|
148
|
+
isSelectedAll: false,
|
|
149
|
+
isSelectedIndeterminate: false,
|
|
150
|
+
onMouseEnter: () => {},
|
|
151
|
+
onMouseLeave: () => {},
|
|
152
|
+
onSelectAll: () => {},
|
|
153
|
+
onSelectNone: () => {},
|
|
154
|
+
onSort: i => {},
|
|
155
|
+
sortable: column.sortable,
|
|
156
|
+
sortDirection: null,
|
|
157
|
+
title: column.title
|
|
158
|
+
})
|
|
159
|
+
})))
|
|
149
160
|
);
|
|
150
161
|
}
|
|
@@ -11,7 +11,7 @@ LICENSE file in the root directory of this source tree.
|
|
|
11
11
|
import * as React from 'react';
|
|
12
12
|
import { getOverride, getOverrideProps } from '../helpers/overrides.js';
|
|
13
13
|
import { UIDConsumer } from 'react-uid';
|
|
14
|
-
import { Label as StyledLabel, Caption as StyledCaption, ControlContainer as StyledControlContainer } from './styled-components.js';
|
|
14
|
+
import { Label as StyledLabel, LabelEndEnhancer as StyledLabelEndEnhancer, LabelContainer as StyledLabelContainer, Caption as StyledCaption, ControlContainer as StyledControlContainer } from './styled-components.js';
|
|
15
15
|
|
|
16
16
|
function chooseRenderedHint(caption, error, positive, sharedProps) {
|
|
17
17
|
if (error && typeof error !== 'boolean') {
|
|
@@ -34,6 +34,8 @@ export default class FormControl extends React.Component {
|
|
|
34
34
|
const {
|
|
35
35
|
overrides: {
|
|
36
36
|
Label: LabelOverride,
|
|
37
|
+
LabelEndEnhancer: LabelEndEnhancerOverride,
|
|
38
|
+
LabelContainer: LabelContainerOverride,
|
|
37
39
|
Caption: CaptionOverride,
|
|
38
40
|
ControlContainer: ControlContainerOverride
|
|
39
41
|
},
|
|
@@ -43,7 +45,8 @@ export default class FormControl extends React.Component {
|
|
|
43
45
|
error,
|
|
44
46
|
positive,
|
|
45
47
|
htmlFor,
|
|
46
|
-
children
|
|
48
|
+
children,
|
|
49
|
+
counter
|
|
47
50
|
} = this.props;
|
|
48
51
|
const onlyChildProps = React.Children.only(children).props;
|
|
49
52
|
const sharedProps = {
|
|
@@ -52,6 +55,8 @@ export default class FormControl extends React.Component {
|
|
|
52
55
|
$positive: !!positive
|
|
53
56
|
};
|
|
54
57
|
const Label = getOverride(LabelOverride) || StyledLabel;
|
|
58
|
+
const LabelEndEnhancer = getOverride(LabelEndEnhancerOverride) || StyledLabelEndEnhancer;
|
|
59
|
+
const LabelContainer = getOverride(LabelContainerOverride) || StyledLabelContainer;
|
|
55
60
|
const Caption = getOverride(CaptionOverride) || StyledCaption;
|
|
56
61
|
const ControlContainer = getOverride(ControlContainerOverride) || StyledControlContainer;
|
|
57
62
|
const hint = chooseRenderedHint(caption, error, positive, sharedProps);
|
|
@@ -63,10 +68,55 @@ export default class FormControl extends React.Component {
|
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
let labelEndEnhancer = this.props.labelEndEnhancer;
|
|
72
|
+
|
|
73
|
+
if (counter) {
|
|
74
|
+
// inferred values are preferred but if the user specifies the value
|
|
75
|
+
// that is then used as the default.
|
|
76
|
+
let maxLength = null;
|
|
77
|
+
let length = null;
|
|
78
|
+
let counterError = null;
|
|
79
|
+
|
|
80
|
+
if (typeof counter === 'object') {
|
|
81
|
+
length = counter.length;
|
|
82
|
+
maxLength = counter.maxLength;
|
|
83
|
+
counterError = counter.error;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
maxLength = maxLength ? maxLength : onlyChildProps.maxLength;
|
|
87
|
+
|
|
88
|
+
if (length == null && typeof onlyChildProps.value === 'string') {
|
|
89
|
+
length = onlyChildProps.value.length;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (length == null) {
|
|
93
|
+
length = 0;
|
|
94
|
+
|
|
95
|
+
if (process.env.NODE_ENV !== "production") {
|
|
96
|
+
console.warn(`[FromControl] \`length\` must either be explicitly set via \`counter\` object property, or \`value\` string property on the child component.`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
sharedProps.$length = length;
|
|
101
|
+
|
|
102
|
+
if (maxLength == null) {
|
|
103
|
+
if (!labelEndEnhancer) labelEndEnhancer = `${length}`;
|
|
104
|
+
} else {
|
|
105
|
+
sharedProps.$maxLength = length;
|
|
106
|
+
if (!labelEndEnhancer) labelEndEnhancer = `${length}/${maxLength}`;
|
|
107
|
+
if (length > maxLength && counterError == null) counterError = true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (counterError) {
|
|
111
|
+
sharedProps.$error = true;
|
|
112
|
+
sharedProps.$counterError = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, label && /*#__PURE__*/React.createElement(LabelContainer, _extends({}, sharedProps, getOverrideProps(LabelContainerOverride)), /*#__PURE__*/React.createElement(Label, _extends({
|
|
67
117
|
"data-baseweb": "form-control-label",
|
|
68
118
|
htmlFor: htmlFor || onlyChildProps.id
|
|
69
|
-
}, sharedProps, getOverrideProps(LabelOverride)), typeof label === 'function' ? label(sharedProps) : label), /*#__PURE__*/React.createElement(UIDConsumer, null, captionId => /*#__PURE__*/React.createElement(ControlContainer, _extends({
|
|
119
|
+
}, sharedProps, getOverrideProps(LabelOverride)), typeof label === 'function' ? label(sharedProps) : label), labelEndEnhancer && /*#__PURE__*/React.createElement(LabelEndEnhancer, _extends({}, sharedProps, getOverrideProps(LabelEndEnhancerOverride)), typeof labelEndEnhancer === 'function' ? labelEndEnhancer(sharedProps) : labelEndEnhancer)), /*#__PURE__*/React.createElement(UIDConsumer, null, captionId => /*#__PURE__*/React.createElement(ControlContainer, _extends({
|
|
70
120
|
"data-baseweb": "form-control-container"
|
|
71
121
|
}, sharedProps, getOverrideProps(ControlContainerOverride)), React.Children.map(children, (child, index) => {
|
|
72
122
|
if (!child) return;
|
|
@@ -76,8 +126,8 @@ export default class FormControl extends React.Component {
|
|
|
76
126
|
'aria-errormessage': error ? captionId : null,
|
|
77
127
|
'aria-describedby': caption || positive ? captionId : null,
|
|
78
128
|
disabled: onlyChildProps.disabled || disabled,
|
|
79
|
-
error: typeof onlyChildProps.error !== 'undefined' ? onlyChildProps.error : error,
|
|
80
|
-
positive: typeof onlyChildProps.positive !== 'undefined' ? onlyChildProps.positive : positive
|
|
129
|
+
error: typeof onlyChildProps.error !== 'undefined' ? onlyChildProps.error : sharedProps.$error,
|
|
130
|
+
positive: typeof onlyChildProps.positive !== 'undefined' ? onlyChildProps.positive : sharedProps.$positive
|
|
81
131
|
});
|
|
82
132
|
}), (caption || error || positive) && /*#__PURE__*/React.createElement(Caption, _extends({
|
|
83
133
|
"data-baseweb": "form-control-caption",
|
|
@@ -91,5 +141,6 @@ _defineProperty(FormControl, "defaultProps", {
|
|
|
91
141
|
overrides: {},
|
|
92
142
|
label: null,
|
|
93
143
|
caption: null,
|
|
94
|
-
disabled: false
|
|
144
|
+
disabled: false,
|
|
145
|
+
counter: false
|
|
95
146
|
});
|
|
@@ -10,7 +10,6 @@ export const Label = styled('label', props => {
|
|
|
10
10
|
$disabled,
|
|
11
11
|
$theme: {
|
|
12
12
|
colors,
|
|
13
|
-
sizing,
|
|
14
13
|
typography
|
|
15
14
|
}
|
|
16
15
|
} = props;
|
|
@@ -22,14 +21,36 @@ export const Label = styled('label', props => {
|
|
|
22
21
|
paddingTop: 0,
|
|
23
22
|
paddingRight: 0,
|
|
24
23
|
paddingBottom: 0,
|
|
25
|
-
paddingLeft: 0
|
|
26
|
-
marginTop: sizing.scale300,
|
|
27
|
-
marginRight: 0,
|
|
28
|
-
marginBottom: sizing.scale300,
|
|
29
|
-
marginLeft: 0
|
|
24
|
+
paddingLeft: 0
|
|
30
25
|
};
|
|
31
26
|
});
|
|
32
27
|
Label.displayName = "Label";
|
|
28
|
+
export const LabelContainer = styled('span', ({
|
|
29
|
+
$theme: {
|
|
30
|
+
sizing
|
|
31
|
+
}
|
|
32
|
+
}) => ({
|
|
33
|
+
display: 'flex',
|
|
34
|
+
width: '100%',
|
|
35
|
+
marginTop: sizing.scale300,
|
|
36
|
+
marginRight: 0,
|
|
37
|
+
marginBottom: sizing.scale300,
|
|
38
|
+
marginLeft: 0
|
|
39
|
+
}));
|
|
40
|
+
LabelContainer.displayName = "LabelContainer";
|
|
41
|
+
export const LabelEndEnhancer = styled('span', ({
|
|
42
|
+
$disabled,
|
|
43
|
+
$counterError,
|
|
44
|
+
$theme: {
|
|
45
|
+
colors,
|
|
46
|
+
typography
|
|
47
|
+
}
|
|
48
|
+
}) => ({ ...typography.font100,
|
|
49
|
+
flex: 0,
|
|
50
|
+
width: '100%',
|
|
51
|
+
color: $counterError ? colors.negative400 : $disabled ? colors.contentSecondary : colors.contentPrimary
|
|
52
|
+
}));
|
|
53
|
+
LabelEndEnhancer.displayName = "LabelEndEnhancer";
|
|
33
54
|
export const Caption = styled('div', props => {
|
|
34
55
|
const {
|
|
35
56
|
$error,
|
package/es/popover/popover.js
CHANGED
|
@@ -457,7 +457,7 @@ class PopoverInner extends React.Component {
|
|
|
457
457
|
crossFrame: false,
|
|
458
458
|
focusOptions: this.props.focusOptions
|
|
459
459
|
}, this.renderPopover(renderedContent)) : /*#__PURE__*/React.createElement(MoveFocusInside, {
|
|
460
|
-
disabled: !this.props.autoFocus
|
|
460
|
+
disabled: !this.props.autoFocus || !this.state.autoFocusAfterPositioning
|
|
461
461
|
}, this.renderPopover(renderedContent)))));
|
|
462
462
|
} else {
|
|
463
463
|
rendered.push( /*#__PURE__*/React.createElement(Hidden, {
|