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.
Files changed (39) hide show
  1. package/data-table/column-numerical.js +355 -307
  2. package/data-table/column-numerical.js.flow +287 -273
  3. package/data-table/constants.js +11 -17
  4. package/data-table/constants.js.flow +8 -11
  5. package/data-table/data-table.js +50 -53
  6. package/data-table/data-table.js.flow +13 -18
  7. package/data-table/filter-shell.js +4 -27
  8. package/data-table/filter-shell.js.flow +9 -33
  9. package/data-table/locale.js +2 -4
  10. package/data-table/locale.js.flow +2 -6
  11. package/data-table/measure-column-widths.js +121 -83
  12. package/data-table/measure-column-widths.js.flow +109 -87
  13. package/es/data-table/column-numerical.js +317 -245
  14. package/es/data-table/constants.js +8 -12
  15. package/es/data-table/data-table.js +16 -18
  16. package/es/data-table/filter-shell.js +4 -26
  17. package/es/data-table/locale.js +2 -4
  18. package/es/data-table/measure-column-widths.js +86 -75
  19. package/es/form-control/form-control.js +58 -7
  20. package/es/form-control/styled-components.js +27 -6
  21. package/es/popover/popover.js +1 -1
  22. package/esm/data-table/column-numerical.js +353 -304
  23. package/esm/data-table/constants.js +8 -12
  24. package/esm/data-table/data-table.js +50 -53
  25. package/esm/data-table/filter-shell.js +4 -26
  26. package/esm/data-table/locale.js +2 -4
  27. package/esm/data-table/measure-column-widths.js +121 -83
  28. package/esm/form-control/form-control.js +60 -9
  29. package/esm/form-control/styled-components.js +23 -3
  30. package/esm/popover/popover.js +1 -1
  31. package/form-control/form-control.js +61 -8
  32. package/form-control/form-control.js.flow +82 -10
  33. package/form-control/index.d.ts +1 -0
  34. package/form-control/styled-components.js +27 -5
  35. package/form-control/styled-components.js.flow +25 -3
  36. package/form-control/types.js.flow +20 -8
  37. package/package.json +1 -2
  38. package/popover/popover.js +1 -1
  39. 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: `${sum(ctx.widths)}px`,
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]); // We use state for our ref, to allow hooks to update when the ref changes.
473
- // eslint-disable-next-line flowtype/no-weak-types
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
- const gridProps = gridRef.props;
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
- }, [gridRef, measuredWidths, resizeDeltas, browserScrollbarWidth, rows.length, columns]);
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: setGridRef,
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: FILTER_SHELL_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
- alignItems: 'flex-end',
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
- }, excludeText)), /*#__PURE__*/React.createElement(Button, {
41
+ }, locale.datatable.filterExclude), /*#__PURE__*/React.createElement(Button, {
64
42
  size: BUTTON_SIZE.compact,
65
43
  type: "submit"
66
44
  }, locale.datatable.filterApply)));
@@ -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 rows.',
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 categories found',
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
- function MeasureColumn({
13
- sampleIndexes,
14
- column,
15
- columnIndex,
16
- rows,
17
- isSelectable,
18
- onLayout
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 (ref.current) {
24
- onLayout(columnIndex, ref.current.getBoundingClientRect());
19
+ if (typeof document !== 'undefined') {
20
+ if (node) {
21
+ window.requestAnimationFrame(() => {
22
+ setDimensions(node.getBoundingClientRect());
23
+ });
24
+ }
25
25
  }
26
- }, []);
27
- return /*#__PURE__*/React.createElement("div", {
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 widthMap = React.useMemo(() => {
100
- return new Map();
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 sampleIndexes = React.useMemo(() => {
105
- return generateSampleIndices(0, rows.length - 1, sampleSize);
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
- const nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, widthMap.get(columnIndex) || 0, dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);
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 !== widthMap.get(columnIndex)) {
111
- widthMap.set(columnIndex, nextWidth);
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 ( // Refresh at 100% of done
115
- widthMap.size === columns.length || // ...50%
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
- }); // Remove the measurement nodes after we are done updating our column width
114
+ });
126
115
 
127
- if (widthMap.size === columns.length) {
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
- }, columns.map((column, i) => {
139
- return /*#__PURE__*/React.createElement(MeasureColumn, {
140
- key: column.title + i,
141
- column: column,
142
- rows: rows,
143
- isSelectable: isSelectable,
144
- onLayout: handleDimensionsChange,
145
- columnIndex: i,
146
- sampleIndexes: sampleIndexes
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
- return /*#__PURE__*/React.createElement(React.Fragment, null, label && /*#__PURE__*/React.createElement(Label, _extends({
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,
@@ -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 && !this.state.autoFocusAfterPositioning
460
+ disabled: !this.props.autoFocus || !this.state.autoFocusAfterPositioning
461
461
  }, this.renderPopover(renderedContent)))));
462
462
  } else {
463
463
  rendered.push( /*#__PURE__*/React.createElement(Hidden, {