@khanacademy/wonder-blocks-dropdown 10.0.4 → 10.0.5

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/dist/index.js CHANGED
@@ -2,13 +2,12 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var _extends = require('@babel/runtime/helpers/extends');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
7
  var aphrodite = require('aphrodite');
8
8
  var wonderBlocksCell = require('@khanacademy/wonder-blocks-cell');
9
9
  var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
10
10
  var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
11
- var _objectWithoutPropertiesLoose = require('@babel/runtime/helpers/objectWithoutPropertiesLoose');
12
11
  var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
13
12
  var wonderBlocksLayout = require('@khanacademy/wonder-blocks-layout');
14
13
  var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
@@ -49,9 +48,7 @@ function _interopNamespace(e) {
49
48
  return Object.freeze(n);
50
49
  }
51
50
 
52
- var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
53
51
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
54
- var _objectWithoutPropertiesLoose__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutPropertiesLoose);
55
52
  var checkIcon__default = /*#__PURE__*/_interopDefaultLegacy(checkIcon);
56
53
  var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
57
54
  var SearchField__default = /*#__PURE__*/_interopDefaultLegacy(SearchField);
@@ -61,3348 +58,59 @@ var xIcon__default = /*#__PURE__*/_interopDefaultLegacy(xIcon);
61
58
  var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
62
59
  var Pill__default = /*#__PURE__*/_interopDefaultLegacy(Pill);
63
60
 
64
- const selectDropdownStyle = {
65
- marginTop: wonderBlocksTokens.spacing.xSmall_8,
66
- marginBottom: wonderBlocksTokens.spacing.xSmall_8
67
- };
68
- const filterableDropdownStyle = {
69
- minHeight: 100
70
- };
71
- const DROPDOWN_ITEM_HEIGHT = 40;
72
- const MAX_VISIBLE_ITEMS = 9;
73
- const SEPARATOR_ITEM_HEIGHT = 9;
74
- const defaultLabels = {
75
- clearSearch: "Clear search",
76
- filter: "Filter",
77
- noResults: "No results",
78
- selectNoneLabel: "Select none",
79
- selectAllLabel: numOptions => `Select all (${numOptions})`,
80
- noneSelected: "0 items",
81
- someSelected: numSelectedValues => numSelectedValues === 1 ? "1 item" : `${numSelectedValues} items`,
82
- allSelected: "All items"
83
- };
84
- const defaultComboboxLabels = {
85
- clearSelection: "Clear selection",
86
- closedState: "Combobox is closed",
87
- comboboxButton: "Toggle listbox",
88
- listbox: "Options list",
89
- removeSelected: label => `Remove ${label}`,
90
- liveRegionCurrentItem: ({
91
- current,
92
- index,
93
- total,
94
- disabled,
95
- focused,
96
- selected
97
- }) => `${current}${focused ? " focused" : ""}${disabled ? " disabled" : ""}${selected ? " selected" : ""}, ${index + 1} of ${total}.`,
98
- liveRegionMultipleSelectionTotal: total => `${total} selected options.`,
99
- liveRegionListboxTotal: total => `${total} results available.`,
100
- noItems: "No results",
101
- selected: labels => `${labels} selected`,
102
- selectionCleared: "Selection cleared",
103
- unselected: labels => `${labels} not selected`
104
- };
61
+ const selectDropdownStyle={marginTop:wonderBlocksTokens.spacing.xSmall_8,marginBottom:wonderBlocksTokens.spacing.xSmall_8};const filterableDropdownStyle={minHeight:100};const DROPDOWN_ITEM_HEIGHT=40;const MAX_VISIBLE_ITEMS=9;const SEPARATOR_ITEM_HEIGHT=9;const defaultLabels={clearSearch:"Clear search",filter:"Filter",noResults:"No results",selectNoneLabel:"Select none",selectAllLabel:numOptions=>`Select all (${numOptions})`,noneSelected:"0 items",someSelected:numSelectedValues=>numSelectedValues===1?"1 item":`${numSelectedValues} items`,allSelected:"All items"};const defaultComboboxLabels={clearSelection:"Clear selection",closedState:"Combobox is closed",comboboxButton:"Toggle listbox",listbox:"Options list",removeSelected:label=>`Remove ${label}`,liveRegionCurrentItem:({current,index,total,disabled,focused,selected})=>`${current}${focused?" focused":""}${disabled?" disabled":""}${selected?" selected":""}, ${index+1} of ${total}.`,liveRegionMultipleSelectionTotal:total=>`${total} selected options.`,liveRegionListboxTotal:total=>`${total} results available.`,noItems:"No results",selected:labels=>`${labels} selected`,selectionCleared:"Selection cleared",unselected:labels=>`${labels} not selected`};
105
62
 
106
- class ActionItem extends React__namespace.Component {
107
- static isClassOf(instance) {
108
- return instance && instance.type && instance.type.__IS_ACTION_ITEM__;
109
- }
110
- render() {
111
- const {
112
- disabled,
113
- horizontalRule,
114
- href,
115
- target,
116
- indent,
117
- label,
118
- lang,
119
- leftAccessory,
120
- rightAccessory,
121
- onClick,
122
- role,
123
- style,
124
- testId
125
- } = this.props;
126
- const defaultStyle = [styles$b.wrapper, style];
127
- const labelComponent = typeof label === "string" ? React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
128
- lang: lang,
129
- style: styles$b.label
130
- }, label) : (React__namespace.cloneElement(label, _extends__default["default"]({
131
- lang,
132
- style: styles$b.label
133
- }, label.props)));
134
- return React__namespace.createElement(wonderBlocksCell.CompactCell, {
135
- disabled: disabled,
136
- horizontalRule: horizontalRule,
137
- rootStyle: defaultStyle,
138
- leftAccessory: leftAccessory,
139
- rightAccessory: rightAccessory,
140
- style: [styles$b.shared, indent && styles$b.indent],
141
- role: role,
142
- testId: testId,
143
- title: labelComponent,
144
- href: href,
145
- target: target,
146
- onClick: onClick
147
- });
148
- }
149
- }
150
- ActionItem.defaultProps = {
151
- disabled: false,
152
- horizontalRule: "none",
153
- indent: false,
154
- role: "menuitem"
155
- };
156
- ActionItem.__IS_ACTION_ITEM__ = true;
157
- const actionType$1 = wonderBlocksTokens.semanticColor.action.primary.progressive;
158
- const theme$7 = {
159
- actionItem: {
160
- color: {
161
- hover: {
162
- background: actionType$1.hover.background,
163
- foreground: actionType$1.hover.foreground
164
- },
165
- press: {
166
- background: actionType$1.press.background,
167
- foreground: actionType$1.press.foreground
168
- }
169
- }
170
- }
171
- };
172
- const styles$b = aphrodite.StyleSheet.create({
173
- wrapper: {
174
- minHeight: DROPDOWN_ITEM_HEIGHT,
175
- touchAction: "manipulation",
176
- ":focus": {
177
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
178
- outline: `${wonderBlocksTokens.spacing.xxxxSmall_2}px solid ${wonderBlocksTokens.semanticColor.focus.outer}`,
179
- outlineOffset: -wonderBlocksTokens.spacing.xxxxSmall_2
180
- },
181
- [":hover[aria-disabled=false]"]: {
182
- color: theme$7.actionItem.color.hover.foreground,
183
- background: theme$7.actionItem.color.hover.background
184
- },
185
- [":active[aria-disabled=false]"]: {
186
- color: theme$7.actionItem.color.press.foreground,
187
- background: theme$7.actionItem.color.press.background
188
- }
189
- },
190
- shared: {
191
- minHeight: DROPDOWN_ITEM_HEIGHT,
192
- paddingBlock: wonderBlocksTokens.sizing.size_100
193
- },
194
- label: {
195
- whiteSpace: "nowrap",
196
- userSelect: "none"
197
- },
198
- indent: {
199
- paddingLeft: wonderBlocksTokens.spacing.medium_16 * 2
200
- }
201
- });
63
+ class ActionItem extends React__namespace.Component{static isClassOf(instance){return instance&&instance.type&&instance.type.__IS_ACTION_ITEM__}render(){const{disabled,horizontalRule,href,target,indent,label,lang,leftAccessory,rightAccessory,onClick,role,style,testId}=this.props;const defaultStyle=[styles$b.wrapper,style];const labelComponent=typeof label==="string"?jsxRuntime.jsx(wonderBlocksTypography.LabelMedium,{lang:lang,style:styles$b.label,children:label}):React__namespace.cloneElement(label,{lang,style:styles$b.label,...label.props});return jsxRuntime.jsx(wonderBlocksCell.CompactCell,{disabled:disabled,horizontalRule:horizontalRule,rootStyle:defaultStyle,leftAccessory:leftAccessory,rightAccessory:rightAccessory,style:[styles$b.shared,indent&&styles$b.indent],role:role,testId:testId,title:labelComponent,href:href,target:target,onClick:onClick})}}ActionItem.defaultProps={disabled:false,horizontalRule:"none",indent:false,role:"menuitem"};ActionItem.__IS_ACTION_ITEM__=true;const actionType$1=wonderBlocksTokens.semanticColor.action.primary.progressive;const theme$7={actionItem:{color:{hover:{background:actionType$1.hover.background,foreground:actionType$1.hover.foreground},press:{background:actionType$1.press.background,foreground:actionType$1.press.foreground}}}};const styles$b=aphrodite.StyleSheet.create({wrapper:{minHeight:DROPDOWN_ITEM_HEIGHT,touchAction:"manipulation",":focus":{borderRadius:wonderBlocksTokens.border.radius.radius_040,outline:`${wonderBlocksTokens.spacing.xxxxSmall_2}px solid ${wonderBlocksTokens.semanticColor.focus.outer}`,outlineOffset:-wonderBlocksTokens.spacing.xxxxSmall_2},[":hover[aria-disabled=false]"]:{color:theme$7.actionItem.color.hover.foreground,background:theme$7.actionItem.color.hover.background},[":active[aria-disabled=false]"]:{color:theme$7.actionItem.color.press.foreground,background:theme$7.actionItem.color.press.background}},shared:{minHeight:DROPDOWN_ITEM_HEIGHT,paddingBlock:wonderBlocksTokens.sizing.size_100},label:{whiteSpace:"nowrap",userSelect:"none"},indent:{paddingLeft:wonderBlocksTokens.spacing.medium_16*2}});
202
64
 
203
- const Check = function Check(props) {
204
- const {
205
- selected
206
- } = props;
207
- return React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
208
- icon: checkIcon__default["default"],
209
- size: "small",
210
- style: [styles$a.bounds, !selected && styles$a.hide]
211
- });
212
- };
213
- const styles$a = aphrodite.StyleSheet.create({
214
- bounds: {
215
- alignSelf: "center",
216
- height: wonderBlocksTokens.spacing.medium_16,
217
- minHeight: wonderBlocksTokens.spacing.medium_16,
218
- minWidth: wonderBlocksTokens.spacing.medium_16
219
- },
220
- hide: {
221
- visibility: "hidden"
222
- }
223
- });
65
+ const Check=function(props){const{selected}=props;return jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{icon:checkIcon__default["default"],size:"small",style:[styles$a.bounds,!selected&&styles$a.hide]})};const styles$a=aphrodite.StyleSheet.create({bounds:{alignSelf:"center",height:wonderBlocksTokens.spacing.medium_16,minHeight:wonderBlocksTokens.spacing.medium_16,minWidth:wonderBlocksTokens.spacing.medium_16},hide:{visibility:"hidden"}});
224
66
 
225
- const Checkbox = function Checkbox(props) {
226
- const {
227
- disabled,
228
- selected
229
- } = props;
230
- return React__namespace.createElement(wonderBlocksCore.View, {
231
- className: "checkbox",
232
- style: [styles$9.checkbox, selected && !disabled && styles$9.noBorder, disabled && styles$9.disabledCheckbox]
233
- }, selected && React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
234
- icon: checkIcon__default["default"],
235
- size: "small",
236
- className: "check",
237
- style: [{
238
- width: wonderBlocksTokens.spacing.small_12,
239
- height: wonderBlocksTokens.spacing.small_12,
240
- margin: wonderBlocksTokens.spacing.xxxxSmall_2
241
- }, disabled && selected && styles$9.disabledCheckFormatting]
242
- }));
243
- };
244
- const theme$6 = {
245
- checkbox: {
246
- color: {
247
- default: {
248
- border: wonderBlocksTokens.semanticColor.border.strong
249
- },
250
- disabled: {
251
- border: wonderBlocksTokens.semanticColor.action.secondary.disabled.border,
252
- background: wonderBlocksTokens.semanticColor.action.secondary.disabled.background
253
- }
254
- }
255
- }
256
- };
257
- const styles$9 = aphrodite.StyleSheet.create({
258
- checkbox: {
259
- alignSelf: "center",
260
- minHeight: wonderBlocksTokens.spacing.medium_16,
261
- minWidth: wonderBlocksTokens.spacing.medium_16,
262
- height: wonderBlocksTokens.spacing.medium_16,
263
- borderRadius: 3,
264
- borderWidth: wonderBlocksTokens.border.width.thin,
265
- borderStyle: "solid",
266
- borderColor: theme$6.checkbox.color.default.border
267
- },
268
- noBorder: {
269
- borderWidth: 0
270
- },
271
- disabledCheckbox: {
272
- borderColor: theme$6.checkbox.color.disabled.border,
273
- backgroundColor: theme$6.checkbox.color.disabled.background
274
- },
275
- disabledCheckFormatting: {
276
- position: "absolute",
277
- top: -1,
278
- left: -1
279
- }
280
- });
67
+ const Checkbox=function(props){const{disabled,selected}=props;return jsxRuntime.jsx(wonderBlocksCore.View,{className:"checkbox",style:[styles$9.checkbox,selected&&!disabled&&styles$9.noBorder,disabled&&styles$9.disabledCheckbox],children:selected&&jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{icon:checkIcon__default["default"],size:"small",className:"check",style:[{width:wonderBlocksTokens.spacing.small_12,height:wonderBlocksTokens.spacing.small_12,margin:wonderBlocksTokens.spacing.xxxxSmall_2},disabled&&selected&&styles$9.disabledCheckFormatting]})})};const theme$6={checkbox:{color:{default:{border:wonderBlocksTokens.semanticColor.border.strong},disabled:{border:wonderBlocksTokens.semanticColor.action.secondary.disabled.border,background:wonderBlocksTokens.semanticColor.action.secondary.disabled.background}}}};const styles$9=aphrodite.StyleSheet.create({checkbox:{alignSelf:"center",minHeight:wonderBlocksTokens.spacing.medium_16,minWidth:wonderBlocksTokens.spacing.medium_16,height:wonderBlocksTokens.spacing.medium_16,borderRadius:3,borderWidth:wonderBlocksTokens.border.width.thin,borderStyle:"solid",borderColor:theme$6.checkbox.color.default.border},noBorder:{borderWidth:0},disabledCheckbox:{borderColor:theme$6.checkbox.color.disabled.border,backgroundColor:theme$6.checkbox.color.disabled.background},disabledCheckFormatting:{position:"absolute",top:-1,left:-1}});
281
68
 
282
- const _excluded$5 = ["disabled", "label", "selected", "testId", "leftAccessory", "horizontalRule", "parentComponent", "rightAccessory", "style", "subtitle1", "subtitle2", "value", "onClick", "onToggle", "variant", "role"];
283
- const StyledLi = wonderBlocksCore.addStyle("li");
284
- class OptionItem extends React__namespace.Component {
285
- constructor(...args) {
286
- super(...args);
287
- this.handleClick = () => {
288
- const {
289
- onClick,
290
- onToggle,
291
- value
292
- } = this.props;
293
- onToggle(value);
294
- if (onClick) {
295
- onClick();
296
- }
297
- };
298
- }
299
- static isClassOf(instance) {
300
- return instance && instance.type && instance.type.__IS_OPTION_ITEM__;
301
- }
302
- getCheckComponent() {
303
- if (this.props.variant === "check") {
304
- return Check;
305
- } else {
306
- return Checkbox;
307
- }
308
- }
309
- renderCell() {
310
- const _this$props = this.props,
311
- {
312
- disabled,
313
- label,
314
- selected,
315
- testId,
316
- leftAccessory,
317
- horizontalRule,
318
- parentComponent,
319
- rightAccessory,
320
- style,
321
- subtitle1,
322
- subtitle2,
323
- role
324
- } = _this$props,
325
- sharedProps = _objectWithoutPropertiesLoose__default["default"](_this$props, _excluded$5);
326
- const CheckComponent = this.getCheckComponent();
327
- const defaultStyle = [styles$8.item, style];
328
- return React__namespace.createElement(wonderBlocksCell.DetailCell, _extends__default["default"]({
329
- disabled: disabled,
330
- horizontalRule: horizontalRule,
331
- rootStyle: parentComponent === "listbox" ? styles$8.listboxItem : defaultStyle,
332
- style: styles$8.itemContainer,
333
- "aria-selected": parentComponent !== "listbox" && selected ? "true" : "false",
334
- role: parentComponent !== "listbox" ? role : undefined,
335
- testId: testId,
336
- leftAccessory: React__namespace.createElement(React__namespace.Fragment, null, leftAccessory ? React__namespace.createElement(wonderBlocksCore.View, {
337
- style: {
338
- flexDirection: "row"
339
- }
340
- }, React__namespace.createElement(CheckComponent, {
341
- disabled: disabled,
342
- selected: selected
343
- }), React__namespace.createElement(wonderBlocksLayout.Strut, {
344
- size: wonderBlocksTokens.spacing.xSmall_8
345
- }), leftAccessory) : React__namespace.createElement(CheckComponent, {
346
- disabled: disabled,
347
- selected: selected
348
- })),
349
- rightAccessory: rightAccessory,
350
- subtitle1: subtitle1 ? React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
351
- className: "subtitle"
352
- }, subtitle1) : undefined,
353
- title: React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
354
- style: styles$8.label
355
- }, label),
356
- subtitle2: subtitle2 ? React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
357
- className: "subtitle"
358
- }, subtitle2) : undefined,
359
- onClick: parentComponent !== "listbox" ? this.handleClick : undefined
360
- }, sharedProps));
361
- }
362
- render() {
363
- const {
364
- disabled,
365
- focused,
366
- parentComponent,
367
- role,
368
- selected
369
- } = this.props;
370
- if (parentComponent === "listbox") {
371
- return (React__namespace.createElement(StyledLi, {
372
- onMouseDown: e => {
373
- e.preventDefault();
374
- },
375
- onClick: this.handleClick,
376
- style: [styles$8.reset, styles$8.item, focused && styles$8.itemFocused, disabled && styles$8.itemDisabled],
377
- role: role,
378
- "aria-selected": selected ? "true" : "false",
379
- "aria-disabled": disabled ? "true" : "false",
380
- id: this.props.id,
381
- tabIndex: -1
382
- }, this.renderCell())
383
- );
384
- }
385
- return this.renderCell();
386
- }
387
- }
388
- OptionItem.defaultProps = {
389
- disabled: false,
390
- focused: false,
391
- horizontalRule: "none",
392
- onToggle: () => void 0,
393
- role: "option",
394
- selected: false
395
- };
396
- OptionItem.__IS_OPTION_ITEM__ = true;
397
- const focusedStyle = {
398
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
399
- outline: `${wonderBlocksTokens.spacing.xxxxSmall_2}px solid ${wonderBlocksTokens.semanticColor.focus.outer}`,
400
- outlineOffset: -wonderBlocksTokens.spacing.xxxxSmall_2
401
- };
402
- const actionType = wonderBlocksTokens.semanticColor.action.primary.progressive;
403
- const theme$5 = {
404
- optionItem: {
405
- color: {
406
- default: {
407
- background: wonderBlocksTokens.semanticColor.surface.primary,
408
- foreground: wonderBlocksTokens.semanticColor.text.primary
409
- },
410
- hover: {
411
- background: actionType.hover.background,
412
- foreground: actionType.hover.foreground
413
- },
414
- press: {
415
- background: actionType.press.background,
416
- foreground: actionType.press.foreground
417
- },
418
- disabled: {
419
- background: "transparent",
420
- foreground: wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground
421
- }
422
- }
423
- },
424
- checkbox: {
425
- color: {
426
- hover: {
427
- background: wonderBlocksTokens.semanticColor.surface.primary,
428
- foreground: wonderBlocksTokens.semanticColor.action.secondary.progressive.hover.foreground
429
- },
430
- press: {
431
- background: wonderBlocksTokens.semanticColor.surface.primary,
432
- foreground: wonderBlocksTokens.semanticColor.action.secondary.progressive.press.foreground
433
- },
434
- selected: {
435
- background: actionType.default.background,
436
- foreground: actionType.default.foreground
437
- }
438
- }
439
- },
440
- subtitle: {
441
- color: {
442
- default: {
443
- foreground: wonderBlocksTokens.semanticColor.text.secondary
444
- },
445
- hover: {
446
- foreground: wonderBlocksTokens.semanticColor.text.inverse
447
- },
448
- press: {
449
- foreground: wonderBlocksTokens.semanticColor.text.inverse
450
- }
451
- }
452
- }
453
- };
454
- const styles$8 = aphrodite.StyleSheet.create({
455
- reset: {
456
- margin: 0,
457
- padding: 0,
458
- border: 0,
459
- background: "none",
460
- outline: "none",
461
- fontSize: "100%",
462
- verticalAlign: "baseline",
463
- textAlign: "left",
464
- textDecoration: "none",
465
- listStyle: "none",
466
- cursor: "pointer"
467
- },
468
- listboxItem: {
469
- backgroundColor: "transparent",
470
- color: "inherit"
471
- },
472
- item: {
473
- background: theme$5.optionItem.color.default.background,
474
- color: theme$5.optionItem.color.default.foreground,
475
- minHeight: "unset",
476
- ":focus": focusedStyle,
477
- ":focus-visible": {
478
- overflow: "visible"
479
- },
480
- [":hover[aria-disabled=false]"]: {
481
- color: theme$5.optionItem.color.hover.foreground,
482
- background: theme$5.optionItem.color.hover.background
483
- },
484
- [":active[aria-selected=false]"]: {},
485
- [":hover[aria-disabled=true]"]: {
486
- cursor: "not-allowed"
487
- },
488
- [":is([aria-disabled=true])"]: {
489
- color: theme$5.optionItem.color.disabled.foreground,
490
- ":focus-visible": {
491
- outline: "none"
492
- }
493
- },
494
- [":active[aria-disabled=false]"]: {
495
- color: theme$5.optionItem.color.press.foreground,
496
- background: theme$5.optionItem.color.press.background
497
- },
498
- [":hover[aria-disabled=false] .checkbox"]: {
499
- background: theme$5.checkbox.color.hover.background
500
- },
501
- [":active[aria-disabled=false] .checkbox"]: {
502
- background: theme$5.checkbox.color.press.background
503
- },
504
- [":hover[aria-disabled=false] .check"]: {
505
- color: theme$5.checkbox.color.hover.foreground
506
- },
507
- [":active[aria-disabled=false] .check"]: {
508
- color: theme$5.checkbox.color.press.foreground
509
- },
510
- [":is([aria-selected=true]) .checkbox"]: {
511
- background: theme$5.checkbox.color.selected.background
512
- },
513
- [":is([aria-selected=true]) .check"]: {
514
- color: theme$5.checkbox.color.selected.foreground
515
- },
516
- [":is([aria-disabled=false]) .subtitle"]: {
517
- color: theme$5.subtitle.color.default.foreground
518
- },
519
- [":hover[aria-disabled=false] .subtitle"]: {
520
- color: theme$5.subtitle.color.hover.foreground
521
- },
522
- [":active[aria-disabled=false] .subtitle"]: {
523
- color: theme$5.subtitle.color.press.foreground
524
- }
525
- },
526
- itemFocused: focusedStyle,
527
- itemDisabled: {
528
- outlineColor: wonderBlocksTokens.semanticColor.focus.outer
529
- },
530
- itemContainer: {
531
- minHeight: "unset",
532
- paddingBlock: wonderBlocksTokens.spacing.xSmall_8 + wonderBlocksTokens.spacing.xxxxSmall_2,
533
- paddingInlineStart: wonderBlocksTokens.spacing.xSmall_8,
534
- paddingInlineEnd: wonderBlocksTokens.spacing.medium_16,
535
- whiteSpace: "nowrap"
536
- },
537
- label: {
538
- whiteSpace: "nowrap",
539
- userSelect: "none",
540
- overflow: "hidden",
541
- textOverflow: "ellipsis"
542
- },
543
- hide: {
544
- visibility: "hidden"
545
- }
546
- });
69
+ const StyledLi=wonderBlocksCore.addStyle("li");class OptionItem extends React__namespace.Component{static isClassOf(instance){return instance&&instance.type&&instance.type.__IS_OPTION_ITEM__}getCheckComponent(){if(this.props.variant==="check"){return Check}else {return Checkbox}}renderCell(){const{disabled,label,selected,testId,leftAccessory,horizontalRule,parentComponent,rightAccessory,style,subtitle1,subtitle2,value,onClick,onToggle,variant,role,...sharedProps}=this.props;const CheckComponent=this.getCheckComponent();const defaultStyle=[styles$8.item,style];return jsxRuntime.jsx(wonderBlocksCell.DetailCell,{disabled:disabled,horizontalRule:horizontalRule,rootStyle:parentComponent==="listbox"?styles$8.listboxItem:defaultStyle,style:styles$8.itemContainer,"aria-selected":parentComponent!=="listbox"&&selected?"true":"false",role:parentComponent!=="listbox"?role:undefined,testId:testId,leftAccessory:jsxRuntime.jsx(jsxRuntime.Fragment,{children:leftAccessory?jsxRuntime.jsxs(wonderBlocksCore.View,{style:{flexDirection:"row"},children:[jsxRuntime.jsx(CheckComponent,{disabled:disabled,selected:selected}),jsxRuntime.jsx(wonderBlocksLayout.Strut,{size:wonderBlocksTokens.spacing.xSmall_8}),leftAccessory]}):jsxRuntime.jsx(CheckComponent,{disabled:disabled,selected:selected})}),rightAccessory:rightAccessory,subtitle1:subtitle1?jsxRuntime.jsx(wonderBlocksTypography.LabelSmall,{className:"subtitle",children:subtitle1}):undefined,title:jsxRuntime.jsx(wonderBlocksTypography.LabelMedium,{style:styles$8.label,children:label}),subtitle2:subtitle2?jsxRuntime.jsx(wonderBlocksTypography.LabelSmall,{className:"subtitle",children:subtitle2}):undefined,onClick:parentComponent!=="listbox"?this.handleClick:undefined,...sharedProps})}render(){const{disabled,focused,parentComponent,role,selected}=this.props;if(parentComponent==="listbox"){return jsxRuntime.jsx(StyledLi,{onMouseDown:e=>{e.preventDefault();},onClick:this.handleClick,style:[styles$8.reset,styles$8.item,focused&&styles$8.itemFocused,disabled&&styles$8.itemDisabled],role:role,"aria-selected":selected?"true":"false","aria-disabled":disabled?"true":"false",id:this.props.id,tabIndex:-1,children:this.renderCell()})}return this.renderCell()}constructor(...args){super(...args),this.handleClick=()=>{const{onClick,onToggle,value}=this.props;onToggle(value);if(onClick){onClick();}};}}OptionItem.defaultProps={disabled:false,focused:false,horizontalRule:"none",onToggle:()=>void 0,role:"option",selected:false};OptionItem.__IS_OPTION_ITEM__=true;const focusedStyle={borderRadius:wonderBlocksTokens.border.radius.radius_040,outline:`${wonderBlocksTokens.spacing.xxxxSmall_2}px solid ${wonderBlocksTokens.semanticColor.focus.outer}`,outlineOffset:-wonderBlocksTokens.spacing.xxxxSmall_2};const actionType=wonderBlocksTokens.semanticColor.action.primary.progressive;const theme$5={optionItem:{color:{default:{background:wonderBlocksTokens.semanticColor.surface.primary,foreground:wonderBlocksTokens.semanticColor.text.primary},hover:{background:actionType.hover.background,foreground:actionType.hover.foreground},press:{background:actionType.press.background,foreground:actionType.press.foreground},disabled:{background:"transparent",foreground:wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground}}},checkbox:{color:{hover:{background:wonderBlocksTokens.semanticColor.surface.primary,foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.hover.foreground},press:{background:wonderBlocksTokens.semanticColor.surface.primary,foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.press.foreground},selected:{background:actionType.default.background,foreground:actionType.default.foreground}}},subtitle:{color:{default:{foreground:wonderBlocksTokens.semanticColor.text.secondary},hover:{foreground:wonderBlocksTokens.semanticColor.text.inverse},press:{foreground:wonderBlocksTokens.semanticColor.text.inverse}}}};const styles$8=aphrodite.StyleSheet.create({reset:{margin:0,padding:0,border:0,background:"none",outline:"none",fontSize:"100%",verticalAlign:"baseline",textAlign:"left",textDecoration:"none",listStyle:"none",cursor:"pointer"},listboxItem:{backgroundColor:"transparent",color:"inherit"},item:{background:theme$5.optionItem.color.default.background,color:theme$5.optionItem.color.default.foreground,minHeight:"unset",":focus":focusedStyle,":focus-visible":{overflow:"visible"},[":hover[aria-disabled=false]"]:{color:theme$5.optionItem.color.hover.foreground,background:theme$5.optionItem.color.hover.background},[":active[aria-selected=false]"]:{},[":hover[aria-disabled=true]"]:{cursor:"not-allowed"},[":is([aria-disabled=true])"]:{color:theme$5.optionItem.color.disabled.foreground,":focus-visible":{outline:"none"}},[":active[aria-disabled=false]"]:{color:theme$5.optionItem.color.press.foreground,background:theme$5.optionItem.color.press.background},[":hover[aria-disabled=false] .checkbox"]:{background:theme$5.checkbox.color.hover.background},[":active[aria-disabled=false] .checkbox"]:{background:theme$5.checkbox.color.press.background},[":hover[aria-disabled=false] .check"]:{color:theme$5.checkbox.color.hover.foreground},[":active[aria-disabled=false] .check"]:{color:theme$5.checkbox.color.press.foreground},[":is([aria-selected=true]) .checkbox"]:{background:theme$5.checkbox.color.selected.background},[":is([aria-selected=true]) .check"]:{color:theme$5.checkbox.color.selected.foreground},[":is([aria-disabled=false]) .subtitle"]:{color:theme$5.subtitle.color.default.foreground},[":hover[aria-disabled=false] .subtitle"]:{color:theme$5.subtitle.color.hover.foreground},[":active[aria-disabled=false] .subtitle"]:{color:theme$5.subtitle.color.press.foreground}},itemFocused:focusedStyle,itemDisabled:{outlineColor:wonderBlocksTokens.semanticColor.focus.outer},itemContainer:{minHeight:"unset",paddingBlock:wonderBlocksTokens.spacing.xSmall_8+wonderBlocksTokens.spacing.xxxxSmall_2,paddingInlineStart:wonderBlocksTokens.spacing.xSmall_8,paddingInlineEnd:wonderBlocksTokens.spacing.medium_16,whiteSpace:"nowrap"},label:{whiteSpace:"nowrap",userSelect:"none",overflow:"hidden",textOverflow:"ellipsis"},hide:{visibility:"hidden"}});
547
70
 
