playbook_ui 11.3.0.pre.alpha2 → 11.4.0.pre.alpha.rubytheme2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_button/_button.tsx +6 -6
  3. data/app/pb_kits/playbook/pb_circle_icon_button/{_circle_icon_button.jsx → _circle_icon_button.tsx} +6 -10
  4. data/app/pb_kits/playbook/pb_contact/contact.test.js +45 -1
  5. data/app/pb_kits/playbook/pb_currency/{_currency.jsx → _currency.tsx} +17 -12
  6. data/app/pb_kits/playbook/pb_date/_date.tsx +101 -0
  7. data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +10 -9
  8. data/app/pb_kits/playbook/pb_date_time/{_date_time.jsx → _date_time.tsx} +2 -5
  9. data/app/pb_kits/playbook/pb_date_time/dateTime.test.js +110 -0
  10. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_align.jsx +1 -1
  11. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_default.jsx +1 -1
  12. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_size.jsx +1 -1
  13. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +32 -14
  14. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +5 -0
  15. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_body.jsx +2 -2
  16. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_footer.jsx +22 -4
  17. data/app/pb_kits/playbook/pb_dialog/child_kits/_dialog_header.jsx +3 -3
  18. data/app/pb_kits/playbook/pb_dialog/dialog.test.jsx +79 -17
  19. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_stacked_alert.jsx +55 -93
  20. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_status.jsx +79 -42
  21. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +80 -0
  22. data/app/pb_kits/playbook/pb_hashtag/_hashtag.tsx +10 -1
  23. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.html.erb +5 -0
  24. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.jsx +26 -0
  25. data/app/pb_kits/playbook/pb_hashtag/docs/_hashtag_link.md +1 -0
  26. data/app/pb_kits/playbook/pb_hashtag/docs/example.yml +2 -0
  27. data/app/pb_kits/playbook/pb_hashtag/docs/index.js +1 -0
  28. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -1
  29. data/app/pb_kits/playbook/pb_hashtag/hashtag.rb +6 -0
  30. data/app/pb_kits/playbook/pb_hashtag/hashtag.test.js +54 -0
  31. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.jsx +3 -0
  32. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +2 -1
  33. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.rb +2 -0
  34. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.html.erb +12 -0
  35. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.jsx +23 -0
  36. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_link.md +1 -0
  37. data/app/pb_kits/playbook/pb_home_address_street/docs/example.yml +3 -0
  38. data/app/pb_kits/playbook/pb_home_address_street/docs/index.js +1 -0
  39. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.rb +4 -0
  40. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +2 -1
  41. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.rb +4 -1
  42. data/app/pb_kits/playbook/pb_icon/_icon.tsx +1 -0
  43. data/app/pb_kits/playbook/pb_icon_circle/{_icon_circle.jsx → _icon_circle.tsx} +2 -4
  44. data/app/pb_kits/playbook/pb_kit/{dateTime.js → dateTime.ts} +5 -6
  45. data/app/pb_kits/playbook/pb_label_pill/{_label_pill.jsx → _label_pill.tsx} +2 -4
  46. data/app/pb_kits/playbook/pb_label_value/_label_value.jsx +1 -1
  47. data/app/pb_kits/playbook/pb_logistic/_logistic.jsx +1 -1
  48. data/app/pb_kits/playbook/pb_pill/_pill.tsx +1 -1
  49. data/app/pb_kits/playbook/pb_section_separator/{_section_separator.jsx → _section_separator.tsx} +7 -8
  50. data/app/pb_kits/playbook/pb_time/_time.tsx +92 -0
  51. data/app/pb_kits/playbook/pb_time/docs/_time_align.jsx +1 -1
  52. data/app/pb_kits/playbook/pb_time/docs/_time_default.jsx +1 -1
  53. data/app/pb_kits/playbook/pb_time/docs/_time_sizes.jsx +1 -1
  54. data/app/pb_kits/playbook/pb_time/docs/_time_timestamp.jsx +1 -1
  55. data/app/pb_kits/playbook/pb_time/docs/_time_timezone.jsx +1 -1
  56. data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.jsx +1 -1
  57. data/app/pb_kits/playbook/pb_title/_title.tsx +1 -1
  58. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_without_pills.html.erb +37 -0
  59. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_without_pills.md +1 -0
  60. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
  61. data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +2 -2
  62. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +10 -2
  63. data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.jsx +1 -1
  64. data/app/pb_kits/playbook/tokens/_colors.scss +74 -74
  65. data/app/pb_kits/playbook/tokens/_typography.scss +8 -8
  66. data/dist/reset.css +2 -0
  67. data/lib/playbook/version.rb +2 -2
  68. metadata +24 -13
  69. data/app/pb_kits/playbook/pb_date/_date.jsx +0 -138
  70. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.jsx +0 -93
  71. data/app/pb_kits/playbook/pb_time/_time.jsx +0 -90
