@pie-lib/config-ui 12.0.0-beta.4 → 12.0.0-next.0

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 (120) hide show
  1. package/CHANGELOG.json +8 -1653
  2. package/CHANGELOG.md +540 -58
  3. package/LICENSE.md +5 -0
  4. package/NEXT.CHANGELOG.json +1 -0
  5. package/lib/alert-dialog.js +44 -20
  6. package/lib/alert-dialog.js.map +1 -1
  7. package/lib/checkbox.js +59 -61
  8. package/lib/checkbox.js.map +1 -1
  9. package/lib/choice-configuration/feedback-menu.js +30 -65
  10. package/lib/choice-configuration/feedback-menu.js.map +1 -1
  11. package/lib/choice-configuration/index.js +231 -244
  12. package/lib/choice-configuration/index.js.map +1 -1
  13. package/lib/choice-utils.js +7 -19
  14. package/lib/choice-utils.js.map +1 -1
  15. package/lib/feedback-config/feedback-selector.js +89 -115
  16. package/lib/feedback-config/feedback-selector.js.map +1 -1
  17. package/lib/feedback-config/group.js +28 -42
  18. package/lib/feedback-config/group.js.map +1 -1
  19. package/lib/feedback-config/index.js +55 -87
  20. package/lib/feedback-config/index.js.map +1 -1
  21. package/lib/form-section.js +32 -34
  22. package/lib/form-section.js.map +1 -1
  23. package/lib/help.js +41 -80
  24. package/lib/help.js.map +1 -1
  25. package/lib/index.js +2 -32
  26. package/lib/index.js.map +1 -1
  27. package/lib/input.js +24 -57
  28. package/lib/input.js.map +1 -1
  29. package/lib/inputs.js +62 -88
  30. package/lib/inputs.js.map +1 -1
  31. package/lib/langs.js +59 -102
  32. package/lib/langs.js.map +1 -1
  33. package/lib/layout/config-layout.js +95 -67
  34. package/lib/layout/config-layout.js.map +1 -1
  35. package/lib/layout/index.js +1 -4
  36. package/lib/layout/index.js.map +1 -1
  37. package/lib/layout/layout-contents.js +130 -75
  38. package/lib/layout/layout-contents.js.map +1 -1
  39. package/lib/layout/settings-box.js +28 -58
  40. package/lib/layout/settings-box.js.map +1 -1
  41. package/lib/mui-box/index.js +42 -58
  42. package/lib/mui-box/index.js.map +1 -1
  43. package/lib/number-text-field-custom.js +164 -152
  44. package/lib/number-text-field-custom.js.map +1 -1
  45. package/lib/number-text-field.js +87 -119
  46. package/lib/number-text-field.js.map +1 -1
  47. package/lib/radio-with-label.js +33 -26
  48. package/lib/radio-with-label.js.map +1 -1
  49. package/lib/settings/display-size.js +17 -33
  50. package/lib/settings/display-size.js.map +1 -1
  51. package/lib/settings/index.js +26 -46
  52. package/lib/settings/index.js.map +1 -1
  53. package/lib/settings/panel.js +202 -221
  54. package/lib/settings/panel.js.map +1 -1
  55. package/lib/settings/settings-radio-label.js +37 -29
  56. package/lib/settings/settings-radio-label.js.map +1 -1
  57. package/lib/settings/toggle.js +40 -33
  58. package/lib/settings/toggle.js.map +1 -1
  59. package/lib/tabs/index.js +26 -57
  60. package/lib/tabs/index.js.map +1 -1
  61. package/lib/tags-input/index.js +51 -100
  62. package/lib/tags-input/index.js.map +1 -1
  63. package/lib/two-choice.js +47 -91
  64. package/lib/two-choice.js.map +1 -1
  65. package/lib/with-stateful-model.js +11 -34
  66. package/lib/with-stateful-model.js.map +1 -1
  67. package/package.json +22 -11
  68. package/src/__tests__/alert-dialog.test.jsx +283 -0
  69. package/src/__tests__/checkbox.test.jsx +249 -0
  70. package/src/__tests__/choice-utils.test.js +12 -0
  71. package/src/__tests__/form-section.test.jsx +334 -0
  72. package/src/__tests__/help.test.jsx +184 -0
  73. package/src/__tests__/input.test.jsx +192 -0
  74. package/src/__tests__/langs.test.jsx +457 -0
  75. package/src/__tests__/number-text-field-custom.test.jsx +438 -0
  76. package/src/__tests__/number-text-field.test.jsx +341 -0
  77. package/src/__tests__/radio-with-label.test.jsx +259 -0
  78. package/src/__tests__/settings-panel.test.js +187 -0
  79. package/src/__tests__/settings.test.jsx +515 -0
  80. package/src/__tests__/tabs.test.jsx +193 -0
  81. package/src/__tests__/two-choice.test.js +110 -0
  82. package/src/__tests__/with-stateful-model.test.jsx +145 -0
  83. package/src/alert-dialog.jsx +31 -16
  84. package/src/checkbox.jsx +45 -39
  85. package/src/choice-configuration/__tests__/feedback-menu.test.jsx +163 -0
  86. package/src/choice-configuration/__tests__/index.test.jsx +234 -0
  87. package/src/choice-configuration/feedback-menu.jsx +15 -28
  88. package/src/choice-configuration/index.jsx +233 -182
  89. package/src/choice-utils.js +1 -1
  90. package/src/feedback-config/__tests__/feedback-config.test.jsx +141 -0
  91. package/src/feedback-config/__tests__/feedback-selector.test.jsx +107 -0
  92. package/src/feedback-config/feedback-selector.jsx +65 -60
  93. package/src/feedback-config/group.jsx +26 -29
  94. package/src/feedback-config/index.jsx +59 -47
  95. package/src/form-section.jsx +26 -18
  96. package/src/help.jsx +27 -36
  97. package/src/index.js +2 -5
  98. package/src/input.jsx +9 -9
  99. package/src/inputs.jsx +36 -50
  100. package/src/langs.jsx +57 -73
  101. package/src/layout/__tests__/config.layout.test.jsx +59 -0
  102. package/src/layout/__tests__/layout-content.test.jsx +3 -0
  103. package/src/layout/config-layout.jsx +70 -37
  104. package/src/layout/layout-contents.jsx +96 -39
  105. package/src/layout/settings-box.jsx +22 -21
  106. package/src/mui-box/index.jsx +37 -45
  107. package/src/number-text-field-custom.jsx +136 -81
  108. package/src/number-text-field.jsx +59 -37
  109. package/src/radio-with-label.jsx +28 -12
  110. package/src/settings/display-size.jsx +14 -13
  111. package/src/settings/index.js +20 -12
  112. package/src/settings/panel.jsx +147 -110
  113. package/src/settings/settings-radio-label.jsx +29 -13
  114. package/src/settings/toggle.jsx +39 -20
  115. package/src/tabs/index.jsx +15 -19
  116. package/src/tags-input/__tests__/index.test.jsx +113 -0
  117. package/src/tags-input/index.jsx +42 -47
  118. package/src/two-choice.jsx +19 -23
  119. package/src/with-stateful-model.jsx +5 -5
  120. package/README.md +0 -12
