@scality/core-ui 0.126.0 → 0.127.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.
@@ -1 +1 @@
1
- {"version":3,"file":"inputv2.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputv2/inputv2.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAIxD,OAAO,EAAQ,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAExD,eAAO,MAAM,gBAAgB,UAAW,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,2CAKlE,CAAC;AAgFF,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,GAAG,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;AAExD,eAAO,MAAM,KAAK;;QANZ,MAAM;;;;0GAsDX,CAAC"}
1
+ {"version":3,"file":"inputv2.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputv2/inputv2.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAIxD,OAAO,EAAQ,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAExD,eAAO,MAAM,gBAAgB,UAAW,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,2CAKlE,CAAC;AAwFF,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,GAAG,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;AAExD,eAAO,MAAM,KAAK;;QANZ,MAAM;;;;0GAsDX,CAAC"}
@@ -40,6 +40,14 @@ const StyledInput = styled.input `
40
40
  border: 0;
41
41
  outline: none;
42
42
  }
43
+ &:-webkit-autofill,
44
+ &:-webkit-autofill:hover,
45
+ &:-webkit-autofill:focus,
46
+ &:-webkit-autofill:active {
47
+ -webkit-text-fill-color: ${(props) => props.theme.textPrimary};
48
+ -webkit-background-clip: text;
49
+ caret-color: ${(props) => props.theme.textPrimary};
50
+ }
43
51
  `;
44
52
  const InputContainer = styled.div `
45
53
  height: 100%;
@@ -10,6 +10,7 @@ export type Props = {
10
10
  disabled?: boolean;
11
11
  id?: string;
12
12
  size?: InputSize;
13
+ autoComplete?: 'on' | 'off';
13
14
  };
14
15
  declare const SearchInput: React.ForwardRefExoticComponent<Props & React.RefAttributes<unknown>>;
15
16
  export { SearchInput };
@@ -1 +1 @@
1
- {"version":3,"file":"SearchInput.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/searchinput/SearchInput.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAA2C,MAAM,OAAO,CAAC;AAG7E,OAAO,EAAS,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,MAAM,KAAK,GAAG;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC;AAuCF,QAAA,MAAM,WAAW,uEAsFhB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"SearchInput.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/searchinput/SearchInput.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAA2C,MAAM,OAAO,CAAC;AAG7E,OAAO,EAAS,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,MAAM,KAAK,GAAG;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC;CAC7B,CAAC;AAuCF,QAAA,MAAM,WAAW,uEAwFhB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -38,7 +38,7 @@ const ClearButton = styled.div `
38
38
  right: 1px;
39
39
  top: 0px;
40
40
  `;
41
- const SearchInput = forwardRef(({ disableToggle, placeholder, value, onChange, onReset, disabled, id, size, ...rest }, forwardedRef) => {
41
+ const SearchInput = forwardRef(({ disableToggle, placeholder, value, onChange, onReset, disabled, id, size, autoComplete = 'on', ...rest }, forwardedRef) => {
42
42
  const myInputRef = useRef(null);
43
43
  const debounce = useRef(null);
44
44
  const [debouncedValue, setDebouncedValue] = useState(value);
@@ -64,7 +64,7 @@ const SearchInput = forwardRef(({ disableToggle, placeholder, value, onChange, o
64
64
  onChange(e);
65
65
  }, 300);
66
66
  };
67
- return (_jsxs(SearchInputContainer, { className: "sc-searchinput", disabled: disabled, ...rest, children: [_jsx(Input, { min: '1', id: id || 'search', type: "search", "aria-label": "search", name: "search", placeholder: placeholder, value: debouncedValue, onChange: handleChange, onReset: reset, size: size, leftIcon: "Search", className: "search-box", disabled: disabled, ref: (element) => {
67
+ return (_jsxs(SearchInputContainer, { className: "sc-searchinput", disabled: disabled, ...rest, children: [_jsx(Input, { autoComplete: autoComplete, min: '1', id: id || 'search', type: "search", "aria-label": "search", name: "search", placeholder: placeholder, value: debouncedValue, onChange: handleChange, onReset: reset, size: size, leftIcon: "Search", className: "search-box", disabled: disabled, ref: (element) => {
68
68
  myInputRef.current = element;
69
69
  if (typeof forwardedRef === 'function') {
70
70
  forwardedRef(element);
@@ -1 +1 @@
1
- {"version":3,"file":"StyledTabs.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tabsv2/StyledTabs.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,MAAM,yGAGlB,CAAC;AACF,eAAO,MAAM,OAAO;;;;;;SAkDnB,CAAC;AACF,eAAO,MAAM,aAAa;;oBAER,MAAM;SAwBvB,CAAC;AACF,eAAO,MAAM,UAAU;;SAMtB,CAAC;AACF,eAAO,MAAM,mBAAmB,yGAE/B,CAAC;AACF,eAAO,MAAM,YAAY,yGAYxB,CAAC"}
1
+ {"version":3,"file":"StyledTabs.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tabsv2/StyledTabs.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,yGAGlB,CAAC;AACF,eAAO,MAAM,OAAO;;;;;;SAkDnB,CAAC;AACF,eAAO,MAAM,aAAa;;oBAER,MAAM;SAyBvB,CAAC;AACF,eAAO,MAAM,UAAU;;SAUtB,CAAC;AACF,eAAO,MAAM,mBAAmB,yGAE/B,CAAC;AACF,eAAO,MAAM,YAAY,yGAYxB,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import styled from 'styled-components';
2
- import { getThemePropSelector } from '../../utils';
3
2
  import { spacing } from '../../spacing';
4
3
  export const TabBar = styled.div `
5
4
  display: flex;
@@ -16,7 +15,7 @@ export const TabItem = styled.div `
16
15
  &:focus-visible {
17
16
  outline: 0;
18
17
  position: relative;
19
- border: ${spacing.r1} dashed ${getThemePropSelector('selectedActive')};
18
+ border: ${spacing.r1} dashed ${(props) => props.theme.selectedActive};
20
19
  }
21
20
 
22
21
  &:focus-within {
@@ -51,6 +50,7 @@ export const TabItem = styled.div `
51
50
  `;
52
51
  export const TabsContainer = styled.div `
53
52
  height: 100%;
53
+ width: 100%;
54
54
  display: flex;
55
55
  flex-direction: column;
56
56
  background-color: ${(props) => props.tabLineColor || props.theme.backgroundLevel3};
@@ -75,7 +75,11 @@ export const TabsContainer = styled.div `
75
75
  export const TabContent = styled.div `
