@synerise/ds-factors 1.2.2 → 1.3.1

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 (35) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +29 -37
  3. package/dist/FactorValue/Array/Array.const.d.ts +1 -0
  4. package/dist/FactorValue/Array/Array.const.js +1 -0
  5. package/dist/FactorValue/Array/Array.d.ts +3 -0
  6. package/dist/FactorValue/Array/Array.js +72 -0
  7. package/dist/FactorValue/Array/Array.styles.d.ts +32 -0
  8. package/dist/FactorValue/Array/Array.styles.js +82 -0
  9. package/dist/FactorValue/Array/Array.types.d.ts +39 -0
  10. package/dist/FactorValue/Array/Array.types.js +1 -0
  11. package/dist/FactorValue/Array/Array.utils.d.ts +6 -0
  12. package/dist/FactorValue/Array/Array.utils.js +25 -0
  13. package/dist/FactorValue/Array/components/ArrayCollector.d.ts +3 -0
  14. package/dist/FactorValue/Array/components/ArrayCollector.js +112 -0
  15. package/dist/FactorValue/Array/components/ArrayCreator.d.ts +3 -0
  16. package/dist/FactorValue/Array/components/ArrayCreator.js +81 -0
  17. package/dist/FactorValue/Array/components/ArrayLimit.d.ts +3 -0
  18. package/dist/FactorValue/Array/components/ArrayLimit.js +14 -0
  19. package/dist/FactorValue/Array/components/ArrayModal.d.ts +3 -0
  20. package/dist/FactorValue/Array/components/ArrayModal.js +161 -0
  21. package/dist/FactorValue/Array/components/ArrayRaw.d.ts +3 -0
  22. package/dist/FactorValue/Array/components/ArrayRaw.js +69 -0
  23. package/dist/FactorValue/Array/components/CopyButton.d.ts +3 -0
  24. package/dist/FactorValue/Array/components/CopyButton.js +42 -0
  25. package/dist/FactorValue/Array/hooks/useCollector.d.ts +17 -0
  26. package/dist/FactorValue/Array/hooks/useCollector.js +40 -0
  27. package/dist/FactorValue/FactorValue.d.ts +1 -1
  28. package/dist/FactorValue/FactorValue.js +4 -2
  29. package/dist/FactorValue/Parameter/utils.d.ts +1 -1
  30. package/dist/Factors.d.ts +1 -1
  31. package/dist/Factors.js +4 -1
  32. package/dist/Factors.types.d.ts +37 -4
  33. package/dist/hooks/useTexts.d.ts +1 -1
  34. package/dist/hooks/useTexts.js +86 -0
  35. package/package.json +32 -23