@@ -1,64 +1,97 @@
1
1
  import React from 'react';
2
2
  import Measure from 'react-measure';
3
+ import { createTheme, ThemeProvider, StyledEngineProvider } from '@mui/material/styles';
4
+ import { withContentRect } from 'react-measure';
3
5
  import PropTypes from 'prop-types';
4
6
  import LayoutContents from './layout-contents';
5
7
  import SettingsBox from './settings-box';
8
+ import { AppendCSSRules } from '@pie-lib/render-ui';
6
9
 
7
- class ConfigLayout extends React.Component {
10
+ const theme = createTheme({
11
+ typography: {
12
+ fontFamily: 'inherit',
13
+ },
14
+ components: {
15
+ MuiButton: {
16
+ styleOverrides: {
17
+ contained: {
18
+ backgroundColor: '#e0e0e0',
19
+ color: '#000000',
20
+ '&:hover': {
21
+ backgroundColor: '#bdbdbd',
22
+ },
23
+ },
24
+ },
25
+ },
26
+ },
27
+ });
28
+
29
+ class MeasuredConfigLayout extends AppendCSSRules {
8
30
  static propTypes = {
9
- children: PropTypes.oneOfType([
10
- PropTypes.string,
11
- PropTypes.arrayOf(PropTypes.element),
12
- PropTypes.element
13
- ]),
14
- settings: PropTypes.element,
31
+ children: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.element), PropTypes.element]),
15
32
  className: PropTypes.string,
