playbook_ui 12.12.0.pre.alpha.PLAY697sandpacklayoutstyles413 → 12.13.0.pre.alpha.PLAY693tooltipwrongbg440

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +8 -1
  3. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +4 -1
  4. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.jsx +43 -0
  5. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.md +3 -0
  6. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +1 -0
  7. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +1 -0
  8. data/app/pb_kits/playbook/pb_flex/_flex.scss +1 -0
  9. data/app/pb_kits/playbook/pb_flex/_flex.tsx +4 -3
  10. data/app/pb_kits/playbook/pb_flex/docs/_flex_gap.html.erb +1 -1
  11. data/app/pb_kits/playbook/pb_flex/docs/_flex_gap.jsx +1 -1
  12. data/app/pb_kits/playbook/pb_flex/docs/_flex_gap.md +1 -1
  13. data/app/pb_kits/playbook/pb_flex/flex.rb +3 -3
  14. data/app/pb_kits/playbook/pb_layout/_layout.tsx +6 -1
  15. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +23 -9
  16. data/app/pb_kits/playbook/pb_selectable_list/_item.tsx +107 -0
  17. data/app/pb_kits/playbook/pb_selectable_list/{_selectable_list.jsx → _selectable_list.tsx} +11 -9
  18. data/app/pb_kits/playbook/pb_selectable_list/selectable_list.test.js +68 -0
  19. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +11 -6
  20. data/app/pb_kits/playbook/tokens/_positioning.scss +13 -0
  21. data/app/pb_kits/playbook/utilities/_positioning.scss +20 -0
  22. data/app/pb_kits/playbook/utilities/globalProps.ts +11 -2
  23. data/lib/playbook/classnames.rb +1 -0
  24. data/lib/playbook/kit_base.rb +2 -0
  25. data/lib/playbook/position.rb +33 -0
  26. data/lib/playbook/version.rb +2 -2
  27. metadata +8 -4
  28. data/app/pb_kits/playbook/pb_selectable_list/_item.jsx +0 -106
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eac850ebbc05e1ce91f38e6377564b32fa3ba241de3ff599b5e0084a39666223
4
- data.tar.gz: 2ce42692684f6598b0c22d7e763ff9bd815044bd28ea806b659746d1f73ea098
3
+ metadata.gz: 18b2b312491b972cf09d3520048e4bcee3b3a54fc77823a96f99e4b8124d691e
4
+ data.tar.gz: 15984bc190a04b1a771106b3c0d487164c94a5565f9403946cba9f042f244c6e
5
5
  SHA512:
6
- metadata.gz: 268d73b140d2e8aeb3086a4588b2a42c3f3c0dd26d7c4112b37583bcd85e9657fe59e6854042e2a8c9ca02bb139e4aef5aec926430d9da6f2b98c2c1b92d2d2e
7
- data.tar.gz: f58ed28b37d12a8e3555f44612a907aabb5e60b81cba57c78c017bb86328c6d437d14999849106847bc5967f59f51daac1c3e5bca921f7e7f7958dffc1ee843a
6
+ metadata.gz: 93575b229a5e34b07acfa9efcdfa1a7c4abdc4d312a1ada00215312802a5a51c42b5d0a23c8ba12876bc102400e7f768202c8656145ff00bf724006a25eb28bd
7
+ data.tar.gz: fce5886dc11ec423b86399cfbb5879c3bdc8d9c5833d5a4cc4f6dcea84928396f00a80fa6832f44e91f9a63f7767a6a6975e1dbce541e6a6822ed3dcca05f345
@@ -78,6 +78,7 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
78
78
  mode = 'single',
79
79
  name,
80
80
  onChange = () => { void 0 },
81
+ onClose,
81
82
  pickerId,
82
83
  placeholder = 'Select Date',
83
84
  plugins = false,
@@ -95,9 +96,13 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
95
96
  const inputAriaProps = buildAriaProps(inputAria)
96
97
  const inputDataProps = buildDataProps(inputData)
97
98
 
99
+ const filteredProps = {...props}
100
+ delete filteredProps?.position
101
+
98
102
  const classes = classnames(
99
103
  buildCss('pb_date_picker_kit'),
100
- globalProps(props),
104
+ //@ts-ignore
105
+ globalProps(filteredProps),
101
106
  error ? 'error' : null,
102
107
  className
103
108
  )
@@ -117,8 +122,10 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
117
122
  minDate,
118
123
  mode,
119
124
  onChange,
125
+ onClose,
120
126
  pickerId,
