@cashub/ui 0.22.13 → 0.23.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.
package/Tab/Tab.js CHANGED
@@ -11,12 +11,16 @@ const Tab = _ref => {
11
11
  let {
12
12
  children,
13
13
  selected,
14
- onChange
14
+ onChange,
15
+ mode = 'view',
16
+ onNameChange
15
17
  } = _ref;
16
18
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_TabContext.default.Provider, {
17
19
  value: {
18
20
  selected,
19
- onChange
21
+ onChange,
22
+ mode,
23
+ onNameChange
20
24
  },
21
25
  children: children
22
26
  });
package/Tab/TabList.js CHANGED
@@ -4,26 +4,144 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _react = require("react");
7
8
  var _styledComponents = _interopRequireDefault(require("styled-components"));
9
+ var _fa = require("react-icons/fa");
10
+ var _button = require("../button");
8
11
  var _jsxRuntime = require("react/jsx-runtime");
9
- var _templateObject;
12
+ var _templateObject, _templateObject2, _templateObject3;
10
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
14
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
15
+ const MAX_MOVE_PIXEL = 300;
12
16
  const TabList = _ref => {
13
17
  let {
14
18
  children,
19
+ wrap = true,
15
20
  ...props
16
21
  } = _ref;
22
+ const wrapperRef = (0, _react.useRef)(null);
23
+ const [exceedContainerWidth, setExceedContainerWidth] = (0, _react.useState)(false);
24
+ const [hasPrevious, setHasPrevious] = (0, _react.useState)(false);
25
+ const [hasNext, setHasNext] = (0, _react.useState)(false);
26
+ const checkExceedContainerWidth = (0, _react.useCallback)(() => {
27
+ if (wrapperRef.current) {
28
+ const {
29
+ offsetWidth,
30
+ scrollWidth
31
+ } = wrapperRef.current;
32
+ let {
33
+ marginLeft
34
+ } = getComputedStyle(wrapperRef.current);
35
+ const currentMarginLeft = Math.abs(parseInt(marginLeft));
36
+ setHasPrevious(currentMarginLeft > 0);
37
+ setHasNext(scrollWidth - offsetWidth > 0);
38
+ setExceedContainerWidth(scrollWidth > offsetWidth - currentMarginLeft);
39
+ }
40
+ }, []);
41
+ const handleResize = (0, _react.useCallback)(() => {
42
+ checkExceedContainerWidth();
43
+ }, []);
44
+ const handleTransitionend = (0, _react.useCallback)(event => {
45
+ // only allow margin-left transition event
46
+ if (event && event.propertyName !== 'margin-left') {
47
+ return;
48
+ }
49
+ checkExceedContainerWidth();
50
+ }, []);
51
+ const getMovePixel = offsetWidth => {
52
+ // move 1/3 pixel as default
53
+ const defaultMovePixel = Math.ceil(offsetWidth / 3);
54
+ return defaultMovePixel > MAX_MOVE_PIXEL ? MAX_MOVE_PIXEL : defaultMovePixel;
55
+ };
56
+ const updateScrollPosition = marginLeft => {
57
+ wrapperRef.current.style.marginLeft = marginLeft;
58
+ };
59
+ const handlePrevious = () => {
60
+ const {
61
+ offsetWidth
62
+ } = wrapperRef.current;
63
+ const {
64
+ marginLeft
65
+ } = getComputedStyle(wrapperRef.current);
66
+ const currentMarginLeft = Math.abs(parseInt(marginLeft));
67
+ const availableMovePixel = currentMarginLeft;
68
+ const movePixel = getMovePixel(offsetWidth - currentMarginLeft);
69
+ if (movePixel > availableMovePixel) {
70
+ // exceed edge, so move to edge only
71
+ updateScrollPosition('0px');
72
+ } else {
73
+ updateScrollPosition("-".concat(currentMarginLeft - movePixel, "px"));
74
+ }
75
+ };
76
+ const handleNext = () => {
77
+ const {
78
+ offsetWidth,
79
+ scrollWidth
80
+ } = wrapperRef.current;
81
+ const {
82
+ marginLeft
83
+ } = getComputedStyle(wrapperRef.current);
84
+ const currentMarginLeft = Math.abs(parseInt(marginLeft));
85
+ const availableMovePixel = scrollWidth - offsetWidth;
86
+ const movePixel = getMovePixel(offsetWidth - currentMarginLeft);
87
+ if (movePixel > availableMovePixel) {
88
+ // exceed edge, so move to edge only
89
+ updateScrollPosition("-".concat(currentMarginLeft + availableMovePixel, "px"));
90
+ } else {
91
+ updateScrollPosition("-".concat(currentMarginLeft + movePixel, "px"));
92
+ }
93
+ };
94
+ (0, _react.useEffect)(() => {
95
+ window.addEventListener('resize', handleResize);
96
+ handleResize();
97
+ return () => {
98
+ window.removeEventListener('resize', handleResize);
99
+ };
100
+ }, [wrap, children]);
101
+ (0, _react.useEffect)(() => {
102
+ if (wrapperRef.current) {
103
+ wrapperRef.current.addEventListener('transitionend', handleTransitionend);
104
+ }
105
+ }, [wrap]);
17
106
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Container, {
18
107
  role: "tablist",
108
+ $wrap: wrap,
19
109
  ...props,
20
- children: children
110
+ children: wrap ? children : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
111
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(TabWrapper, {
112
+ ref: wrapperRef,
113
+ children: children
114
+ }), exceedContainerWidth && /*#__PURE__*/(0, _jsxRuntime.jsxs)(Paginate, {
115
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
116
+ "aria-label": "Previous",
117
+ reverse: true,
118
+ onClick: handlePrevious,
119
+ iconOnly: true,
120
+ disabled: !hasPrevious,
121
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fa.FaAngleLeft, {})
122
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
123
+ "aria-label": "Next",
124
+ reverse: true,
125
+ onClick: handleNext,
126
+ iconOnly: true,
127
+ disabled: !hasNext,
128
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_fa.FaAngleRight, {})
129
+ })]
130
+ })]
131
+ })
21
132
  });
