@transferwise/components 0.0.0-experimental-414f25f → 0.0.0-experimental-ec79c77

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 (49) hide show
  1. package/build/index.esm.js +59 -118
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +59 -118
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +0 -107
  6. package/build/styles/main.css +0 -107
  7. package/build/types/common/responsivePanel/ResponsivePanel.d.ts.map +1 -1
  8. package/build/types/dimmer/Dimmer.d.ts.map +1 -1
  9. package/build/types/index.d.ts +1 -0
  10. package/build/types/index.d.ts.map +1 -1
  11. package/build/types/inputs/SelectInput.d.ts +2 -2
  12. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  13. package/build/types/inputs/_BottomSheet.d.ts.map +1 -1
  14. package/build/types/inputs/_Popover.d.ts.map +1 -1
  15. package/build/types/moneyInput/MoneyInput.d.ts +45 -31
  16. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  17. package/build/types/moneyInput/MoneyInput.messages.d.ts +6 -6
  18. package/build/types/moneyInput/MoneyInput.messages.d.ts.map +1 -1
  19. package/build/types/moneyInput/currencyFormatting.d.ts +2 -2
  20. package/build/types/moneyInput/currencyFormatting.d.ts.map +1 -1
  21. package/build/types/moneyInput/index.d.ts +2 -1
  22. package/build/types/moneyInput/index.d.ts.map +1 -1
  23. package/package.json +1 -1
  24. package/src/common/bottomSheet/__snapshots__/BottomSheet.spec.tsx.snap +1 -1
  25. package/src/common/responsivePanel/ResponsivePanel.tsx +1 -2
  26. package/src/dimmer/Dimmer.tsx +5 -1
  27. package/src/index.ts +1 -0
  28. package/src/inputs/SelectInput.tsx +2 -2
  29. package/src/inputs/_BottomSheet.tsx +5 -1
  30. package/src/inputs/_Popover.tsx +5 -1
  31. package/src/main.css +0 -107
  32. package/src/main.less +0 -1
  33. package/src/moneyInput/{MoneyInput.rtl.spec.js → MoneyInput.rtl.spec.tsx} +4 -4
  34. package/src/moneyInput/MoneyInput.spec.js +109 -49
  35. package/src/moneyInput/MoneyInput.story.tsx +6 -14
  36. package/src/moneyInput/{MoneyInput.js → MoneyInput.tsx} +123 -127
  37. package/src/moneyInput/{currencyFormatting.spec.js → currencyFormatting.spec.ts} +2 -2
  38. package/src/moneyInput/{currencyFormatting.js → currencyFormatting.ts} +7 -10
  39. package/src/moneyInput/index.ts +2 -0
  40. package/src/popover/__snapshots__/Popover.spec.js.snap +1 -1
  41. package/build/styles/segmentedControl/SegmentedControl.css +0 -107
  42. package/build/types/segmentedControl/SegmentedControl.d.ts +0 -31
  43. package/build/types/segmentedControl/SegmentedControl.d.ts.map +0 -1
  44. package/src/moneyInput/index.js +0 -1
  45. package/src/segmentedControl/SegmentedControl.css +0 -107
  46. package/src/segmentedControl/SegmentedControl.less +0 -107
  47. package/src/segmentedControl/SegmentedControl.story.tsx +0 -55
  48. package/src/segmentedControl/SegmentedControl.tsx +0 -146
  49. /package/src/moneyInput/{MoneyInput.messages.js → MoneyInput.messages.ts} +0 -0
@@ -1,48 +1,64 @@
1
1
  import { isEmpty, isNumber, isNull } from '@transferwise/neptune-validation';
2
2
  import { Flag } from '@wise/art';
3
3
  import classNames from 'classnames';
4
- import PropTypes from 'prop-types';
5
4
  import { Component } from 'react';
6
- import { injectIntl } from 'react-intl';
5
+ import { injectIntl, WrappedComponentProps } from 'react-intl';
7
6
 
8
7
  import { Typography } from '../common';
9
8
  import { Key as keyValues } from '../common/key';
10
9
  import keyCodes from '../common/keyCodes';
11
- import { Size } from '../common/propsValues/size';
10
+ import { Size, SizeLarge, SizeMedium, SizeSmall } from '../common/propsValues/size';
12
11
  import { Input } from '../inputs/Input';
13
- import { SelectInput, SelectInputOptionContent } from '../inputs/SelectInput';
12
+ import {
13
+ SelectInput,
14
+ SelectInputItem,
15
+ SelectInputOptionContent,
16
+ SelectInputOptionItem,
17
+ SelectInputProps,
18
+ } from '../inputs/SelectInput';
14
19
  import Title from '../title';
15
20
 
16
21
  import messages from './MoneyInput.messages';
17
22
  import { formatAmount, parseAmount } from './currencyFormatting';
18
23
 
19
- const Currency = PropTypes.shape({
20
- header: PropTypes.string,
21
- value: PropTypes.string,
22
- label: PropTypes.string,
23
- currency: PropTypes.string,
24
- note: PropTypes.string,
25
- searchable: PropTypes.string,
26
- });
24
+ export interface CurrencyOption {
25
+ value: string;
26
+ label: string;
27
+ currency: string;
28
+ note?: string;
29
+ searchable?: string;
30
+ }
31
+
32
+ type Currency = { header: string } | ({ header?: never } & CurrencyOption);
27
33
 
28
- const isNumberOrNull = (v) => isNumber(v) || isNull(v);
34
+ const isNumberOrNull = (v: unknown): v is number | null => isNumber(v) || isNull(v);
29
35
 
30
- const formatAmountIfSet = (amount, currency, locale, maxLengthOverride) => {
36
+ const formatAmountIfSet = (
37
+ amount: number | null | undefined,
38
+ currency: string,
39
+ locale: string,
40
+ maxLengthOverride: number | undefined,
41
+ ) => {
31
42
  if (maxLengthOverride) {
32
- return amount || '';
43
+ return amount != null ? String(amount) : '';
33
44
  } else {
34
45
  return typeof amount === 'number' ? formatAmount(amount, currency, locale) : '';
35
46
  }
36
47
  };
37
48
 
38
- const parseNumber = (amount, currency, locale, maxLengthOverride) => {
49
+ const parseNumber = (
50
+ amount: string,
51
+ currency: string,
52
+ locale: string,
53
+ maxLengthOverride: number | undefined,
54
+ ) => {
39
55
  if (!maxLengthOverride) {
40
56
  return parseAmount(amount, currency, locale);
41
57
  }
42
58
  if (maxLengthOverride && amount.length > maxLengthOverride) {
43
59
  return 0;
44
60
  }
45
- return +amount;
61
+ return Number(amount);
46
62
  };
47
63
 
48
64
  const inputKeyCodeAllowlist = new Set([
@@ -61,39 +77,76 @@ const inputKeyCodeAllowlist = new Set([
61
77
 
62
78
  const inputKeyAllowlist = new Set([keyValues.PERIOD, keyValues.COMMA]);
63
79
 
64
- class MoneyInput extends Component {
65
- constructor(props) {
80
+ export interface MoneyInputProps extends WrappedComponentProps {
81
+ id?: string;
82
+ currencies: readonly Currency[];
83
+ selectedCurrency: CurrencyOption;
84
+ onCurrencyChange?: (value: CurrencyOption) => void;
85
+ placeholder?: number;
86
+ amount?: number;
87
+ size?: SizeSmall | SizeMedium | SizeLarge;
88
+ onAmountChange?: (value: number | null) => void;
89
+ addon?: React.ReactNode;
90
+ searchPlaceholder?: string;
91
+ /**
92
+ * Allows the consumer to react to searching, while the search itself is handled internally.
93
+ */
94
+ onSearchChange?: (value: { searchQuery: string; filteredOptions: Currency[] }) => void; // TODO
95
+ customActionLabel?: React.ReactNode;
96
+ onCustomAction?: () => void;
97
+ classNames?: Record<string, string>;
98
+ selectProps?: Partial<SelectInputProps<CurrencyOption>>;
99
+ maxLengthOverride?: number;
100
+ }
101
+
102
+ interface MoneyInputState {
103
+ searchQuery: string;
104
+ formattedAmount: string;
105
+ locale: string;
106
+ }
107
+
108
+ class MoneyInput extends Component<MoneyInputProps, MoneyInputState> {
109
+ declare props: MoneyInputProps &
110
+ Required<Pick<MoneyInputProps, keyof typeof MoneyInput.defaultProps>>;
111
+
112
+ static defaultProps = {
113
+ size: Size.LARGE,
114
+ classNames: {},
115
+ selectProps: {},
116
+ } satisfies Partial<MoneyInputProps>;
117
+
118
+ amountFocused = false;
119
+
120
+ constructor(props: MoneyInputProps) {
66
121
  super(props);
67
- const { locale } = this.props.intl;
68
- this.formatMessage = this.props.intl.formatMessage;
69
122
  this.state = {
70
123
  searchQuery: '',
71
124
  formattedAmount: formatAmountIfSet(
72
125
  props.amount,
73
126
  props.selectedCurrency.currency,
74
- locale,
127
+ props.intl.locale,
75
128
  props.maxLengthOverride,
76
129
  ),
77
- locale,
130
+ locale: props.intl.locale,
78
131
  };
79
132
  }
80
133
 
81
- UNSAFE_componentWillReceiveProps(nextProps) {
82
- this.setState({ locale: nextProps?.intl?.locale });
134
+ UNSAFE_componentWillReceiveProps(nextProps: MoneyInputProps) {
135
+ this.setState({ locale: nextProps.intl.locale });
83
136
 
84
137
  if (!this.amountFocused) {
85
138
  this.setState({
86
139
  formattedAmount: formatAmountIfSet(
87
140
  nextProps.amount,
88
141
  nextProps.selectedCurrency.currency,
89
- nextProps?.intl?.locale,
142
+ nextProps.intl.locale,
90
143
  nextProps.maxLengthOverride,
91
144
  ),
92
145
  });
93
146
  }
94
147
  }
95
148
 
96
- isInputAllowedForKeyEvent = (event) => {
149
+ isInputAllowedForKeyEvent = (event: React.KeyboardEvent<HTMLInputElement>) => {
97
150
  const { keyCode, metaKey, key, ctrlKey } = event;
98
151
  const isNumberKey = isNumber(parseInt(key, 10));
99
152
 
@@ -106,14 +159,14 @@ class MoneyInput extends Component {
106
159
  );
107
160
  };
108
161
 
109
- handleKeyDown = (event) => {
162
+ handleKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
110
163
  if (!this.isInputAllowedForKeyEvent(event)) {
111
164
  event.preventDefault();
112
165
  }
113
166
  };
114
167
 
115
- handlePaste = (event) => {
116
- const paste = (event.clipboardData || window.clipboardData).getData('text');
168
+ handlePaste: React.ClipboardEventHandler<HTMLInputElement> = (event) => {
169
+ const paste = event.clipboardData.getData('text');
117
170
  const { locale } = this.state;
118
171
  const parsed = isEmpty(paste)
119
172
  ? null
@@ -133,13 +186,13 @@ class MoneyInput extends Component {
133
186
  this.props.maxLengthOverride,
134
187
  ),
135
188
  });
136
- this.props.onAmountChange(parsed);
189
+ this.props.onAmountChange?.(parsed);
137
190
  }
138
191
 
139
192
  event.preventDefault();
140
193
  };
141
194
 
142
- onAmountChange = (event) => {
195
+ onAmountChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
143
196
  const { value } = event.target;
144
197
  this.setState({
145
198
  formattedAmount: value,
@@ -153,7 +206,7 @@ class MoneyInput extends Component {
153
206
  this.props.maxLengthOverride,
154
207
  );
155
208
  if (isNumberOrNull(parsed)) {
156
- this.props.onAmountChange(parsed);
209
+ this.props.onAmountChange?.(parsed);
157
210
  }
158
211
  };
159
212
 
@@ -166,34 +219,26 @@ class MoneyInput extends Component {
166
219
  this.amountFocused = true;
167
220
  };
168
221
 
169
- mapOption = (item) => {
170
- return {
171
- type: 'option',
172
- value: item,
173
- filterMatchers: [item.value, item.label, item.note, item.searchable],
174
- };
175
- };
176
-
177
222
  getSelectOptions() {
178
- const selectOptions = [...filterOptionsForQuery(this.props.currencies, this.state.searchQuery)];
223
+ const selectOptions = filterCurrenciesForQuery(this.props.currencies, this.state.searchQuery);
179
224
 
180
- let formattedOptions = [];
181
- let groupIndex = null;
225
+ const formattedOptions: SelectInputItem<CurrencyOption>[] = [];
226
+ let currentGroupOptions: SelectInputOptionItem<CurrencyOption>[] | undefined;
182
227
 
183
228
  selectOptions.forEach((item) => {
184
- if (item.header) {
229
+ if (item.header != null) {
230
+ currentGroupOptions = [];
185
231
  formattedOptions.push({
186
232
  type: 'group',
187
233
  label: item.header,
188
- options: [],
234
+ options: currentGroupOptions,
189
235
  });
190
- groupIndex = formattedOptions.length - 1;
191
236
  } else {
192
- if (groupIndex === null) {
193
- formattedOptions.push(this.mapOption(item));
194
- } else {
195
- formattedOptions[groupIndex]?.options.push(this.mapOption(item));
196
- }
237
+ (currentGroupOptions ?? formattedOptions).push({
238
+ type: 'option',
239
+ value: item,
240
+ filterMatchers: [item.value, item.label, item.note ?? '', item.searchable ?? ''],
241
+ });
197
242
  }
198
243
  });
199
244
 
@@ -224,29 +269,25 @@ class MoneyInput extends Component {
224
269
  });
225
270
  }
226
271
 
227
- handleSelectChange = (value) => {
272
+ handleSelectChange = (value: CurrencyOption) => {
228
273
  this.handleSearchChange('');
229
- this.props.onCurrencyChange(value);
274
+ this.props.onCurrencyChange?.(value);
230
275
  };
231
276
 
232
277
  handleCustomAction = () => {
233
278
  this.handleSearchChange('');
234
- if (this.props.onCustomAction) {
235
- this.props.onCustomAction();
236
- }
279
+ this.props.onCustomAction?.();
237
280
  };
238
281
 
239
- handleSearchChange = (searchQuery) => {
282
+ handleSearchChange = (searchQuery: string) => {
240
283
  this.setState({ searchQuery });
241
- if (this.props.onSearchChange) {
242
- this.props.onSearchChange({
243
- searchQuery,
244
- filteredOptions: filterOptionsForQuery(this.props.currencies, searchQuery),
245
- });
246
- }
284
+ this.props.onSearchChange?.({
285
+ searchQuery,
286
+ filteredOptions: filterCurrenciesForQuery(this.props.currencies, searchQuery),
287
+ });
247
288
  };
248
289
 
249
- style = (className) => this.props.classNames[className] || className;
290
+ style = (className: string) => this.props.classNames[className] || className;
250
291
 
251
292
  render() {
252
293
  const { selectedCurrency, onCurrencyChange, size, addon, id, selectProps, maxLengthOverride } =
@@ -364,13 +405,13 @@ class MoneyInput extends Component {
364
405
  this.props.onCustomAction
365
406
  ? () => (
366
407
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events
367
- <div role="button" tabIndex="0" onClick={this.handleCustomAction}>
408
+ <div role="button" tabIndex={0} onClick={this.handleCustomAction}>
368
409
  {this.props.customActionLabel}
369
410
  </div>
370
411
  )
371
- : null
412
+ : undefined
372
413
  }
373
- placeholder={this.formatMessage(messages.selectPlaceholder)}
414
+ placeholder={this.props.intl.formatMessage(messages.selectPlaceholder)}
374
415
  filterable
375
416
  filterPlaceholder={this.props.searchPlaceholder}
376
417
  disabled={disabled}
@@ -388,33 +429,31 @@ class MoneyInput extends Component {
388
429
  }
389
430
  }
390
431
 
391
- function filterOptionsForQuery(options, query) {
432
+ function filterCurrenciesForQuery(currencies: readonly Currency[], query: string): Currency[] {
392
433
  if (!query) {
393
- return options;
434
+ return [...currencies];
394
435
  }
395
436
 
437
+ const options = currencies.filter((option): option is CurrencyOption => option.header == null);
396
438
  const filteredOptions = removeDuplicateValueOptions(options).filter((option) =>
397
- isCurrencyOptionAndFitsQuery(option, query),
439
+ currencyOptionFitsQuery(option, query),
398
440
  );
399
441
 
400
442
  return sortOptionsLabelsToFirst(filteredOptions, query);
401
443
  }
402
444
 
403
- function removeDuplicateValueOptions(options) {
404
- const result = [];
405
- const resultValues = [];
406
-
407
- options.forEach((option) => {
408
- if (option.value && !resultValues.includes(option.value)) {
409
- result.push(option);
410
- resultValues.push(option.value);
445
+ function removeDuplicateValueOptions(options: CurrencyOption[]) {
446
+ const uniqueValues = new Set<string>();
447
+ return options.filter((option) => {
448
+ if (!uniqueValues.has(option.value)) {
449
+ uniqueValues.add(option.value);
450
+ return true;
411
451
  }
452
+ return false;
412
453
  });
413
-
414
- return result;
415
454
  }
416
455
 
417
- function isCurrencyOptionAndFitsQuery(option, query) {
456
+ function currencyOptionFitsQuery(option: CurrencyOption, query: string) {
418
457
  if (!option.value) {
419
458
  return false;
420
459
  }
@@ -426,11 +465,11 @@ function isCurrencyOptionAndFitsQuery(option, query) {
426
465
  );
427
466
  }
428
467
 
429
- function contains(property, query) {
468
+ function contains(property: string | undefined, query: string) {
430
469
  return property && property.toLowerCase().includes(query.toLowerCase());
431
470
  }
432
471
 
433
- function sortOptionsLabelsToFirst(options, query) {
472
+ function sortOptionsLabelsToFirst(options: CurrencyOption[], query: string) {
434
473
  return options.sort((first, second) => {
435
474
  const firstContains = contains(first.label, query);
436
475
  const secondContains = contains(second.label, query);
@@ -448,47 +487,4 @@ function sortOptionsLabelsToFirst(options, query) {
448
487
  });
449
488
  }
450
489
 
451
- MoneyInput.propTypes = {
452
- id: PropTypes.string,
453
- currencies: PropTypes.arrayOf(Currency).isRequired,
454
- selectedCurrency: Currency.isRequired,
455
- onCurrencyChange: PropTypes.func,
456
- placeholder: PropTypes.number,
457
- amount: PropTypes.number,
458
- size: PropTypes.oneOf(['sm', 'md', 'lg']),
459
- onAmountChange: PropTypes.func,
460
- addon: PropTypes.node,
461
- searchPlaceholder: PropTypes.string,
462
- /**
463
- * Allows the consumer to react to searching, while the search itself is handled internally. Called with `{ searchQuery: string, filteredOptions: Currency[] }`
464
- */
465
- onSearchChange: PropTypes.func,
466
- customActionLabel: PropTypes.node,
467
- onCustomAction: PropTypes.func,
468
- classNames: PropTypes.objectOf(PropTypes.string),
469
- selectProps: PropTypes.object,
470
- maxLengthOverride: PropTypes.number,
471
- };
472
-
473
- MoneyInput.defaultProps = {
474
- id: null,
475
- size: Size.LARGE,
476
- addon: null,
477
- searchPlaceholder: '',
478
- onSearchChange: undefined,
479
- onCurrencyChange: null,
480
- placeholder: null,
481
- amount: null,
482
- onAmountChange: null,
483
- customActionLabel: '',
484
- onCustomAction: null,
485
- classNames: {},
486
- selectProps: {},
487
- maxLengthOverride: null,
488
- };
489
-
490
- // this export is necessary for react-to-typescript-definitions
491
- // to be able to properly generate TS types, this is due to us wrapping this component in `injectIntl` before exporting
492
- export { MoneyInput };
493
-
494
490
  export default injectIntl(MoneyInput);
@@ -1,12 +1,12 @@
1
1
  import { formatAmount, parseAmount } from './currencyFormatting';
2
2
 
3
3
  jest.mock('@transferwise/formatting', () => ({
4
- formatAmount: (number) => `formatted ${number}`,
4
+ formatAmount: (number: number) => `formatted ${number}`,
5
5
  }));
6
6
 
7
7
  describe('Number formatting', () => {
8
8
  it('uses @transferwise/formatting for formatting numbers', () => {
9
- expect(formatAmount(100)).toBe('formatted 100');
9
+ expect(formatAmount(100, 'gbp')).toBe('formatted 100');
10
10
  });
11
11
 
12
12
  it('parses localized numbers', () => {
@@ -5,7 +5,7 @@ import { DEFAULT_LOCALE } from '../common/locale';
5
5
  export { formatAmount };
6
6
 
7
7
  // TODO: do not duplicate this between formatting and components
8
- const currencyDecimals = {
8
+ const currencyDecimals: Record<string, number> = {
9
9
  BIF: 0,
10
10
  BYR: 0,
11
11
  CLP: 0,
@@ -41,30 +41,27 @@ function isNumberLocaleSupported() {
41
41
  return numberString === '1,234';
42
42
  }
43
43
 
44
- function getValidLocale(locale) {
44
+ function getValidLocale(locale: string) {
45
45
  try {
46
46
  const noUnderscoreLocale = locale.replace(/_/, '-');
47
47
 
48
48
  Intl.NumberFormat(noUnderscoreLocale);
49
49
  return noUnderscoreLocale;
50
50
  } catch {
51
- return 'en-GB';
51
+ return DEFAULT_LOCALE;
52
52
  }
53
53
  }
54
54
 
55
- function getCurrencyDecimals(currency = '') {
55
+ function getCurrencyDecimals(currency: string) {
56
56
  const upperCaseCurrency = currency.toUpperCase();
57
- if (Object.prototype.hasOwnProperty.call(currencyDecimals, upperCaseCurrency)) {
58
- return currencyDecimals[upperCaseCurrency];
59
- }
60
- return DEFAULT_CURRENCY_DECIMALS;
57
+ return currencyDecimals[upperCaseCurrency] ?? DEFAULT_CURRENCY_DECIMALS;
61
58
  }
62
59
 
63
- function getDecimalSeparator(locale) {
60
+ function getDecimalSeparator(locale: string) {
64
61
  return isNumberLocaleSupported() ? (1.1).toLocaleString(locale)[1] : '.';
65
62
  }
66
63
 
67
- export function parseAmount(number, currency, locale) {
64
+ export function parseAmount(number: string, currency: string, locale = DEFAULT_LOCALE) {
68
65
  const validLocale = getValidLocale(locale);
69
66
 
70
67
  const precision = getCurrencyDecimals(currency);
@@ -0,0 +1,2 @@
1
+ export type { CurrencyOption, MoneyInputProps } from './MoneyInput';
2
+ export { default } from './MoneyInput';
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`Popover on desktop renders when is open 1`] = `
4
4
  <div
5
- class="np-panel np-panel--open np-theme-light np-popover__container"
5
+ class="np-panel np-panel--open np-popover__container"
6
6
  data-popper-escaped="true"
7
7
  data-popper-placement="right"
8
8
  data-popper-reference-hidden="true"
@@ -1,107 +0,0 @@
1
- .segmented-control {
2
- box-sizing: border-box;
3
- --segment-highlight-width: 0;
4
- --segment-highlight-x: var(--size-4);
5
- }
6
- .segmented-control__segments {
7
- display: inline-flex;
8
- position: relative;
9
- justify-content: center;
10
- align-items: center;
11
- background: rgba(134,167,189,0.10196);
12
- background: var(--color-background-neutral);
13
- padding: 4px;
14
- padding: var(--size-4);
15
- border-radius: 24px;
16
- border-radius: var(--size-24);
17
- width: 100%;
18
- transition: outline 300ms;
19
- outline: 2px solid transparent;
20
- }
21
- .segmented-control--input:has(:focus-visible) > .segmented-control__segments::after {
22
- outline: 2px solid var(--color-interactive-primary);
23
- }
24
- .segmented-control__segments::after {
25
- content: "";
26
- background: #ffffff;
27
- background: var(--color-background-screen);
28
- width: var(--segment-highlight-width);
29
- position: absolute;
30
- top: 4px;
31
- top: var(--size-4);
32
- bottom: 4px;
33
- bottom: var(--size-4);
34
- left: var(--segment-highlight-x);
35
- z-index: 0;
36
- border-radius: 24px;
37
- border-radius: var(--size-24);
38
- transition: left 300ms;
39
- }
40
- .segmented-control__segments--no-animate::after {
41
- transition: none !important;
42
- }
43
- .segmented-control__segment {
44
- position: relative;
45
- flex: 1 1 100%;
46
- align-items: center;
47
- text-align: center;
48
- vertical-align: middle;
49
- min-height: 40px;
50
- min-height: var(--size-40);
51
- line-height: 40px;
52
- line-height: var(--size-40);
53
- margin: 0;
54
- border-radius: 24px;
55
- border-radius: var(--size-24);
56
- z-index: 1;
57
- cursor: pointer;
58
- transition: font-weight 300ms, background 300ms;
59
- }
60
- .segmented-control__segment:hover {
61
- background: rgba(0,0,0,0.10196);
62
- background: var(--color-background-overlay);
63
- }
64
- .segmented-control__radio-input {
65
- position: fixed;
66
- opacity: 0;
67
- pointer-events: none;
68
- }
69
- .segmented-control__button {
70
- background: none;
71
- -webkit-appearance: none;
72
- -moz-appearance: none;
73
- appearance: none;
74
- border: none;
75
- outline: none;
76
- width: 100%;
77
- height: 100%;
78
- font: inherit;
79
- padding: none;
80
- outline: 2px solid transparent;
81
- }
82
- .segmented-control__button:focus {
83
- outline-offset: 0px;
84
- }
85
- .segmented-control__button:focus-visible {
86
- outline-color: var(--color-interactive-primary);
87
- }
88
- .segmented-control__selected-segment:hover {
89
- background: transparent;
90
- }
91
- .segmented-control__selected-segment {
92
- font-weight: 800;
93
- font-weight: var(--font-weight-bold);
94
- }
95
- .segmented-control__label-text {
96
- white-space: nowrap;
97
- color: var(--color-interactive-primary);
98
- }
99
- .segmented-control__segments--nav {
100
- list-style: none;
101
- }
102
- .segmented-control__segments--nav li,
103
- .segmented-control__segments--nav ui {
104
- flex-grow: 1;
105
- margin: 0;
106
- padding: 0;
107
- }
@@ -1,31 +0,0 @@
1
- /// <reference types="react" />
2
- type SegmentBase = {
3
- id: string;
4
- label: string;
5
- value: string;
6
- };
7
- type Segment = SegmentBase & {
8
- controls?: never;
9
- };
10
- type SegmentWithControls = SegmentBase & {
11
- controls: string;
12
- };
13
- export type Segments = Segment[] | SegmentWithControls[];
14
- type SegmentedControlPropsBase = {
15
- name: string;
16
- defaultValue: string;
17
- type: 'input' | 'navigation';
18
- onChange: (value: string) => void;
19
- };
20
- type SegmentedControlNavigationProps = {
21
- type: 'navigation';
22
- segments: SegmentWithControls[];
23
- };
24
- type SegmentedControlInputProps = {
25
- type: 'input';
26
- segments: Segment[];
27
- };
28
- export type SegmentedControlProps = SegmentedControlPropsBase & (SegmentedControlNavigationProps | SegmentedControlInputProps);
29
- export declare const SegmentedControl: ({ name, defaultValue, type, segments, onChange, }: SegmentedControlProps) => import("react").JSX.Element;
30
- export {};
31
- //# sourceMappingURL=SegmentedControl.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../../src/segmentedControl/SegmentedControl.tsx"],"names":[],"mappings":";AAGA,KAAK,WAAW,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,KAAK,OAAO,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAClD,KAAK,mBAAmB,GAAG,WAAW,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,QAAQ,GAAG,OAAO,EAAE,GAAG,mBAAmB,EAAE,CAAC;AAEzD,KAAK,yBAAyB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,KAAK,+BAA+B,GAAG;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,yBAAyB,GAC3D,CAAC,+BAA+B,GAAG,0BAA0B,CAAC,CAAC;AAEjE,eAAO,MAAM,gBAAgB,sDAM1B,qBAAqB,gCA6GvB,CAAC"}
@@ -1 +0,0 @@
1
- export { default } from './MoneyInput';