superdesk-ui-framework 3.1.9 → 3.1.13

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 (113) hide show
  1. package/app/styles/_helpers.scss +926 -776
  2. package/app/styles/_master-desk.scss +2 -2
  3. package/app/styles/_toggle-box.scss +45 -28
  4. package/app/styles/components/_sd-collapse-box.scss +113 -0
  5. package/app/styles/components/_subnav.scss +0 -1
  6. package/app/styles/design-tokens/_design-tokens-general.scss +19 -5
  7. package/app/styles/design-tokens/_new-colors.scss +11 -1
  8. package/app/styles/form-elements/_inputs.scss +14 -0
  9. package/app/styles/grids/_grid-layout.scss +3 -0
  10. package/app-typescript/components/DatePicker.tsx +6 -0
  11. package/app-typescript/components/Layouts/LayoutContainer.tsx +7 -1
  12. package/app-typescript/components/Layouts/PageLayout.tsx +2 -1
  13. package/app-typescript/components/TimePickerV2.tsx +222 -0
  14. package/app-typescript/components/ToggleBox/CustomHeaderToggleBox.tsx +61 -0
  15. package/app-typescript/components/{Togglebox.tsx → ToggleBox/SimpleToggleBox.tsx} +13 -34
  16. package/app-typescript/components/ToggleBox/index.tsx +43 -0
  17. package/app-typescript/components/TreeMenu.tsx +12 -7
  18. package/app-typescript/components/TreeSelect/TreeSelect.tsx +13 -12
  19. package/app-typescript/components/TreeSelect/TreeSelectItem.tsx +11 -1
  20. package/app-typescript/index.ts +2 -1
  21. package/dist/components/Alerts.tsx +1 -1
  22. package/dist/components/ContentDivider.tsx +1 -1
  23. package/dist/components/DragHandleDocs.tsx +2 -2
  24. package/dist/components/Index.tsx +105 -50
  25. package/dist/components/Panel.tsx +13 -13
  26. package/dist/components/Tags.tsx +2 -2
  27. package/dist/components/TimePicker.tsx +43 -1
  28. package/dist/components/Togglebox.tsx +171 -17
  29. package/dist/components/TreeMenu.tsx +2 -0
  30. package/dist/components/utilities/BorderRadiusUtilities.tsx +56 -0
  31. package/dist/components/utilities/BorderUtilities.tsx +170 -0
  32. package/dist/components/utilities/DisplayUtilities.tsx +116 -0
  33. package/dist/components/utilities/FlexAndGridUtilities.tsx +551 -0
  34. package/dist/components/utilities/ObjectFitUtilities.tsx +53 -0
  35. package/dist/components/utilities/ObjectPositionUtilities.tsx +68 -0
  36. package/dist/components/utilities/OpacityUtilities.tsx +64 -0
  37. package/dist/components/utilities/OverflowUtilities.tsx +93 -0
  38. package/dist/components/utilities/PositionUtilities.tsx +52 -0
  39. package/dist/components/utilities/ShadowUtilities.tsx +123 -0
  40. package/dist/components/utilities/SpacingUtilities.tsx +2 -2
  41. package/dist/components/utilities/TextUtilities.tsx +83 -4
  42. package/dist/components.html +2 -4
  43. package/dist/components_deprecated/modals.html +2 -2
  44. package/dist/components_deprecated.html +1 -0
  45. package/dist/design-patterns/Index.tsx +1 -42
  46. package/dist/design-patterns/ThreePaneLayoutPattern.tsx +1 -1
  47. package/dist/design-patterns.html +2 -4
  48. package/dist/design.html +1 -0
  49. package/dist/examples.bundle.css +15 -7
  50. package/dist/examples.bundle.js +4283 -2189
  51. package/dist/main.html +1 -0
  52. package/dist/playgrounds/react-playgrounds/Rundowns.tsx +1 -1
  53. package/dist/playgrounds/react-playgrounds/TestGround.tsx +214 -2
  54. package/dist/playgrounds.html +1 -0
  55. package/dist/superdesk-ui.bundle.css +1397 -1019
  56. package/dist/superdesk-ui.bundle.js +2039 -1653
  57. package/dist/vendor.bundle.js +16 -16
  58. package/examples/css/docs-page.css +15 -7
  59. package/examples/js/doc.js +13 -1
  60. package/examples/pages/components/Alerts.tsx +1 -1
  61. package/examples/pages/components/ContentDivider.tsx +1 -1
  62. package/examples/pages/components/DragHandleDocs.tsx +2 -2
  63. package/examples/pages/components/Index.tsx +105 -50
  64. package/examples/pages/components/Panel.tsx +13 -13
  65. package/examples/pages/components/Tags.tsx +2 -2
  66. package/examples/pages/components/TimePicker.tsx +43 -1
  67. package/examples/pages/components/Togglebox.tsx +171 -17
  68. package/examples/pages/components/TreeMenu.tsx +2 -0
  69. package/examples/pages/components/utilities/BorderRadiusUtilities.tsx +56 -0
  70. package/examples/pages/components/utilities/BorderUtilities.tsx +170 -0
  71. package/examples/pages/components/utilities/DisplayUtilities.tsx +116 -0
  72. package/examples/pages/components/utilities/FlexAndGridUtilities.tsx +551 -0
  73. package/examples/pages/components/utilities/ObjectFitUtilities.tsx +53 -0
  74. package/examples/pages/components/utilities/ObjectPositionUtilities.tsx +68 -0
  75. package/examples/pages/components/utilities/OpacityUtilities.tsx +64 -0
  76. package/examples/pages/components/utilities/OverflowUtilities.tsx +93 -0
  77. package/examples/pages/components/utilities/PositionUtilities.tsx +52 -0
  78. package/examples/pages/components/utilities/ShadowUtilities.tsx +123 -0
  79. package/examples/pages/components/utilities/SpacingUtilities.tsx +2 -2
  80. package/examples/pages/components/utilities/TextUtilities.tsx +83 -4
  81. package/examples/pages/components.html +2 -4
  82. package/examples/pages/components_deprecated/modals.html +2 -2
  83. package/examples/pages/components_deprecated.html +1 -0
  84. package/examples/pages/design-patterns/Index.tsx +1 -42
  85. package/examples/pages/design-patterns/ThreePaneLayoutPattern.tsx +1 -1
  86. package/examples/pages/design-patterns.html +2 -4
  87. package/examples/pages/design.html +1 -0
  88. package/examples/pages/main.html +1 -0
  89. package/examples/pages/playgrounds/react-playgrounds/Rundowns.tsx +1 -1
  90. package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +214 -2
  91. package/examples/pages/playgrounds.html +1 -0
  92. package/package.json +1 -1
  93. package/react/components/DatePicker.d.ts +3 -0
  94. package/react/components/DatePicker.js +2 -2
  95. package/react/components/Layouts/LayoutContainer.d.ts +1 -0
  96. package/react/components/Layouts/LayoutContainer.js +8 -1
  97. package/react/components/Layouts/PageLayout.d.ts +1 -0
  98. package/react/components/Layouts/PageLayout.js +1 -1
  99. package/react/components/TimePickerV2.d.ts +28 -0
  100. package/react/components/TimePickerV2.js +189 -0
  101. package/react/components/ToggleBox/CustomHeaderToggleBox.d.ts +12 -0
  102. package/react/components/ToggleBox/CustomHeaderToggleBox.js +81 -0
  103. package/react/components/ToggleBox/SimpleToggleBox.d.ts +18 -0
  104. package/react/components/{Togglebox.js → ToggleBox/SimpleToggleBox.js} +15 -13
  105. package/react/components/ToggleBox/index.d.ts +27 -0
  106. package/react/components/ToggleBox/index.js +71 -0
  107. package/react/components/TreeMenu.js +9 -7
  108. package/react/components/TreeSelect/TreeSelect.js +9 -11
  109. package/react/components/TreeSelect/TreeSelectItem.d.ts +1 -0
  110. package/react/components/TreeSelect/TreeSelectItem.js +7 -4
  111. package/react/index.d.ts +2 -1
  112. package/react/index.js +7 -5
  113. package/react/components/Togglebox.d.ts +0 -28