16
- classes: PropTypes.object,
17
- sidePanelMinWidth: PropTypes.number
33
+ dimensions: PropTypes.object,
34
+ settings: PropTypes.element,
35
+ sidePanelMinWidth: PropTypes.number,
36
+ hideSettings: PropTypes.bool,
18
37
  };
19
38
 
20
39
  static defaultProps = {
21
- sidePanelMinWidth: 950
40
+ sidePanelMinWidth: 1135,
41
+ hideSettings: false,
42
+ dimensions: {},
22
43
  };
23
44
 
24
- constructor(props) {
25
- super(props);
26
- this.state = {
27
- layoutMode: undefined
28
- };
45
+ constructor(...props) {
46
+ super(...props);
47
+ this.state = { layoutMode: undefined };
29
48
  }
30
49
 
31
- onResize = contentRect => {
50
+ onResize = (contentRect) => {
32
51
  const { bounds } = contentRect;
33
- const { sidePanelMinWidth } = this.props;
34
- const layoutMode = bounds.width >= sidePanelMinWidth ? 'inline' : 'tabbed';
52
+ const { sidePanelMinWidth, dimensions } = this.props;
53
+ const { maxWidth } = dimensions || {};
35
54
 
36
- this.setState({ layoutMode });
55
+ const layoutMode =
56
+ bounds.width > sidePanelMinWidth && (maxWidth ? maxWidth > sidePanelMinWidth : true) ? 'inline' : 'tabbed';
57
+
58
+ // Only update state (and cause a re-render) if the computed layoutMode changed.
59
+ if (layoutMode !== this.state.layoutMode) {
60
+ this.setState({ layoutMode });
61
+ }
37
62
  };
38
63
 
39
64
  render() {
40
65
  return (
41
- <Measure bounds onResize={this.onResize}>
42
- {({ measureRef }) => {
43
- const { settings, children } = this.props;
44
- const { layoutMode } = this.state;
66
+ // TODO: REVIEW MuiThemeProvider usage - is this still needed after mui update?
67
+ // Different theme object identities will force theme consumers to re-render.
68
+ <StyledEngineProvider injectFirst>
69
+ <ThemeProvider theme={theme}>
70
+ <Measure bounds onResize={this.onResize}>
71
+ {({ measureRef }) => {
72
+ const { children, settings, hideSettings, dimensions } = this.props;
73
+ const { layoutMode } = this.state;
74
+
75
+ const settingsPanel =
76
+ layoutMode === 'inline' ? <SettingsBox className="settings-box">{settings}</SettingsBox> : settings;
77
+ const secondaryContent = hideSettings ? null : settingsPanel;
78
+ const finalClass = 'main-container';
45
79
 
46
- return (
47
- <div ref={measureRef}>
48
- <LayoutContents
49
- mode={layoutMode}
50
- secondary={
51
- layoutMode === 'inline' ? <SettingsBox>{settings}</SettingsBox> : settings
52
- }
53
- >
54
- {children}
55
- </LayoutContents>
56
- </div>
57
- );
58
- }}
59
- </Measure>
80
+ return (
81
+ <div ref={measureRef} className={finalClass}>
82
+ <LayoutContents mode={layoutMode} secondary={secondaryContent} dimensions={dimensions}>
83
+ {children}
84
+ </LayoutContents>
85
+ </div>
86
+ );
87
+ }}
88
+ </Measure>
89
+ </ThemeProvider>
90
+ </StyledEngineProvider>
60
91
  );
61
92
  }
62
93
  }
63
94
 
95
+ const ConfigLayout = withContentRect('bounds')(MeasuredConfigLayout);
96
+
64
97
  export default ConfigLayout;
@@ -1,60 +1,117 @@
1
1
  import React from 'react';
2
- import { withStyles } from '@material-ui/core';
3
- import Tabs from '../tabs';
4
- import classnames from 'classnames';
5
2
  import PropTypes from 'prop-types';
3
+ import { styled } from '@mui/material/styles';
4
+ import Tabs from '../tabs';
5
+
6
+ const StyledContainer = styled('div')(() => ({
7
+ display: 'flex',
8
+ flexDirection: 'column',
9
+ position: 'relative',
10
+ }));
11
+
12
+ const StyledFlow = styled('div')(() => ({
13
+ display: 'flex',
14
+ justifyContent: 'space-between',
15
+ }));
16
+
17
+ const StyledContentContainer = styled('div')(({ theme }) => ({
18
+ padding: `${theme.spacing(2)} 0`,
19
+ }));
20
+
21
+ const StyledConfigContainer = styled('div')(() => ({
22
+ flex: '1',
23
+ }));
24
+
25
+ const StyledSettingsContainer = styled('div')(({ theme }) => ({
26
+ marginLeft: theme.spacing(2),
27
+ }));
6
28
 
7
29
  class RawLayoutContents extends React.Component {
8
30
  static propTypes = {
9
31
  mode: PropTypes.oneOf(['tabbed', 'inline']),
10
32
  secondary: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
11
33
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
12
- classes: PropTypes.object
34
+ dimensions: PropTypes.object,
35
+ };
36
+
37
+ getConfiguration = () => {
38
+ const { secondary } = this.props;
39
+ // in config-layout, secondary can be: <SettingsBox>{settings}</SettingsBox>, settings, null
40
+
41
+ return secondary?.props?.configuration || secondary?.props?.children?.props?.configuration || undefined;
13
42
  };
14
43
 
44
+ // // eslint-disable-next-line no-unused-vars
45
+ // componentDidUpdate(prevProps, prevState, snapshot) {
46
+ // const configuration = this.getConfiguration();
47
+ // const { mode } = this.props;
48
+ //
49
+ // // promptHolder class is used to wrap up inputs:
50
+ // // we don't want inputs to fill the entire scrollable container,
51
+ // // but instead we want inputs to fit in the first view,
52
+ // // so we calculate the maximum space inputs need
53
+ // try {
54
+ // if (
55
+ // configuration?.maxWidth &&
56
+ // getComputedStyle(document.documentElement).getPropertyValue('--pie-prompt-holder-max-width') !==
57
+ // configuration?.maxWidth
58
+ // ) {
59
+ // document.documentElement.style.setProperty(
60
+ // '--pie-prompt-holder-max-width',
61
+ // mode === 'inline' ? `calc(${configuration.maxWidth} - 340px)` : configuration.maxWidth,
62
+ // );
63
+ // }
64
+ // } catch (e) {
65
+ // console.log(e.toString());
66
+ // }
67
+ // }
68
+
15
69
  render() {
16
- const { mode, secondary, children, classes } = this.props;
70
+ const { mode, secondary, children, dimensions } = this.props;
71
+ const { minHeight, minWidth, maxHeight, maxWidth } = dimensions || {};
72
+ const configuration = this.getConfiguration();
73
+
74
+ let hasSettingsPanel = Object.entries(configuration || {}).some(([, obj]) => !!obj?.settings);
75
+ // ebsr has configuration.partA and configuration.partB
76
+ // because we might have nested configuration for other item types as well, let's add this simple regex to check values for settings
77
+
78
+ if (!hasSettingsPanel) {
79
+ try {
80
+ hasSettingsPanel = JSON.stringify(configuration)?.match(/settings":true/)?.length;
81
+ } catch (e) {
82
+ // eslint-disable-next-line no-console
83
+ console.log(e.toString());
84
+ }
85
+ }
17
86
 
18
87
  return (
19
- <div className={classnames(classes.container)}>
88
+ <StyledContainer style={{ minHeight, minWidth, maxHeight, maxWidth }}>
20
89
  {mode === 'inline' && (
21
- <div className={classes.flow}>
22
- <div className={classes.configContainer}>{children}</div>
23
- <div>{secondary}</div>
24
- </div>
90
+ <StyledFlow>
91
+ <StyledConfigContainer className="design-container">{children}</StyledConfigContainer>
92
+ {hasSettingsPanel && (
93
+ <StyledSettingsContainer className="settings-container">{secondary}</StyledSettingsContainer>
94
+ )}
95
+ </StyledFlow>
25
96
  )}
26
- {mode === 'tabbed' && (
27
- <Tabs
28
- onChange={this.onTabsChange}
29
- contentClassName={classes.contentContainer}
30
- indicatorColor="primary"
31
- >
32
- <div title="Design">{children}</div>
33
- <div title="settings">{secondary}</div>
97
+
98
+ {mode === 'tabbed' && hasSettingsPanel && (
99
+ <Tabs onChange={this.onTabsChange} contentClassName="content-container" indicatorColor="primary">
100
+ <StyledContentContainer title="Design" className="design-container">
101
+ {children}
102
+ </StyledContentContainer>
103
+ <StyledContentContainer title="Settings" className="settings-container">
104
+ {secondary}
105
+ </StyledContentContainer>
34
106
  </Tabs>
35
107
  )}
36
- </div>
108
+
109
+ {mode === 'tabbed' && !hasSettingsPanel && (
110
+ <StyledContentContainer className="design-container">{children}</StyledContentContainer>
111
+ )}
112
+ </StyledContainer>
37
113
  );
38
114
  }
39
115
  }
40
116
 
41
- const styles = () => ({
42
- flow: {
43
- display: 'flex',
44
- justifyContent: 'space-between'
45
- },
46
- container: {
47
- display: 'flex',
48
- flexDirection: 'column',
49
- position: 'relative'
50
- },
51
- contentContainer: {
52
- padding: '32px 16px 0 16px'
53
- },
54
- configContainer: {
55
- flex: '1',
56
- marginRight: '20px'
57
- }
58
- });
59
-
60
- export default withStyles(styles)(RawLayoutContents);
117
+ export default RawLayoutContents;
@@ -1,31 +1,32 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { withStyles } from '@material-ui/core/styles';
4
- import classNames from 'classnames';
3
+ import { styled } from '@mui/material/styles';
4
+
5
+ const StyledSettingsBox = styled('div')(({ theme }) => ({
6
+ backgroundColor: theme.palette.background.paper,
7
+ border: `2px solid ${theme.palette.grey[200]}`,
8
+ display: 'flex',
9
+ flexDirection: 'column',
10
+ justifyContent: 'flex-start',
11
+ minWidth: '275px',
12
+ maxWidth: '300px',
13
+ padding: '20px 4px 4px 20px',
14
+ zIndex: 99,
15
+ }));
16
+
5
17
  export class SettingsBox extends React.Component {
6
18
  static propTypes = {
7
- classes: PropTypes.object.isRequired,
8
19
  className: PropTypes.string,
9
- children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
20
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
10
21
  };
22
+
11
23
  static defaultProps = {};
24
+
12
25
  render() {
13
- const { classes, className, children } = this.props;
14
- return <div className={classNames(classes.settingsBox, className)}>{children}</div>;
26
+ const { className, children } = this.props;
27
+
28
+ return <StyledSettingsBox className={className}>{children}</StyledSettingsBox>;
15
29
  }
16
30
  }
17
- const styles = () => ({
18
- settingsBox: {
19
- backgroundColor: '#FFF',
20
- border: '2px solid #EEE',
21
- display: 'flex',
22
- flexDirection: 'column',
23
- justifyContent: 'flex-start',
24
- minWidth: '275px',
25
- maxWidth: '300px',
26
- padding: '24px 8px 24px 24px',
27
- width: '80%',
28
- zIndex: 99
29
- }
30
- });
31
- export default withStyles(styles)(SettingsBox);
31
+
32
+ export default SettingsBox;
@@ -1,64 +1,56 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { withStyles } from '@material-ui/core/styles';
3
+ import { styled } from '@mui/material/styles';
4
4
  import debug from 'debug';
5
- import classNames from 'classnames';
6
5
 
7
6
  const log = debug('pie-elements:config-ui:mui-box');
8
7
 
9
- const MuiBox = withStyles(theme => {
10
- const light = theme.palette.type === 'light';
8
+ const StyledMuiBox = styled('div')(({ theme, focused }) => {
9
+ const light = theme.palette.mode === 'light';
11
10
  const bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)';
12
11
 
13
- log(theme.palette.primary[theme.palette.type || 'light']);
12
+ log(theme.palette.primary[theme.palette.mode || 'light']);
14
13
 
15
14
  return {
16
- muiBox: {
17
- paddingTop: theme.spacing.unit,
18
- paddingBottom: theme.spacing.unit,
19
- position: 'relative',
20
- '&:before': {
21
- left: 0,
22
- right: 0,
23
- bottom: 0,
24
- height: '1px',
25
- content: '""',
26
- position: 'absolute',
27
- transition: 'background-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
28
- pointerEvents: 'none',
29
- backgroundColor: bottomLineColor
30
- },
31
- '&:hover:before': {
32
- height: '2px'
33
- },
34
- '&:after': {
35
- left: 0,
36
- right: 0,
37
- bottom: 0,
38
- height: '2px',
39
- content: '""',
40
- position: 'absolute',
41
- transform: 'scaleX(0)',
42
- transition: 'transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms',
43
- pointerEvents: 'none',
44
- backgroundColor: theme.palette.primary[theme.palette.type] //'#304ffe'
45
- }
15
+ paddingTop: theme.spacing(1),
16
+ paddingBottom: theme.spacing(1),
17
+ position: 'relative',
18
+ '&:before': {
19
+ left: 0,
20
+ right: 0,
21
+ bottom: 0,
22
+ height: '1px',
23
+ content: '""',
24
+ position: 'absolute',
25
+ transition: 'background-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
26
+ pointerEvents: 'none',
27
+ backgroundColor: bottomLineColor,
28
+ },
29
+ '&:hover:before': {
30
+ height: '2px',
31
+ },
32
+ '&:after': {
33
+ left: 0,
34
+ right: 0,
35
+ bottom: 0,
36
+ height: '2px',
37
+ content: '""',
38
+ position: 'absolute',
39
+ transform: focused ? 'scaleX(1)' : 'scaleX(0)',
40
+ transition: 'transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms',
41
+ pointerEvents: 'none',
42
+ backgroundColor: theme.palette.primary[theme.palette.mode], //'#304ffe'
46
43
  },
47
- focused: {
48
- '&:after': {
49
- transform: 'scaleX(1)'
50
- }
51
- }
52
44
  };
53
- })(({ children, classes, focused }) => {
54
- const names = classNames(classes.muiBox, focused && classes.focused);
55
-
56
- return <div className={names}>{children}</div>;
57
45
  });
58
46
 
47
+ const MuiBox = ({ children, focused }) => {
48
+ return <StyledMuiBox focused={focused}>{children}</StyledMuiBox>;
49
+ };
50
+
59
51
  MuiBox.propTypes = {
60
52
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
61
- focused: PropTypes.bool.isRequired
53
+ focused: PropTypes.bool.isRequired,
62
54
  };
63
55
 
64
56
  export default MuiBox;