22
133
  };
23
- const Container = _styledComponents.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n flex-wrap: wrap;\n border-bottom: var(--border-width) solid var(--border-color);\n margin-bottom: var(--spacing);\n\n ", "\n"])), _ref2 => {
134
+ const Container = _styledComponents.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n border-bottom: var(--border-width) solid var(--border-color);\n margin-bottom: var(--spacing);\n overflow: hidden;\n\n ", "\n\n ", "\n"])), _ref2 => {
24
135
  let {
25
- noMargin
136
+ $wrap
26
137
  } = _ref2;
138
+ return !$wrap && 'white-space: nowrap;';
139
+ }, _ref3 => {
140
+ let {
141
+ noMargin
142
+ } = _ref3;
27
143
  return noMargin && 'margin-bottom: 0;';
28
144
  });
145
+ const TabWrapper = _styledComponents.default.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n margin-right: calc(1rem * 2 + 10px * 4 + var(--spacing-xs) * 2);\n overflow: hidden;\n margin-left: 0;\n transition: margin-left 0.3s;\n"])));
146
+ const Paginate = _styledComponents.default.div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n\n > :not(:last-child) {\n margin-right: var(--spacing-xs);\n }\n"])));
29
147
  var _default = exports.default = TabList;
package/Tab/TabTab.js CHANGED
@@ -5,10 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _react = require("react");
8
+ var _utils = require("@cashub/utils");
8
9
  var _styledComponents = _interopRequireDefault(require("styled-components"));