@@ -0,0 +1,222 @@
1
+ import * as React from 'react';
2
+ import { InputWrapper } from './Form';
3
+ import {IInputWrapper} from './Form/InputWrapper';
4
+ import {padStart, range} from 'lodash';
5
+
6
+ interface IProps extends IInputWrapper {
7
+ value: string; // ISO 8601, 13:59:01
8
+ allowSeconds?: boolean;
9
+ disabledOptions: {
10
+ hours?: Array<number>;
11
+ minutes?: Array<number>;
12
+ seconds?: Array<number>;
13
+ };
14
+ 'data-test-id'?: string;
15
+ onChange(valueNext: string): void;
16
+ }
17
+
18
+ type ITimeUnit = 'hours' | 'minutes' | 'seconds';
19
+
20
+ export class TimePickerV2 extends React.PureComponent<IProps> {
21
+ private is12HourFormat: boolean;
22
+
23
+ constructor(props: IProps) {
24
+ super(props);
25
+
26
+ this.handleTimeChange = this.handleTimeChange.bind(this);
27
+ this.getCorrectedTime = this.getCorrectedTime.bind(this);
28
+ this.getOptionsForTimeUnit = this.getOptionsForTimeUnit.bind(this);
29
+ this.padValue = this.padValue.bind(this);
30
+
31
+ const hour = new Date().toLocaleTimeString([], { hour: 'numeric' });
32
+ this.is12HourFormat = hour.includes('AM') || hour.includes('PM');
33
+ }
34
+
35
+ /**
36
+ * in case initial time is not valid according to disabled options, we return first valid option
37
+ */
38
+ private getCorrectedTime(timeUnit: ITimeUnit, timeStringArray: Array<string>): string {
39
+ const dividedValue = this.props.value.split(':');
40
+ const value = (() => {
41
+ if (timeUnit === 'hours') {
42
+ return dividedValue[0];
43
+ } else if (timeUnit === 'minutes') {
44
+ return dividedValue[1];
45
+ }
46
+
47
+ return dividedValue[2];
48
+ })();
49
+
50
+ if (!(this.props.disabledOptions[timeUnit] ?? []).includes(parseInt(value, 10)) && value != null) {
51
+ return value;
52
+ }
53
+
54
+ return timeStringArray[0];
55
+ }
56
+
57
+ private getOptionsForTimeUnit(timeUnit: ITimeUnit): Array<string> {
58
+ let format12HourArr = range(1, 13);
59
+ format12HourArr.unshift(format12HourArr.pop() as number);
60
+
61
+ const timeUnitArray = (() => {
62
+ if (timeUnit === 'hours') {
63
+ if (this.is12HourFormat) {
64
+ return format12HourArr;
65
+ } else {
66
+ return range(24);
67
+ }
68
+ } else {
69
+ return range(60);
70
+ }
71
+ })();
72
+
73
+ return timeUnitArray
74
+ .filter((item) => !(this.props.disabledOptions[timeUnit] ?? []).includes(item))
75
+ .map((value) => padStart(value.toString(), 2, '0'));
76
+ }
77
+
78
+ private handleTimeChange(index: number, newValue: string) {
79
+ let current = this.props.value.split(':');
80
+
81
+ const updated12HourValue = (() => {
82
+ if (parseInt(current[0], 10) >= 12) {
83
+ if (newValue === '12') {
84
+ return newValue;
85
+ } else {
86
+ return (parseInt(newValue, 10) + 12).toString();
87
+ }
88
+ } else {
89
+ if (newValue === '12') {
90
+ return '00';
91
+ } else {
92
+ return newValue;
93
+ }
94
+ }
95
+ })();
96
+
97
+ current[index] = this.is12HourFormat ? updated12HourValue : newValue;
98
+
99
+ this.props.onChange(current.join(':'));
100
+ }
101
+
102
+ componentDidMount(): void {
103
+ const correctedTime = [
104
+ this.getCorrectedTime('hours', this.getOptionsForTimeUnit('hours')),
105
+ ':',
106
+ this.getCorrectedTime('minutes', this.getOptionsForTimeUnit('minutes')),
107
+ this.props.allowSeconds
108
+ ? `:${this.getCorrectedTime('seconds', this.getOptionsForTimeUnit('seconds'))}`
109
+ : '',
110
+ ].join('');
111
+
112
+ if (this.props.value !== correctedTime) {
113
+ this.props.onChange(correctedTime);
114
+ }
115
+ }
116
+
117
+ padValue(value: number) {
118
+ return padStart((value).toString(), 2, '0');
119
+ }
120
+
121
+ updatedTimeUnit() {
122
+ const timeUnitValuesArray = this.props.value.split(':');
123
+
124
+ /**
125
+ * updating the initial value from props
126
+ */
127
+ if (this.is12HourFormat) {
128
+ if (parseInt(timeUnitValuesArray[0], 10) > 12) {
129
+ timeUnitValuesArray[0] = this.padValue(parseInt(timeUnitValuesArray[0], 10) - 12);
130
+ }
131
+ }
132
+
133
+ return timeUnitValuesArray;
134
+ }
135
+
136
+ render() {
137
+ const timeUnitValuesArray = this.updatedTimeUnit();
138
+
139
+ return (
140
+ <InputWrapper
141
+ label={this.props.label}
142
+ error={this.props.error}
143
+ invalid={this.props.error != null}
144
+ required={this.props.required}
145
+ disabled={this.props.disabled}
146
+ info={this.props.info}
147
+ inlineLabel={this.props.inlineLabel}
148
+ labelHidden={this.props.labelHidden}
149
+ tabindex={this.props.tabindex}
150
+ >
151
+ <div className='sd__input__time-picker-v2' data-test-id={this.props['data-test-id']}>
152
+ <div className='input-wrapper__time-picker-v2'>
153
+ <select
154
+ className='sd-input__select'
155
+ value={timeUnitValuesArray[0]}
156
+ onChange={({target}) => {
157
+ this.handleTimeChange(0, target.value);
158
+ }}
159
+ >
160
+ {this.getOptionsForTimeUnit('hours').map((hour) => (
161
+ <option value={hour} label={hour} key={hour} />
162
+ ))}
163
+ </select>
164
+ <span className='time-picker-v2-suffix'>:</span>
165
+ </div>
166
+ <div className='input-wrapper__time-picker-v2'>
167
+ <select
168
+ className='sd-input__select'
169
+ value={timeUnitValuesArray[1]}
170
+ onChange={({target}) => {
171
+ this.handleTimeChange(1, target.value);
172
+ }}
173
+ >
174
+ {this.getOptionsForTimeUnit('minutes').map((minute) => (
175
+ <option value={minute} label={minute} key={minute} />
176
+ ))}
177
+ </select>
178
+ {this.props.allowSeconds && (<span className='time-picker-v2-suffix'>:</span>)}
179
+ </div>
180
+ {this.props.allowSeconds && (
181
+ <div className='input-wrapper__time-picker-v2'>
182
+ <select
183
+ className='sd-input__select'
184
+ value={timeUnitValuesArray[2]}
185
+ onChange={({target}) => {
186
+ this.handleTimeChange(2, target.value);
187
+ }}
188
+ >
189
+ {this.getOptionsForTimeUnit('seconds').map((second) => (
190
+ <option value={second} label={second} key={second} />
191
+ ))}
192
+ </select>
193
+ </div>
194
+ )}
195
+ {this.is12HourFormat && (
196
+ <div className='input-wrapper__time-picker-v2'>
197
+ <span className='time-picker-v2-suffix' />
198
+ <select
199
+ className='sd-input__select'
200
+ value={(parseInt(this.props.value.split(':')[0], 10) >= 12) ? 'PM' : 'AM'}
201
+ onChange={({target}) => {
202
+ let splitValue = this.props.value.split(':');
203
+
204
+ if (target.value === 'PM') {
205
+ splitValue[0] = this.padValue(parseInt(splitValue[0], 10) + 12);
206
+ } else {
207
+ splitValue[0] = this.padValue(parseInt(splitValue[0], 10) - 12);
208
+ }
209
+
210
+ this.props.onChange(splitValue.join(':'));
211
+ }}
212
+ >
213
+ <option value='AM' label='AM' />
214
+ <option value='PM' label='PM' />
215
+ </select>
216
+ </div>
217
+ )}
218
+ </div>
219
+ </InputWrapper>
220
+ );
221
+ }
222
+ }
@@ -0,0 +1,61 @@
1
+ import * as React from 'react';
2
+ import classNames from 'classnames';
3
+ import nextId from "react-id-generator";
4
+ import {IPropsCustomHeader} from "../ToggleBox/index";
5
+
6
+ interface IState {
7
+ isOpen: boolean;
8
+ }
9
+
10
+ export class CustomHeaderToggleBox extends React.PureComponent<IPropsCustomHeader, IState> {
11
+ htmlId = nextId('togglebox-');
12
+ constructor(props: IPropsCustomHeader) {
13
+ super(props);
14
+ this.state = {
15
+ isOpen: this.props.initiallyOpen ?? false,
16
+ };
17
+ }
18
+
19
+ toggle = (): void => {
20
+ this.setState({isOpen: !this.state.isOpen}, () => {
21
+ this.props.onToggle?.(this.state.isOpen);
22
+ });
23
+ }
24
+
25
+ render() {
26
+ let classes = classNames('sd-shadow--z1 new-collapse-box', {
27
+ 'new-collapse-box--open': this.state.isOpen,
28
+ });
29
+ const { isOpen } = this.state;
30
+
31
+ return (
32
+ <div
33
+ className={classes}
34
+ aria-expanded={isOpen}
35
+ data-test-id='toggle-box'
36
+ >
37
+ <div className='new-collapse-box__header'>
38
+ <div className='new-collapse-box__header-inner'>
39
+ {this.props.header}
40
+ </div>
41
+
42
+ <button
43
+ className='new-collapse-box__divider'
44
+ onClick={this.toggle}
45
+ aria-controls={this.htmlId}
46
+ >
47
+ <span className='label label--translucent new-collapse-box__divider-label'>
48
+ {this.props.toggleButtonLabel}
49
+ </span>
50
+ </button>
51
+ </div>
52
+
53
+ <div className='new-collapse-box__content'>
54
+ <div id={this.htmlId} aria-hidden={!isOpen} className='new-collapse-box__content-inner p-2 pt-0-5'>
55
+ {this.props.children}
56
+ </div>
57
+ </div>
58
+ </div>
59
+ );
60
+ }
61
+ }
@@ -1,18 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import classNames from 'classnames';
3
3
  import nextId from "react-id-generator";
