@pingux/astro 1.12.0-alpha.4 → 1.13.0-alpha.1

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 (26) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/lib/cjs/components/Breadcrumbs/Breadcrumbs.js +2 -1
  3. package/lib/cjs/components/IconButtonToggle/IconButtonToggle.js +78 -0
  4. package/lib/cjs/components/IconButtonToggle/IconButtonToggle.stories.js +76 -0
  5. package/lib/cjs/components/IconButtonToggle/IconButtonToggle.test.js +60 -0
  6. package/lib/cjs/components/IconButtonToggle/index.js +18 -0
  7. package/lib/cjs/hooks/index.js +18 -0
  8. package/lib/cjs/hooks/useComponentToggle/index.js +18 -0
  9. package/lib/cjs/hooks/useComponentToggle/useComponentToggle.js +70 -0
  10. package/lib/cjs/hooks/useComponentToggle/useComponentToggle.test.js +133 -0
  11. package/lib/cjs/index.js +72 -49
  12. package/lib/cjs/recipes/OneWayToBidirectionalArrow.stories.js +160 -0
  13. package/lib/cjs/styles/variants/buttons.js +8 -1
  14. package/lib/components/Breadcrumbs/Breadcrumbs.js +2 -1
  15. package/lib/components/IconButtonToggle/IconButtonToggle.js +59 -0
  16. package/lib/components/IconButtonToggle/IconButtonToggle.stories.js +40 -0
  17. package/lib/components/IconButtonToggle/IconButtonToggle.test.js +46 -0
  18. package/lib/components/IconButtonToggle/index.js +1 -0
  19. package/lib/hooks/index.js +2 -0
  20. package/lib/hooks/useComponentToggle/index.js +1 -0
  21. package/lib/hooks/useComponentToggle/useComponentToggle.js +55 -0
  22. package/lib/hooks/useComponentToggle/useComponentToggle.test.js +105 -0
  23. package/lib/index.js +2 -0
  24. package/lib/recipes/OneWayToBidirectionalArrow.stories.js +137 -0
  25. package/lib/styles/variants/buttons.js +8 -1
  26. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