548
- class SeparatorItem extends React__namespace.Component {
549
- static isClassOf(instance) {
550
- return instance && instance.type && instance.type.__IS_SEPARATOR_ITEM__;
551
- }
552
- render() {
553
- return (React__namespace.createElement(wonderBlocksCore.View, {
554
- style: [styles$7.separator, this.props.style],
555
- "aria-hidden": "true"
556
- })
557
- );
558
- }
559
- }
560
- SeparatorItem.__IS_SEPARATOR_ITEM__ = true;
561
- const theme$4 = {
562
- separator: {
563
- color: {
564
- border: wonderBlocksTokens.semanticColor.border.primary
565
- }
566
- }
567
- };
568
- const styles$7 = aphrodite.StyleSheet.create({
569
- separator: {
570
- borderTop: `1px solid ${theme$4.separator.color.border}`,
571
- height: 1,
572
- minHeight: 1,
573
- marginTop: wonderBlocksTokens.spacing.xxxSmall_4,
574
- marginBottom: wonderBlocksTokens.spacing.xxxSmall_4
575
- }
576
- });
71
+ class SeparatorItem extends React__namespace.Component{static isClassOf(instance){return instance&&instance.type&&instance.type.__IS_SEPARATOR_ITEM__}render(){return jsxRuntime.jsx(wonderBlocksCore.View,{style:[styles$7.separator,this.props.style],"aria-hidden":"true"})}}SeparatorItem.__IS_SEPARATOR_ITEM__=true;const theme$4={separator:{color:{border:wonderBlocksTokens.semanticColor.border.primary}}};const styles$7=aphrodite.StyleSheet.create({separator:{borderTop:`1px solid ${theme$4.separator.color.border}`,height:1,minHeight:1,marginTop:wonderBlocksTokens.spacing.xxxSmall_4,marginBottom:wonderBlocksTokens.spacing.xxxSmall_4}});
577
72
 
578
- class DropdownOpener extends React__namespace.Component {
579
- constructor(...args) {
580
- super(...args);
581
- this.getTestIdFromProps = childrenProps => {
582
- return childrenProps.testId || childrenProps["data-testid"];
583
- };
584
- }
585
- renderAnchorChildren(eventState, clickableChildrenProps) {
586
- var _childrenProps$ariaL;
587
- const {
588
- disabled,
589
- testId,
590
- text,
591
- opened,
592
- "aria-controls": ariaControls,
593
- "aria-haspopup": ariaHasPopUp,
594
- "aria-required": ariaRequired,
595
- id,
596
- role,
597
- onBlur
598
- } = this.props;
599
- const renderedChildren = this.props.children(_extends__default["default"]({}, eventState, {
600
- text,
601
- opened
602
- }));
603
- const childrenProps = renderedChildren.props;
604
- const childrenTestId = this.getTestIdFromProps(childrenProps);
605
- const renderedAriaLabel = (_childrenProps$ariaL = childrenProps["aria-label"]) != null ? _childrenProps$ariaL : this.props["aria-label"];
606
- return React__namespace.cloneElement(renderedChildren, _extends__default["default"]({}, clickableChildrenProps, {
607
- "aria-label": renderedAriaLabel != null ? renderedAriaLabel : undefined,
608
- "aria-invalid": this.props.error,
609
- disabled,
610
- "aria-controls": ariaControls,
611
- role,
612
- id,
613
- "aria-expanded": opened ? "true" : "false",
614
- "aria-haspopup": ariaHasPopUp,
615
- "aria-required": ariaRequired,
616
- onClick: childrenProps.onClick ? e => {
617
- childrenProps.onClick(e);
618
- clickableChildrenProps.onClick(e);
619
- } : clickableChildrenProps.onClick,
620
- "data-testid": childrenTestId || testId,
621
- onBlur
622
- }));
623
- }
624
- render() {
625
- return React__namespace.createElement(wonderBlocksClickable.ClickableBehavior, {
626
- onClick: this.props.onClick,
627
- disabled: this.props.disabled,
628
- tabIndex: 0
629
- }, (eventState, handlers) => this.renderAnchorChildren(eventState, handlers));
630
- }
631
- }
632
- DropdownOpener.defaultProps = {
633
- disabled: false
634
- };
73
+ class DropdownOpener extends React__namespace.Component{renderAnchorChildren(eventState,clickableChildrenProps){const{disabled,testId,text,opened,"aria-controls":ariaControls,"aria-haspopup":ariaHasPopUp,"aria-required":ariaRequired,id,role,onBlur}=this.props;const renderedChildren=this.props.children({...eventState,text,opened});const childrenProps=renderedChildren.props;const childrenTestId=this.getTestIdFromProps(childrenProps);const renderedAriaLabel=childrenProps["aria-label"]??this.props["aria-label"];return React__namespace.cloneElement(renderedChildren,{...clickableChildrenProps,"aria-label":renderedAriaLabel??undefined,"aria-invalid":this.props.error,disabled,"aria-controls":ariaControls,role,id,"aria-expanded":opened?"true":"false","aria-haspopup":ariaHasPopUp,"aria-required":ariaRequired,onClick:childrenProps.onClick?e=>{childrenProps.onClick(e);clickableChildrenProps.onClick(e);}:clickableChildrenProps.onClick,"data-testid":childrenTestId||testId,onBlur})}render(){return jsxRuntime.jsx(wonderBlocksClickable.ClickableBehavior,{onClick:this.props.onClick,disabled:this.props.disabled,tabIndex:0,children:(eventState,handlers)=>this.renderAnchorChildren(eventState,handlers)})}constructor(...args){super(...args),this.getTestIdFromProps=childrenProps=>{return childrenProps.testId||childrenProps["data-testid"]};}}DropdownOpener.defaultProps={disabled:false};
635
74
 
636
- class DropdownVirtualizedItem extends React__namespace.Component {
637
- render() {
638
- const {
639
- data,
640
- index,
641
- style
642
- } = this.props;
643
- const item = data[index];
644
- if (SeparatorItem.isClassOf(item.component)) {
645
- return React__namespace.cloneElement(item.component, {
646
- style
647
- });
648
- } else {
649
- const {
650
- component,
651
- populatedProps,
652
- onClick,
653
- role,
654
- ref
655
- } = item;
656
- return React__namespace.cloneElement(component, _extends__default["default"]({
657
- style
658
- }, populatedProps, {
659
- key: index,
660
- onClick,
661
- ref: item.focusable && ref,
662
- role
663
- }));
664
- }
665
- }
666
- }
75
+ class DropdownVirtualizedItem extends React__namespace.Component{render(){const{data,index,style}=this.props;const item=data[index];if(SeparatorItem.isClassOf(item.component)){return React__namespace.cloneElement(item.component,{style})}else {const{component,populatedProps,onClick,role,ref}=item;return React__namespace.cloneElement(component,{style,...populatedProps,key:index,onClick,ref:item.focusable&&ref,role})}}}
667
76
 
668
- function getDropdownMenuHeight(items, initialHeight = 0) {
669
- return items.slice(0, MAX_VISIBLE_ITEMS).reduce((sum, item) => {
670
- if (SeparatorItem.isClassOf(item.component)) {
671
- return sum + SEPARATOR_ITEM_HEIGHT;
672
- } else {
673
- return sum + DROPDOWN_ITEM_HEIGHT;
674
- }
675
- }, initialHeight);
676
- }
77
+ function getDropdownMenuHeight(items,initialHeight=0){return items.slice(0,MAX_VISIBLE_ITEMS).reduce((sum,item)=>{if(SeparatorItem.isClassOf(item.component)){return sum+SEPARATOR_ITEM_HEIGHT}else {return sum+DROPDOWN_ITEM_HEIGHT}},initialHeight)}
677
78
 
678
- class DropdownCoreVirtualized extends React__namespace.Component {
679
- constructor(props) {
680
- super(props);
681
- this.getItemSize = index => {
682
- const item = this.props.data[index];
683
- if (SeparatorItem.isClassOf(item.component)) {
684
- return SEPARATOR_ITEM_HEIGHT;
685
- } else {
686
- return DROPDOWN_ITEM_HEIGHT;
687
- }
688
- };
689
- this.state = {
690
- height: getDropdownMenuHeight(props.data),
691
- width: props.width
692
- };
693
- }
694
- componentDidMount() {
695
- const {
696
- schedule
697
- } = this.props;
698
- schedule.animationFrame(() => {
699
- this.setWidth();
700
- });
701
- }
702
- componentDidUpdate(prevProps) {
703
- const {
704
- data,
705
- listRef
706
- } = this.props;
707
- if (prevProps.data.length !== data.length) {
708
- this.setHeight();
709
- if (listRef && listRef.current) {
710
- listRef.current.resetAfterIndex(1);
711
- }
712
- }
713
- }
714
- setWidth() {
715
- const rootNode = ReactDOM__namespace.findDOMNode(this);
716
- const parentNode = rootNode == null ? void 0 : rootNode.parentElement;
717
- if (parentNode) {
718
- const width = parentNode.getBoundingClientRect().width;
719
- this.setState({
720
- width
721
- });
722
- }
723
- }
724
- setHeight() {
725
- const height = getDropdownMenuHeight(this.props.data);
726
- this.setState({
727
- height
728
- });
729
- }
730
- renderInitialItems() {
731
- const {
732
- data
733
- } = this.props;
734
- const allComponents = data.map(e => e.component);
735
- const longestItems = React__namespace.Children.toArray(allComponents).filter(Boolean).sort((a, b) => {
736
- if (b.props.label && a.props.label) {
737
- return b.props.label.length - a.props.label.length;
738
- }
739
- return -1;
740
- }).slice(0, MAX_VISIBLE_ITEMS);
741
- return longestItems.map(item => React__namespace.cloneElement(item, {
742
- style: {
743
- visibility: "hidden"
744
- }
745
- }));
746
- }
747
- renderVirtualizedList(width, height) {
748
- const {
749
- data,
750
- listRef
751
- } = this.props;
752
- return React__namespace.createElement(reactWindow.VariableSizeList, {
753
- height: height,
754
- itemCount: data.length,
755
- itemSize: this.getItemSize,
756
- itemData: data,
757
- style: {
758
- overflowX: "hidden"
759
- },
760
- width: width,
761
- overscanCount: 5,
762
- ref: listRef
763
- }, DropdownVirtualizedItem);
764
- }
765
- render() {
766
- const {
767
- width,
768
- height
769
- } = this.state;
770
- if (width == null) {
771
- return this.renderInitialItems();
772
- } else {
773
- return this.renderVirtualizedList(width, height);
774
- }
775
- }
776
- }
777
- var DropdownCoreVirtualized$1 = wonderBlocksTiming.withActionScheduler(DropdownCoreVirtualized);
79
+ class DropdownCoreVirtualized extends React__namespace.Component{componentDidMount(){const{schedule}=this.props;schedule.animationFrame(()=>{this.setWidth();});}componentDidUpdate(prevProps){const{data,listRef}=this.props;if(prevProps.data.length!==data.length){this.setHeight();if(listRef&&listRef.current){listRef.current.resetAfterIndex(1);}}}setWidth(){const rootNode=ReactDOM__namespace.findDOMNode(this);const parentNode=rootNode?.parentElement;if(parentNode){const width=parentNode.getBoundingClientRect().width;this.setState({width});}}setHeight(){const height=getDropdownMenuHeight(this.props.data);this.setState({height});}renderInitialItems(){const{data}=this.props;const allComponents=data.map(e=>e.component);const longestItems=React__namespace.Children.toArray(allComponents).filter(Boolean).sort((a,b)=>{if(b.props.label&&a.props.label){return b.props.label.length-a.props.label.length}return -1}).slice(0,MAX_VISIBLE_ITEMS);return longestItems.map(item=>React__namespace.cloneElement(item,{style:{visibility:"hidden"}}))}renderVirtualizedList(width,height){const{data,listRef}=this.props;return jsxRuntime.jsx(reactWindow.VariableSizeList,{height:height,itemCount:data.length,itemSize:this.getItemSize,itemData:data,style:{overflowX:"hidden"},width:width,overscanCount:5,ref:listRef,children:DropdownVirtualizedItem})}render(){const{width,height}=this.state;if(width==null){return this.renderInitialItems()}else {return this.renderVirtualizedList(width,height)}}constructor(props){super(props),this.getItemSize=index=>{const item=this.props.data[index];if(SeparatorItem.isClassOf(item.component)){return SEPARATOR_ITEM_HEIGHT}else {return DROPDOWN_ITEM_HEIGHT}};this.state={height:getDropdownMenuHeight(props.data),width:props.width};}}var DropdownCoreVirtualized$1 = wonderBlocksTiming.withActionScheduler(DropdownCoreVirtualized);
778
80
 
779
- function modifyMaxHeight({
780
- state,
781
- options
782
- }) {
783
- const overflow = core.detectOverflow(state, options);
784
- const {
785
- y
786
- } = state.modifiersData.preventOverflow || {
787
- x: 0,
788
- y: 0
789
- };
790
- const {
791
- height
792
- } = state.rects.popper;
793
- const [basePlacement] = state.placement.split("-");
794
- const heightProp = basePlacement === "top" ? "top" : "bottom";
795
- const maxHeight = height - overflow[heightProp] - y;
796
- state.styles.popper = _extends__default["default"]({}, state.styles.popper, {
797
- maxHeight: `${maxHeight}px`,
798
- ["--popper-max-height"]: `${maxHeight}px`
799
- });
800
- }
801
- const maxHeightModifier = {
802
- name: "maxHeight",
803
- enabled: true,
804
- phase: "main",
805
- options: {
806
- padding: DROPDOWN_ITEM_HEIGHT
807
- },
808
- requiresIfExists: ["offset", "preventOverflow", "flip"],
809
- fn: modifyMaxHeight
810
- };
81
+ function modifyMaxHeight({state,options}){const overflow=core.detectOverflow(state,options);const{y}=state.modifiersData.preventOverflow||{x:0,y:0};const{height}=state.rects.popper;const[basePlacement]=state.placement.split("-");const heightProp=basePlacement==="top"?"top":"bottom";const maxHeight=height-overflow[heightProp]-y;state.styles.popper={...state.styles.popper,maxHeight:`${maxHeight}px`,["--popper-max-height"]:`${maxHeight}px`};}const maxHeightModifier={name:"maxHeight",enabled:true,phase:"main",options:{padding:DROPDOWN_ITEM_HEIGHT},requiresIfExists:["offset","preventOverflow","flip"],fn:modifyMaxHeight};
811
82
 
812
- const modifiers = [{
813
- name: "preventOverflow",
814
- options: {
815
- rootBoundary: "viewport",
816
- altAxis: true,
817
- tether: false
818
- }
819
- }, maxHeightModifier];
820
- const DropdownPopper = function DropdownPopper({
821
- children,
822
- alignment = "left",
823
- onPopperElement,
824
- referenceElement
825
- }) {
826
- const modalHost = wonderBlocksModal.maybeGetPortalMountedModalHostElement(referenceElement) || document.querySelector("body");
827
- if (!modalHost) {
828
- return null;
829
- }
830
- return ReactDOM__namespace.createPortal(React__namespace.createElement(reactPopper.Popper, {
831
- innerRef: node => {
832
- if (node && onPopperElement) {
833
- onPopperElement(node);
834
- }
835
- },
836
- referenceElement: referenceElement,
837
- strategy: "fixed",
838
- placement: alignment === "left" ? "bottom-start" : "bottom-end",
839
- modifiers: modifiers
840
- }, ({
841
- placement,
842
- ref,
843
- style,
844
- hasPopperEscaped,
845
- isReferenceHidden
846
- }) => {
847
- const shouldHidePopper = !!(hasPopperEscaped || isReferenceHidden);
848
- return React__namespace.createElement("div", {
849
- ref: ref,
850
- style: style,
851
- "data-testid": "dropdown-popper",
852
- "data-placement": placement
853
- }, children(shouldHidePopper));
854
- }), modalHost);
855
- };
83
+ const modifiers=[{name:"preventOverflow",options:{rootBoundary:"viewport",altAxis:true,tether:false}},maxHeightModifier];const DropdownPopper=function({children,alignment="left",onPopperElement,referenceElement}){const modalHost=wonderBlocksModal.maybeGetPortalMountedModalHostElement(referenceElement)||document.querySelector("body");if(!modalHost){return null}return ReactDOM__namespace.createPortal(jsxRuntime.jsx(reactPopper.Popper,{innerRef:node=>{if(node&&onPopperElement){onPopperElement(node);}},referenceElement:referenceElement,strategy:"fixed",placement:alignment==="left"?"bottom-start":"bottom-end",modifiers:modifiers,children:({placement,ref,style,hasPopperEscaped,isReferenceHidden})=>{const shouldHidePopper=!!(hasPopperEscaped||isReferenceHidden);return jsxRuntime.jsx("div",{ref:ref,style:style,"data-testid":"dropdown-popper","data-placement":placement,children:children(shouldHidePopper)})}}),modalHost)};
856
84
 
857
- function getStringForKey(key) {
858
- if (key.length === 1 || !/^[A-Z]/i.test(key)) {
859
- return key;
860
- }
861
- return "";
862
- }
863
- function debounce(callback, wait) {
864
- let timeout;
865
- return function executedFunction(...args) {
866
- const later = () => {
867
- clearTimeout(timeout);
868
- callback(...args);
869
- };
870
- clearTimeout(timeout);
871
- timeout = setTimeout(later, wait);
872
- };
873
- }
874
- function isString(x) {
875
- return typeof x === "string";
876
- }
877
- function getLabel(props) {
878
- if (isString(props.label)) {
879
- return props.label;
880
- }
881
- if (isString(props.labelAsText)) {
882
- return props.labelAsText;
883
- }
884
- return "";
885
- }
886
- function getSelectOpenerLabel(showOpenerLabelAsText, props) {
887
- if (showOpenerLabelAsText) {
888
- return getLabel(props);
889
- }
890
- return props.label;
891
- }
85
+ function getStringForKey(key){if(key.length===1||!/^[A-Z]/i.test(key)){return key}return ""}function debounce(callback,wait){let timeout;return function executedFunction(...args){const later=()=>{clearTimeout(timeout);callback(...args);};clearTimeout(timeout);timeout=setTimeout(later,wait);}}function isString(x){return typeof x==="string"}function getLabel(props){if(isString(props.label)){return props.label}if(isString(props.labelAsText)){return props.labelAsText}return ""}function getSelectOpenerLabel(showOpenerLabelAsText,props){if(showOpenerLabelAsText){return getLabel(props)}return props.label}
892
86
 