package/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.3.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-factors@1.3.0...@synerise/ds-factors@1.3.1) (2025-06-26)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-factors
9
+
10
+
11
+
12
+
13
+
14
+ # [1.3.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-factors@1.2.2...@synerise/ds-factors@1.3.0) (2025-06-24)
15
+
16
+
17
+ ### Features
18
+
19
+ * **factors:** array factor type ([195d328](https://github.com/Synerise/synerise-design/commit/195d3286e98b5f07fc9c1e56001e6ae844b7a080))
20
+
21
+
22
+
23
+
24
+
6
25
  ## [1.2.2](https://github.com/Synerise/synerise-design/compare/@synerise/ds-factors@1.2.1...@synerise/ds-factors@1.2.2) (2025-06-12)
7
26
 
8
27
  **Note:** Version bump only for package @synerise/ds-factors
package/README.md CHANGED
@@ -6,6 +6,7 @@ title: Factors
6
6
  Factors UI Component
7
7
 
8
8
  ## Installation
9
+
9
10
  ```
10
11
  npm i @synerise/ds-factors
11
12
  or
@@ -13,6 +14,7 @@ yarn add @synerise/ds-factors
13
14
  ```
14
15
 
15
16
  ## Usage
17
+
16
18
  ```
17
19
  import Factors from '@synerise/ds-factors'
18
20
 
@@ -98,62 +100,52 @@ import Factors from '@synerise/ds-factors'
98
100
 
99
101
  ## API
100
102
 
101
- | Property | Description | Type | Default |
102
- | --- | --- | --- | --- |
103
- | autocompleteText | Array of available autocomplete suggestions (only if textType is equal to `autocomplete`) | {options: string[]} | - |
104
- | availableFactorTypes | Array of available factor types | FactorType[] | - |
105
- | defaultFactorType | Default factor type | FactorType | - |
106
- | formulaEditor | Formula editor render in modal when factory type is equal to `formula` | React.ReactNode | - |
107
- | getPopupContainerOverride | Popup container function for child tooltips and dropdowns | (trigger: HTMLElement \ null) => HTMLElement; | - |
108
- | onActivate | Callback called when user opens dropdown | (fieldType: string) => void | - |
109
- | onChangeValue | Callback called when user change value | (value: FactorValueType) => void | - |
110
- | onDeactivate | Callback called when user closes dropdown | () => void | - |
111
- | opened | Whether if dropdown should opens from outside of component | boolean | false |
112
- | parameters | Options for parameters list | ParameterOptions | - |
113
- | selectedFactorType | Selected factor type | FactorType | - |
114
- | setSelectedFactorType | Callback called when user selects factor type | (factor: FactorType) => void | - |
115
- | texts | Translations object | FactorsTexts | - |
116
- | textType | Variant of text type input (`autocomplete` \ `expansible` \ `default` ) | string | `default` |
117
- | unavailableFactorTypes | Array of excluded factor types | FactorType[] | - |
118
- | value | Value | FactorValueType | - |
119
- | withoutTypeSelector | Whether if hide factor type selector | boolean | - |
120
- | inputProps | Array of available props of input | InputProps | - |
103
+ | Property | Description | Type | Default |
104
+ | ------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------- | --------- |
105
+ | autocompleteText | Array of available autocomplete suggestions (only if textType is equal to `autocomplete`) | {options: string[]} | - |
106
+ | availableFactorTypes | Array of available factor types | FactorType[] | - |
107
+ | defaultFactorType | Default factor type | FactorType | - |
108
+ | formulaEditor | Formula editor render in modal when factory type is equal to `formula` | React.ReactNode | - |
109
+ | getPopupContainerOverride | Popup container function for child tooltips and dropdowns | (trigger: HTMLElement \ null) => HTMLElement; | - |
110
+ | onActivate | Callback called when user opens dropdown | (fieldType: string) => void | - |
111
+ | onChangeValue | Callback called when user change value | (value: FactorValueType) => void | - |
112
+ | onDeactivate | Callback called when user closes dropdown | () => void | - |
113
+ | opened | Whether if dropdown should opens from outside of component | boolean | false |
114
+ | parameters | Options for parameters list | ParameterOptions | - |
115
+ | selectedFactorType | Selected factor type | FactorType | - |
116
+ | setSelectedFactorType | Callback called when user selects factor type | (factor: FactorType) => void | - |
117
+ | texts | Translations object | FactorsTexts | - |
118
+ | textType | Variant of text type input (`autocomplete` \ `expansible` \ `default` ) | string | `default` |
119
+ | unavailableFactorTypes | Array of excluded factor types | FactorType[] | - |
120
+ | value | Value | FactorValueType | - |
121
+ | withoutTypeSelector | Whether if hide factor type selector | boolean | - |
122
+ | inputProps | text input additional props (for text factor type) | InputProps | - |
123
+ | arrayProps | options for array factor type | { itemType?: 'string' / 'number', limit?: number } | - |
121
124
 
122
125
  ### FactorType
123
126
 
124
- All available factor types: `text`, `number`, `parameter`, `contextParameter`, `dynamicKey`, `formula`, `array`, `date`,
127
+ All available factor types: `text`, `number`, `parameter`, `contextParameter`, `dynamicKey`, `formula`, `array`, `date`, `relativeDate`,
125
128
 
126
129
  ### FactorValueType
127
130
 
128
- Type of value depends on current factor type and can contain values: `string` \ `number` \ `Date` \ `undefined` \ `DynamicKeyValueType` \ `FormulaValueType` \ `ParameterValueType`;
131
+ Type of value depends on current factor type and can contain values: `string` \ `number` \ `Array<string | numer>` \ `Date` \ `undefined` \ `DynamicKeyValueType` \ `FormulaValueType` \ `ParameterValueType`;
129
132
 
130
133
  ### DynamicKeyValueType
131
134
 
132
- `{
133
- key: React.ReactText;
134
- value: React.ReactText
135
- }`
135
+ `{ key: React.ReactText; value: React.ReactText }`
136
136
 
137
137
  ### FormulaValueType
138
138
 
139
- `{
140
- name: string;
141
- value: string
142
- }`
139
+ `{ name: string; value: string }`
143
140
 
144
141
  ### ParameterValueType
145
142
 
146
- `{
147
- type: string;
148
- icon: string;
149
- name: string;
150
- id: React.ReactText;
151
- }`
143
+ `{ type: string; icon: string; name: string; id: React.ReactText; }`
152
144
 
153
145
  ### ParameterOptions
154
146
 
155
147
  | Property | Description | Type | Default |
156
- |-------------------------|------------------------------------------------------------|--------------------------|---------|
148
+ | ----------------------- | ---------------------------------------------------------- | ------------------------ | ------- |
157
149
  | buttonIcon | Icon in button | React.ReactNode | - |
158
150
  | buttonLabel | Label of button | string \ React.ReactNode | - |
159
151
  | groups | Array of parameter groups | ParameterGroup[] | - |
@@ -0,0 +1 @@
1
+ export declare const MODAL_VIEWPORT_HEIGHT = 80;
@@ -0,0 +1 @@
1
+ export var MODAL_VIEWPORT_HEIGHT = 80;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ArrayItemType, FactorValueComponentProps } from '../../Factors.types';
3
+ export declare const Array: <ItemType extends ArrayItemType>({ value: arrayValue, onChange, texts, opened, onActivate, onDeactivate, readOnly, error, arrayProps, }: FactorValueComponentProps) => React.JSX.Element;
@@ -0,0 +1,72 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React, { useMemo, useState } from 'react';
3
+ import Icon, { EditS } from '@synerise/ds-icon';
4
+ import { useTheme } from '@synerise/ds-core';
5
+ import { TagShape } from '@synerise/ds-tag';
6
+ import { ArrayModal } from './components/ArrayModal';
7
+ import * as S from './Array.styles';
8
+ export var Array = function Array(_ref) {
9
+ var arrayValue = _ref.value,
10
+ onChange = _ref.onChange,
11
+ texts = _ref.texts,
12
+ opened = _ref.opened,
13
+ onActivate = _ref.onActivate,
14
+ onDeactivate = _ref.onDeactivate,
15
+ _ref$readOnly = _ref.readOnly,
16
+ readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly,
17
+ error = _ref.error,
18
+ _ref$arrayProps = _ref.arrayProps,
19
+ arrayProps = _ref$arrayProps === void 0 ? {} : _ref$arrayProps;
20
+ var _useState = useState(opened),
21
+ isVisible = _useState[0],
22
+ setIsVisible = _useState[1];
23
+ var handleOnClick = function handleOnClick() {
24
+ setIsVisible(true);
25
+ onActivate && onActivate();
26
+ };
27
+ var buttonLabel = useMemo(function () {
28
+ if (!(arrayValue != null && arrayValue.length)) return texts.array.triggerLabel;
29
+ return arrayValue.join(', ') + " ";
30
+ }, [arrayValue, texts.array.triggerLabel]);
31
+ var triggerMode = useMemo(function () {
32
+ return readOnly ? '' : 'label-icon';
33
+ }, [readOnly]);
34
+ var handleApply = function handleApply(changedValue) {
35
+ setIsVisible(false);
36
+ onChange(changedValue);
37
+ };
38
+ var handleCancel = function handleCancel() {
39
+ setIsVisible(false);
40
+ onDeactivate && onDeactivate();
41
+ };
42
+ var theme = useTheme();
43
+ var tagProps = {
44
+ asPill: true,
45
+ name: "" + arrayValue.length,
46
+ color: error ? theme.palette['red-600'] : theme.palette['grey-600'],
47
+ textColor: '#fff',
48
+ shape: TagShape.DEFAULT_ROUND
49
+ };
50
+ var tooltipProps = arrayValue != null && arrayValue.length ? {
51
+ title: /*#__PURE__*/React.createElement(React.Fragment, null, arrayValue.join(', '))
52
+ } : undefined;
53
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(S.TriggerButton, {
54
+ error: error,
55
+ type: "secondary",
56
+ mode: triggerMode,
57
+ onClick: handleOnClick,
58
+ tooltipProps: tooltipProps,
59
+ "data-testid": "ds-factors-array",
60
+ tagProps: arrayValue.length ? tagProps : undefined
61
+ }, /*#__PURE__*/React.createElement(S.TriggerButtonLabel, null, buttonLabel), !readOnly && /*#__PURE__*/React.createElement(Icon, {
62
+ component: /*#__PURE__*/React.createElement(EditS, null)
63
+ })), /*#__PURE__*/React.createElement(ArrayModal, _extends({
64
+ value: arrayValue,
65
+ onApply: handleApply,
66
+ onCancel: handleCancel,
67
+ texts: texts,
68
+ visible: isVisible,
69
+ readOnly: readOnly,
70
+ itemType: "string"
71
+ }, arrayProps)));
72
+ };
@@ -0,0 +1,32 @@
1
+ /// <reference types="react" />
2
+ import Button from '@synerise/ds-button';
3
+ export declare const TextArea: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/lib/input").TextAreaProps & {
4
+ error?: boolean | undefined;
5
+ } & import("react").RefAttributes<import("antd/lib/input/TextArea").TextAreaRef>>, any, {
6
+ error?: boolean | undefined;
7
+ }, never>;
8
+ export declare const Modal: import("styled-components").StyledComponent<{
9
+ (props: import("@synerise/ds-modal").ModalProps): import("react").JSX.Element;
10
+ info: import("antd/lib/modal/confirm").ModalFunc;
11
+ success: import("antd/lib/modal/confirm").ModalFunc;
12
+ error: import("antd/lib/modal/confirm").ModalFunc;
13
+ warning: import("antd/lib/modal/confirm").ModalFunc;
14
+ confirm: import("antd/lib/modal/confirm").ModalFunc;
15
+ }, any, {
16
+ viewportHeight: number;
17
+ }, never>;
18
+ export declare const EmptyState: import("styled-components").StyledComponent<({ size, label, text, button, fontSize, customIcon, className, mode, iconPosition, textAlign, }: import("@synerise/ds-empty-states").EmptyStatesProps) => import("react").JSX.Element, any, {}, never>;
19
+ export declare const TriggerButtonLabel: import("styled-components").StyledComponent<"div", any, {}, never>;
20
+ export declare const TriggerButton: import("styled-components").StyledComponent<typeof Button, any, {}, never>;
21
+ export declare const ModalFooterLeftSide: import("styled-components").StyledComponent<"div", any, {}, never>;
22
+ export declare const ModalSubHeader: import("styled-components").StyledComponent<"div", any, {}, never>;
23
+ export declare const ModalContentWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
24
+ export declare const Limit: import("styled-components").StyledComponent<"div", any, {}, never>;
25
+ export declare const LimitPart: import("styled-components").StyledComponent<"div", any, {}, never>;
26
+ export declare const SearchWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
27
+ export declare const RightSide: import("styled-components").StyledComponent<"div", any, {}, never>;
28
+ export declare const LeftSide: import("styled-components").StyledComponent<"div", any, {}, never>;
29
+ export declare const CreatorItemsList: import("styled-components").StyledComponent<"div", any, {}, never>;
30
+ export declare const DeleteIcon: import("styled-components").StyledComponent<({ name, component, className, ...rest }: import("@synerise/ds-icon").IconProps) => import("react").JSX.Element, any, {}, never>;
31
+ export declare const CollectorWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
32
+ export declare const CreatorRow: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,82 @@
1
+ import styled from 'styled-components';
2
+ import EmptyStateBase from '@synerise/ds-empty-states';
3
+ import Icon from '@synerise/ds-icon';
4
+ import Button from '@synerise/ds-button';
5
+ import ModalBase from '@synerise/ds-modal';
6
+ import { RawTextArea } from '@synerise/ds-input';
7
+ export var TextArea = styled(RawTextArea).withConfig({
8
+ displayName: "Arraystyles__TextArea",
9
+ componentId: "sc-9atgo7-0"
10
+ })([""]);
11
+ export var Modal = styled(ModalBase).withConfig({
12
+ displayName: "Arraystyles__Modal",
13
+ componentId: "sc-9atgo7-1"
14
+ })(["&&{top:50px;.ant-modal-content{height:", "vh;}}", "{height:calc(", "vh - 211px);min-height:auto;resize:none;font-family:'IBM Plex Mono Regular',monospace;&,&:focus{border:0;background:transparent;box-shadow:none;}}"], function (props) {
15
+ return props.viewportHeight;
16
+ }, TextArea, function (props) {
17
+ return props.viewportHeight;
18
+ });
19
+ export var EmptyState = styled(EmptyStateBase).withConfig({
20
+ displayName: "Arraystyles__EmptyState",
21
+ componentId: "sc-9atgo7-2"
22
+ })(["margin:90px auto 120px;"]);
23
+ export var TriggerButtonLabel = styled.div.withConfig({
24
+ displayName: "Arraystyles__TriggerButtonLabel",
25
+ componentId: "sc-9atgo7-3"
26
+ })(["min-width:0;text-overflow:ellipsis;overflow:hidden;"]);
27
+ export var TriggerButton = styled(Button).withConfig({
28
+ displayName: "Arraystyles__TriggerButton",
29
+ componentId: "sc-9atgo7-4"
30
+ })(["max-width:100%;"]);
31
+ export var ModalFooterLeftSide = styled.div.withConfig({
32
+ displayName: "Arraystyles__ModalFooterLeftSide",
33
+ componentId: "sc-9atgo7-5"
34
+ })(["flex:1 1 100%;text-align:left;"]);
35
+ export var ModalSubHeader = styled.div.withConfig({
36
+ displayName: "Arraystyles__ModalSubHeader",
37
+ componentId: "sc-9atgo7-6"
38
+ })(["padding:12px 24px;display:flex;justify-content:space-between;"]);
39
+ export var ModalContentWrapper = styled.div.withConfig({
40
+ displayName: "Arraystyles__ModalContentWrapper",
41
+ componentId: "sc-9atgo7-7"
42
+ })(["padding:24px;"]);
43
+ export var Limit = styled.div.withConfig({
44
+ displayName: "Arraystyles__Limit",
45
+ componentId: "sc-9atgo7-8"
46
+ })(["display:flex;gap:4px;align-items:center;"]);
47
+ export var LimitPart = styled.div.withConfig({
48
+ displayName: "Arraystyles__LimitPart",
49
+ componentId: "sc-9atgo7-9"
50
+ })([""]);
51
+ export var SearchWrapper = styled.div.withConfig({
52
+ displayName: "Arraystyles__SearchWrapper",
53
+ componentId: "sc-9atgo7-10"
54
+ })(["max-width:200px;min-width:32px;"]);
55
+ export var RightSide = styled.div.withConfig({
56
+ displayName: "Arraystyles__RightSide",
57
+ componentId: "sc-9atgo7-11"
58
+ })(["flex:1 1 auto;display:flex;justify-content:flex-end;align-items:center;gap:12px;"]);
59
+ export var LeftSide = styled.div.withConfig({
60
+ displayName: "Arraystyles__LeftSide",
61
+ componentId: "sc-9atgo7-12"
62
+ })(["flex:0 0 auto;text-align:left;"]);
63
+ export var CreatorItemsList = styled.div.withConfig({
64
+ displayName: "Arraystyles__CreatorItemsList",
65
+ componentId: "sc-9atgo7-13"
66
+ })(["display:flex;flex-direction:column;gap:12px;"]);
67
+ export var DeleteIcon = styled(Icon).withConfig({
68
+ displayName: "Arraystyles__DeleteIcon",
69
+ componentId: "sc-9atgo7-14"
70
+ })(["position:absolute;right:0;top:50%;transform:translateY(-50%);display:none;color:", ";&:hover{color:", ";}"], function (props) {
71
+ return props.theme.palette['red-600'];
72
+ }, function (props) {
73
+ return props.theme.palette['red-500'];
74
+ });
75
+ export var CollectorWrapper = styled.div.withConfig({
76
+ displayName: "Arraystyles__CollectorWrapper",
77
+ componentId: "sc-9atgo7-15"
78
+ })(["padding:0 34px;margin-bottom:24px;"]);
79
+ export var CreatorRow = styled.div.withConfig({
80
+ displayName: "Arraystyles__CreatorRow",
81
+ componentId: "sc-9atgo7-16"
82
+ })(["padding:0 34px;position:relative;&:hover{", "{display:block;}}"], DeleteIcon);
@@ -0,0 +1,39 @@
1
+ import { ReactNode } from 'react';
2
+ import type { RequiredProps } from '@synerise/ds-utils';
3
+ import type { ArrayProps, FactorsTexts } from '../../Factors.types';
4
+ export type ArrayModalProps<ItemType extends 'string' | 'number'> = RequiredProps<ArrayProps, 'itemType'> & {
5
+ visible?: boolean;
6
+ readOnly?: boolean;
7
+ onApply: (updatedValue: ArrayValueElement<ItemType>[]) => void;
8
+ onCancel: () => void;
9
+ texts: FactorsTexts;
10
+ value?: ArrayValueElement<ItemType>[];
11
+ };
12
+ export type ArrayValueElement<ItemType extends 'string' | 'number'> = ItemType extends 'number' ? number : string;
13
+ export type ArrayValueWithID<ItemType extends 'string' | 'number'> = {
14
+ value: ArrayValueElement<ItemType>;
15
+ id: string;
16
+ };
17
+ export type ArrayCreatorProps<ItemType extends 'string' | 'number'> = Pick<ArrayModalProps<ItemType>, 'itemType' | 'texts' | 'readOnly' | 'limit' | 'collectorSuggestions'> & {
18
+ value: ArrayValueWithID<ItemType>[];
19
+ onValueChange: (updatedValue: ArrayValueWithID<ItemType>[]) => void;
20
+ searchQuery?: string;
21
+ };
22
+ export type ArrayCollectorProps<ItemType extends 'string' | 'number'> = Pick<ArrayModalProps<ItemType>, 'itemType' | 'texts' | 'limit' | 'collectorSuggestions'> & {
23
+ arrayValueCount: number;
24
+ onConfirm: (newItems: ArrayValueWithID<ItemType>[]) => void;
25
+ };
26
+ export type ArrayRawProps<ItemType extends 'string' | 'number'> = Pick<ArrayModalProps<ItemType>, 'itemType' | 'texts' | 'readOnly' | 'limit'> & {
27
+ value: ArrayValueWithID<ItemType>[];
28
+ onValueChange: (updatedValue: ArrayValueWithID<ItemType>[]) => void;
29
+ onError: (errorMessage: ReactNode) => void;
30
+ };
31
+ export type ArrayLimitProps = {
32
+ limit: number;
33
+ count?: number;
34
+ texts: FactorsTexts;
35
+ };
36
+ export type CopyButtonProps = {
37
+ copyValue: string;
38
+ texts: FactorsTexts;
39
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { ArrayValueElement, ArrayValueWithID } from './Array.types';
2
+ export declare const matchesSearchQuery: (item: string | number, searchQuery: string) => boolean;
3
+ export declare const arrayWithUUID: <ItemType extends "string" | "number">(items: ArrayValueElement<ItemType>[]) => ArrayValueWithID<ItemType>[];
4
+ export declare const sanitiseValues: (element: string) => string;
5
+ export declare const isNumberAsString: (value: string) => boolean;
6
+ export declare const isArrayOfNumbersAsString: (array: string[]) => boolean;
@@ -0,0 +1,25 @@
1
+ import { v4 as uuid } from 'uuid';
2
+ export var matchesSearchQuery = function matchesSearchQuery(item, searchQuery) {
3
+ return String(item).toLocaleLowerCase().includes(searchQuery.toLocaleLowerCase());
4
+ };
5
+ export var arrayWithUUID = function arrayWithUUID(items) {
6
+ return items.map(function (item) {
7
+ return {
8
+ value: item,
9
+ id: uuid()
10
+ };
11
+ });
12
+ };
13
+ export var sanitiseValues = function sanitiseValues(element) {
14
+ return element.trim();
15
+ };
16
+ export var isNumberAsString = function isNumberAsString(value) {
17
+ return sanitiseValues(value) === "" + parseFloat(sanitiseValues(value));
18
+ };
19
+ export var isArrayOfNumbersAsString = function isArrayOfNumbersAsString(array) {
20
+ var sanitisedArray = array.map(sanitiseValues);
21
+ var comparisonArray = array.map(function (item) {
22
+ return "" + parseFloat(sanitiseValues(item));
23
+ });
24
+ return JSON.stringify(sanitisedArray) === JSON.stringify(comparisonArray);
25
+ };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ArrayCollectorProps } from '../Array.types';
3
+ export declare const ArrayCollector: <ItemType extends "string" | "number">({ limit, itemType, arrayValueCount, texts, onConfirm, collectorSuggestions, }: ArrayCollectorProps<ItemType>) => React.JSX.Element;
@@ -0,0 +1,112 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { v4 as uuid } from 'uuid';
3
+ import Collector from '@synerise/ds-collector';
4
+ import { isArrayOfNumbersAsString, isNumberAsString, sanitiseValues } from '../Array.utils';
5
+ import { useCollector } from '../hooks/useCollector';
6
+ import * as S from '../Array.styles';
7
+ export var ArrayCollector = function ArrayCollector(_ref) {
8
+ var limit = _ref.limit,
9
+ itemType = _ref.itemType,
10
+ arrayValueCount = _ref.arrayValueCount,
11
+ texts = _ref.texts,
12
+ onConfirm = _ref.onConfirm,
13
+ collectorSuggestions = _ref.collectorSuggestions;
14
+ var _useState = useState([]),
15
+ collectorValues = _useState[0],
16
+ setCollectorValues = _useState[1];
17
+ var _useCollector = useCollector({
18
+ limit: limit,
19
+ collectorCount: collectorValues.length,
20
+ arrayValueCount: arrayValueCount,
21
+ texts: texts
22
+ }),
23
+ disabled = _useCollector.disabled,
24
+ error = _useCollector.error,
25
+ errorMessage = _useCollector.errorMessage,
26
+ addEnabled = _useCollector.addEnabled,
27
+ setHasTypeError = _useCollector.setHasTypeError,
28
+ exceedsLimit = _useCollector.exceedsLimit;
29
+ useEffect(function () {
30
+ if (itemType === 'number') {
31
+ var plainValues = collectorValues.map(function (item) {
32
+ return sanitiseValues(item.value);
33
+ });
34
+ setHasTypeError(!isArrayOfNumbersAsString(plainValues));
35
+ }
36
+ }, [collectorValues, setHasTypeError, itemType]);
37
+ var handleCancel = function handleCancel() {
38
+ setCollectorValues([]);
39
+ };
40
+ var handleConfirm = function handleConfirm(items) {
41
+ var hasError = items.some(function (item) {
42
+ return item.hasError;
43
+ });
44
+ var hasExceededLimit = exceedsLimit(items.length);
45
+ if (!hasError && !hasExceededLimit) {
46
+ var rawItemValues = items.map(function (item) {
47
+ return {
48
+ value: item.value,
49
+ id: item.id
50
+ };
51
+ });
52
+ onConfirm(rawItemValues);
53
+ setCollectorValues([]);
54
+ } else {
55
+ setCollectorValues(items);
56
+ }
57
+ };
58
+ var handleItemAdd = function handleItemAdd(text) {
59
+ return {
60
+ value: sanitiseValues("" + text),
61
+ type: itemType,
62
+ hasError: itemType === 'number' && !isNumberAsString("" + text),
63
+ id: uuid()
64
+ };
65
+ };
66
+ var handleItemSelect = function handleItemSelect(item) {
67
+ setCollectorValues([].concat(collectorValues, [item]));
68
+ };
69
+ var handleItemDeselect = function handleItemDeselect(deselectedItem) {
70
+ setCollectorValues(collectorValues.filter(function (collectorItem) {
71
+ return collectorItem.id !== deselectedItem.id;
72
+ }));
73
+ };
74
+ var handleMultipleItemSelect = function handleMultipleItemSelect(items) {
75
+ setCollectorValues([].concat(collectorValues, items));
76
+ };
77
+ return /*#__PURE__*/React.createElement(S.CollectorWrapper, null, /*#__PURE__*/React.createElement(Collector, {
78
+ valuesSeparator: ",",
79
+ error: error,
80
+ errorText: errorMessage,
81
+ onConfirm: addEnabled ? handleConfirm : undefined,
82
+ onItemSelect: handleItemSelect,
83
+ onMultipleItemsSelect: handleMultipleItemSelect,
84
+ selected: collectorValues,
85
+ onCancel: handleCancel,
86
+ onItemAdd: handleItemAdd,
87
+ allowCustomValue: true,
88
+ disabled: disabled,
89
+ cancelButtonProps: {
90
+ 'data-testid': 'array-collector-cancel-button'
91
+ },
92
+ addButtonProps: addEnabled ? {
93
+ 'data-testid': 'array-collector-add-button'
94
+ } : {
95
+ disabled: true,
96
+ 'data-testid': 'array-collector-add-button'
97
+ },
98
+ allowMultipleValues: true,
99
+ lookupConfig: {
100
+ display: 'value',
101
+ filter: 'value'
102
+ },
103
+ onItemDeselect: handleItemDeselect,
104
+ allowPaste: true,
105
+ suggestions: collectorSuggestions || [],
106
+ texts: {
107
+ add: texts.array.collectorAdd,
108
+ placeholder: texts.array.collectorPlaceholder,
109
+ cancel: texts.array.collectorCancel
110
+ }
111
+ }));
112
+ };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { ArrayCreatorProps } from '../Array.types';
3
+ export declare const ArrayCreator: <ItemType extends "string" | "number">({ value: arrayValue, searchQuery, itemType, onValueChange, limit, readOnly, texts, collectorSuggestions, }: ArrayCreatorProps<ItemType>) => React.JSX.Element;
@@ -0,0 +1,81 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React, { useMemo } from 'react';
3
+ import { Input } from '@synerise/ds-input';
4
+ import InputNumber from '@synerise/ds-input-number';
5
+ import Tooltip from '@synerise/ds-tooltip';
6
+ import { InboxNoResultsL, CloseM } from '@synerise/ds-icon';
7
+ import * as S from '../Array.styles';
8
+ import { matchesSearchQuery } from '../Array.utils';
9
+ import { ArrayCollector } from './ArrayCollector';
10
+ export var ArrayCreator = function ArrayCreator(_ref) {
11
+ var _ref$value = _ref.value,
12
+ arrayValue = _ref$value === void 0 ? [] : _ref$value,
13
+ searchQuery = _ref.searchQuery,
14
+ itemType = _ref.itemType,
15
+ onValueChange = _ref.onValueChange,
16
+ limit = _ref.limit,
17
+ readOnly = _ref.readOnly,
18
+ texts = _ref.texts,
19
+ collectorSuggestions = _ref.collectorSuggestions;
20
+ var arrayReversed = useMemo(function () {
21
+ return [].concat(arrayValue).reverse();
22
+ }, [arrayValue]);
23
+ var handleItemChange = function handleItemChange(valueIndex, newValue) {
24
+ var updatedArray = arrayReversed.map(function (currentValue, index) {
25
+ return index === valueIndex ? _extends({}, currentValue, {
26
+ value: newValue
27
+ }) : currentValue;
28
+ }).reverse();
29
+ onValueChange(updatedArray);
30
+ };
31
+ var handleItemRemove = function handleItemRemove(valueIndex) {
32
+ onValueChange([].concat(arrayReversed.slice(0, valueIndex), arrayReversed.slice(valueIndex + 1)).reverse());
33
+ };
34
+ var handleConfirm = function handleConfirm(rawItemValues) {
35
+ onValueChange([].concat(arrayValue, rawItemValues));
36
+ };
37
+ var filteredItems = useMemo(function () {
38
+ return searchQuery ? arrayReversed.filter(function (item) {
39
+ return matchesSearchQuery(item.value, searchQuery);
40
+ }) : arrayReversed;
41
+ }, [searchQuery, arrayReversed]);
42
+ return /*#__PURE__*/React.createElement(S.ModalContentWrapper, null, /*#__PURE__*/React.createElement(React.Fragment, null, !readOnly && /*#__PURE__*/React.createElement(ArrayCollector, {
43
+ arrayValueCount: arrayValue.length,
44
+ limit: limit,
45
+ itemType: itemType,
46
+ onConfirm: handleConfirm,
47
+ texts: texts,
48
+ collectorSuggestions: collectorSuggestions
49
+ }), filteredItems != null && filteredItems.length ? /*#__PURE__*/React.createElement(S.CreatorItemsList, null, filteredItems.map(function (item, index) {
50
+ return /*#__PURE__*/React.createElement(S.CreatorRow, {
51
+ "data-testid": "ds-factors-array-item",
52
+ key: item.id
53
+ }, itemType === 'string' ? /*#__PURE__*/React.createElement(Input, {
54
+ resetMargin: true,
55
+ readOnly: readOnly,
56
+ onChange: function onChange(event) {
57
+ return handleItemChange(index, event.target.value);
58
+ },
59
+ value: item.value
60
+ }) : /*#__PURE__*/React.createElement(InputNumber, {
61
+ raw: true,
62
+ readOnly: readOnly,
63
+ onChange: function onChange(changedValue) {
64
+ return changedValue && handleItemChange(index, changedValue);
65
+ },
66
+ value: item.value
67
+ }), !readOnly && /*#__PURE__*/React.createElement(Tooltip, {
68
+ title: texts.array.deleteItemTooltip
69
+ }, /*#__PURE__*/React.createElement(S.DeleteIcon, {
70
+ "data-testid": "ds-factors-array-remove-item",
71
+ onClick: function onClick() {
72
+ return handleItemRemove(index);
73
+ },
74
+ component: /*#__PURE__*/React.createElement(CloseM, null)
75
+ })));
76
+ })) : /*#__PURE__*/React.createElement(S.EmptyState, {
77
+ customIcon: /*#__PURE__*/React.createElement(InboxNoResultsL, null),
78
+ text: searchQuery ? texts.array.emptyResultsTitle : texts.array.emptyTitle,
79
+ label: searchQuery ? texts.array.emptyResultsDescription : texts.array.emptyDescription
80
+ })));
81
+ };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ArrayLimitProps } from '../Array.types';
3
+ export declare const ArrayLimit: ({ limit, count, texts }: ArrayLimitProps) => React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { IconAlert } from '@synerise/ds-alert';
3
+ import * as S from '../Array.styles';
4
+ export var ArrayLimit = function ArrayLimit(_ref) {
5
+ var limit = _ref.limit,
6
+ _ref$count = _ref.count,
7
+ count = _ref$count === void 0 ? 0 : _ref$count,
8
+ texts = _ref.texts;
9
+ return /*#__PURE__*/React.createElement(S.Limit, null, /*#__PURE__*/React.createElement(S.LimitPart, null, count === limit ? /*#__PURE__*/React.createElement(IconAlert, {
10
+ iconAlert: true,
11
+ type: "warning",
12
+ message: texts.array.limitReached
13
+ }) : texts.array.limitPrefix), /*#__PURE__*/React.createElement(S.LimitPart, null, " " + count + "/" + limit));
14
+ };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ArrayModalProps } from '../Array.types';
3
+ export declare const ArrayModal: <ItemType extends "string" | "number">({ value, itemType, onApply, onCancel, visible, readOnly, texts, limit, collectorSuggestions, }: ArrayModalProps<ItemType>) => React.JSX.Element;