2
+ import React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import IconButton from '../IconButton';
5
+ import Icon from '../Icon';
6
+ import { useComponentToggle } from '../../hooks';
7
+ import { jsx as ___EmotionJSX } from "@emotion/react";
8
+
9
+ var IconButtonToggle = function IconButtonToggle(props) {
10
+ var toggledIcon = props.toggledIcon,
11
+ defaultIcon = props.defaultIcon,
12
+ buttonProps = props.buttonProps,
13
+ iconProps = props.iconProps,
14
+ isToggled = props.isToggled,
15
+ onToggle = props.onToggle,
16
+ title = props.title;
17
+ var conditionalRenderProps = {
18
+ ComponentToRenderIfTrue: toggledIcon,
19
+ ComponentToRenderIfFalse: defaultIcon,
20
+ condition: isToggled,
21
+ onConditionChange: onToggle
22
+ };
23
+
24
+ var _useComponentToggle = useComponentToggle(conditionalRenderProps),
25
+ handleConditionChange = _useComponentToggle.handleConditionChange,
26
+ RenderedComponent = _useComponentToggle.RenderedComponent;
27
+
28
+ return ___EmotionJSX(IconButton, _extends({
29
+ onPress: handleConditionChange
30
+ }, buttonProps, {
31
+ title: title
32
+ }), ___EmotionJSX(Icon, _extends({
33
+ icon: RenderedComponent
34
+ }, iconProps)));
35
+ };
36
+
37
+ IconButtonToggle.propTypes = {
38
+ /** Props object that is spread into the icon element. */
39
+ iconProps: PropTypes.shape({}),
40
+
41
+ /** Props object that is spread into the button element. */
42
+ buttonProps: PropTypes.shape({}),
43
+
44
+ /** The icon that will render by default. */
45
+ defaultIcon: PropTypes.elementType.isRequired,
46
+
47
+ /** The icon that will render after toggling the icon. */
48
+ toggledIcon: PropTypes.elementType.isRequired,
49
+
50
+ /** Whether or not the icon is toggled. (use only when controlled) */
51
+ isToggled: PropTypes.bool,
52
+
53
+ /** Function that is passed into the IconButton within this component. */
54
+ onToggle: PropTypes.func,
55
+
56
+ /** Content will be displayed in a tooltip on hover or focus. */
57
+ title: PropTypes.string
58
+ };
59
+ export default IconButtonToggle;
@@ -0,0 +1,40 @@
1
+ import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
2
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
3
+ import React, { useState } from 'react';
4
+ import EyeIcon from 'mdi-react/EyeOutlineIcon';
5
+ import EyeOffIcon from 'mdi-react/EyeOffOutlineIcon';
6
+ import IconButtonToggle from '.';
7
+ import { jsx as ___EmotionJSX } from "@emotion/react";
8
+ export default {
9
+ title: 'IconButtonToggle',
10
+ component: IconButtonToggle
11
+ };
12
+ export var Default = function Default(args) {
13
+ return ___EmotionJSX(IconButtonToggle, _extends({}, args, {
14
+ toggledIcon: EyeIcon,
15
+ defaultIcon: EyeOffIcon,
16
+ buttonProps: {
17
+ 'aria-label': 'eye icon'
18
+ }
19
+ }));
20
+ };
21
+ export var Controlled = function Controlled(args) {
22
+ var _useState = useState(false),
23
+ _useState2 = _slicedToArray(_useState, 2),
24
+ isToggled = _useState2[0],
25
+ onToggledChange = _useState2[1];
26
+
27
+ var handleToggleChange = function handleToggleChange() {
28
+ onToggledChange(!isToggled);
29
+ };
30
+
31
+ return ___EmotionJSX(IconButtonToggle, _extends({}, args, {
32
+ toggledIcon: EyeIcon,
33
+ defaultIcon: EyeOffIcon,
34
+ onToggle: handleToggleChange,
35
+ isToggled: isToggled,
36
+ buttonProps: {
37
+ 'aria-label': 'eye icon'
38
+ }
39
+ }));
40
+ };
@@ -0,0 +1,46 @@
1
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
2
+ import React from 'react';
3
+ import EyeIcon from 'mdi-react/EyeOutlineIcon';
4
+ import EyeOffIcon from 'mdi-react/EyeOffOutlineIcon';
5
+ import axeTest from '../../utils/testUtils/testAxe';
6
+ import { render, screen } from '../../utils/testUtils/testWrapper';
7
+ import IconButtonToggle from '.';
8
+ import { jsx as ___EmotionJSX } from "@emotion/react";
9
+ var iconTestId = 'test-icon';
10
+
11
+ var OnIcon = function OnIcon(props) {
12
+ return ___EmotionJSX(EyeIcon, _extends({
13
+ "data-testid": iconTestId
14
+ }, props));
15
+ };
16
+
17
+ var OffIcon = function OffIcon(props) {
18
+ return ___EmotionJSX(EyeOffIcon, _extends({
19
+ "data-testid": iconTestId
20
+ }, props));
21
+ };
22
+
23
+ var testId = 'test-button';
24
+ var defaultProps = {
25
+ buttonProps: {
26
+ 'data-testid': testId,
27
+ 'aria-label': 'Eye'
28
+ },
29
+ defaultIcon: OffIcon,
30
+ toggledIcon: OnIcon
31
+ };
32
+
33
+ var getComponent = function getComponent() {
34
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
35
+ return render(___EmotionJSX(IconButtonToggle, _extends({}, defaultProps, props)));
36
+ }; // Need to be added to each test file to test accessibility using axe.
37
+
38
+
39
+ axeTest(getComponent);
40
+ test('default icon button', function () {
41
+ getComponent();
42
+ var button = screen.getByRole('button');
43
+ expect(button).toHaveAttribute('data-testid', testId);
44
+ expect(button).toBeInstanceOf(HTMLButtonElement);
45
+ expect(button).toBeInTheDocument();
46
+ });
@@ -0,0 +1 @@
1
+ export { default } from './IconButtonToggle';
@@ -6,6 +6,8 @@ export { default as useLabelHeight } from './useLabelHeight';
6
6
  export { default as useModalState } from './useModalState';
7
7
  export { default as useOverlayPanelState } from './useOverlayPanelState';
8
8
  export { default as usePropWarning } from './usePropWarning';
9
+ export { default as useProgressiveState } from './useProgressiveState';
10
+ export { default as useComponentToggle } from './useComponentToggle';
9
11
  export { default as useNavBarPress } from './useNavBarPress';
10
12
  export { default as useRockerButton } from './useRockerButton';
11
13
  export { default as useSelectField } from './useSelectField';
