@inceptionbg/iui 2.0.19 → 2.0.21

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 (37) hide show
  1. package/dist/icons/index.d.ts +5 -1
  2. package/dist/icons/index.js +1 -1
  3. package/dist/index.d.ts +18 -7
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/iui.css +1 -1
  7. package/package.json +2 -1
  8. package/src/assets/icons/index.ts +2 -0
  9. package/src/assets/icons/light/faArrowLeft.ts +15 -0
  10. package/src/assets/icons/light/faArrowRight.ts +15 -0
  11. package/src/components/Accordions/Accordions.tsx +22 -10
  12. package/src/components/Dialog/Dialog.tsx +27 -25
  13. package/src/components/Header/Components/EnvBadge.tsx +17 -0
  14. package/src/components/Header/Header.tsx +7 -3
  15. package/src/components/Helper/Collapse.tsx +5 -1
  16. package/src/components/Inputs/Selects/components/SelectWrapper.tsx +1 -1
  17. package/src/components/Table/components/items/TableItemActions.tsx +5 -3
  18. package/src/components/Table/contexts/TableContext.tsx +8 -5
  19. package/src/components/Table/hooks/localHooks/useLocalTableData.tsx +1 -1
  20. package/src/components/Table/hooks/localHooks/useLocalTableKeyboard.ts +3 -1
  21. package/src/components/Table/hooks/useTableEdit.tsx +9 -2
  22. package/src/components/Table/hooks/useTableSearch.ts +2 -1
  23. package/src/components/Tabs/Tabs.tsx +3 -3
  24. package/src/components/Wrappers/FormWrapper.tsx +2 -0
  25. package/src/components/Wrappers/PageLayout.tsx +14 -6
  26. package/src/index.ts +2 -0
  27. package/src/styles/common/_typography.scss +2 -2
  28. package/src/styles/common/helpers/_size.scss +3 -0
  29. package/src/styles/components/_accordions.scss +3 -0
  30. package/src/styles/components/_dialog.scss +25 -19
  31. package/src/styles/components/_header.scss +5 -0
  32. package/src/styles/components/_page.scss +45 -12
  33. package/src/styles/components/_table.scss +2 -1
  34. package/src/styles/components/_tabs.scss +1 -1
  35. package/src/types/ITable.ts +1 -1
  36. package/src/utils/InputPatternValidation.ts +2 -2
  37. package/src/utils/objectUtils.ts +15 -5
@@ -11,9 +11,11 @@ interface BaseItemProps<T> {
11
11
  placeholder?: string;
12
12
  required?: boolean;
13
13
  additionalClearIds?: (keyof T)[];
14
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
14
15
  }
