@spaced-out/ui-design-system 0.3.24 → 0.3.25

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.
@@ -18,12 +18,14 @@ Choibalsan
18
18
  Chuuk
19
19
  circlehollow
20
20
  CODEOWNERS
21
+ Combobox
21
22
  commitlint
22
23
  contributorsrc
23
24
  Crespo
24
25
  Cuiaba
25
26
  D'Urville
26
27
  Danmarkshavn
28
+ darsh-mecwan-sense
27
29
  datetime
28
30
  DEFAULTTEXT
29
31
  Dili
@@ -22,7 +22,7 @@ jobs:
22
22
  - name: Check Permissions
23
23
  id: check-permissions
24
24
  env:
25
- ALLOWED_USERS: superrover, Anant-Raj, ashwini-sensehq, vish-sah, VishalBarnawal, sanskar-s, VivekJangid, sharad-kushwah, Swatantramishra1, bhatiarush27
25
+ ALLOWED_USERS: superrover, Anant-Raj, ashwini-sensehq, vish-sah, VishalBarnawal, sanskar-s, VivekJangid, sharad-kushwah, Swatantramishra1, bhatiarush27, darsh-mecwan-sense
26
26
  if: ${{ !contains(env.ALLOWED_USERS, github.actor) }}
27
27
  run: |