@@ -0,0 +1 @@
1
+ export { default } from './useComponentToggle';
@@ -0,0 +1,55 @@
1
+ import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
2
+ import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
3
+ import { useProgressiveState } from '../index';
4
+ /**
5
+ * Returns one of two components that are supplied via props.
6
+ * A boolean value is used to determine which component to render.
7
+ * State can be handled by either props or within this hook if props are not provided.
8
+ * Also returns a function that inverts the boolean attribute, and calls a callback function.
9
+ * @param {Object} [props] Properties provided to the state
10
+ * @param {Boolean} [props.condition] Boolean that controls which component is returned.
11
+ * @param {Component} [props.ComponentToRenderIfTrue]
12
+ * Component that is returned when the condition is true.
13
+ * @param {Component} [props.ComponentToRenderIfFalse]
14
+ * Component that is returned when the condition is false.
15
+ * @param {Function} [props.onConditionChange]
16
+ * Callback function that is called, when the condition boolean changes, if it is provided .
17
+ * @returns {Object} `{ isOpen: Boolean, open: Function, close: Function, toggle: Function }`
18
+ * @returns {Object} `{ handleCondtionChange: Function, renderedComponent: Component, }`
19
+ */
20
+
21
+ var useComponentToggle = function useComponentToggle() {
22
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
23
+ var ComponentToRenderIfTrue = props.ComponentToRenderIfTrue,
24
+ ComponentToRenderIfFalse = props.ComponentToRenderIfFalse,
25
+ condition = props.condition,
26
+ onConditionChange = props.onConditionChange;
27
+
28
+ var _useProgressiveState = useProgressiveState(condition, function () {}),
29
+ _useProgressiveState2 = _slicedToArray(_useProgressiveState, 2),
30
+ isToggled = _useProgressiveState2[0],
31
+ setIsToggled = _useProgressiveState2[1];
32
+
33
+ var RenderedComponent = isToggled ? ComponentToRenderIfTrue : ComponentToRenderIfFalse;
34
+
35
+ var handleConditionChange = function handleConditionChange() {
36
+ setIsToggled(!isToggled);
37
+
38
+ if (onConditionChange) {
39
+ var _context;
40
+
41
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
42
+ args[_key] = arguments[_key];
43
+ }
44
+
45
+ onConditionChange.apply(void 0, _concatInstanceProperty(_context = [!isToggled]).call(_context, args));
46
+ }
47
+ };
48
+
49
+ return {
50
+ handleConditionChange: handleConditionChange,
51
+ RenderedComponent: RenderedComponent
52
+ };
53
+ };
54
+
55
+ export default useComponentToggle;
@@ -0,0 +1,105 @@
1
+ import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime-corejs3/helpers/esm/asyncToGenerator";
3
+ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
4
+ import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
5
+ import React, { useState } from 'react';
6
+ import { renderHook, act } from '@testing-library/react-hooks';
7
+ import userEvent from '@testing-library/user-event';
8
+ import { render, screen } from '@testing-library/react';
9
+ import useComponentToggle from './useComponentToggle';
10
+ import { jsx as ___EmotionJSX } from "@emotion/react";
11
+ var callback = jest.fn();
12
+ var condition = false;
13
+ var defaultProps = {
14
+ condition: condition,
15
+ onConditionChange: callback,
16
+ ComponentToRenderIfTrue: 'true-string',
17
+ ComponentToRenderIfFalse: 'false-string'
18
+ };
19
+
20
+ var TestComponent = function TestComponent() {
21
+ var _useState = useState(false),
22
+ _useState2 = _slicedToArray(_useState, 2),
23
+ thisCondition = _useState2[0],
24
+ setCondition = _useState2[1];
25
+
26
+ var conditionalRenderProps = {
27
+ condition: thisCondition,
28
+ onConditionChange: setCondition,
29
+ ComponentToRenderIfTrue: 'true-string',
30
+ ComponentToRenderIfFalse: 'false-string',
31
+ onConditionChangeProp: callback
32
+ };
33
+
34
+ var _useComponentToggle = useComponentToggle(conditionalRenderProps),
35
+ handleConditionChange = _useComponentToggle.handleConditionChange,
36
+ RenderedComponent = _useComponentToggle.RenderedComponent;
37
+
38
+ return ___EmotionJSX("button", {
39
+ "data-testid": "test-div",
40
+ onClick: handleConditionChange,
41
+ onKeyDown: handleConditionChange
42
+ }, RenderedComponent);
43
+ };
44
+
45
+ var getComponent = function getComponent() {
46
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
47
+ return render(___EmotionJSX(TestComponent, _extends({}, props, defaultProps)));
48
+ };
49
+
50
+ test('default useField', function () {
51
+ renderHook(function () {
52
+ return useComponentToggle();
53
+ });
54
+ });
55
+ test('callback function should call, if provided', function () {
56
+ var _renderHook = renderHook(function () {
57
+ return useComponentToggle(defaultProps);
58
+ }),
59
+ result = _renderHook.result;
60
+
61
+ act(function () {
62
+ return result.current.handleConditionChange();
63
+ });
64
+ expect(callback).toHaveBeenCalled();
65
+ });
66
+ test('expect hook to return correct data shape', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
67
+ var _renderHook2, result, _result$current, handleConditionChange, RenderedComponent;
68
+
69
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
70
+ while (1) {
71
+ switch (_context.prev = _context.next) {
72
+ case 0:
73
+ _renderHook2 = renderHook(function () {
74
+ return useComponentToggle(defaultProps);
75
+ }), result = _renderHook2.result;
76
+ _result$current = result.current, handleConditionChange = _result$current.handleConditionChange, RenderedComponent = _result$current.RenderedComponent;
77
+ expect(handleConditionChange).toEqual(expect.any(Function));
78
+ expect(RenderedComponent).toEqual('false-string');
79
+
80
+ case 4:
81
+ case "end":
82
+ return _context.stop();
83
+ }
84
+ }
85
+ }, _callee);
86
+ })));
87
+ test('expect conditional toggling to work', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
88
+ var component;
89
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
90
+ while (1) {
91
+ switch (_context2.prev = _context2.next) {
92
+ case 0:
93
+ getComponent();
94
+ component = screen.getByTestId('test-div');
95
+ expect(component).toHaveTextContent('false-string');
96
+ userEvent.click(component);
97
+ expect(component).toHaveTextContent('true-string');
98
+
99
+ case 5:
100
+ case "end":
101
+ return _context2.stop();
102
+ }
103
+ }
104
+ }, _callee2);
105
+ })));
package/lib/index.js CHANGED
@@ -43,6 +43,8 @@ export { default as Icon } from './components/Icon';
43
43
  export * from './components/Icon';