893
- const VIRTUALIZE_THRESHOLD = 125;
894
- class DropdownCore extends React__namespace.Component {
895
- static sameItemsFocusable(prevItems, currentItems) {
896
- if (prevItems.length !== currentItems.length) {
897
- return false;
898
- }
899
- for (let i = 0; i < prevItems.length; i++) {
900
- if (prevItems[i].focusable !== currentItems[i].focusable) {
901
- return false;
902
- }
903
- }
904
- return true;
905
- }
906
- static getDerivedStateFromProps(props, state) {
907
- if (state.itemRefs.length === 0 && props.open || !DropdownCore.sameItemsFocusable(state.prevItems, props.items)) {
908
- const itemRefs = [];
909
- for (let i = 0; i < props.items.length; i++) {
910
- if (props.items[i].focusable) {
911
- const ref = React__namespace.createRef();
912
- itemRefs.push({
913
- ref,
914
- originalIndex: i
915
- });
916
- }
917
- }
918
- return {
919
- itemRefs,
920
- prevItems: props.items,
921
- sameItemsFocusable: false
922
- };
923
- } else {
924
- return {
925
- prevItems: props.items,
926
- sameItemsFocusable: true
927
- };
928
- }
929
- }
930
- constructor(props) {
931
- super(props);
932
- this.popperElement = void 0;
933
- this.virtualizedListRef = void 0;
934
- this.handleKeyDownDebounced = void 0;
935
- this.textSuggestion = void 0;
936
- this.focusedIndex = -1;
937
- this.focusedOriginalIndex = -1;
938
- this.itemsClicked = false;
939
- this.searchFieldRef = React__namespace.createRef();
940
- this.handleInteract = event => {
941
- const {
942
- open,
943
- onOpenChanged
944
- } = this.props;
945
- const target = event.target;
946
- const thisElement = ReactDOM__namespace.findDOMNode(this);
947
- if (open && thisElement && !thisElement.contains(target) && this.popperElement && !this.popperElement.contains(target)) {
948
- onOpenChanged(false);
949
- }
950
- };
951
- this.handleKeyDown = event => {
952
- const {
953
- enableTypeAhead,
954
- onOpenChanged,
955
- open,
956
- searchText
957
- } = this.props;
958
- const key = event.key;
959
- if (enableTypeAhead && getStringForKey(key)) {
960
- event.stopPropagation();
961
- this.textSuggestion += key;
962
- this.handleKeyDownDebounced(this.textSuggestion);
963
- }
964
- if (!open) {
965
- if (key === wonderBlocksCore.keys.down) {
966
- event.preventDefault();
967
- onOpenChanged(true);
968
- return;
969
- }
970
- return;
971
- }
972
- switch (key) {
973
- case wonderBlocksCore.keys.tab:
974
- if (this.isSearchFieldFocused() && searchText) {
975
- return;
976
- }
977
- this.restoreTabOrder();
978
- onOpenChanged(false);
979
- return;
980
- case wonderBlocksCore.keys.space:
981
- if (this.isSearchFieldFocused()) {
982
- return;
983
- }
984
- event.preventDefault();
985
- return;
986
- case wonderBlocksCore.keys.up:
987
- event.preventDefault();
988
- this.focusPreviousItem();
989
- return;
990
- case wonderBlocksCore.keys.down:
991
- event.preventDefault();
992
- this.focusNextItem();
993
- return;
994
- }
995
- };
996
- this.handleKeyUp = event => {
997
- const {
998
- onOpenChanged,
999
- open
1000
- } = this.props;
1001
- const key = event.key;
1002
- switch (key) {
1003
- case wonderBlocksCore.keys.space:
1004
- if (this.isSearchFieldFocused()) {
1005
- return;
1006
- }
1007
- event.preventDefault();
1008
- return;
1009
- case wonderBlocksCore.keys.escape:
1010
- if (open) {
1011
- event.stopPropagation();
1012
- this.restoreTabOrder();
1013
- onOpenChanged(false);
1014
- }
1015
- return;
1016
- }
1017
- };
1018
- this.handleKeyDownDebounceResult = key => {
1019
- const foundIndex = this.props.items.filter(item => item.focusable).findIndex(({
1020
- component
1021
- }) => {
1022
- if (SeparatorItem.isClassOf(component)) {
1023
- return false;
1024
- }
1025
- if (OptionItem.isClassOf(component)) {
1026
- const optionItemProps = component.props;
1027
- return getLabel(optionItemProps).toLowerCase().startsWith(key.toLowerCase());
1028
- }
1029
- return false;
1030
- });
1031
- if (foundIndex >= 0) {
1032
- const isClosed = !this.props.open;
1033
- if (isClosed) {
1034
- this.props.onOpenChanged(true);
1035
- }
1036
- this.focusedIndex = foundIndex;
1037
- this.scheduleToFocusCurrentItem(node => {
1038
- if (this.props.selectionType === "single" && isClosed && node) {
1039
- node.click();
1040
- this.props.onOpenChanged(false);
1041
- }
1042
- });
1043
- }
1044
- this.textSuggestion = "";
1045
- };
1046
- this.handleClickFocus = index => {
1047
- this.itemsClicked = true;
1048
- this.focusedIndex = index;
1049
- this.focusedOriginalIndex = this.state.itemRefs[this.focusedIndex].originalIndex;
1050
- };
1051
- this.handleDropdownMouseUp = event => {
1052
- if (event.nativeEvent.stopImmediatePropagation) {
1053
- event.nativeEvent.stopImmediatePropagation();
1054
- } else {
1055
- event.stopPropagation();
1056
- }
1057
- };
1058
- this.handleItemClick = (focusIndex, item) => {
1059
- this.handleClickFocus(focusIndex);
1060
- if (item.component.props.onClick) {
1061
- item.component.props.onClick();
1062
- }
1063
- if (item.populatedProps.onClick) {
1064
- item.populatedProps.onClick();
1065
- }
1066
- };
1067
- this.handleSearchTextChanged = searchText => {
1068
- const {
1069
- onSearchTextChanged
1070
- } = this.props;
1071
- if (onSearchTextChanged) {
1072
- onSearchTextChanged(searchText);
1073
- }
1074
- };
1075
- this.resetFocusedIndex();
1076
- this.state = {
1077
- prevItems: this.props.items,
1078
- itemRefs: [],
1079
- sameItemsFocusable: false,
1080
- labels: _extends__default["default"]({
1081
- noResults: defaultLabels.noResults,
1082
- someResults: defaultLabels.someSelected
1083
- }, props.labels)
1084
- };
1085
- this.virtualizedListRef = React__namespace.createRef();
1086
- this.handleKeyDownDebounced = debounce(this.handleKeyDownDebounceResult, 500);
1087
- this.textSuggestion = "";
1088
- }
1089
- componentDidMount() {
1090
- this.updateEventListeners();
1091
- this.maybeFocusInitialItem();
1092
- }
1093
- componentDidUpdate(prevProps) {
1094
- const {
1095
- open,
1096
- searchText
1097
- } = this.props;
1098
- if (prevProps.open !== open) {
1099
- this.updateEventListeners();
1100
- this.maybeFocusInitialItem();
1101
- } else if (open) {
1102
- const {
1103
- itemRefs,
1104
- sameItemsFocusable
1105
- } = this.state;
1106
- if (sameItemsFocusable || prevProps.searchText !== searchText) {
1107
- return;
1108
- } else {
1109
- const newFocusableIndex = itemRefs.findIndex(ref => ref.originalIndex === this.focusedOriginalIndex);
1110
- if (newFocusableIndex === -1) {
1111
- this.focusedIndex = 0;
1112
- this.itemsClicked = false;
1113
- this.scheduleToFocusCurrentItem();
1114
- } else {
1115
- this.focusedIndex = newFocusableIndex;
1116
- }
1117
- }
1118
- if (this.props.labels !== prevProps.labels) {
1119
- this.setState({
1120
- labels: _extends__default["default"]({}, this.state.labels, this.props.labels)
1121
- });
1122
- }
1123
- }
1124
- }
1125
- componentWillUnmount() {
1126
- this.removeEventListeners();
1127
- }
1128
- resetFocusedIndex() {
1129
- const {
1130
- initialFocusedIndex
1131
- } = this.props;
1132
- if (typeof initialFocusedIndex !== "undefined") {
1133
- this.focusedIndex = initialFocusedIndex;
1134
- } else {
1135
- if (this.hasSearchField() && !this.isSearchFieldFocused()) {
1136
- return this.focusSearchField();
1137
- }
1138
- this.focusedIndex = 0;
1139
- }
1140
- }
1141
- maybeFocusInitialItem() {
1142
- const {
1143
- autoFocus,
1144
- open
1145
- } = this.props;
1146
- if (!autoFocus) {
1147
- return;
1148
- }
1149
- if (open) {
1150
- this.resetFocusedIndex();
1151
- this.scheduleToFocusCurrentItem();
1152
- } else if (!open) {
1153
- this.itemsClicked = false;
1154
- }
1155
- }
1156
- updateEventListeners() {
1157
- if (this.props.open) {
1158
- this.addEventListeners();
1159
- } else {
1160
- this.removeEventListeners();
1161
- }
1162
- }
1163
- addEventListeners() {
1164
- document.addEventListener("mouseup", this.handleInteract);
1165
- document.addEventListener("touchend", this.handleInteract);
1166
- }
1167
- removeEventListeners() {
1168
- document.removeEventListener("mouseup", this.handleInteract);
1169
- document.removeEventListener("touchend", this.handleInteract);
1170
- }
1171
- scheduleToFocusCurrentItem(onFocus) {
1172
- if (this.shouldVirtualizeList()) {
1173
- this.props.schedule.animationFrame(() => {
1174
- this.focusCurrentItem(onFocus);
1175
- });
1176
- } else {
1177
- this.focusCurrentItem(onFocus);
1178
- }
1179
- }
1180
- focusCurrentItem(onFocus) {
1181
- const focusedItemRef = this.state.itemRefs[this.focusedIndex];
1182
- if (!focusedItemRef) {
1183
- return;
1184
- }
1185
- const {
1186
- current: virtualizedList
1187
- } = this.virtualizedListRef;
1188
- if (virtualizedList) {
1189
- virtualizedList.scrollToItem(focusedItemRef.originalIndex);
1190
- }
1191
- const focusNode = () => {
1192
- if (!this.props.open) {
1193
- return;
1194
- }
1195
- const currentFocusedItemRef = this.state.itemRefs[this.focusedIndex];
1196
- const node = ReactDOM__namespace.findDOMNode(currentFocusedItemRef.ref.current);
1197
- if (!node && this.shouldVirtualizeList()) {
1198
- this.props.schedule.animationFrame(focusNode);
1199
- return;
1200
- }
1201
- if (node) {
1202
- node.focus();
1203
- this.focusedOriginalIndex = currentFocusedItemRef.originalIndex;
1204
- if (onFocus) {
1205
- onFocus(node);
1206
- }
1207
- }
1208
- };
1209
- if (this.shouldVirtualizeList()) {
1210
- this.props.schedule.animationFrame(focusNode);
1211
- } else {
1212
- focusNode();
1213
- }
1214
- }
1215
- focusSearchField() {
1216
- if (this.searchFieldRef.current) {
1217
- this.searchFieldRef.current.focus();
1218
- }
1219
- }
1220
- hasSearchField() {
1221
- return !!this.props.isFilterable;
1222
- }
1223
- isSearchFieldFocused() {
1224
- return this.hasSearchField() && document.activeElement === this.searchFieldRef.current;
1225
- }
1226
- focusPreviousItem() {
1227
- if (this.focusedIndex === 0 || this.isSearchFieldFocused() && !this.props.enableTypeAhead) {
1228
- if (this.hasSearchField() && !this.isSearchFieldFocused()) {
1229
- return this.focusSearchField();
1230
- }
1231
- this.focusedIndex = this.state.itemRefs.length - 1;
1232
- } else if (!this.isSearchFieldFocused()) {
1233
- this.focusedIndex -= 1;
1234
- }
1235
- this.scheduleToFocusCurrentItem();
1236
- }
1237
- focusNextItem() {
1238
- if (this.focusedIndex === this.state.itemRefs.length - 1 || this.isSearchFieldFocused() && !this.props.enableTypeAhead) {
1239
- if (this.hasSearchField() && !this.isSearchFieldFocused()) {
1240
- return this.focusSearchField();
1241
- }
1242
- this.focusedIndex = 0;
1243
- } else if (!this.isSearchFieldFocused()) {
1244
- this.focusedIndex += 1;
1245
- }
1246
- this.scheduleToFocusCurrentItem();
1247
- }
1248
- restoreTabOrder() {
1249
- if (this.props.openerElement) {
1250
- this.props.openerElement.focus();
1251
- }
1252
- }
1253
- getItemRole() {
1254
- const {
1255
- role
1256
- } = this.props;
1257
- switch (role) {
1258
- case "listbox":
1259
- return "option";
1260
- case "menu":
1261
- return "menuitem";
1262
- default:
1263
- throw new Error(`Expected "listbox" or "menu" for role, but receieved "${role}" instead.`);
1264
- }
1265
- }
1266
- maybeRenderNoResults() {
1267
- const {
1268
- items,
1269
- labels: {
1270
- noResults
1271
- }
1272
- } = this.props;
1273
- const numResults = items.length;
1274
- if (numResults === 0) {
1275
- return React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
1276
- style: styles$6.noResult,
1277
- testId: "dropdown-core-no-results"
1278
- }, noResults);
1279
- }
1280
- return null;
1281
- }
1282
- shouldVirtualizeList() {
1283
- return this.props.items.length > VIRTUALIZE_THRESHOLD;
1284
- }
1285
- renderList() {
1286
- let focusCounter = 0;
1287
- const itemRole = this.getItemRole();
1288
- return this.props.items.map((item, index) => {
1289
- if (SeparatorItem.isClassOf(item.component)) {
1290
- return item.component;
1291
- }
1292
- const {
1293
- component,
1294
- focusable,
1295
- populatedProps
1296
- } = item;
1297
- if (focusable) {
1298
- focusCounter += 1;
1299
- }
1300
- const focusIndex = focusCounter - 1;
1301
- const currentRef = this.state.itemRefs[focusIndex] ? this.state.itemRefs[focusIndex].ref : null;
1302
- return React__namespace.cloneElement(component, _extends__default["default"]({}, populatedProps, {
1303
- key: index,
1304
- onClick: () => {
1305
- this.handleItemClick(focusIndex, item);
1306
- },
1307
- ref: focusable ? currentRef : null,
1308
- role: populatedProps.role || itemRole
1309
- }));
1310
- });
1311
- }
1312
- parseVirtualizedItems() {
1313
- let focusCounter = 0;
1314
- const itemRole = this.getItemRole();
1315
- return this.props.items.map((item, index) => {
1316
- const {
1317
- populatedProps
1318
- } = item;
1319
- if (!SeparatorItem.isClassOf(item.component) && item.focusable) {
1320
- focusCounter += 1;
1321
- }
1322
- const focusIndex = focusCounter - 1;
1323
- return _extends__default["default"]({}, item, {
1324
- role: populatedProps.role || itemRole,
1325
- ref: item.focusable && this.state.itemRefs[focusIndex] ? this.state.itemRefs[focusIndex].ref : null,
1326
- onClick: () => {
1327
- this.handleItemClick(focusIndex, item);
1328
- }
1329
- });
1330
- });
1331
- }
1332
- renderVirtualizedList() {
1333
- const virtualizedItems = this.parseVirtualizedItems();
1334
- return React__namespace.createElement(DropdownCoreVirtualized$1, {
1335
- data: virtualizedItems,
1336
- listRef: this.virtualizedListRef
1337
- });
1338
- }
1339
- renderSearchField() {
1340
- const {
1341
- searchText
1342
- } = this.props;
1343
- const {
1344
- labels
1345
- } = this.state;
1346
- return React__namespace.createElement(SearchField__default["default"], {
1347
- clearAriaLabel: labels.clearSearch,
1348
- onChange: this.handleSearchTextChanged,
1349
- placeholder: labels.filter,
1350
- ref: this.searchFieldRef,
1351
- style: styles$6.searchInputStyle,
1352
- value: searchText || ""
1353
- });
1354
- }
1355
- renderDropdownMenu(listRenderer, isReferenceHidden) {
1356
- const {
1357
- "aria-invalid": ariaInvalid,
1358
- "aria-required": ariaRequired,
1359
- dropdownStyle,
1360
- isFilterable,
1361
- openerElement,
1362
- role,
1363
- id
1364
- } = this.props;
1365
- const openerStyle = openerElement && window.getComputedStyle(openerElement);
1366
- const minDropdownWidth = openerStyle ? openerStyle.getPropertyValue("width") : 0;
1367
- return React__namespace.createElement(wonderBlocksCore.View, {
1368
- onMouseUp: this.handleDropdownMouseUp,
1369
- style: [styles$6.dropdown, isReferenceHidden && styles$6.hidden, dropdownStyle],
1370
- testId: "dropdown-core-container"
1371
- }, isFilterable && this.renderSearchField(), React__namespace.createElement(wonderBlocksCore.View, {
1372
- id: id,
1373
- role: role,
1374
- style: [styles$6.listboxOrMenu, {
1375
- minWidth: minDropdownWidth
1376
- }],
1377
- "aria-invalid": role === "listbox" ? ariaInvalid : undefined,
1378
- "aria-required": role === "listbox" ? ariaRequired : undefined
1379
- }, listRenderer), this.maybeRenderNoResults());
1380
- }
1381
- renderDropdown() {
1382
- const {
1383
- alignment,
1384
- openerElement
1385
- } = this.props;
1386
- const listRenderer = this.shouldVirtualizeList() ? this.renderVirtualizedList() : this.renderList();
1387
- return React__namespace.createElement(DropdownPopper, {
1388
- alignment: alignment,
1389
- onPopperElement: popperElement => {
1390
- this.popperElement = popperElement;
1391
- },
1392
- referenceElement: openerElement
1393
- }, isReferenceHidden => this.renderDropdownMenu(listRenderer, isReferenceHidden));
1394
- }
1395
- render() {
1396
- const {
1397
- open,
1398
- opener,
1399
- style,
1400
- className,
1401
- disabled
1402
- } = this.props;
1403
- return React__namespace.createElement(wonderBlocksCore.View, {
1404
- onKeyDown: !disabled ? this.handleKeyDown : undefined,
1405
- onKeyUp: !disabled ? this.handleKeyUp : undefined,
1406
- style: [styles$6.menuWrapper, style],
1407
- className: className
1408
- }, opener, open && this.renderDropdown());
1409
- }
1410
- }
1411
- DropdownCore.defaultProps = {
1412
- alignment: "left",
1413
- autoFocus: true,
1414
- enableTypeAhead: true,
1415
- labels: {
1416
- clearSearch: defaultLabels.clearSearch,
1417
- filter: defaultLabels.filter,
1418
- noResults: defaultLabels.noResults,
1419
- someResults: defaultLabels.someSelected
1420
- },
1421
- selectionType: "single"
1422
- };
1423
- const theme$3 = {
1424
- dropdown: {
1425
- color: {
1426
- default: {
1427
- background: wonderBlocksTokens.semanticColor.surface.primary,
1428
- border: wonderBlocksTokens.semanticColor.border.primary
1429
- }
1430
- }
1431
- },
1432
- noResults: {
1433
- color: {
1434
- foreground: wonderBlocksTokens.semanticColor.text.secondary
1435
- }
1436
- }
1437
- };
1438
- const styles$6 = aphrodite.StyleSheet.create({
1439
- menuWrapper: {
1440
- width: "fit-content"
1441
- },
1442
- dropdown: {
1443
- backgroundColor: theme$3.dropdown.color.default.background,
1444
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
1445
- paddingTop: wonderBlocksTokens.spacing.xxxSmall_4,
1446
- paddingBottom: wonderBlocksTokens.spacing.xxxSmall_4,
1447
- border: `solid 1px ${theme$3.dropdown.color.default.border}`,
1448
- boxShadow: `0px 8px 8px 0px ${wonderBlocksTokens.color.offBlack8}`,
1449
- maxHeight: "var(--popper-max-height)"
1450
- },
1451
- listboxOrMenu: {
1452
- overflowY: "auto"
1453
- },
1454
- hidden: {
1455
- pointerEvents: "none",
1456
- visibility: "hidden"
1457
- },
1458
- noResult: {
1459
- color: theme$3.noResults.color.foreground,
1460
- alignSelf: "center",
1461
- marginTop: wonderBlocksTokens.spacing.xxSmall_6
1462
- },
1463
- searchInputStyle: {
1464
- margin: wonderBlocksTokens.spacing.xSmall_8,
1465
- marginTop: wonderBlocksTokens.spacing.xxxSmall_4,
1466
- minHeight: "auto",
1467
- position: "sticky"
1468
- },
1469
- srOnly: {
1470
- border: 0,
1471
- clip: "rect(0,0,0,0)",
1472
- height: 1,
1473
- margin: -1,
1474
- overflow: "hidden",
1475
- padding: 0,
1476
- position: "absolute",
1477
- width: 1
1478
- }
1479
- });
1480
- var DropdownCore$1 = wonderBlocksTiming.withActionScheduler(DropdownCore);
87
+ const VIRTUALIZE_THRESHOLD=125;class DropdownCore extends React__namespace.Component{static sameItemsFocusable(prevItems,currentItems){if(prevItems.length!==currentItems.length){return false}for(let i=0;i<prevItems.length;i++){if(prevItems[i].focusable!==currentItems[i].focusable){return false}}return true}static getDerivedStateFromProps(props,state){if(state.itemRefs.length===0&&props.open||!DropdownCore.sameItemsFocusable(state.prevItems,props.items)){const itemRefs=[];for(let i=0;i<props.items.length;i++){if(props.items[i].focusable){const ref=React__namespace.createRef();itemRefs.push({ref,originalIndex:i});}}return {itemRefs,prevItems:props.items,sameItemsFocusable:false}}else {return {prevItems:props.items,sameItemsFocusable:true}}}componentDidMount(){this.updateEventListeners();this.maybeFocusInitialItem();}componentDidUpdate(prevProps){const{open,searchText}=this.props;if(prevProps.open!==open){this.updateEventListeners();this.maybeFocusInitialItem();}else if(open){const{itemRefs,sameItemsFocusable}=this.state;if(sameItemsFocusable||prevProps.searchText!==searchText){return}else {const newFocusableIndex=itemRefs.findIndex(ref=>ref.originalIndex===this.focusedOriginalIndex);if(newFocusableIndex===-1){this.focusedIndex=0;this.itemsClicked=false;this.scheduleToFocusCurrentItem();}else {this.focusedIndex=newFocusableIndex;}}if(this.props.labels!==prevProps.labels){this.setState({labels:{...this.state.labels,...this.props.labels}});}}}componentWillUnmount(){this.removeEventListeners();}resetFocusedIndex(){const{initialFocusedIndex}=this.props;if(typeof initialFocusedIndex!=="undefined"){this.focusedIndex=initialFocusedIndex;}else {if(this.hasSearchField()&&!this.isSearchFieldFocused()){return this.focusSearchField()}this.focusedIndex=0;}}maybeFocusInitialItem(){const{autoFocus,open}=this.props;if(!autoFocus){return}if(open){this.resetFocusedIndex();this.scheduleToFocusCurrentItem();}else if(!open){this.itemsClicked=false;}}updateEventListeners(){if(this.props.open){this.addEventListeners();}else {this.removeEventListeners();}}addEventListeners(){document.addEventListener("mouseup",this.handleInteract);document.addEventListener("touchend",this.handleInteract);}removeEventListeners(){document.removeEventListener("mouseup",this.handleInteract);document.removeEventListener("touchend",this.handleInteract);}scheduleToFocusCurrentItem(onFocus){if(this.shouldVirtualizeList()){this.props.schedule.animationFrame(()=>{this.focusCurrentItem(onFocus);});}else {this.focusCurrentItem(onFocus);}}focusCurrentItem(onFocus){const focusedItemRef=this.state.itemRefs[this.focusedIndex];if(!focusedItemRef){return}const{current:virtualizedList}=this.virtualizedListRef;if(virtualizedList){virtualizedList.scrollToItem(focusedItemRef.originalIndex);}const focusNode=()=>{if(!this.props.open){return}const currentFocusedItemRef=this.state.itemRefs[this.focusedIndex];const node=ReactDOM__namespace.findDOMNode(currentFocusedItemRef.ref.current);if(!node&&this.shouldVirtualizeList()){this.props.schedule.animationFrame(focusNode);return}if(node){node.focus();this.focusedOriginalIndex=currentFocusedItemRef.originalIndex;if(onFocus){onFocus(node);}}};if(this.shouldVirtualizeList()){this.props.schedule.animationFrame(focusNode);}else {focusNode();}}focusSearchField(){if(this.searchFieldRef.current){this.searchFieldRef.current.focus();}}hasSearchField(){return !!this.props.isFilterable}isSearchFieldFocused(){return this.hasSearchField()&&document.activeElement===this.searchFieldRef.current}focusPreviousItem(){if(this.focusedIndex===0||this.isSearchFieldFocused()&&!this.props.enableTypeAhead){if(this.hasSearchField()&&!this.isSearchFieldFocused()){return this.focusSearchField()}this.focusedIndex=this.state.itemRefs.length-1;}else if(!this.isSearchFieldFocused()){this.focusedIndex-=1;}this.scheduleToFocusCurrentItem();}focusNextItem(){if(this.focusedIndex===this.state.itemRefs.length-1||this.isSearchFieldFocused()&&!this.props.enableTypeAhead){if(this.hasSearchField()&&!this.isSearchFieldFocused()){return this.focusSearchField()}this.focusedIndex=0;}else if(!this.isSearchFieldFocused()){this.focusedIndex+=1;}this.scheduleToFocusCurrentItem();}restoreTabOrder(){if(this.props.openerElement){this.props.openerElement.focus();}}getItemRole(){const{role}=this.props;switch(role){case"listbox":return "option";case"menu":return "menuitem";default:throw new Error(`Expected "listbox" or "menu" for role, but receieved "${role}" instead.`)}}maybeRenderNoResults(){const{items,labels:{noResults}}=this.props;const numResults=items.length;if(numResults===0){return jsxRuntime.jsx(wonderBlocksTypography.LabelMedium,{style:styles$6.noResult,testId:"dropdown-core-no-results",children:noResults})}return null}shouldVirtualizeList(){return this.props.items.length>VIRTUALIZE_THRESHOLD}renderList(){let focusCounter=0;const itemRole=this.getItemRole();return this.props.items.map((item,index)=>{if(SeparatorItem.isClassOf(item.component)){return item.component}const{component,focusable,populatedProps}=item;if(focusable){focusCounter+=1;}const focusIndex=focusCounter-1;const currentRef=this.state.itemRefs[focusIndex]?this.state.itemRefs[focusIndex].ref:null;return React__namespace.cloneElement(component,{...populatedProps,key:index,onClick:()=>{this.handleItemClick(focusIndex,item);},ref:focusable?currentRef:null,role:populatedProps.role||itemRole})})}parseVirtualizedItems(){let focusCounter=0;const itemRole=this.getItemRole();return this.props.items.map((item,index)=>{const{populatedProps}=item;if(!SeparatorItem.isClassOf(item.component)&&item.focusable){focusCounter+=1;}const focusIndex=focusCounter-1;return {...item,role:populatedProps.role||itemRole,ref:item.focusable&&this.state.itemRefs[focusIndex]?this.state.itemRefs[focusIndex].ref:null,onClick:()=>{this.handleItemClick(focusIndex,item);}}})}renderVirtualizedList(){const virtualizedItems=this.parseVirtualizedItems();return jsxRuntime.jsx(DropdownCoreVirtualized$1,{data:virtualizedItems,listRef:this.virtualizedListRef})}renderSearchField(){const{searchText}=this.props;const{labels}=this.state;return jsxRuntime.jsx(SearchField__default["default"],{clearAriaLabel:labels.clearSearch,onChange:this.handleSearchTextChanged,placeholder:labels.filter,ref:this.searchFieldRef,style:styles$6.searchInputStyle,value:searchText||""})}renderDropdownMenu(listRenderer,isReferenceHidden){const{"aria-invalid":ariaInvalid,"aria-required":ariaRequired,dropdownStyle,isFilterable,openerElement,role,id}=this.props;const openerStyle=openerElement&&window.getComputedStyle(openerElement);const minDropdownWidth=openerStyle?openerStyle.getPropertyValue("width"):0;return jsxRuntime.jsxs(wonderBlocksCore.View,{onMouseUp:this.handleDropdownMouseUp,style:[styles$6.dropdown,isReferenceHidden&&styles$6.hidden,dropdownStyle],testId:"dropdown-core-container",children:[isFilterable&&this.renderSearchField(),jsxRuntime.jsx(wonderBlocksCore.View,{id:id,role:role,style:[styles$6.listboxOrMenu,{minWidth:minDropdownWidth}],"aria-invalid":role==="listbox"?ariaInvalid:undefined,"aria-required":role==="listbox"?ariaRequired:undefined,children:listRenderer}),this.maybeRenderNoResults()]})}renderDropdown(){const{alignment,openerElement}=this.props;const listRenderer=this.shouldVirtualizeList()?this.renderVirtualizedList():this.renderList();return jsxRuntime.jsx(DropdownPopper,{alignment:alignment,onPopperElement:popperElement=>{this.popperElement=popperElement;},referenceElement:openerElement,children:isReferenceHidden=>this.renderDropdownMenu(listRenderer,isReferenceHidden)})}render(){const{open,opener,style,className,disabled}=this.props;return jsxRuntime.jsxs(wonderBlocksCore.View,{onKeyDown:!disabled?this.handleKeyDown:undefined,onKeyUp:!disabled?this.handleKeyUp:undefined,style:[styles$6.menuWrapper,style],className:className,children:[opener,open&&this.renderDropdown()]})}constructor(props){super(props),this.focusedIndex=-1,this.focusedOriginalIndex=-1,this.itemsClicked=false,this.searchFieldRef=React__namespace.createRef(),this.handleInteract=event=>{const{open,onOpenChanged}=this.props;const target=event.target;const thisElement=ReactDOM__namespace.findDOMNode(this);if(open&&thisElement&&!thisElement.contains(target)&&this.popperElement&&!this.popperElement.contains(target)){onOpenChanged(false);}},this.handleKeyDown=event=>{const{enableTypeAhead,onOpenChanged,open,searchText}=this.props;const key=event.key;if(enableTypeAhead&&getStringForKey(key)){event.stopPropagation();this.textSuggestion+=key;this.handleKeyDownDebounced(this.textSuggestion);}if(!open){if(key===wonderBlocksCore.keys.down){event.preventDefault();onOpenChanged(true);return}return}switch(key){case wonderBlocksCore.keys.tab:if(this.isSearchFieldFocused()&&searchText){return}this.restoreTabOrder();onOpenChanged(false);return;case wonderBlocksCore.keys.space:if(this.isSearchFieldFocused()){return}event.preventDefault();return;case wonderBlocksCore.keys.up:event.preventDefault();this.focusPreviousItem();return;case wonderBlocksCore.keys.down:event.preventDefault();this.focusNextItem();return}},this.handleKeyUp=event=>{const{onOpenChanged,open}=this.props;const key=event.key;switch(key){case wonderBlocksCore.keys.space:if(this.isSearchFieldFocused()){return}event.preventDefault();return;case wonderBlocksCore.keys.escape:if(open){event.stopPropagation();this.restoreTabOrder();onOpenChanged(false);}return}},this.handleKeyDownDebounceResult=key=>{const foundIndex=this.props.items.filter(item=>item.focusable).findIndex(({component})=>{if(SeparatorItem.isClassOf(component)){return false}if(OptionItem.isClassOf(component)){const optionItemProps=component.props;return getLabel(optionItemProps).toLowerCase().startsWith(key.toLowerCase())}return false});if(foundIndex>=0){const isClosed=!this.props.open;if(isClosed){this.props.onOpenChanged(true);}this.focusedIndex=foundIndex;this.scheduleToFocusCurrentItem(node=>{if(this.props.selectionType==="single"&&isClosed&&node){node.click();this.props.onOpenChanged(false);}});}this.textSuggestion="";},this.handleClickFocus=index=>{this.itemsClicked=true;this.focusedIndex=index;this.focusedOriginalIndex=this.state.itemRefs[this.focusedIndex].originalIndex;},this.handleDropdownMouseUp=event=>{if(event.nativeEvent.stopImmediatePropagation){event.nativeEvent.stopImmediatePropagation();}else {event.stopPropagation();}},this.handleItemClick=(focusIndex,item)=>{this.handleClickFocus(focusIndex);if(item.component.props.onClick){item.component.props.onClick();}if(item.populatedProps.onClick){item.populatedProps.onClick();}},this.handleSearchTextChanged=searchText=>{const{onSearchTextChanged}=this.props;if(onSearchTextChanged){onSearchTextChanged(searchText);}};this.resetFocusedIndex();this.state={prevItems:this.props.items,itemRefs:[],sameItemsFocusable:false,labels:{noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected,...props.labels}};this.virtualizedListRef=React__namespace.createRef();this.handleKeyDownDebounced=debounce(this.handleKeyDownDebounceResult,500);this.textSuggestion="";}}DropdownCore.defaultProps={alignment:"left",autoFocus:true,enableTypeAhead:true,labels:{clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected},selectionType:"single"};const theme$3={dropdown:{color:{default:{background:wonderBlocksTokens.semanticColor.surface.primary,border:wonderBlocksTokens.semanticColor.border.primary}}},noResults:{color:{foreground:wonderBlocksTokens.semanticColor.text.secondary}}};const styles$6=aphrodite.StyleSheet.create({menuWrapper:{width:"fit-content"},dropdown:{backgroundColor:theme$3.dropdown.color.default.background,borderRadius:wonderBlocksTokens.border.radius.radius_040,paddingTop:wonderBlocksTokens.spacing.xxxSmall_4,paddingBottom:wonderBlocksTokens.spacing.xxxSmall_4,border:`solid 1px ${theme$3.dropdown.color.default.border}`,boxShadow:`0px 8px 8px 0px ${wonderBlocksTokens.color.offBlack8}`,maxHeight:"var(--popper-max-height)"},listboxOrMenu:{overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},noResult:{color:theme$3.noResults.color.foreground,alignSelf:"center",marginTop:wonderBlocksTokens.spacing.xxSmall_6},searchInputStyle:{margin:wonderBlocksTokens.spacing.xSmall_8,marginTop:wonderBlocksTokens.spacing.xxxSmall_4,minHeight:"auto",position:"sticky"},srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});var DropdownCore$1 = wonderBlocksTiming.withActionScheduler(DropdownCore);
1481
88
 