15
16
  interface SelectProps<T> extends BaseItemProps<T> {
16
17
  options: readonly (string | boolean)[] | (string | boolean)[];
18
+ minWidth?: number;
17
19
  formatOption: (value: string | boolean) => {
18
20
  value: string | boolean;
19
21
  label: string;
@@ -30,6 +32,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
30
32
  required,
31
33
  id,
32
34
  additionalClearIds = [],
35
+ inputProps,
33
36
  }: BaseItemProps<T>) => ({
34
37
  value: (
35
38
  <TextInput
@@ -39,6 +42,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
39
42
  setValue={e =>
40
43
  setEditData(e ? { ...editData, [id]: e } : deleteProps(editData as T, [id]))
41
44
  }
45
+ inputProps={inputProps}
42
46
  onClear={() => deleteProps(editData as T, [id, ...additionalClearIds])}
43
47
  />
44
48
  ),
@@ -50,6 +54,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
50
54
  required,
51
55
  id,
52
56
  additionalClearIds = [],
57
+ inputProps,
53
58
  }: BaseItemProps<T>) => ({
54
59
  value: (
55
60
  <NumberInput
@@ -59,6 +64,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
59
64
  setValue={e =>
60
65
  setEditData(e ? { ...editData, [id]: e } : deleteProps(editData as T, [id]))
61
66
  }
67
+ inputProps={inputProps}
62
68
  onClear={() => deleteProps(editData as T, [id, ...additionalClearIds])}
63
69
  />
64
70
  ),
@@ -69,7 +75,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
69
75
  id,
70
76
  required,
71
77
  additionalClearIds,
72
- }: Omit<BaseItemProps<T>, 'placeholder'>) => ({
78
+ }: Omit<BaseItemProps<T>, 'placeholder' | 'inputProps'>) => ({
73
79
  value: (
74
80
  <DateInput
75
81
  required={required}
@@ -92,6 +98,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
92
98
  options,
93
99
  formatOption,
94
100
  additionalClearIds = [],
101
+ minWidth = 110,
95
102
  }: SelectProps<T>) => ({
96
103
  value: (
97
104
  <Select
@@ -99,7 +106,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
99
106
  placeholder={placeholder}
100
107
  value={hasValue(editData[id]) ? formatOption(editData[id]!) : null}
101
108
  options={options.map(formatOption)}
102
- minWidth={150}
109
+ minWidth={minWidth}
103
110
  onChange={e => {
104
111
  e
105
112
  ? setEditData({
@@ -1,4 +1,5 @@
1
1
  import { Dispatch, SetStateAction, useState } from 'react';
2
+ import { deletePropsThatEndsWith } from '../../../utils/objectUtils';
2
3
 
3
4
  export interface ITableSearchProps<T> {
4
5
  setOffset: Dispatch<SetStateAction<number>>;
@@ -17,7 +18,7 @@ export const useTableSearch = <T>({
17
18
  const onSearch = (filters: T) => {
18
19
  setOffset(0);
19
20
  resetSelectedRows?.();
20
- setSearch(filters);
21
+ setSearch(<T>deletePropsThatEndsWith(filters, 'Obj'));
21
22
  };
22
23
 
23
24
  return {
@@ -27,9 +27,9 @@ export const Tabs: FC<Props> = ({
27
27
  }) => {
28
28
  const filteredTabs = useMemo(() => tabs.filter(e => !e.hidden), [tabs]);
29
29
 
30
- const [selected, setSelected] = useState(initialValue || filteredTabs[0].value);
30
+ const [selected, setSelected] = useState(initialValue || filteredTabs[0]?.value || '');
31
31
 
32
- const activeTab = filteredTabs.find(tab => (control?.value || selected) === tab.value);
32
+ const activeTab = filteredTabs.find(tab => (control?.value ?? selected) === tab.value);
33
33
 
34
34
  return filteredTabs.length > 0 ? (
35
35
  <div className={className}>
@@ -39,7 +39,7 @@ export const Tabs: FC<Props> = ({
39
39
  id={tab.value}
40
40
  key={tab.value}
41
41
  className={clsx('iui-tab clickable', {
42
- selected: (control?.value || selected) === tab.value,
42
+ selected: (control?.value ?? selected) === tab.value,
43
43
  disabled: tab.disabled,
44
44
  'no-wrap': noWrap,
45
45
  })}
@@ -61,6 +61,7 @@ export const FormWrapper: FC<IFormWrapper> = ({
61
61
  variant={e.variant}
62
62
  color={e.color}
63
63
  onClick={e.onClick}
64
+ type="button"
64
65
  />
65
66
  )
66
67
  )}
@@ -71,6 +72,7 @@ export const FormWrapper: FC<IFormWrapper> = ({
71
72
  disabled={isLoading || submitButton.disabled}
72
73
  variant={submitButton.variant}
73
74
  color={submitButton.color}
75
+ type="submit"
74
76
  />
75
77
  )}
76
78
  </div>
@@ -28,6 +28,7 @@ export interface IPageLayoutProps {
28
28
  noAccess?: boolean;
29
29
  isInitiallyLoading?: boolean;
30
30
  isLoading?: boolean;
31
+ hideFooter?: boolean;
31
32
  children?: ReactNode;
32
33
  }
33
34
 
@@ -40,6 +41,7 @@ export const PageLayout: FC<IPageLayoutProps> = ({
40
41
  noAccess,
41
42
  isLoading,
42
43
  isInitiallyLoading,
44
+ hideFooter,
43
45
  children,
44
46
  }) => {
45
47
  const [isMoreActionsOpen, setIsMoreActionsOpen] = useState(false);
@@ -56,9 +58,11 @@ export const PageLayout: FC<IPageLayoutProps> = ({
56
58
  return null;
57
59
  }
58
60
 
59
- return isInitiallyLoading ? (
60
- <Loader isLoading isFullPage />
61
- ) : (
61
+ if (isInitiallyLoading) {
62
+ return <Loader isLoading isFullPage />;
63
+ }
64
+
65
+ return (
62
66
  <Loader isLoading={!!isLoading}>
63
67
  <div className="page-container">
64
68
  {breadcrumbs && (
@@ -138,9 +142,13 @@ export const PageLayout: FC<IPageLayoutProps> = ({
138
142
  </div>
139
143
  )}
140
144
  <div className="page-content">{children}</div>
141
- <footer className="page-footer">
142
- <Trans i18nKey="FooterText" />
143
- </footer>
145
+ {!hideFooter && (
146
+ <footer className="page-footer">
147
+ <p className="page-footer-text">
148
+ <Trans i18nKey="FooterText" />
149
+ </p>
150
+ </footer>
151
+ )}
144
152
  </div>
145
153
  </Loader>
146
154
  );
package/src/index.ts CHANGED
@@ -173,6 +173,7 @@ import {
173
173
  deleteEmptyPropsIncludingArray,
174
174
  deleteProps,
175
175
  deletePropsThatEndsWith,
176
+ flattenTreeForSelect,
176
177
  intersectArrays,
177
178
  } from './utils/objectUtils';
178
179
  import {
@@ -345,6 +346,7 @@ export {
345
346
  setTemplateData,
346
347
  getVisibleColumnsIds,
347
348
  inputPattern,
349
+ flattenTreeForSelect,
348
350
  intersectArrays,
349
351
  maxChar,
350
352
  parseUrlSearch,
@@ -1,8 +1,8 @@
1
1
  @use '../variables/bp';
2
- @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,500;0,600;0,700;0,900;1,400;1,500;1,600;1,700;1,900&display=swap');
2
+ @import url('@fontsource-variable/ibm-plex-sans');
3
3
 
4
4
  * {
5
- font-family: 'Poppins', sans-serif;
5
+ font-family: 'IBM Plex Sans Variable', sans-serif;
6
6
  }
7
7
 
8
8
  body {
@@ -14,6 +14,9 @@
14
14
  .w-300 {
15
15
  width: 300px !important;
16
16
  }
17
+ .w-600 {
18
+ width: 600px !important;
19
+ }
17
20
 
18
21
  .full-height {
19
22
  height: 100% !important;
@@ -44,4 +44,7 @@
44
44
  height: 12px;
45
45
  width: 14px;
46
46
  }
47
+ .iui-accordion-content {
48
+ padding: 8px 24px 16px;
49
+ }
47
50
  }
@@ -24,15 +24,22 @@ $dialog-sizes: (
24
24
  }
25
25
 
26
26
  .iui-dialog-container {
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: 24px;
27
30
  background-color: var(--background);
28
31
  border-radius: 16px;
29
32
  min-width: 400px;
30
33
  max-width: 98vw;
34
+ max-height: 95dvh;
31
35
  animation: scale-in 0.2s forwards;
32
36
  overflow: hidden;
37
+ padding: 24px;
38
+
33
39
  .iui-dialog-header {
34
40
  display: flex;
35
41
  gap: 16px;
42
+ flex-shrink: 0;
36
43
  .iui-dialog-desc {
37
44
  color: var(--text);
38
45
  word-break: break-word;
@@ -53,6 +60,18 @@ $dialog-sizes: (
53
60
  }
54
61
  }
55
62
  }
63
+ .iui-dialog-content {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: 8px;
67
+ flex: 1;
68
+ margin-right: -24px;
69
+ padding-right: 24px;
70
+ &:not(.no-overflow) {
71
+ overflow: auto;
72
+ overscroll-behavior: none;
73
+ }
74
+ }
56
75
 
57
76
  @each $key, $value in $dialog-sizes {
58
77
  &.#{$key} {
@@ -71,28 +90,15 @@ $dialog-sizes: (
71
90
  }
72
91
  }
73
92
  }
74
- }
75
-
76
- .iui-dialog-content {
77
- display: flex;
78
- flex-direction: column;
79
- gap: 8px;
80
- max-height: 80vh;
81
- padding: 24px;
82
- &:not(.no-overflow) {
83
- overflow: auto;
84
- overscroll-behavior: none;
93
+ .iui-dialog-actions {
94
+ display: flex;
95
+ gap: 8px;
96
+ justify-content: right;
97
+ padding-top: 24px;
98
+ border-top: var(--border);
85
99
  }
86
100
  }
87
101
 
88
- .iui-dialog-actions {
89
- display: flex;
90
- gap: 8px;
91
- justify-content: right;
92
- padding: 24px;
93
- border-top: var(--border);
94
- }
95
-
96
102
  @media #{bp.$mobile} {
97
103
  .iui-dialog-container {
98
104
  height: 100dvh;
@@ -12,6 +12,11 @@
12
12
  padding-left: 8px;
13
13
  box-sizing: border-box;
14
14
  z-index: 2;
15
+ .env-badge {
16
+ color: var(--text);
17
+ font-weight: bold;
18
+ font-size: 14px;
19
+ }
15
20
  .header-button {
16
21
  height: 40px;
17
22
  width: 40px;
@@ -32,14 +32,6 @@
32
32
  max-height: calc(100vh - var(--header-height));
33
33
  }
34
34
 
35
- .page-content {
36
- display: flex;
37
- flex-direction: column;
38
- padding: 1.5rem 1.5rem 1rem 1.5rem;
39
- flex: 1;
40
- overflow-y: auto;
41
- }
42
-
43
35
  .page-header {
44
36
  display: flex;
45
37
  justify-content: space-between;
@@ -57,9 +49,50 @@
57
49
  }
58
50
  }
59
51
 
52
+ .page-content {
53
+ display: flex;
54
+ flex-direction: column;
55
+ padding: 1.5rem 1.5rem 1rem 1.5rem;
56
+ flex: 1;
57
+ overflow-y: auto;
58
+ }
59
+ .scrollable-content {
60
+ display: flex;
61
+ flex-direction: column;
62
+ flex: 1;
63
+ overflow-y: auto;
64
+ margin-right: -1.5rem;
65
+ padding-right: 1.5rem;
66
+ padding-bottom: 1rem;
67
+ }
68
+
60
69
  .page-footer {
61
- text-align: center;
62
- padding: 16px;
63
- font-size: 12px;
64
- white-space: pre-line;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ gap: 16px;
74
+ padding: 16px 24px;
75
+ margin: 0 -1.5rem -1rem;
76
+ &.footer-actions {
77
+ box-shadow: var(--container-shadow);
78
+ z-index: 2;
79
+ }
80
+ .page-footer-text {
81
+ text-align: center;
82
+ font-size: 12px;
83
+ white-space: pre-line;
84
+ }
85
+ }
86
+
87
+ .page-footer-text {
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ gap: 16px;
92
+ padding: 16px 24px;
93
+ .page-footer-text {
94
+ text-align: center;
95
+ font-size: 12px;
96
+ white-space: pre-line;
97
+ }
65
98
  }
@@ -94,13 +94,14 @@ table {
94
94
  }
95
95
  .clickable-cell:hover {
96
96
  background-color: var(--primary-100) !important;
97
+ cursor: pointer;
97
98
  }
98
99
  // Item Actions
99
100
  .table-item-actions {
100
101
  display: flex;
101
102
  align-items: center;
102
103
  justify-content: center;
103
- padding: 0 4px;
104
+ padding: 0 8px;
104
105
  }
105
106
 
106
107
  //// Footer ////
@@ -2,7 +2,7 @@
2
2
  display: flex;
3
3
  overflow: auto;
4
4
  border-bottom: var(--border);
5
- padding-bottom: 4px;
5
+ flex-shrink: 0;
6
6
  &::-webkit-scrollbar {
7
7
  height: 5px;
8
8
  }
@@ -97,7 +97,7 @@ export interface ITableDataItemCells {
97
97
  }
98
98
 
99
99
  export interface ITableDataActions<T = unknown> {
100
- hasEditAccess: boolean;
100
+ hasEditAccess?: boolean;
101
101
  actions?: (item?: T) => {
102
102
  label: string;
103
103
  onClick: () => void;
@@ -3,10 +3,10 @@ export const inputPattern = {
3
3
  businessCode: '^\\d{8}$',
4
4
  umcn: '^\\d{13}$',
5
5
  idCardNumber: '^\\d{9}$',
6
- phoneNumber: '^\\d{8,9}$',
6
+ phoneNumber: '^\\+\\d{11,13}$',
7
7
  port: '^\\d{4}$',
8
8
  year: '^\\d{4}$',
9
9
  number: '^\\d*$',
10
10
  strongPassword: '^.*(?=.{8,})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).*$',
11
- // email: '\\S+@\\S+\\.\\S+',
11
+ email: '\\S+@\\S+\\.\\S+',
12
12
  };
@@ -14,17 +14,14 @@ export const deleteProps = <T extends Record<string, any>>(
14
14
  return newObj as Partial<T>;
15
15
  };
16
16
 
17
- export const deletePropsThatEndsWith = <T extends Record<string, any>>(
18
- obj: T,
19
- endsWith: string
20
- ) => {
17
+ export const deletePropsThatEndsWith = <T>(obj: T, endsWith: string) => {
21
18
  const newObj = { ...obj };
22
19
  for (const prop in newObj) {
23
20
  if (prop.endsWith(endsWith)) {
24
21
  delete newObj[prop];
25
22
  }
26
23
  }
27
- return newObj;
24
+ return newObj as Partial<T>;
28
25
  };
29
26
 
30
27
  export const deleteEmptyProps = <T extends Record<string, any>>(obj: T): T =>
@@ -102,3 +99,16 @@ export const getNotificationValues = (
102
99
  }
103
100
  return { ...obj, [item.key]: processedValue };
104
101
  }, {});
102
+
103
+ export const flattenTreeForSelect = (items: any[], depth = 0, maxDepth = 5): any[] => {
104
+ if (!Array.isArray(items)) return [];
105
+ const indent = '\u00A0'.repeat(Math.min(depth, maxDepth) * 3);
106
+ return items.flatMap(node => [
107
+ {
108
+ value: node.uuid,
109
+ label: `${indent}${node.code ? node.code + ' - ' : ''}${node.name}`,
110
+ disabled: node.active === false || node.hasUserAccess === false,
111
+ },
112
+ ...(node.children ? flattenTreeForSelect(node.children, depth + 1, maxDepth) : []),
113
+ ]);
114
+ };