76
76
  margin: 0;
77
77
  padding: 0;
78
- flex: 1;
78
+ display: block;
79
+ width: 100%;
80
+ height: 100%;
81
+ box-sizing: border-box;
82
+ overflow: auto;
79
83
  background-color: ${(props) => props.tabContentColor || props.theme.backgroundLevel4};
80
84
  `;
81
85
  export const ScrollableContainer = styled.div `
@@ -1 +1 @@
1
- {"version":3,"file":"Tabsv2.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tabsv2/Tabsv2.component.tsx"],"names":[],"mappings":"AACA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAkB/C,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAM5B,KAAK,SAAS,GAAG;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,WAAW,wBAAgC,CAAC;AAMzD,iBAAS,IAAI,CAAC,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,SAAS,eA4LX;kBAvMQ,IAAI;;;AA2Mb,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"Tabsv2.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/tabsv2/Tabsv2.component.tsx"],"names":[],"mappings":"AACA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAkB/C,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAM5B,KAAK,SAAS,GAAG;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,WAAW,wBAAgC,CAAC;AAMzD,iBAAS,IAAI,CAAC,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,SAAS,eA6LX;kBAxMQ,IAAI;;;AA4Mb,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC"}
@@ -79,7 +79,7 @@ function Tabs({ activeTabColor, activeTabSeparator, tabLineColor, inactiveTabCol
79
79
  }
80
80
  }, ...childRest, children: [icon && _jsx(TabIcon, { label: label, children: icon }), isSelected ? (_jsx(BasicText, { className: "sc-tabs-item-title", children: label })) : (_jsx(SecondaryText, { className: "sc-tabs-item-title", children: label })), textBadge && (_jsx(EmphaseText, { className: "sc-tabs-item-icon", children: textBadge }))] }, index));
81
81
  });