9
10
  var _TabContext = _interopRequireDefault(require("./subComponent/TabContext"));
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
- var _templateObject;
12
+ var _templateObject, _templateObject2, _templateObject3;
12
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
14
15
  const TabTab = _ref => {
@@ -19,25 +20,61 @@ const TabTab = _ref => {
19
20
  } = _ref;
20
21
  const {
21
22
  selected,
22
- onChange
23
+ onChange,
24
+ mode,
25
+ onNameChange
23
26
  } = (0, _react.useContext)(_TabContext.default);
27
+ const [isModify, setIsModify] = (0, _react.useState)(false);
28
+ const [currentName, setCurrentName] = (0, _react.useState)(name);
24
29
  const handleClick = (0, _react.useCallback)(() => {
25
30
  if (selected !== name) {
26
31
  onChange(name);
27
32
  }
28
33
  }, [name, selected, onChange]);
29
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Tab, {
34
+ const handleDoubleClick = () => {
35
+ if (mode !== 'modify') return;
36
+ setIsModify(true);
37
+ };
38
+ const handleBlur = () => {
39
+ onNameChange(name, currentName);
40
+ setIsModify(false);
41
+ };
42
+ const handleKeyUp = event => {
43
+ const key = event.keyCode;
44
+ if (key === _utils.KEY_CODE.ENTER) {
45
+ onNameChange(name, currentName);
46
+ setIsModify(false);
47
+ }
48
+ };
49
+ return isModify ? /*#__PURE__*/(0, _jsxRuntime.jsx)(InputTab, {
50
+ role: "tab",
51
+ type: "text",
52
+ value: currentName,
53
+ onChange: event => {
54
+ setCurrentName(event.target.value);
55
+ },
56
+ onBlur: handleBlur,
57
+ onKeyUp: handleKeyUp,
58
+ autoFocus: true
59
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(ButtonTab, {
30
60
  role: "tab",
31
61
  onClick: handleClick,
62
+ onDoubleClick: handleDoubleClick,
32
63
  active: selected === name,
33
64
  ...props,
34
65
  children: children
35
66
  });
36
67
  };
37
- const Tab = _styledComponents.default.button(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n background: transparent;\n color: var(--font-on-mute);\n padding: 10px var(--spacing-s);\n border: none;\n border-bottom: 4px solid transparent;\n transition: color 0.3s, border 0.3s;\n cursor: pointer;\n\n &:hover {\n color: var(--font-on-background);\n }\n\n ", "\n"])), _ref2 => {
68
+ const Tab = _styledComponents.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n background: transparent;\n padding: 10px var(--spacing-s);\n border: none;\n border-bottom: 4px solid transparent;\n"])));
69
+ const ButtonTab = (0, _styledComponents.default)(Tab).attrs({
70
+ as: 'button'
71
+ })(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n color: var(--font-on-mute);\n transition: color 0.3s, border 0.3s;\n cursor: pointer;\n\n &:hover {\n color: var(--font-on-background);\n }\n\n ", "\n"])), _ref2 => {
38
72
  let {
39
73
  active
40
74
  } = _ref2;
41
75
  return active && "\n border-color: var(--color-primary);\n color: var(--font-on-background);\n ";
42
76
  });
77
+ const InputTab = (0, _styledComponents.default)(Tab).attrs({
78
+ as: 'input'
79
+ })(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n color: var(--font-on-background);\n border-color: var(--color-primary);\n outline: none;\n"])));
43
80
  var _default = exports.default = TabTab;
@@ -145,6 +145,8 @@ const Container = _styledComponents.default.div(_templateObject2 || (_templateOb
145
145
  size
146
146
  } = _ref5;
147
147
  switch (size) {
148
+ case 'extraLarge':
149
+ return 'max-width: 90%;';
148
150
  case 'large':
149
151
  return 'max-width: 75%;';
150
152
  case 'normal':
@@ -159,6 +161,7 @@ const Container = _styledComponents.default.div(_templateObject2 || (_templateOb
159
161
  size
160
162
  } = _ref6;
161
163
  switch (size) {
164
+ case 'extraLarge':
162
165
  case 'large':
163
166
  return 'max-width: 90%;';
164
167
  case 'normal':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cashub/ui",
3
- "version": "0.22.13",
3
+ "version": "0.23.0",
4
4
  "private": false,
5
5
  "author": "CASHUB Team",
6
6
  "description": "CASHUB UI components library",