@pallasoft/ps-input-components 3.9.0 → 3.10.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/dist/components/ps-cascader-input.d.ts +2 -1
- package/dist/components/ps-cascader-input.js +11 -7
- package/dist/components/ps-checkbox-matrix.js +1 -1
- package/dist/components/ps-combobox-close-bridge.js +7 -1
- package/dist/components/ps-combobox-input.d.ts +3 -1
- package/dist/components/ps-combobox-input.js +7 -3
- package/dist/components/ps-date-input.d.ts +3 -1
- package/dist/components/ps-date-input.js +3 -2
- package/dist/components/ps-grouped-switcher.js +2 -2
- package/dist/components/ps-multi-select-input.js +1 -1
- package/dist/components/ps-percent-input.js +1 -1
- package/dist/components/ps-phone-input.js +2 -2
- package/dist/components/ps-select-input.d.ts +3 -1
- package/dist/components/ps-select-input.js +6 -2
- package/dist/components/ps-select-option-item.js +1 -1
- package/dist/components/ps-select-with-create.d.ts +3 -1
- package/dist/components/ps-select-with-create.js +2 -2
- package/dist/components/ps-suggested-tag.d.ts +6 -0
- package/dist/components/ps-suggested-tag.js +8 -0
- package/dist/components/ps-tag-input.js +1 -1
- package/dist/components/ps-text-input.d.ts +3 -1
- package/dist/components/ps-text-input.js +4 -3
- package/dist/constants/ps-portable-text-editor-config.d.ts +1 -1
- package/dist/constants/ps-portable-text-editor-config.js +1 -1
- package/dist/esm/components/ps-cascader-input.js +11 -7
- package/dist/esm/components/ps-checkbox-matrix.js +1 -1
- package/dist/esm/components/ps-combobox-close-bridge.js +7 -1
- package/dist/esm/components/ps-combobox-input.js +7 -3
- package/dist/esm/components/ps-date-input.js +3 -2
- package/dist/esm/components/ps-grouped-switcher.js +2 -2
- package/dist/esm/components/ps-multi-select-input.js +1 -1
- package/dist/esm/components/ps-percent-input.js +1 -1
- package/dist/esm/components/ps-phone-input.js +2 -2
- package/dist/esm/components/ps-select-input.js +6 -2
- package/dist/esm/components/ps-select-option-item.js +1 -1
- package/dist/esm/components/ps-select-with-create.js +2 -2
- package/dist/esm/components/ps-suggested-tag.js +4 -0
- package/dist/esm/components/ps-tag-input.js +1 -1
- package/dist/esm/components/ps-text-input.js +4 -3
- package/dist/esm/constants/ps-portable-text-editor-config.js +1 -1
- package/dist/esm/form/components/ps-form-cascader-field.js +1 -1
- package/dist/esm/form/components/ps-form-date-field.js +1 -1
- package/dist/esm/form/components/ps-form-money-field.js +2 -2
- package/dist/esm/form/components/ps-form-select-field.js +2 -2
- package/dist/esm/form/components/ps-form-text-field.js +3 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/services/ps-suggested-tag-service.js +5 -0
- package/dist/form/components/ps-form-cascader-field.d.ts +3 -1
- package/dist/form/components/ps-form-cascader-field.js +1 -1
- package/dist/form/components/ps-form-date-field.d.ts +3 -1
- package/dist/form/components/ps-form-date-field.js +1 -1
- package/dist/form/components/ps-form-money-field.d.ts +3 -1
- package/dist/form/components/ps-form-money-field.js +2 -2
- package/dist/form/components/ps-form-select-field.d.ts +3 -1
- package/dist/form/components/ps-form-select-field.js +2 -2
- package/dist/form/components/ps-form-text-field.d.ts +3 -1
- package/dist/form/components/ps-form-text-field.js +3 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/services/ps-suggested-tag-service.d.ts +3 -0
- package/dist/services/ps-suggested-tag-service.js +9 -0
- package/package.json +1 -1
|
@@ -3,7 +3,13 @@ import { ComboBoxStateContext } from 'react-aria-components';
|
|
|
3
3
|
export const PsComboboxCloseBridge = ({ closeRef }) => {
|
|
4
4
|
const state = useContext(ComboBoxStateContext);
|
|
5
5
|
useEffect(() => {
|
|
6
|
-
closeRef.current =
|
|
6
|
+
closeRef.current =
|
|
7
|
+
state === null
|
|
8
|
+
? null
|
|
9
|
+
: () => {
|
|
10
|
+
if (state.isOpen)
|
|
11
|
+
state.toggle();
|
|
12
|
+
};
|
|
7
13
|
}, [closeRef, state]);
|
|
8
14
|
return null;
|
|
9
15
|
};
|
|
@@ -4,15 +4,19 @@ import { PsSpinner } from '@pallasoft/ps-core-components';
|
|
|
4
4
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
5
5
|
import { ComboBox, Label, ListBox, ListBoxItem, Popover } from 'react-aria-components';
|
|
6
6
|
import { PsComboboxInputService } from '../services/ps-combobox-input-service';
|
|
7
|
+
import { PsSuggestedTagService } from '../services/ps-suggested-tag-service';
|
|
7
8
|
import { PsComboboxCloseBridge } from './ps-combobox-close-bridge';
|
|
8
9
|
import { PsComboboxScanInput } from './ps-combobox-scan-input';
|
|
9
10
|
import { PsRequiredMark } from './ps-required-mark';
|
|
10
|
-
|
|
11
|
+
import { PsSuggestedTag } from './ps-suggested-tag';
|
|
12
|
+
export const PsComboboxInput = ({ className, emptyText, getItemKey, getItemLabel, hideLabel = false, inputValue, isDisabled = false, isLoading = false, isSuggested = false, items, label, menuTrigger = 'input', onInputChange, onScan, onSelectionChange, placeholder, renderItem, required, selectedKey, suggestedLabel, }) => {
|
|
11
13
|
const itemsByKey = new Map(items.map((item) => [getItemKey(item), item]));
|
|
12
14
|
const closeRef = useRef(null);
|
|
13
|
-
return (_jsxs(ComboBox, { allowsEmptyCollection: true, "aria-label": hideLabel
|
|
15
|
+
return (_jsxs(ComboBox, { allowsEmptyCollection: true, "aria-label": hideLabel && label !== undefined
|
|
16
|
+
? PsSuggestedTagService.accessibleLabel(label, isSuggested, suggestedLabel)
|
|
17
|
+
: undefined, className: PallasoftClassNameService.merge('block', className), defaultFilter: () => true, inputValue: inputValue, isDisabled: isDisabled, items: items, menuTrigger: menuTrigger, onInputChange: onInputChange, selectedKey: selectedKey, onSelectionChange: (key) => {
|
|
14
18
|
onSelectionChange?.(key === null ? null : PsComboboxInputService.getItem(itemsByKey, key));
|
|
15
19
|
if (key !== null && closeRef.current !== null)
|
|
16
20
|
closeRef.current();
|
|
17
|
-
}, children: [_jsx(PsComboboxCloseBridge, { closeRef: closeRef }), label && !hideLabel ? (_jsxs(Label, { className: 'ps-input-label', children: [label, _jsx(PsRequiredMark, { isRequired: required })] })) : null, _jsx("span", { className: hideLabel || !label ? 'relative block' : 'relative mt-2 block', children: _jsx(PsComboboxScanInput, { className: 'ps-input-control ps-focus-ring w-full text-sm font-semibold', onScan: onScan, placeholder: placeholder }) }), _jsx(Popover, { className: 'w-[--trigger-width] rounded-2xl border border-line bg-surface p-1.5 shadow-lg', children: isLoading && items.length === 0 ? (_jsx("div", { className: 'flex items-center justify-center py-4', children: _jsx(PsSpinner, { label: 'Loading results', size: 'small' }) })) : (_jsx(ListBox, { "aria-busy": isLoading, className: 'max-h-72 overflow-y-auto outline-none', items: items, renderEmptyState: () => emptyText ? _jsx("div", { className: 'px-3 py-2 text-sm text-
|
|
21
|
+
}, children: [_jsx(PsComboboxCloseBridge, { closeRef: closeRef }), label && !hideLabel ? (_jsxs(Label, { className: 'ps-input-label', children: [label, _jsx(PsRequiredMark, { isRequired: required }), _jsx(PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] })) : null, _jsx("span", { className: hideLabel || !label ? 'relative block' : 'relative mt-2 block', children: _jsx(PsComboboxScanInput, { className: 'ps-input-control ps-focus-ring w-full text-sm font-semibold', onScan: onScan, placeholder: placeholder }) }), _jsx(Popover, { className: 'w-[--trigger-width] rounded-2xl border border-line bg-surface p-1.5 shadow-lg', children: isLoading && items.length === 0 ? (_jsx("div", { className: 'flex items-center justify-center py-4', children: _jsx(PsSpinner, { label: 'Loading results', size: 'small' }) })) : (_jsx(ListBox, { "aria-busy": isLoading, className: 'max-h-72 overflow-y-auto outline-none', items: items, renderEmptyState: () => emptyText ? _jsx("div", { className: 'px-3 py-2 text-sm text-muted', children: emptyText }) : null, children: (item) => (_jsx(ListBoxItem, { className: 'ps-focus-ring cursor-pointer rounded-ps-control px-3 py-2 text-sm font-semibold text-ink selected:bg-primary-soft selected:text-primary hover:bg-mist focused:bg-mist', id: getItemKey(item), textValue: getItemLabel(item), children: renderItem ? renderItem(item) : getItemLabel(item) })) })) })] }));
|
|
18
22
|
};
|
|
@@ -12,7 +12,8 @@ import { PsDatePickerFallback } from './ps-date-picker-fallback';
|
|
|
12
12
|
import { PsFieldSkeleton } from './ps-field-skeleton';
|
|
13
13
|
import { PsLazyDatePicker } from './ps-lazy-date-picker';
|
|
14
14
|
import { PsRequiredMark } from './ps-required-mark';
|
|
15
|
-
|
|
15
|
+
import { PsSuggestedTag } from './ps-suggested-tag';
|
|
16
|
+
export const PsDateInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, isSuggested = false, label, max, min, name, onChange, placeholder = PsDateInputConfig.placeholder, required, suggestedLabel, value, }) => {
|
|
16
17
|
if (isLoading)
|
|
17
18
|
return _jsx(PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
18
19
|
const inputId = useId();
|
|
@@ -42,5 +43,5 @@ export const PsDateInput = ({ className, defaultValue, disabled, helperText, hid
|
|
|
42
43
|
onChange?.(nextValue);
|
|
43
44
|
};
|
|
44
45
|
const fallback = (_jsx(PsDatePickerFallback, { disabled: disabled, id: inputId, placeholder: placeholder, required: required, text: PsDateInputService.display(currentValue) }));
|
|
45
|
-
return (_jsxs("div", { className: PallasoftClassNameService.merge('block', className), children: [_jsxs("label", { className: hideLabel ? 'sr-only' : 'ps-input-label block', htmlFor: inputId, children: [label, _jsx(PsRequiredMark, { isRequired: required })] }), _jsxs("div", { className: hideLabel ? 'relative' : 'relative mt-2', children: [isHydrated ? (_jsx(Suspense, { fallback: fallback, children: _jsx(PsLazyDatePicker, { autoComplete: 'off', calendarClassName: PallasoftClassNameService.merge('ps-floating-panel ps-datepicker', view === PsCalendarView.day ? undefined : PsDateInputConfig.pickingClassName), className: PsDatePickerClasses.control, dateFormat: [...PsDateInputConfig.inputFormats], disabled: disabled, id: inputId, maxDate: maxDate, minDate: minDate, onCalendarClose: () => setView(PsCalendarView.day), onChange: handleChange, placeholderText: placeholder, popperClassName: 'ps-datepicker-popper', popperPlacement: 'bottom-start', popperProps: { strategy: 'fixed' }, portalId: portalId, renderCustomHeader: (headerProps) => (_jsx(PsCalendarHeader, { ...headerProps, maxDate: maxDate, minDate: minDate, onViewChange: setView, view: view })), required: required, selected: PsDateInputService.parse(currentValue), showPopperArrow: false, wrapperClassName: PsDatePickerClasses.wrapperOption }) })) : (fallback), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-ink/50', iconKey: PsIconKey.Calendar }), name ? _jsx("input", { name: name, type: 'hidden', value: currentValue }) : null] }), helperText ? _jsx("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
46
|
+
return (_jsxs("div", { className: PallasoftClassNameService.merge('block', className), children: [_jsxs("label", { className: hideLabel ? 'sr-only' : 'ps-input-label block', htmlFor: inputId, children: [label, _jsx(PsRequiredMark, { isRequired: required }), _jsx(PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] }), _jsxs("div", { className: hideLabel ? 'relative' : 'relative mt-2', children: [isHydrated ? (_jsx(Suspense, { fallback: fallback, children: _jsx(PsLazyDatePicker, { autoComplete: 'off', calendarClassName: PallasoftClassNameService.merge('ps-floating-panel ps-datepicker', view === PsCalendarView.day ? undefined : PsDateInputConfig.pickingClassName), className: PsDatePickerClasses.control, dateFormat: [...PsDateInputConfig.inputFormats], disabled: disabled, id: inputId, maxDate: maxDate, minDate: minDate, onCalendarClose: () => setView(PsCalendarView.day), onChange: handleChange, placeholderText: placeholder, popperClassName: 'ps-datepicker-popper', popperPlacement: 'bottom-start', popperProps: { strategy: 'fixed' }, portalId: portalId, renderCustomHeader: (headerProps) => (_jsx(PsCalendarHeader, { ...headerProps, maxDate: maxDate, minDate: minDate, onViewChange: setView, view: view })), required: required, selected: PsDateInputService.parse(currentValue), showPopperArrow: false, wrapperClassName: PsDatePickerClasses.wrapperOption }) })) : (fallback), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-ink/50', iconKey: PsIconKey.Calendar }), name ? _jsx("input", { name: name, type: 'hidden', value: currentValue }) : null] }), helperText ? _jsx("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
46
47
|
};
|
|
@@ -42,11 +42,11 @@ export const PsGroupedSwitcher = ({ allOption, ariaLabel, className, emptyText,
|
|
|
42
42
|
setIsOpen(next);
|
|
43
43
|
if (!next)
|
|
44
44
|
setQuery('');
|
|
45
|
-
}, children: [_jsxs(Button, { "aria-label": ariaLabel, className: PallasoftClassNameService.merge('ps-input-control ps-focus-ring relative flex w-full min-w-0 items-center pr-10 text-left text-sm font-semibold', className), children: [_jsx("span", { className: 'min-w-0 flex-1', children: renderSelected(isAllSelected ? null : selected) }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-primary', iconKey: PsIconKey.Chevron })] }), _jsx(Popover, { className: 'ps-floating-panel w-[max(var(--trigger-width),min(32rem,calc(100vw-2rem)))] min-w-[var(--trigger-width)] overflow-hidden p-0 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsx(Dialog, { "aria-label": ariaLabel, className: 'flex max-h-[min(34rem,75vh)] flex-col outline-none', children: _jsxs(Autocomplete, { filter: () => true, inputValue: query, onInputChange: setQuery, children: [_jsxs(SearchField, { "aria-label": searchPlaceholder, autoFocus: true, className: 'relative block border-b border-line p-2', children: [_jsx(Input, { className: 'ps-input-control ps-focus-ring w-full pl-10 text-sm font-semibold', placeholder: searchPlaceholder }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute left-5 top-1/2 h-4 w-4 -translate-y-1/2 text-ink/45', iconKey: PsIconKey.Search })] }), _jsxs(ListBox, { "aria-label": ariaLabel, className: 'ps-scrollbar-hidden min-h-0 flex-1 overflow-y-auto p-1.5 outline-none', onSelectionChange: onSelectionChange, renderEmptyState: () => (_jsx("div", { className: 'px-3 py-6 text-center text-sm text-
|
|
45
|
+
}, children: [_jsxs(Button, { "aria-label": ariaLabel, className: PallasoftClassNameService.merge('ps-input-control ps-focus-ring relative flex w-full min-w-0 items-center pr-10 text-left text-sm font-semibold', className), children: [_jsx("span", { className: 'min-w-0 flex-1', children: renderSelected(isAllSelected ? null : selected) }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-primary', iconKey: PsIconKey.Chevron })] }), _jsx(Popover, { className: 'ps-floating-panel w-[max(var(--trigger-width),min(32rem,calc(100vw-2rem)))] min-w-[var(--trigger-width)] overflow-hidden p-0 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsx(Dialog, { "aria-label": ariaLabel, className: 'flex max-h-[min(34rem,75vh)] flex-col outline-none', children: _jsxs(Autocomplete, { filter: () => true, inputValue: query, onInputChange: setQuery, children: [_jsxs(SearchField, { "aria-label": searchPlaceholder, autoFocus: true, className: 'relative block border-b border-line p-2', children: [_jsx(Input, { className: 'ps-input-control ps-focus-ring w-full pl-10 text-sm font-semibold', placeholder: searchPlaceholder }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute left-5 top-1/2 h-4 w-4 -translate-y-1/2 text-ink/45', iconKey: PsIconKey.Search })] }), _jsxs(ListBox, { "aria-label": ariaLabel, className: 'ps-scrollbar-hidden min-h-0 flex-1 overflow-y-auto p-1.5 outline-none', onSelectionChange: onSelectionChange, renderEmptyState: () => (_jsx("div", { className: 'px-3 py-6 text-center text-sm text-muted', children: emptyText })), selectedKeys: [
|
|
46
46
|
isAllSelected
|
|
47
47
|
? PsGroupedSwitcherConfig.allKey
|
|
48
48
|
: PsGroupedSwitcherService.selectedOptionId(sections, selectedKey, getItemKey),
|
|
49
|
-
], selectionMode: 'single', children: [showAll ? (_jsx(ListBoxSection, { children: _jsx(ListBoxItem, { className: 'ps-floating-option min-h-12 text-ink', id: PsGroupedSwitcherConfig.allKey, textValue: 'all', children: allOption.content }) })) : null, sections.map((section) => (_jsxs(ListBoxSection, { id: section.key, children: [_jsx(Header, { className: 'px-3 pb-1 pt-3 text-xs font-semibold tracking-wide text-
|
|
49
|
+
], selectionMode: 'single', children: [showAll ? (_jsx(ListBoxSection, { children: _jsx(ListBoxItem, { className: 'ps-floating-option min-h-12 text-ink', id: PsGroupedSwitcherConfig.allKey, textValue: 'all', children: allOption.content }) })) : null, sections.map((section) => (_jsxs(ListBoxSection, { id: section.key, children: [_jsx(Header, { className: 'px-3 pb-1 pt-3 text-xs font-semibold tracking-wide text-muted uppercase', children: renderSectionLabel === undefined
|
|
50
50
|
? section.label
|
|
51
51
|
: renderSectionLabel(section.key, section.label) }), section.items.map((item) => {
|
|
52
52
|
const key = getItemKey(item);
|
|
@@ -20,7 +20,7 @@ export const PsMultiSelectInput = ({ className, defaultValue, disabled, helperTe
|
|
|
20
20
|
setUncontrolledValue(nextValue);
|
|
21
21
|
onChange?.(nextValue);
|
|
22
22
|
};
|
|
23
|
-
return (_jsxs(Select, { "aria-label": hideLabel ? label : undefined, className: PallasoftClassNameService.merge('block', className), isDisabled: disabled, isRequired: required, name: name, onChange: handleChange, placeholder: placeholder, selectionMode: 'multiple', value: currentValue.filter((selected) => labelByValue.has(selected)), children: [hideLabel ? null : (_jsxs(Label, { className: 'ps-input-label block', children: [label, _jsx(PsRequiredMark, { isRequired: required })] })), _jsxs(Button, { className: PallasoftClassNameService.merge('ps-input-control ps-focus-ring relative flex w-full items-center py-1.5 pr-10 text-left text-sm font-semibold disabled:cursor-not-allowed disabled:opacity-60', hideLabel ? '' : 'mt-2'), children: [_jsx(SelectValue, { className: 'flex min-w-0 flex-1 flex-wrap gap-1.5', children: ({ isPlaceholder }) => isPlaceholder ? (_jsx("span", { className: 'font-medium text-
|
|
23
|
+
return (_jsxs(Select, { "aria-label": hideLabel ? label : undefined, className: PallasoftClassNameService.merge('block', className), isDisabled: disabled, isRequired: required, name: name, onChange: handleChange, placeholder: placeholder, selectionMode: 'multiple', value: currentValue.filter((selected) => labelByValue.has(selected)), children: [hideLabel ? null : (_jsxs(Label, { className: 'ps-input-label block', children: [label, _jsx(PsRequiredMark, { isRequired: required })] })), _jsxs(Button, { className: PallasoftClassNameService.merge('ps-input-control ps-focus-ring relative flex w-full items-center py-1.5 pr-10 text-left text-sm font-semibold disabled:cursor-not-allowed disabled:opacity-60', hideLabel ? '' : 'mt-2'), children: [_jsx(SelectValue, { className: 'flex min-w-0 flex-1 flex-wrap gap-1.5', children: ({ isPlaceholder }) => isPlaceholder ? (_jsx("span", { className: 'font-medium text-subtle', children: placeholder })) : (currentValue
|
|
24
24
|
.filter((selected) => labelByValue.has(selected))
|
|
25
25
|
.map((selected) => (_jsx("span", { className: 'inline-flex max-w-full items-center rounded-ps-control bg-primary/12 px-2.5 py-0.5 text-xs font-semibold text-ink', children: _jsx("span", { className: 'truncate', children: labelByValue.get(selected) }) }, selected)))) }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-primary', iconKey: PsIconKey.Chevron })] }), helperText ? (_jsx(Text, { className: 'ps-input-helper', slot: 'description', children: helperText })) : null, _jsx(Popover, { className: 'ps-floating-panel ps-scrollbar-hidden max-h-72 min-w-[var(--trigger-width)] overflow-y-auto p-1.5 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsx(ListBox, { className: 'outline-none', items: options.map((option) => ({ ...option, id: option.value })), children: (option) => _jsx(PsSelectOptionItem, { option: option }) }) })] }));
|
|
26
26
|
};
|
|
@@ -9,4 +9,4 @@ export const PsPercentInput = ({ className, onChange, ...props }) => (_jsxs("div
|
|
|
9
9
|
event.target.value = normalised;
|
|
10
10
|
if (onChange)
|
|
11
11
|
onChange(event);
|
|
12
|
-
}, type: 'text' }), _jsx("span", { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 bottom-3 text-sm text-
|
|
12
|
+
}, type: 'text' }), _jsx("span", { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 bottom-3 text-sm text-muted', children: PsTextFormatConfig.percentSuffix })] }));
|
|
@@ -34,9 +34,9 @@ export const PsPhoneInput = ({ className, defaultCountry = PsPhoneInputConfig.de
|
|
|
34
34
|
emit(national, code);
|
|
35
35
|
document.getElementById(inputId)?.focus();
|
|
36
36
|
};
|
|
37
|
-
return (_jsxs("div", { className: PallasoftClassNameService.merge('block', className), children: [_jsxs("label", { className: hideLabel ? 'sr-only' : 'ps-input-label', htmlFor: inputId, children: [label, _jsx(PsRequiredMark, { isRequired: required })] }), _jsxs("div", { className: PallasoftClassNameService.merge('ps-input-control flex items-stretch overflow-hidden p-0 focus-within:border-primary focus-within:shadow-[0_0_0_1px_rgb(var(--ps-color-primary-rgb))]', hideLabel ? '' : 'mt-2', isInvalid ? 'border-danger bg-danger/5' : '', disabled ? 'opacity-60' : ''), children: [_jsxs(DialogTrigger, { isOpen: isOpen, onOpenChange: setIsOpen, children: [_jsxs(Button, { "aria-label": PsPhoneInputConfig.countryLabel, className: 'flex shrink-0 items-center gap-1.5 border-r border-line px-3 outline-none focus-visible:bg-primary/10 text-sm font-semibold text-ink', isDisabled: disabled, children: [country, _jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-3.5 w-3.5 text-ink/45', iconKey: PsIconKey.Chevron })] }), _jsx(Popover, { className: 'ps-floating-panel w-72 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsxs(Dialog, { "aria-label": PsPhoneInputConfig.countryLabel, className: 'flex flex-col outline-none', children: [_jsx("div", { className: 'border-b border-line p-2', children: _jsx("input", { "aria-label": PsPhoneInputConfig.searchPlaceholder, autoFocus: true, className: 'ps-input-control ps-control-compact ps-focus-ring w-full text-sm', onChange: (event) => setQuery(event.target.value), placeholder: PsPhoneInputConfig.searchPlaceholder, type: 'search', value: query }) }), _jsx("ul", { className: 'ps-scrollbar-hidden max-h-64 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? (_jsx("li", { className: 'px-3 py-2.5 text-sm text-
|
|
37
|
+
return (_jsxs("div", { className: PallasoftClassNameService.merge('block', className), children: [_jsxs("label", { className: hideLabel ? 'sr-only' : 'ps-input-label', htmlFor: inputId, children: [label, _jsx(PsRequiredMark, { isRequired: required })] }), _jsxs("div", { className: PallasoftClassNameService.merge('ps-input-control flex items-stretch overflow-hidden p-0 focus-within:border-primary focus-within:shadow-[0_0_0_1px_rgb(var(--ps-color-primary-rgb))]', hideLabel ? '' : 'mt-2', isInvalid ? 'border-danger bg-danger/5' : '', disabled ? 'opacity-60' : ''), children: [_jsxs(DialogTrigger, { isOpen: isOpen, onOpenChange: setIsOpen, children: [_jsxs(Button, { "aria-label": PsPhoneInputConfig.countryLabel, className: 'flex shrink-0 items-center gap-1.5 border-r border-line px-3 outline-none focus-visible:bg-primary/10 text-sm font-semibold text-ink', isDisabled: disabled, children: [country, _jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-3.5 w-3.5 text-ink/45', iconKey: PsIconKey.Chevron })] }), _jsx(Popover, { className: 'ps-floating-panel w-72 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsxs(Dialog, { "aria-label": PsPhoneInputConfig.countryLabel, className: 'flex flex-col outline-none', children: [_jsx("div", { className: 'border-b border-line p-2', children: _jsx("input", { "aria-label": PsPhoneInputConfig.searchPlaceholder, autoFocus: true, className: 'ps-input-control ps-control-compact ps-focus-ring w-full text-sm', onChange: (event) => setQuery(event.target.value), placeholder: PsPhoneInputConfig.searchPlaceholder, type: 'search', value: query }) }), _jsx("ul", { className: 'ps-scrollbar-hidden max-h-64 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? (_jsx("li", { className: 'px-3 py-2.5 text-sm text-muted', children: PsPhoneInputConfig.emptyMessage })) : (matches.map((option) => (_jsx("li", { role: 'none', children: _jsxs("button", { "aria-selected": option.code === country, className: PallasoftClassNameService.merge('ps-focus-ring flex w-full items-center justify-between gap-3 rounded-ps-control px-3 py-2.5 text-left text-sm', option.code === country
|
|
38
38
|
? 'bg-primary/10 text-ink'
|
|
39
|
-
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), onClick: () => choose(option.code), role: 'option', type: 'button', children: [_jsx("span", { className: 'min-w-0 truncate', children: PsPhoneInputService.highlight(option.label, query).map((part, index) => part.isMatch ? (_jsx("strong", { className: 'font-semibold text-ink', children: part.text }, index)) : (_jsx("span", { children: part.text }, index))) }), _jsxs("span", { className: 'shrink-0 text-xs text-
|
|
39
|
+
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), onClick: () => choose(option.code), role: 'option', type: 'button', children: [_jsx("span", { className: 'min-w-0 truncate', children: PsPhoneInputService.highlight(option.label, query).map((part, index) => part.isMatch ? (_jsx("strong", { className: 'font-semibold text-ink', children: part.text }, index)) : (_jsx("span", { children: part.text }, index))) }), _jsxs("span", { className: 'shrink-0 text-xs text-muted', children: ["+", option.callingCode] })] }) }, option.code)))) })] }) })] }), _jsxs("span", { "aria-hidden": 'true', className: 'flex items-center pl-3 text-sm text-subtle', children: [PsPhoneInputConfig.plus, PsPhoneInputService.callingCode(country)] }), _jsx("input", { "aria-invalid": isInvalid, autoComplete: 'tel-national', className: 'min-w-0 flex-1 bg-transparent px-2 text-sm text-ink outline-none', disabled: disabled, id: inputId, inputMode: 'tel', name: name, onBlur: () => {
|
|
40
40
|
setIsTouched(true);
|
|
41
41
|
if (onBlur)
|
|
42
42
|
onBlur();
|
|
@@ -6,10 +6,12 @@ import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
|
6
6
|
import { Button, Label, ListBox, Popover, Select, SelectValue, Text, } from 'react-aria-components';
|
|
7
7
|
import { PsInputSizeClassNames } from '../constants/ps-input-size-class-names';
|
|
8
8
|
import { PsSelectInputService } from '../services/ps-select-input-service';
|
|
9
|
+
import { PsSuggestedTagService } from '../services/ps-suggested-tag-service';
|
|
9
10
|
import { PsFieldSkeleton } from './ps-field-skeleton';
|
|
10
11
|
import { PsRequiredMark } from './ps-required-mark';
|
|
11
12
|
import { PsSelectOptionItem } from './ps-select-option-item';
|
|
12
|
-
|
|
13
|
+
import { PsSuggestedTag } from './ps-suggested-tag';
|
|
14
|
+
export const PsSelectInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, isSuggested = false, label, name, onChange, options, placeholder = 'Select an option', required, suggestedLabel, controlSize = 'default', value, }) => {
|
|
13
15
|
if (isLoading)
|
|
14
16
|
return _jsx(PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
15
17
|
const [uncontrolledValue, setUncontrolledValue] = useState(() => PsSelectInputService.getDefaultValue(defaultValue, options));
|
|
@@ -22,5 +24,7 @@ export const PsSelectInput = ({ className, defaultValue, disabled, helperText, h
|
|
|
22
24
|
setUncontrolledValue(nextValue);
|
|
23
25
|
onChange?.(nextValue);
|
|
24
26
|
};
|
|
25
|
-
return (_jsxs(Select, { "aria-label": hideLabel
|
|
27
|
+
return (_jsxs(Select, { "aria-label": hideLabel
|
|
28
|
+
? PsSuggestedTagService.accessibleLabel(label, isSuggested, suggestedLabel)
|
|
29
|
+
: undefined, className: PallasoftClassNameService.merge('block', className), isDisabled: disabled, isRequired: required, name: name, onChange: handleChange, placeholder: placeholder, value: hasOption ? currentValue : null, children: [hideLabel ? null : (_jsxs(Label, { className: 'ps-input-label block', children: [label, _jsx(PsRequiredMark, { isRequired: required }), _jsx(PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] })), _jsxs(Button, { className: PallasoftClassNameService.merge('ps-input-control ps-focus-ring relative flex w-full items-center pr-10 text-left text-sm font-semibold disabled:cursor-not-allowed disabled:opacity-60', hideLabel ? '' : 'mt-2', PsInputSizeClassNames[controlSize]), children: [_jsx(SelectValue, { className: 'min-w-0 flex-1 truncate', children: ({ isPlaceholder, selectedText }) => isPlaceholder ? (_jsx("span", { className: 'font-medium text-subtle', children: placeholder })) : (selectedText) }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-primary', iconKey: PsIconKey.Chevron })] }), helperText ? (_jsx(Text, { className: 'ps-input-helper', slot: 'description', children: helperText })) : null, _jsx(Popover, { className: 'ps-floating-panel ps-scrollbar-hidden max-h-72 min-w-[var(--trigger-width)] overflow-y-auto p-1.5 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsx(ListBox, { className: 'outline-none', items: options.map((option) => ({ ...option, id: option.value })), children: (option) => _jsx(PsSelectOptionItem, { option: option }) }) })] }));
|
|
26
30
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
3
3
|
import { ListBoxItem } from 'react-aria-components';
|
|
4
|
-
export const PsSelectOptionItem = ({ option }) => (_jsx(ListBoxItem, { className: 'ps-floating-option text-ink', id: option.value, textValue: option.label, children: ({ isSelected }) => (_jsxs(_Fragment, { children: [_jsx("span", { className: 'flex h-4 w-4 shrink-0 items-center justify-center text-primary', children: isSelected ? (_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: PsIconKey.Check })) : null }), _jsxs("span", { className: 'min-w-0 flex-1', children: [_jsx("span", { className: 'block truncate', children: option.label }), option.description ? (_jsx("span", { className: 'mt-0.5 block text-xs font-normal text-
|
|
4
|
+
export const PsSelectOptionItem = ({ option }) => (_jsx(ListBoxItem, { className: 'ps-floating-option text-ink', id: option.value, textValue: option.label, children: ({ isSelected }) => (_jsxs(_Fragment, { children: [_jsx("span", { className: 'flex h-4 w-4 shrink-0 items-center justify-center text-primary', children: isSelected ? (_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: PsIconKey.Check })) : null }), _jsxs("span", { className: 'min-w-0 flex-1', children: [_jsx("span", { className: 'block truncate', children: option.label }), option.description ? (_jsx("span", { className: 'mt-0.5 block text-xs font-normal text-muted', children: option.description })) : null] })] })) }));
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { PsSelectWithCreateConfig } from '../constants/ps-select-with-create-config';
|
|
3
3
|
import { PsFormControl } from './ps-form-control';
|
|
4
4
|
import { PsSelectInput } from './ps-select-input';
|
|
5
|
-
export const PsSelectWithCreate = ({ createHref, createOptionLabel, errorText, hideLabel, label, onChange, options, placeholder, required, value, }) => (_jsx(PsFormControl, { errorText: errorText, children: _jsx(PsSelectInput, { hideLabel: hideLabel, label: label, onChange: (next) => {
|
|
5
|
+
export const PsSelectWithCreate = ({ createHref, createOptionLabel, errorText, hideLabel, isSuggested, label, onChange, options, placeholder, required, suggestedLabel, value, }) => (_jsx(PsFormControl, { errorText: errorText, children: _jsx(PsSelectInput, { hideLabel: hideLabel, isSuggested: isSuggested, label: label, onChange: (next) => {
|
|
6
6
|
if (next !== PsSelectWithCreateConfig.createValue) {
|
|
7
7
|
onChange(next);
|
|
8
8
|
return;
|
|
@@ -11,4 +11,4 @@ export const PsSelectWithCreate = ({ createHref, createOptionLabel, errorText, h
|
|
|
11
11
|
}, options: [
|
|
12
12
|
...options,
|
|
13
13
|
{ label: createOptionLabel, value: PsSelectWithCreateConfig.createValue },
|
|
14
|
-
], placeholder: placeholder, required: required, value: value }) }));
|
|
14
|
+
], placeholder: placeholder, required: required, suggestedLabel: suggestedLabel, value: value }) }));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
4
|
+
export const PsSuggestedTag = ({ className, isSuggested = false, label }) => isSuggested && label !== undefined ? (_jsxs("span", { className: PallasoftClassNameService.merge('ml-2 inline-flex shrink-0 items-center gap-1 align-middle text-xs font-medium text-muted', className), children: [_jsx("span", { className: 'sr-only', children: ", " }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-3 w-3 text-primary', iconKey: PsIconKey.Spark }), label] })) : null;
|
|
@@ -29,7 +29,7 @@ export const PsTagInput = ({ className, errorText, helperText, hideLabel, isDisa
|
|
|
29
29
|
return (_jsx(PsFormControl, { className: className, errorText: errorText, helperText: helperText, children: _jsxs("label", { className: 'block', children: [_jsxs("span", { className: hideLabel ? 'sr-only' : 'ps-input-label', children: [label, _jsx(PsRequiredMark, { isRequired: required })] }), _jsxs("span", { className: PallasoftClassNameService.merge('ps-input-control flex flex-wrap items-center gap-1.5 py-1.5', hideLabel ? '' : 'mt-2', isDisabled ? 'opacity-60' : ''), children: [values.map((value) => (_jsx(PsActiveFilterChip, { label: value, onRemove: () => {
|
|
30
30
|
if (!isDisabled)
|
|
31
31
|
onChange(PsTagInputService.remove(values, value));
|
|
32
|
-
}, removeLabel: removeLabel(value) }, value))), _jsx("input", { "aria-invalid": errorText ? true : undefined, className: 'min-w-24 flex-1 bg-transparent text-sm font-semibold outline-none placeholder:font-medium placeholder:text-
|
|
32
|
+
}, removeLabel: removeLabel(value) }, value))), _jsx("input", { "aria-invalid": errorText ? true : undefined, className: 'min-w-24 flex-1 bg-transparent text-sm font-semibold outline-none placeholder:font-medium placeholder:text-subtle disabled:cursor-not-allowed', disabled: isDisabled || isFull, name: name, onBlur: () => commit(draft), onChange: (event) => {
|
|
33
33
|
const text = event.target.value;
|
|
34
34
|
if (text.includes(PsTagInputConfig.separator))
|
|
35
35
|
commit(text);
|
|
@@ -4,13 +4,14 @@ import { PsInputSizeClassNames } from '../constants/ps-input-size-class-names';
|
|
|
4
4
|
import { PsDateInput } from './ps-date-input';
|
|
5
5
|
import { PsFieldSkeleton } from './ps-field-skeleton';
|
|
6
6
|
import { PsRequiredMark } from './ps-required-mark';
|
|
7
|
-
|
|
7
|
+
import { PsSuggestedTag } from './ps-suggested-tag';
|
|
8
|
+
export const PsTextInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, isSuggested = false, label, name, onChange, required, suggestedLabel, controlSize = 'default', type, value, ...props }) => {
|
|
8
9
|
if (isLoading)
|
|
9
10
|
return _jsx(PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
10
11
|
if (type === 'date') {
|
|
11
12
|
return (_jsx(PsDateInput, { className: className, defaultValue: typeof defaultValue === 'string' ? defaultValue : undefined, disabled: disabled, helperText: helperText, hideLabel: hideLabel, label: label, name: name, onChange: (nextValue) => onChange?.({
|
|
12
13
|
target: { name, value: nextValue },
|
|
13
|
-
}), required: required, value: typeof value === 'string' ? value : undefined }));
|
|
14
|
+
}), isSuggested: isSuggested, required: required, suggestedLabel: suggestedLabel, value: typeof value === 'string' ? value : undefined }));
|
|
14
15
|
}
|
|
15
|
-
return (_jsxs("label", { className: 'block', children: [_jsxs("span", { className: hideLabel ? 'sr-only' : 'ps-input-label', children: [label, _jsx(PsRequiredMark, { isRequired: required })] }), _jsx("input", { className: PallasoftClassNameService.merge(hideLabel ? 'ps-input-control' : 'ps-input-control mt-2', PsInputSizeClassNames[controlSize], className), defaultValue: defaultValue, disabled: disabled, name: name, onChange: onChange, required: required, type: type, value: value, ...props }), helperText ? _jsx("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
16
|
+
return (_jsxs("label", { className: 'block', children: [_jsxs("span", { className: hideLabel ? 'sr-only' : 'ps-input-label', children: [label, _jsx(PsRequiredMark, { isRequired: required }), _jsx(PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] }), _jsx("input", { className: PallasoftClassNameService.merge(hideLabel ? 'ps-input-control' : 'ps-input-control mt-2', PsInputSizeClassNames[controlSize], className), defaultValue: defaultValue, disabled: disabled, name: name, onChange: onChange, required: required, type: type, value: value, ...props }), helperText ? _jsx("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
16
17
|
};
|
|
@@ -15,6 +15,6 @@ export const PsPortableTextEditorConfig = {
|
|
|
15
15
|
code: 'rounded bg-ink/10 px-1 font-mono text-[0.9em]',
|
|
16
16
|
link: 'text-primary underline',
|
|
17
17
|
orderedList: 'list-decimal pl-6',
|
|
18
|
-
placeholder: 'before:pointer-events-none before:float-left before:h-0 before:text-
|
|
18
|
+
placeholder: 'before:pointer-events-none before:float-left before:h-0 before:text-subtle before:content-[attr(data-placeholder)]',
|
|
19
19
|
},
|
|
20
20
|
};
|
|
@@ -3,4 +3,4 @@ import { Controller } from 'react-hook-form';
|
|
|
3
3
|
import { PsCascaderInput } from '../../components/ps-cascader-input';
|
|
4
4
|
import { PsFormControl } from '../../components/ps-form-control';
|
|
5
5
|
import { PsFormFieldService } from '../services/ps-form-field-service';
|
|
6
|
-
export const PsFormCascaderField = ({ control, disabled, groups, label, name, placeholder, rules, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsCascaderInput, { disabled: disabled, groups: groups, label: label, onChange: field.onChange, placeholder: placeholder, value: PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
6
|
+
export const PsFormCascaderField = ({ control, disabled, groups, isSuggested, label, name, placeholder, rules, suggestedLabel, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsCascaderInput, { disabled: disabled, groups: groups, isSuggested: isSuggested, label: label, onChange: field.onChange, placeholder: placeholder, suggestedLabel: suggestedLabel, value: PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
@@ -3,4 +3,4 @@ import { Controller } from 'react-hook-form';
|
|
|
3
3
|
import { PsDateInput } from '../../components/ps-date-input';
|
|
4
4
|
import { PsFormControl } from '../../components/ps-form-control';
|
|
5
5
|
import { PsFormFieldService } from '../services/ps-form-field-service';
|
|
6
|
-
export const PsFormDateField = ({ control, helperText, label, name, rules, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsDateInput, { helperText: helperText, label: label, name: field.name, onChange: field.onChange, required: PsFormFieldService.isRequired(rules), value: PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
6
|
+
export const PsFormDateField = ({ control, helperText, isSuggested, label, name, rules, suggestedLabel, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsDateInput, { helperText: helperText, isSuggested: isSuggested, label: label, name: field.name, onChange: field.onChange, required: PsFormFieldService.isRequired(rules), suggestedLabel: suggestedLabel, value: PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
@@ -3,7 +3,7 @@ import { Controller } from 'react-hook-form';
|
|
|
3
3
|
import { PsAmountInput } from '../../components/ps-amount-input';
|
|
4
4
|
import { PsFormControl } from '../../components/ps-form-control';
|
|
5
5
|
import { PsFormFieldService } from '../services/ps-form-field-service';
|
|
6
|
-
export const PsFormMoneyField = ({ control, label, name, normalize, placeholder, rules, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsAmountInput, { className: 'text-right tabular-nums', label: label, name: field.name, onBlur: () => {
|
|
6
|
+
export const PsFormMoneyField = ({ control, isSuggested, label, name, normalize, placeholder, rules, suggestedLabel, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsAmountInput, { className: 'text-right tabular-nums', isSuggested: isSuggested, label: label, name: field.name, onBlur: () => {
|
|
7
7
|
if (normalize)
|
|
8
8
|
field.onChange(normalize(PsFormFieldService.text(field.value)));
|
|
9
|
-
}, onChange: field.onChange, placeholder: placeholder, required: PsFormFieldService.isRequired(rules), value: field.value }) })), rules: rules }));
|
|
9
|
+
}, onChange: field.onChange, placeholder: placeholder, required: PsFormFieldService.isRequired(rules), suggestedLabel: suggestedLabel, value: field.value }) })), rules: rules }));
|
|
@@ -3,8 +3,8 @@ import { Controller } from 'react-hook-form';
|
|
|
3
3
|
import { PsFormControl } from '../../components/ps-form-control';
|
|
4
4
|
import { PsSelectInput } from '../../components/ps-select-input';
|
|
5
5
|
import { PsFormFieldService } from '../services/ps-form-field-service';
|
|
6
|
-
export const PsFormSelectField = ({ control, helperText, label, name, onValueChange, options, placeholder, rules, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsSelectInput, { helperText: helperText, label: label, name: field.name, onChange: (value) => {
|
|
6
|
+
export const PsFormSelectField = ({ control, helperText, isSuggested, label, name, onValueChange, options, placeholder, rules, suggestedLabel, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => (_jsx(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: _jsx(PsSelectInput, { helperText: helperText, isSuggested: isSuggested, label: label, name: field.name, onChange: (value) => {
|
|
7
7
|
field.onChange(value);
|
|
8
8
|
if (onValueChange)
|
|
9
9
|
onValueChange(value);
|
|
10
|
-
}, options: options, placeholder: placeholder, required: PsFormFieldService.isRequired(rules), value: PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
10
|
+
}, options: options, placeholder: placeholder, required: PsFormFieldService.isRequired(rules), suggestedLabel: suggestedLabel, value: PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
@@ -9,12 +9,13 @@ import { PsTextInput } from '../../components/ps-text-input';
|
|
|
9
9
|
import { PsUrlInput } from '../../components/ps-url-input';
|
|
10
10
|
import { PsFormTextKind } from '../constants/ps-form-text-kind';
|
|
11
11
|
import { PsFormFieldService } from '../services/ps-form-field-service';
|
|
12
|
-
export const PsFormTextField = ({ asNumber = false, autoComplete, className, control, country = '', disabled, helperText, inputMode, kind = PsFormTextKind.Text, label, maxLength, name, placeholder, rules, type, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => {
|
|
12
|
+
export const PsFormTextField = ({ asNumber = false, autoComplete, className, control, country = '', disabled, helperText, inputMode, isSuggested, kind = PsFormTextKind.Text, label, maxLength, name, placeholder, rules, suggestedLabel, type, }) => (_jsx(Controller, { control: control, name: name, render: ({ field, fieldState }) => {
|
|
13
13
|
const shared = {
|
|
14
14
|
autoComplete,
|
|
15
15
|
className,
|
|
16
16
|
disabled,
|
|
17
17
|
helperText,
|
|
18
|
+
isSuggested,
|
|
18
19
|
label,
|
|
19
20
|
maxLength,
|
|
20
21
|
name: field.name,
|
|
@@ -22,6 +23,7 @@ export const PsFormTextField = ({ asNumber = false, autoComplete, className, con
|
|
|
22
23
|
onChange: (event) => field.onChange(asNumber ? PsFormFieldService.number(event.target.value) : event),
|
|
23
24
|
placeholder,
|
|
24
25
|
required: PsFormFieldService.isRequired(rules),
|
|
26
|
+
suggestedLabel,
|
|
25
27
|
value: PsFormFieldService.text(field.value),
|
|
26
28
|
};
|
|
27
29
|
return (_jsxs(PsFormControl, { errorText: PsFormFieldService.error(fieldState.error), children: [kind === PsFormTextKind.Email ? _jsx(PsEmailInput, { ...shared }) : null, kind === PsFormTextKind.Url ? _jsx(PsUrlInput, { ...shared }) : null, kind === PsFormTextKind.Amount ? _jsx(PsAmountInput, { ...shared }) : null, kind === PsFormTextKind.Percent ? _jsx(PsPercentInput, { ...shared }) : null, kind === PsFormTextKind.PostalCode ? (_jsx(PsPostalCodeInput, { ...shared, country: country })) : null, kind === PsFormTextKind.Text ? (_jsx(PsTextInput, { ...shared, inputMode: inputMode, type: type })) : null] }));
|
package/dist/esm/index.js
CHANGED
|
@@ -38,6 +38,8 @@ export * from './services/ps-postal-code-service';
|
|
|
38
38
|
export * from './services/ps-select-option-service';
|
|
39
39
|
export * from './services/ps-text-format-service';
|
|
40
40
|
export * from './components/ps-required-mark';
|
|
41
|
+
export * from './components/ps-suggested-tag';
|
|
42
|
+
export * from './services/ps-suggested-tag-service';
|
|
41
43
|
export * from './components/ps-year-input';
|
|
42
44
|
export * from './constants/ps-year-input-config';
|
|
43
45
|
export * from './services/ps-year-input-service';
|
|
@@ -5,9 +5,11 @@ export interface PsFormCascaderFieldProps<T extends FieldValues> {
|
|
|
5
5
|
control: Control<T>;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
groups: PsCascaderGroup[];
|
|
8
|
+
isSuggested?: boolean;
|
|
8
9
|
label: string;
|
|
9
10
|
name: Path<T>;
|
|
10
11
|
placeholder?: string;
|
|
11
12
|
rules?: PsFormFieldRules<T>;
|
|
13
|
+
suggestedLabel?: string;
|
|
12
14
|
}
|
|
13
|
-
export declare const PsFormCascaderField: <T extends FieldValues>({ control, disabled, groups, label, name, placeholder, rules, }: PsFormCascaderFieldProps<T>) => import("react").JSX.Element;
|
|
15
|
+
export declare const PsFormCascaderField: <T extends FieldValues>({ control, disabled, groups, isSuggested, label, name, placeholder, rules, suggestedLabel, }: PsFormCascaderFieldProps<T>) => import("react").JSX.Element;
|
|
@@ -6,5 +6,5 @@ const react_hook_form_1 = require("react-hook-form");
|
|
|
6
6
|
const ps_cascader_input_1 = require("../../components/ps-cascader-input");
|
|
7
7
|
const ps_form_control_1 = require("../../components/ps-form-control");
|
|
8
8
|
const ps_form_field_service_1 = require("../services/ps-form-field-service");
|
|
9
|
-
const PsFormCascaderField = ({ control, disabled, groups, label, name, placeholder, rules, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_cascader_input_1.PsCascaderInput, { disabled: disabled, groups: groups, label: label, onChange: field.onChange, placeholder: placeholder, value: ps_form_field_service_1.PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
9
|
+
const PsFormCascaderField = ({ control, disabled, groups, isSuggested, label, name, placeholder, rules, suggestedLabel, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_cascader_input_1.PsCascaderInput, { disabled: disabled, groups: groups, isSuggested: isSuggested, label: label, onChange: field.onChange, placeholder: placeholder, suggestedLabel: suggestedLabel, value: ps_form_field_service_1.PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
10
10
|
exports.PsFormCascaderField = PsFormCascaderField;
|
|
@@ -3,8 +3,10 @@ import type { PsFormFieldRules } from '../models/ps-form-field-rules';
|
|
|
3
3
|
export interface PsFormDateFieldProps<T extends FieldValues> {
|
|
4
4
|
control: Control<T>;
|
|
5
5
|
helperText?: string;
|
|
6
|
+
isSuggested?: boolean;
|
|
6
7
|
label: string;
|
|
7
8
|
name: Path<T>;
|
|
8
9
|
rules?: PsFormFieldRules<T>;
|
|
10
|
+
suggestedLabel?: string;
|
|
9
11
|
}
|
|
10
|
-
export declare const PsFormDateField: <T extends FieldValues>({ control, helperText, label, name, rules, }: PsFormDateFieldProps<T>) => import("react").JSX.Element;
|
|
12
|
+
export declare const PsFormDateField: <T extends FieldValues>({ control, helperText, isSuggested, label, name, rules, suggestedLabel, }: PsFormDateFieldProps<T>) => import("react").JSX.Element;
|
|
@@ -6,5 +6,5 @@ const react_hook_form_1 = require("react-hook-form");
|
|
|
6
6
|
const ps_date_input_1 = require("../../components/ps-date-input");
|
|
7
7
|
const ps_form_control_1 = require("../../components/ps-form-control");
|
|
8
8
|
const ps_form_field_service_1 = require("../services/ps-form-field-service");
|
|
9
|
-
const PsFormDateField = ({ control, helperText, label, name, rules, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_date_input_1.PsDateInput, { helperText: helperText, label: label, name: field.name, onChange: field.onChange, required: ps_form_field_service_1.PsFormFieldService.isRequired(rules), value: ps_form_field_service_1.PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
9
|
+
const PsFormDateField = ({ control, helperText, isSuggested, label, name, rules, suggestedLabel, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_date_input_1.PsDateInput, { helperText: helperText, isSuggested: isSuggested, label: label, name: field.name, onChange: field.onChange, required: ps_form_field_service_1.PsFormFieldService.isRequired(rules), suggestedLabel: suggestedLabel, value: ps_form_field_service_1.PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
10
10
|
exports.PsFormDateField = PsFormDateField;
|
|
@@ -2,10 +2,12 @@ import { type Control, type FieldValues, type Path } from 'react-hook-form';
|
|
|
2
2
|
import type { PsFormFieldRules } from '../models/ps-form-field-rules';
|
|
3
3
|
export interface PsFormMoneyFieldProps<T extends FieldValues> {
|
|
4
4
|
control: Control<T>;
|
|
5
|
+
isSuggested?: boolean;
|
|
5
6
|
label: string;
|
|
6
7
|
name: Path<T>;
|
|
7
8
|
normalize?: (value: string) => string;
|
|
8
9
|
placeholder?: string;
|
|
9
10
|
rules?: PsFormFieldRules<T>;
|
|
11
|
+
suggestedLabel?: string;
|
|
10
12
|
}
|
|
11
|
-
export declare const PsFormMoneyField: <T extends FieldValues>({ control, label, name, normalize, placeholder, rules, }: PsFormMoneyFieldProps<T>) => import("react").JSX.Element;
|
|
13
|
+
export declare const PsFormMoneyField: <T extends FieldValues>({ control, isSuggested, label, name, normalize, placeholder, rules, suggestedLabel, }: PsFormMoneyFieldProps<T>) => import("react").JSX.Element;
|
|
@@ -6,8 +6,8 @@ const react_hook_form_1 = require("react-hook-form");
|
|
|
6
6
|
const ps_amount_input_1 = require("../../components/ps-amount-input");
|
|
7
7
|
const ps_form_control_1 = require("../../components/ps-form-control");
|
|
8
8
|
const ps_form_field_service_1 = require("../services/ps-form-field-service");
|
|
9
|
-
const PsFormMoneyField = ({ control, label, name, normalize, placeholder, rules, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_amount_input_1.PsAmountInput, { className: 'text-right tabular-nums', label: label, name: field.name, onBlur: () => {
|
|
9
|
+
const PsFormMoneyField = ({ control, isSuggested, label, name, normalize, placeholder, rules, suggestedLabel, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_amount_input_1.PsAmountInput, { className: 'text-right tabular-nums', isSuggested: isSuggested, label: label, name: field.name, onBlur: () => {
|
|
10
10
|
if (normalize)
|
|
11
11
|
field.onChange(normalize(ps_form_field_service_1.PsFormFieldService.text(field.value)));
|
|
12
|
-
}, onChange: field.onChange, placeholder: placeholder, required: ps_form_field_service_1.PsFormFieldService.isRequired(rules), value: field.value }) })), rules: rules }));
|
|
12
|
+
}, onChange: field.onChange, placeholder: placeholder, required: ps_form_field_service_1.PsFormFieldService.isRequired(rules), suggestedLabel: suggestedLabel, value: field.value }) })), rules: rules }));
|
|
13
13
|
exports.PsFormMoneyField = PsFormMoneyField;
|
|
@@ -4,11 +4,13 @@ import type { PsFormFieldRules } from '../models/ps-form-field-rules';
|
|
|
4
4
|
export interface PsFormSelectFieldProps<T extends FieldValues> {
|
|
5
5
|
control: Control<T>;
|
|
6
6
|
helperText?: string;
|
|
7
|
+
isSuggested?: boolean;
|
|
7
8
|
label: string;
|
|
8
9
|
name: Path<T>;
|
|
9
10
|
onValueChange?: (value: string) => void;
|
|
10
11
|
options: PsSelectOption[];
|
|
11
12
|
placeholder?: string;
|
|
12
13
|
rules?: PsFormFieldRules<T>;
|
|
14
|
+
suggestedLabel?: string;
|
|
13
15
|
}
|
|
14
|
-
export declare const PsFormSelectField: <T extends FieldValues>({ control, helperText, label, name, onValueChange, options, placeholder, rules, }: PsFormSelectFieldProps<T>) => import("react").JSX.Element;
|
|
16
|
+
export declare const PsFormSelectField: <T extends FieldValues>({ control, helperText, isSuggested, label, name, onValueChange, options, placeholder, rules, suggestedLabel, }: PsFormSelectFieldProps<T>) => import("react").JSX.Element;
|
|
@@ -6,9 +6,9 @@ const react_hook_form_1 = require("react-hook-form");
|
|
|
6
6
|
const ps_form_control_1 = require("../../components/ps-form-control");
|
|
7
7
|
const ps_select_input_1 = require("../../components/ps-select-input");
|
|
8
8
|
const ps_form_field_service_1 = require("../services/ps-form-field-service");
|
|
9
|
-
const PsFormSelectField = ({ control, helperText, label, name, onValueChange, options, placeholder, rules, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_select_input_1.PsSelectInput, { helperText: helperText, label: label, name: field.name, onChange: (value) => {
|
|
9
|
+
const PsFormSelectField = ({ control, helperText, isSuggested, label, name, onValueChange, options, placeholder, rules, suggestedLabel, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: (0, jsx_runtime_1.jsx)(ps_select_input_1.PsSelectInput, { helperText: helperText, isSuggested: isSuggested, label: label, name: field.name, onChange: (value) => {
|
|
10
10
|
field.onChange(value);
|
|
11
11
|
if (onValueChange)
|
|
12
12
|
onValueChange(value);
|
|
13
|
-
}, options: options, placeholder: placeholder, required: ps_form_field_service_1.PsFormFieldService.isRequired(rules), value: ps_form_field_service_1.PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
13
|
+
}, options: options, placeholder: placeholder, required: ps_form_field_service_1.PsFormFieldService.isRequired(rules), suggestedLabel: suggestedLabel, value: ps_form_field_service_1.PsFormFieldService.text(field.value) }) })), rules: rules }));
|
|
14
14
|
exports.PsFormSelectField = PsFormSelectField;
|
|
@@ -11,12 +11,14 @@ export interface PsFormTextFieldProps<T extends FieldValues> {
|
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
helperText?: string;
|
|
13
13
|
inputMode?: HTMLAttributes<HTMLInputElement>['inputMode'];
|
|
14
|
+
isSuggested?: boolean;
|
|
14
15
|
kind?: PsFormTextKind;
|
|
15
16
|
label: string;
|
|
16
17
|
maxLength?: number;
|
|
17
18
|
name: Path<T>;
|
|
18
19
|
placeholder?: string;
|
|
19
20
|
rules?: PsFormFieldRules<T>;
|
|
21
|
+
suggestedLabel?: string;
|
|
20
22
|
type?: string;
|
|
21
23
|
}
|
|
22
|
-
export declare const PsFormTextField: <T extends FieldValues>({ asNumber, autoComplete, className, control, country, disabled, helperText, inputMode, kind, label, maxLength, name, placeholder, rules, type, }: PsFormTextFieldProps<T>) => import("react").JSX.Element;
|
|
24
|
+
export declare const PsFormTextField: <T extends FieldValues>({ asNumber, autoComplete, className, control, country, disabled, helperText, inputMode, isSuggested, kind, label, maxLength, name, placeholder, rules, suggestedLabel, type, }: PsFormTextFieldProps<T>) => import("react").JSX.Element;
|
|
@@ -12,12 +12,13 @@ const ps_text_input_1 = require("../../components/ps-text-input");
|
|
|
12
12
|
const ps_url_input_1 = require("../../components/ps-url-input");
|
|
13
13
|
const ps_form_text_kind_1 = require("../constants/ps-form-text-kind");
|
|
14
14
|
const ps_form_field_service_1 = require("../services/ps-form-field-service");
|
|
15
|
-
const PsFormTextField = ({ asNumber = false, autoComplete, className, control, country = '', disabled, helperText, inputMode, kind = ps_form_text_kind_1.PsFormTextKind.Text, label, maxLength, name, placeholder, rules, type, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => {
|
|
15
|
+
const PsFormTextField = ({ asNumber = false, autoComplete, className, control, country = '', disabled, helperText, inputMode, isSuggested, kind = ps_form_text_kind_1.PsFormTextKind.Text, label, maxLength, name, placeholder, rules, suggestedLabel, type, }) => ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: name, render: ({ field, fieldState }) => {
|
|
16
16
|
const shared = {
|
|
17
17
|
autoComplete,
|
|
18
18
|
className,
|
|
19
19
|
disabled,
|
|
20
20
|
helperText,
|
|
21
|
+
isSuggested,
|
|
21
22
|
label,
|
|
22
23
|
maxLength,
|
|
23
24
|
name: field.name,
|
|
@@ -25,6 +26,7 @@ const PsFormTextField = ({ asNumber = false, autoComplete, className, control, c
|
|
|
25
26
|
onChange: (event) => field.onChange(asNumber ? ps_form_field_service_1.PsFormFieldService.number(event.target.value) : event),
|
|
26
27
|
placeholder,
|
|
27
28
|
required: ps_form_field_service_1.PsFormFieldService.isRequired(rules),
|
|
29
|
+
suggestedLabel,
|
|
28
30
|
value: ps_form_field_service_1.PsFormFieldService.text(field.value),
|
|
29
31
|
};
|
|
30
32
|
return ((0, jsx_runtime_1.jsxs)(ps_form_control_1.PsFormControl, { errorText: ps_form_field_service_1.PsFormFieldService.error(fieldState.error), children: [kind === ps_form_text_kind_1.PsFormTextKind.Email ? (0, jsx_runtime_1.jsx)(ps_email_input_1.PsEmailInput, { ...shared }) : null, kind === ps_form_text_kind_1.PsFormTextKind.Url ? (0, jsx_runtime_1.jsx)(ps_url_input_1.PsUrlInput, { ...shared }) : null, kind === ps_form_text_kind_1.PsFormTextKind.Amount ? (0, jsx_runtime_1.jsx)(ps_amount_input_1.PsAmountInput, { ...shared }) : null, kind === ps_form_text_kind_1.PsFormTextKind.Percent ? (0, jsx_runtime_1.jsx)(ps_percent_input_1.PsPercentInput, { ...shared }) : null, kind === ps_form_text_kind_1.PsFormTextKind.PostalCode ? ((0, jsx_runtime_1.jsx)(ps_postal_code_input_1.PsPostalCodeInput, { ...shared, country: country })) : null, kind === ps_form_text_kind_1.PsFormTextKind.Text ? ((0, jsx_runtime_1.jsx)(ps_text_input_1.PsTextInput, { ...shared, inputMode: inputMode, type: type })) : null] }));
|
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export * from './services/ps-postal-code-service';
|
|
|
38
38
|
export * from './services/ps-select-option-service';
|
|
39
39
|
export * from './services/ps-text-format-service';
|
|
40
40
|
export * from './components/ps-required-mark';
|
|
41
|
+
export * from './components/ps-suggested-tag';
|
|
42
|
+
export * from './services/ps-suggested-tag-service';
|
|
41
43
|
export * from './components/ps-year-input';
|
|
42
44
|
export * from './constants/ps-year-input-config';
|
|
43
45
|
export * from './services/ps-year-input-service';
|
package/dist/index.js
CHANGED
|
@@ -54,6 +54,8 @@ __exportStar(require("./services/ps-postal-code-service"), exports);
|
|
|
54
54
|
__exportStar(require("./services/ps-select-option-service"), exports);
|
|
55
55
|
__exportStar(require("./services/ps-text-format-service"), exports);
|
|
56
56
|
__exportStar(require("./components/ps-required-mark"), exports);
|
|
57
|
+
__exportStar(require("./components/ps-suggested-tag"), exports);
|
|
58
|
+
__exportStar(require("./services/ps-suggested-tag-service"), exports);
|
|
57
59
|
__exportStar(require("./components/ps-year-input"), exports);
|
|
58
60
|
__exportStar(require("./constants/ps-year-input-config"), exports);
|
|
59
61
|
__exportStar(require("./services/ps-year-input-service"), exports);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsSuggestedTagService = void 0;
|
|
4
|
+
class PsSuggestedTagService {
|
|
5
|
+
static accessibleLabel(label, isSuggested, suggestedLabel) {
|
|
6
|
+
return isSuggested && suggestedLabel !== undefined ? `${label}, ${suggestedLabel}` : label;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.PsSuggestedTagService = PsSuggestedTagService;
|