1482
- const _excluded$4 = ["children", "disabled", "focused", "hovered", "pressed", "waiting", "testId", "opened", "aria-label"];
1483
- const StyledButton$1 = wonderBlocksCore.addStyle("button");
1484
- class ActionMenuOpenerCore extends React__namespace.Component {
1485
- render() {
1486
- const _this$props = this.props,
1487
- {
1488
- children,
1489
- disabled: disabledProp,
1490
- focused,
1491
- hovered,
1492
- pressed,
1493
- testId,
1494
- opened,
1495
- "aria-label": ariaLabel
1496
- } = _this$props,
1497
- restProps = _objectWithoutPropertiesLoose__default["default"](_this$props, _excluded$4);
1498
- const disabled = disabledProp;
1499
- const defaultStyle = [sharedStyles.shared, sharedStyles.default, disabled && sharedStyles.disabled, !disabled && pressed && sharedStyles.press];
1500
- const label = React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
1501
- style: sharedStyles.text
1502
- }, children);
1503
- return React__namespace.createElement(StyledButton$1, _extends__default["default"]({
1504
- "aria-expanded": opened ? "true" : "false",
1505
- "aria-haspopup": "menu",
1506
- "aria-label": ariaLabel,
1507
- disabled: disabled,
1508
- style: defaultStyle,
1509
- type: "button"
1510
- }, restProps, {
1511
- "data-testid": testId
1512
- }), React__namespace.createElement(wonderBlocksCore.View, {
1513
- style: !disabled && (hovered || focused) && sharedStyles.focus
1514
- }, label), React__namespace.createElement(wonderBlocksLayout.Strut, {
1515
- size: wonderBlocksTokens.spacing.xxxSmall_4
1516
- }), React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
1517
- size: "small",
1518
- color: "currentColor",
1519
- icon: caretDownIcon__default["default"],
1520
- "aria-hidden": "true"
1521
- }));
1522
- }
1523
- }
1524
- const theme$2 = {
1525
- actionMenuOpener: {
1526
- color: {
1527
- default: {
1528
- background: "none",
1529
- foreground: wonderBlocksTokens.semanticColor.action.secondary.progressive.default.foreground
1530
- },
1531
- disabled: {
1532
- foreground: wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground
1533
- },
1534
- press: {
1535
- foreground: wonderBlocksTokens.semanticColor.action.secondary.progressive.press.foreground
1536
- }
1537
- }
1538
- }
1539
- };
1540
- const sharedStyles = aphrodite.StyleSheet.create({
1541
- shared: {
1542
- position: "relative",
1543
- display: "inline-flex",
1544
- alignItems: "center",
1545
- justifyContent: "center",
1546
- height: DROPDOWN_ITEM_HEIGHT,
1547
- border: "none",
1548
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
1549
- cursor: "pointer",
1550
- outline: "none",
1551
- textDecoration: "none",
1552
- boxSizing: "border-box",
1553
- touchAction: "manipulation",
1554
- ":focus": {
1555
- WebkitTapHighlightColor: "rgba(0,0,0,0)"
1556
- }
1557
- },
1558
- default: {
1559
- background: theme$2.actionMenuOpener.color.default.background,
1560
- color: theme$2.actionMenuOpener.color.default.foreground
1561
- },
1562
- disabled: {
1563
- color: theme$2.actionMenuOpener.color.disabled.foreground,
1564
- cursor: "not-allowed"
1565
- },
1566
- small: {
1567
- height: wonderBlocksTokens.spacing.xLarge_32
1568
- },
1569
- text: {
1570
- textAlign: "left",
1571
- display: "inline-block",
1572
- alignItems: "center",
1573
- fontWeight: "bold",
1574
- userSelect: "none",
1575
- whiteSpace: "nowrap",
1576
- overflow: "hidden",
1577
- textOverflow: "ellipsis",
1578
- pointerEvents: "none"
1579
- },
1580
- focus: {
1581
- ":after": {
1582
- content: "''",
1583
- position: "absolute",
1584
- height: 2,
1585
- left: 0,
1586
- right: 0,
1587
- bottom: -1,
1588
- background: "currentColor"
1589
- }
1590
- },
1591
- press: {
1592
- color: theme$2.actionMenuOpener.color.press.foreground
1593
- }
1594
- });
89
+ const StyledButton$1=wonderBlocksCore.addStyle("button");class ActionMenuOpenerCore extends React__namespace.Component{render(){const{children,disabled:disabledProp,focused,hovered,pressed,waiting:_,testId,opened,"aria-label":ariaLabel,...restProps}=this.props;const disabled=disabledProp;const defaultStyle=[sharedStyles.shared,sharedStyles.default,disabled&&sharedStyles.disabled,!disabled&&pressed&&sharedStyles.press];const label=jsxRuntime.jsx(wonderBlocksTypography.LabelLarge,{style:sharedStyles.text,children:children});return jsxRuntime.jsxs(StyledButton$1,{"aria-expanded":opened?"true":"false","aria-haspopup":"menu","aria-label":ariaLabel,disabled:disabled,style:defaultStyle,type:"button",...restProps,"data-testid":testId,children:[jsxRuntime.jsx(wonderBlocksCore.View,{style:!disabled&&(hovered||focused)&&sharedStyles.focus,children:label}),jsxRuntime.jsx(wonderBlocksLayout.Strut,{size:wonderBlocksTokens.spacing.xxxSmall_4}),jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{size:"small",color:"currentColor",icon:caretDownIcon__default["default"],"aria-hidden":"true"})]})}}const theme$2={actionMenuOpener:{color:{default:{background:"none",foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.default.foreground},disabled:{foreground:wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground},press:{foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.press.foreground}}}};const sharedStyles=aphrodite.StyleSheet.create({shared:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",height:DROPDOWN_ITEM_HEIGHT,border:"none",borderRadius:wonderBlocksTokens.border.radius.radius_040,cursor:"pointer",outline:"none",textDecoration:"none",boxSizing:"border-box",touchAction:"manipulation",":focus":{WebkitTapHighlightColor:"rgba(0,0,0,0)"}},default:{background:theme$2.actionMenuOpener.color.default.background,color:theme$2.actionMenuOpener.color.default.foreground},disabled:{color:theme$2.actionMenuOpener.color.disabled.foreground,cursor:"not-allowed"},small:{height:wonderBlocksTokens.spacing.xLarge_32},text:{textAlign:"left",display:"inline-block",alignItems:"center",fontWeight:"bold",userSelect:"none",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",pointerEvents:"none"},focus:{":after":{content:"''",position:"absolute",height:2,left:0,right:0,bottom:-1,background:"currentColor"}},press:{color:theme$2.actionMenuOpener.color.press.foreground}});
1595
90
 
1596
- const _excluded$3 = ["text", "opened"];
1597
- class ActionMenu extends React__namespace.Component {
1598
- constructor(...args) {
1599
- super(...args);
1600
- this.openerElement = void 0;
1601
- this.state = {
1602
- opened: false
1603
- };
1604
- this.handleItemSelected = () => {
1605
- this.handleOpenChanged(false);
1606
- if (this.openerElement) {
1607
- this.openerElement.focus();
1608
- }
1609
- };
1610
- this.handleOpenChanged = opened => {
1611
- this.setState({
1612
- opened
1613
- });
1614
- if (this.props.onToggle) {
1615
- this.props.onToggle(opened);
1616
- }
1617
- };
1618
- this.handleOptionSelected = selectedValue => {
1619
- const {
1620
- onChange,
1621
- selectedValues
1622
- } = this.props;
1623
- if (!onChange || !selectedValues) {
1624
- return;
1625
- }
1626
- if (selectedValues.includes(selectedValue)) {
1627
- const index = selectedValues.indexOf(selectedValue);
1628
- const updatedSelection = [...selectedValues.slice(0, index), ...selectedValues.slice(index + 1)];
1629
- onChange(updatedSelection);
1630
- } else {
1631
- onChange([...selectedValues, selectedValue]);
1632
- }
1633
- this.handleItemSelected();
1634
- };
1635
- this.handleOpenerRef = node => {
1636
- this.openerElement = ReactDOM__namespace.findDOMNode(node);
1637
- };
1638
- this.handleClick = e => {
1639
- this.handleOpenChanged(!this.state.opened);
1640
- };
1641
- }
1642
- static getDerivedStateFromProps(props, state) {
1643
- return {
1644
- opened: typeof props.opened === "boolean" ? props.opened : state.opened
1645
- };
1646
- }
1647
- getMenuItems() {
1648
- const {
1649
- children,
1650
- selectedValues
1651
- } = this.props;
1652
- const allChildren = React__namespace.Children.toArray(children).filter(Boolean);
1653
- const isOptionItemIncluded = allChildren.some(item => OptionItem.isClassOf(item));
1654
- return allChildren.map(item => {
1655
- const {
1656
- value,
1657
- disabled
1658
- } = item.props;
1659
- const itemObject = {
1660
- component: item,
1661
- focusable: ActionItem.isClassOf(item) || OptionItem.isClassOf(item) ? !disabled : false,
1662
- populatedProps: {}
1663
- };
1664
- if (ActionItem.isClassOf(item)) {
1665
- return _extends__default["default"]({}, itemObject, {
1666
- populatedProps: {
1667
- indent: isOptionItemIncluded,
1668
- onClick: this.handleItemSelected
1669
- }
1670
- });
1671
- } else if (OptionItem.isClassOf(item)) {
1672
- const selected = selectedValues ? selectedValues.includes(value) : false;
1673
- return _extends__default["default"]({}, itemObject, {
1674
- populatedProps: {
1675
- onToggle: this.handleOptionSelected,
1676
- selected,
1677
- variant: "check",
1678
- role: "menuitemcheckbox",
1679
- "aria-checked": selected,
1680
- "aria-selected": undefined
1681
- }
1682
- });
1683
- } else {
1684
- return itemObject;
1685
- }
1686
- });
1687
- }
1688
- renderOpener(numItems, dropdownId) {
1689
- const {
1690
- disabled,
1691
- menuText,
1692
- opener,
1693
- testId,
1694
- id
1695
- } = this.props;
1696
- return React__namespace.createElement(wonderBlocksCore.Id, {
1697
- id: id
1698
- }, uniqueOpenerId => React__namespace.createElement(DropdownOpener, {
1699
- id: uniqueOpenerId,
1700
- "aria-controls": dropdownId,
1701
- "aria-haspopup": "menu",
1702
- onClick: this.handleClick,
1703
- disabled: numItems === 0 || disabled,
1704
- text: menuText,
1705
- ref: this.handleOpenerRef,
1706
- testId: opener ? undefined : testId,
1707
- opened: this.state.opened,
1708
- role: "button"
1709
- }, opener ? opener : openerProps => {
1710
- const {
1711
- opened
1712
- } = openerProps,
1713
- eventState = _objectWithoutPropertiesLoose__default["default"](openerProps, _excluded$3);
1714
- return React__namespace.createElement(ActionMenuOpenerCore, _extends__default["default"]({}, eventState, {
1715
- disabled: disabled,
1716
- opened: !!opened,
1717
- testId: testId
1718
- }), menuText);
1719
- }));
1720
- }
1721
- render() {
1722
- const {
1723
- alignment,
1724
- dropdownStyle,
1725
- style,
1726
- className,
1727
- dropdownId
1728
- } = this.props;
1729
- const items = this.getMenuItems();
1730
- return React__namespace.createElement(wonderBlocksCore.Id, {
1731
- id: dropdownId
1732
- }, uniqueDropdownId => React__namespace.createElement(DropdownCore$1, {
1733
- id: uniqueDropdownId,
1734
- role: "menu",
1735
- style: style,
1736
- className: className,
1737
- opener: this.renderOpener(items.length, uniqueDropdownId),
1738
- alignment: alignment,
1739
- open: this.state.opened,
1740
- items: items,
1741
- openerElement: this.openerElement,
1742
- onOpenChanged: this.handleOpenChanged,
1743
- dropdownStyle: [styles$5.menuTopSpace, dropdownStyle]
1744
- }));
1745
- }
1746
- }
1747
- ActionMenu.defaultProps = {
1748
- alignment: "left",
1749
- disabled: false
1750
- };
1751
- const styles$5 = aphrodite.StyleSheet.create({
1752
- caret: {
1753
- marginLeft: 4
1754
- },
1755
- opener: {
1756
- whiteSpace: "nowrap",
1757
- userSelect: "none",
1758
- overflow: "hidden",
1759
- textOverflow: "ellipsis"
1760
- },
1761
- menuTopSpace: {
1762
- top: -4
1763
- }
1764
- });
91
+ class ActionMenu extends React__namespace.Component{static getDerivedStateFromProps(props,state){return {opened:typeof props.opened==="boolean"?props.opened:state.opened}}getMenuItems(){const{children,selectedValues}=this.props;const allChildren=React__namespace.Children.toArray(children).filter(Boolean);const isOptionItemIncluded=allChildren.some(item=>OptionItem.isClassOf(item));return allChildren.map(item=>{const{value,disabled}=item.props;const itemObject={component:item,focusable:ActionItem.isClassOf(item)||OptionItem.isClassOf(item)?!disabled:false,populatedProps:{}};if(ActionItem.isClassOf(item)){return {...itemObject,populatedProps:{indent:isOptionItemIncluded,onClick:this.handleItemSelected}}}else if(OptionItem.isClassOf(item)){const selected=selectedValues?selectedValues.includes(value):false;return {...itemObject,populatedProps:{onToggle:this.handleOptionSelected,selected,variant:"check",role:"menuitemcheckbox","aria-checked":selected,"aria-selected":undefined}}}else {return itemObject}})}renderOpener(numItems,dropdownId){const{disabled,menuText,opener,testId,id}=this.props;return jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueOpenerId=>jsxRuntime.jsx(DropdownOpener,{id:uniqueOpenerId,"aria-controls":dropdownId,"aria-haspopup":"menu",onClick:this.handleClick,disabled:numItems===0||disabled,text:menuText,ref:this.handleOpenerRef,testId:opener?undefined:testId,opened:this.state.opened,role:"button",children:opener?opener:openerProps=>{const{text,opened,...eventState}=openerProps;return jsxRuntime.jsx(ActionMenuOpenerCore,{...eventState,disabled:disabled,opened:!!opened,testId:testId,children:menuText})}})})}render(){const{alignment,dropdownStyle,style,className,dropdownId}=this.props;const items=this.getMenuItems();return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{id:uniqueDropdownId,role:"menu",style:style,className:className,opener:this.renderOpener(items.length,uniqueDropdownId),alignment:alignment,open:this.state.opened,items:items,openerElement:this.openerElement,onOpenChanged:this.handleOpenChanged,dropdownStyle:[styles$5.menuTopSpace,dropdownStyle]})})}constructor(...args){super(...args),this.state={opened:false},this.handleItemSelected=()=>{this.handleOpenChanged(false);if(this.openerElement){this.openerElement.focus();}},this.handleOpenChanged=opened=>{this.setState({opened});if(this.props.onToggle){this.props.onToggle(opened);}},this.handleOptionSelected=selectedValue=>{const{onChange,selectedValues}=this.props;if(!onChange||!selectedValues){return}if(selectedValues.includes(selectedValue)){const index=selectedValues.indexOf(selectedValue);const updatedSelection=[...selectedValues.slice(0,index),...selectedValues.slice(index+1)];onChange(updatedSelection);}else {onChange([...selectedValues,selectedValue]);}this.handleItemSelected();},this.handleOpenerRef=node=>{this.openerElement=ReactDOM__namespace.findDOMNode(node);},this.handleClick=e=>{this.handleOpenChanged(!this.state.opened);};}}ActionMenu.defaultProps={alignment:"left",disabled:false};const styles$5=aphrodite.StyleSheet.create({caret:{marginLeft:4},opener:{whiteSpace:"nowrap",userSelect:"none",overflow:"hidden",textOverflow:"ellipsis"},menuTopSpace:{top:-4}});
1765
92
 