121
127
  plugins,
128
+ // @ts-ignore
122
129
  position,
123
130
  positionElement,
124
131
  selectionType,
@@ -19,6 +19,7 @@ type DatePickerConfig = {
19
19
  hideIcon?: boolean;
20
20
  inLine?: boolean,
21
21
  onChange: (dateStr: string, selectedDates: Date[]) => void,
22
+ onClose: (dateStr: Date[] | string, selectedDates: Date[] | string) => void,
22
23
  selectionType?: "month" | "week" | "",
23
24
  showTimezone?: boolean,
24
25
  staticPosition: boolean,
@@ -41,6 +42,7 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
41
42
  minDate,
42
43
  mode,
43
44
  onChange = () => {},
45
+ onClose = () => {},
44
46
  pickerId,
45
47
  plugins,
46
48
  position = "auto",
@@ -151,9 +153,10 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
151
153
  window.addEventListener('resize', calendarResizer)
152
154
  if (!staticPosition && scrollContainer) attachToScroll(scrollContainer)
153
155
  }],
154
- onClose: [() => {
156
+ onClose: [(selectedDates, dateStr) => {
155
157
  window.removeEventListener('resize', calendarResizer)
156
158
  if (!staticPosition && scrollContainer) detachFromScroll(scrollContainer as HTMLElement)
159
+ onClose(selectedDates, dateStr)
157
160
  }],
158
161
  onChange: [(selectedDates, dateStr) => {
159
162
  onChange(dateStr, selectedDates)
@@ -0,0 +1,43 @@
1
+ /* eslint-disable react/no-multi-comp */
2
+ import React, { useState } from 'react'
3
+ import { DatePicker,LabelValue } from '../..'
4
+
5
+
6
+ const DatePickerOnClose = (props) => {
7
+ const today = new Date()
8
+ const [dateString, setDateString] = useState(today.toLocaleDateString())
9
+ const [dateObj, setDateObj] = useState([today])
10
+
11
+ const handleOnClose = (selectedDates, dateStr) => {
12
+ setDateString(dateStr)
13
+ setDateObj(selectedDates)
14
+ }
15
+
16
+
17
+ return (
18
+ <div>
19
+ <DatePicker
20
+ defaultDate={dateString}
21
+ enableTime
22
+ marginBottom="lg"
23
+ onClose={handleOnClose}
24
+ pickerId="date-picker-on-close"
25
+ showTimezone
26
+ {...props}
27
+ />
28
+ <LabelValue
29
+ label="Date Object"
30
+ marginBottom="lg"
31
+ value={dateObj[0] ? dateObj[0].toString() : ''}
32
+ {...props}
33
+ />
34
+ <LabelValue
35
+ label="Date String"
36
+ value={dateString}
37
+ {...props}
38
+ />
39
+ </div>
40
+ )
41
+ }
42
+
43
+ export default DatePickerOnClose
@@ -0,0 +1,3 @@
1
+ The `onClose` handler function has access to two arguments: `dateStr` and `selectedDates`.
2
+
3
+ The first, `dateStr`, is a string of the chosen date. The second, `selectedDates`, is an array of selected date objects. In many use cases `selectedDates` will have only one value but you'll still need to access it from index 0.
@@ -31,6 +31,7 @@ examples:
31
31
  - date_picker_input: Input Field
32
32
  - date_picker_label: Label
33
33
  - date_picker_on_change: onChange
34
+ - date_picker_on_close: onClose
34
35
  - date_picker_range: Range
35
36
  - date_picker_format: Format
36
37
  - date_picker_disabled: Disabled Dates
@@ -19,3 +19,4 @@ export { default as DatePickerWeek } from './_date_picker_week.jsx'
19
19
  export { default as DatePickerPositions } from './_date_picker_positions.jsx'
20
20
  export { default as DatePickerPositionsElement } from './_date_picker_positions_element.jsx'
21
21
  export { default as DatePickerAllowInput } from './_date_picker_allow_input'
22
+ export { default as DatePickerOnClose } from './_date_picker_on_close.jsx'
@@ -2,6 +2,7 @@
2
2
  @import "../tokens/spacing";
3
3
 
4
4
  $gapSpaces:(
5
+ xxs: $space_xxs,
5
6
  xs: $space_xs,
6
7
  sm: $space_sm,
7
8
  md: $space_md,
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildCss, buildDataProps } from '../utilities/props'
4
4
  import { GlobalProps, globalProps } from '../utilities/globalProps'
5
+ import { Sizes } from '../types'
5
6
 
6
7
  type FlexProps = {
7
8
  children: React.ReactChild[] | React.ReactNode,
@@ -16,9 +17,9 @@ type FlexProps = {
16
17
  reverse?: boolean,
17
18
  vertical?: "top" | "center" | "bottom" | "stretch" | "baseline" | "none",
18
19
  align?: "start" | "center" | "end" | "stretch" | "baseline" | "none",
19
- gap?: "xs" | "sm" | "md" | "lg" | "xl" | "none",
20
- rowGap?: "xs" | "sm" | "md" | "lg" | "xl" | "none",
21
- columnGap?: "xs" | "sm" | "md" | "lg" | "xl" | "none",
20
+ gap?: Sizes | "none",
21
+ rowGap?: Sizes| "none",
22
+ columnGap?: Sizes| "none",
22
23
  wrap?: boolean,
23
24
  alignSelf?: "start" | "end" | "center" | "stretch" | "none"
24
25
  } & GlobalProps
@@ -1,7 +1,7 @@
1
1
  <%= pb_rails("title", props: {size: 4, text: "Row"}) %>
2
2
  <br/>
3
3
  <div class="flex-doc-example">
4
- <%= pb_rails("flex", props:{ gap: "xs", wrap:true}) do %>
4
+ <%= pb_rails("flex", props:{ gap: "xxs", wrap:true}) do %>
5
5
  <%40.times do |i|%>
6
6
  <%= pb_rails("flex/flex_item") do %> <%=i%> <% end %>
7
7
  <% end %>
@@ -14,7 +14,7 @@ const FlexGap = (props) => {
14
14
  <>
15
15
  <div className="flex-doc-example">
16
16
  <Flex
17
- gap="xs"
17
+ gap="xxs"
18
18
  wrap
19
19
  {...props}
20
20
  >
@@ -1,6 +1,6 @@
1
1
  ##### Prop
2
2
 
3
- * `gap` | `row_gap` | `rowGap` | `column_gap` | `columnGap` | **Type**: String | **Values**: xs | sm | md | lg | xl | none
3
+ * `gap` | `row_gap` | `rowGap` | `column_gap` | `columnGap` | **Type**: String | **Values**: xxs | xs | sm | md | lg | xl | none
4
4
 
5
5
  - Setting the gap prop sets the row_gap || rowGap and the column_gap || columnGap props to the same size and creates equal space within a flex container.
6
6
 
@@ -25,15 +25,15 @@ module Playbook
25
25
  deprecated: true
26
26
 
27
27
  prop :gap, type: Playbook::Props::Enum,
28
- values: %w[xs sm md lg xl none],
28
+ values: %w[xxs xs sm md lg xl none],
29
29
  default: "none"
30
30
 
31
31
  prop :row_gap, type: Playbook::Props::Enum,
32
- values: %w[xs sm md lg xl none],
32
+ values: %w[xxs xs sm md lg xl none],
33
33
  default: "none"
34
34
 
35
35
  prop :column_gap, type: Playbook::Props::Enum,
36
- values: %w[xs sm md lg xl none],
36
+ values: %w[xxs xs sm md lg xl none],
37
37
  default: "none"
38
38
 
39
39
  prop :reverse, type: Playbook::Props::Boolean,
@@ -151,6 +151,10 @@ const Layout = (props: LayoutPropTypes) => {
151
151
  const nonSideChildren = layoutChildren.filter(
152
152
  (child: React.ReactElement & {type: {displayName: string}}) => child.type?.displayName !== 'Side'
153
153
  )
154
+
155
+ const filteredProps = {...props}
156
+ delete filteredProps?.position
157
+
154
158
  return (
155
159
  <div
156
160
  {...ariaProps}
@@ -159,7 +163,8 @@ const Layout = (props: LayoutPropTypes) => {
159
163
  layoutCss,
160
164
  layoutCollapseCss,
161
165
  className,
162
- globalProps(props)
166
+ //@ts-ignore
167
+ globalProps(filteredProps)
163
168
  )}
164
169
  >
165
170
  {subComponentTags('Side')}
@@ -89,6 +89,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
89
89
  const [itiInit, setItiInit] = useState<any>()
90
90
  const [error, setError] = useState('')
91
91
  const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
92
+ const [selectedData, setSelectedData] = useState()
92
93
 
93
94
  const validateTooLongNumber = (itiInit: any) => {
94
95
  const error = itiInit.getValidationError()
@@ -121,10 +122,16 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
121
122
  validateOnlyNumbers()
122
123
  }
123
124
 
125
+ const getCurrentSelectedData = (itiInit: any, inputValue: string) => {
126
+ return { ...itiInit.getSelectedCountryData(), number: inputValue }
127
+ }
128
+
124
129
  const handleOnChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
125
130
  setInputValue(evt.target.value)
126
131
  validateTooLongNumber(itiInit)
127
- onChange(evt)
132
+ const phoneNumberData = getCurrentSelectedData(itiInit, evt.target.value)
133
+ setSelectedData(phoneNumberData)
134
+ onChange(phoneNumberData)
128
135
  isValid(itiInit.isValidNumber())
129
136
  }
130
137
 
@@ -136,15 +143,21 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
136
143
 
137
144
  useEffect(() => {
138
145
  const telInputInit = new intlTelInput(inputRef.current, {
139
- separateDialCode: true,
140
- preferredCountries,
141
- allowDropdown: !disabled,
142
- initialCountry,
143
- onlyCountries,
144
- }
146
+ separateDialCode: true,
147
+ preferredCountries,
148
+ allowDropdown: !disabled,
149
+ initialCountry,
150
+ onlyCountries,
151
+ }
145
152
  )
146
-
147
- inputRef.current.addEventListener("countrychange", () => validateTooLongNumber(telInputInit))
153
+
154
+ inputRef.current.addEventListener("countrychange", (evt: Event) => {
155
+ validateTooLongNumber(telInputInit)
156
+ const phoneNumberData = getCurrentSelectedData(telInputInit, (evt.target as HTMLInputElement).value)
157
+ setSelectedData(phoneNumberData)
158
+ onChange(phoneNumberData)
159
+ })
160
+
148
161
  inputRef.current.addEventListener("open:countrydropdown", () => setDropDownIsOpen(true))
149
162
  inputRef.current.addEventListener("close:countrydropdown", () => setDropDownIsOpen(false))
150
163
 
@@ -156,6 +169,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps) => {
156
169
  <TextInput
157
170
  className={dropDownIsOpen ? 'dropdown_open' : ''}
158
171
  dark={dark}
172
+ data-phone-number={JSON.stringify(selectedData)}
159
173
  disabled={disabled}
160
174
  error={error}
161
175
  id={id}
@@ -0,0 +1,107 @@
1
+ import React, { useState } from "react";
2
+ import classnames from "classnames";
3
+
4
+ import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
5
+ import { globalProps } from "../utilities/globalProps";
6
+
7
+ import Checkbox from "../pb_checkbox/_checkbox";
8
+ import ListItem from "../pb_list/_list_item";
9
+ import Radio from "../pb_radio/_radio";
10
+
11
+ export type SelectableListItemProps = {
12
+ aria?: { [key: string]: string };
13
+ children: React.ReactNode[] | React.ReactNode;
14
+ checked?: boolean;
15
+ className?: string;
16
+ data?: object;
17
+ defaultChecked?: boolean;
18
+ id?: string;
19
+ label?: string;
20
+ text?: string;
21
+ name?: string;
22
+ value?: string;
23
+ variant?: string;
24
+ onChange: (arg: React.ChangeEvent<HTMLInputElement> | null) => void;
25
+ };
26
+
27
+ const SelectableListItem = ({
28
+ aria = {},
29
+ checked = false,
30
+ children,
31
+ className,
32
+ data = {},
33
+ defaultChecked,
34
+ id,
35
+ label,
36
+ text = "",
37
+ name = "",
38
+ value = "",
39
+ variant = "checkbox",
40
+ onChange = () => {},
41
+ ...props
42
+ }: SelectableListItemProps) => {
43
+ const ariaProps = buildAriaProps(aria);
44
+ const dataProps = buildDataProps(data);
45
+ const classes = classnames(
46
+ buildCss("pb_selectable_list_item_kit"),
47
+ globalProps(props),
48
+ className
49
+ );
50
+
51
+ const initialCheckedState = checked;
52
+ const [checkedState, setCheckedState] = useState(initialCheckedState);
53
+
54
+ const handleChecked = (event: React.ChangeEvent<HTMLInputElement>) => {
55
+ onChange(event);
56
+ setCheckedState(event.target.checked);
57
+ };
58
+
59
+ return (
60
+ <ListItem
61
+ {...props}
62
+ className={classnames(checkedState ? "checked_item" : "", className)}
63
+ >
64
+ <div {...ariaProps} {...dataProps} className={classes}>
65
+ {variant == "checkbox" && (
66
+ <>
67
+ <Checkbox
68
+ checked={checkedState}
69
+ id={id}
70
+ name={name}
71
+ onChange={handleChecked}
72
+ // eslint suppressor, text is needed to display on screen
73
+ //@ts-ignore
74
+ text={label || (text && false)}
75
+ type="checkbox"
76
+ value={value}
77
+ {...props}
78
+ />
79
+ {children}
80
+ </>
81
+ )}
82
+ {variant == "radio" && (
83
+ <>
84
+ <Radio
85
+ defaultChecked={defaultChecked}
86
+ id={id}
87
+ label={label}
88
+ name={name}
89
+ onChange={onChange}
90
+ //@ts-ignore
91
+ text={label}
92
+ type="radio"
93
+ value={value}
94
+ {...props}
95
+ />
96
+ {children}
97
+ </>
98
+ )}
99
+ {variant !== "checkbox" && variant !== "radio" && (
100
+ { children }
101
+ )}
102
+ </div>
103
+ </ListItem>
104
+ );
105
+ };
106
+
107
+ export default SelectableListItem;
@@ -1,16 +1,16 @@
1
- /* @flow */
2
1
  import React, { useState } from 'react'
3
2
  import classnames from 'classnames'
4
3
 
5
4
  import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
6
5
  import { globalProps } from '../utilities/globalProps'
6
+ import { SelectableListItemProps } from './_item.js'
7
7
 
8
8
  import List from '../pb_list/_list'
9
- import SelectableListItem from './_item.jsx'
9
+ import SelectableListItem from './_item'
10
10
 
11
11
  type SelectableListProps = {
12
- aria?: object,
13
- children?: Node,
12
+ aria?: {[key: string]: string },
13
+ children?: React.ReactElement[],
14
14
  className?: string,
15
15
  data?: object,
16
16
  id?: string,
@@ -30,17 +30,18 @@ const SelectableList = (props: SelectableListProps) => {
30
30
  const classes = classnames(buildCss('pb_selectable_list_kit'), globalProps(props), className)
31
31
  const dataProps = buildDataProps(data)
32
32
  const isRadio = props.variant === "radio"
33
- const defaultCheckedRadioValue = children.filter(item => item.props.defaultChecked)[0]?.props?.value
33
+ const defaultCheckedRadioValue = children.filter((item: {props:SelectableListItemProps} ) => item.props.defaultChecked)[0]?.props?.value
34
+
34
35
  const [selectedRadioValue, setSelectedRadioValue] = useState(defaultCheckedRadioValue)
35
36
 
36
- const onChangeRadioValue = ({ target }) => {
37
+ const onChangeRadioValue = ({ target }: React.ChangeEvent<HTMLInputElement>) => {
37
38
  setSelectedRadioValue(target.value)
38
39
  }
39
40
 
40
41
  let selectableListItems = children
41
42
 
42
43
  if (isRadio) {
43
- selectableListItems = children.map(({ props }) => {
44
+ selectableListItems = children.map(( {props}: {props:SelectableListItemProps} ) => {
44
45
  return (
45
46
  <SelectableListItem
46
47
  {...props}
@@ -51,6 +52,7 @@ const SelectableList = (props: SelectableListProps) => {
51
52
  )
52
53
  })
53
54
  }
55
+
54
56
 
55
57
  return (
56
58
  <div
@@ -59,13 +61,13 @@ const SelectableList = (props: SelectableListProps) => {
59
61
  className={classes}
60
62
  id={id}
61
63
  >
62
- <List {...props}>
64
+ <List variant={props.variant}>
63
65
  {selectableListItems}
64
66
  </List>
65
67
  </div>
66
68
  )
67
69
  }
68
-
70
+
69
71
  SelectableList.Item = SelectableListItem
70
72
 
71
73
  export default SelectableList
@@ -0,0 +1,68 @@
1
+ import React from 'react'
2
+ import { render, screen } from '../utilities/test-utils'
3
+ import SelectableList from './_selectable_list'
4
+
5
+ const testId = "selectable-list-test"
6
+
7
+ const SelectableListCheckbox = () => {
8
+ return (
9
+ <SelectableList
10
+ data={{ testid: testId }}
11
+ variant="checkbox">
12
+ <SelectableList.Item
13
+ label="Mild"
14
+ name="checkbox-name-1"
15
+ value="1"
16
+ />
17
+ <SelectableList.Item
18
+ checked
19
+ label="Medium"
20
+ name="checkbox-name-2"
21
+ value="2"
22
+ />
23
+ </SelectableList>
24
+ )
25
+ }
26
+
27
+ const SelectableListRadio = () => {
28
+ return (
29
+ <SelectableList
30
+ data={{ testid: testId }}
31
+ variant="radio">
32
+ <SelectableList.Item
33
+ label="Small"
34
+ name="radio"
35
+ value="1"
36
+ />
37
+ <SelectableList.Item
38
+ defaultChecked
39
+ label="Medium"
40
+ name="radio"
41
+ value="2"
42
+ />
43
+ </SelectableList>
44
+ )
45
+ }
46
+
47
+
48
+ test("classname renders as expected", () => {
49
+ render(<SelectableListCheckbox />)
50
+
51
+ const kit = screen.getByTestId("selectable-list-test")
52
+ expect(kit).toHaveClass("pb_selectable_list_kit")
53
+ })
54
+
55
+ test("renders variant checkbox", () => {
56
+ render(<SelectableListCheckbox />)
57
+ const kit = screen.getByTestId("selectable-list-test")
58
+ const checkbox = kit.querySelector(".pb_checkbox_kit")
59
+ expect(checkbox).toBeInTheDocument()
60
+ })
61
+
62
+ test("renders variant radio", () => {
63
+ render(<SelectableListRadio />)
64
+ const kit = screen.getByTestId("selectable-list-test")
65
+ const checkbox = kit.querySelector(".pb_radio_kit")
66
+ expect(checkbox).toBeInTheDocument()
67
+
68
+ })
@@ -88,13 +88,18 @@ $tooltip_shadow: rgba(60, 106, 172, 0.18);
88
88
  &.show {
89
89
  opacity: 1;
90
90
  margin-bottom: $space_sm;
91
- background-color: $white;
91
+ color: $white;
92
+ background-color: rgba($black, $opacity_9);
92
93
  &.fade_out {
93
94
  animation-name: fadeOut;
94
95
  animation-duration: 150ms;
95
96
  animation-timing-function: linear;
96
97
  animation-fill-mode: forwards;
97
98
  }
99
+ .arrow {
100
+ border-color: $black transparent transparent transparent;
101
+ opacity: $opacity_9;
102
+ }
98
103
  }
99
104
  }
100
105
 
@@ -109,12 +114,12 @@ $tooltip_shadow: rgba(60, 106, 172, 0.18);
109
114
  }
110
115
  //rails
111
116
  &.show {
112
- color: $white;
113
- background-color: rgba($black, $opacity_9);
117
+ color: $charcoal;
118
+ background-color: $white;
114
119
  }
115
- .arrow {
116
- border-color: $black transparent transparent transparent;
117
- opacity: $opacity_9;
120
+ .arrow {
121
+ border-color: $white transparent transparent transparent;
122
+ opacity: $opacity_10;
118
123
  }
119
124
  // react arrow
120
125
  .arrow_bg {
@@ -1,3 +1,16 @@
1
+ $relative: relative !default;
2
+ $absolute: absolute !default;
3
+ $fixed: fixed !default;
4
+ $sticky: sticky !default;
5
+ $static: static !default;
6
+ $position: (
7
+ relative: $relative,
8
+ absolute: $absolute,
9
+ fixed: $fixed,
10
+ sticky: $sticky,
11
+ static: $static
12
+ );
13
+
1
14
  // z_index variables
2
15
  $z_1: 100 !default;
3
16
  $z_2: 200 !default;
@@ -1,3 +1,23 @@
1
+ .position_relative {
2
+ position: relative;
3
+ }
4
+
5
+ .position_absolute {
6
+ position: absolute;
7
+ }
8
+
9
+ .position_fixed {
10
+ position: fixed;
11
+ }
12
+
13
+ .position_sticky {
14
+ position: sticky;
15
+ }
16
+
17
+ .position_static {
18
+ position: static;
19
+ }
20
+
1
21
  .z_index_1 {
2
22
  z-index: 100;
3
23
  }
@@ -100,6 +100,10 @@ type Padding = {
100
100
  padding?: AllSizes,
101
101
  }
102
102
 
103
+ type Position = {
104
+ position?: "relative" | "absolute" | "fixed" | "sticky" | "static",
105
+ }
106
+
103
107
  type Shadow = {
104
108
  shadow?: "none" | "deep" | "deeper" | "deepest",
105
109
  }
@@ -115,7 +119,7 @@ export type GlobalProps = AlignContent & AlignItems & AlignSelf &
115
119
  BorderRadius & Cursor & Dark & Display & DisplaySizes & Flex & FlexDirection &
116
120
  FlexGrow & FlexShrink & FlexWrap & JustifyContent & JustifySelf &
117
121
  LineHeight & Margin & MaxWidth & NumberSpacing & Order & Padding &
118
- Shadow & ZIndex
122
+ Position & Shadow & ZIndex
119
123
 
120
124
  const getResponsivePropClasses = (prop: {[key: string]: string}, classPrefix: string) => {
121
125
  const keys: string[] = Object.keys(prop)
@@ -283,7 +287,12 @@ const PROP_CATEGORIES: {[key:string]: (props: {[key: string]: any}) => string} =
283
287
  } else {
284
288
  return order ? `flex_order_${order}` : ''
285
289
  }
286
- }
290
+ },
291
+ positionProps: ({ position }: Position) => {
292
+ let css = ''
293
+ css += position && position !== 'static' ? `position_${position}` : ''
294
+ return css
295
+ },
287
296
  }
288
297
 
289
298
  type DefaultProps = {[key: string]: string} | Record<string, unknown>
@@ -31,6 +31,7 @@ module Playbook
31
31
  flex_grow_props,
32
32
  flex_shrink_props,
33
33
  order_props,
34
+ position_props,
34
35
  ].compact.join(" ")
35
36
  end
36
37
 
@@ -19,6 +19,7 @@ require "playbook/flex"
19
19
  require "playbook/flex_grow"
20
20
  require "playbook/flex_shrink"
21
21
  require "playbook/order"
22
+ require "playbook/position"
22
23
 
23
24
  module Playbook
24
25
  class KitBase < ViewComponent::Base
@@ -43,6 +44,7 @@ module Playbook
43
44
  include Playbook::FlexGrow
44
45
  include Playbook::FlexShrink
45
46
  include Playbook::Order
47
+ include Playbook::Position
46
48
 
47
49
  prop :id
48
50
  prop :data, type: Playbook::Props::Hash, default: {}
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Playbook
4
+ module Position
5
+ def self.included(base)
6
+ base.prop :position
7
+ end
8
+
9
+ private
10
+
11
+ def position_props
12
+ selected_props = position_options.keys.select { |sk| try(sk) }
13
+ return nil unless selected_props.present?
14
+
15
+ selected_props.map do |k|
16
+ value = send(k)
17
+ return nil unless position_values.include? value
18
+
19
+ "position_#{value}"
20
+ end.compact.join(" ")
21
+ end
22
+
23
+ def position_options
24
+ {
25
+ position: "position",
26
+ }
27
+ end
28
+
29
+ def position_values
30
+ %w[relative absolute fixed sticky]
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Playbook
4
- PREVIOUS_VERSION = "12.12.0"
5
- VERSION = "12.12.0.pre.alpha.PLAY697sandpacklayoutstyles413"
4
+ PREVIOUS_VERSION = "12.13.0"
5
+ VERSION = "12.13.0.pre.alpha.PLAY693tooltipwrongbg440"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playbook_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.12.0.pre.alpha.PLAY697sandpacklayoutstyles413
4
+ version: 12.13.0.pre.alpha.PLAY693tooltipwrongbg440
5
5
  platform: ruby
6
6
  authors:
7
7
  - Power UX
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-04-04 00:00:00.000000000 Z
12
+ date: 2023-04-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -738,6 +738,8 @@ files:
738
738
  - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_month_and_year.md
739
739
  - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_change.jsx
740
740
  - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_change.md
741
+ - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.jsx
742
+ - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.md
741
743
  - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.html.erb
742
744
  - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.jsx
743
745
  - app/pb_kits/playbook/pb_date_picker/docs/_date_picker_positions.md
@@ -1843,9 +1845,9 @@ files:
1843
1845
  - app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb
1844
1846
  - app/pb_kits/playbook/pb_selectable_icon/selectable_icon.rb
1845
1847
  - app/pb_kits/playbook/pb_selectable_icon/selectable_icon.test.js
1846
- - app/pb_kits/playbook/pb_selectable_list/_item.jsx
1847
- - app/pb_kits/playbook/pb_selectable_list/_selectable_list.jsx
1848
+ - app/pb_kits/playbook/pb_selectable_list/_item.tsx
1848
1849
  - app/pb_kits/playbook/pb_selectable_list/_selectable_list.scss
1850
+ - app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx
1849
1851
  - app/pb_kits/playbook/pb_selectable_list/docs/_selectable_list_checkbox.html.erb
1850
1852
  - app/pb_kits/playbook/pb_selectable_list/docs/_selectable_list_checkbox.jsx
1851
1853
  - app/pb_kits/playbook/pb_selectable_list/docs/_selectable_list_radio.html.erb
@@ -1854,6 +1856,7 @@ files:
1854
1856
  - app/pb_kits/playbook/pb_selectable_list/docs/index.js
1855
1857
  - app/pb_kits/playbook/pb_selectable_list/selectable_list.html.erb
1856
1858
  - app/pb_kits/playbook/pb_selectable_list/selectable_list.rb
1859
+ - app/pb_kits/playbook/pb_selectable_list/selectable_list.test.js
1857
1860
  - app/pb_kits/playbook/pb_selectable_list/selectable_list_item.html.erb
1858
1861
  - app/pb_kits/playbook/pb_selectable_list/selectable_list_item.rb
1859
1862
  - app/pb_kits/playbook/pb_source/_source.scss
@@ -2437,6 +2440,7 @@ files:
2437
2440
  - lib/playbook/pb_doc_helper.rb
2438
2441
  - lib/playbook/pb_forms_helper.rb
2439
2442
  - lib/playbook/pb_kit_helper.rb
2443
+ - lib/playbook/position.rb
2440
2444
  - lib/playbook/props.rb
2441
2445
  - lib/playbook/props/array.rb
2442
2446
  - lib/playbook/props/base.rb
@@ -1,106 +0,0 @@
1
- /* @flow */
2
-
3
- import React, { Node, useState } from 'react'
4
- import classnames from 'classnames'
5
-
6
- import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
7
- import { globalProps } from '../utilities/globalProps'
8
-
9
- import Checkbox from '../pb_checkbox/_checkbox'
10
- import ListItem from '../pb_list/_list_item'
11
- import Radio from '../pb_radio/_radio'
12
-
13
- type SelectableListItemProps = {
14
- aria?: object,
15
- children: array<Node> | Node,
16
- checked?: boolean,
17
- className?: string,
18
- data?: object,
19
- defaultChecked?: boolean,
20
- id?: string,
21
- label?: string,
22
- text?: string,
23
- name?: string,
24
- value?: string,
25
- variant?: string,
26
- onChange: (boolean)=>void,
27
- }
28
-
29
- const SelectableListItem = ({
30
- aria = {},
31
- checked = false,
32
- children,
33
- className,
34
- data = {},
35
- defaultChecked,
36
- id,
37
- label,
38
- text = '',
39
- name = '',
40
- value = '',
41
- variant = 'checkbox',
42
- onChange = () => {},
43
- ...props
44
- }: SelectableListItemProps) => {
45
- const ariaProps = buildAriaProps(aria)
46
- const dataProps = buildDataProps(data)
47
- const classes = classnames(
48
- buildCss('pb_selectable_list_item_kit'),
49
- globalProps(props),
50
- className
51
- )
52
-
53
- const initialCheckedState = checked
54
- const [checkedState, setCheckedState] = useState(initialCheckedState)
55
-
56
- const handleChecked = (event) => {
57
- onChange(event)
58
- setCheckedState(event.target.checked)
59
- }
60
-
61
- return (
62
- <ListItem
63
- {...props}
64
- className={classnames(checkedState ? "checked_item" : "", className)}
65
- >
66
- <div
67
- {...ariaProps}
68
- {...dataProps}
69
- className={classes}
70
- >
71
- <Choose>
72
- <When condition={variant == 'checkbox'}>
73
- <Checkbox
74
- checked={checkedState}
75
- id={id}
76
- name={name}
77
- onChange={handleChecked}
78
- // eslint suppressor, text is needed to display on screen
79
- text={label || (text && false)}
80
- type="checkbox"
81
- value={value}
82
- {...props}
83
- />
84
- {children}
85
- </When>
86
- <When condition={variant == 'radio'}>
87
- <Radio
88
- defaultChecked={defaultChecked}
89
- id={id}
90
- label={label}
91
- name={name}
92
- onChange={onChange}
93
- type="radio"
94
- value={value}
95
- {...props}
96
- />
97
- {children}
98
- </When>
99
- <Otherwise>{children}</Otherwise>
100
- </Choose>
101
- </div>
102
- </ListItem>
103
- )
104
- }
105
-
106
- export default SelectableListItem