4
-
5
- interface IProps {
6
- title: string;
7
- badge?: JSX.Element;
8
- children: any;
9
- hideUsingCSS?: boolean;
10
- initiallyOpen?: boolean; // defaults to false
11
- className?: string;
12
- margin?: 'none' | 'small' | 'normal' | 'large';
13
- onOpen?(): void;
14
- onClose?(): void;
15
- }
4
+ import {IPropsSimple} from "../ToggleBox/index";
16
5
 
17
6
  interface IState {
18
7
  isOpen: boolean;
@@ -24,9 +13,9 @@ interface IState {
24
13
  * @description ToggleBox used to open/close a set of details
25
14
  */
26
15
 
27
- export class ToggleBox extends React.PureComponent<IProps, IState> {
28
- htmlId = nextId();
29
- constructor(props: IProps) {
16
+ export class SimpleToggleBox extends React.PureComponent<IPropsSimple, IState> {
17
+ htmlId = nextId('togglebox-');
18
+ constructor(props: IPropsSimple) {
30
19
  super(props);
31
20
  this.state = {
32
21
  isOpen: this.props.initiallyOpen ?? false,
@@ -56,10 +45,13 @@ export class ToggleBox extends React.PureComponent<IProps, IState> {
56
45
  render() {
57
46
  let classes = classNames('toggle-box', {
58
47
  'toggle-box--margin-normal': this.props.margin === undefined,
48
+ 'toggle-box--large-title': this.props.largeTitle,
49
+ 'toggle-box--circle': this.props.circledChevron,
59
50
  [`toggle-box--margin-${this.props.margin}`]: this.props.margin,
60
51
  'hidden': !this.state.isOpen,
52
+ 'open': this.state.isOpen,
61
53
  }, this.props.className);
62
- const { title, hideUsingCSS, children, badge } = this.props;
54
+ const { title, children, badge } = this.props;
63
55
  const { isOpen } = this.state;
64
56
 
65
57
  return (
@@ -72,7 +64,8 @@ export class ToggleBox extends React.PureComponent<IProps, IState> {
72
64
  role="button"
73
65
  tabIndex={0}
74
66
  onKeyDown={this.handleKeyDown}
75
- id={`togglebox-${this.htmlId}`}
67
+ aria-expanded={isOpen}
68
+ aria-controls={this.htmlId}
76
69
  >
77
70
  <div className="toggle-box__chevron">
78
71
  <i className="icon-chevron-right-thin" />
@@ -86,23 +79,9 @@ export class ToggleBox extends React.PureComponent<IProps, IState> {
86
79
  {badge ? badge : null}
87
80
  </a>
88
81
  <div className="toggle-box__content-wraper">
89
- {isOpen && !hideUsingCSS && (
90
- <div className="toggle-box__content" aria-describedby={`togglebox-${this.htmlId}`}>
91
- {children}
92
- </div>
93
- )}
94
-
95
- {hideUsingCSS && (
96
- <div
97
- className={classNames(
98
- 'toggle-box__content',
99
- { 'toggle-box__content--hidden': !isOpen },
100
- )}
101
- aria-describedby={`togglebox-${this.htmlId}`}
102
- >
103
- {children}
104
- </div>
105
- )}
82
+ <div id={this.htmlId} className="toggle-box__content" aria-hidden={!isOpen}>
83
+ {children}
84
+ </div>
106
85
  </div>
107
86
  </div>
108
87
  );
@@ -0,0 +1,43 @@
1
+ import * as React from 'react';
2
+ import {SimpleToggleBox} from './SimpleToggleBox';
3
+ import {CustomHeaderToggleBox} from './CustomHeaderToggleBox';
4
+
5
+ export interface IPropsSimple {
6
+ variant: 'simple';
7
+ title: string;
8
+ badge?: JSX.Element;
9
+ children: React.ReactNode;
10
+ circledChevron?: boolean;
11
+ initiallyOpen?: boolean; // defaults to false
12
+ largeTitle?: boolean;
13
+
14
+ className?: string;
15
+ margin?: 'none' | 'small' | 'normal' | 'large';
16
+ onOpen?(): void;
17
+ onClose?(): void;
18
+ }
19
+
20
+ export interface IPropsCustomHeader {
21
+ variant: 'custom-header'; // always visible
22
+ header: React.ReactNode;
23
+ children: React.ReactNode;
24
+ toggleButtonLabel: string;
25
+ initiallyOpen?: boolean;
26
+ onToggle?(isOpen: boolean): void;
27
+ }
28
+
29
+ type IProps = IPropsSimple | IPropsCustomHeader;
30
+
31
+ export class ToggleBox extends React.PureComponent<IProps> {
32
+ render() {
33
+ if (this.props.variant === "simple") {
34
+ return (
35
+ <SimpleToggleBox {...this.props} />
36
+ );
37
+ } else {
38
+ return (
39
+ <CustomHeaderToggleBox {...this.props} />
40
+ );
41
+ }
42
+ }
43
+ }
@@ -57,7 +57,7 @@ function nodeCanBeSelected<T>(item: IParent<T> | IChildren<T>): item is IChildre
57
57
 
58
58
  function onSelect<T>(item: ITreeMenuNode<T>) {
59
59
  if (nodeCanBeSelected(item)) {
60
- return item.onSelect;
60
+ return item.onSelect();
61
61
  }
62
62
 
63
63
  return undefined;
@@ -285,11 +285,9 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
285
285
 
286
286
  const item = this.state.buttonTree.pop();
287
287
 
288
- if (item != null) {
289
- this.setState({
290
- buttonValue: item,
291
- });
292
- }
288
+ this.setState({
289
+ buttonValue: item ?? null,
290
+ });
293
291
  }
294
292
 
295
293
  recursion(arr: Array<ITreeMenuNode<T>>) {
@@ -414,15 +412,22 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
414
412
  <ul
415
413
  ref={this.ref}
416
414
  className="suggestion-list suggestion-list--multi-select"
415
+ role='tree'
417
416
  >
418
417
  {this.state.options.map((option, i: React.Key | undefined) => (
419
418
  <TreeSelectItem
420
419
  key={i}
421
420
  option={option}
422
421
  handleTree={this.handleTree}
423
- onClick={onSelect(option)}
422
+ onClick={() => {
423
+ onSelect(option);
424
+ }}
424
425
  disabledItem={disabledItem(option)}
425
426
  getBorderColor={this.props.getBorderColor}
427
+ parentCategory={this.state.buttonValue == null
428
+ ? undefined
429
+ : this.props.getLabel(this.state.buttonValue.value)
430
+ }
426
431
  getBackgroundColor={this.props.getBackgroundColor}
427
432
  getId={this.props.getId}
428
433
  optionTemplate={this.props.optionTemplate}
@@ -455,11 +455,9 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
455
455
 
456
456
  const item = this.state.buttonTree.pop();
457
457
 
458
- if (item != null) {
459
- this.setState({
460
- buttonValue: item,
461
- });
462
- }
458
+ this.setState({
459
+ buttonValue: item ?? null,
460
+ });
463
461
  }
464
462
 
465
463
  recursion(arr: Array<ITreeNode<T>>) {
@@ -738,6 +736,8 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
738
736
  }
739
737
  }}
740
738
  data-test-id="open-popover"
739
+ aria-haspopup="tree"
740
+ aria-expanded={this.state.openDropdown}
741
741
  >
742
742
  <i className="icon-plus-large"></i>
743
743
  </button>
@@ -893,12 +893,7 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
893
893
  ref={this.dropdownRef}
894
894
  >
895
895
  <div className='autocomplete__header'>
896
- <div
897
- className="autocomplete__icon"
898
- onClick={() => {
899
- this.backButton();
900
- }}
901
- >
896
+ <div className="autocomplete__icon">
902
897
  <Icon name="search" className="search"></Icon>
903
898
  </div>
904
899
 
@@ -968,6 +963,8 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
968
963
  className="suggestion-list suggestion-list--multi-select"
969
964
  ref={this.ref}
970
965
  data-test-id="options"
966
+ role='tree'
967
+ aria-multiselectable={this.props.allowMultiple}
971
968
  >
972
969
  {this.state.options.map((option, i: React.Key | undefined) => {
973
970
  let selectedItem = this.state.value.some((obj) =>
@@ -981,11 +978,15 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
981
978
  handleTree={this.handleTree}
982
979
  selectedItem={selectedItem}
983
980
  allowMultiple={this.props.allowMultiple}
981
+ parentCategory={this.state.buttonValue == null
982
+ ? undefined
983
+ : this.props.getLabel(this.state.buttonValue.value)
984
+ }
984
985
  getBorderColor={this.props.getBorderColor}
985
986
  getBackgroundColor={this.props.getBackgroundColor}
986
987
  getId={this.props.getId}
987
- optionTemplate={this.props.optionTemplate}
988
988
  getLabel={this.props.getLabel}
989
+ optionTemplate={this.props.optionTemplate}
989
990
  onKeyDown={() => this.setState({
990
991
  buttonTarget: [
991
992
  ...this.state.buttonTarget,
@@ -12,6 +12,7 @@ interface IProps<T> {
12
12
  selectedItem?: boolean;
13
13
  disabledItem?: boolean;
14
14
  allowMultiple?: boolean;
15
+ parentCategory?: string | undefined;
15
16
  handleTree(event: React.MouseEvent<HTMLLIElement, MouseEvent>, option: ITreeNode<T>): any;
16
17
  getLabel(item: T): string;
17
18
  getId(item: T): string;
@@ -24,9 +25,14 @@ interface IProps<T> {
24
25
 
25
26
  export class TreeSelectItem<T> extends React.Component<IProps<T>> {
26
27
  render() {
28
+ const ariaLabel = this.props.parentCategory !== undefined
29
+ ? `${this.props.getLabel(this.props.option.value)}, parent ${this.props.parentCategory}`
30
+ : this.props.getLabel(this.props.option.value);
31
+
27
32
  return (
28
33
  <li
29
34
  className='suggestion-item suggestion-item--multi-select'
35
+ role='none'
30
36
  onClick={(event) => {
31
37
  if (!this.props.disabledItem) {
32
38
  this.props.onClick?.();
@@ -49,6 +55,9 @@ export class TreeSelectItem<T> extends React.Component<IProps<T>> {
49
55
  }}
50
56
  disabled={this.props.disabledItem}
51
57
  data-test-id="option"
58
+ role='treeItem'
59
+ aria-selected={this.props.selectedItem === true}
60
+ aria-disabled={this.props.disabledItem === true}
52
61
  >
53
62
  {(this.props.getBorderColor && !this.props.allowMultiple)
54
63
  && <div
@@ -74,6 +83,7 @@ export class TreeSelectItem<T> extends React.Component<IProps<T>> {
74
83
  }
75
84
  : undefined
76
85
  }
86
+ aria-label={ariaLabel}
77
87
  >
78
88
  {this.props.optionTemplate
79
89
  ? this.props.optionTemplate(this.props.option.value)
@@ -82,7 +92,7 @@ export class TreeSelectItem<T> extends React.Component<IProps<T>> {
82
92
  </span>
83
93
 
84
94
  {this.props.option.children
85
- && <span className="suggestion-item__icon">
95
+ && <span className="suggestion-item__icon" aria-hidden="true">
86
96
  <Icon name="chevron-right-thin"></Icon>
87
97
  </span>
88
98
  }
@@ -27,6 +27,7 @@ export { DatePicker } from './components/DatePicker';
27
27
  export { DatePickerISO } from './components/DatePicker';
28
28
  export { DatePickerLocaleSettings } from './components/DatePicker';
29
29
  export { TimePicker } from './components/TimePicker';
30
+ export { TimePickerV2 } from './components/TimePickerV2';
30
31
  export { FormLabel } from './components/FormLabel';
31
32
  export { Switch } from './components/Switch';
32
33
  export { SwitchGroup } from './components/SwitchGroup';
@@ -69,7 +70,7 @@ export { GridItem, GridItemContent, GridItemMedia, GridItemFooter, GridItemConte
69
70
  } from './components/GridItem';
70
71
  export { toasted } from './components/Toast';
71
72
  export { Menu } from './components/Menu';
72
- export { ToggleBox } from './components/Togglebox';
73
+ export { ToggleBox } from './components/ToggleBox/index';
73
74
  export { SelectGrid } from './components/SelectGrid';
74
75
  export { IconPicker } from './components/IconPicker';
75
76
  export { ThemeSelector } from './components/ThemeSelector';
@@ -142,7 +142,7 @@ export default class AlertDoc extends React.Component {
142
142
  This will strip all margins and the border-radius from the component. Hollow style is not recommended in this case, and small size is advised.</p>
143
143
  <Markup.ReactMarkup>
144
144
  <Markup.ReactMarkupPreview>
145
- <div className='sd-display--flex' style={{border: '1px solid var(--sd-colour-line--medium)', backgroundColor: 'var(--sd-colour-panel-bg--100)', maxHeight: '360px'}}>
145
+ <div className='d-flex' style={{border: '1px solid var(--sd-colour-line--medium)', backgroundColor: 'var(--sd-colour-panel-bg--100)', maxHeight: '360px'}}>
146
146
  <PanelElements.Panel open={true} side='left' size='small'>
147
147
  <PanelElements.PanelHeader title='Panel example' onClose={()=> false}>
148
148
  <Alert type='warning' icon='exclamation-sign' banner={true} size='small'>
@@ -125,7 +125,7 @@ export default class ContentDividerDoc extends React.Component {
125
125
  </div>
126
126
  <p className="docs-page__paragraph ">// With text</p>
127
127
  <p className="docs-page__paragraph--small sd-margin-b--3">Inside a flex container (flex-direction: column;).</p>
128
- <div className='docs-page__content-row sd-display--flex'>
128
+ <div className='docs-page__content-row d-flex'>
129
129
  <div style={{width:'100%'}}>
130
130
  Cras justo odio, dapibus ac facilisis in, egestas eget quam. Cum sociis natoque penatibus et
131
131
  magnis dis parturient montes, nascetur ridiculus mus. Maecenas sed diam eget risus varius blandit
@@ -23,7 +23,7 @@ export default class DragHandleDocs extends React.Component {
23
23
  offering a wide range of size options.
24
24
  </p>
25
25
  <div className="docs-page__content-row">
26
- <div className='sd-display--flex sd-flex--items-start sd-gap--medium'>
26
+ <div className='d-flex items-start sd-gap--medium'>
27
27
  <DragHandle dotsInRow='2' dotRows='5' />
28
28
  <DragHandle dotsInRow='2' dotRows='8' />
29
29
  <DragHandle dotsInRow='3' dotRows='6' />
@@ -39,7 +39,7 @@ export default class DragHandleDocs extends React.Component {
39
39
  To be used within list items, draggable labels, and similar contexts.
40
40
  </p>
41
41
  <div className="docs-page__content-row">
42
- <div className='sd-display--flex sd-flex--items-start sd-gap--medium'>
42
+ <div className='d-flex items-start sd-gap--medium'>
43
43
  <DragHandle blank={true} />
44
44
  <DragHandle dotsInRow='2' dotRows='10' blank={true} />
45
45
  <DragHandle dotsInRow='4' dotRows='10' blank={true} />