1766
- const _excluded$2 = ["children", "disabled", "error", "id", "isPlaceholder", "open", "testId", "aria-label", "aria-required", "aria-controls", "onBlur", "onOpenChanged"];
1767
- const StyledButton = wonderBlocksCore.addStyle("button");
1768
- class SelectOpener extends React__namespace.Component {
1769
- constructor(props) {
1770
- super(props);
1771
- this.handleClick = e => {
1772
- const {
1773
- open
1774
- } = this.props;
1775
- this.props.onOpenChanged(!open);
1776
- };
1777
- this.handleKeyDown = e => {
1778
- const keyName = e.key;
1779
- if (keyName === wonderBlocksCore.keys.enter || keyName === wonderBlocksCore.keys.space) {
1780
- this.setState({
1781
- pressed: true
1782
- });
1783
- e.preventDefault();
1784
- }
1785
- };
1786
- this.handleKeyUp = e => {
1787
- const keyName = e.key;
1788
- if (keyName === wonderBlocksCore.keys.enter || keyName === wonderBlocksCore.keys.space) {
1789
- this.setState({
1790
- pressed: false
1791
- });
1792
- this.handleClick(e);
1793
- }
1794
- };
1795
- this.state = {
1796
- pressed: false
1797
- };
1798
- }
1799
- render() {
1800
- const _this$props = this.props,
1801
- {
1802
- children,
1803
- disabled,
1804
- error,
1805
- id,
1806
- isPlaceholder,
1807
- open,
1808
- testId,
1809
- "aria-label": ariaLabel,
1810
- "aria-required": ariaRequired,
1811
- "aria-controls": ariaControls,
1812
- onBlur
1813
- } = _this$props,
1814
- sharedProps = _objectWithoutPropertiesLoose__default["default"](_this$props, _excluded$2);
1815
- const stateStyles = _generateStyles(isPlaceholder, error);
1816
- const iconColor = disabled ? wonderBlocksTokens.semanticColor.icon.disabled : wonderBlocksTokens.semanticColor.icon.primary;
1817
- const style = [styles$4.shared, stateStyles.default, disabled && stateStyles.disabled, !disabled && this.state.pressed && stateStyles.press];
1818
- return React__namespace.createElement(StyledButton, _extends__default["default"]({}, sharedProps, {
1819
- "aria-disabled": disabled,
1820
- "aria-expanded": open ? "true" : "false",
1821
- "aria-invalid": error,
1822
- "aria-label": ariaLabel != null ? ariaLabel : undefined,
1823
- "aria-required": ariaRequired,
1824
- "aria-haspopup": "listbox",
1825
- "aria-controls": ariaControls,
1826
- "data-testid": testId,
1827
- id: id,
1828
- role: "combobox",
1829
- type: "button",
1830
- style: style,
1831
- onClick: !disabled ? this.handleClick : undefined,
1832
- onKeyDown: !disabled ? this.handleKeyDown : undefined,
1833
- onKeyUp: !disabled ? this.handleKeyUp : undefined,
1834
- onBlur: onBlur
1835
- }), React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
1836
- style: styles$4.text
1837
- }, children || React__namespace.createElement("span", {
1838
- "aria-hidden": "true"
1839
- }, "\xA0")), React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
1840
- icon: caretDownIcon__default["default"],
1841
- color: iconColor,
1842
- size: "small",
1843
- style: styles$4.caret,
1844
- "aria-hidden": "true"
1845
- }));
1846
- }
1847
- }
1848
- SelectOpener.defaultProps = {
1849
- disabled: false,
1850
- error: false,
1851
- isPlaceholder: false
1852
- };
1853
- const styles$4 = aphrodite.StyleSheet.create({
1854
- shared: {
1855
- position: "relative",
1856
- display: "inline-flex",
1857
- alignItems: "center",
1858
- justifyContent: "space-between",
1859
- color: wonderBlocksTokens.semanticColor.text.primary,
1860
- height: DROPDOWN_ITEM_HEIGHT,
1861
- paddingLeft: wonderBlocksTokens.spacing.medium_16,
1862
- paddingRight: wonderBlocksTokens.spacing.small_12,
1863
- borderWidth: 0,
1864
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
1865
- borderStyle: "solid",
1866
- outline: "none",
1867
- textDecoration: "none",
1868
- boxSizing: "border-box",
1869
- whiteSpace: "nowrap",
1870
- touchAction: "manipulation"
1871
- },
1872
- text: {
1873
- marginRight: wonderBlocksTokens.spacing.xSmall_8,
1874
- whiteSpace: "nowrap",
1875
- userSelect: "none",
1876
- overflow: "hidden",
1877
- textOverflow: "ellipsis"
1878
- },
1879
- caret: {
1880
- minWidth: 16
1881
- }
1882
- });
1883
- const stateStyles = {};
1884
- const _generateStyles = (placeholder, error) => {
1885
- const styleKey = `${placeholder}-${error}`;
1886
- if (stateStyles[styleKey]) {
1887
- return stateStyles[styleKey];
1888
- }
1889
- const states = {
1890
- default: {
1891
- border: wonderBlocksTokens.semanticColor.border.strong,
1892
- background: wonderBlocksTokens.semanticColor.surface.primary,
1893
- foreground: wonderBlocksTokens.semanticColor.text.primary
1894
- },
1895
- disabled: {
1896
- border: wonderBlocksTokens.semanticColor.action.secondary.disabled.border,
1897
- background: wonderBlocksTokens.semanticColor.action.secondary.disabled.background,
1898
- foreground: wonderBlocksTokens.semanticColor.text.secondary
1899
- },
1900
- error: {
1901
- border: wonderBlocksTokens.semanticColor.status.critical.foreground,
1902
- background: wonderBlocksTokens.semanticColor.status.critical.background,
1903
- foreground: wonderBlocksTokens.semanticColor.text.primary
1904
- }
1905
- };
1906
- const actionType = error ? "destructive" : "progressive";
1907
- const action = wonderBlocksTokens.semanticColor.action.secondary[actionType];
1908
- const sharedOutlineStyling = {
1909
- outlineOffset: `calc(${wonderBlocksTokens.border.width.medium} * -1)`,
1910
- outlineStyle: "solid",
1911
- outlineWidth: wonderBlocksTokens.border.width.medium
1912
- };
1913
- const focusStyling = _extends__default["default"]({}, sharedOutlineStyling, {
1914
- outlineColor: wonderBlocksTokens.semanticColor.focus.outer
1915
- });
1916
- const hoverStyling = _extends__default["default"]({}, sharedOutlineStyling, {
1917
- outlineColor: action.hover.border
1918
- });
1919
- const pressStyling = _extends__default["default"]({
1920
- background: action.press.background,
1921
- color: placeholder ? error ? wonderBlocksTokens.semanticColor.text.secondary : wonderBlocksTokens.semanticColor.action.secondary.progressive.press.foreground : wonderBlocksTokens.semanticColor.text.primary,
1922
- outlineColor: action.press.border
1923
- }, sharedOutlineStyling);
1924
- const currentState = error ? states.error : states.default;
1925
- const newStyles = {
1926
- default: {
1927
- background: currentState.background,
1928
- borderColor: currentState.border,
1929
- borderWidth: wonderBlocksTokens.border.width.thin,
1930
- color: placeholder ? wonderBlocksTokens.semanticColor.text.secondary : currentState.foreground,
1931
- ":hover:not([aria-disabled=true])": hoverStyling,
1932
- ["@media not (hover: hover)"]: {
1933
- ":hover:not([aria-disabled=true])": {
1934
- borderColor: currentState.border,
1935
- borderWidth: wonderBlocksTokens.border.width.thin,
1936
- paddingLeft: wonderBlocksTokens.spacing.medium_16,
1937
- paddingRight: wonderBlocksTokens.spacing.small_12
1938
- }
1939
- },
1940
- ":focus-visible:not([aria-disabled=true])": focusStyling,
1941
- ":active:not([aria-disabled=true])": pressStyling
1942
- },
1943
- disabled: {
1944
- background: states.disabled.background,
1945
- borderColor: states.disabled.border,
1946
- color: states.disabled.foreground,
1947
- cursor: "not-allowed",
1948
- ":focus-visible": _extends__default["default"]({
1949
- outlineColor: wonderBlocksTokens.semanticColor.focus.outer
1950
- }, sharedOutlineStyling)
1951
- },
1952
- press: pressStyling
1953
- };
1954
- stateStyles[styleKey] = aphrodite.StyleSheet.create(newStyles);
1955
- return stateStyles[styleKey];
1956
- };
93
+ const StyledButton=wonderBlocksCore.addStyle("button");class SelectOpener extends React__namespace.Component{render(){const{children,disabled,error,id,isPlaceholder,open,testId,"aria-label":ariaLabel,"aria-required":ariaRequired,"aria-controls":ariaControls,onBlur,onOpenChanged,...sharedProps}=this.props;const stateStyles=_generateStyles(isPlaceholder,error);const iconColor=disabled?wonderBlocksTokens.semanticColor.icon.disabled:wonderBlocksTokens.semanticColor.icon.primary;const style=[styles$4.shared,stateStyles.default,disabled&&stateStyles.disabled,!disabled&&this.state.pressed&&stateStyles.press];return jsxRuntime.jsxs(StyledButton,{...sharedProps,"aria-disabled":disabled,"aria-expanded":open?"true":"false","aria-invalid":error,"aria-label":ariaLabel??undefined,"aria-required":ariaRequired,"aria-haspopup":"listbox","aria-controls":ariaControls,"data-testid":testId,id:id,role:"combobox",type:"button",style:style,onClick:!disabled?this.handleClick:undefined,onKeyDown:!disabled?this.handleKeyDown:undefined,onKeyUp:!disabled?this.handleKeyUp:undefined,onBlur:onBlur,children:[jsxRuntime.jsx(wonderBlocksTypography.LabelMedium,{style:styles$4.text,children:children||jsxRuntime.jsx("span",{"aria-hidden":"true",children:" "})}),jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{icon:caretDownIcon__default["default"],color:iconColor,size:"small",style:styles$4.caret,"aria-hidden":"true"})]})}constructor(props){super(props),this.handleClick=e=>{const{open}=this.props;this.props.onOpenChanged(!open);},this.handleKeyDown=e=>{const keyName=e.key;if(keyName===wonderBlocksCore.keys.enter||keyName===wonderBlocksCore.keys.space){this.setState({pressed:true});e.preventDefault();}},this.handleKeyUp=e=>{const keyName=e.key;if(keyName===wonderBlocksCore.keys.enter||keyName===wonderBlocksCore.keys.space){this.setState({pressed:false});this.handleClick(e);}};this.state={pressed:false};}}SelectOpener.defaultProps={disabled:false,error:false,isPlaceholder:false};const styles$4=aphrodite.StyleSheet.create({shared:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"space-between",color:wonderBlocksTokens.semanticColor.text.primary,height:DROPDOWN_ITEM_HEIGHT,paddingLeft:wonderBlocksTokens.spacing.medium_16,paddingRight:wonderBlocksTokens.spacing.small_12,borderWidth:0,borderRadius:wonderBlocksTokens.border.radius.radius_040,borderStyle:"solid",outline:"none",textDecoration:"none",boxSizing:"border-box",whiteSpace:"nowrap",touchAction:"manipulation"},text:{marginRight:wonderBlocksTokens.spacing.xSmall_8,whiteSpace:"nowrap",userSelect:"none",overflow:"hidden",textOverflow:"ellipsis"},caret:{minWidth:16}});const stateStyles={};const _generateStyles=(placeholder,error)=>{const styleKey=`${placeholder}-${error}`;if(stateStyles[styleKey]){return stateStyles[styleKey]}const states={default:{border:wonderBlocksTokens.semanticColor.border.strong,background:wonderBlocksTokens.semanticColor.surface.primary,foreground:wonderBlocksTokens.semanticColor.text.primary},disabled:{border:wonderBlocksTokens.semanticColor.action.secondary.disabled.border,background:wonderBlocksTokens.semanticColor.action.secondary.disabled.background,foreground:wonderBlocksTokens.semanticColor.text.secondary},error:{border:wonderBlocksTokens.semanticColor.status.critical.foreground,background:wonderBlocksTokens.semanticColor.status.critical.background,foreground:wonderBlocksTokens.semanticColor.text.primary}};const actionType=error?"destructive":"progressive";const action=wonderBlocksTokens.semanticColor.action.secondary[actionType];const sharedOutlineStyling={outlineOffset:`calc(${wonderBlocksTokens.border.width.medium} * -1)`,outlineStyle:"solid",outlineWidth:wonderBlocksTokens.border.width.medium};const focusStyling={...sharedOutlineStyling,outlineColor:wonderBlocksTokens.semanticColor.focus.outer};const hoverStyling={...sharedOutlineStyling,outlineColor:action.hover.border};const pressStyling={background:action.press.background,color:placeholder?error?wonderBlocksTokens.semanticColor.text.secondary:wonderBlocksTokens.semanticColor.action.secondary.progressive.press.foreground:wonderBlocksTokens.semanticColor.text.primary,outlineColor:action.press.border,...sharedOutlineStyling};const currentState=error?states.error:states.default;const newStyles={default:{background:currentState.background,borderColor:currentState.border,borderWidth:wonderBlocksTokens.border.width.thin,color:placeholder?wonderBlocksTokens.semanticColor.text.secondary:currentState.foreground,":hover:not([aria-disabled=true])":hoverStyling,["@media not (hover: hover)"]:{":hover:not([aria-disabled=true])":{borderColor:currentState.border,borderWidth:wonderBlocksTokens.border.width.thin,paddingLeft:wonderBlocksTokens.spacing.medium_16,paddingRight:wonderBlocksTokens.spacing.small_12}},":focus-visible:not([aria-disabled=true])":focusStyling,":active:not([aria-disabled=true])":pressStyling},disabled:{background:states.disabled.background,borderColor:states.disabled.border,color:states.disabled.foreground,cursor:"not-allowed",":focus-visible":{outlineColor:wonderBlocksTokens.semanticColor.focus.outer,...sharedOutlineStyling}},press:pressStyling};stateStyles[styleKey]=aphrodite.StyleSheet.create(newStyles);return stateStyles[styleKey]};
1957
94
 
1958
- const defaultErrorMessage = "This field is required.";
1959
- function hasValue(value) {
1960
- return value ? value.length > 0 : false;
1961
- }
1962
- function useSelectValidation({
1963
- value,
1964
- disabled = false,
1965
- validate,
1966
- onValidate,
1967
- required,
1968
- open
1969
- }) {
1970
- const [errorMessage, setErrorMessage] = React__namespace.useState(() => validate && hasValue(value) && !disabled && validate(value) || null);
1971
- const handleValidation = React__namespace.useCallback(newValue => {
1972
- if (disabled) {
1973
- return;
1974
- }
1975
- if (validate) {
1976
- const error = newValue !== undefined && validate(newValue) || null;
1977
- setErrorMessage(error);
1978
- if (onValidate) {
1979
- onValidate(error);
1980
- }
1981
- if (error) {
1982
- return;
1983
- }
1984
- }
1985
- if (required) {
1986
- const requiredString = typeof required === "string" ? required : defaultErrorMessage;
1987
- const error = hasValue(newValue) ? null : requiredString;
1988
- setErrorMessage(error);
1989
- if (onValidate) {
1990
- onValidate(error);
1991
- }
1992
- }
1993
- }, [disabled, validate, setErrorMessage, onValidate, required]);
1994
- wonderBlocksCore.useOnMountEffect(() => {
1995
- if (hasValue(value)) {
1996
- handleValidation(value);
1997
- }
1998
- });
1999
- function onOpenerBlurValidation() {
2000
- if (!open && required && !hasValue(value)) {
2001
- handleValidation(value);
2002
- }
2003
- }
2004
- const onDropdownClosedValidation = () => {
2005
- if (required && !hasValue(value)) {
2006
- handleValidation(value);
2007
- }
2008
- };
2009
- const onSelectionValidation = newValue => {
2010
- handleValidation(newValue);
2011
- };
2012
- const onSelectedValuesChangeValidation = () => {
2013
- setErrorMessage(null);
2014
- if (onValidate) {
2015
- onValidate(null);
2016
- }
2017
- };
2018
- return {
2019
- errorMessage,
2020
- onOpenerBlurValidation,
2021
- onDropdownClosedValidation,
2022
- onSelectionValidation,
2023
- onSelectedValuesChangeValidation
2024
- };
2025
- }
95
+ const defaultErrorMessage="This field is required.";function hasValue(value){return value?value.length>0:false}function useSelectValidation({value,disabled=false,validate,onValidate,required,open}){const[errorMessage,setErrorMessage]=React__namespace.useState(()=>validate&&hasValue(value)&&!disabled&&validate(value)||null);const handleValidation=React__namespace.useCallback(newValue=>{if(disabled){return}if(validate){const error=newValue!==undefined&&validate(newValue)||null;setErrorMessage(error);if(onValidate){onValidate(error);}if(error){return}}if(required){const requiredString=typeof required==="string"?required:defaultErrorMessage;const error=hasValue(newValue)?null:requiredString;setErrorMessage(error);if(onValidate){onValidate(error);}}},[disabled,validate,setErrorMessage,onValidate,required]);wonderBlocksCore.useOnMountEffect(()=>{if(hasValue(value)){handleValidation(value);}});function onOpenerBlurValidation(){if(!open&&required&&!hasValue(value)){handleValidation(value);}}const onDropdownClosedValidation=()=>{if(required&&!hasValue(value)){handleValidation(value);}};const onSelectionValidation=newValue=>{handleValidation(newValue);};const onSelectedValuesChangeValidation=()=>{setErrorMessage(null);if(onValidate){onValidate(null);}};return {errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation,onSelectedValuesChangeValidation}}
2026
96
 