@@ -9,17 +9,35 @@ import { globalProps } from '../../utilities/globalProps'
9
9
  import Flex from '../../pb_flex/_flex'
10
10
  import SectionSeparator from '../../pb_section_separator/_section_separator'
11
11
 
12
+
13
+ type DialogFooterProps = {
14
+ aria?: object,
15
+ children: array<React.ReactNode> | React.ReactNode | string,
16
+ className?: string,
17
+ closeable: boolean,
18
+ data?: object,
19
+ id?: string,
20
+ padding?: string,
21
+ paddingBottom?: string,
22
+ paddingX?: string,
23
+ separator: boolean,
24
+ spacing?: string,
25
+ }
26
+
12
27
  // Footer component
13
28
  const DialogFooter = (props: DialogFooterProps) => {
14
29
  const {
15
30
  children,
16
- padding = 'sm',
31
+ padding = "sm",
32
+ paddingBottom = "sm",
33
+ paddingX = "sm",
17
34
  className,
18
- spacing = 'between',
35
+ spacing = "between",
19
36
  separator = false,
20
37
  } = props
21
- const footerCSS = buildCss('dialog_footer')
22
- const footerSpacing = globalProps(props, { padding })
38
+
39
+ const footerCSS = buildCss("dialog_footer")
40
+ const footerSpacing = globalProps(props, { padding, paddingBottom, paddingX })
23
41
 
24
42
  return (
25
43
  <>
@@ -30,8 +30,8 @@ const DialogHeader = (props: DialogHeaderProps) => {
30
30
  children,
31
31
  className,
32
32
  data = {},
33
- padding = 'sm',
34
- spacing = 'between',
33
+ padding = "sm",
34
+ spacing = "between",
35
35
  closeable = true,
36
36
  separator = true,
37
37
  } = props
@@ -39,7 +39,7 @@ const DialogHeader = (props: DialogHeaderProps) => {
39
39
  const ariaProps = buildAriaProps(aria)
40
40
  const dataProps = buildDataProps(data)
41
41
  const api = useContext(DialogContext)
42
- const headerCSS = buildCss('dialog_header')
42
+ const headerCSS = buildCss("dialog_header")
43
43
  const headerSpacing = globalProps(props, { padding })
44
44
 
45
45
  /* eslint-disable react/jsx-handler-names */
@@ -1,23 +1,85 @@
1
- import React from 'react'
2
- import { render, screen } from '../utilities/test-utils'
3
- import { Dialog } from '../'
1
+ import React, {useState} from 'react'
2
+ import { render, cleanup, waitFor, fireEvent } from "../utilities/test-utils";
3
+ import { Dialog, Button } from '../'
4
4
 
5
- /* eslint-disable jsx-control-statements/jsx-jcs-no-undef */
5
+ const text="Hello Body Text, Nice to meet ya."
6
+ const title="Header Title is the Title Prop"
7
+ const size="sm"
8
+ const confirmButton="Okay"
9
+ const cancelButton="Cancel Button"
6
10
 
7
- /* See these resources for more testing info:
8
- - https://github.com/testing-library/jest-dom#usage for useage and examples
9
- - https://jestjs.io/docs/en/using-matchers
10
- */
11
+ function DialogTest() {
12
+ const [isOpen, setIsOpen] = useState(false)
13
+ const close = () => setIsOpen(false)
14
+ const open = () => setIsOpen(true)
15
+ const [isLoading, setIsLoading] = useState(false)
16
+ return (
17
+ <>
18
+ <Button onClick={open}>{'Open Dialog'}</Button>
19
+ <Dialog
20
+ cancelButton={cancelButton}
21
+ className="wrapper"
22
+ confirmButton={confirmButton}
23
+ loading={isLoading}
24
+ onCancel={close}
25
+ onClose={close}
26
+ onConfirm={() => setIsLoading(!isLoading)}
27
+ opened={isOpen}
28
+ portalClassName="portal"
29
+ size={size}
30
+ text={text}
31
+ title={title}
32
+ />
33
+ </>
34
+ );
35
+ }
11
36
 
12
- test('Kit renders Dialog', () => {
13
- const testId = 'test1'
37
+ test('renders the component when clicked', async () => {
14
38
 
15
- render(
16
- <Dialog
17
- data={{ testid: testId }}
18
- />
19
- )
39
+ const { queryByText } = render(<DialogTest />);
20
40
 
21
- const kit = screen.getByTestId(testId)
22
- expect(kit).toBeInTheDocument()
41
+ fireEvent.click(queryByText('Open Dialog'));
42
+
43
+ await waitFor(() => expect(queryByText("Header Title is the Title Prop")).toBeInTheDocument());
44
+
45
+ cleanup()
23
46
  })
47
+
48
+ test("renders the title and body text", async () => {
49
+
50
+ const { queryByText } = render(<DialogTest />);
51
+
52
+ fireEvent.click(queryByText('Open Dialog'));
53
+
54
+ await waitFor(() => expect(queryByText("Header Title is the Title Prop")).toHaveTextContent(title));
55
+
56
+ await waitFor(() => expect(queryByText("Hello Body Text, Nice to meet ya.")).toHaveTextContent(text));
57
+
58
+ cleanup()
59
+ });
60
+
61
+ test("renders the title and body text", async () => {
62
+
63
+ const { queryByText } = render(<DialogTest />);
64
+
65
+ fireEvent.click(queryByText('Open Dialog'));
66
+
67
+ await waitFor(() => expect(queryByText("Header Title is the Title Prop")).toHaveTextContent(title));
68
+
69
+ await waitFor(() => expect(queryByText("Hello Body Text, Nice to meet ya.")).toHaveTextContent(text));
70
+
71
+ cleanup()
72
+ });
73
+
74
+ test("renders the buttons", async () => {
75
+
76
+ const { queryByText } = render(<DialogTest />);
77
+
78
+ fireEvent.click(queryByText('Open Dialog'));
79
+
80
+ await waitFor(() => expect(queryByText("Okay")).toHaveTextContent(confirmButton));
81
+
82
+ await waitFor(() => expect(queryByText("Cancel Button")).toHaveTextContent(cancelButton));
83
+
84
+ cleanup()
85
+ });
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable react/jsx-handler-names */
2
-
3
2
  import React, { useState } from "react"
4
- import { Button, Dialog, Flex, FlexItem, SectionSeparator } from "../.."
3
+ import { Button, Dialog, Flex} from "../.."
5
4
 
6
5
  const useDialog = (visible = false) => {
7
6
  const [opened, setOpened] = useState(visible)
@@ -10,46 +9,40 @@ const useDialog = (visible = false) => {
10
9
  }
11
10
 
12
11
  const DialogStackedAlert = () => {
13
- const [singleButtonOpen, toggleSingleButtonOpen] = useDialog()
14
- const [stackedButtonOpen, toggleStackedButtonOpen] = useDialog()
15
- const [singleLinkButtonOpen, toggleSingleLinkButtonOpen] = useDialog()
16
- const [twoLinkButtonOpen, toggleTwoLinkButtonOpen] = useDialog()
17
-
12
+ const [defaultAlertOpened, toggleDefaultAlert] = useDialog()
13
+ const [cautionAlertOpened, toggleCautionAlert] = useDialog()
14
+ const [deleteAlertOpened, toggleDeleteAlert] = useDialog()
18
15
 
19
16
  const dialogs = [
20
17
  {
21
- status: "info",
18
+ size: "sm",
19
+ status: "default",
22
20
  text: "Text explaining why there is an alert",
23
21
  title: "Are you sure?",
24
- toggle: toggleSingleButtonOpen,
25
- visible: singleButtonOpen,
26
- confirmedButton:"Ok, Thanks",
27
- },
28
- {
29
- status: "error",
30
- text: "Text explaining the error",
31
- title: "Error Message",
32
- confirmedButton:"Yes, Action",
33
- cancelledButton: "Ok, Cancel",
34
- toggle: toggleStackedButtonOpen,
35
- visible: stackedButtonOpen,
22
+ toggle: toggleDefaultAlert,
23
+ visible: defaultAlertOpened,
24
+ buttonOneText:"Yes, Action",
25
+ buttonTwoText: "No, Cancel"
36
26
  },
37
27
  {
28
+ size: "sm",
38
29
  status: "caution",
39
30
  text: "This is the action you will be taking",
40
31
  title: "Are you sure?",
41
- toggle: toggleSingleLinkButtonOpen,
42
- visible: singleLinkButtonOpen,
43
- linkConfirmedButton:"Ok, Thanks!"
32
+ toggle: toggleCautionAlert,
33
+ visible: cautionAlertOpened,
34
+ buttonOneText:"Yes, Action",
35
+ buttonTwoText: "No, Cancel"
44
36
  },
45
37
  {
46
- status: "success",
47
- text: "Text explaining what is successful",
48
- title: "Success",
49
- toggle: toggleTwoLinkButtonOpen,
50
- visible: twoLinkButtonOpen,
51
- linkConfirmedButton:"Ok",
52
- linkCancelledButton: "Cancel"
38
+ size: "sm",
39
+ status: "delete",
40
+ text: "You are about to delete ...",
41
+ title: "Delete",
42
+ toggle: toggleDeleteAlert,
43
+ visible: deleteAlertOpened,
44
+ buttonOneText:"Yes, Delete",
45
+ buttonTwoText: "No, Cancel"
53
46
  }
54
47
  ]
55
48
 
@@ -58,27 +51,21 @@ const DialogStackedAlert = () => {
58
51
  <Flex>
59
52
  <Button
60
53
  marginRight="md"
61
- onClick={toggleSingleButtonOpen}
62
- >
63
- {"1 Button Information Status"}
64
- </Button>
65
- <Button
66
- marginRight="md"
67
- onClick={toggleStackedButtonOpen}
54
+ onClick={toggleDefaultAlert}
68
55
  >
69
- {"2 Button Error Status"}
56
+ {"Default Status"}
70
57
  </Button>
71
58
  <Button
72
59
  marginRight="md"
73
- onClick={toggleSingleLinkButtonOpen}
60
+ onClick={toggleCautionAlert}
74
61
  >
75
- {"1 Link Button Caution"}
62
+ {"Caution Status"}
76
63
  </Button>
77
64
  <Button
78
65
  marginRight="md"
79
- onClick={toggleTwoLinkButtonOpen}
66
+ onClick={toggleDeleteAlert}
80
67
  >
81
- {"2 Link Button Success"}
68
+ {"Delete Status"}
82
69
  </Button>
83
70
  </Flex>
84
71
  <Flex>
@@ -88,61 +75,36 @@ const DialogStackedAlert = () => {
88
75
  key={dialog.status}
89
76
  onClose={dialog.toggle}
90
77
  opened={dialog.visible}
91
- size="sm"
78
+ size={dialog.size}
92
79
  status={dialog.status}
93
80
  text={dialog.text}
94
81
  title={dialog.title}
95
82
  >
96
- <If condition={dialog.cancelledButton || dialog.confirmedButton}>
97
- <Dialog.Footer>
98
- <Button
99
- fullWidth
100
- onClick={dialog.toggle}
101
- >
102
- {dialog.confirmedButton}
103
- </Button>
104
- </Dialog.Footer>
105
- <If condition={dialog.cancelledButton}>
106
- <Dialog.Footer paddingTop="none">
107
- <Button
108
- fullWidth
109
- onClick={dialog.toggle}
110
- variant="secondary"
111
- >
112
- {dialog.cancelledButton}
113
- </Button>
114
- </Dialog.Footer>
115
- </If>
116
- </If>
117
- <If condition={dialog.linkCancelledButton || dialog.linkConfirmedButton} >
118
- <SectionSeparator />
119
- <Flex
120
- inline="flex-container"
121
- vertical="stretch"
122
- >
123
- <FlexItem flex={1} >
124
- <Button
125
- fullWidth
126
- onClick={dialog.toggle}
127
- variant="link"
128
- >
129
- {dialog.linkConfirmedButton}
130
- </Button>
131
- </FlexItem>
132
- <If condition={dialog.linkCancelledButton}>
133
- <SectionSeparator orientation="vertical"/>
134
- <FlexItem flex={1}>
135
- <Button
136
- fullWidth
137
- onClick={dialog.toggle}
138
- variant="link"
139
- >
140
- {dialog.linkCancelledButton}
141
- </Button>
142
- </FlexItem>
143
- </If>
144
- </Flex>
145
- </If>
83
+ <Dialog.Footer
84
+ padding="sm"
85
+ paddingBottom = "none"
86
+ paddingX="md"
87
+ >
88
+ <Button
89
+ fullWidth
90
+ onClick={dialog.toggle}
91
+ >
92
+ {dialog.buttonOneText}
93
+ </Button>
94
+ </Dialog.Footer>
95
+ <Dialog.Footer
96
+ padding="sm"
97
+ paddingBottom = "md"
98
+ paddingX="md"
99
+ >
100
+ <Button
101
+ fullWidth
102
+ onClick={dialog.toggle}
103
+ variant="secondary"
104
+ >
105
+ {dialog.buttonTwoText}
106
+ </Button>
107
+ </Dialog.Footer>
146
108
  </Dialog>
147
109
  ))}
148
110
  </Flex>
@@ -12,57 +12,70 @@ const useDialog = (visible = false) => {
12
12
  }
13
13
 
14
14
  const DialogStatus = () => {
15
- const [infoAlertOpened, toggleInfoAlert] = useDialog()
15
+ const [defaultAlertOpened, toggleDefaultAlert] = useDialog()
16
16
  const [cautionAlertOpened, toggleCautionAlert] = useDialog()
17
+ const [deleteAlertOpened, toggleDeleteAlert] = useDialog()
18
+ const [infoAlertOpened, toggleInfoAlert] = useDialog()
17
19
  const [successAlertOpened, toggleSuccessAlert] = useDialog()
18
20
  const [errorAlertOpened, toggleErrorAlert] = useDialog()
19
- const [deleteAlertOpened, toggleDeleteAlert] = useDialog()
20
21
 
21
22
  const dialogs = [
22
23
  {
23
- status: "info",
24
+ size: "status_size",
25
+ status: "default",
24
26
  text: "Text explaining why there is an alert",
25
- title: "Are you Sure?",
26
- toggle: toggleInfoAlert,
27
- visible: infoAlertOpened,
28
- buttonOneText:"No, Cancel",
29
- buttonTwoText: "Yes, Action"
27
+ title: "Are you sure?",
28
+ toggle: toggleDefaultAlert,
29
+ visible: defaultAlertOpened,
30
+ buttonOneText:"Yes, Action",
31
+ buttonTwoText: "No, Cancel"
30
32
  },
31
33
  {
34
+ size: "status_size",
32
35
  status: "caution",
33
36
  text: "This is the action you will be taking",
34
- title: "Are you Sure?",
37
+ title: "Are you sure?",
35
38
  toggle: toggleCautionAlert,
36
39
  visible: cautionAlertOpened,
37
- buttonOneText:"No, Cancel",
38
- buttonTwoText: "Yes, Action"
40
+ buttonOneText:"Yes, Action",
41
+ buttonTwoText: "No, Cancel"
39
42
  },
40
43
  {
44
+ size: "status_size",
41
45
  status: "delete",
42
46
  text: "You are about to delete ...",
43
47
  title: "Delete",
44
48
  toggle: toggleDeleteAlert,
45
49
  visible: deleteAlertOpened,
46
- buttonOneText:"No, Cancel",
47
- buttonTwoText: "Yes, Delete"
50
+ buttonOneText:"Yes, Delete",
51
+ buttonTwoText: "No, Cancel"
48
52
  },
49
53
  {
50
- status: "error",
51
- text: "Text explaining the error",
52
- title: "Error Message",
53
- toggle: toggleErrorAlert,
54
- visible: errorAlertOpened,
55
- buttonOneText:"No, Cancel",
56
- buttonTwoText: "Ok, Thanks"
54
+ size: "sm",
55
+ status: "info",
56
+ text: "Text explaining why there is an alert",
57
+ title: "Information",
58
+ toggle: toggleInfoAlert,
59
+ visible: infoAlertOpened,
60
+ buttonOneText:"Ok, Thanks!",
57
61
  },
58
62
  {
63
+ size: "sm",
59
64
  status: "success",
60
65
  text: "Text explaining what is successful",
61
66
  title: "Success!",
62
67
  toggle: toggleSuccessAlert,
63
68
  visible: successAlertOpened,
64
- buttonOneText:"No, Cancel",
65
- buttonTwoText: "Ok, Thanks"
69
+ buttonOneText: "Great!",
70
+ },
71
+ {
72
+ size: "sm",
73
+ status: "error",
74
+ text: "Text explaining the error",
75
+ title: "Error Message",
76
+ toggle: toggleErrorAlert,
77
+ visible: errorAlertOpened,
78
+ buttonOneText:"Oh no!",
66
79
  },
67
80
  ]
68
81
 
@@ -71,9 +84,9 @@ const DialogStatus = () => {
71
84
  <Flex>
72
85
  <Button
73
86
  marginRight="md"
74
- onClick={toggleInfoAlert}
87
+ onClick={toggleDefaultAlert}
75
88
  >
76
- {"Information Status"}
89
+ {"Default Status"}
77
90
  </Button>
78
91
  <Button
79
92
  marginRight="md"
@@ -83,18 +96,27 @@ const DialogStatus = () => {
83
96
  </Button>
84
97
  <Button
85
98
  marginRight="md"
86
- onClick={toggleSuccessAlert}
99
+ onClick={toggleDeleteAlert}
87
100
  >
88
- {"Success Status"}
101
+ {"Delete Status"}
89
102
  </Button>
90
- <Button onClick={toggleErrorAlert}>
91
- {"Error Status"}
103
+ <Button
104
+ marginRight="md"
105
+ onClick={toggleInfoAlert}
106
+ >
107
+ {"Information Status"}
92
108
  </Button>
93
109
  <Button
94
110
  marginRight="md"
95
- onClick={toggleDeleteAlert}
111
+ onClick={toggleSuccessAlert}
96
112
  >
97
- {"Delete Status"}
113
+ {"Success Status"}
114
+ </Button>
115
+ <Button
116
+ marginRight="md"
117
+ onClick={toggleErrorAlert}
118
+ >
119
+ {"Error Status"}
98
120
  </Button>
99
121
  </Flex>
100
122
  <Flex>
@@ -103,22 +125,37 @@ const DialogStatus = () => {
103
125
  key={dialog.status}
104
126
  onClose={dialog.toggle}
105
127
  opened={dialog.visible}
128
+ size={dialog.size}
106
129
  status={dialog.status}
107
130
  text={dialog.text}
108
131
  title={dialog.title}
109
132
  >
110
- <Dialog.Footer>
111
- <Button
112
- onClick={dialog.toggle}
113
- variant="secondary"
114
- >
115
- {dialog.buttonOneText}
116
- </Button>
117
- <Button
118
- onClick={dialog.toggle}
119
- >
120
- {dialog.buttonTwoText}
121
- </Button>
133
+ <Dialog.Footer
134
+ paddingBottom="md"
135
+ paddingX="md"
136
+ >
137
+ <If condition={!dialog.buttonTwoText}>
138
+ <Button
139
+ fullWidth
140
+ onClick={dialog.toggle}
141
+ >
142
+ {dialog.buttonOneText}
143
+ </Button>
144
+ </If>
145
+ <If condition={dialog.buttonTwoText}>
146
+ <Button
147
+ onClick={dialog.toggle}
148
+ paddingRight="xl"
149
+ >
150
+ {dialog.buttonOneText}
151
+ </Button>
152
+ <Button
153
+ onClick={dialog.toggle}
154
+ variant="secondary"
155
+ >
156
+ {dialog.buttonTwoText}
157
+ </Button>
158
+ </If>
122
159
  </Dialog.Footer>
123
160
  </Dialog>
124
161
  ))}
@@ -0,0 +1,80 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import classnames from "classnames";
3
+
4
+ import { globalProps } from "../utilities/globalProps";
5
+
6
+ import Icon from "../pb_icon/_icon";
7
+ import Title from "../pb_title/_title";
8
+
9
+ const iconMap = {
10
+ success: "check",
11
+ error: "exclamation-triangle",
12
+ neutral: "info-circle",
13
+ tip: "info-circle",
14
+ };
15
+
16
+ type FixedConfirmationToastProps = {
17
+ className?: string;
18
+ closeable?: boolean;
19
+ data?: string;
20
+ horizontal?: "right" | "left" | "center";
21
+ id?: string;
22
+ multiLine?: boolean;
23
+ onClose?: () => void;
24
+ open?: boolean;
25
+ status?: "success" | "error" | "neutral" | "tip";
26
+ text: string;
27
+ vertical?: "top" | "bottom";
28
+ };
29
+
30
+ const FixedConfirmationToast = (props: FixedConfirmationToastProps) => {
31
+ const [showToast, toggleToast] = useState(true);
32
+ const {
33
+ className,
34
+ closeable = false,
35
+ horizontal,
36
+ multiLine = false,
37
+ onClose = () => {},
38
+ open = true,
39
+ status = "neutral",
40
+ text,
41
+ vertical,
42
+ } = props;
43
+ const css = classnames(
44
+ `pb_fixed_confirmation_toast_kit_${status}`,
45
+ { _multi_line: multiLine },
46
+ { [`positioned_toast ${vertical} ${horizontal}`]: vertical && horizontal },
47
+ globalProps(props),
48
+ className
49
+ );
50
+ const icon = iconMap[status];
51
+
52
+ useEffect(() => {
53
+ toggleToast(open);
54
+ }, [open]);
55
+
56
+ const handleClick = () => {
57
+ toggleToast(!closeable);
58
+ onClose();
59
+ };
60
+
61
+ return (
62
+ <>
63
+ {showToast && (
64
+ <div className={css} onClick={handleClick}>
65
+ {icon && <Icon className="pb_icon" fixedWidth icon={icon} />}
66
+ <Title
67
+ className="pb_fixed_confirmation_toast_text"
68
+ size={4}
69
+ text={text}
70
+ />
71
+ {closeable && (
72
+ <Icon className="pb_icon" fixedWidth={false} icon="times" />
73
+ )}
74
+ </div>
75
+ )}
76
+ </>
77
+ );
78
+ };
79
+
80
+ export default FixedConfirmationToast;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/jsx-no-target-blank */
1
2
  /* eslint-disable react/no-multi-comp, flowtype/space-before-type-colon */
2
3
 
3
4
  import React from 'react'
@@ -14,6 +15,8 @@ type HashtagProps = {
14
15
  dark?: boolean,
15
16
  data?: string,
16
17
  id?: string,
18
+ newWindow?: boolean,
19
+ rel?: string,
17
20
  text?: string,
18
21
  type: "default" | "home" | "project" | "appointment",
19
22
  url?: string,
@@ -33,6 +36,8 @@ const Hashtag = (props: HashtagProps) => {
33
36
  dark = false,
34
37
  data = {},
35
38
  id,
39
+ newWindow,
40
+ rel,
36
41
  text,
37
42
  type = 'default',
38
43
  url,
@@ -49,7 +54,11 @@ const Hashtag = (props: HashtagProps) => {
49
54
  className={classes}
50
55
  id={id}
51
56
  >
52
- <a href={url}>
57
+ <a
58
+ href={url}
59
+ rel={(newWindow ? "noreferrer" : rel)}
60
+ target={(newWindow ? '_blank' : '_self')}
61
+ >
53
62
  <Badge
54
63
  dark={dark}
55
64
  text={typeMap[type] + text}
@@ -0,0 +1,5 @@
1
+ <%= pb_rails("hashtag", props: {text: "Open in the same Window", url: "https://google.com", type: "project"}) %>
2
+
3
+ <br/><br/>
4
+
5
+ <%= pb_rails("hashtag", props: {text: "Open in a new Window", url: "https://google.com", type: "project", new_window: true}) %>