playbook_ui 14.14.0.pre.alpha.play1853typeaheadreacthookform6373 → 14.14.0.pre.alpha.play1868dependencyremovallodash6413

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_card/_card.tsx +2 -1
  3. data/app/pb_kits/playbook/pb_drawer/_drawer.scss +32 -8
  4. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_behavior.html.erb +8 -0
  5. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.html.erb +33 -0
  6. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.html.erb +0 -0
  7. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.html.erb +20 -1
  8. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.html.erb +24 -0
  9. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.html.erb +21 -0
  10. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.md +1 -0
  11. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_sizes.html.erb +49 -0
  12. data/app/pb_kits/playbook/pb_drawer/docs/example.yml +5 -0
  13. data/app/pb_kits/playbook/pb_drawer/drawer.html.erb +20 -12
  14. data/app/pb_kits/playbook/pb_drawer/drawer.rb +49 -1
  15. data/app/pb_kits/playbook/pb_drawer/index.js +257 -0
  16. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +5 -4
  17. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.tsx +2 -2
  18. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
  19. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.html.erb +11 -0
  20. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.md +1 -0
  21. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +1 -0
  22. data/app/pb_kits/playbook/pb_overlay/index.js +61 -0
  23. data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +5 -3
  24. data/app/pb_kits/playbook/pb_overlay/overlay.rb +9 -0
  25. data/app/pb_kits/playbook/pb_popover/_popover.tsx +1 -1
  26. data/app/pb_kits/playbook/pb_select/index.js +38 -0
  27. data/app/pb_kits/playbook/pb_select/select.rb +8 -0
  28. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +0 -3
  29. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.html.erb +39 -0
  30. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.md +3 -0
  31. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_interaction.html.erb +26 -0
  32. data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +2 -0
  33. data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +282 -0
  34. data/app/pb_kits/playbook/pb_tooltip/index.js +1 -1
  35. data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +10 -2
  36. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +6 -10
  37. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +0 -1
  38. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +0 -1
  39. data/app/pb_kits/playbook/utilities/object.test.js +99 -0
  40. data/app/pb_kits/playbook/utilities/object.ts +29 -1
  41. data/dist/chunks/_typeahead-Dd8gkRY2.js +36 -0
  42. data/dist/chunks/_weekday_stacked-bhqmtN2l.js +45 -0
  43. data/dist/chunks/{lib-D3us1bGD.js → lib-Dzh-65PP.js} +2 -2
  44. data/dist/chunks/{pb_form_validation-BpihMSOQ.js → pb_form_validation-1T09rwCG.js} +1 -1
  45. data/dist/chunks/vendor.js +1 -1
  46. data/dist/menu.yml +2 -2
  47. data/dist/playbook-doc.js +1 -1
  48. data/dist/playbook-rails-react-bindings.js +1 -1
  49. data/dist/playbook-rails.js +1 -1
  50. data/dist/playbook.css +1 -1
  51. data/lib/playbook/version.rb +1 -1
  52. metadata +23 -8
  53. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.jsx +0 -66
  54. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.md +0 -1
  55. data/dist/chunks/_typeahead-B0mEqUUF.js +0 -36
  56. data/dist/chunks/_weekday_stacked-77oCRlb0.js +0 -45
@@ -1,9 +1,10 @@
1
- import React, { forwardRef } from 'react'
1
+ import React from 'react'
2
2
  import Select from 'react-select'
3
3
  import AsyncSelect from 'react-select/async'
4
4
  import CreateableSelect from 'react-select/creatable'
5
5
  import AsyncCreateableSelect from 'react-select/async-creatable'
6
- import { get, isString, uniqueId } from 'lodash'
6
+ import { get, isString, uniqueId } from '../utilities/object'
7
+
7
8
  import { globalProps, GlobalProps } from '../utilities/globalProps'
8
9
  import classnames from 'classnames'
9
10
 
@@ -47,7 +48,6 @@ type TypeaheadProps = {
47
48
  name?: string,
48
49
  marginBottom?: "none" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl",
49
50
  pillColor?: "primary" | "neutral" | "success" | "warning" | "error" | "info" | "data_1" | "data_2" | "data_3" | "data_4" | "data_5" | "data_6" | "data_7" | "data_8" | "windows" | "siding" | "roofing" | "doors" | "gutters" | "solar" | "insulation" | "accessories",
50
- onChange?: (event: React.FormEvent<HTMLInputElement> | null) => void,
51
51
  } & GlobalProps
52
52
 
53
53
  export type SelectValueType = {
@@ -67,7 +67,8 @@ type TagOnChangeValues = {
67
67
  * @constant {React.ReactComponent} Typeahead
68
68
  * @param {TypeaheadProps} props - props as described at https://react-select.com/props
69
69
  */
70
- const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
70
+
71
+ const Typeahead = ({
71
72
  async,
72
73
  className,
73
74
  components = {},
@@ -78,11 +79,9 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
78
79
  getOptionValue,
79
80
  htmlOptions = {},
80
81
  id,
81
- name,
82
82
  loadOptions = noop,
83
83
  marginBottom = "sm",
84
84
  pillColor,
85
- onChange = () => { void 0 },
86
85
  ...props
87
86
  }: TypeaheadProps) => {
88
87
  const selectProps = {
@@ -124,8 +123,6 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
124
123
  )
125
124
 
126
125
  const handleOnChange = (_data: SelectValueType, { action, option, removedValue }: TagOnChangeValues) => {
127
- onChange({ target: { name: name, value: _data } } as unknown as React.ChangeEvent<HTMLInputElement>)
128
-
129
126
  if (action === 'select-option') {
130
127
  if (selectProps.onMultiValueClick) selectProps.onMultiValueClick(option)
131
128
  const multiValueClearEvent = new CustomEvent(`pb-typeahead-kit-${selectProps.id}-result-option-select`, { detail: option ? option : _data })
@@ -169,11 +166,10 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
169
166
  />
170
167
  </div>
171
168
  )
172
- })
169
+ }
173
170
 
174
171
  Object.keys(kitComponents).forEach((k) => {
175
172
  (Typeahead as GenericObject)[k] = (kitComponents as {[key: string]: unknown})[k]
176
173
  })
177
174
 
178
- Typeahead.displayName = 'Typeahead'
179
175
  export default Typeahead
@@ -15,7 +15,6 @@ examples:
15
15
 
16
16
  react:
17
17
  - typeahead_default: Default
18
- - typeahead_react_hook: React Hook
19
18
  - typeahead_with_highlight: With Highlight
20
19
  - typeahead_with_pills: With Pills
21
20
  - typeahead_with_pills_async: With Pills (Async Data)
@@ -13,4 +13,3 @@ export { default as TypeaheadCustomMenuList } from './_typeahead_custom_menu_lis
13
13
  export { default as TypeaheadMarginBottom } from './_typeahead_margin_bottom.jsx'
14
14
  export { default as TypeaheadWithPillsColor } from './_typeahead_with_pills_color.jsx'
15
15
  export { default as TypeaheadTruncatedText } from './_typeahead_truncated_text.jsx'
16
- export { default as TypeaheadReactHook } from './_typeahead_react_hook.jsx'
@@ -0,0 +1,99 @@
1
+ import { isEmpty, get, isString, uniqueId, omitBy } from './object';
2
+
3
+ describe('Lodash functions', () => {
4
+ describe('isEmpty', () => {
5
+ test('returns true for empty objects', () => {
6
+ expect(isEmpty({})).toBe(true);
7
+ });
8
+ test('returns true for empty arrays', () => {
9
+ expect(isEmpty([])).toBe(true);
10
+ });
11
+ test('returns false for non-empty objects', () => {
12
+ expect(isEmpty({ a: 1 })).toBe(false);
13
+ });
14
+ test('returns false for non-empty arrays', () => {
15
+ expect(isEmpty([1])).toBe(false);
16
+ });
17
+ test('returns true for null and undefined', () => {
18
+ expect(isEmpty(null)).toBe(true);
19
+ expect(isEmpty(undefined)).toBe(true);
20
+ });
21
+ test('returns false for non-object, non-array values', () => {
22
+ expect(isEmpty("hello")).toBe(false);
23
+ expect(isEmpty(123)).toBe(false);
24
+ });
25
+ });
26
+
27
+ describe('get', () => {
28
+ const obj = { a: { b: { c: 42 } }, arr: [{ x: 1 }, { y: 2 }] };
29
+
30
+ test('retrieves nested properties by dot path', () => {
31
+ expect(get(obj, 'a.b.c')).toBe(42);
32
+ });
33
+ test('returns default value if path does not exist', () => {
34
+ expect(get(obj, 'a.b.d', 'default')).toBe('default');
35
+ });
36
+ test('retrieves array values using bracket notation', () => {
37
+ expect(get(obj, 'arr[1].y')).toBe(2);
38
+ });
39
+ test('returns default for non-existent paths', () => {
40
+ expect(get(obj, 'non.existent.path', null)).toBe(null);
41
+ });
42
+ });
43
+
44
+ describe('isString', () => {
45
+ test('returns true for string literal', () => {
46
+ expect(isString('test')).toBe(true);
47
+ });
48
+ test('returns true for String object', () => {
49
+ expect(isString(new String('test'))).toBe(true);
50
+ });
51
+ test('returns false for non-string values', () => {
52
+ expect(isString(123)).toBe(false);
53
+ expect(isString(null)).toBe(false);
54
+ expect(isString({ a: 1 })).toBe(false);
55
+ expect(isString([ 'a','b','c' ])).toBe(false);
56
+ });
57
+ });
58
+
59
+ describe('uniqueId', () => {
60
+ test('generates unique ids without prefix', () => {
61
+ const id1 = uniqueId();
62
+ const id2 = uniqueId();
63
+ expect(id1).not.toBe(id2);
64
+ expect(Number(id1)).toBeLessThan(Number(id2));
65
+ });
66
+ test('generates unique ids with prefix', () => {
67
+ const id1 = uniqueId('id_');
68
+ const id2 = uniqueId('id_');
69
+ const id3 = uniqueId('id_');
70
+ expect(id1).not.toBe(id2);
71
+ expect(id1).not.toBe(id3);
72
+ expect(id2).not.toBe(id3);
73
+ expect(id1.startsWith('id_')).toBe(true);
74
+ expect(id2.startsWith('id_')).toBe(true);
75
+ expect(id3.startsWith('id_')).toBe(true);
76
+ });
77
+ });
78
+
79
+ describe('omitBy', () => {
80
+ test('omits keys for which predicate returns true', () => {
81
+ const obj = { a: 1, b: 2, c: 3 };
82
+ const isEven = value => value % 2 === 0;
83
+ const noEvenValues = omitBy(obj, isEven);
84
+ expect(noEvenValues).toEqual({ a: 1, c: 3 });
85
+ });
86
+ test('returns empty object for null input', () => {
87
+ expect(omitBy(null, () => true)).toEqual({});
88
+ });
89
+ test('returns empty object for non-object input', () => {
90
+ expect(omitBy("string", () => true)).toEqual({});
91
+ });
92
+ test('returns original object if predicate returns false for all keys', () => {
93
+ const obj = { a: 1, b: 2 };
94
+ const isBiggerThanFive = value => value >= 4;
95
+ const objWithSmallValues = omitBy(obj, isBiggerThanFive);
96
+ expect(objWithSmallValues).toEqual(obj);
97
+ });
98
+ });
99
+ });
@@ -1,3 +1,31 @@
1
1
  /* 🛠️ Any commonly used lodash functions can be added here. 🤙 */
2
2
 
3
- export const isEmpty = (obj: Record<string, unknown>): boolean => Object.keys(obj).length < 1
3
+ export const isEmpty = (obj: any) => [Object, Array].includes((obj || {}).constructor) && !Object.entries((obj || {})).length;
4
+
5
+ export const get = <T, R = any>(obj: T, path: string, defaultValue?: R): R | any => {
6
+ const travel = (regexp: RegExp): any =>
7
+ String.prototype.split
8
+ .call(path, regexp)
9
+ .filter(Boolean)
10
+ .reduce((res: any, key: string) => (res !== null && res !== undefined ? res[key] : res), obj)
11
+ const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/)
12
+ return result === undefined || result === obj ? defaultValue : result
13
+ }
14
+
15
+ export const isString = (str: unknown): str is string =>
16
+ str != null && typeof (str as any).valueOf() === "string"
17
+
18
+ export const uniqueId: (prefix?: string) => string = (() => {
19
+ let counter = 0
20
+ return (prefix = '') => `${prefix}${++counter}`
21
+ })()
22
+
23
+ export const omitBy = (obj: Record<string, any>, predicate: (value: any, key: string) => boolean) => {
24
+ if (obj === null || typeof obj !== 'object') return {}
25
+ return Object.keys(obj).reduce((result: Record<string, any>, key: string) => {
26
+ if (!predicate(obj[key], key)) {
27
+ result[key] = obj[key];
28
+ }
29
+ return result;
30
+ }, {})
31
+ }