28
28
  echo "You don't have correct permissions to do this release"
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.3.25](https://github.com/spaced-out/ui-design-system/compare/v0.3.24...v0.3.25) (2025-03-01)
6
+
7
+
8
+ ### Features
9
+
10
+ * adds combobox ([#322](https://github.com/spaced-out/ui-design-system/issues/322)) ([ba788c8](https://github.com/spaced-out/ui-design-system/commit/ba788c8d9f7fe2913d07d6c24a605e87a5250bd0))
11
+
5
12
  ### [0.3.24](https://github.com/spaced-out/ui-design-system/compare/v0.3.23...v0.3.24) (2025-02-26)
6
13
 
7
14
 
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Combobox = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _classify = _interopRequireDefault(require("../../utils/classify"));
9
+ var _Dropdown = require("../Dropdown");
10
+ var _Input = require("../Input");
11
+ var _Text = require("../Text");
12
+ var _ComboboxModule = _interopRequireDefault(require("./Combobox.module.css"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
+
17
+ const Combobox = /*#__PURE__*/React.forwardRef((props, ref) => {
18
+ const {
19
+ value,
20
+ onChange,
21
+ classNames,
22
+ disabled,
23
+ type = 'text',
24
+ label,
25
+ inputPlaceholder,
26
+ size = 'medium',
27
+ onContainerClick,
28
+ onInputFocus,
29
+ onInputBlur,
30
+ onInputKeyDown,
31
+ onInputContainerClick,
32
+ inputName,
33
+ locked,
34
+ error,
35
+ errorText,
36
+ helperText,
37
+ required,
38
+ iconLeftName,
39
+ iconLeftType,
40
+ iconRightName,
41
+ iconRightType,
42
+ onIconRightClick,
43
+ readOnly,
44
+ boxRef,
45
+ inputBoxRef,
46
+ minLength,
47
+ maxLength,
48
+ pattern,
49
+ min,
50
+ max,
51
+ menu,
52
+ onMenuOpen,
53
+ onMenuClose,
54
+ scrollMenuToBottom,
55
+ onDropdownFocus,
56
+ onDropdownBlur,
57
+ onDropdownKeyDown,
58
+ onDropdownContainerClick,
59
+ dropdownName,
60
+ dropdownPlaceholder,
61
+ dropdownBoxRef
62
+ } = props;
63
+ const inputRef = React.useRef();
64
+ const dropdownRef = React.useRef();
65
+ const {
66
+ input: inputValue,
67
+ dropdown: dropdownInputText
68
+ } = value;
69
+ const handleInputChange = (evt, isEnter) => {
70
+ onChange({
71
+ dropdown: dropdownInputText || '',
72
+ input: evt.target.value,
73
+ inputChange: {
74
+ evt,
75
+ isEnter
76
+ }
77
+ });
78
+ };
79
+ const handleDropdownChange = option => {
80
+ onChange({
81
+ dropdown: option.label || '',
82
+ input: inputValue || '',
83
+ dropdownOption: option
84
+ });
85
+ };
86
+
87
+ /* Handling locked functionality at Combobox level */
88
+ React.useEffect(() => {
89
+ if (locked) {
90
+ inputRef.current && (inputRef.current.disabled = true);
91
+ dropdownRef.current && (dropdownRef.current.disabled = true);
92
+ } else {
93
+ inputRef.current && (inputRef.current.disabled = false);
94
+ dropdownRef.current && (dropdownRef.current.disabled = false);
95
+ }
96
+ }, [locked]);
97
+ return /*#__PURE__*/React.createElement("div", {
98
+ ref: ref,
99
+ className: (0, _classify.default)(_ComboboxModule.default.wrapper, classNames?.wrapper)
100
+ }, Boolean(label) && /*#__PURE__*/React.createElement("div", {
101
+ className: _ComboboxModule.default.info
102
+ }, /*#__PURE__*/React.createElement("div", {
103
+ className: _ComboboxModule.default.infoContent
104
+ }, /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
105
+ color: "secondary"
106
+ }, label ?? ''), "\xA0", required && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
107
+ color: "danger"
108
+ }, "*"))), /*#__PURE__*/React.createElement("div", {
109
+ className: (0, _classify.default)(_ComboboxModule.default.box, {
110
+ [_ComboboxModule.default.withError]: error ?? false
111
+ }, classNames?.box),
112
+ onClick: !(disabled || locked) ? onContainerClick : null,
113
+ ref: boxRef
114
+ }, /*#__PURE__*/React.createElement(_Dropdown.Dropdown, {
115
+ ref: dropdownRef,
116
+ menu: menu,
117
+ boxRef: dropdownBoxRef,
118
+ placeholder: dropdownPlaceholder,
119
+ readOnly: readOnly,
120
+ classNames: {
121
+ wrapper: (0, _classify.default)(_ComboboxModule.default.dropdownWrapper, classNames?.dropdown?.wrapper),
122
+ box: (0, _classify.default)(_ComboboxModule.default.dropdownBox, {
123
+ [_ComboboxModule.default.disabled]: disabled ?? null,
124
+ [_ComboboxModule.default.locked]: locked ?? null
125
+ }, classNames?.dropdown?.box),
126
+ iconRight: _ComboboxModule.default.chevron
127
+ },
128
+ disabled: disabled,
129
+ size: size,
130
+ onMenuOpen: onMenuOpen,
131
+ onMenuClose: onMenuClose,
132
+ onChange: handleDropdownChange,
133
+ scrollMenuToBottom: scrollMenuToBottom,
134
+ dropdownInputText: dropdownInputText,
135
+ onFocus: onDropdownFocus,
136
+ onBlur: onDropdownBlur,
137
+ onKeyDown: onDropdownKeyDown,
138
+ onContainerClick: onDropdownContainerClick,
139
+ name: dropdownName
140
+ }), /*#__PURE__*/React.createElement(_Input.Input, {
141
+ ref: inputRef,
142
+ boxRef: inputBoxRef,
143
+ name: inputName,
144
+ placeholder: inputPlaceholder,
145
+ onFocus: onInputFocus,
146
+ onBlur: onInputBlur,
147
+ onChange: handleInputChange,
148
+ onKeyDown: onInputKeyDown,
149
+ onContainerClick: onInputContainerClick,
150
+ value: inputValue,
151
+ type: type,
152
+ error: error,
153
+ disabled: disabled,
154
+ readOnly: readOnly,
155
+ classNames: {
156
+ wrapper: (0, _classify.default)(_ComboboxModule.default.inputWrapper, classNames?.input?.wrapper),
157
+ box: (0, _classify.default)(_ComboboxModule.default.inputBox, {
158
+ [_ComboboxModule.default.disabled]: disabled ?? null,
159
+ [_ComboboxModule.default.locked]: locked ?? null
160
+ }, classNames?.input?.box),
161
+ iconLeft: classNames?.input?.iconLeft,
162
+ iconRight: classNames?.input?.iconRight
163
+ },
164
+ size: size,
165
+ iconLeftName: iconLeftName,
166
+ iconLeftType: iconLeftType,
167
+ iconRightName: iconRightName,
168
+ iconRightType: iconRightType,
169
+ onIconRightClick: onIconRightClick,
170
+ minLength: minLength,
171
+ maxLength: maxLength,
172
+ pattern: pattern,
173
+ min: min,
174
+ max: max
175
+ })), (Boolean(helperText) || error) && /*#__PURE__*/React.createElement("div", {
176
+ className: _ComboboxModule.default.info
177
+ }, error && errorText ? /*#__PURE__*/React.createElement(_Text.BodySmall, {
178
+ color: "danger"
179
+ }, errorText) : typeof helperText === 'string' ? /*#__PURE__*/React.createElement(_Text.BodySmall, {
180
+ color: disabled ? 'disabled' : 'secondary'
181
+ }, helperText) : helperText));
182
+ });
183
+ exports.Combobox = Combobox;
@@ -0,0 +1,287 @@
1
+ // @flow strict
2
+
3
+ import * as React from 'react';
4
+
5
+ import classify from '../../utils/classify';
6
+ import {Dropdown} from '../Dropdown';
7
+ import type {IconType} from '../Icon';
8
+ import type {InputOnChangeParamsType} from '../Input';
9
+ import {Input} from '../Input';
10
+ import type {MenuOption, MenuProps} from '../Menu';
11
+ import {BodySmall, FormLabelSmall} from '../Text';
12
+
13
+ import css from './Combobox.module.css';
14
+
15
+
16
+ type InputClassNames = $ReadOnly<{
17
+ box?: string,
18
+ iconLeft?: string,
19
+ iconRight?: string,
20
+ wrapper?: string,
21
+ }>;
22
+
23
+ type DropdownClassNames = $ReadOnly<{
24
+ wrapper?: string,
25
+ box?: string,
26
+ iconRight?: string,
27
+ }>;
28
+
29
+ type ClassNames = $ReadOnly<{
30
+ wrapper?: string,
31
+ box?: string,
32
+ input?: InputClassNames,
33
+ dropdown?: DropdownClassNames,
34
+ }>;
35
+
36
+ export type ComboboxProps = {
37
+ /* Combobox props */
38
+ classNames?: ClassNames,
39
+ disabled?: boolean,
40
+ type?: 'text' | 'tel',
41
+ label?: string | React.Node,
42
+ size?: 'medium' | 'small',
43
+ onContainerClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
44
+ locked?: boolean,
45
+ error?: boolean,
46
+ errorText?: string,
47
+ helperText?: string | React.Node,
48
+ required?: boolean,
49
+ readOnly?: boolean,
50
+ boxRef?: (?HTMLElement) => mixed,
51
+ value: {dropdown?: string, input?: string},
52
+ onChange: ({
53
+ input: string,
54
+ dropdown: string,
55
+ inputChange?: InputOnChangeParamsType,
56
+ dropdownOption?: MenuOption,
57
+ }) => mixed,
58
+
59
+ /* Input props */
60
+ inputPlaceholder?: string,
61
+ onInputFocus?: (e: SyntheticInputEvent<HTMLInputElement>) => mixed,
62
+ onInputBlur?: (e: SyntheticInputEvent<HTMLInputElement>) => mixed,
63
+ onInputKeyDown?: (e: SyntheticKeyboardEvent<HTMLInputElement>) => mixed,
64
+ onInputContainerClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
65
+ inputName?: string,
66
+ iconLeftName?: string,
67
+ iconLeftType?: IconType,
68
+ iconRightName?: string,
69
+ iconRightType?: IconType,
70
+ onIconRightClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
71
+ inputBoxRef?: (?HTMLElement) => mixed,
72
+ minLength?: string,
73
+ maxLength?: string,
74
+ pattern?: string,
75
+ min?: string,
76
+ max?: string,
77
+
78
+ /* Dropdown props */
79
+ menu?: MenuProps,
80
+ onMenuOpen?: () => mixed,
81
+ onMenuClose?: () => mixed,
82
+ scrollMenuToBottom?: boolean,
83
+ onDropdownFocus?: (e: SyntheticInputEvent<HTMLInputElement>) => mixed,
84
+ onDropdownBlur?: (e: SyntheticInputEvent<HTMLInputElement>) => mixed,
85
+ onDropdownKeyDown?: (e: SyntheticKeyboardEvent<HTMLInputElement>) => mixed,
86
+ onDropdownContainerClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
87
+ dropdownName?: string,
88
+ dropdownPlaceholder?: string,
89
+ dropdownBoxRef?: (?HTMLElement) => mixed,
90
+ ...
91
+ };
92
+
93
+ export const Combobox: React$AbstractComponent<ComboboxProps, HTMLDivElement> =
94
+ React.forwardRef<ComboboxProps, HTMLDivElement>(
95
+ (props: ComboboxProps, ref) => {
96
+ const {
97
+ value,
98
+ onChange,
99
+ classNames,
100
+ disabled,
101
+ type = 'text',
102
+ label,
103
+ inputPlaceholder,
104
+ size = 'medium',
105
+ onContainerClick,
106
+ onInputFocus,
107
+ onInputBlur,
108
+ onInputKeyDown,
109
+ onInputContainerClick,
110
+ inputName,
111
+ locked,
112
+ error,
113
+ errorText,
114
+ helperText,
115
+ required,
116
+ iconLeftName,
117
+ iconLeftType,
118
+ iconRightName,
119
+ iconRightType,
120
+ onIconRightClick,
121
+ readOnly,
122
+ boxRef,
123
+ inputBoxRef,
124
+ minLength,
125
+ maxLength,
126
+ pattern,
127
+ min,
128
+ max,
129
+ menu,
130
+ onMenuOpen,
131
+ onMenuClose,
132
+ scrollMenuToBottom,
133
+ onDropdownFocus,
134
+ onDropdownBlur,
135
+ onDropdownKeyDown,
136
+ onDropdownContainerClick,
137
+ dropdownName,
138
+ dropdownPlaceholder,
139
+ dropdownBoxRef,
140
+ } = props;
141
+
142
+ const inputRef = React.useRef();
143
+ const dropdownRef = React.useRef();
144
+
145
+ const {input: inputValue, dropdown: dropdownInputText} = value;
146
+
147
+ const handleInputChange = (evt, isEnter) => {
148
+ onChange({
149
+ dropdown: dropdownInputText || '',
150
+ input: evt.target.value,
151
+ inputChange: {evt, isEnter},
152
+ });
153
+ };
154
+
155
+ const handleDropdownChange = (option) => {
156
+ onChange({
157
+ dropdown: option.label || '',
158
+ input: inputValue || '',
159
+ dropdownOption: option,
160
+ });
161
+ };
162
+
163
+ /* Handling locked functionality at Combobox level */
164
+ React.useEffect(() => {
165
+ if (locked) {
166
+ inputRef.current && (inputRef.current.disabled = true);
167
+ dropdownRef.current && (dropdownRef.current.disabled = true);
168
+ } else {
169
+ inputRef.current && (inputRef.current.disabled = false);
170
+ dropdownRef.current && (dropdownRef.current.disabled = false);
171
+ }
172
+ }, [locked]);
173
+
174
+ return (
175
+ <div ref={ref} className={classify(css.wrapper, classNames?.wrapper)}>
176
+ {Boolean(label) && (
177
+ <div className={css.info}>
178
+ <div className={css.infoContent}>
179
+ <FormLabelSmall color="secondary">{label ?? ''}</FormLabelSmall>
180
+ &nbsp;
181
+ {required && <FormLabelSmall color="danger">*</FormLabelSmall>}
182
+ </div>
183
+ </div>
184
+ )}
185
+ <div
186
+ className={classify(
187
+ css.box,
188
+ {
189
+ [css.withError]: error ?? false,
190
+ },
191
+ classNames?.box,
192
+ )}
193
+ onClick={!(disabled || locked) ? onContainerClick : null}
194
+ ref={boxRef}
195
+ >
196
+ <Dropdown
197
+ ref={dropdownRef}
198
+ menu={menu}
199
+ boxRef={dropdownBoxRef}
200
+ placeholder={dropdownPlaceholder}
201
+ readOnly={readOnly}
202
+ classNames={{
203
+ wrapper: classify(
204
+ css.dropdownWrapper,
205
+ classNames?.dropdown?.wrapper,
206
+ ),
207
+ box: classify(
208
+ css.dropdownBox,
209
+ {
210
+ [css.disabled]: disabled ?? null,
211
+ [css.locked]: locked ?? null,
212
+ },
213
+ classNames?.dropdown?.box,
214
+ ),
215
+ iconRight: css.chevron,
216
+ }}
217
+ disabled={disabled}
218
+ size={size}
219
+ onMenuOpen={onMenuOpen}
220
+ onMenuClose={onMenuClose}
221
+ onChange={handleDropdownChange}
222
+ scrollMenuToBottom={scrollMenuToBottom}
223
+ dropdownInputText={dropdownInputText}
224
+ onFocus={onDropdownFocus}
225
+ onBlur={onDropdownBlur}
226
+ onKeyDown={onDropdownKeyDown}
227
+ onContainerClick={onDropdownContainerClick}
228
+ name={dropdownName}
229
+ />
230
+ <Input
231
+ ref={inputRef}
232
+ boxRef={inputBoxRef}
233
+ name={inputName}
234
+ placeholder={inputPlaceholder}
235
+ onFocus={onInputFocus}
236
+ onBlur={onInputBlur}
237
+ onChange={handleInputChange}
238
+ onKeyDown={onInputKeyDown}
239
+ onContainerClick={onInputContainerClick}
240
+ value={inputValue}
241
+ type={type}
242
+ error={error}
243
+ disabled={disabled}
244
+ readOnly={readOnly}
245
+ classNames={{
246
+ wrapper: classify(css.inputWrapper, classNames?.input?.wrapper),
247
+ box: classify(
248
+ css.inputBox,
249
+ {
250
+ [css.disabled]: disabled ?? null,
251
+ [css.locked]: locked ?? null,
252
+ },
253
+ classNames?.input?.box,
254
+ ),
255
+ iconLeft: classNames?.input?.iconLeft,
256
+ iconRight: classNames?.input?.iconRight,
257
+ }}
258
+ size={size}
259
+ iconLeftName={iconLeftName}
260
+ iconLeftType={iconLeftType}
261
+ iconRightName={iconRightName}
262
+ iconRightType={iconRightType}
263
+ onIconRightClick={onIconRightClick}
264
+ minLength={minLength}
265
+ maxLength={maxLength}
266
+ pattern={pattern}
267
+ min={min}
268
+ max={max}
269
+ />
270
+ </div>
271
+ {(Boolean(helperText) || error) && (
272
+ <div className={css.info}>
273
+ {error && errorText ? (
274
+ <BodySmall color="danger">{errorText}</BodySmall>
275
+ ) : typeof helperText === 'string' ? (
276
+ <BodySmall color={disabled ? 'disabled' : 'secondary'}>
277
+ {helperText}
278
+ </BodySmall>
279
+ ) : (
280
+ helperText
281
+ )}
282
+ </div>
283
+ )}
284
+ </div>
285
+ );
286
+ },
287
+ );
@@ -0,0 +1,100 @@
1
+ @value (
2
+ colorBackgroundSecondary,
3
+ colorTextPrimary,
4
+ colorFillNone
5
+ ) from '../../styles/variables/_color.css';
6
+ @value (
7
+ sizeFluid,
8
+ size42
9
+ ) from '../../styles/variables/_size.css';
10
+ @value (
11
+ spaceNone,
12
+ spaceXXSmall
13
+ ) from '../../styles/variables/_space.css';
14
+ @value (
15
+ borderRadiusNone,
16
+ borderWidthPrimary
17
+ ) from '../../styles/variables/_border.css';
18
+ @value (
19
+ elevationCard
20
+ ) from '../../styles/variables/_elevation.css';
21
+
22
+ .wrapper {
23
+ display: flex;
24
+ flex-direction: column;
25
+ width: sizeFluid;
26
+ gap: spaceXXSmall;
27
+ }
28
+
29
+ .info {
30
+ display: flex;
31
+ justify-content: space-between;
32
+ }
33
+
34
+ .infoContent {
35
+ display: flex;
36
+ }
37
+
38
+ .box {
39
+ display: flex;
40
+ height: size42;
41
+ }
42
+
43
+ .box.withError .inputBox {
44
+ /* Enable border for error state */
45
+ border-left-width: borderWidthPrimary;
46
+ }
47
+
48
+ .locked {
49
+ border-style: dashed;
50
+ }
51
+
52
+ .dropdownWrapper {
53
+ flex: 1;
54
+ }
55
+
56
+ .dropdownBox {
57
+ /* Alter dropdown box default values */
58
+ background-color: colorBackgroundSecondary;
59
+ border-top-right-radius: borderRadiusNone;
60
+ border-bottom-right-radius: borderRadiusNone;
61
+ border-right-color: colorFillNone;
62
+ z-index: auto;
63
+ }
64
+
65
+ .dropdownWrapper:focus-within,
66
+ .dropdownBox:focus-within,
67
+ .dropdownBox:not(.disabled):not(.locked):hover {
68
+ /* brings up the (default dropdown) box shadow on hover */
69
+ z-index: elevationCard;
70
+ }
71
+
72
+ .inputWrapper {
73
+ flex: 2;
74
+ /* For error state input's default wrapper adds gap between box and zero height error text */
75
+ gap: spaceNone;
76
+ }
77
+
78
+ .inputBox {
79
+ /* Alter input box default values */
80
+ border-top-left-radius: borderRadiusNone;
81
+ border-bottom-left-radius: borderRadiusNone;
82
+ border-left-color: colorFillNone;
83
+ z-index: auto;
84
+ }
85
+
86
+ .inputWrapper:focus-within,
87
+ .inputBox:focus-within,
88
+ .inputBox:not(.disabled):not(.locked):hover {
89
+ /* brings up the (default input) box shadow on hover */
90
+ z-index: elevationCard;
91
+ }
92
+
93
+ .dropdownBox:not(.disabled) .chevron {
94
+ color: colorTextPrimary;
95
+ }
96
+
97
+ .dropdownBox.locked,
98
+ .inputBox.locked {
99
+ pointer-events: none;
100
+ }
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.phoneNumberOptions = exports.formatPhoneNumber = exports.defaultOptions = exports.currencyOptions = void 0;
7
+
8
+ const defaultOptions = [{
9
+ key: '1',
10
+ label: 'Option one',
11
+ iconLeft: 'coffee'
12
+ }, {
13
+ key: '2',
14
+ label: 'Option two',
15
+ iconLeft: 'user'
16
+ }, {
17
+ key: '4',
18
+ label: 'Option three',
19
+ iconLeft: 'face-party'
20
+ }, {
21
+ key: '5',
22
+ label: 'Option five(disabled)',
23
+ disabled: true,
24
+ iconLeft: 'flag'
25
+ }, {
26
+ key: '6',
27
+ label: 'Option six(disabled) very long option that would truncate',
28
+ disabled: true,
29
+ iconLeft: 'camera'
30
+ }, {
31
+ key: '7',
32
+ label: 'Option seven',
33
+ iconLeft: 'coffee'
34
+ }, {
35
+ key: '8',
36
+ label: 'Option eight',
37
+ iconLeft: 'user'
38
+ }, {
39
+ key: '9',
40
+ label: 'Option nine',
41
+ iconLeft: 'face-party'
42
+ }];
43
+ exports.defaultOptions = defaultOptions;
44
+ const currencyOptions = [{
45
+ key: 'USD',
46
+ label: 'USD',
47
+ iconLeft: 'dollar-sign'
48
+ }, {
49
+ key: 'JPY',
50
+ label: 'JPY',
51
+ iconLeft: 'yen-sign'
52
+ }, {
53
+ key: 'KRW',
54
+ label: 'KRW',
55
+ iconLeft: 'won-sign'
56
+ }, {
57
+ key: 'KRW',
58
+ label: 'KRW',
59
+ iconLeft: 'won-sign'
60
+ }, {
61
+ key: 'GBP',
62
+ label: 'GBP',
63
+ iconLeft: 'sterling-sign'
64
+ }, {
65
+ key: 'INR',
66
+ label: 'INR',
67
+ iconLeft: 'indian-rupee-sign'
68
+ }, {
69
+ key: 'EUR',
70
+ label: 'EUR',
71
+ iconLeft: 'euro-sign'
72
+ }, {
73
+ key: 'CHF',
74
+ label: 'CHF',
75
+ iconLeft: 'franc-sign'
76
+ }];
77
+ exports.currencyOptions = currencyOptions;
78
+ const phoneNumberOptions = [{
79
+ key: 'US',
80
+ label: '+1 (United States)'
81
+ }, {
82
+ key: 'GB',
83
+ label: '+44 (United Kingdom)'
84
+ }, {
85
+ key: 'JP',
86
+ label: '+81 (Japan)'
87
+ }, {
88
+ key: 'KR',
89
+ label: '+82 (South Korea)'
90
+ }, {
91
+ key: 'IN',
92
+ label: '+91 (India)'
93
+ }, {
94
+ key: 'FR',
95
+ label: '+33 (France)'
96
+ }, {
97
+ key: 'DE',
98
+ label: '+49 (Germany)'
99
+ }];
100
+
101
+ /**
102
+ * Format phone numbers according to country-specific patterns
103
+ * @param {string} phoneNumber - The phone number to format
104
+ * @param {string} locale - The locale/country code (e.g., 'US', 'GB', 'JP')
105
+ * @returns {string} - Formatted phone number
106
+ */
107
+ exports.phoneNumberOptions = phoneNumberOptions;
108
+ const formatPhoneNumber = function (phoneNumber) {
109
+ let locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'US';
110
+ // Remove all non-numeric characters
111
+ const cleaned = phoneNumber.replace(/\D/g, '');
112
+
113
+ // Format patterns for different locales
114
+ const patterns = {
115
+ // North America
116
+ US: {
117
+ // United States
118
+ pattern: /(\d{3})(\d{3})(\d{4})/,
119
+ format: '($1) $2-$3',
120
+ countryCode: '+1'
121
+ },
122
+ CA: {
123
+ // Canada
124
+ pattern: /(\d{3})(\d{3})(\d{4})/,
125
+ format: '($1) $2-$3',
126
+ countryCode: '+1'
127
+ },
128
+ // Europe
129
+ GB: {
130
+ // United Kingdom
131
+ pattern: /(\d{2})(\d{4})(\d{4})/,
132
+ format: '$1 $2 $3',
133
+ countryCode: '+44'
134
+ },
135
+ DE: {
136
+ // Germany
137
+ pattern: /(\d{3})(\d{4})(\d{4})/,
138
+ format: '$1 $2 $3',
139
+ countryCode: '+49'
140
+ },
141
+ FR: {
142
+ // France
143
+ pattern: /(\d{1})(\d{2})(\d{2})(\d{2})(\d{2})/,
144
+ format: '$1 $2 $3 $4 $5',
145
+ countryCode: '+33'
146
+ },
147
+ // Asia
148
+ JP: {
149
+ // Japan
150
+ pattern: /(\d{2})(\d{4})(\d{4})/,
151
+ format: '$1-$2-$3',
152
+ countryCode: '+81'
153
+ },
154
+ KR: {
155
+ // South Korea
156
+ pattern: /(\d{3})(\d{4})(\d{4})/,
157
+ format: '$1-$2-$3',
158
+ countryCode: '+82'
159
+ },
160
+ CN: {
161
+ // China
162
+ pattern: /(\d{3})(\d{4})(\d{4})/,
163
+ format: '$1 $2 $3',
164
+ countryCode: '+86'
165
+ },
166
+ IN: {
167
+ // India
168
+ pattern: /(\d{3})(\d{3})(\d{4})/,
169
+ format: '$1 $2 $3',
170
+ countryCode: '+91'
171
+ }
172
+ };
173
+
174
+ // Get the formatting rule for the locale
175
+ const rule = patterns[locale] || patterns.US; // Default to US formatting
176
+
177
+ // If number starts with country code, remove it for formatting
178
+ let numberToFormat = cleaned;
179
+ const countryCode = rule.countryCode.replace('+', '');
180
+ if (cleaned.startsWith(countryCode)) {
181
+ numberToFormat = cleaned.slice(countryCode.length);
182
+ }
183
+
184
+ // Format the number according to the pattern
185
+ const formatted = numberToFormat.replace(rule.pattern, rule.format);
186
+ return formatted;
187
+ };
188
+ exports.formatPhoneNumber = formatPhoneNumber;
@@ -0,0 +1,204 @@
1
+ // @flow strict
2
+ import type {MenuOption} from '../Menu';
3
+
4
+
5
+ export const defaultOptions: MenuOption[] = [
6
+ {
7
+ key: '1',
8
+ label: 'Option one',
9
+ iconLeft: 'coffee',
10
+ },
11
+ {key: '2', label: 'Option two', iconLeft: 'user'},
12
+ {
13
+ key: '4',
14
+ label: 'Option three',
15
+ iconLeft: 'face-party',
16
+ },
17
+ {
18
+ key: '5',
19
+ label: 'Option five(disabled)',
20
+ disabled: true,
21
+ iconLeft: 'flag',
22
+ },
23
+ {
24
+ key: '6',
25
+ label: 'Option six(disabled) very long option that would truncate',
26
+ disabled: true,
27
+ iconLeft: 'camera',
28
+ },
29
+ {
30
+ key: '7',
31
+ label: 'Option seven',
32
+ iconLeft: 'coffee',
33
+ },
34
+ {key: '8', label: 'Option eight', iconLeft: 'user'},
35
+ {
36
+ key: '9',
37
+ label: 'Option nine',
38
+ iconLeft: 'face-party',
39
+ },
40
+ ];
41
+
42
+ export const currencyOptions: MenuOption[] = [
43
+ {
44
+ key: 'USD',
45
+ label: 'USD',
46
+ iconLeft: 'dollar-sign',
47
+ },
48
+ {
49
+ key: 'JPY',
50
+ label: 'JPY',
51
+ iconLeft: 'yen-sign',
52
+ },
53
+ {
54
+ key: 'KRW',
55
+ label: 'KRW',
56
+ iconLeft: 'won-sign',
57
+ },
58
+ {
59
+ key: 'KRW',
60
+ label: 'KRW',
61
+ iconLeft: 'won-sign',
62
+ },
63
+ {
64
+ key: 'GBP',
65
+ label: 'GBP',
66
+ iconLeft: 'sterling-sign',
67
+ },
68
+ {
69
+ key: 'INR',
70
+ label: 'INR',
71
+ iconLeft: 'indian-rupee-sign',
72
+ },
73
+ {
74
+ key: 'EUR',
75
+ label: 'EUR',
76
+ iconLeft: 'euro-sign',
77
+ },
78
+ {
79
+ key: 'CHF',
80
+ label: 'CHF',
81
+ iconLeft: 'franc-sign',
82
+ },
83
+ ];
84
+
85
+ export const phoneNumberOptions: MenuOption[] = [
86
+ {
87
+ key: 'US',
88
+ label: '+1 (United States)',
89
+ },
90
+ {
91
+ key: 'GB',
92
+ label: '+44 (United Kingdom)',
93
+ },
94
+ {
95
+ key: 'JP',
96
+ label: '+81 (Japan)',
97
+ },
98
+ {
99
+ key: 'KR',
100
+ label: '+82 (South Korea)',
101
+ },
102
+ {
103
+ key: 'IN',
104
+ label: '+91 (India)',
105
+ },
106
+ {
107
+ key: 'FR',
108
+ label: '+33 (France)',
109
+ },
110
+ {
111
+ key: 'DE',
112
+ label: '+49 (Germany)',
113
+ },
114
+ ];
115
+
116
+ /**
117
+ * Format phone numbers according to country-specific patterns
118
+ * @param {string} phoneNumber - The phone number to format
119
+ * @param {string} locale - The locale/country code (e.g., 'US', 'GB', 'JP')
120
+ * @returns {string} - Formatted phone number
121
+ */
122
+ export const formatPhoneNumber = (
123
+ phoneNumber: string,
124
+ locale: string = 'US',
125
+ ): string => {
126
+ // Remove all non-numeric characters
127
+ const cleaned = phoneNumber.replace(/\D/g, '');
128
+
129
+ // Format patterns for different locales
130
+ const patterns = {
131
+ // North America
132
+ US: {
133
+ // United States
134
+ pattern: /(\d{3})(\d{3})(\d{4})/,
135
+ format: '($1) $2-$3',
136
+ countryCode: '+1',
137
+ },
138
+ CA: {
139
+ // Canada
140
+ pattern: /(\d{3})(\d{3})(\d{4})/,
141
+ format: '($1) $2-$3',
142
+ countryCode: '+1',
143
+ },
144
+ // Europe
145
+ GB: {
146
+ // United Kingdom
147
+ pattern: /(\d{2})(\d{4})(\d{4})/,
148
+ format: '$1 $2 $3',
149
+ countryCode: '+44',
150
+ },
151
+ DE: {
152
+ // Germany
153
+ pattern: /(\d{3})(\d{4})(\d{4})/,
154
+ format: '$1 $2 $3',
155
+ countryCode: '+49',
156
+ },
157
+ FR: {
158
+ // France
159
+ pattern: /(\d{1})(\d{2})(\d{2})(\d{2})(\d{2})/,
160
+ format: '$1 $2 $3 $4 $5',
161
+ countryCode: '+33',
162
+ },
163
+ // Asia
164
+ JP: {
165
+ // Japan
166
+ pattern: /(\d{2})(\d{4})(\d{4})/,
167
+ format: '$1-$2-$3',
168
+ countryCode: '+81',
169
+ },
170
+ KR: {
171
+ // South Korea
172
+ pattern: /(\d{3})(\d{4})(\d{4})/,
173
+ format: '$1-$2-$3',
174
+ countryCode: '+82',
175
+ },
176
+ CN: {
177
+ // China
178
+ pattern: /(\d{3})(\d{4})(\d{4})/,
179
+ format: '$1 $2 $3',
180
+ countryCode: '+86',
181
+ },
182
+ IN: {
183
+ // India
184
+ pattern: /(\d{3})(\d{3})(\d{4})/,
185
+ format: '$1 $2 $3',
186
+ countryCode: '+91',
187
+ },
188
+ };
189
+
190
+ // Get the formatting rule for the locale
191
+ const rule = patterns[locale] || patterns.US; // Default to US formatting
192
+
193
+ // If number starts with country code, remove it for formatting
194
+ let numberToFormat = cleaned;
195
+ const countryCode = rule.countryCode.replace('+', '');
196
+ if (cleaned.startsWith(countryCode)) {
197
+ numberToFormat = cleaned.slice(countryCode.length);
198
+ }
199
+
200
+ // Format the number according to the pattern
201
+ const formatted = numberToFormat.replace(rule.pattern, rule.format);
202
+
203
+ return formatted;
204
+ };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _Combobox = require("./Combobox");
7
+ Object.keys(_Combobox).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _Combobox[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _Combobox[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,3 @@
1
+ // @flow strict
2
+
3
+ export * from './Combobox';
@@ -79,7 +79,8 @@ const Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) => {
79
79
  placeholder: placeholder,
80
80
  value: dropdownInputText,
81
81
  classNames: {
82
- box: (0, _classify.classify)(_DropdownModule.default.inputBox, classNames?.box)
82
+ box: (0, _classify.classify)(_DropdownModule.default.inputBox, classNames?.box),
83
+ iconRight: classNames?.iconRight
83
84
  },
84
85
  iconRightName: isOpen ? 'angle-up' : 'angle-down',
85
86
  readOnly: true,
@@ -25,7 +25,11 @@ import {Menu} from '../Menu';
25
25
  import css from './Dropdown.module.css';
26
26
 
27
27
 
28
- type ClassNames = $ReadOnly<{wrapper?: string, box?: string}>;
28
+ type ClassNames = $ReadOnly<{
29
+ wrapper?: string,
30
+ box?: string,
31
+ iconRight?: string,
32
+ }>;
29
33
 
30
34
  export type DropdownProps = {
31
35
  ...InputProps,
@@ -97,7 +101,10 @@ export const Dropdown: React$AbstractComponent<
97
101
  size={size}
98
102
  placeholder={placeholder}
99
103
  value={dropdownInputText}
100
- classNames={{box: classify(css.inputBox, classNames?.box)}}
104
+ classNames={{
105
+ box: classify(css.inputBox, classNames?.box),
106
+ iconRight: classNames?.iconRight,
107
+ }}
101
108
  iconRightName={isOpen ? 'angle-up' : 'angle-down'}
102
109
  readOnly
103
110
  onContainerClick={(e) => {
@@ -36,6 +36,11 @@ export const INPUT_TYPES = Object.freeze({
36
36
 
37
37
  export type InputType = $Values<typeof INPUT_TYPES>;
38
38
 
39
+ export type InputOnChangeParamsType = {
40
+ evt: SyntheticInputEvent<HTMLInputElement>,
41
+ isEnter?: boolean,
42
+ };
43
+
39
44
  export type InputProps = {
40
45
  value?: string,
41
46
  onChange?: (
@@ -168,6 +168,17 @@ Object.keys(_CollapsibleCard).forEach(function (key) {
168
168
  }
169
169
  });
170
170
  });
171
+ var _Combobox = require("./Combobox");
172
+ Object.keys(_Combobox).forEach(function (key) {
173
+ if (key === "default" || key === "__esModule") return;
174
+ if (key in exports && exports[key] === _Combobox[key]) return;
175
+ Object.defineProperty(exports, key, {
176
+ enumerable: true,
177
+ get: function () {
178
+ return _Combobox[key];
179
+ }
180
+ });
181
+ });
171
182
  var _ConditionalWrapper = require("./ConditionalWrapper");
172
183
  Object.keys(_ConditionalWrapper).forEach(function (key) {
173
184
  if (key === "default" || key === "__esModule") return;
@@ -15,6 +15,7 @@ export * from './Checkbox';
15
15
  export * from './Chip';
16
16
  export * from './CircularLoader';
17
17
  export * from './CollapsibleCard';
18
+ export * from './Combobox';
18
19
  export * from './ConditionalWrapper';
19
20
  export * from './DateRangePicker';
20
21
  export * from './Dialog';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.3.24",
3
+ "version": "0.3.25",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {