playbook_ui 14.15.0.pre.alpha.play1949lodashremoval3of36815 → 14.15.0.pre.alpha.play1952fixhorizontalnavcursorstyle6795

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +4 -3
  3. data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +3 -2
  4. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +0 -67
  5. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +0 -67
  6. data/app/pb_kits/playbook/pb_form/pb_form_validation.js +1 -1
  7. data/app/pb_kits/playbook/pb_icon_button/_icon_button.tsx +1 -4
  8. data/app/pb_kits/playbook/pb_icon_button/docs/example.yml +0 -1
  9. data/app/pb_kits/playbook/pb_icon_button/docs/index.js +0 -1
  10. data/app/pb_kits/playbook/pb_lightbox/hooks/useVisibility.js +1 -1
  11. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +0 -23
  12. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +1 -28
  13. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +0 -4
  14. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -3
  15. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +0 -10
  16. data/app/pb_kits/playbook/pb_typeahead/index.ts +2 -2
  17. data/app/pb_kits/playbook/utilities/globalProps.ts +1 -1
  18. data/app/pb_kits/playbook/utilities/object.test.js +1 -149
  19. data/app/pb_kits/playbook/utilities/object.ts +42 -124
  20. data/dist/chunks/_typeahead-CVryXNui.js +22 -0
  21. data/dist/chunks/_weekday_stacked-BGcc0MlV.js +45 -0
  22. data/dist/chunks/{lib-DpO_YjaF.js → lib-Co5y3V4K.js} +3 -3
  23. data/dist/chunks/{pb_form_validation-C3rQtNR-.js → pb_form_validation-DMajaRt3.js} +1 -1
  24. data/dist/chunks/vendor.js +1 -1
  25. data/dist/playbook-doc.js +1 -1
  26. data/dist/playbook-rails-react-bindings.js +1 -1
  27. data/dist/playbook-rails.js +1 -1
  28. data/dist/playbook.css +1 -1
  29. data/lib/playbook/forms/builder/multi_level_select_field.rb +0 -2
  30. data/lib/playbook/version.rb +1 -1
  31. metadata +6 -12
  32. data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_click.jsx +0 -13
  33. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.html.erb +0 -72
  34. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.jsx +0 -97
  35. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +0 -71
  36. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +0 -91
  37. data/app/pb_kits/playbook/pb_multi_level_select/index.js +0 -105
  38. data/dist/chunks/_typeahead-DZNrDsCe.js +0 -22
  39. data/dist/chunks/_weekday_stacked-BwM21XCO.js +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00c74c07957b56cf1da4de814303ddc2a8ddd7632aac68fff9e7d4cdd3cbf203
4
- data.tar.gz: f27e1e2692df72b86d23da070e3ca4e78c98ec266d451f2ef31267946da5c524
3
+ metadata.gz: c8462d011ee01fbc2e1dcbcc3da414e4c97080fd50b0fca45cbdaa02e39015a4
4
+ data.tar.gz: 1ca28020da66e69a5262d5817ab9a827f82586f861ffeb2657d939fe1e0335a7
5
5
  SHA512:
6
- metadata.gz: 97b42f8f769cd29673a57688f2f0fff0ae8894242137f0966b267f33098b0b7b6d934f4ae59302d0c3bb502f05b21e52a95fbb49072ad0a763eb5a6b571ca21e
7
- data.tar.gz: 00fa01e72545d9ce4edadee984709233526e7279fce642627d9e89dfff0de4b3488013685ed0744ece60475eee2250160a9b44eead8f65169227d7d7b21c9709
6
+ metadata.gz: 6cdcb36480d01c4657d5dcc7614a39b8d4f068c5122242d2eea84e189216cc146fb14ba5c17d0a9716211284fb542c15c6a4a9902274236f2623a0a9cc46b1b0
7
+ data.tar.gz: 6f2d7d27c882350ea27cf7c31dac83c82b029b32e54511f0783b85d3279be6314eb19253a9e3680d81cf5f0b7112c25f78b593dfa9c686a284148616dbfc0db2
@@ -1,5 +1,6 @@
1
1
  import React from 'react'