44
44
  export { default as IconButton } from './components/IconButton';
45
45
  export * from './components/IconButton';
46
+ export { default as IconButtonToggle } from './components/IconButtonToggle';
47
+ export * from './components/IconButtonToggle';
46
48
  export { default as Image } from './components/Image';
47
49
  export * from './components/Image';
48
50
  export { default as ImageUploadField } from './components/ImageUploadField';
@@ -0,0 +1,137 @@
1
+ import React from 'react';
2
+ import DragVerticalIcon from 'mdi-react/DragVerticalIcon';
3
+ import DeleteIcon from 'mdi-react/DeleteIcon';
4
+ import CogsIcon from 'mdi-react/CogsIcon';
5
+ import Box from '../components/Box';
6
+ import { Icon, ComboBoxField, Item, IconButton, IconButtonToggle } from '../index';
7
+ import { jsx as ___EmotionJSX } from "@emotion/react";
8
+ export default {
9
+ title: 'Recipes/OneWayToBidirectionalArrow'
10
+ };
11
+ var items = [{
12
+ name: 'Last Name',
13
+ id: '1'
14
+ }, {
15
+ name: 'First Name',
16
+ id: '2'
17
+ }, {
18
+ name: 'Third Option',
19
+ id: '3'
20
+ }];
21
+ export var Default = function Default() {
22
+ var CustomOnSvg = function CustomOnSvg() {
23
+ return ___EmotionJSX("svg", {
24
+ width: "24",
25
+ height: "24",
26
+ viewBox: "0 0 24 24",
27
+ fill: "none",
28
+ xmlns: "http://www.w3.org/2000/svg"
29
+ }, ___EmotionJSX("path", {
30
+ d: "M8 10V13H14V18H8V21L2 15.5L8 10Z",
31
+ fill: "#CACED3"
32
+ }), ___EmotionJSX("path", {
33
+ d: "M9.83325 10.6251V6.37511H15.4999V2.94678L21.0533 8.50011L15.4999 14.0534V10.6251H9.83325Z",
34
+ fill: "#4462ED"
35
+ }), ___EmotionJSX("path", {
36
+ d: "M8 10V13H14V18H8V21L2 15.5L8 10ZM22 8.5L16 3V6H10V11H16V14L22 8.5Z",
37
+ fill: "#515F6B"
38
+ }));
39
+ };
40
+
41
+ var CustomOffSvg = function CustomOffSvg() {
42
+ return ___EmotionJSX("svg", {
43
+ width: "24",
44
+ height: "24",
45
+ viewBox: "0 0 24 24",
46
+ fill: "none",
47
+ xmlns: "http://www.w3.org/2000/svg"
48
+ }, ___EmotionJSX("path", {
49
+ d: "M8 10V13H14V18H8V21L2 15.5L8 10Z",
50
+ fill: "#CACED3"
51
+ }), ___EmotionJSX("path", {
52
+ d: "M9.83331 10.6251V6.37511H15.5V2.94678L21.0533 8.50011L15.5 14.0534V10.6251H9.83331Z",
53
+ fill: "#4462ED"
54
+ }));
55
+ };
56
+
57
+ return ___EmotionJSX(Box, {
58
+ sx: {
59
+ alignItems: 'center'
60
+ },
61
+ isRow: true
62
+ }, ___EmotionJSX(Icon, {
63
+ icon: DragVerticalIcon,
64
+ size: 25,
65
+ color: "neutral.50"
66
+ }), ___EmotionJSX(ComboBoxField, {
67
+ items: items,
68
+ defaultSelectedKey: "Last Name",
69
+ containerProps: {
70
+ width: '275px'
71
+ },
72
+ labelProps: {
73
+ mb: 0
74
+ },
75
+ "aria-label": "Row one value",
76
+ controlProps: {
77
+ 'aria-label': 'test'
78
+ }
79
+ }, function (item) {
80
+ return ___EmotionJSX(Item, {
81
+ key: item.name,
82
+ "data-id": item.name
83
+ }, item.name);
84
+ }), ___EmotionJSX(Box, {
85
+ sx: {
86
+ ml: '5px',
87
+ mr: '5px',
88
+ flexShrink: 0
89
+ }
90
+ }, ___EmotionJSX(IconButtonToggle, {
91
+ toggledIcon: CustomOnSvg,
92
+ defaultIcon: CustomOffSvg,
93
+ title: "Bidirectional/ Outbound toggle",
94
+ iconProps: {
95
+ size: 20
96
+ },
97
+ buttonProps: {
98
+ variant: 'svgIconButton'
99
+ }
100
+ })), ___EmotionJSX(ComboBoxField, {
101
+ items: items,
102
+ defaultSelectedKey: "First Name",
103
+ containerProps: {
104
+ width: '275px'
105
+ },
106
+ labelProps: {
107
+ mb: 0
108
+ },
109
+ controlProps: {
110
+ 'aria-label': 'Row one Pingone value'
111
+ }
112
+ }, function (item) {
113
+ return ___EmotionJSX(Item, {
114
+ key: item.name,
115
+ "data-id": item.name
116
+ }, item.name);
117
+ }), ___EmotionJSX(Box, {
118
+ isRow: true,
119
+ alignItems: "center",
120
+ sx: {
121
+ marginLeft: '12px',
122
+ marginRight: '12px'
123
+ }
124
+ }, ___EmotionJSX(IconButton, null, ___EmotionJSX(Icon, {
125
+ icon: CogsIcon,
126
+ color: "neutral.30",
127
+ size: 20,
128
+ title: "edit icon"
129
+ })), ___EmotionJSX(IconButton, {
130
+ ml: "5px"
131
+ }, ___EmotionJSX(Icon, {
132
+ icon: DeleteIcon,
133
+ color: "neutral.30",
134
+ size: 20,
135
+ title: "delete icon"
136
+ }))));
137
+ };
@@ -116,6 +116,12 @@ var iconButton = {
116
116
  }
117
117
  };
118
118
 
119
+ var svgIconButton = _objectSpread(_objectSpread({}, iconButton), {}, {
120
+ path: {
121
+ fill: 'default'
122
+ }
123
+ });
124
+
119
125
  var square = _objectSpread(_objectSpread({}, iconButton), {}, {
120
126
  borderRadius: '2px'
121
127
  });
@@ -701,5 +707,6 @@ export default {
701
707
  colorBlock: colorBlock,
702
708
  menuTab: menuTab,
703
709
  collapsiblePanelToggle: collapsiblePanelToggle,
704
- neutralText: neutralText
710
+ neutralText: neutralText,
711
+ svgIconButton: svgIconButton
705
712
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pingux/astro",
3
- "version": "1.12.0-alpha.4",
3
+ "version": "1.13.0-alpha.1",
4
4
  "description": "PingUX themeable React component library",
5
5
  "author": "ux-development@pingidentity.com",
6
6
  "license": "Apache-2.0",