2027
- const _excluded$1 = ["children", "error", "id", "opener", "placeholder", "selectedValue", "testId", "alignment", "autoFocus", "dropdownStyle", "enableTypeAhead", "isFilterable", "labels", "onChange", "onToggle", "opened", "style", "className", "aria-label", "aria-invalid", "aria-required", "disabled", "dropdownId", "validate", "onValidate", "required", "showOpenerLabelAsText"];
2028
- const SingleSelect = props => {
2029
- const selectedIndex = React__namespace.useRef(0);
2030
- const {
2031
- children,
2032
- error = false,
2033
- id,
2034
- opener,
2035
- placeholder,
2036
- selectedValue,
2037
- testId,
2038
- alignment = "left",
2039
- autoFocus = true,
2040
- dropdownStyle,
2041
- enableTypeAhead = true,
2042
- isFilterable,
2043
- labels = {
2044
- clearSearch: defaultLabels.clearSearch,
2045
- filter: defaultLabels.filter,
2046
- noResults: defaultLabels.noResults,
2047
- someResults: defaultLabels.someSelected
2048
- },
2049
- onChange,
2050
- onToggle,
2051
- opened,
2052
- style,
2053
- className,
2054
- "aria-label": ariaLabel,
2055
- "aria-invalid": ariaInvalid,
2056
- "aria-required": ariaRequired,
2057
- disabled = false,
2058
- dropdownId,
2059
- validate,
2060
- onValidate,
2061
- required,
2062
- showOpenerLabelAsText = true
2063
- } = props,
2064
- sharedProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded$1);
2065
- const [open, setOpen] = React__namespace.useState(false);
2066
- const [searchText, setSearchText] = React__namespace.useState("");
2067
- const [openerElement, setOpenerElement] = React__namespace.useState();
2068
- const {
2069
- errorMessage,
2070
- onOpenerBlurValidation,
2071
- onDropdownClosedValidation,
2072
- onSelectionValidation
2073
- } = useSelectValidation({
2074
- value: selectedValue,
2075
- disabled,
2076
- validate,
2077
- onValidate,
2078
- required,
2079
- open
2080
- });
2081
- const hasError = error || !!errorMessage;
2082
- React__namespace.useEffect(() => {
2083
- if (disabled) {
2084
- setOpen(false);
2085
- } else if (typeof opened === "boolean") {
2086
- setOpen(opened);
2087
- }
2088
- }, [disabled, opened]);
2089
- const handleOpenChanged = opened => {
2090
- setOpen(opened);
2091
- setSearchText("");
2092
- if (onToggle) {
2093
- onToggle(opened);
2094
- }
2095
- if (!opened) {
2096
- onDropdownClosedValidation();
2097
- }
2098
- };
2099
- const handleToggle = newSelectedValue => {
2100
- if (newSelectedValue !== selectedValue) {
2101
- onChange(newSelectedValue);
2102
- }
2103
- if (open && openerElement) {
2104
- openerElement.focus();
2105
- }
2106
- setOpen(false);
2107
- if (onToggle) {
2108
- onToggle(false);
2109
- }
2110
- onSelectionValidation(newSelectedValue);
2111
- };
2112
- const mapOptionItemsToDropdownItems = children => {
2113
- let indexCounter = 0;
2114
- selectedIndex.current = 0;
2115
- return children.map(option => {
2116
- const {
2117
- disabled,
2118
- value
2119
- } = option.props;
2120
- const selected = selectedValue === value;
2121
- if (selected) {
2122
- selectedIndex.current = indexCounter;
2123
- }
2124
- if (!disabled) {
2125
- indexCounter += 1;
2126
- }
2127
- return {
2128
- component: option,
2129
- focusable: !disabled,
2130
- populatedProps: {
2131
- onToggle: handleToggle,
2132
- selected: selected,
2133
- variant: "check"
2134
- }
2135
- };
2136
- });
2137
- };
2138
- const filterChildren = children => {
2139
- const lowercasedSearchText = searchText.toLowerCase();
2140
- return children.filter(({
2141
- props
2142
- }) => !searchText || getLabel(props).toLowerCase().indexOf(lowercasedSearchText) > -1);
2143
- };
2144
- const getMenuItems = children => {
2145
- return mapOptionItemsToDropdownItems(isFilterable ? filterChildren(children) : children);
2146
- };
2147
- const handleSearchTextChanged = searchText => {
2148
- setSearchText(searchText);
2149
- };
2150
- const handleOpenerRef = node => {
2151
- const openerElement = ReactDOM__namespace.findDOMNode(node);
2152
- setOpenerElement(openerElement);
2153
- };
2154
- const handleClick = e => {
2155
- handleOpenChanged(!open);
2156
- };
2157
- const handleAnnouncement = message => {
2158
- wonderBlocksAnnouncer.announceMessage({
2159
- message
2160
- });
2161
- };
2162
- React__namespace.useEffect(() => {
2163
- const optionItems = React__namespace.Children.toArray(children);
2164
- const selectedItem = optionItems.find(option => option.props.value === selectedValue);
2165
- if (selectedItem) {
2166
- const label = getLabel(selectedItem.props);
2167
- if (label) {
2168
- handleAnnouncement(label);
2169
- }
2170
- }
2171
- }, [selectedValue, children]);
2172
- const renderOpener = (isDisabled, dropdownId) => {
2173
- const items = React__namespace.Children.toArray(children);
2174
- const selectedItem = items.find(option => option.props.value === selectedValue);
2175
- let menuContent;
2176
- if (selectedItem) {
2177
- menuContent = getSelectOpenerLabel(showOpenerLabelAsText, selectedItem.props);
2178
- } else {
2179
- menuContent = placeholder;
2180
- }
2181
- const dropdownOpener = React__namespace.createElement(wonderBlocksCore.Id, {
2182
- id: id
2183
- }, uniqueOpenerId => {
2184
- return opener ? React__namespace.createElement(DropdownOpener, {
2185
- id: uniqueOpenerId,
2186
- "aria-label": ariaLabel,
2187
- "aria-controls": dropdownId,
2188
- "aria-haspopup": "listbox",
2189
- onClick: handleClick,
2190
- disabled: isDisabled,
2191
- ref: handleOpenerRef,
2192
- role: "combobox",
2193
- text: menuContent,
2194
- opened: open,
2195
- error: hasError,
2196
- onBlur: onOpenerBlurValidation
2197
- }, opener) : React__namespace.createElement(SelectOpener, _extends__default["default"]({}, sharedProps, {
2198
- "aria-label": ariaLabel,
2199
- "aria-controls": dropdownId,
2200
- disabled: isDisabled,
2201
- id: uniqueOpenerId,
2202
- error: hasError,
2203
- isPlaceholder: !selectedItem,
2204
- onOpenChanged: handleOpenChanged,
2205
- open: open,
2206
- ref: handleOpenerRef,
2207
- testId: testId,
2208
- onBlur: onOpenerBlurValidation
2209
- }), menuContent);
2210
- });
2211
- return dropdownOpener;
2212
- };
2213
- const allChildren = React__namespace.Children.toArray(children).filter(Boolean);
2214
- const numEnabledOptions = allChildren.filter(option => !option.props.disabled).length;
2215
- const items = getMenuItems(allChildren);
2216
- const isDisabled = numEnabledOptions === 0 || disabled;
2217
- const {
2218
- someResults
2219
- } = labels;
2220
- React__namespace.useEffect(() => {
2221
- if (open) {
2222
- handleAnnouncement(someResults(items.length));
2223
- }
2224
- }, [items.length, someResults, open]);
2225
- return React__namespace.createElement(wonderBlocksCore.Id, {
2226
- id: dropdownId
2227
- }, uniqueDropdownId => React__namespace.createElement(DropdownCore$1, {
2228
- id: uniqueDropdownId,
2229
- role: "listbox",
2230
- selectionType: "single",
2231
- alignment: alignment,
2232
- autoFocus: autoFocus,
2233
- enableTypeAhead: enableTypeAhead,
2234
- dropdownStyle: [isFilterable && filterableDropdownStyle, selectDropdownStyle, dropdownStyle],
2235
- initialFocusedIndex: selectedIndex.current,
2236
- items: items,
2237
- onOpenChanged: handleOpenChanged,
2238
- open: open,
2239
- opener: renderOpener(isDisabled, uniqueDropdownId),
2240
- openerElement: openerElement,
2241
- style: style,
2242
- className: className,
2243
- isFilterable: isFilterable,
2244
- onSearchTextChanged: isFilterable ? handleSearchTextChanged : undefined,
2245
- searchText: isFilterable ? searchText : "",
2246
- labels: labels,
2247
- "aria-invalid": ariaInvalid,
2248
- "aria-required": ariaRequired,
2249
- disabled: isDisabled
2250
- }));
2251
- };
97
+ const SingleSelect=props=>{const selectedIndex=React__namespace.useRef(0);const{children,error=false,id,opener,placeholder,selectedValue,testId,alignment="left",autoFocus=true,dropdownStyle,enableTypeAhead=true,isFilterable,labels={clearSearch:defaultLabels.clearSearch,filter:defaultLabels.filter,noResults:defaultLabels.noResults,someResults:defaultLabels.someSelected},onChange,onToggle,opened,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,dropdownId,validate,onValidate,required,showOpenerLabelAsText=true,...sharedProps}=props;const[open,setOpen]=React__namespace.useState(false);const[searchText,setSearchText]=React__namespace.useState("");const[openerElement,setOpenerElement]=React__namespace.useState();const{errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation}=useSelectValidation({value:selectedValue,disabled,validate,onValidate,required,open});const hasError=error||!!errorMessage;React__namespace.useEffect(()=>{if(disabled){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);const handleOpenChanged=opened=>{setOpen(opened);setSearchText("");if(onToggle){onToggle(opened);}if(!opened){onDropdownClosedValidation();}};const handleToggle=newSelectedValue=>{if(newSelectedValue!==selectedValue){onChange(newSelectedValue);}if(open&&openerElement){openerElement.focus();}setOpen(false);if(onToggle){onToggle(false);}onSelectionValidation(newSelectedValue);};const mapOptionItemsToDropdownItems=children=>{let indexCounter=0;selectedIndex.current=0;return children.map(option=>{const{disabled,value}=option.props;const selected=selectedValue===value;if(selected){selectedIndex.current=indexCounter;}if(!disabled){indexCounter+=1;}return {component:option,focusable:!disabled,populatedProps:{onToggle:handleToggle,selected:selected,variant:"check"}}})};const filterChildren=children=>{const lowercasedSearchText=searchText.toLowerCase();return children.filter(({props})=>!searchText||getLabel(props).toLowerCase().indexOf(lowercasedSearchText)>-1)};const getMenuItems=children=>{return mapOptionItemsToDropdownItems(isFilterable?filterChildren(children):children)};const handleSearchTextChanged=searchText=>{setSearchText(searchText);};const handleOpenerRef=node=>{const openerElement=ReactDOM__namespace.findDOMNode(node);setOpenerElement(openerElement);};const handleClick=e=>{handleOpenChanged(!open);};const handleAnnouncement=message=>{wonderBlocksAnnouncer.announceMessage({message});};React__namespace.useEffect(()=>{const optionItems=React__namespace.Children.toArray(children);const selectedItem=optionItems.find(option=>option.props.value===selectedValue);if(selectedItem){const label=getLabel(selectedItem.props);if(label){handleAnnouncement(label);}}},[selectedValue,children]);const renderOpener=(isDisabled,dropdownId)=>{const items=React__namespace.Children.toArray(children);const selectedItem=items.find(option=>option.props.value===selectedValue);let menuContent;if(selectedItem){menuContent=getSelectOpenerLabel(showOpenerLabelAsText,selectedItem.props);}else {menuContent=placeholder;}const dropdownOpener=jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueOpenerId=>{return opener?jsxRuntime.jsx(DropdownOpener,{id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-haspopup":"listbox",onClick:handleClick,disabled:isDisabled,ref:handleOpenerRef,role:"combobox",text:menuContent,opened:open,error:hasError,onBlur:onOpenerBlurValidation,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,"aria-label":ariaLabel,"aria-controls":dropdownId,disabled:isDisabled,id:uniqueOpenerId,error:hasError,isPlaceholder:!selectedItem,onOpenChanged:handleOpenChanged,open:open,ref:handleOpenerRef,testId:testId,onBlur:onOpenerBlurValidation,children:menuContent})}});return dropdownOpener};const allChildren=React__namespace.Children.toArray(children).filter(Boolean);const numEnabledOptions=allChildren.filter(option=>!option.props.disabled).length;const items=getMenuItems(allChildren);const isDisabled=numEnabledOptions===0||disabled;const{someResults}=labels;React__namespace.useEffect(()=>{if(open){handleAnnouncement(someResults(items.length));}},[items.length,someResults,open]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{id:uniqueDropdownId,role:"listbox",selectionType:"single",alignment:alignment,autoFocus:autoFocus,enableTypeAhead:enableTypeAhead,dropdownStyle:[isFilterable&&filterableDropdownStyle,selectDropdownStyle,dropdownStyle],initialFocusedIndex:selectedIndex.current,items:items,onOpenChanged:handleOpenChanged,open:open,opener:renderOpener(isDisabled,uniqueDropdownId),openerElement:openerElement,style:style,className:className,isFilterable:isFilterable,onSearchTextChanged:isFilterable?handleSearchTextChanged:undefined,searchText:isFilterable?searchText:"",labels:labels,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:isDisabled})})};
2252
98
 
2253
- const _excluded = ["id", "opener", "testId", "alignment", "dropdownStyle", "implicitAllEnabled", "isFilterable", "labels", "onChange", "onToggle", "opened", "selectedValues", "shortcuts", "style", "className", "aria-label", "aria-invalid", "aria-required", "disabled", "error", "children", "dropdownId", "showOpenerLabelAsText", "validate", "onValidate", "required"];
2254
- const MultiSelect = props => {
2255
- const {
2256
- id,
2257
- opener,
2258
- testId,
2259
- alignment = "left",
2260
- dropdownStyle,
2261
- implicitAllEnabled,
2262
- isFilterable,
2263
- labels: propLabels,
2264
- onChange,
2265
- onToggle,
2266
- opened,
2267
- selectedValues = [],
2268
- shortcuts = false,
2269
- style,
2270
- className,
2271
- "aria-label": ariaLabel,
2272
- "aria-invalid": ariaInvalid,
2273
- "aria-required": ariaRequired,
2274
- disabled = false,
2275
- error = false,
2276
- children,
2277
- dropdownId,
2278
- showOpenerLabelAsText = true,
2279
- validate,
2280
- onValidate,
2281
- required
2282
- } = props,
2283
- sharedProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded);
2284
- const labels = React__namespace.useMemo(() => {
2285
- return _extends__default["default"]({}, defaultLabels, propLabels);
2286
- }, [propLabels]);
2287
- const [open, setOpen] = React__namespace.useState(false);
2288
- const [searchText, setSearchText] = React__namespace.useState("");
2289
- const [lastSelectedValues, setLastSelectedValues] = React__namespace.useState([]);
2290
- const [openerElement, setOpenerElement] = React__namespace.useState();
2291
- const {
2292
- errorMessage,
2293
- onOpenerBlurValidation,
2294
- onDropdownClosedValidation,
2295
- onSelectionValidation,
2296
- onSelectedValuesChangeValidation
2297
- } = useSelectValidation({
2298
- value: selectedValues,
2299
- disabled,
2300
- validate,
2301
- onValidate,
2302
- required,
2303
- open
2304
- });
2305
- const hasError = error || !!errorMessage;
2306
- React__namespace.useEffect(() => {
2307
- if (disabled) {
2308
- setOpen(false);
2309
- } else if (typeof opened === "boolean") {
2310
- setOpen(opened);
2311
- }
2312
- }, [disabled, opened]);
2313
- const handleOpenChanged = opened => {
2314
- setOpen(opened);
2315
- setSearchText("");
2316
- setLastSelectedValues(selectedValues);
2317
- if (onToggle) {
2318
- onToggle(opened);
2319
- }
2320
- if (!opened) {
2321
- if (lastSelectedValues !== selectedValues) {
2322
- onSelectionValidation(selectedValues);
2323
- } else {
2324
- onDropdownClosedValidation();
2325
- }
2326
- }
2327
- };
2328
- const handleToggle = selectedValue => {
2329
- if (selectedValues.includes(selectedValue)) {
2330
- const index = selectedValues.indexOf(selectedValue);
2331
- const updatedSelection = [...selectedValues.slice(0, index), ...selectedValues.slice(index + 1)];
2332
- onChange(updatedSelection);
2333
- } else {
2334
- onChange([...selectedValues, selectedValue]);
2335
- }
2336
- onSelectedValuesChangeValidation();
2337
- };
2338
- const handleSelectAll = () => {
2339
- const allChildren = React__namespace.Children.toArray(children);
2340
- const selected = allChildren.filter(option => !!option && !option.props.disabled).map(option => option.props.value);
2341
- onChange(selected);
2342
- onSelectedValuesChangeValidation();
2343
- };
2344
- const handleSelectNone = () => {
2345
- onChange([]);
2346
- onSelectedValuesChangeValidation();
2347
- };
2348
- const getMenuTextOrNode = React__namespace.useCallback(children => {
2349
- const {
2350
- noneSelected,
2351
- someSelected,
2352
- allSelected
2353
- } = labels;
2354
- const numSelectedAll = children.filter(option => !option.props.disabled).length;
2355
- const noSelectionText = implicitAllEnabled ? allSelected : noneSelected;
2356
- switch (selectedValues.length) {
2357
- case 0:
2358
- return noSelectionText;
2359
- case 1:
2360
- const selectedItem = children.find(option => option.props.value === selectedValues[0]);
2361
- if (selectedItem) {
2362
- const selectedLabel = getSelectOpenerLabel(showOpenerLabelAsText, selectedItem == null ? void 0 : selectedItem.props);
2363
- if (selectedLabel) {
2364
- return selectedLabel;
2365
- } else {
2366
- return someSelected(1);
2367
- }
2368
- }
2369
- return noSelectionText;
2370
- case numSelectedAll:
2371
- return allSelected;
2372
- default:
2373
- return someSelected(selectedValues.length);
2374
- }
2375
- }, [implicitAllEnabled, labels, selectedValues, showOpenerLabelAsText]);
2376
- const getShortcuts = numOptions => {
2377
- const {
2378
- selectAllLabel,
2379
- selectNoneLabel
2380
- } = labels;
2381
- if (shortcuts && !searchText) {
2382
- const selectAllDisabled = numOptions === selectedValues.length;
2383
- const selectAll = {
2384
- component: React__namespace.createElement(ActionItem, {
2385
- disabled: selectAllDisabled,
2386
- label: selectAllLabel(numOptions),
2387
- indent: true,
2388
- onClick: handleSelectAll
2389
- }),
2390
- focusable: !selectAllDisabled,
2391
- populatedProps: {}
2392
- };
2393
- const selectNoneDisabled = selectedValues.length === 0;
2394
- const selectNone = {
2395
- component: React__namespace.createElement(ActionItem, {
2396
- disabled: selectNoneDisabled,
2397
- label: selectNoneLabel,
2398
- indent: true,
2399
- onClick: handleSelectNone
2400
- }),
2401
- focusable: !selectNoneDisabled,
2402
- populatedProps: {}
2403
- };
2404
- const separator = {
2405
- component: React__namespace.createElement(SeparatorItem, {
2406
- key: "shortcuts-separator"
2407
- }),
2408
- focusable: false,
2409
- populatedProps: {}
2410
- };
2411
- return [selectAll, selectNone, separator];
2412
- } else {
2413
- return [];
2414
- }
2415
- };
2416
- const getMenuItems = children => {
2417
- if (!isFilterable) {
2418
- return children.map(mapOptionItemToDropdownItem);
2419
- }
2420
- const lowercasedSearchText = searchText.toLowerCase();
2421
- const filteredChildren = children.filter(({
2422
- props
2423
- }) => !searchText || getLabel(props).toLowerCase().indexOf(lowercasedSearchText) > -1);
2424
- const lastSelectedChildren = [];
2425
- const restOfTheChildren = [];
2426
- for (const child of filteredChildren) {
2427
- if (lastSelectedValues.includes(child.props.value)) {
2428
- lastSelectedChildren.push(child);
2429
- } else {
2430
- restOfTheChildren.push(child);
2431
- }
2432
- }
2433
- const lastSelectedItems = lastSelectedChildren.map(mapOptionItemToDropdownItem);
2434
- if (lastSelectedChildren.length && restOfTheChildren.length) {
2435
- lastSelectedItems.push({
2436
- component: React__namespace.createElement(SeparatorItem, {
2437
- key: "selected-separator"
2438
- }),
2439
- focusable: false,
2440
- populatedProps: {}
2441
- });
2442
- }
2443
- return [...lastSelectedItems, ...restOfTheChildren.map(mapOptionItemToDropdownItem)];
2444
- };
2445
- const mapOptionItemToDropdownItem = option => {
2446
- const {
2447
- disabled,
2448
- value
2449
- } = option.props;
2450
- return {
2451
- component: option,
2452
- focusable: !disabled,
2453
- populatedProps: {
2454
- onToggle: handleToggle,
2455
- selected: selectedValues.includes(value),
2456
- variant: "checkbox"
2457
- }
2458
- };
2459
- };
2460
- const handleOpenerRef = node => {
2461
- const openerElement = ReactDOM__namespace.findDOMNode(node);
2462
- setOpenerElement(openerElement);
2463
- };
2464
- const handleSearchTextChanged = searchText => {
2465
- setSearchText(searchText);
2466
- };
2467
- const handleClick = e => {
2468
- handleOpenChanged(!open);
2469
- };
2470
- const handleAnnouncement = message => {
2471
- wonderBlocksAnnouncer.announceMessage({
2472
- message
2473
- });
2474
- };
2475
- const maybeGetOpenerStringValue = React__namespace.useCallback((children, openerContent) => {
2476
- let openerStringValue;
2477
- if (selectedValues.length === 1) {
2478
- const selectedItem = children.find(option => option.props.value === selectedValues[0]);
2479
- openerStringValue = selectedItem ? getLabel(selectedItem == null ? void 0 : selectedItem.props) : undefined;
2480
- } else if (typeof openerContent === "string") {
2481
- openerStringValue = openerContent;
2482
- }
2483
- return openerStringValue;
2484
- }, [selectedValues]);
2485
- React__namespace.useEffect(() => {
2486
- const optionItems = React__namespace.Children.toArray(children);
2487
- const openerContent = getMenuTextOrNode(optionItems);
2488
- const openerStringValue = maybeGetOpenerStringValue(optionItems, openerContent);
2489
- if (openerStringValue) {
2490
- handleAnnouncement(openerStringValue);
2491
- }
2492
- }, [children, getMenuTextOrNode, maybeGetOpenerStringValue]);
2493
- const renderOpener = (allChildren, isDisabled, dropdownId) => {
2494
- const {
2495
- noneSelected
2496
- } = labels;
2497
- const openerContent = getMenuTextOrNode(allChildren);
2498
- const dropdownOpener = React__namespace.createElement(wonderBlocksCore.Id, {
2499
- id: id
2500
- }, uniqueOpenerId => {
2501
- return opener ? React__namespace.createElement(DropdownOpener, {
2502
- id: uniqueOpenerId,
2503
- error: hasError,
2504
- "aria-label": ariaLabel,
2505
- "aria-controls": dropdownId,
2506
- "aria-haspopup": "listbox",
2507
- onClick: handleClick,
2508
- onBlur: onOpenerBlurValidation,
2509
- disabled: isDisabled,
2510
- ref: handleOpenerRef,
2511
- role: "combobox",
2512
- text: openerContent,
2513
- opened: open
2514
- }, opener) : React__namespace.createElement(SelectOpener, _extends__default["default"]({}, sharedProps, {
2515
- error: hasError,
2516
- disabled: isDisabled,
2517
- id: uniqueOpenerId,
2518
- "aria-label": ariaLabel,
2519
- "aria-controls": dropdownId,
2520
- isPlaceholder: openerContent === noneSelected,
2521
- onOpenChanged: handleOpenChanged,
2522
- onBlur: onOpenerBlurValidation,
2523
- open: open,
2524
- ref: handleOpenerRef,
2525
- testId: testId
2526
- }), openerContent);
2527
- });
2528
- return dropdownOpener;
2529
- };
2530
- const {
2531
- clearSearch,
2532
- filter,
2533
- noResults,
2534
- someSelected
2535
- } = labels;
2536
- const allChildren = React__namespace.Children.toArray(children).filter(Boolean);
2537
- const numEnabledOptions = allChildren.filter(option => !option.props.disabled).length;
2538
- const filteredItems = getMenuItems(allChildren);
2539
- const isDisabled = numEnabledOptions === 0 || disabled;
2540
- React__namespace.useEffect(() => {
2541
- if (open) {
2542
- handleAnnouncement(someSelected(filteredItems.length));
2543
- }
2544
- }, [filteredItems.length, someSelected, open]);
2545
- return React__namespace.createElement(wonderBlocksCore.Id, {
2546
- id: dropdownId
2547
- }, uniqueDropdownId => React__namespace.createElement(DropdownCore$1, {
2548
- id: uniqueDropdownId,
2549
- role: "listbox",
2550
- alignment: alignment,
2551
- dropdownStyle: [isFilterable && filterableDropdownStyle, selectDropdownStyle, dropdownStyle],
2552
- isFilterable: isFilterable,
2553
- items: [...getShortcuts(numEnabledOptions), ...filteredItems],
2554
- onOpenChanged: handleOpenChanged,
2555
- open: open,
2556
- opener: renderOpener(allChildren, isDisabled, uniqueDropdownId),
2557
- openerElement: openerElement,
2558
- selectionType: "multi",
2559
- style: style,
2560
- className: className,
2561
- onSearchTextChanged: isFilterable ? handleSearchTextChanged : undefined,
2562
- searchText: isFilterable ? searchText : "",
2563
- labels: {
2564
- clearSearch,
2565
- filter,
2566
- noResults,
2567
- someResults: someSelected
2568
- },
2569
- "aria-invalid": ariaInvalid,
2570
- "aria-required": ariaRequired,
2571
- disabled: isDisabled
2572
- }));
2573
- };
99
+ const MultiSelect=props=>{const{id,opener,testId,alignment="left",dropdownStyle,implicitAllEnabled,isFilterable,labels:propLabels,onChange,onToggle,opened,selectedValues=[],shortcuts=false,style,className,"aria-label":ariaLabel,"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled=false,error=false,children,dropdownId,showOpenerLabelAsText=true,validate,onValidate,required,...sharedProps}=props;const labels=React__namespace.useMemo(()=>{return {...defaultLabels,...propLabels}},[propLabels]);const[open,setOpen]=React__namespace.useState(false);const[searchText,setSearchText]=React__namespace.useState("");const[lastSelectedValues,setLastSelectedValues]=React__namespace.useState([]);const[openerElement,setOpenerElement]=React__namespace.useState();const{errorMessage,onOpenerBlurValidation,onDropdownClosedValidation,onSelectionValidation,onSelectedValuesChangeValidation}=useSelectValidation({value:selectedValues,disabled,validate,onValidate,required,open});const hasError=error||!!errorMessage;React__namespace.useEffect(()=>{if(disabled){setOpen(false);}else if(typeof opened==="boolean"){setOpen(opened);}},[disabled,opened]);const handleOpenChanged=opened=>{setOpen(opened);setSearchText("");setLastSelectedValues(selectedValues);if(onToggle){onToggle(opened);}if(!opened){if(lastSelectedValues!==selectedValues){onSelectionValidation(selectedValues);}else {onDropdownClosedValidation();}}};const handleToggle=selectedValue=>{if(selectedValues.includes(selectedValue)){const index=selectedValues.indexOf(selectedValue);const updatedSelection=[...selectedValues.slice(0,index),...selectedValues.slice(index+1)];onChange(updatedSelection);}else {onChange([...selectedValues,selectedValue]);}onSelectedValuesChangeValidation();};const handleSelectAll=()=>{const allChildren=React__namespace.Children.toArray(children);const selected=allChildren.filter(option=>!!option&&!option.props.disabled).map(option=>option.props.value);onChange(selected);onSelectedValuesChangeValidation();};const handleSelectNone=()=>{onChange([]);onSelectedValuesChangeValidation();};const getMenuTextOrNode=React__namespace.useCallback(children=>{const{noneSelected,someSelected,allSelected}=labels;const numSelectedAll=children.filter(option=>!option.props.disabled).length;const noSelectionText=implicitAllEnabled?allSelected:noneSelected;switch(selectedValues.length){case 0:return noSelectionText;case 1:const selectedItem=children.find(option=>option.props.value===selectedValues[0]);if(selectedItem){const selectedLabel=getSelectOpenerLabel(showOpenerLabelAsText,selectedItem?.props);if(selectedLabel){return selectedLabel}else {return someSelected(1)}}return noSelectionText;case numSelectedAll:return allSelected;default:return someSelected(selectedValues.length)}},[implicitAllEnabled,labels,selectedValues,showOpenerLabelAsText]);const getShortcuts=numOptions=>{const{selectAllLabel,selectNoneLabel}=labels;if(shortcuts&&!searchText){const selectAllDisabled=numOptions===selectedValues.length;const selectAll={component:jsxRuntime.jsx(ActionItem,{disabled:selectAllDisabled,label:selectAllLabel(numOptions),indent:true,onClick:handleSelectAll}),focusable:!selectAllDisabled,populatedProps:{}};const selectNoneDisabled=selectedValues.length===0;const selectNone={component:jsxRuntime.jsx(ActionItem,{disabled:selectNoneDisabled,label:selectNoneLabel,indent:true,onClick:handleSelectNone}),focusable:!selectNoneDisabled,populatedProps:{}};const separator={component:jsxRuntime.jsx(SeparatorItem,{},"shortcuts-separator"),focusable:false,populatedProps:{}};return [selectAll,selectNone,separator]}else {return []}};const getMenuItems=children=>{if(!isFilterable){return children.map(mapOptionItemToDropdownItem)}const lowercasedSearchText=searchText.toLowerCase();const filteredChildren=children.filter(({props})=>!searchText||getLabel(props).toLowerCase().indexOf(lowercasedSearchText)>-1);const lastSelectedChildren=[];const restOfTheChildren=[];for(const child of filteredChildren){if(lastSelectedValues.includes(child.props.value)){lastSelectedChildren.push(child);}else {restOfTheChildren.push(child);}}const lastSelectedItems=lastSelectedChildren.map(mapOptionItemToDropdownItem);if(lastSelectedChildren.length&&restOfTheChildren.length){lastSelectedItems.push({component:jsxRuntime.jsx(SeparatorItem,{},"selected-separator"),focusable:false,populatedProps:{}});}return [...lastSelectedItems,...restOfTheChildren.map(mapOptionItemToDropdownItem)]};const mapOptionItemToDropdownItem=option=>{const{disabled,value}=option.props;return {component:option,focusable:!disabled,populatedProps:{onToggle:handleToggle,selected:selectedValues.includes(value),variant:"checkbox"}}};const handleOpenerRef=node=>{const openerElement=ReactDOM__namespace.findDOMNode(node);setOpenerElement(openerElement);};const handleSearchTextChanged=searchText=>{setSearchText(searchText);};const handleClick=e=>{handleOpenChanged(!open);};const handleAnnouncement=message=>{wonderBlocksAnnouncer.announceMessage({message});};const maybeGetOpenerStringValue=React__namespace.useCallback((children,openerContent)=>{let openerStringValue;if(selectedValues.length===1){const selectedItem=children.find(option=>option.props.value===selectedValues[0]);openerStringValue=selectedItem?getLabel(selectedItem?.props):undefined;}else if(typeof openerContent==="string"){openerStringValue=openerContent;}return openerStringValue},[selectedValues]);React__namespace.useEffect(()=>{const optionItems=React__namespace.Children.toArray(children);const openerContent=getMenuTextOrNode(optionItems);const openerStringValue=maybeGetOpenerStringValue(optionItems,openerContent);if(openerStringValue){handleAnnouncement(openerStringValue);}},[children,getMenuTextOrNode,maybeGetOpenerStringValue]);const renderOpener=(allChildren,isDisabled,dropdownId)=>{const{noneSelected}=labels;const openerContent=getMenuTextOrNode(allChildren);const dropdownOpener=jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueOpenerId=>{return opener?jsxRuntime.jsx(DropdownOpener,{id:uniqueOpenerId,error:hasError,"aria-label":ariaLabel,"aria-controls":dropdownId,"aria-haspopup":"listbox",onClick:handleClick,onBlur:onOpenerBlurValidation,disabled:isDisabled,ref:handleOpenerRef,role:"combobox",text:openerContent,opened:open,children:opener}):jsxRuntime.jsx(SelectOpener,{...sharedProps,error:hasError,disabled:isDisabled,id:uniqueOpenerId,"aria-label":ariaLabel,"aria-controls":dropdownId,isPlaceholder:openerContent===noneSelected,onOpenChanged:handleOpenChanged,onBlur:onOpenerBlurValidation,open:open,ref:handleOpenerRef,testId:testId,children:openerContent})}});return dropdownOpener};const{clearSearch,filter,noResults,someSelected}=labels;const allChildren=React__namespace.Children.toArray(children).filter(Boolean);const numEnabledOptions=allChildren.filter(option=>!option.props.disabled).length;const filteredItems=getMenuItems(allChildren);const isDisabled=numEnabledOptions===0||disabled;React__namespace.useEffect(()=>{if(open){handleAnnouncement(someSelected(filteredItems.length));}},[filteredItems.length,someSelected,open]);return jsxRuntime.jsx(wonderBlocksCore.Id,{id:dropdownId,children:uniqueDropdownId=>jsxRuntime.jsx(DropdownCore$1,{id:uniqueDropdownId,role:"listbox",alignment:alignment,dropdownStyle:[isFilterable&&filterableDropdownStyle,selectDropdownStyle,dropdownStyle],isFilterable:isFilterable,items:[...getShortcuts(numEnabledOptions),...filteredItems],onOpenChanged:handleOpenChanged,open:open,opener:renderOpener(allChildren,isDisabled,uniqueDropdownId),openerElement:openerElement,selectionType:"multi",style:style,className:className,onSearchTextChanged:isFilterable?handleSearchTextChanged:undefined,searchText:isFilterable?searchText:"",labels:{clearSearch,filter,noResults,someResults:someSelected},"aria-invalid":ariaInvalid,"aria-required":ariaRequired,disabled:isDisabled})})};
2574
100
 
2575
- function updateMultipleSelection(previousSelection, value = "") {
2576
- if (!previousSelection) {
2577
- return [value];
2578
- }
2579
- return previousSelection.includes(value) ? previousSelection.filter(item => item !== value) : [...previousSelection, value];
2580
- }
101
+ function updateMultipleSelection(previousSelection,value=""){if(!previousSelection){return [value]}return previousSelection.includes(value)?previousSelection.filter(item=>item!==value):[...previousSelection,value]}
2581
102
 
2582
- function useListbox({
2583
- children: options,
2584
- disabled,
2585
- disableSpaceSelection,
2586
- id,
2587
- onChange,
2588
- selectionType = "single",
2589
- value
2590
- }) {
2591
- const selectedValueIndex = React__namespace.useMemo(() => {
2592
- const firstValue = Array.isArray(value) ? value[0] : value;
2593
- if (!firstValue || firstValue === "") {
2594
- return 0;
2595
- }
2596
- return options.findIndex(item => item.props.value === firstValue);
2597
- }, [options, value]);
2598
- const [focusedIndex, setFocusedIndex] = React__namespace.useState(selectedValueIndex);
2599
- const [isListboxFocused, setIsListboxFocused] = React__namespace.useState(false);
2600
- const [selected, setSelected] = React__namespace.useState(value);
2601
- const focusItem = index => {
2602
- setFocusedIndex(index);
2603
- };
2604
- const focusPreviousItem = React__namespace.useCallback(() => {
2605
- if (focusedIndex <= 0) {
2606
- focusItem(options.length - 1);
2607
- } else {
2608
- focusItem(focusedIndex - 1);
2609
- }
2610
- }, [options, focusedIndex]);
2611
- const focusNextItem = React__namespace.useCallback(() => {
2612
- if (focusedIndex === options.length - 1) {
2613
- focusItem(0);
2614
- } else {
2615
- focusItem(focusedIndex + 1);
2616
- }
2617
- }, [options, focusedIndex]);
2618
- const selectOption = React__namespace.useCallback(index => {
2619
- const optionItem = options[index];
2620
- if (optionItem.props.disabled) {
2621
- return;
2622
- }
2623
- if (selectionType === "single") {
2624
- setSelected(optionItem.props.value);
2625
- if (onChange) {
2626
- onChange(optionItem.props.value);
2627
- }
2628
- } else {
2629
- setSelected(prevSelected => {
2630
- const newSelectedValue = updateMultipleSelection(prevSelected, optionItem.props.value);
2631
- if (onChange) {
2632
- onChange(newSelectedValue);
2633
- }
2634
- return newSelectedValue;
2635
- });
2636
- }
2637
- }, [onChange, options, selectionType]);
2638
- const handleKeyDown = React__namespace.useCallback(event => {
2639
- const {
2640
- key
2641
- } = event;
2642
- switch (key) {
2643
- case "ArrowUp":
2644
- event.preventDefault();
2645
- focusPreviousItem();
2646
- return;
2647
- case "ArrowDown":
2648
- event.preventDefault();
2649
- focusNextItem();
2650
- return;
2651
- case "Home":
2652
- event.preventDefault();
2653
- focusItem(0);
2654
- return;
2655
- case "End":
2656
- event.preventDefault();
2657
- focusItem(options.length - 1);
2658
- return;
2659
- case "Enter":
2660
- case " ":
2661
- if (focusedIndex < 0 || key === " " && disableSpaceSelection) {
2662
- return;
2663
- }
2664
- event.preventDefault();
2665
- selectOption(focusedIndex);
2666
- return;
2667
- }
2668
- }, [disableSpaceSelection, focusNextItem, focusPreviousItem, focusedIndex, options, selectOption]);
2669
- const handleKeyUp = React__namespace.useCallback(event => {
2670
- switch (event.key) {
2671
- case " ":
2672
- event.preventDefault();
2673
- return;
2674
- }
2675
- }, []);
2676
- const handleFocus = React__namespace.useCallback(() => {
2677
- if (!disabled) {
2678
- setIsListboxFocused(true);
2679
- }
2680
- }, [disabled]);
2681
- const handleBlur = React__namespace.useCallback(() => {
2682
- if (!disabled) {
2683
- setIsListboxFocused(false);
2684
- }
2685
- }, [disabled]);
2686
- const handleClick = React__namespace.useCallback(value => {
2687
- const index = options.findIndex(item => item.props.value === value);
2688
- const isOptionDisabled = options[index].props.disabled;
2689
- if (disabled || isOptionDisabled) {
2690
- return;
2691
- }
2692
- focusItem(index);
2693
- selectOption(index);
2694
- }, [disabled, options, selectOption]);
2695
- const renderList = React__namespace.useMemo(() => {
2696
- return options.map((component, index) => {
2697
- const isSingleSelection = selectionType === "single" && typeof selected === "string";
2698
- const isSelected = (isSingleSelection ? selected === component.props.value : selected == null ? void 0 : selected.includes(component.props.value)) || false;
2699
- const optionId = id ? `${id}-option-${index}` : `option-${index}`;
2700
- return React__namespace.cloneElement(component, {
2701
- key: index,
2702
- focused: isListboxFocused && index === focusedIndex,
2703
- disabled: component.props.disabled || disabled || false,
2704
- selected: isSelected,
2705
- variant: selectionType === "single" ? "check" : "checkbox",
2706
- parentComponent: "listbox",
2707
- id: optionId,
2708
- onToggle: () => {
2709
- handleClick(component.props.value);
2710
- },
2711
- role: "option"
2712
- });
2713
- });
2714
- }, [options, selected, id, isListboxFocused, focusedIndex, disabled, selectionType, handleClick]);
2715
- return {
2716
- isListboxFocused,
2717
- focusedIndex,
2718
- setFocusedIndex,
2719
- renderList,
2720
- setSelected,
2721
- selected,
2722
- handleKeyDown,
2723
- handleKeyUp,
2724
- handleFocus,
2725
- handleBlur
2726
- };
2727
- }
103
+ function useListbox({children:options,disabled,disableSpaceSelection,id,onChange,selectionType="single",value}){const selectedValueIndex=React__namespace.useMemo(()=>{const firstValue=Array.isArray(value)?value[0]:value;if(!firstValue||firstValue===""){return 0}return options.findIndex(item=>item.props.value===firstValue)},[options,value]);const[focusedIndex,setFocusedIndex]=React__namespace.useState(selectedValueIndex);const[isListboxFocused,setIsListboxFocused]=React__namespace.useState(false);const[selected,setSelected]=React__namespace.useState(value);const focusItem=index=>{setFocusedIndex(index);};const focusPreviousItem=React__namespace.useCallback(()=>{if(focusedIndex<=0){focusItem(options.length-1);}else {focusItem(focusedIndex-1);}},[options,focusedIndex]);const focusNextItem=React__namespace.useCallback(()=>{if(focusedIndex===options.length-1){focusItem(0);}else {focusItem(focusedIndex+1);}},[options,focusedIndex]);const selectOption=React__namespace.useCallback(index=>{const optionItem=options[index];if(optionItem.props.disabled){return}if(selectionType==="single"){setSelected(optionItem.props.value);if(onChange){onChange(optionItem.props.value);}}else {setSelected(prevSelected=>{const newSelectedValue=updateMultipleSelection(prevSelected,optionItem.props.value);if(onChange){onChange(newSelectedValue);}return newSelectedValue});}},[onChange,options,selectionType]);const handleKeyDown=React__namespace.useCallback(event=>{const{key}=event;switch(key){case"ArrowUp":event.preventDefault();focusPreviousItem();return;case"ArrowDown":event.preventDefault();focusNextItem();return;case"Home":event.preventDefault();focusItem(0);return;case"End":event.preventDefault();focusItem(options.length-1);return;case"Enter":case" ":if(focusedIndex<0||key===" "&&disableSpaceSelection){return}event.preventDefault();selectOption(focusedIndex);return}},[disableSpaceSelection,focusNextItem,focusPreviousItem,focusedIndex,options,selectOption]);const handleKeyUp=React__namespace.useCallback(event=>{switch(event.key){case" ":event.preventDefault();return}},[]);const handleFocus=React__namespace.useCallback(()=>{if(!disabled){setIsListboxFocused(true);}},[disabled]);const handleBlur=React__namespace.useCallback(()=>{if(!disabled){setIsListboxFocused(false);}},[disabled]);const handleClick=React__namespace.useCallback(value=>{const index=options.findIndex(item=>item.props.value===value);const isOptionDisabled=options[index].props.disabled;if(disabled||isOptionDisabled){return}focusItem(index);selectOption(index);},[disabled,options,selectOption]);const renderList=React__namespace.useMemo(()=>{return options.map((component,index)=>{const isSingleSelection=selectionType==="single"&&typeof selected==="string";const isSelected=(isSingleSelection?selected===component.props.value:selected?.includes(component.props.value))||false;const optionId=id?`${id}-option-${index}`:`option-${index}`;return React__namespace.cloneElement(component,{key:index,focused:isListboxFocused&&index===focusedIndex,disabled:component.props.disabled||disabled||false,selected:isSelected,variant:selectionType==="single"?"check":"checkbox",parentComponent:"listbox",id:optionId,onToggle:()=>{handleClick(component.props.value);},role:"option"})})},[options,selected,id,isListboxFocused,focusedIndex,disabled,selectionType,handleClick]);return {isListboxFocused,focusedIndex,setFocusedIndex,renderList,setSelected,selected,handleKeyDown,handleKeyUp,handleFocus,handleBlur}}
2728
104
 
2729
- function useMultipleSelection({
2730
- inputValue,
2731
- selected,
2732
- setSelected
2733
- }) {
2734
- const [focusedMultiSelectIndex, setFocusedMultiSelectIndex] = React__namespace.useState(-1);
2735
- const handleKeyDown = React__namespace.useCallback(event => {
2736
- const {
2737
- key
2738
- } = event;
2739
- if (!Array.isArray(selected) || selected.length === 0) {
2740
- return;
2741
- }
2742
- if (key === "ArrowLeft") {
2743
- setFocusedMultiSelectIndex(prev => {
2744
- const newIndex = prev - 1;
2745
- return newIndex < 0 ? (selected == null ? void 0 : selected.length) - 1 : newIndex;
2746
- });
2747
- }
2748
- if (key === "ArrowRight") {
2749
- setFocusedMultiSelectIndex(prev => {
2750
- const newIndex = prev + 1;
2751
- return newIndex >= (selected == null ? void 0 : selected.length) ? 0 : newIndex;
2752
- });
2753
- }
2754
- if (inputValue === "" && key === "Backspace") {
2755
- let newSelected = [];
2756
- if (focusedMultiSelectIndex < 0) {
2757
- newSelected = selected == null ? void 0 : selected.slice(0, -1);
2758
- } else {
2759
- newSelected = selected.filter((_, index) => index !== focusedMultiSelectIndex);
2760
- }
2761
- setSelected(newSelected);
2762
- setFocusedMultiSelectIndex(-1);
2763
- }
2764
- if (focusedMultiSelectIndex >= 0 && key === "Enter") {
2765
- const newSelected = selected == null ? void 0 : selected.filter((_, index) => index !== focusedMultiSelectIndex);
2766
- setSelected(newSelected);
2767
- setFocusedMultiSelectIndex(-1);
2768
- }
2769
- if (key === "ArrowDown" || key === "ArrowUp") {
2770
- setFocusedMultiSelectIndex(-1);
2771
- }
2772
- if (key === "Escape") {
2773
- setFocusedMultiSelectIndex(-1);
2774
- }
2775
- }, [focusedMultiSelectIndex, inputValue, selected, setSelected]);
2776
- return {
2777
- focusedMultiSelectIndex,
2778
- handleKeyDown
2779
- };
2780
- }
105
+ function useMultipleSelection({inputValue,selected,setSelected}){const[focusedMultiSelectIndex,setFocusedMultiSelectIndex]=React__namespace.useState(-1);const handleKeyDown=React__namespace.useCallback(event=>{const{key}=event;if(!Array.isArray(selected)||selected.length===0){return}if(key==="ArrowLeft"){setFocusedMultiSelectIndex(prev=>{const newIndex=prev-1;return newIndex<0?selected?.length-1:newIndex});}if(key==="ArrowRight"){setFocusedMultiSelectIndex(prev=>{const newIndex=prev+1;return newIndex>=selected?.length?0:newIndex});}if(inputValue===""&&key==="Backspace"){let newSelected=[];if(focusedMultiSelectIndex<0){newSelected=selected?.slice(0,-1);}else {newSelected=selected.filter((_,index)=>index!==focusedMultiSelectIndex);}setSelected(newSelected);setFocusedMultiSelectIndex(-1);}if(focusedMultiSelectIndex>=0&&key==="Enter"){const newSelected=selected?.filter((_,index)=>index!==focusedMultiSelectIndex);setSelected(newSelected);setFocusedMultiSelectIndex(-1);}if(key==="ArrowDown"||key==="ArrowUp"){setFocusedMultiSelectIndex(-1);}if(key==="Escape"){setFocusedMultiSelectIndex(-1);}},[focusedMultiSelectIndex,inputValue,selected,setSelected]);return {focusedMultiSelectIndex,handleKeyDown}}
2781
106
 
2782
- const StyledSpan = wonderBlocksCore.addStyle("span");
2783
- function ComboboxLiveRegion({
2784
- focusedIndex,
2785
- focusedMultiSelectIndex,
2786
- labels = {
2787
- closedState: defaultComboboxLabels.closedState,
2788
- liveRegionCurrentItem: defaultComboboxLabels.liveRegionCurrentItem,
2789
- liveRegionListboxTotal: defaultComboboxLabels.liveRegionListboxTotal,
2790
- liveRegionMultipleSelectionTotal: defaultComboboxLabels.liveRegionMultipleSelectionTotal,
2791
- noItems: defaultComboboxLabels.noItems,
2792
- selected: defaultComboboxLabels.selected,
2793
- selectionCleared: defaultComboboxLabels.selectionCleared,
2794
- unselected: defaultComboboxLabels.unselected
2795
- },
2796
- selectedLabels,
2797
- opened,
2798
- options,
2799
- selected,
2800
- selectionType = "single",
2801
- testId
2802
- }) {
2803
- const lastSelectedValue = React__namespace.useRef(null);
2804
- const [message, setMessage] = React__namespace.useState("");
2805
- React__namespace.useEffect(() => {
2806
- if (selected && selected !== (lastSelectedValue == null ? void 0 : lastSelectedValue.current)) {
2807
- var _lastSelectedValue$cu, _lastSelectedValue$cu2, _selected$length;
2808
- let newMessage = "";
2809
- const lastSelectedLength = (_lastSelectedValue$cu = lastSelectedValue == null || (_lastSelectedValue$cu2 = lastSelectedValue.current) == null ? void 0 : _lastSelectedValue$cu2.length) != null ? _lastSelectedValue$cu : 0;
2810
- const selectedLength = (_selected$length = selected == null ? void 0 : selected.length) != null ? _selected$length : 0;
2811
- if (Array.isArray(selected) && selected.length > 0) {
2812
- const currentLabels = selectedLabels.join(", ");
2813
- const selectedState = selectedLength > lastSelectedLength ? labels.selected(currentLabels) : labels.unselected(currentLabels);
2814
- newMessage = selectedState;
2815
- } else {
2816
- newMessage = labels.selected(selectedLabels[0]);
2817
- }
2818
- setMessage(newMessage);
2819
- }
2820
- if (selectionType === "single" && !selected && lastSelectedValue.current) {
2821
- setMessage(labels.selectionCleared);
2822
- }
2823
- lastSelectedValue.current = selected;
2824
- if (selectionType === "multiple" && !opened) {
2825
- setMessage(labels.closedState);
2826
- }
2827
- }, [labels, labels.closedState, selectedLabels, opened, selected, selectionType]);
2828
- const focusedElementDescription = React__namespace.useMemo(() => {
2829
- if (focusedMultiSelectIndex >= 0) {
2830
- const _label = selectedLabels[focusedMultiSelectIndex];
2831
- return labels.liveRegionCurrentItem({
2832
- current: _label,
2833
- focused: true,
2834
- index: focusedMultiSelectIndex,
2835
- total: selectedLabels.length
2836
- }) + " " + labels.liveRegionMultipleSelectionTotal(selectedLabels.length);
2837
- }
2838
- if (options.length === 0) {
2839
- return labels.noItems;
2840
- }
2841
- if (focusedIndex < 0 || !options[focusedIndex]) {
2842
- return "";
2843
- }
2844
- const currentItemProps = options[focusedIndex].props;
2845
- const label = getLabel(currentItemProps);
2846
- const totalResults = options.length;
2847
- return labels.liveRegionCurrentItem({
2848
- current: label,
2849
- disabled: currentItemProps.disabled,
2850
- focused: false,
2851
- index: focusedIndex,
2852
- selected: currentItemProps.selected,
2853
- total: totalResults
2854
- }) + " " + labels.liveRegionListboxTotal(totalResults);
2855
- }, [focusedIndex, focusedMultiSelectIndex, labels, options, selectedLabels]);
2856
- return React__namespace.createElement(StyledSpan, {
2857
- role: "log",
2858
- "aria-live": "polite",
2859
- "aria-atomic": "false",
2860
- "aria-relevant": "additions text",
2861
- style: styles$3.srOnly,
2862
- "data-testid": testId ? `${testId}-status` : undefined
2863
- }, opened ? focusedElementDescription : message);
2864
- }
2865
- const styles$3 = aphrodite.StyleSheet.create({
2866
- srOnly: {
2867
- border: 0,
2868
- clip: "rect(0,0,0,0)",
2869
- height: 1,
2870
- margin: -1,
2871
- overflow: "hidden",
2872
- padding: 0,
2873
- position: "absolute",
2874
- width: 1
2875
- }
2876
- });
107
+ const StyledSpan=wonderBlocksCore.addStyle("span");function ComboboxLiveRegion({focusedIndex,focusedMultiSelectIndex,labels={closedState:defaultComboboxLabels.closedState,liveRegionCurrentItem:defaultComboboxLabels.liveRegionCurrentItem,liveRegionListboxTotal:defaultComboboxLabels.liveRegionListboxTotal,liveRegionMultipleSelectionTotal:defaultComboboxLabels.liveRegionMultipleSelectionTotal,noItems:defaultComboboxLabels.noItems,selected:defaultComboboxLabels.selected,selectionCleared:defaultComboboxLabels.selectionCleared,unselected:defaultComboboxLabels.unselected},selectedLabels,opened,options,selected,selectionType="single",testId}){const lastSelectedValue=React__namespace.useRef(null);const[message,setMessage]=React__namespace.useState("");React__namespace.useEffect(()=>{if(selected&&selected!==lastSelectedValue?.current){let newMessage="";const lastSelectedLength=lastSelectedValue?.current?.length??0;const selectedLength=selected?.length??0;if(Array.isArray(selected)&&selected.length>0){const currentLabels=selectedLabels.join(", ");const selectedState=selectedLength>lastSelectedLength?labels.selected(currentLabels):labels.unselected(currentLabels);newMessage=selectedState;}else {newMessage=labels.selected(selectedLabels[0]);}setMessage(newMessage);}if(selectionType==="single"&&!selected&&lastSelectedValue.current){setMessage(labels.selectionCleared);}lastSelectedValue.current=selected;if(selectionType==="multiple"&&!opened){setMessage(labels.closedState);}},[labels,labels.closedState,selectedLabels,opened,selected,selectionType]);const focusedElementDescription=React__namespace.useMemo(()=>{if(focusedMultiSelectIndex>=0){const label=selectedLabels[focusedMultiSelectIndex];return labels.liveRegionCurrentItem({current:label,focused:true,index:focusedMultiSelectIndex,total:selectedLabels.length})+" "+labels.liveRegionMultipleSelectionTotal(selectedLabels.length)}if(options.length===0){return labels.noItems}if(focusedIndex<0||!options[focusedIndex]){return ""}const currentItemProps=options[focusedIndex].props;const label=getLabel(currentItemProps);const totalResults=options.length;return labels.liveRegionCurrentItem({current:label,disabled:currentItemProps.disabled,focused:false,index:focusedIndex,selected:currentItemProps.selected,total:totalResults})+" "+labels.liveRegionListboxTotal(totalResults)},[focusedIndex,focusedMultiSelectIndex,labels,options,selectedLabels]);return jsxRuntime.jsx(StyledSpan,{role:"log","aria-live":"polite","aria-atomic":"false","aria-relevant":"additions text",style:styles$3.srOnly,"data-testid":testId?`${testId}-status`:undefined,children:opened?focusedElementDescription:message})}const styles$3=aphrodite.StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
2877
108
 
2878
- const MultipleSelection = React__namespace.memo(function SelectedPills({
2879
- disabled,
2880
- focusedMultiSelectIndex,
2881
- id,
2882
- labels,
2883
- onRemove,
2884
- removeSelectedLabel,
2885
- selected,
2886
- testId
2887
- }) {
2888
- return React__namespace.createElement(wonderBlocksCore.View, {
2889
- role: "group",
2890
- style: styles$2.pillsWrapper,
2891
- id: id
2892
- }, selected.map((value, index) => {
2893
- const label = labels[index];
2894
- const focused = index === focusedMultiSelectIndex;
2895
- const uniqueId = id + index;
2896
- return React__namespace.createElement(Pill__default["default"], {
2897
- id: uniqueId,
2898
- key: uniqueId,
2899
- testId: testId ? `${testId}-pill-${index}` : undefined,
2900
- size: "small",
2901
- style: [styles$2.pill, focused && styles$2.pillFocused],
2902
- kind: focused ? "info" : "neutral",
2903
- "aria-label": removeSelectedLabel(label),
2904
- tabIndex: -1,
2905
- onClick: () => onRemove(value)
2906
- }, React__namespace.createElement(React__namespace.Fragment, null, label, !disabled && React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
2907
- icon: xIcon__default["default"],
2908
- size: "small"
2909
- })));
2910
- }));
2911
- });
2912
- const styles$2 = aphrodite.StyleSheet.create({
2913
- pillsWrapper: {
2914
- flexDirection: "row",
2915
- flexWrap: "wrap"
2916
- },
2917
- pill: {
2918
- fontSize: wonderBlocksTokens.font.size.small,
2919
- justifyContent: "space-between",
2920
- alignItems: "center",
2921
- marginBlockStart: wonderBlocksTokens.spacing.xxxSmall_4,
2922
- marginInlineEnd: wonderBlocksTokens.spacing.xxxSmall_4,
2923
- paddingInlineEnd: wonderBlocksTokens.spacing.xxxSmall_4
2924
- },
2925
- pillFocused: {
2926
- outline: `1px solid ${wonderBlocksTokens.semanticColor.focus.outer}`
2927
- }
2928
- });
109
+ const MultipleSelection=React__namespace.memo(function SelectedPills({disabled,focusedMultiSelectIndex,id,labels,onRemove,removeSelectedLabel,selected,testId}){return jsxRuntime.jsx(wonderBlocksCore.View,{role:"group",style:styles$2.pillsWrapper,id:id,children:selected.map((value,index)=>{const label=labels[index];const focused=index===focusedMultiSelectIndex;const uniqueId=id+index;return jsxRuntime.jsx(Pill__default["default"],{id:uniqueId,testId:testId?`${testId}-pill-${index}`:undefined,size:"small",style:[styles$2.pill,focused&&styles$2.pillFocused],kind:focused?"info":"neutral","aria-label":removeSelectedLabel(label),tabIndex:-1,onClick:()=>onRemove(value),children:jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[label,!disabled&&jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{icon:xIcon__default["default"],size:"small"})]})},uniqueId)})})});const styles$2=aphrodite.StyleSheet.create({pillsWrapper:{flexDirection:"row",flexWrap:"wrap"},pill:{fontSize:wonderBlocksTokens.font.size.small,justifyContent:"space-between",alignItems:"center",marginBlockStart:wonderBlocksTokens.spacing.xxxSmall_4,marginInlineEnd:wonderBlocksTokens.spacing.xxxSmall_4,paddingInlineEnd:wonderBlocksTokens.spacing.xxxSmall_4},pillFocused:{outline:`1px solid ${wonderBlocksTokens.semanticColor.focus.outer}`}});
2929
110
 
2930
- function StandaloneListbox(props) {
2931
- const {
2932
- children,
2933
- disabled,
2934
- id,
2935
- onChange,
2936
- selectionType = "single",
2937
- style,
2938
- tabIndex = 0,
2939
- testId,
2940
- value,
2941
- "aria-label": ariaLabel,
2942
- "aria-labelledby": ariaLabelledby
2943
- } = props;
2944
- const generatedUniqueId = React.useId();
2945
- const uniqueId = id != null ? id : generatedUniqueId;
2946
- const {
2947
- focusedIndex,
2948
- isListboxFocused,
2949
- renderList,
2950
- selected,
2951
- handleKeyDown,
2952
- handleKeyUp,
2953
- handleFocus,
2954
- handleBlur
2955
- } = useListbox({
2956
- children,
2957
- disabled,
2958
- id: uniqueId,
2959
- selectionType,
2960
- value
2961
- });
2962
- React__namespace.useEffect(() => {
2963
- if (selected && selected !== value) {
2964
- onChange == null || onChange(selected);
2965
- }
2966
- }, [onChange, selected, value]);
2967
- return React__namespace.createElement(wonderBlocksCore.View, {
2968
- role: "listbox",
2969
- id: uniqueId,
2970
- style: [styles$1.listbox, style, disabled && styles$1.disabled],
2971
- tabIndex: tabIndex,
2972
- testId: testId,
2973
- "aria-disabled": disabled,
2974
- "aria-label": ariaLabel,
2975
- "aria-labelledby": ariaLabelledby,
2976
- "aria-multiselectable": selectionType === "multiple",
2977
- onKeyDown: handleKeyDown,
2978
- onKeyUp: handleKeyUp,
2979
- onFocus: handleFocus,
2980
- onBlur: handleBlur,
2981
- "aria-activedescendant": isListboxFocused ? renderList[focusedIndex].props.id : undefined
2982
- }, renderList);
2983
- }
2984
- function Listbox(props) {
2985
- const {
2986
- children,
2987
- disabled,
2988
- id,
2989
- selectionType = "single",
2990
- style,
2991
- tabIndex = 0,
2992
- testId,
2993
- "aria-label": ariaLabel,
2994
- "aria-labelledby": ariaLabelledby
2995
- } = props;
2996
- if (tabIndex === 0) {
2997
- return React__namespace.createElement(StandaloneListbox, props);
2998
- }
2999
- return React__namespace.createElement(wonderBlocksCore.View, {
3000
- role: "listbox",
3001
- id: id,
3002
- style: [styles$1.listbox, style, disabled && styles$1.disabled],
3003
- tabIndex: tabIndex,
3004
- testId: testId,
3005
- "aria-disabled": disabled,
3006
- "aria-label": ariaLabel,
3007
- "aria-labelledby": ariaLabelledby,
3008
- "aria-multiselectable": selectionType === "multiple"
3009
- }, children);
3010
- }
3011
- const theme$1 = {
3012
- listbox: {
3013
- color: {
3014
- disabled: {
3015
- foreground: wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground
3016
- }
3017
- }
3018
- }
3019
- };
3020
- const styles$1 = aphrodite.StyleSheet.create({
3021
- listbox: {
3022
- outline: "none"
3023
- },
3024
- disabled: {
3025
- color: theme$1.listbox.color.disabled.foreground
3026
- }
3027
- });
111
+ function StandaloneListbox(props){const{children,disabled,id,onChange,selectionType="single",style,tabIndex=0,testId,value,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby}=props;const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const{focusedIndex,isListboxFocused,renderList,selected,handleKeyDown,handleKeyUp,handleFocus,handleBlur}=useListbox({children,disabled,id:uniqueId,selectionType,value});React__namespace.useEffect(()=>{if(selected&&selected!==value){onChange?.(selected);}},[onChange,selected,value]);return jsxRuntime.jsx(wonderBlocksCore.View,{role:"listbox",id:uniqueId,style:[styles$1.listbox,style,disabled&&styles$1.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",onKeyDown:handleKeyDown,onKeyUp:handleKeyUp,onFocus:handleFocus,onBlur:handleBlur,"aria-activedescendant":isListboxFocused?renderList[focusedIndex].props.id:undefined,children:renderList})}function Listbox(props){const{children,disabled,id,selectionType="single",style,tabIndex=0,testId,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby}=props;if(tabIndex===0){return jsxRuntime.jsx(StandaloneListbox,{...props})}return jsxRuntime.jsx(wonderBlocksCore.View,{role:"listbox",id:id,style:[styles$1.listbox,style,disabled&&styles$1.disabled],tabIndex:tabIndex,testId:testId,"aria-disabled":disabled,"aria-label":ariaLabel,"aria-labelledby":ariaLabelledby,"aria-multiselectable":selectionType==="multiple",children:children})}const theme$1={listbox:{color:{disabled:{foreground:wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground}}}};const styles$1=aphrodite.StyleSheet.create({listbox:{outline:"none"},disabled:{color:theme$1.listbox.color.disabled.foreground}});
3028
112
 
3029
- function Combobox({
3030
- autoComplete,
3031
- children,
3032
- disabled,
3033
- error,
3034
- id,
3035
- labels = defaultComboboxLabels,
3036
- onChange,
3037
- onToggle,
3038
- opened,
3039
- placeholder,
3040
- selectionType = "single",
3041
- startIcon,
3042
- testId,
3043
- value = ""
3044
- }) {
3045
- var _renderList$find, _renderList$focusedIn;
3046
- const generatedUniqueId = React.useId();
3047
- const uniqueId = id != null ? id : generatedUniqueId;
3048
- const comboboxRef = React__namespace.useRef(null);
3049
- const rootNodeRef = React__namespace.useRef(null);
3050
- const [open, setOpen] = React__namespace.useState(opened != null ? opened : false);
3051
- const isControlled = opened !== undefined;
3052
- const openState = disabled ? false : isControlled ? opened : open;
3053
- const [selectedValue, setSelectedValue] = React__namespace.useState(value);
3054
- const isValueControlled = value !== "" && onChange !== undefined;
3055
- const valueState = isValueControlled ? value : selectedValue;
3056
- const [currentOptions, setCurrentOptions] = React__namespace.useState(children);
3057
- const {
3058
- focusedIndex,
3059
- isListboxFocused,
3060
- setFocusedIndex,
3061
- handleKeyDown,
3062
- handleFocus,
3063
- handleBlur,
3064
- selected,
3065
- setSelected,
3066
- renderList
3067
- } = useListbox({
3068
- children: currentOptions,
3069
- disabled,
3070
- id: uniqueId,
3071
- onChange: value => handleChange(value),
3072
- value: valueState,
3073
- disableSpaceSelection: true,
3074
- selectionType
3075
- });
3076
- const itemFromSelected = (_renderList$find = renderList.find(item => item.props.value === selected)) == null ? void 0 : _renderList$find.props;
3077
- const labelFromSelected = itemFromSelected ? getLabel(itemFromSelected) : "";
3078
- const initialValue = typeof value === "string" ? labelFromSelected : "";
3079
- const [inputValue, setInputValue] = React__namespace.useState(initialValue);
3080
- const {
3081
- focusedMultiSelectIndex,
3082
- handleKeyDown: handleMultipleSelectionKeyDown
3083
- } = useMultipleSelection({
3084
- inputValue,
3085
- selected,
3086
- setSelected
3087
- });
3088
- const updateOpenState = React__namespace.useCallback((newState, selectedLabel = labelFromSelected) => {
3089
- if (disabled || newState === openState) {
3090
- return;
3091
- }
3092
- if (!isControlled) {
3093
- setOpen(newState);
3094
- }
3095
- if (!newState) {
3096
- setFocusedIndex(-1);
3097
- if (selectionType === "multiple") {
3098
- setInputValue("");
3099
- } else {
3100
- setInputValue(selectedLabel != null ? selectedLabel : "");
3101
- }
3102
- setCurrentOptions(children);
3103
- }
3104
- onToggle == null || onToggle(newState);
3105
- }, [children, disabled, isControlled, labelFromSelected, onToggle, openState, selectionType, setFocusedIndex]);
3106
- const handleChange = React__namespace.useCallback(value => {
3107
- if (value !== valueState) {
3108
- setSelectedValue(value);
3109
- onChange == null || onChange(value);
3110
- }
3111
- if (selectionType === "single" && typeof value === "string") {
3112
- var _renderList$find2;
3113
- const itemFromSelected = (_renderList$find2 = renderList.find(item => item.props.value === value)) == null ? void 0 : _renderList$find2.props;
3114
- const labelFromSelected = itemFromSelected ? getLabel(itemFromSelected) : "";
3115
- updateOpenState(false, labelFromSelected);
3116
- } else if (Array.isArray(value)) {
3117
- setInputValue("");
3118
- setCurrentOptions(children);
3119
- }
3120
- }, [children, onChange, renderList, selectionType, updateOpenState, valueState]);
3121
- const focusOnFilteredItem = React__namespace.useCallback((filtered, value) => {
3122
- const lowercasedSearchText = value.normalize("NFC").toLowerCase();
3123
- const itemIndex = filtered.findIndex(item => getLabel(item.props).normalize("NFC").toLowerCase().trim().includes(lowercasedSearchText));
3124
- setFocusedIndex(itemIndex);
3125
- }, [setFocusedIndex]);
3126
- const filterItems = React__namespace.useCallback(value => {
3127
- const lowercasedSearchText = value.normalize("NFC").toLowerCase();
3128
- return children.filter(item => getLabel(item.props).normalize("NFC").trim().toLowerCase().indexOf(lowercasedSearchText) > -1);
3129
- }, [children]);
3130
- const onKeyDown = event => {
3131
- const {
3132
- key
3133
- } = event;
3134
- const conditionsToOpen = key === "ArrowDown" || key === "ArrowUp" || key === "Backspace" || key.length === 1;
3135
- if (!openState && conditionsToOpen) {
3136
- updateOpenState(true);
3137
- }
3138
- if (key === "ArrowLeft" || key === "ArrowRight") {
3139
- setFocusedIndex(-1);
3140
- }
3141
- handleMultipleSelectionKeyDown(event);
3142
- if (key === "Escape" && openState) {
3143
- event.stopPropagation();
3144
- updateOpenState(false);
3145
- }
3146
- handleKeyDown(event);
3147
- };
3148
- const handleOnRemove = React__namespace.useCallback(value => {
3149
- const selectedValues = selected;
3150
- const newValues = selectedValues.filter(selectedValue => selectedValue !== value);
3151
- setSelected(newValues);
3152
- }, [selected, setSelected]);
3153
- const handleTextFieldChange = React__namespace.useCallback(value => {
3154
- setInputValue(value);
3155
- let filteredItems = renderList;
3156
- if (autoComplete === "list") {
3157
- filteredItems = filterItems(value);
3158
- setCurrentOptions(filteredItems);
3159
- }
3160
- focusOnFilteredItem(filteredItems, value);
3161
- }, [autoComplete, filterItems, focusOnFilteredItem, renderList]);
3162
- const handleClearClick = React__namespace.useCallback(e => {
3163
- var _comboboxRef$current;
3164
- e.stopPropagation();
3165
- setInputValue("");
3166
- setSelected("");
3167
- onChange == null || onChange("");
3168
- (_comboboxRef$current = comboboxRef.current) == null || _comboboxRef$current.focus();
3169
- }, [onChange, setSelected]);
3170
- React__namespace.useEffect(() => {
3171
- if (openState) {
3172
- var _comboboxRef$current2;
3173
- (_comboboxRef$current2 = comboboxRef.current) == null || _comboboxRef$current2.focus();
3174
- }
3175
- }, [openState]);
3176
- const selectedLabels = React__namespace.useMemo(() => {
3177
- if (Array.isArray(selected)) {
3178
- return selected.map(value => {
3179
- const item = children.find(item => item.props.value === value);
3180
- return item ? getLabel(item == null ? void 0 : item.props) : "";
3181
- });
3182
- }
3183
- return [labelFromSelected];
3184
- }, [children, labelFromSelected, selected]);
3185
- const maybeRenderStartIcon = () => {
3186
- var _startIcon$props$colo;
3187
- if (!startIcon) {
3188
- return null;
3189
- }
3190
- const startIconElement = React__namespace.cloneElement(startIcon, _extends__default["default"]({
3191
- size: "small"
3192
- }, startIcon.props, {
3193
- color: disabled ? wonderBlocksTokens.semanticColor.icon.disabled : (_startIcon$props$colo = startIcon.props.color) != null ? _startIcon$props$colo : wonderBlocksTokens.semanticColor.icon.primary
3194
- }));
3195
- return React__namespace.createElement(wonderBlocksCore.View, {
3196
- style: styles.iconWrapper
3197
- }, startIconElement);
3198
- };
3199
- const pillIdPrefix = `${uniqueId}-pill-`;
3200
- const textFieldId = React.useId();
3201
- const currentActiveDescendant = !openState ? undefined : focusedIndex >= 0 ? (_renderList$focusedIn = renderList[focusedIndex]) == null || (_renderList$focusedIn = _renderList$focusedIn.props) == null ? void 0 : _renderList$focusedIn.id : pillIdPrefix + focusedMultiSelectIndex;
3202
- const controlledWidget = !openState ? undefined : focusedIndex >= 0 ? uniqueId : pillIdPrefix;
3203
- return React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement(wonderBlocksCore.View, {
3204
- onClick: () => {
3205
- updateOpenState(true);
3206
- },
3207
- ref: rootNodeRef,
3208
- style: [styles.wrapper, isListboxFocused && styles.focused, disabled && styles.disabled, !disabled && error && styles.error]
3209
- }, React__namespace.createElement(ComboboxLiveRegion, {
3210
- focusedIndex: focusedIndex,
3211
- focusedMultiSelectIndex: focusedMultiSelectIndex,
3212
- labels: labels,
3213
- options: renderList,
3214
- selectedLabels: selectedLabels,
3215
- testId: testId,
3216
- opened: openState,
3217
- selected: selected,
3218
- selectionType: selectionType
3219
- }), selectionType === "multiple" && Array.isArray(selected) && React__namespace.createElement(MultipleSelection, {
3220
- labels: selectedLabels,
3221
- focusedMultiSelectIndex: focusedMultiSelectIndex,
3222
- id: pillIdPrefix,
3223
- selected: selected,
3224
- onRemove: handleOnRemove,
3225
- disabled: disabled,
3226
- testId: testId,
3227
- removeSelectedLabel: labels.removeSelected
3228
- }), maybeRenderStartIcon(), React__namespace.createElement(wonderBlocksForm.TextField, {
3229
- id: textFieldId,
3230
- testId: testId,
3231
- style: styles.combobox,
3232
- value: inputValue,
3233
- onChange: handleTextFieldChange,
3234
- disabled: disabled,
3235
- onFocus: () => {
3236
- updateOpenState(true);
3237
- handleFocus();
3238
- },
3239
- placeholder: placeholder,
3240
- onBlur: () => {
3241
- updateOpenState(false);
3242
- handleBlur();
3243
- },
3244
- onKeyDown: onKeyDown,
3245
- "aria-activedescendant": currentActiveDescendant,
3246
- "aria-autocomplete": autoComplete,
3247
- "aria-controls": controlledWidget,
3248
- "aria-expanded": openState,
3249
- "aria-invalid": !!error,
3250
- ref: comboboxRef,
3251
- autoComplete: "off",
3252
- role: "combobox"
3253
- }), inputValue && !disabled && React__namespace.createElement(IconButton__default["default"], {
3254
- icon: xIcon__default["default"],
3255
- onClick: handleClearClick,
3256
- actionType: "neutral",
3257
- kind: "tertiary",
3258
- size: "small",
3259
- style: [styles.button, styles.clearButton],
3260
- "aria-label": labels.clearSelection,
3261
- testId: testId ? `${testId}-clear` : undefined
3262
- }), React__namespace.createElement(IconButton__default["default"], {
3263
- disabled: disabled,
3264
- icon: caretDownIcon__default$1["default"],
3265
- onClick: e => {
3266
- e.stopPropagation();
3267
- updateOpenState(!openState);
3268
- },
3269
- onMouseDown: e => {
3270
- e.preventDefault();
3271
- },
3272
- actionType: "neutral",
3273
- kind: "tertiary",
3274
- size: "small",
3275
- style: [styles.button, openState && styles.buttonOpen],
3276
- tabIndex: -1,
3277
- "aria-controls": uniqueId,
3278
- "aria-expanded": openState,
3279
- "aria-label": labels.comboboxButton
3280
- })), openState && React__namespace.createElement(DropdownPopper, {
3281
- alignment: "left",
3282
- referenceElement: rootNodeRef == null ? void 0 : rootNodeRef.current
3283
- }, isReferenceHidden => {
3284
- var _rootNodeRef$current, _rootNodeRef$current2;
3285
- return React__namespace.createElement(React__namespace.Fragment, null, renderList.length === 0 ? React__namespace.createElement(wonderBlocksCell.DetailCell, {
3286
- title: labels.noItems,
3287
- style: [styles.listbox, {
3288
- minWidth: rootNodeRef == null || (_rootNodeRef$current = rootNodeRef.current) == null ? void 0 : _rootNodeRef$current.offsetWidth
3289
- }],
3290
- horizontalRule: "none"
3291
- }) : React__namespace.createElement(Listbox, {
3292
- id: uniqueId,
3293
- tabIndex: -1,
3294
- selectionType: selectionType,
3295
- style: [styles.listbox, isReferenceHidden && styles.hidden, {
3296
- minWidth: rootNodeRef == null || (_rootNodeRef$current2 = rootNodeRef.current) == null ? void 0 : _rootNodeRef$current2.offsetWidth
3297
- }],
3298
- testId: testId ? `${testId}-listbox` : undefined,
3299
- "aria-label": labels.listbox,
3300
- "aria-labelledby": textFieldId
3301
- }, renderList));
3302
- }));
3303
- }
3304
- const theme = {
3305
- combobox: {
3306
- color: {
3307
- default: {
3308
- border: wonderBlocksTokens.semanticColor.border.strong,
3309
- background: wonderBlocksTokens.semanticColor.surface.primary
3310
- },
3311
- focus: {
3312
- border: wonderBlocksTokens.semanticColor.focus.outer,
3313
- background: wonderBlocksTokens.semanticColor.surface.primary
3314
- },
3315
- disabled: {
3316
- border: wonderBlocksTokens.semanticColor.action.secondary.disabled.border,
3317
- background: wonderBlocksTokens.semanticColor.action.secondary.disabled.background,
3318
- foreground: wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground
3319
- },
3320
- error: {
3321
- border: wonderBlocksTokens.semanticColor.status.critical.foreground,
3322
- background: wonderBlocksTokens.semanticColor.status.critical.background,
3323
- foreground: wonderBlocksTokens.semanticColor.text.primary
3324
- }
3325
- }
3326
- },
3327
- listbox: {
3328
- color: {
3329
- default: {
3330
- background: wonderBlocksTokens.semanticColor.surface.primary,
3331
- border: wonderBlocksTokens.semanticColor.border.primary
3332
- }
3333
- }
3334
- }
3335
- };
3336
- const styles = aphrodite.StyleSheet.create({
3337
- wrapper: {
3338
- flexDirection: "row",
3339
- alignItems: "center",
3340
- width: "100%",
3341
- maxWidth: "100%",
3342
- flexWrap: "wrap",
3343
- background: theme.combobox.color.default.background,
3344
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
3345
- border: `solid 1px ${theme.combobox.color.default.border}`,
3346
- paddingInline: wonderBlocksTokens.spacing.xSmall_8
3347
- },
3348
- focused: {
3349
- background: theme.combobox.color.focus.background,
3350
- border: `1px solid ${theme.combobox.color.focus.border}`
3351
- },
3352
- disabled: {
3353
- background: theme.combobox.color.disabled.background,
3354
- border: `1px solid ${theme.combobox.color.disabled.border}`,
3355
- color: theme.combobox.color.disabled.foreground
3356
- },
3357
- error: {
3358
- background: theme.combobox.color.error.background,
3359
- border: `1px solid ${theme.combobox.color.error.border}`,
3360
- color: theme.combobox.color.error.foreground
3361
- },
3362
- combobox: {
3363
- appearance: "none",
3364
- background: "none",
3365
- border: "none",
3366
- outline: "none",
3367
- padding: 0,
3368
- minWidth: wonderBlocksTokens.spacing.xxxSmall_4,
3369
- width: "auto",
3370
- display: "inline-grid",
3371
- gridArea: "1 / 2",
3372
- ":focus-visible": {
3373
- outline: "none",
3374
- border: "none"
3375
- }
3376
- },
3377
- listbox: {
3378
- backgroundColor: theme.listbox.color.default.background,
3379
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
3380
- border: `solid ${wonderBlocksTokens.border.width.thin} ${theme.listbox.color.default.border}`,
3381
- boxShadow: `0px ${wonderBlocksTokens.spacing.xSmall_8}px ${wonderBlocksTokens.spacing.xSmall_8}px 0px ${wonderBlocksTokens.color.offBlack8}`,
3382
- maxHeight: "var(--popper-max-height)",
3383
- overflowY: "auto"
3384
- },
3385
- hidden: {
3386
- pointerEvents: "none",
3387
- visibility: "hidden"
3388
- },
3389
- button: {
3390
- position: "absolute",
3391
- right: wonderBlocksTokens.spacing.xxxSmall_4,
3392
- top: wonderBlocksTokens.spacing.xxxSmall_4,
3393
- margin: 0
3394
- },
3395
- buttonOpen: {
3396
- transform: "rotate(180deg)"
3397
- },
3398
- clearButton: {
3399
- right: wonderBlocksTokens.spacing.xLarge_32 + wonderBlocksTokens.spacing.xSmall_8
3400
- },
3401
- iconWrapper: {
3402
- padding: wonderBlocksTokens.spacing.xxxSmall_4,
3403
- minWidth: "auto"
3404
- }
3405
- });
113
+ function Combobox({autoComplete,children,disabled,error,id,labels=defaultComboboxLabels,onChange,onToggle,opened,placeholder,selectionType="single",startIcon,testId,value=""}){const generatedUniqueId=React.useId();const uniqueId=id??generatedUniqueId;const comboboxRef=React__namespace.useRef(null);const rootNodeRef=React__namespace.useRef(null);const[open,setOpen]=React__namespace.useState(opened??false);const isControlled=opened!==undefined;const openState=disabled?false:isControlled?opened:open;const[selectedValue,setSelectedValue]=React__namespace.useState(value);const isValueControlled=value!==""&&onChange!==undefined;const valueState=isValueControlled?value:selectedValue;const[currentOptions,setCurrentOptions]=React__namespace.useState(children);const{focusedIndex,isListboxFocused,setFocusedIndex,handleKeyDown,handleFocus,handleBlur,selected,setSelected,renderList}=useListbox({children:currentOptions,disabled,id:uniqueId,onChange:value=>handleChange(value),value:valueState,disableSpaceSelection:true,selectionType});const itemFromSelected=renderList.find(item=>item.props.value===selected)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";const initialValue=typeof value==="string"?labelFromSelected:"";const[inputValue,setInputValue]=React__namespace.useState(initialValue);const{focusedMultiSelectIndex,handleKeyDown:handleMultipleSelectionKeyDown}=useMultipleSelection({inputValue,selected,setSelected});const updateOpenState=React__namespace.useCallback((newState,selectedLabel=labelFromSelected)=>{if(disabled||newState===openState){return}if(!isControlled){setOpen(newState);}if(!newState){setFocusedIndex(-1);if(selectionType==="multiple"){setInputValue("");}else {setInputValue(selectedLabel??"");}setCurrentOptions(children);}onToggle?.(newState);},[children,disabled,isControlled,labelFromSelected,onToggle,openState,selectionType,setFocusedIndex]);const handleChange=React__namespace.useCallback(value=>{if(value!==valueState){setSelectedValue(value);onChange?.(value);}if(selectionType==="single"&&typeof value==="string"){const itemFromSelected=renderList.find(item=>item.props.value===value)?.props;const labelFromSelected=itemFromSelected?getLabel(itemFromSelected):"";updateOpenState(false,labelFromSelected);}else if(Array.isArray(value)){setInputValue("");setCurrentOptions(children);}},[children,onChange,renderList,selectionType,updateOpenState,valueState]);const focusOnFilteredItem=React__namespace.useCallback((filtered,value)=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();const itemIndex=filtered.findIndex(item=>getLabel(item.props).normalize("NFC").toLowerCase().trim().includes(lowercasedSearchText));setFocusedIndex(itemIndex);},[setFocusedIndex]);const filterItems=React__namespace.useCallback(value=>{const lowercasedSearchText=value.normalize("NFC").toLowerCase();return children.filter(item=>getLabel(item.props).normalize("NFC").trim().toLowerCase().indexOf(lowercasedSearchText)>-1)},[children]);const onKeyDown=event=>{const{key}=event;const conditionsToOpen=key==="ArrowDown"||key==="ArrowUp"||key==="Backspace"||key.length===1;if(!openState&&conditionsToOpen){updateOpenState(true);}if(key==="ArrowLeft"||key==="ArrowRight"){setFocusedIndex(-1);}handleMultipleSelectionKeyDown(event);if(key==="Escape"&&openState){event.stopPropagation();updateOpenState(false);}handleKeyDown(event);};const handleOnRemove=React__namespace.useCallback(value=>{const selectedValues=selected;const newValues=selectedValues.filter(selectedValue=>selectedValue!==value);setSelected(newValues);},[selected,setSelected]);const handleTextFieldChange=React__namespace.useCallback(value=>{setInputValue(value);let filteredItems=renderList;if(autoComplete==="list"){filteredItems=filterItems(value);setCurrentOptions(filteredItems);}focusOnFilteredItem(filteredItems,value);},[autoComplete,filterItems,focusOnFilteredItem,renderList]);const handleClearClick=React__namespace.useCallback(e=>{e.stopPropagation();setInputValue("");setSelected("");onChange?.("");comboboxRef.current?.focus();},[onChange,setSelected]);React__namespace.useEffect(()=>{if(openState){comboboxRef.current?.focus();}},[openState]);const selectedLabels=React__namespace.useMemo(()=>{if(Array.isArray(selected)){return selected.map(value=>{const item=children.find(item=>item.props.value===value);return item?getLabel(item?.props):""})}return [labelFromSelected]},[children,labelFromSelected,selected]);const maybeRenderStartIcon=()=>{if(!startIcon){return null}const startIconElement=React__namespace.cloneElement(startIcon,{size:"small",...startIcon.props,color:disabled?wonderBlocksTokens.semanticColor.icon.disabled:startIcon.props.color??wonderBlocksTokens.semanticColor.icon.primary});return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.iconWrapper,children:startIconElement})};const pillIdPrefix=`${uniqueId}-pill-`;const textFieldId=React.useId();const currentActiveDescendant=!openState?undefined:focusedIndex>=0?renderList[focusedIndex]?.props?.id:pillIdPrefix+focusedMultiSelectIndex;const controlledWidget=!openState?undefined:focusedIndex>=0?uniqueId:pillIdPrefix;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(wonderBlocksCore.View,{onClick:()=>{updateOpenState(true);},ref:rootNodeRef,style:[styles.wrapper,isListboxFocused&&styles.focused,disabled&&styles.disabled,!disabled&&error&&styles.error],children:[jsxRuntime.jsx(ComboboxLiveRegion,{focusedIndex:focusedIndex,focusedMultiSelectIndex:focusedMultiSelectIndex,labels:labels,options:renderList,selectedLabels:selectedLabels,testId:testId,opened:openState,selected:selected,selectionType:selectionType}),selectionType==="multiple"&&Array.isArray(selected)&&jsxRuntime.jsx(MultipleSelection,{labels:selectedLabels,focusedMultiSelectIndex:focusedMultiSelectIndex,id:pillIdPrefix,selected:selected,onRemove:handleOnRemove,disabled:disabled,testId:testId,removeSelectedLabel:labels.removeSelected}),maybeRenderStartIcon(),jsxRuntime.jsx(wonderBlocksForm.TextField,{id:textFieldId,testId:testId,style:styles.combobox,value:inputValue,onChange:handleTextFieldChange,disabled:disabled,onFocus:()=>{updateOpenState(true);handleFocus();},placeholder:placeholder,onBlur:()=>{updateOpenState(false);handleBlur();},onKeyDown:onKeyDown,"aria-activedescendant":currentActiveDescendant,"aria-autocomplete":autoComplete,"aria-controls":controlledWidget,"aria-expanded":openState,"aria-invalid":!!error,ref:comboboxRef,autoComplete:"off",role:"combobox"}),inputValue&&!disabled&&jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],onClick:handleClearClick,actionType:"neutral",kind:"tertiary",size:"small",style:[styles.button,styles.clearButton],"aria-label":labels.clearSelection,testId:testId?`${testId}-clear`:undefined}),jsxRuntime.jsx(IconButton__default["default"],{disabled:disabled,icon:caretDownIcon__default$1["default"],onClick:e=>{e.stopPropagation();updateOpenState(!openState);},onMouseDown:e=>{e.preventDefault();},actionType:"neutral",kind:"tertiary",size:"small",style:[styles.button,openState&&styles.buttonOpen],tabIndex:-1,"aria-controls":uniqueId,"aria-expanded":openState,"aria-label":labels.comboboxButton})]}),openState&&jsxRuntime.jsx(DropdownPopper,{alignment:"left",referenceElement:rootNodeRef?.current,children:isReferenceHidden=>jsxRuntime.jsx(jsxRuntime.Fragment,{children:renderList.length===0?jsxRuntime.jsx(wonderBlocksCell.DetailCell,{title:labels.noItems,style:[styles.listbox,{minWidth:rootNodeRef?.current?.offsetWidth}],horizontalRule:"none"}):jsxRuntime.jsx(Listbox,{id:uniqueId,tabIndex:-1,selectionType:selectionType,style:[styles.listbox,isReferenceHidden&&styles.hidden,{minWidth:rootNodeRef?.current?.offsetWidth}],testId:testId?`${testId}-listbox`:undefined,"aria-label":labels.listbox,"aria-labelledby":textFieldId,children:renderList})})})]})}const theme={combobox:{color:{default:{border:wonderBlocksTokens.semanticColor.border.strong,background:wonderBlocksTokens.semanticColor.surface.primary},focus:{border:wonderBlocksTokens.semanticColor.focus.outer,background:wonderBlocksTokens.semanticColor.surface.primary},disabled:{border:wonderBlocksTokens.semanticColor.action.secondary.disabled.border,background:wonderBlocksTokens.semanticColor.action.secondary.disabled.background,foreground:wonderBlocksTokens.semanticColor.action.secondary.disabled.foreground},error:{border:wonderBlocksTokens.semanticColor.status.critical.foreground,background:wonderBlocksTokens.semanticColor.status.critical.background,foreground:wonderBlocksTokens.semanticColor.text.primary}}},listbox:{color:{default:{background:wonderBlocksTokens.semanticColor.surface.primary,border:wonderBlocksTokens.semanticColor.border.primary}}}};const styles=aphrodite.StyleSheet.create({wrapper:{flexDirection:"row",alignItems:"center",width:"100%",maxWidth:"100%",flexWrap:"wrap",background:theme.combobox.color.default.background,borderRadius:wonderBlocksTokens.border.radius.radius_040,border:`solid 1px ${theme.combobox.color.default.border}`,paddingInline:wonderBlocksTokens.spacing.xSmall_8},focused:{background:theme.combobox.color.focus.background,border:`1px solid ${theme.combobox.color.focus.border}`},disabled:{background:theme.combobox.color.disabled.background,border:`1px solid ${theme.combobox.color.disabled.border}`,color:theme.combobox.color.disabled.foreground},error:{background:theme.combobox.color.error.background,border:`1px solid ${theme.combobox.color.error.border}`,color:theme.combobox.color.error.foreground},combobox:{appearance:"none",background:"none",border:"none",outline:"none",padding:0,minWidth:wonderBlocksTokens.spacing.xxxSmall_4,width:"auto",display:"inline-grid",gridArea:"1 / 2",":focus-visible":{outline:"none",border:"none"}},listbox:{backgroundColor:theme.listbox.color.default.background,borderRadius:wonderBlocksTokens.border.radius.radius_040,border:`solid ${wonderBlocksTokens.border.width.thin} ${theme.listbox.color.default.border}`,boxShadow:`0px ${wonderBlocksTokens.spacing.xSmall_8}px ${wonderBlocksTokens.spacing.xSmall_8}px 0px ${wonderBlocksTokens.color.offBlack8}`,maxHeight:"var(--popper-max-height)",overflowY:"auto"},hidden:{pointerEvents:"none",visibility:"hidden"},button:{position:"absolute",right:wonderBlocksTokens.spacing.xxxSmall_4,top:wonderBlocksTokens.spacing.xxxSmall_4,margin:0},buttonOpen:{transform:"rotate(180deg)"},clearButton:{right:wonderBlocksTokens.spacing.xLarge_32+wonderBlocksTokens.spacing.xSmall_8},iconWrapper:{padding:wonderBlocksTokens.spacing.xxxSmall_4,minWidth:"auto"}});
3406
114
 
3407
115
  exports.ActionItem = ActionItem;
3408
116
  exports.ActionMenu = ActionMenu;