2
- import { isEmpty, omitBy, map } from '../../utilities/object'
2
+ import { map } from 'lodash'
3
+ import { isEmpty, omitBy } from '../../utilities/object'
3
4
 
4
5
  import Body from '../../pb_body/_body'
5
6
  import Caption from '../../pb_caption/_caption'
@@ -45,12 +46,12 @@ const CurrentFilters = ({ dark, filters }: CurrentFiltersProps): React.ReactElem
45
46
  dark={dark}
46
47
  size={4}
47
48
  tag="h4"
48
- text={`${name}`}
49
+ text={name}
49
50
  /> :
50
51
  <div>
51
52
  <Caption
52
53
  dark={dark}
53
- text={`${name}`}
54
+ text={name}
54
55
  />
55
56
  <Title
56
57
  dark={dark}
@@ -1,5 +1,6 @@
1
1
  import React, { useState } from 'react'
2
- import { find, partial, map } from '../../utilities/object'
2
+ import { map } from 'lodash'
3
+ import { find, partial } from '../../utilities/object'
3
4
 
4
5
  import Button from '../../pb_button/_button'
5
6
  import Icon from '../../pb_icon/_icon'
@@ -26,7 +27,7 @@ const directionIcon = (dir: Direction) => (
26
27
 
27
28
  const renderOptions = (options: SortOptions, value: SortValue[], handleChange: (arg0: SortValue) => void) => (
28
29
  map(options, (label, name) => {
29
- const next = nextValue(value, String(name))
30
+ const next = nextValue(value, name)
30
31
  return (
31
32
  <ListItem key={`option-${next.name}-${next.dir}`}>
32
33
  <Button
@@ -22,72 +22,6 @@
22
22
 
23
23
  %>
24
24
 
25
- <% treeData = [{
26
- label: "Power Home Remodeling",
27
- value: "Power Home Remodeling",
28
- id: "100",
29
- expanded: true,
30
- children: [
31
- {
32
- label: "People",
33
- value: "People",
34
- id: "101",
35
- expanded: true,
36
- children: [
37
- {
38
- label: "Talent Acquisition",
39
- value: "Talent Acquisition",
40
- id: "102",
41
- },
42
- {
43
- label: "Business Affairs",
44
- value: "Business Affairs",
45
- id: "103",
46
- children: [
47
- {
48
- label: "Initiatives",
49
- value: "Initiatives",
50
- id: "104",
51
- },
52
- {
53
- label: "Learning & Development",
54
- value: "Learning & Development",
55
- id: "105",
56
- },
57
- ],
58
- },
59
- {
60
- label: "People Experience",
61
- value: "People Experience",
62
- id: "106",
63
- },
64
- ],
65
- },
66
- {
67
- label: "Contact Center",
68
- value: "Contact Center",
69
- id: "107",
70
- children: [
71
- {
72
- label: "Appointment Management",
73
- value: "Appointment Management",
74
- id: "108",
75
- },
76
- {
77
- label: "Customer Service",
78
- value: "Customer Service",
79
- id: "109",
80
- },
81
- {
82
- label: "Energy",
83
- value: "Energy",
84
- id: "110",
85
- },
86
- ],
87
- },
88
- ],
89
- }] %>
90
-
91
25
  <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
92
26
  <%= form.typeahead :example_typeahead, props: { data: { typeahead_example1: true, user: {} }, label: true, placeholder: "Search for a user" } %>
93
27
  <%= form.text_field :example_text_field, props: { label: true } %>
@@ -113,7 +47,6 @@
113
47
  <%= form.date_picker :example_date_picker_1, props: { label: true } %>
114
48
  <%= form.star_rating_field :example_star_rating, props: { variant: "interactive", label: true } %>
115
49
  <%= form.time_zone_select_field :example_time_zone_select, ActiveSupport::TimeZone.us_zones, { default: "Eastern Time (US & Canada)" }, props: { label: true } %>
116
- <%= form.multi_level_select :example_multi_level_select, props: { id: "multi-level-select-form-default", tree_data: treeData, margin_bottom: "sm", label: "Example Multi Level Select field" } %>
117
50
 
118
51
  <%= form.actions do |action| %>
119
52
  <%= action.submit %>
@@ -21,72 +21,6 @@
21
21
  ]
22
22
  %>
23
23
 
24
- <% treeData = [{
25
- label: "Power Home Remodeling",
26
- value: "Power Home Remodeling",
27
- id: "100",
28
- expanded: true,
29
- children: [
30
- {
31
- label: "People",
32
- value: "People",
33
- id: "101",
34
- expanded: true,
35
- children: [
36
- {
37
- label: "Talent Acquisition",
38
- value: "Talent Acquisition",
39
- id: "102",
40
- },
41
- {
42
- label: "Business Affairs",
43
- value: "Business Affairs",
44
- id: "103",
45
- children: [
46
- {
47
- label: "Initiatives",
48
- value: "Initiatives",
49
- id: "104",
50
- },
51
- {
52
- label: "Learning & Development",
53
- value: "Learning & Development",
54
- id: "105",
55
- },
56
- ],
57
- },
58
- {
59
- label: "People Experience",
60
- value: "People Experience",
61
- id: "106",
62
- },
63
- ],
64
- },
65
- {
66
- label: "Contact Center",
67
- value: "Contact Center",
68
- id: "107",
69
- children: [
70
- {
71
- label: "Appointment Management",
72
- value: "Appointment Management",
73
- id: "108",
74
- },
75
- {
76
- label: "Customer Service",
77
- value: "Customer Service",
78
- id: "109",
79
- },
80
- {
81
- label: "Energy",
82
- value: "Energy",
83
- id: "110",
84
- },
85
- ],
86
- },
87
- ],
88
- }] %>
89
-
90
24
  <%= pb_form_with(scope: :example, method: :get, url: "", validate: true) do |form| %>
91
25
  <%= form.typeahead :example_typeahead_validation, props: { data: { typeahead_example2: true, user: {} }, label: true, placeholder: "Search for a user", required: true, validation: { message: "Please select a user." } } %>
92
26
  <%= form.text_field :example_text_field_validation, props: { label: true, required: true } %>
@@ -104,7 +38,6 @@
104
38
  <%= form.date_picker :example_date_picker_2, props: { label: true, required: true, validation_message: "Please, select a date.", allow_input: true } %>
105
39
  <%= form.star_rating_field :example_star_rating_validation, props: { variant: "interactive", label: true, required: true } %>
106
40
  <%= form.time_zone_select_field :example_time_zone_select, ActiveSupport::TimeZone.us_zones, { default: "Eastern Time (US & Canada)" }, props: { label: true, blank_selection: "Select a Time Zone...", required: true } %>
107
- <%= form.multi_level_select :example_multi_level_select, props: { id: "multi-level-select-form", tree_data: treeData, margin_bottom: "sm", required: true, label: "Example Multi Level Select field" } %>
108
41
 
109
42
  <%= form.actions do |action| %>
110
43
  <%= action.submit %>
@@ -1,5 +1,5 @@
1
1
  import PbEnhancedElement from '../pb_enhanced_element'
2
- import { debounce } from '../utilities/object'
2
+ import { debounce } from 'lodash'
3
3
 
4
4
  // Kit selectors
5
5
  const KIT_SELECTOR = '[class^="pb_"][class*="_kit"]'
@@ -1,7 +1,7 @@
1
1
 
2
2
  import React from 'react'
3
3
  import classnames from 'classnames'
4
- import { buildAriaProps, buildCss, buildDataProps, noop } from '../utilities/props'
4
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
5
5
  import { globalProps } from '../utilities/globalProps'
6
6
 
7
7
  import Button from '../pb_button/_button'
@@ -17,7 +17,6 @@ type IconButtonProps = {
17
17
  id?: string,
18
18
  link?: string,
19
19
  newWindow?: boolean,
20
- onClick?: React.MouseEventHandler<HTMLElement>,
21
20
  size?: IconSizes,
22
21
  target?: string,
23
22
  variant?: 'default' | 'link',
@@ -33,7 +32,6 @@ const IconButton = (props: IconButtonProps) => {
33
32
  id,
34
33
  link,
35
34
  newWindow = false,
36
- onClick = noop,
37
35
  size = "2x",
38
36
  target,
39
37
  variant = "default",
@@ -55,7 +53,6 @@ const IconButton = (props: IconButtonProps) => {
55
53
  htmlType={htmlType}
56
54
  link={link}
57
55
  newWindow={newWindow}
58
- onClick={onClick}
59
56
  target={target}
60
57
  >
61
58
  <Icon
@@ -7,4 +7,3 @@ examples:
7
7
  react:
8
8
  - icon_button_default: Default
9
9
  - icon_button_sizes: Sizes
10
- - icon_button_click: Click Handler
@@ -1,3 +1,2 @@
1
1
  export { default as IconButtonDefault } from './_icon_button_default.jsx'
2
2
  export { default as IconButtonSizes } from './_icon_button_sizes.jsx'
3
- export { default as IconButtonClick } from './_icon_button_click.jsx'
@@ -1,4 +1,4 @@
1
- import { debounce } from "../../utilities/object"
1
+ import { debounce } from 'lodash'
2
2
  import { useCallback, useMemo, useState } from 'react'
3
3
 
4
4
  export default function useVisibility(initialState = false) {
@@ -10,16 +10,6 @@
10
10
  .pb_multi_level_select {
11
11
  font-family: $font-family-base;
12
12
 
13
- &.error {
14
- .wrapper {
15
- .input_wrapper {
16
- border-color: $error;
17
- }
18
- }
19
- [class*=pb_body_kit_negative] {
20
- margin-top: $space_xxs;
21
- }
22
- }
23
13
  .wrapper {
24
14
  position: relative;
25
15
 
@@ -102,17 +92,4 @@
102
92
  .open {
103
93
  display: block;
104
94
  }
105
-
106
- &.dark {
107
- &.error {
108
- .wrapper {
109
- .input_wrapper {
110
- border-color: $error_dark;
111
- }
112
- }
113
- [class*=pb_body_kit_negative] {
114
- color: $error_dark;
115
- }
116
- }
117
- }
118
95
  }
@@ -7,12 +7,9 @@ import {
7
7
  buildDataProps,
8
8
  buildHtmlProps,
9
9
  } from "../utilities/props";
10
- import { cloneDeep } from "../utilities/object";
11
-
12
10
  import Icon from "../pb_icon/_icon";
13
11
  import FormPill from "../pb_form_pill/_form_pill";
14
- import Body from "../pb_body/_body";
15
- import Caption from "../pb_caption/_caption";
12
+ import { cloneDeep } from "lodash";
16
13
  import MultiLevelSelectOptions from "./multi_level_select_options";
17
14
  import MultiLevelSelectContext from "./context";
18
15
 
@@ -38,14 +35,11 @@ type MultiLevelSelectProps = {
38
35
  className?: string
39
36
  data?: { [key: string]: string }
40
37
  disabled?: boolean
41
- error?: string
42
38
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
43
39
  id?: string
44
40
  inputDisplay?: "pills" | "none"
45
41
  inputName?: string
46
- label?: string
47
42
  name?: string
48
- required?: boolean
49
43
  returnAllSelected?: boolean
50
44
  treeData?: { [key: string]: string; }[] | any
51
45
  onChange?: (event: { target: { name?: string; value: any } }) => void
@@ -62,14 +56,11 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
62
56
  className,
63
57
  data = {},
64
58
  disabled = false,
65
- error,
66
59
  htmlOptions = {},
67
60
  id,
68
61
  inputDisplay = "pills",
69
62
  inputName,
70
63
  name,
71
- label,
72
- required = false,
73
64
  returnAllSelected = false,
74
65
  treeData,
75
66
  onChange = () => null,
@@ -86,7 +77,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
86
77
  const htmlProps = buildHtmlProps(htmlOptions);
87
78
  const classes = classnames(
88
79
  buildCss("pb_multi_level_select"),
89
- error && "error",
90
80
  globalProps(props),
91
81
  className
92
82
  );
@@ -449,12 +439,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
449
439
  className={classes}
450
440
  id={id}
451
441
  >
452
- {label &&
453
- <Caption
454
- marginBottom="xs"
455
- text={label}
456
- />
457
- }
458
442
  <MultiLevelSelectContext.Provider value={{
459
443
  variant,
460
444
  inputName,
@@ -478,7 +462,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
478
462
  disabled={disabled}
479
463
  key={selectedItem.id}
480
464
  name={`${name}[]`}
481
- required={required}
482
465
  type="hidden"
483
466
  value={selectedItem.id}
484
467
  />
@@ -493,7 +476,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
493
476
  disabled={disabled}
494
477
  key={item.id}
495
478
  name={`${name}[]`}
496
- required={required}
497
479
  type="hidden"
498
480
  value={item.id}
499
481
  />
@@ -506,7 +488,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
506
488
  disabled={disabled}
507
489
  key={item.id}
508
490
  name={`${name}[]`}
509
- required={required}
510
491
  type="hidden"
511
492
  value={item.id}
512
493
  />
@@ -567,7 +548,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
567
548
  } selected`
568
549
  : "Start typing..."
569
550
  }
570
- required={required}
571
551
  value={singleSelectedItem.value || filterItem}
572
552
  />
573
553
  </div>
@@ -600,13 +580,6 @@ const MultiLevelSelect = forwardRef<HTMLInputElement, MultiLevelSelectProps>((pr
600
580
  </div>
601
581
  </div>
602
582
  </MultiLevelSelectContext.Provider>
603
- {error &&
604
- <Body
605
- dark={props.dark}
606
- status="negative"
607
- text={error}
608
- />
609
- }
610
583
  </div>
611
584
  );
612
585
  }) as MultiLevelSelectComponent;
@@ -8,8 +8,6 @@ examples:
8
8
  - multi_level_select_with_form: With Form
9
9
  - multi_level_select_color: With Pills (Custom Color)
10
10
  - multi_level_select_reset: Reset Selection
11
- - multi_level_select_label: With Label
12
- - multi_level_select_error: Error
13
11
  - multi_level_select_disabled: Disabled Input
14
12
  - multi_level_select_disabled_options_default: Disabled Options (Default)
15
13
  - multi_level_select_disabled_options: Disabled Options (Return All Selected)
@@ -26,8 +24,6 @@ examples:
26
24
  - multi_level_select_color: With Pills (Custom Color)
27
25
  - multi_level_select_with_children: Checkboxes With Children
28
26
  - multi_level_select_with_children_with_radios: Single Select With Children
29
- - multi_level_select_label: With Label
30
- - multi_level_select_error: Error
31
27
  - multi_level_select_disabled: Disabled Input
32
28
  - multi_level_select_disabled_options_default: Disabled Options (Default)
33
29
  - multi_level_select_disabled_options: Disabled Options (Return All Selected)
@@ -8,9 +8,7 @@ export { default as MultiLevelSelectWithChildren } from './_multi_level_select_w
8
8
  export { default as MultiLevelSelectWithChildrenWithRadios } from './_multi_level_select_with_children_with_radios.jsx'
9
9
  export { default as MultiLevelSelectDisabled } from './_multi_level_select_disabled.jsx'
10
10
  export { default as MultiLevelSelectReactHook } from './_multi_level_select_react_hook.jsx'
11
- export { default as MultiLevelSelectError } from './_multi_level_select_error.jsx'
12
11
  export { default as MultiLevelSelectDisabledOptions } from './_multi_level_select_disabled_options.jsx'
13
12
  export { default as MultiLevelSelectDisabledOptionsParent } from './_multi_level_select_disabled_options_parent.jsx'
14
13
  export { default as MultiLevelSelectDisabledOptionsParentDefault } from './_multi_level_select_disabled_options_parent_default.jsx'
15
- export { default as MultiLevelSelectDisabledOptionsDefault } from './_multi_level_select_disabled_options_default.jsx'
16
- export { default as MultiLevelSelectLabel } from './_multi_level_select_label.jsx'
14
+ export { default as MultiLevelSelectDisabledOptionsDefault } from './_multi_level_select_disabled_options_default.jsx'
@@ -26,12 +26,6 @@ module Playbook
26
26
  default: false
27
27
  prop :disabled, type: Playbook::Props::Boolean,
28
28
  default: false
29
- prop :required, type: Playbook::Props::Boolean,
30
- default: false
31
- prop :error, type: Playbook::Props::String,
32
- default: ""
33
- prop :label, type: Playbook::Props::String,
34
- default: ""
35
29
 
36
30
  def classname
37
31
  generate_classname("pb_multi_level_select")
@@ -39,15 +33,11 @@ module Playbook
39
33
 
40
34
  def multi_level_select_options
41
35
  {
42
- data: data,
43
36
  disabled: disabled,
44
- error: error,
45
37
  id: id,
46
38
  inputDisplay: input_display,
47
39
  name: name,
48
- label: label,
49
40
  treeData: tree_data,
50
- required: required,
51
41
  returnAllSelected: return_all_selected,
52
42
  selectedIds: selected_ids,
53
43
  inputName: input_name,
@@ -1,5 +1,5 @@
1
1
  import PbEnhancedElement from '../pb_enhanced_element'
2
- import { debounce } from '../utilities/object'
2
+ import { debounce } from 'lodash'
3
3
 
4
4
  export default class PbTypeahead extends PbEnhancedElement {
5
5
  _searchInput: HTMLInputElement
@@ -284,4 +284,4 @@ export default class PbTypeahead extends PbEnhancedElement {
284
284
  if (visible) visibilityProperty = '1'
285
285
  this.resultsLoadingIndicator.style.opacity = visibilityProperty
286
286
  }
287
- }
287
+ }
@@ -1,4 +1,4 @@
1
- import { omit } from './object'
1
+ import { omit } from 'lodash'
2
2
  import { camelToSnakeCase } from './text'
3
3
 
4
4
  import {
@@ -1,4 +1,4 @@
1
- import { isEmpty, get, isString, uniqueId, omitBy, noop, merge, filter, find, partial, map, cloneDeep, omit, debounce } from './object';
1
+ import { isEmpty, get, isString, uniqueId, omitBy, noop, merge, filter, find, partial } from './object';
2
2
 
3
3
  describe('Lodash functions', () => {
4
4
  describe('isEmpty', () => {
@@ -234,152 +234,4 @@ describe('Lodash functions', () => {
234
234
  expect(joinPartial('b', 'c')).toBe('a_b_c');
235
235
  });
236
236
  });
237
-
238
- describe('map', () => {
239
- test('maps over an array with a function iteratee', () => {
240
- const arr = [1, 2, 3];
241
- const result = map(arr, (num) => num * 2);
242
- expect(result).toEqual([2, 4, 6]);
243
- });
244
-
245
- test('maps over an array with a string iteratee', () => {
246
- const arr = [{ value: 1 }, { value: 2 }, { value: 3 }];
247
- const result = map(arr, 'value');
248
- expect(result).toEqual([1, 2, 3]);
249
- });
250
-
251
- test('maps over an object with a function iteratee', () => {
252
- const obj = { a: 1, b: 2, c: 3 };
253
- const result = map(obj, (val, key) => key + val);
254
- expect(result.sort()).toEqual(['a1', 'b2', 'c3'].sort());
255
- });
256
-
257
- test('maps over an object with a string iteratee', () => {
258
- const obj = {
259
- one: { num: 1 },
260
- two: { num: 2 },
261
- three: { num: 3 },
262
- };
263
- const result = map(obj, 'num');
264
- expect(result.sort()).toEqual([1, 2, 3].sort());
265
- });
266
-
267
- test('returns original values if no iteratee provided', () => {
268
- const arr = [1, 2, 3];
269
- const result = map(arr);
270
- expect(result).toEqual([1, 2, 3]);
271
- });
272
- });
273
-
274
- describe('cloneDeep', () => {
275
- test('clones primitive values', () => {
276
- expect(cloneDeep(42)).toBe(42);
277
- expect(cloneDeep('test')).toBe('test');
278
- expect(cloneDeep(null)).toBe(null);
279
- });
280
-
281
- test('clones arrays deeply', () => {
282
- const arr = [1, [2, 3]];
283
- const cloned = cloneDeep(arr);
284
- expect(cloned).toEqual(arr);
285
- cloned[1][0] = 99;
286
- expect(arr[1][0]).toBe(2);
287
- });
288
-
289
- test('clones objects deeply', () => {
290
- const obj = { a: { b: 2 } };
291
- const cloned = cloneDeep(obj);
292
- expect(cloned).toEqual(obj);
293
- cloned.a.b = 99;
294
- expect(obj.a.b).toBe(2);
295
- });
296
-
297
- test('clones Date objects', () => {
298
- const date = new Date();
299
- const cloned = cloneDeep(date);
300
- expect(cloned).not.toBe(date);
301
- expect(cloned.getTime()).toBe(date.getTime());
302
- });
303
-
304
- test('clones RegExp objects', () => {
305
- const regex = /test/gi;
306
- const cloned = cloneDeep(regex);
307
- expect(cloned).not.toBe(regex);
308
- expect(cloned.source).toBe(regex.source);
309
- expect(cloned.flags).toBe(regex.flags);
310
- });
311
- });
312
-
313
- describe('omit', () => {
314
- test('omits specified keys from object', () => {
315
- const obj = { a: 1, b: 2, c: 3 };
316
- expect(omit(obj, 'a', 'c')).toEqual({ b: 2 });
317
- });
318
-
319
- test('supports array of keys to omit', () => {
320
- const obj = { a: 1, b: 2, c: 3 };
321
- expect(omit(obj, ['b'])).toEqual({ a: 1, c: 3 });
322
- });
323
-
324
- test('returns empty object for null or non-object input', () => {
325
- expect(omit(null, 'a')).toEqual({});
326
- expect(omit("string", 'a')).toEqual({});
327
- });
328
-
329
- test('returns original object if no keys match', () => {
330
- const obj = { a: 1, b: 2 };
331
- expect(omit(obj, 'c')).toEqual({ a: 1, b: 2 });
332
- });
333
- });
334
-
335
- describe('debounce', () => {
336
- beforeEach(() => {
337
- jest.useFakeTimers();
338
- });
339
-
340
- afterEach(() => {
341
- jest.useRealTimers();
342
- });
343
-
344
- test('delays execution until wait time has passed', () => {
345
- const func = jest.fn();
346
- const debounced = debounce(func, 1000);
347
- debounced();
348
- expect(func).not.toHaveBeenCalled();
349
- jest.advanceTimersByTime(500);
350
- expect(func).not.toHaveBeenCalled();
351
- jest.advanceTimersByTime(500);
352
- expect(func).toHaveBeenCalledTimes(1);
353
- });
354
-
355
- test('calls function only once when called repeatedly', () => {
356
- const func = jest.fn();
357
- const debounced = debounce(func, 1000);
358
- debounced();
359
- debounced();
360
- debounced();
361
- jest.advanceTimersByTime(1000);
362
- expect(func).toHaveBeenCalledTimes(1);
363
- });
364
-
365
- test('immediate option calls function on first call', () => {
366
- const func = jest.fn();
367
- const debounced = debounce(func, 1000, true);
368
- debounced();
369
- expect(func).toHaveBeenCalledTimes(1);
370
- debounced();
371
- debounced();
372
- jest.advanceTimersByTime(1000);
373
- expect(func).toHaveBeenCalledTimes(1);
374
- });
375
-
376
- test('subsequent call after wait period works with immediate option', () => {
377
- const func = jest.fn();
378
- const debounced = debounce(func, 1000, true);
379
- debounced();
380
- jest.advanceTimersByTime(1100);
381
- debounced();
382
- expect(func).toHaveBeenCalledTimes(2);
383
- });
384
- });
385
237
  });