82
- return (_jsx(TabsContext.Provider, { value: true, children: _jsxs(TabsContainer, { className: ['sc-tabs', className].join(' '), tabLineColor: tabLineColor, separatorColor: separatorColor, ...rest, children: [_jsxs(ScrollableContainer, { children: [displayScroll.start && (_jsx(ScrollButton, { ref: scrollButtonStartRef, direction: "left", onClick: handleStartScrollClick })), _jsx(TabsScroller, { ref: tabsRef, onScroll: handleTabsScroll, children: _jsx(TabBar, { onKeyDown: handleKeyDown, ref: tabsListRef, className: "sc-tabs-bar", role: "tablist", children: tabItems }) }), displayScroll.end && (_jsx(ScrollButton, { ref: scrollButtonEndRef, direction: "right", onClick: handleEndScrollClick }))] }), _jsx(TabContent, { className: "sc-tabs-item-content", tabContentColor: tabContentColor, children: filteredTabsChildren.map((tab, index) => (_jsx(Route, { exact: tab.props.exact, sensitive: tab.props.sensitive, strict: tab.props.strict, path: tab.props.path.startsWith('/')
82
+ return (_jsx(TabsContext.Provider, { value: true, children: _jsxs(TabsContainer, { style: { containerType: 'size' }, className: ['sc-tabs', className].join(' '), tabLineColor: tabLineColor, separatorColor: separatorColor, ...rest, children: [_jsxs(ScrollableContainer, { children: [displayScroll.start && (_jsx(ScrollButton, { ref: scrollButtonStartRef, direction: "left", onClick: handleStartScrollClick })), _jsx(TabsScroller, { ref: tabsRef, onScroll: handleTabsScroll, children: _jsx(TabBar, { onKeyDown: handleKeyDown, ref: tabsListRef, className: "sc-tabs-bar", role: "tablist", children: tabItems }) }), displayScroll.end && (_jsx(ScrollButton, { ref: scrollButtonEndRef, direction: "right", onClick: handleEndScrollClick }))] }), _jsx(TabContent, { className: "sc-tabs-item-content", tabContentColor: tabContentColor, children: filteredTabsChildren.map((tab, index) => (_jsx(Route, { exact: tab.props.exact, sensitive: tab.props.sensitive, strict: tab.props.strict, path: tab.props.path.startsWith('/')
83
83
  ? tab.props.path
84
84
  : url + '/' + tab.props.path, children: !tab.props.query ||
85
85
  (tab.props.query && matchQuery(tab.props.query)) ? (tab.props.children) : (_jsx(_Fragment, {})) }, index))) })] }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentTable.d.ts","sourceRoot":"","sources":["../../../src/lib/organisms/attachments/AttachmentTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EASlB,MAAM,OAAO,CAAC;AAef,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAY,eAAe,EAAE,MAAM,aAAa,CAAC;AAQxD,MAAM,MAAM,oBAAoB,CAAC,WAAW,IAAI;IAC9C,yBAAyB,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;IAC3D,+BAA+B,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1E,2BAA2B,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;IAChE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,YAAY,CAAC,EAAE,CACb,MAAM,EAAE,gBAAgB,CAAC,WAAW,CAAC,KAClC,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,uBAAuB,EAAE,MAAM,CAAC;IAChC,8BAA8B,EAAE,CAC9B,oBAAoB,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAAE,KACrD,IAAI,CAAC;IACV,gBAAgB,EACZ;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAClB;QACE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;QAC5B,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAA;SAAE,CAAC;KACtE,GACD;QACE,MAAM,EAAE,SAAS,CAAC;QAClB,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAA;SAAE,CAAC;KACrE,CAAC;IACN,oBAAoB,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD,CAAC;AA0FF,eAAO,MAAM,kBAAkB,+CAE5B,kBAAkB,EAAE,CAAC,gBAmBvB,CAAC;AAEF,eAAO,MAAM,uBAAuB;sDA5BL,iBAAiB,GAAG,CAAC,EAAE,+BACrB,oBAAoB,GAAG,CAAC,EAAE,KACpD,IAAI;CAkCV,CAAC;AAEF,eAAO,MAAM,eAAe,0RAsiB3B,CAAC"}
1
+ {"version":3,"file":"AttachmentTable.d.ts","sourceRoot":"","sources":["../../../src/lib/organisms/attachments/AttachmentTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EASlB,MAAM,OAAO,CAAC;AAef,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAY,eAAe,EAAE,MAAM,aAAa,CAAC;AAQxD,MAAM,MAAM,oBAAoB,CAAC,WAAW,IAAI;IAC9C,yBAAyB,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;IAC3D,+BAA+B,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1E,2BAA2B,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;IAChE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,YAAY,CAAC,EAAE,CACb,MAAM,EAAE,gBAAgB,CAAC,WAAW,CAAC,KAClC,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,uBAAuB,EAAE,MAAM,CAAC;IAChC,8BAA8B,EAAE,CAC9B,oBAAoB,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAAE,KACrD,IAAI,CAAC;IACV,gBAAgB,EACZ;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAClB;QACE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;QAC5B,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAA;SAAE,CAAC;KACtE,GACD;QACE,MAAM,EAAE,SAAS,CAAC;QAClB,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAA;SAAE,CAAC;KACrE,CAAC;IACN,oBAAoB,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD,CAAC;AAmFF,eAAO,MAAM,kBAAkB,+CAE5B,kBAAkB,EAAE,CAAC,gBAmBvB,CAAC;AAEF,eAAO,MAAM,uBAAuB;sDA5BL,iBAAiB,GAAG,CAAC,EAAE,+BACrB,oBAAoB,GAAG,CAAC,EAAE,KACpD,IAAI;CAkCV,CAAC;AAEF,eAAO,MAAM,eAAe,0RAqiB3B,CAAC"}
@@ -18,10 +18,7 @@ const MenuContainer = styled.ul `
18
18
  position: absolute;
19
19
  width: ${(props) => props.width};
20
20
  z-index: 1;
21
- margin-top: -1.7rem;
22
- margin-left: 0;
23
- margin-bottom: 0;
24
- margin-right: 0;
21
+ margin: 0;
25
22
  ${(props) => props.isOpen
26
23
  ? `
27
24
  border-top-left-radius: 0;
@@ -44,25 +41,22 @@ const MenuContainer = styled.ul `
44
41
  }
45
42
  `;
46
43
  const SearchBoxContainer = styled.div `
44
+ position: relative;
47
45
  padding: ${spacing.r16};
48
46
  `;
49
47
  const StyledSearchInput = styled(SearchInput) `
50
48
  flex-grow: 1;
51
- .sc-input-type:focus {
52
- border-bottom: 0;
53
- border-top-left-radius: 4px;
54
- border-top-right-radius: 4px;
55
- border-bottom-right-radius: 0;
49
+
50
+ & > div:focus-within {
51
+ border-color: ${(props) => props.theme.selectedActive};
56
52
  border-bottom-left-radius: 0;
53
+ border-bottom-right-radius: 0;
54
+ border-bottom: 0;
57
55
  }
58
56
  `;
59
57
  const AttachmentTableContainer = styled.div `
60
58
  height: 100%;
61
59
  `;
62
- const StyledTable = styled.div `
63
- background: ${(props) => props.theme.backgroundLevel4};
64
- height: 100%;
65
- `;
66
60
  const CenterredSecondaryText = styled(SecondaryText) `
67
61
  display: block;
68
62
  text-align: center;
@@ -261,118 +255,118 @@ export const AttachmentTable = ({ initiallyAttachedEntities, initiallyAttachedEn
261
255
  // UI styling states
262
256
  const [searchWidth, setSearchWidth] = useState('0px');
263
257
  const [searchInputIsFocused, setSearchInputIsFocused] = useState(false);
264
- return (_jsxs(AttachmentTableContainer, { children: [_jsx(SearchBoxContainer, { ref: (element) => {
258
+ return (_jsxs(Table, { columns: [
259
+ {
260
+ Header: 'Name',
261
+ accessor: 'name',
262
+ cellStyle: {
263
+ flex: 1.5,
264
+ marginRight: '1.5rem',
265
+ },
266
+ Cell: ({ value, row: { original: entity }, }) => {
267
+ const { data: asyncName, status } = useQuery({
268
+ ...(getNameQuery
269
+ ? getNameQuery(entity)
270
+ : { queryKey: ['fakeQuery'], queryFn: () => value }),
271
+ enabled: !value,
272
+ });
273
+ if (value) {
274
+ return _jsx(ConstrainedText, { text: value, lineClamp: 2 });
275
+ }
276
+ if (status === 'error') {
277
+ return (_jsxs(_Fragment, { children: ["An error occured while loading ", entityName.singular, " name"] }));
278
+ }
279
+ if (status === 'loading' || status === 'idle') {
280
+ return _jsx(_Fragment, { children: "Loading..." });
281
+ }
282
+ if (status === 'success') {
283
+ if (!asyncName) {
284
+ return _jsx(EmptyCell, {});
285
+ }
286
+ return _jsx(ConstrainedText, { text: asyncName, lineClamp: 2 });
287
+ }
288
+ return _jsx(EmptyCell, {});
289
+ },
290
+ },
291
+ {
292
+ Header: 'Attachment',
293
+ accessor: 'isPending',
294
+ cellStyle: {
295
+ flex: 0.5,
296
+ },
297
+ Cell: ({ value }) => {
298
+ return value ? _jsx(_Fragment, { children: "Pending" }) : _jsx(_Fragment, { children: "Attached" });
299
+ },
300
+ },
301
+ {
302
+ Header: _jsx(Box, { flex: 0.5 }),
303
+ accessor: 'action',
304
+ cellStyle: {
305
+ textAlign: 'right',
306
+ flex: 0.5,
307
+ marginLeft: 'auto',
308
+ marginRight: '0.5rem',
309
+ },
310
+ Cell: ({ row: { original: entity }, }) => (_jsx(Button, { size: "inline", onClick: () => {
311
+ dispatch({
312
+ action: AttachmentAction.REMOVE,
313
+ entity: {
314
+ name: entity.name,
315
+ id: entity.id,
316
+ type: entity.type,
317
+ },
318
+ });
319
+ }, icon: _jsx(Icon, { name: "Close" }), label: "Remove", variant: "danger", disabled: !!entity.disableDetach })),
320
+ },
321
+ ], data: desiredAttachedEntities.map((entity) => ({
322
+ ...entity,
323
+ isPending: entity.isPending || false,
324
+ action: null,
325
+ })), defaultSortingKey: "name", children: [_jsxs(SearchBoxContainer, { ref: (element) => {
265
326
  if (element === null || element === void 0 ? void 0 : element.firstElementChild) {
266
327
  setSearchWidth(element.firstElementChild.getBoundingClientRect().width -
267
328
  2 +
268
329
  'px');
269
330
  }
270
- }, children: filteredEntities.status === 'error' ? (_jsx(Tooltip, { overlay: _jsx(_Fragment, { children: "We failed to load the entities, hence search is disabled" }), children: _jsxs(Stack, { children: [_jsx(StyledSearchInput, { placeholder: searchEntityPlaceholder, ...getInputProps({
271
- ref: (element) => {
272
- if (element)
273
- searchInputRef.current = element;
274
- },
275
- }), onFocus: () => {
276
- openMenu();
277
- setSearchInputIsFocused(true);
278
- }, onBlur: () => {
279
- setSearchInputIsFocused(false);
280
- }, disableToggle: true, disabled: filteredEntities.status === 'error' }), _jsx(Loader, {})] }) })) : (_jsx(StyledSearchInput, { placeholder: searchEntityPlaceholder, ...getInputProps({
281
- ref: (element) => {
282
- if (element)
283
- searchInputRef.current = element;
284
- },
285
- }), onFocus: () => {
286
- openMenu();
287
- setSearchInputIsFocused(true);
288
- }, onBlur: () => {
289
- setSearchInputIsFocused(false);
290
- }, disableToggle: true })) }), _jsxs(MenuContainer, { ...getMenuProps(), width: searchWidth, isOpen: isOpen, searchInputIsFocused: searchInputIsFocused, children: [isOpen &&
291
- filteredEntities.status === 'success' &&
292
- ((_a = filteredEntities.data) === null || _a === void 0 ? void 0 : _a.entities.map((item, index) => (_jsx("li", { ...getItemProps({ item, index }), children: _jsx(Text, { children: item.name }) }, `${item.id}${index}`)))), isOpen && filteredEntities.status === 'loading' && (_jsx("li", { children: _jsx(Text, { children: "Searching..." }) })), isOpen && filteredEntities.status === 'error' && (_jsx("li", { children: _jsx(Text, { color: "statusCritical", children: "An error occured while searching" }) })), isOpen &&
293
- filteredEntities.status === 'success' &&
294
- (((_b = filteredEntities.data) === null || _b === void 0 ? void 0 : _b.number) || 0) >
295
- ((_c = filteredEntities.data) === null || _c === void 0 ? void 0 : _c.entities.length) && (_jsx("li", { children: _jsxs(Text, { isGentleEmphazed: true, color: "textSecondary", style: { textAlign: 'right' }, children: ["There", ' ', (((_d = filteredEntities.data) === null || _d === void 0 ? void 0 : _d.number) || 0) -
296
- ((_e = filteredEntities.data) === null || _e === void 0 ? void 0 : _e.entities.length) ===
297
- 1
298
- ? 'is'
299
- : 'are', ' ', (((_f = filteredEntities.data) === null || _f === void 0 ? void 0 : _f.number) || 0) -
300
- ((_g = filteredEntities.data) === null || _g === void 0 ? void 0 : _g.entities.length), ' ', "more", ' ', (((_h = filteredEntities.data) === null || _h === void 0 ? void 0 : _h.number) || 0) -
301
- ((_j = filteredEntities.data) === null || _j === void 0 ? void 0 : _j.entities.length) ===
302
- 1
303
- ? entityName.singular
304
- : entityName.plural, ' ', "matching your search. Suggestion: try more specific search expression."] }) })), isOpen &&
305
- filteredEntities.status === 'success' &&
306
- ((_k = filteredEntities.data) === null || _k === void 0 ? void 0 : _k.entities.length) === 0 && (_jsx("li", { children: _jsxs(Text, { isGentleEmphazed: true, color: "textSecondary", children: ["No ", entityName.plural, " found matching your search."] }) }))] }), _jsx(StyledTable, { children: _jsx(Table, { columns: [
307
- {
308
- Header: 'Name',
309
- accessor: 'name',
310
- cellStyle: {
311
- flex: 1.5,
312
- marginRight: '1.5rem',
313
- },
314
- Cell: ({ value, row: { original: entity }, }) => {
315
- const { data: asyncName, status } = useQuery({
316
- ...(getNameQuery
317
- ? getNameQuery(entity)
318
- : { queryKey: ['fakeQuery'], queryFn: () => value }),
319
- enabled: !value,
320
- });
321
- if (value) {
322
- return _jsx(ConstrainedText, { text: value, lineClamp: 2 });
323
- }
324
- if (status === 'error') {
325
- return (_jsxs(_Fragment, { children: ["An error occured while loading ", entityName.singular, " name"] }));
326
- }
327
- if (status === 'loading' || status === 'idle') {
328
- return _jsx(_Fragment, { children: "Loading..." });
329
- }
330
- if (status === 'success') {
331
- if (!asyncName) {
332
- return _jsx(EmptyCell, {});
333
- }
334
- return _jsx(ConstrainedText, { text: asyncName, lineClamp: 2 });
335
- }
336
- return _jsx(EmptyCell, {});
337
- },
338
- },
339
- {
340
- Header: 'Attachment',
341
- accessor: 'isPending',
342
- cellStyle: {
343
- flex: 0.5,
344
- },
345
- Cell: ({ value }) => {
346
- return value ? _jsx(_Fragment, { children: "Pending" }) : _jsx(_Fragment, { children: "Attached" });
347
- },
348
- },
349
- {
350
- Header: _jsx(Box, { flex: 0.5 }),
351
- accessor: 'action',
352
- cellStyle: {
353
- textAlign: 'right',
354
- flex: 0.5,
355
- marginLeft: 'auto',
356
- marginRight: '0.5rem',
357
- },
358
- Cell: ({ row: { original: entity }, }) => (_jsx(Button, { size: "inline", onClick: () => {
359
- dispatch({
360
- action: AttachmentAction.REMOVE,
361
- entity: {
362
- name: entity.name,
363
- id: entity.id,
364
- type: entity.type,
331
+ }, children: [filteredEntities.status === 'error' ? (_jsx(Tooltip, { overlay: _jsx(_Fragment, { children: "We failed to load the entities, hence search is disabled" }), children: _jsxs(Stack, { children: [_jsx(StyledSearchInput, { autoComplete: "off", placeholder: searchEntityPlaceholder, ...getInputProps({
332
+ ref: (element) => {
333
+ if (element)
334
+ searchInputRef.current = element;
365
335
  },
366
- });
367
- }, icon: _jsx(Icon, { name: "Close" }), label: "Remove", variant: "danger", disabled: !!entity.disableDetach })),
368
- },
369
- ], data: desiredAttachedEntities.map((entity) => ({
370
- ...entity,
371
- isPending: entity.isPending || false,
372
- action: null,
373
- })), defaultSortingKey: "name", children: _jsx(Table.SingleSelectableContent, { rowHeight: rowHeight, separationLineVariant: "backgroundLevel2", children: (rows) => (_jsxs(_Fragment, { children: [initiallyAttachedEntitiesStatus === 'idle' ||
374
- initiallyAttachedEntitiesStatus === 'loading' ? (_jsxs(Wrap, { style: { height: `${tableRowHeight[rowHeight]}rem` }, children: [_jsx("p", {}), _jsxs(Stack, { children: [_jsx(Loader, {}), _jsxs(Text, { children: ["Loading ", entityName.plural, "..."] })] }), _jsx("p", {})] })) : initiallyAttachedEntitiesStatus === 'error' ? (_jsxs(Stack, { style: {
375
- justifyContent: 'center',
376
- height: `${tableRowHeight[rowHeight]}rem`,
377
- }, children: [_jsx(Icon, { name: "Exclamation-circle", color: "statusWarning" }), _jsxs(Text, { color: "textSecondary", children: ["Failed to load attached ", entityName.plural, "."] })] })) : (desiredAttachedEntities.length === 0 && (_jsxs(CenterredSecondaryText, { children: ["No ", entityName.plural, " attached"] }))), desiredAttachedEntities.length > 0 && rows] })) }) }) })] }));
336
+ }), onFocus: () => {
337
+ openMenu();
338
+ setSearchInputIsFocused(true);
339
+ }, onBlur: () => {
340
+ setSearchInputIsFocused(false);
341
+ }, disableToggle: true, disabled: filteredEntities.status === 'error' }), _jsx(Loader, {})] }) })) : (_jsx(StyledSearchInput, { autoComplete: "off", placeholder: searchEntityPlaceholder, ...getInputProps({
342
+ ref: (element) => {
343
+ if (element)
344
+ searchInputRef.current = element;
345
+ },
346
+ }), onFocus: () => {
347
+ openMenu();
348
+ setSearchInputIsFocused(true);
349
+ }, onBlur: () => {
350
+ setSearchInputIsFocused(false);
351
+ }, disableToggle: true, searchInputIsFocused: searchInputIsFocused })), _jsxs(MenuContainer, { ...getMenuProps(), width: searchWidth, isOpen: isOpen, searchInputIsFocused: searchInputIsFocused, children: [isOpen &&
352
+ filteredEntities.status === 'success' &&
353
+ ((_a = filteredEntities.data) === null || _a === void 0 ? void 0 : _a.entities.map((item, index) => (_jsx("li", { ...getItemProps({ item, index }), children: _jsx(Text, { children: item.name }) }, `${item.id}${index}`)))), isOpen && filteredEntities.status === 'loading' && (_jsx("li", { children: _jsx(Text, { children: "Searching..." }) })), isOpen && filteredEntities.status === 'error' && (_jsx("li", { children: _jsx(Text, { color: "statusCritical", children: "An error occured while searching" }) })), isOpen &&
354
+ filteredEntities.status === 'success' &&
355
+ (((_b = filteredEntities.data) === null || _b === void 0 ? void 0 : _b.number) || 0) >
356
+ ((_c = filteredEntities.data) === null || _c === void 0 ? void 0 : _c.entities.length) && (_jsx("li", { children: _jsxs(Text, { isGentleEmphazed: true, color: "textSecondary", style: { textAlign: 'right' }, children: ["There", ' ', (((_d = filteredEntities.data) === null || _d === void 0 ? void 0 : _d.number) || 0) -
357
+ ((_e = filteredEntities.data) === null || _e === void 0 ? void 0 : _e.entities.length) ===
358
+ 1
359
+ ? 'is'
360
+ : 'are', ' ', (((_f = filteredEntities.data) === null || _f === void 0 ? void 0 : _f.number) || 0) -
361
+ ((_g = filteredEntities.data) === null || _g === void 0 ? void 0 : _g.entities.length), ' ', "more", ' ', (((_h = filteredEntities.data) === null || _h === void 0 ? void 0 : _h.number) || 0) -
362
+ ((_j = filteredEntities.data) === null || _j === void 0 ? void 0 : _j.entities.length) ===
363
+ 1
364
+ ? entityName.singular
365
+ : entityName.plural, ' ', "matching your search. Suggestion: try more specific search expression."] }) })), isOpen &&
366
+ filteredEntities.status === 'success' &&
367
+ ((_k = filteredEntities.data) === null || _k === void 0 ? void 0 : _k.entities.length) === 0 && (_jsx("li", { children: _jsxs(Text, { isGentleEmphazed: true, color: "textSecondary", children: ["No ", entityName.plural, " found matching your search."] }) }))] })] }), _jsx(Table.SingleSelectableContent, { rowHeight: rowHeight, separationLineVariant: "backgroundLevel2", children: (rows) => (_jsxs(_Fragment, { children: [initiallyAttachedEntitiesStatus === 'idle' ||
368
+ initiallyAttachedEntitiesStatus === 'loading' ? (_jsxs(Wrap, { style: { height: `${tableRowHeight[rowHeight]}rem` }, children: [_jsx("p", {}), _jsxs(Stack, { children: [_jsx(Loader, {}), _jsxs(Text, { children: ["Loading ", entityName.plural, "..."] })] }), _jsx("p", {})] })) : initiallyAttachedEntitiesStatus === 'error' ? (_jsxs(Stack, { style: {
369
+ justifyContent: 'center',
370
+ height: `${tableRowHeight[rowHeight]}rem`,
371
+ }, children: [_jsx(Icon, { name: "Exclamation-circle", color: "statusWarning" }), _jsxs(Text, { color: "textSecondary", children: ["Failed to load attached ", entityName.plural, "."] })] })) : (desiredAttachedEntities.length === 0 && (_jsxs(CenterredSecondaryText, { children: ["No ", entityName.plural, " attached"] }))), desiredAttachedEntities.length > 0 && rows] })) })] }));
378
372
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scality/core-ui",
3
- "version": "0.126.0",
3
+ "version": "0.127.0",
4
4
  "description": "Scality common React component library",
5
5
  "author": "Scality Engineering",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -39,6 +39,14 @@ const StyledInput = styled.input<{ hasIcon: boolean }>`
39
39
  border: 0;
40
40
  outline: none;
41
41
  }
42
+ &:-webkit-autofill,
43
+ &:-webkit-autofill:hover,
44
+ &:-webkit-autofill:focus,
45
+ &:-webkit-autofill:active {
46
+ -webkit-text-fill-color: ${(props) => props.theme.textPrimary};
47
+ -webkit-background-clip: text;
48
+ caret-color: ${(props) => props.theme.textPrimary};
49
+ }
42
50
  `;
43
51
 
44
52
  const InputContainer = styled.div<{
@@ -14,6 +14,7 @@ export type Props = {
14
14
  disabled?: boolean;
15
15
  id?: string;
16
16
  size?: InputSize;
17
+ autoComplete?: 'on' | 'off';
17
18
  };
18
19
  const SearchInputContainer = styled.div<{
19
20
  docked?: boolean;
@@ -64,6 +65,7 @@ const SearchInput = forwardRef(
64
65
  disabled,
65
66
  id,
66
67
  size,
68
+ autoComplete = 'on',
67
69
  ...rest
68
70
  }: Props,
69
71
  forwardedRef,
@@ -105,6 +107,7 @@ const SearchInput = forwardRef(
105
107
  {...rest}
106
108
  >
107
109
  <Input
110
+ autoComplete={autoComplete}
108
111
  min={'1'}
109
112
  id={id || 'search'}
110
113
  type="search"
@@ -1,6 +1,4 @@
1
1
  import styled from 'styled-components';
2
-
3
- import { getThemePropSelector } from '../../utils';
4
2
  import { spacing } from '../../spacing';
5
3
 
6
4
  export const TabBar = styled.div`
@@ -24,7 +22,7 @@ export const TabItem = styled.div<{
24
22
  &:focus-visible {
25
23
  outline: 0;
26
24
  position: relative;
27
- border: ${spacing.r1} dashed ${getThemePropSelector('selectedActive')};
25
+ border: ${spacing.r1} dashed ${(props) => props.theme.selectedActive};
28
26
  }
29
27
 
30
28
  &:focus-within {
@@ -63,6 +61,7 @@ export const TabsContainer = styled.div<{
63
61
  separatorColor: string;
64
62
  }>`
65
63
  height: 100%;
64
+ width: 100%;
66
65
  display: flex;
67
66
  flex-direction: column;
68
67
  background-color: ${(props) =>
@@ -88,7 +87,11 @@ export const TabsContainer = styled.div<{
88
87
  export const TabContent = styled.div<{ tabContentColor?: string }>`
89
88
  margin: 0;
90
89
  padding: 0;
91
- flex: 1;
90
+ display: block;
91
+ width: 100%;
92
+ height: 100%;
93
+ box-sizing: border-box;
94
+ overflow: auto;
92
95
  background-color: ${(props) =>
93
96
  props.tabContentColor || props.theme.backgroundLevel4};
94
97
  `;
@@ -181,6 +181,7 @@ function Tabs({
181
181
  return (
182
182
  <TabsContext.Provider value={true}>
183
183
  <TabsContainer
184
+ style={{ containerType: 'size' }}
184
185
  className={['sc-tabs', className].join(' ')}
185
186
  tabLineColor={tabLineColor}
186
187
  separatorColor={separatorColor}
@@ -77,10 +77,7 @@ const MenuContainer = styled.ul<{
77
77
  position: absolute;
78
78
  width: ${(props) => props.width};
79
79
  z-index: 1;
80
- margin-top: -1.7rem;
81
- margin-left: 0;
82
- margin-bottom: 0;
83
- margin-right: 0;
80
+ margin: 0;
84
81
  ${(props) =>
85
82
  props.isOpen
86
83
  ? `
@@ -105,17 +102,18 @@ const MenuContainer = styled.ul<{
105
102
  `;
106
103
 
107
104
  const SearchBoxContainer = styled.div`
105
+ position: relative;
108
106
  padding: ${spacing.r16};
109
107
  `;
110
108
 
111
- const StyledSearchInput = styled(SearchInput)`
109
+ const StyledSearchInput = styled(SearchInput)<{ searchInputIsFocused }>`
112
110
  flex-grow: 1;
113
- .sc-input-type:focus {
114
- border-bottom: 0;
115
- border-top-left-radius: 4px;
116
- border-top-right-radius: 4px;
117
- border-bottom-right-radius: 0;
111
+
112
+ & > div:focus-within {
113
+ border-color: ${(props) => props.theme.selectedActive};
118
114
  border-bottom-left-radius: 0;
115
+ border-bottom-right-radius: 0;
116
+ border-bottom: 0;
119
117
  }
120
118
  `;
121
119
 
@@ -123,11 +121,6 @@ const AttachmentTableContainer = styled.div`
123
121
  height: 100%;
124
122
  `;
125
123
 
126
- const StyledTable = styled.div`
127
- background: ${(props) => props.theme.backgroundLevel4};
128
- height: 100%;
129
- `;
130
-
131
124
  const CenterredSecondaryText = styled(SecondaryText)`
132
125
  display: block;
133
126
  text-align: center;
@@ -471,7 +464,101 @@ export const AttachmentTable = <ENTITY_TYPE,>({
471
464
  const [searchInputIsFocused, setSearchInputIsFocused] = useState(false);
472
465
 
473
466
  return (
474
- <AttachmentTableContainer>
467
+ <Table
468
+ columns={[
469
+ {
470
+ Header: 'Name',
471
+ accessor: 'name',
472
+ cellStyle: {
473
+ flex: 1.5,
474
+ marginRight: '1.5rem',
475
+ },
476
+ Cell: ({
477
+ value,
478
+ row: { original: entity },
479
+ }: {
480
+ value: string;
481
+ row: { original: AttachableEntity<ENTITY_TYPE> };
482
+ }) => {
483
+ const { data: asyncName, status } = useQuery({
484
+ ...(getNameQuery
485
+ ? getNameQuery(entity)
486
+ : { queryKey: ['fakeQuery'], queryFn: () => value }),
487
+ enabled: !value,
488
+ });
489
+
490
+ if (value) {
491
+ return <ConstrainedText text={value} lineClamp={2} />;
492
+ }
493
+ if (status === 'error') {
494
+ return (
495
+ <>An error occured while loading {entityName.singular} name</>
496
+ );
497
+ }
498
+ if (status === 'loading' || status === 'idle') {
499
+ return <>Loading...</>;
500
+ }
501
+ if (status === 'success') {
502
+ if (!asyncName) {
503
+ return <EmptyCell />;
504
+ }
505
+ return <ConstrainedText text={asyncName} lineClamp={2} />;
506
+ }
507
+
508
+ return <EmptyCell />;
509
+ },
510
+ },
511
+ {
512
+ Header: 'Attachment',
513
+ accessor: 'isPending',
514
+ cellStyle: {
515
+ flex: 0.5,
516
+ },
517
+ Cell: ({ value }: { value?: boolean }) => {
518
+ return value ? <>Pending</> : <>Attached</>;
519
+ },
520
+ },
521
+ {
522
+ Header: <Box flex={0.5} />,
523
+ accessor: 'action',
524
+ cellStyle: {
525
+ textAlign: 'right',
526
+ flex: 0.5,
527
+ marginLeft: 'auto',
528
+ marginRight: '0.5rem',
529
+ },
530
+ Cell: ({
531
+ row: { original: entity },
532
+ }: {
533
+ row: { original: AttachableEntity<ENTITY_TYPE> };
534
+ }) => (
535
+ <Button
536
+ size="inline"
537
+ onClick={() => {
538
+ dispatch({
539
+ action: AttachmentAction.REMOVE,
540
+ entity: {
541
+ name: entity.name,
542
+ id: entity.id,
543
+ type: entity.type,
544
+ },
545
+ });
546
+ }}
547
+ icon={<Icon name="Close" />}
548
+ label="Remove"
549
+ variant="danger"
550
+ disabled={!!entity.disableDetach}
551
+ />
552
+ ),
553
+ },
554
+ ]}
555
+ data={desiredAttachedEntities.map((entity) => ({
556
+ ...entity,
557
+ isPending: entity.isPending || false,
558
+ action: null,
559
+ }))}
560
+ defaultSortingKey="name"
561
+ >
475
562
  <SearchBoxContainer
476
563
  {...{
477
564
  ref: (element) => {
@@ -493,6 +580,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
493
580
  >
494
581
  <Stack>
495
582
  <StyledSearchInput
583
+ autoComplete="off"
496
584
  placeholder={searchEntityPlaceholder}
497
585
  {...getInputProps({
498
586
  ref: (element) => {
@@ -514,6 +602,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
514
602
  </Tooltip>
515
603
  ) : (
516
604
  <StyledSearchInput
605
+ autoComplete="off"
517
606
  placeholder={searchEntityPlaceholder}
518
607
  {...getInputProps({
519
608
  ref: (element) => {
@@ -528,210 +617,113 @@ export const AttachmentTable = <ENTITY_TYPE,>({
528
617
  setSearchInputIsFocused(false);
529
618
  }}
530
619
  disableToggle
620
+ searchInputIsFocused={searchInputIsFocused}
531
621
  />
532
622
  )}
533
- </SearchBoxContainer>
534
- <MenuContainer
535
- {...getMenuProps()}
536
- width={searchWidth}
537
- isOpen={isOpen}
538
- searchInputIsFocused={searchInputIsFocused}
539
- >
540
- {isOpen &&
541
- filteredEntities.status === 'success' &&
542
- filteredEntities.data?.entities.map((item, index) => (
543
- <li key={`${item.id}${index}`} {...getItemProps({ item, index })}>
544
- <Text>{item.name}</Text>
545
- </li>
546
- ))}
547
- {isOpen && filteredEntities.status === 'loading' && (
548
- <li>
549
- <Text>Searching...</Text>
550
- </li>
551
- )}
552
- {isOpen && filteredEntities.status === 'error' && (
553
- <li>
554
- <Text color="statusCritical">An error occured while searching</Text>
555
- </li>
556
- )}
557
- {isOpen &&
558
- filteredEntities.status === 'success' &&
559
- (filteredEntities.data?.number || 0) >
560
- filteredEntities.data?.entities.length && (
623
+ <MenuContainer
624
+ {...getMenuProps()}
625
+ width={searchWidth}
626
+ isOpen={isOpen}
627
+ searchInputIsFocused={searchInputIsFocused}
628
+ >
629
+ {isOpen &&
630
+ filteredEntities.status === 'success' &&
631
+ filteredEntities.data?.entities.map((item, index) => (
632
+ <li key={`${item.id}${index}`} {...getItemProps({ item, index })}>
633
+ <Text>{item.name}</Text>
634
+ </li>
635
+ ))}
636
+ {isOpen && filteredEntities.status === 'loading' && (
561
637
  <li>
562
- <Text
563
- isGentleEmphazed={true}
564
- color="textSecondary"
565
- style={{ textAlign: 'right' }}
566
- >
567
- There{' '}
568
- {(filteredEntities.data?.number || 0) -
569
- filteredEntities.data?.entities.length ===
570
- 1
571
- ? 'is'
572
- : 'are'}{' '}
573
- {(filteredEntities.data?.number || 0) -
574
- filteredEntities.data?.entities.length}{' '}
575
- more{' '}
576
- {(filteredEntities.data?.number || 0) -
577
- filteredEntities.data?.entities.length ===
578
- 1
579
- ? entityName.singular
580
- : entityName.plural}{' '}
581
- matching your search. Suggestion: try more specific search
582
- expression.
583
- </Text>
638
+ <Text>Searching...</Text>
584
639
  </li>
585
640
  )}
586
- {isOpen &&
587
- filteredEntities.status === 'success' &&
588
- filteredEntities.data?.entities.length === 0 && (
641
+ {isOpen && filteredEntities.status === 'error' && (
589
642
  <li>
590
- <Text isGentleEmphazed={true} color="textSecondary">
591
- No {entityName.plural} found matching your search.
643
+ <Text color="statusCritical">
644
+ An error occured while searching
592
645
  </Text>
593
646
  </li>
594
647
  )}
595
- </MenuContainer>
596
- <StyledTable>
597
- <Table
598
- columns={[
599
- {
600
- Header: 'Name',
601
- accessor: 'name',
602
- cellStyle: {
603
- flex: 1.5,
604
- marginRight: '1.5rem',
605
- },
606
- Cell: ({
607
- value,
608
- row: { original: entity },
609
- }: {
610
- value: string;
611
- row: { original: AttachableEntity<ENTITY_TYPE> };
612
- }) => {
613
- const { data: asyncName, status } = useQuery({
614
- ...(getNameQuery
615
- ? getNameQuery(entity)
616
- : { queryKey: ['fakeQuery'], queryFn: () => value }),
617
- enabled: !value,
618
- });
619
-
620
- if (value) {
621
- return <ConstrainedText text={value} lineClamp={2} />;
622
- }
623
- if (status === 'error') {
624
- return (
625
- <>
626
- An error occured while loading {entityName.singular} name
627
- </>
628
- );
629
- }
630
- if (status === 'loading' || status === 'idle') {
631
- return <>Loading...</>;
632
- }
633
- if (status === 'success') {
634
- if (!asyncName) {
635
- return <EmptyCell />;
636
- }
637
- return <ConstrainedText text={asyncName} lineClamp={2} />;
638
- }
639
-
640
- return <EmptyCell />;
641
- },
642
- },
643
- {
644
- Header: 'Attachment',
645
- accessor: 'isPending',
646
- cellStyle: {
647
- flex: 0.5,
648
- },
649
- Cell: ({ value }: { value?: boolean }) => {
650
- return value ? <>Pending</> : <>Attached</>;
651
- },
652
- },
653
- {
654
- Header: <Box flex={0.5} />,
655
- accessor: 'action',
656
- cellStyle: {
657
- textAlign: 'right',
658
- flex: 0.5,
659
- marginLeft: 'auto',
660
- marginRight: '0.5rem',
661
- },
662
- Cell: ({
663
- row: { original: entity },
664
- }: {
665
- row: { original: AttachableEntity<ENTITY_TYPE> };
666
- }) => (
667
- <Button
668
- size="inline"
669
- onClick={() => {
670
- dispatch({
671
- action: AttachmentAction.REMOVE,
672
- entity: {
673
- name: entity.name,
674
- id: entity.id,
675
- type: entity.type,
676
- },
677
- });
678
- }}
679
- icon={<Icon name="Close" />}
680
- label="Remove"
681
- variant="danger"
682
- disabled={!!entity.disableDetach}
683
- />
684
- ),
685
- },
686
- ]}
687
- data={desiredAttachedEntities.map((entity) => ({
688
- ...entity,
689
- isPending: entity.isPending || false,
690
- action: null,
691
- }))}
692
- defaultSortingKey="name"
693
- >
694
- <Table.SingleSelectableContent
695
- rowHeight={rowHeight}
696
- separationLineVariant="backgroundLevel2"
697
- >
698
- {(rows) => (
699
- <>
700
- {initiallyAttachedEntitiesStatus === 'idle' ||
701
- initiallyAttachedEntitiesStatus === 'loading' ? (
702
- <Wrap style={{ height: `${tableRowHeight[rowHeight]}rem` }}>
703
- <p></p>
704
- <Stack>
705
- <Loader />
706
- <Text>Loading {entityName.plural}...</Text>
707
- </Stack>
708
- <p></p>
709
- </Wrap>
710
- ) : initiallyAttachedEntitiesStatus === 'error' ? (
711
- <Stack
712
- style={{
713
- justifyContent: 'center',
714
- height: `${tableRowHeight[rowHeight]}rem`,
715
- }}
716
- >
717
- <Icon name="Exclamation-circle" color="statusWarning" />
718
- <Text color="textSecondary">
719
- Failed to load attached {entityName.plural}.
720
- </Text>
721
- </Stack>
722
- ) : (
723
- desiredAttachedEntities.length === 0 && (
724
- <CenterredSecondaryText>
725
- No {entityName.plural} attached
726
- </CenterredSecondaryText>
727
- )
728
- )}
729
- {desiredAttachedEntities.length > 0 && rows}
730
- </>
648
+ {isOpen &&
649
+ filteredEntities.status === 'success' &&
650
+ (filteredEntities.data?.number || 0) >
651
+ filteredEntities.data?.entities.length && (
652
+ <li>
653
+ <Text
654
+ isGentleEmphazed={true}
655
+ color="textSecondary"
656
+ style={{ textAlign: 'right' }}
657
+ >
658
+ There{' '}
659
+ {(filteredEntities.data?.number || 0) -
660
+ filteredEntities.data?.entities.length ===
661
+ 1
662
+ ? 'is'
663
+ : 'are'}{' '}
664
+ {(filteredEntities.data?.number || 0) -
665
+ filteredEntities.data?.entities.length}{' '}
666
+ more{' '}
667
+ {(filteredEntities.data?.number || 0) -
668
+ filteredEntities.data?.entities.length ===
669
+ 1
670
+ ? entityName.singular
671
+ : entityName.plural}{' '}
672
+ matching your search. Suggestion: try more specific search
673
+ expression.
674
+ </Text>
675
+ </li>
676
+ )}
677
+ {isOpen &&
678
+ filteredEntities.status === 'success' &&
679
+ filteredEntities.data?.entities.length === 0 && (
680
+ <li>
681
+ <Text isGentleEmphazed={true} color="textSecondary">
682
+ No {entityName.plural} found matching your search.
683
+ </Text>
684
+ </li>
731
685
  )}
732
- </Table.SingleSelectableContent>
733
- </Table>
734
- </StyledTable>
735
- </AttachmentTableContainer>
686
+ </MenuContainer>
687
+ </SearchBoxContainer>
688
+ <Table.SingleSelectableContent
689
+ rowHeight={rowHeight}
690
+ separationLineVariant="backgroundLevel2"
691
+ >
692
+ {(rows) => (
693
+ <>
694
+ {initiallyAttachedEntitiesStatus === 'idle' ||
695
+ initiallyAttachedEntitiesStatus === 'loading' ? (
696
+ <Wrap style={{ height: `${tableRowHeight[rowHeight]}rem` }}>
697
+ <p></p>
698
+ <Stack>
699
+ <Loader />
700
+ <Text>Loading {entityName.plural}...</Text>
701
+ </Stack>
702
+ <p></p>
703
+ </Wrap>
704
+ ) : initiallyAttachedEntitiesStatus === 'error' ? (
705
+ <Stack
706
+ style={{
707
+ justifyContent: 'center',
708
+ height: `${tableRowHeight[rowHeight]}rem`,
709
+ }}
710
+ >
711
+ <Icon name="Exclamation-circle" color="statusWarning" />
712
+ <Text color="textSecondary">
713
+ Failed to load attached {entityName.plural}.
714
+ </Text>
715
+ </Stack>
716
+ ) : (
717
+ desiredAttachedEntities.length === 0 && (
718
+ <CenterredSecondaryText>
719
+ No {entityName.plural} attached
720
+ </CenterredSecondaryText>
721
+ )
722
+ )}
723
+ {desiredAttachedEntities.length > 0 && rows}
724
+ </>
725
+ )}
726
+ </Table.SingleSelectableContent>
727
+ </Table>
736
728
  );
737
729
  };
@@ -28,7 +28,11 @@ export const Playground = {
28
28
  status: 'success',
29
29
  data: {
30
30
  number: 1,
31
- entities: [{ name: 'User A', id: 'test', type: 'USER' }],
31
+ entities: [
32
+ { name: 'User A', id: 'test', type: 'USER' },
33
+ { name: 'User B', id: 'test', type: 'USER' },
34
+ { name: 'User C', id: 'test', type: 'USER' },
35
+ ],
32
36
  },
33
37
  }}
34
38
  initialAttachmentOperations={[]}