@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
|
@@ -23,6 +23,7 @@ export interface PsCascaderInputProps {
|
|
|
23
23
|
preferredGroupKey?: string;
|
|
24
24
|
required?: boolean;
|
|
25
25
|
searchPlaceholder?: string;
|
|
26
|
+
suggestedLabel?: string;
|
|
26
27
|
value: string;
|
|
27
28
|
}
|
|
28
|
-
export declare const PsCascaderInput: ({ className, disabled, groups, helperText, hideLabel, isLoading, isSuggested, label, onChange, placeholder, preferredGroupKey, required, searchPlaceholder, value, }: PsCascaderInputProps) => import("react").JSX.Element;
|
|
29
|
+
export declare const PsCascaderInput: ({ className, disabled, groups, helperText, hideLabel, isLoading, isSuggested, label, onChange, placeholder, preferredGroupKey, required, searchPlaceholder, suggestedLabel, value, }: PsCascaderInputProps) => import("react").JSX.Element;
|
|
@@ -9,9 +9,11 @@ const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
|
9
9
|
const react_aria_components_1 = require("react-aria-components");
|
|
10
10
|
const ps_cascader_config_1 = require("../constants/ps-cascader-config");
|
|
11
11
|
const ps_cascader_service_1 = require("../services/ps-cascader-service");
|
|
12
|
+
const ps_suggested_tag_service_1 = require("../services/ps-suggested-tag-service");
|
|
12
13
|
const ps_field_skeleton_1 = require("./ps-field-skeleton");
|
|
13
14
|
const ps_required_mark_1 = require("./ps-required-mark");
|
|
14
|
-
const
|
|
15
|
+
const ps_suggested_tag_1 = require("./ps-suggested-tag");
|
|
16
|
+
const PsCascaderInput = ({ className, disabled, groups, helperText, hideLabel, isLoading = false, isSuggested = false, label, onChange, placeholder = 'Select an option', preferredGroupKey, required, searchPlaceholder = 'Search', suggestedLabel, value, }) => {
|
|
15
17
|
if (isLoading)
|
|
16
18
|
return (0, jsx_runtime_1.jsx)(ps_field_skeleton_1.PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
17
19
|
const zIndex = (0, ps_core_components_1.usePsLayerZIndex)(ps_design_system_1.PallasoftZIndex.Dropdown);
|
|
@@ -37,23 +39,25 @@ const PsCascaderInput = ({ className, disabled, groups, helperText, hideLabel, i
|
|
|
37
39
|
close();
|
|
38
40
|
};
|
|
39
41
|
const renderOption = (option, groupLabel, close) => ((0, jsx_runtime_1.jsxs)("button", { "aria-disabled": option.isDisabled, "aria-selected": option.value === value, className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring flex w-full items-start gap-2 rounded-ps-control px-3 py-2.5 text-left text-sm font-medium transition-colors', option.isDisabled
|
|
40
|
-
? 'cursor-not-allowed text-
|
|
42
|
+
? 'cursor-not-allowed text-subtle'
|
|
41
43
|
: option.value === value
|
|
42
44
|
? 'bg-primary/10 text-ink'
|
|
43
|
-
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), disabled: option.isDisabled, onClick: () => select(option.value, close), role: 'option', type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'flex h-5 w-4 shrink-0 items-center justify-center text-primary', children: option.value === value ? ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check })) : null }), (0, jsx_runtime_1.jsxs)("span", { className: 'min-w-0 flex-1', children: [(0, jsx_runtime_1.jsx)("span", { className: 'block break-words', children: option.label }), groupLabel ? ((0, jsx_runtime_1.jsx)("span", { className: 'mt-0.5 block break-words text-xs font-normal text-
|
|
44
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('block', className), children: [hideLabel ? null : ((0, jsx_runtime_1.jsxs)("span", { className: 'ps-input-label block', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })
|
|
45
|
+
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), disabled: option.isDisabled, onClick: () => select(option.value, close), role: 'option', type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'flex h-5 w-4 shrink-0 items-center justify-center text-primary', children: option.value === value ? ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check })) : null }), (0, jsx_runtime_1.jsxs)("span", { className: 'min-w-0 flex-1', children: [(0, jsx_runtime_1.jsx)("span", { className: 'block break-words', children: option.label }), groupLabel ? ((0, jsx_runtime_1.jsx)("span", { className: 'mt-0.5 block break-words text-xs font-normal text-muted', children: groupLabel })) : null, option.description ? ((0, jsx_runtime_1.jsx)("span", { className: 'mt-0.5 block break-words text-xs font-normal text-muted', children: option.description })) : null] })] }, option.value));
|
|
46
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('block', className), children: [hideLabel ? null : ((0, jsx_runtime_1.jsxs)("span", { className: 'ps-input-label block', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required }), (0, jsx_runtime_1.jsx)(ps_suggested_tag_1.PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] })), (0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { isOpen: isOpen, onOpenChange: open, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { "aria-label": hideLabel
|
|
47
|
+
? ps_suggested_tag_service_1.PsSuggestedTagService.accessibleLabel(label, isSuggested, suggestedLabel)
|
|
48
|
+
: undefined, className: ps_design_system_1.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'), isDisabled: disabled, children: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 flex-1 truncate', children: selected ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: 'truncate', children: selected.option.label }), ps_cascader_service_1.PsCascaderService.groupLabelFor(selected) === null ? null : ((0, jsx_runtime_1.jsx)("span", { className: 'ml-2 text-xs font-medium text-subtle', children: selected.group.label }))] })) : ((0, jsx_runtime_1.jsx)("span", { className: 'font-medium text-subtle', children: placeholder })) }), hideLabel ? (0, jsx_runtime_1.jsx)(ps_suggested_tag_1.PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel }) : null, (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute top-1/2 right-3 h-4 w-4 -translate-y-1/2 text-primary', iconKey: ps_icons_1.PsIconKey.Chevron })] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel w-[min(calc(100vw-2rem),32rem)] min-w-[var(--trigger-width)] outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: (0, jsx_runtime_1.jsx)(react_aria_components_1.Dialog, { "aria-label": label, className: 'flex flex-col outline-none', children: ({ close }) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: groups.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-1 px-4 py-8 text-center', children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-sm font-semibold text-ink', children: ps_cascader_config_1.PsCascaderConfig.emptyLabel }), (0, jsx_runtime_1.jsx)("p", { className: 'text-xs text-muted', children: ps_cascader_config_1.PsCascaderConfig.emptyDescription })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: 'border-b border-line p-2', children: (0, jsx_runtime_1.jsx)("input", { "aria-label": searchPlaceholder, autoFocus: true, className: 'ps-input-control ps-control-compact ps-focus-ring w-full text-sm', onChange: (event) => setQuery(event.target.value), placeholder: searchPlaceholder, type: 'search', value: query }) }), query.trim() === '' ? ((0, jsx_runtime_1.jsxs)("div", { className: 'grid grid-cols-1 sm:grid-cols-[minmax(0,11rem)_minmax(0,1fr)]', children: [(0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5 sm:border-r sm:border-line', activeGroupKey && groups.length > 1 ? 'hidden sm:block' : ''), children: groups.map((group) => {
|
|
45
49
|
const direct = ps_cascader_service_1.PsCascaderService.directOption(group);
|
|
46
50
|
if (direct !== null)
|
|
47
51
|
return ((0, jsx_runtime_1.jsxs)("button", { "aria-selected": direct.value === value, className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring flex w-full items-center gap-2 rounded-ps-control px-3 py-2.5 text-left text-sm font-semibold transition-colors', direct.isDisabled
|
|
48
|
-
? 'cursor-not-allowed text-
|
|
52
|
+
? 'cursor-not-allowed text-subtle'
|
|
49
53
|
: direct.value === value
|
|
50
54
|
? 'bg-primary/10 text-ink'
|
|
51
55
|
: 'text-ink/70 hover:bg-mist/60 hover:text-ink'), disabled: direct.isDisabled, onClick: () => select(direct.value, close), role: 'option', type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 flex-1 truncate', children: direct.label }), direct.value === value ? ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 shrink-0 text-primary', iconKey: ps_icons_1.PsIconKey.Check })) : null] }, group.key));
|
|
52
56
|
return ((0, jsx_runtime_1.jsxs)("button", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring flex w-full items-center gap-2 rounded-ps-control px-3 py-2.5 text-left text-sm font-semibold transition-colors', activeGroup?.key === group.key
|
|
53
57
|
? 'bg-mist text-ink'
|
|
54
|
-
: 'text-ink/70 hover:bg-mist/60 hover:text-ink'), onClick: () => setActiveGroupKey(group.key), type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 flex-1 truncate', children: group.label }), (0, jsx_runtime_1.jsx)("span", { className: 'text-xs font-medium text-
|
|
58
|
+
: 'text-ink/70 hover:bg-mist/60 hover:text-ink'), onClick: () => setActiveGroupKey(group.key), type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 flex-1 truncate', children: group.label }), (0, jsx_runtime_1.jsx)("span", { className: 'text-xs font-medium text-subtle', children: group.options.length }), (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 shrink-0 -rotate-90 text-ink/35', iconKey: ps_icons_1.PsIconKey.Chevron })] }, group.key));
|
|
55
59
|
}) }), (0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5', activeGroupKey && groups.length > 1 ? '' : 'hidden sm:block'), role: 'listbox', children: [groups.length > 1 ? ((0, jsx_runtime_1.jsxs)("button", { className: 'ps-focus-ring mb-1 flex w-full items-center gap-2 rounded-ps-control px-3 py-2 text-left text-xs font-semibold text-ink/60 hover:text-ink sm:hidden', onClick: () => setActiveGroupKey(null), type: 'button', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 rotate-90', iconKey: ps_icons_1.PsIconKey.Chevron }), "All groups"] })) : null, activeGroup
|
|
56
60
|
? activeGroup.options.map((option) => renderOption(option, null, close))
|
|
57
|
-
: null] })] })) : ((0, jsx_runtime_1.jsx)("div", { className: 'ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? ((0, jsx_runtime_1.jsx)("p", { className: 'px-3 py-6 text-center text-sm text-
|
|
61
|
+
: null] })] })) : ((0, jsx_runtime_1.jsx)("div", { className: 'ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? ((0, jsx_runtime_1.jsx)("p", { className: 'px-3 py-6 text-center text-sm text-muted', children: ps_cascader_config_1.PsCascaderConfig.noMatchesLabel })) : (matches.map((match) => renderOption(match.option, ps_cascader_service_1.PsCascaderService.groupLabelFor(match), close))) }))] })) })) }) })] }), helperText ? (0, jsx_runtime_1.jsx)("span", { className: 'ps-input-helper mt-2 block', children: helperText }) : null] }));
|
|
58
62
|
};
|
|
59
63
|
exports.PsCascaderInput = PsCascaderInput;
|
|
@@ -13,7 +13,7 @@ const PsCheckboxMatrix = ({ columns, defaultOpenGroupId = null, groups, isReadOn
|
|
|
13
13
|
const selected = ps_checkbox_matrix_service_1.PsCheckboxMatrixService.selectedCount(group, value);
|
|
14
14
|
const usedColumns = columns.filter((column) => group.rows.some((row) => row.cells.some((cell) => cell.columnId === column.id)));
|
|
15
15
|
const isComplete = ps_checkbox_matrix_service_1.PsCheckboxMatrixService.isGroupComplete(group, value);
|
|
16
|
-
return ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsAccordion, { isOpen: openGroupId === group.id, label: group.label, onToggle: () => setOpenGroupId(openGroupId === group.id ? null : group.id), trailing: (0, jsx_runtime_1.jsx)("span", { className: 'text-xs font-normal text-
|
|
16
|
+
return ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsAccordion, { isOpen: openGroupId === group.id, label: group.label, onToggle: () => setOpenGroupId(openGroupId === group.id ? null : group.id), trailing: (0, jsx_runtime_1.jsx)("span", { className: 'text-xs font-normal text-muted', children: labels.count(selected, total) }), children: (0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-3 px-4 pb-4', children: [(0, jsx_runtime_1.jsx)(ps_checkbox_1.PsCheckbox, { isDisabled: isReadOnly || ps_checkbox_matrix_service_1.PsCheckboxMatrixService.enabledValues(group).length === 0, isIndeterminate: selected > 0 && !isComplete, isSelected: isComplete, label: labels.selectGroup(group), onChange: (isSelected) => onChange(ps_checkbox_matrix_service_1.PsCheckboxMatrixService.toggleGroup(value, group, isSelected)), children: (0, jsx_runtime_1.jsx)("span", { className: 'text-sm font-medium text-ink', children: labels.selectGroup(group) }) }), (0, jsx_runtime_1.jsx)("div", { className: 'overflow-x-auto', children: (0, jsx_runtime_1.jsxs)("table", { className: 'w-full border-collapse text-sm', children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { className: 'text-xs text-muted', children: [(0, jsx_runtime_1.jsx)("th", { className: 'py-1.5 pr-3 text-left font-medium', scope: 'col', children: labels.rowHeading }), usedColumns.map((column) => ((0, jsx_runtime_1.jsx)("th", { className: 'w-14 px-1 py-1.5 text-center font-medium', scope: 'col', title: column.hint === null ? undefined : column.hint, children: column.label }, column.id)))] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: group.rows.map((row) => ((0, jsx_runtime_1.jsxs)("tr", { className: 'border-t border-line/70', children: [(0, jsx_runtime_1.jsx)("th", { className: 'py-2 pr-3 text-left font-normal text-ink', scope: 'row', children: row.label }), usedColumns.map((column) => {
|
|
17
17
|
const cell = row.cells.find((item) => item.columnId === column.id);
|
|
18
18
|
return ((0, jsx_runtime_1.jsx)("td", { className: 'px-1 py-2 text-center', children: cell === undefined ? null : ((0, jsx_runtime_1.jsx)("span", { className: 'inline-flex', title: cell.reason === null ? undefined : cell.reason, children: (0, jsx_runtime_1.jsx)(ps_checkbox_1.PsCheckbox, { isDisabled: isReadOnly || cell.isDisabled, isSelected: value.includes(cell.value), label: cell.reason === null
|
|
19
19
|
? labels.cell(row, column)
|
|
@@ -6,7 +6,13 @@ const react_aria_components_1 = require("react-aria-components");
|
|
|
6
6
|
const PsComboboxCloseBridge = ({ closeRef }) => {
|
|
7
7
|
const state = (0, react_1.useContext)(react_aria_components_1.ComboBoxStateContext);
|
|
8
8
|
(0, react_1.useEffect)(() => {
|
|
9
|
-
closeRef.current =
|
|
9
|
+
closeRef.current =
|
|
10
|
+
state === null
|
|
11
|
+
? null
|
|
12
|
+
: () => {
|
|
13
|
+
if (state.isOpen)
|
|
14
|
+
state.toggle();
|
|
15
|
+
};
|
|
10
16
|
}, [closeRef, state]);
|
|
11
17
|
return null;
|
|
12
18
|
};
|
|
@@ -8,6 +8,7 @@ export interface PsComboboxInputProps<T> {
|
|
|
8
8
|
inputValue?: string;
|
|
9
9
|
isDisabled?: boolean;
|
|
10
10
|
isLoading?: boolean;
|
|
11
|
+
isSuggested?: boolean;
|
|
11
12
|
items: T[];
|
|
12
13
|
label?: string;
|
|
13
14
|
menuTrigger?: 'focus' | 'input' | 'manual';
|
|
@@ -18,5 +19,6 @@ export interface PsComboboxInputProps<T> {
|
|
|
18
19
|
renderItem?: (item: T) => ReactNode;
|
|
19
20
|
required?: boolean;
|
|
20
21
|
selectedKey?: string | null;
|
|
22
|
+
suggestedLabel?: string;
|
|
21
23
|
}
|
|
22
|
-
export declare const PsComboboxInput: <T>({ className, emptyText, getItemKey, getItemLabel, hideLabel, inputValue, isDisabled, isLoading, items, label, menuTrigger, onInputChange, onScan, onSelectionChange, placeholder, renderItem, required, selectedKey, }: PsComboboxInputProps<T>) => import("react").JSX.Element;
|
|
24
|
+
export declare const PsComboboxInput: <T>({ className, emptyText, getItemKey, getItemLabel, hideLabel, inputValue, isDisabled, isLoading, isSuggested, items, label, menuTrigger, onInputChange, onScan, onSelectionChange, placeholder, renderItem, required, selectedKey, suggestedLabel, }: PsComboboxInputProps<T>) => import("react").JSX.Element;
|
|
@@ -7,16 +7,20 @@ const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
|
7
7
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
8
8
|
const react_aria_components_1 = require("react-aria-components");
|
|
9
9
|
const ps_combobox_input_service_1 = require("../services/ps-combobox-input-service");
|
|
10
|
+
const ps_suggested_tag_service_1 = require("../services/ps-suggested-tag-service");
|
|
10
11
|
const ps_combobox_close_bridge_1 = require("./ps-combobox-close-bridge");
|
|
11
12
|
const ps_combobox_scan_input_1 = require("./ps-combobox-scan-input");
|
|
12
13
|
const ps_required_mark_1 = require("./ps-required-mark");
|
|
13
|
-
const
|
|
14
|
+
const ps_suggested_tag_1 = require("./ps-suggested-tag");
|
|
15
|
+
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, }) => {
|
|
14
16
|
const itemsByKey = new Map(items.map((item) => [getItemKey(item), item]));
|
|
15
17
|
const closeRef = (0, react_1.useRef)(null);
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.ComboBox, { allowsEmptyCollection: true, "aria-label": hideLabel
|
|
18
|
+
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.ComboBox, { allowsEmptyCollection: true, "aria-label": hideLabel && label !== undefined
|
|
19
|
+
? ps_suggested_tag_service_1.PsSuggestedTagService.accessibleLabel(label, isSuggested, suggestedLabel)
|
|
20
|
+
: undefined, className: ps_design_system_1.PallasoftClassNameService.merge('block', className), defaultFilter: () => true, inputValue: inputValue, isDisabled: isDisabled, items: items, menuTrigger: menuTrigger, onInputChange: onInputChange, selectedKey: selectedKey, onSelectionChange: (key) => {
|
|
17
21
|
onSelectionChange?.(key === null ? null : ps_combobox_input_service_1.PsComboboxInputService.getItem(itemsByKey, key));
|
|
18
22
|
if (key !== null && closeRef.current !== null)
|
|
19
23
|
closeRef.current();
|
|
20
|
-
}, children: [(0, jsx_runtime_1.jsx)(ps_combobox_close_bridge_1.PsComboboxCloseBridge, { closeRef: closeRef }), label && !hideLabel ? ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Label, { className: 'ps-input-label', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] })) : null, (0, jsx_runtime_1.jsx)("span", { className: hideLabel || !label ? 'relative block' : 'relative mt-2 block', children: (0, jsx_runtime_1.jsx)(ps_combobox_scan_input_1.PsComboboxScanInput, { className: 'ps-input-control ps-focus-ring w-full text-sm font-semibold', onScan: onScan, placeholder: placeholder }) }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'w-[--trigger-width] rounded-2xl border border-line bg-surface p-1.5 shadow-lg', children: isLoading && items.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: 'flex items-center justify-center py-4', children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsSpinner, { label: 'Loading results', size: 'small' }) })) : ((0, jsx_runtime_1.jsx)(react_aria_components_1.ListBox, { "aria-busy": isLoading, className: 'max-h-72 overflow-y-auto outline-none', items: items, renderEmptyState: () => emptyText ? (0, jsx_runtime_1.jsx)("div", { className: 'px-3 py-2 text-sm text-
|
|
24
|
+
}, children: [(0, jsx_runtime_1.jsx)(ps_combobox_close_bridge_1.PsComboboxCloseBridge, { closeRef: closeRef }), label && !hideLabel ? ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Label, { className: 'ps-input-label', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required }), (0, jsx_runtime_1.jsx)(ps_suggested_tag_1.PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] })) : null, (0, jsx_runtime_1.jsx)("span", { className: hideLabel || !label ? 'relative block' : 'relative mt-2 block', children: (0, jsx_runtime_1.jsx)(ps_combobox_scan_input_1.PsComboboxScanInput, { className: 'ps-input-control ps-focus-ring w-full text-sm font-semibold', onScan: onScan, placeholder: placeholder }) }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'w-[--trigger-width] rounded-2xl border border-line bg-surface p-1.5 shadow-lg', children: isLoading && items.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: 'flex items-center justify-center py-4', children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsSpinner, { label: 'Loading results', size: 'small' }) })) : ((0, jsx_runtime_1.jsx)(react_aria_components_1.ListBox, { "aria-busy": isLoading, className: 'max-h-72 overflow-y-auto outline-none', items: items, renderEmptyState: () => emptyText ? (0, jsx_runtime_1.jsx)("div", { className: 'px-3 py-2 text-sm text-muted', children: emptyText }) : null, children: (item) => ((0, jsx_runtime_1.jsx)(react_aria_components_1.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) })) })) })] }));
|
|
21
25
|
};
|
|
22
26
|
exports.PsComboboxInput = PsComboboxInput;
|
|
@@ -5,6 +5,7 @@ export interface PsDateInputProps {
|
|
|
5
5
|
helperText?: string;
|
|
6
6
|
hideLabel?: boolean;
|
|
7
7
|
isLoading?: boolean;
|
|
8
|
+
isSuggested?: boolean;
|
|
8
9
|
label: string;
|
|
9
10
|
max?: string;
|
|
10
11
|
min?: string;
|
|
@@ -12,6 +13,7 @@ export interface PsDateInputProps {
|
|
|
12
13
|
onChange?: (value: string) => void;
|
|
13
14
|
placeholder?: string;
|
|
14
15
|
required?: boolean;
|
|
16
|
+
suggestedLabel?: string;
|
|
15
17
|
value?: string;
|
|
16
18
|
}
|
|
17
|
-
export declare const PsDateInput: ({ className, defaultValue, disabled, helperText, hideLabel, isLoading, label, max, min, name, onChange, placeholder, required, value, }: PsDateInputProps) => import("react").JSX.Element;
|
|
19
|
+
export declare const PsDateInput: ({ className, defaultValue, disabled, helperText, hideLabel, isLoading, isSuggested, label, max, min, name, onChange, placeholder, required, suggestedLabel, value, }: PsDateInputProps) => import("react").JSX.Element;
|
|
@@ -15,7 +15,8 @@ const ps_date_picker_fallback_1 = require("./ps-date-picker-fallback");
|
|
|
15
15
|
const ps_field_skeleton_1 = require("./ps-field-skeleton");
|
|
16
16
|
const ps_lazy_date_picker_1 = require("./ps-lazy-date-picker");
|
|
17
17
|
const ps_required_mark_1 = require("./ps-required-mark");
|
|
18
|
-
const
|
|
18
|
+
const ps_suggested_tag_1 = require("./ps-suggested-tag");
|
|
19
|
+
const PsDateInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, isSuggested = false, label, max, min, name, onChange, placeholder = ps_date_input_config_1.PsDateInputConfig.placeholder, required, suggestedLabel, value, }) => {
|
|
19
20
|
if (isLoading)
|
|
20
21
|
return (0, jsx_runtime_1.jsx)(ps_field_skeleton_1.PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
21
22
|
const inputId = (0, react_1.useId)();
|
|
@@ -45,6 +46,6 @@ const PsDateInput = ({ className, defaultValue, disabled, helperText, hideLabel,
|
|
|
45
46
|
onChange?.(nextValue);
|
|
46
47
|
};
|
|
47
48
|
const fallback = ((0, jsx_runtime_1.jsx)(ps_date_picker_fallback_1.PsDatePickerFallback, { disabled: disabled, id: inputId, placeholder: placeholder, required: required, text: ps_date_input_service_1.PsDateInputService.display(currentValue) }));
|
|
48
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('block', className), children: [(0, jsx_runtime_1.jsxs)("label", { className: hideLabel ? 'sr-only' : 'ps-input-label block', htmlFor: inputId, children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] }), (0, jsx_runtime_1.jsxs)("div", { className: hideLabel ? 'relative' : 'relative mt-2', children: [isHydrated ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: fallback, children: (0, jsx_runtime_1.jsx)(ps_lazy_date_picker_1.PsLazyDatePicker, { autoComplete: 'off', calendarClassName: ps_design_system_1.PallasoftClassNameService.merge('ps-floating-panel ps-datepicker', view === ps_calendar_view_1.PsCalendarView.day ? undefined : ps_date_input_config_1.PsDateInputConfig.pickingClassName), className: ps_date_picker_classes_1.PsDatePickerClasses.control, dateFormat: [...ps_date_input_config_1.PsDateInputConfig.inputFormats], disabled: disabled, id: inputId, maxDate: maxDate, minDate: minDate, onCalendarClose: () => setView(ps_calendar_view_1.PsCalendarView.day), onChange: handleChange, placeholderText: placeholder, popperClassName: 'ps-datepicker-popper', popperPlacement: 'bottom-start', popperProps: { strategy: 'fixed' }, portalId: portalId, renderCustomHeader: (headerProps) => ((0, jsx_runtime_1.jsx)(ps_calendar_header_1.PsCalendarHeader, { ...headerProps, maxDate: maxDate, minDate: minDate, onViewChange: setView, view: view })), required: required, selected: ps_date_input_service_1.PsDateInputService.parse(currentValue), showPopperArrow: false, wrapperClassName: ps_date_picker_classes_1.PsDatePickerClasses.wrapperOption }) })) : (fallback), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Calendar }), name ? (0, jsx_runtime_1.jsx)("input", { name: name, type: 'hidden', value: currentValue }) : null] }), helperText ? (0, jsx_runtime_1.jsx)("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
49
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('block', className), children: [(0, jsx_runtime_1.jsxs)("label", { className: hideLabel ? 'sr-only' : 'ps-input-label block', htmlFor: inputId, children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required }), (0, jsx_runtime_1.jsx)(ps_suggested_tag_1.PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] }), (0, jsx_runtime_1.jsxs)("div", { className: hideLabel ? 'relative' : 'relative mt-2', children: [isHydrated ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: fallback, children: (0, jsx_runtime_1.jsx)(ps_lazy_date_picker_1.PsLazyDatePicker, { autoComplete: 'off', calendarClassName: ps_design_system_1.PallasoftClassNameService.merge('ps-floating-panel ps-datepicker', view === ps_calendar_view_1.PsCalendarView.day ? undefined : ps_date_input_config_1.PsDateInputConfig.pickingClassName), className: ps_date_picker_classes_1.PsDatePickerClasses.control, dateFormat: [...ps_date_input_config_1.PsDateInputConfig.inputFormats], disabled: disabled, id: inputId, maxDate: maxDate, minDate: minDate, onCalendarClose: () => setView(ps_calendar_view_1.PsCalendarView.day), onChange: handleChange, placeholderText: placeholder, popperClassName: 'ps-datepicker-popper', popperPlacement: 'bottom-start', popperProps: { strategy: 'fixed' }, portalId: portalId, renderCustomHeader: (headerProps) => ((0, jsx_runtime_1.jsx)(ps_calendar_header_1.PsCalendarHeader, { ...headerProps, maxDate: maxDate, minDate: minDate, onViewChange: setView, view: view })), required: required, selected: ps_date_input_service_1.PsDateInputService.parse(currentValue), showPopperArrow: false, wrapperClassName: ps_date_picker_classes_1.PsDatePickerClasses.wrapperOption }) })) : (fallback), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Calendar }), name ? (0, jsx_runtime_1.jsx)("input", { name: name, type: 'hidden', value: currentValue }) : null] }), helperText ? (0, jsx_runtime_1.jsx)("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
49
50
|
};
|
|
50
51
|
exports.PsDateInput = PsDateInput;
|
|
@@ -45,11 +45,11 @@ const PsGroupedSwitcher = ({ allOption, ariaLabel, className, emptyText, getItem
|
|
|
45
45
|
setIsOpen(next);
|
|
46
46
|
if (!next)
|
|
47
47
|
setQuery('');
|
|
48
|
-
}, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { "aria-label": ariaLabel, className: ps_design_system_1.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: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 flex-1', children: renderSelected(isAllSelected ? null : selected) }), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Chevron })] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.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: (0, jsx_runtime_1.jsx)(react_aria_components_1.Dialog, { "aria-label": ariaLabel, className: 'flex max-h-[min(34rem,75vh)] flex-col outline-none', children: (0, jsx_runtime_1.jsxs)(react_aria_components_1.Autocomplete, { filter: () => true, inputValue: query, onInputChange: setQuery, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.SearchField, { "aria-label": searchPlaceholder, autoFocus: true, className: 'relative block border-b border-line p-2', children: [(0, jsx_runtime_1.jsx)(react_aria_components_1.Input, { className: 'ps-input-control ps-focus-ring w-full pl-10 text-sm font-semibold', placeholder: searchPlaceholder }), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Search })] }), (0, jsx_runtime_1.jsxs)(react_aria_components_1.ListBox, { "aria-label": ariaLabel, className: 'ps-scrollbar-hidden min-h-0 flex-1 overflow-y-auto p-1.5 outline-none', onSelectionChange: onSelectionChange, renderEmptyState: () => ((0, jsx_runtime_1.jsx)("div", { className: 'px-3 py-6 text-center text-sm text-
|
|
48
|
+
}, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { "aria-label": ariaLabel, className: ps_design_system_1.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: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 flex-1', children: renderSelected(isAllSelected ? null : selected) }), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Chevron })] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.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: (0, jsx_runtime_1.jsx)(react_aria_components_1.Dialog, { "aria-label": ariaLabel, className: 'flex max-h-[min(34rem,75vh)] flex-col outline-none', children: (0, jsx_runtime_1.jsxs)(react_aria_components_1.Autocomplete, { filter: () => true, inputValue: query, onInputChange: setQuery, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.SearchField, { "aria-label": searchPlaceholder, autoFocus: true, className: 'relative block border-b border-line p-2', children: [(0, jsx_runtime_1.jsx)(react_aria_components_1.Input, { className: 'ps-input-control ps-focus-ring w-full pl-10 text-sm font-semibold', placeholder: searchPlaceholder }), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Search })] }), (0, jsx_runtime_1.jsxs)(react_aria_components_1.ListBox, { "aria-label": ariaLabel, className: 'ps-scrollbar-hidden min-h-0 flex-1 overflow-y-auto p-1.5 outline-none', onSelectionChange: onSelectionChange, renderEmptyState: () => ((0, jsx_runtime_1.jsx)("div", { className: 'px-3 py-6 text-center text-sm text-muted', children: emptyText })), selectedKeys: [
|
|
49
49
|
isAllSelected
|
|
50
50
|
? ps_grouped_switcher_config_1.PsGroupedSwitcherConfig.allKey
|
|
51
51
|
: ps_grouped_switcher_service_1.PsGroupedSwitcherService.selectedOptionId(sections, selectedKey, getItemKey),
|
|
52
|
-
], selectionMode: 'single', children: [showAll ? ((0, jsx_runtime_1.jsx)(react_aria_components_1.ListBoxSection, { children: (0, jsx_runtime_1.jsx)(react_aria_components_1.ListBoxItem, { className: 'ps-floating-option min-h-12 text-ink', id: ps_grouped_switcher_config_1.PsGroupedSwitcherConfig.allKey, textValue: 'all', children: allOption.content }) })) : null, sections.map((section) => ((0, jsx_runtime_1.jsxs)(react_aria_components_1.ListBoxSection, { id: section.key, children: [(0, jsx_runtime_1.jsx)(react_aria_components_1.Header, { className: 'px-3 pb-1 pt-3 text-xs font-semibold tracking-wide text-
|
|
52
|
+
], selectionMode: 'single', children: [showAll ? ((0, jsx_runtime_1.jsx)(react_aria_components_1.ListBoxSection, { children: (0, jsx_runtime_1.jsx)(react_aria_components_1.ListBoxItem, { className: 'ps-floating-option min-h-12 text-ink', id: ps_grouped_switcher_config_1.PsGroupedSwitcherConfig.allKey, textValue: 'all', children: allOption.content }) })) : null, sections.map((section) => ((0, jsx_runtime_1.jsxs)(react_aria_components_1.ListBoxSection, { id: section.key, children: [(0, jsx_runtime_1.jsx)(react_aria_components_1.Header, { className: 'px-3 pb-1 pt-3 text-xs font-semibold tracking-wide text-muted uppercase', children: renderSectionLabel === undefined
|
|
53
53
|
? section.label
|
|
54
54
|
: renderSectionLabel(section.key, section.label) }), section.items.map((item) => {
|
|
55
55
|
const key = getItemKey(item);
|
|
@@ -23,7 +23,7 @@ const PsMultiSelectInput = ({ className, defaultValue, disabled, helperText, hid
|
|
|
23
23
|
setUncontrolledValue(nextValue);
|
|
24
24
|
onChange?.(nextValue);
|
|
25
25
|
};
|
|
26
|
-
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Select, { "aria-label": hideLabel ? label : undefined, className: ps_design_system_1.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 : ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Label, { className: 'ps-input-label block', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] })), (0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: ps_design_system_1.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: [(0, jsx_runtime_1.jsx)(react_aria_components_1.SelectValue, { className: 'flex min-w-0 flex-1 flex-wrap gap-1.5', children: ({ isPlaceholder }) => isPlaceholder ? ((0, jsx_runtime_1.jsx)("span", { className: 'font-medium text-
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Select, { "aria-label": hideLabel ? label : undefined, className: ps_design_system_1.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 : ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Label, { className: 'ps-input-label block', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] })), (0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: ps_design_system_1.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: [(0, jsx_runtime_1.jsx)(react_aria_components_1.SelectValue, { className: 'flex min-w-0 flex-1 flex-wrap gap-1.5', children: ({ isPlaceholder }) => isPlaceholder ? ((0, jsx_runtime_1.jsx)("span", { className: 'font-medium text-subtle', children: placeholder })) : (currentValue
|
|
27
27
|
.filter((selected) => labelByValue.has(selected))
|
|
28
28
|
.map((selected) => ((0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)("span", { className: 'truncate', children: labelByValue.get(selected) }) }, selected)))) }), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Chevron })] }), helperText ? ((0, jsx_runtime_1.jsx)(react_aria_components_1.Text, { className: 'ps-input-helper', slot: 'description', children: helperText })) : null, (0, jsx_runtime_1.jsx)(react_aria_components_1.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: (0, jsx_runtime_1.jsx)(react_aria_components_1.ListBox, { className: 'outline-none', items: options.map((option) => ({ ...option, id: option.value })), children: (option) => (0, jsx_runtime_1.jsx)(ps_select_option_item_1.PsSelectOptionItem, { option: option }) }) })] }));
|
|
29
29
|
};
|
|
@@ -12,5 +12,5 @@ const PsPercentInput = ({ className, onChange, ...props }) => ((0, jsx_runtime_1
|
|
|
12
12
|
event.target.value = normalised;
|
|
13
13
|
if (onChange)
|
|
14
14
|
onChange(event);
|
|
15
|
-
}, type: 'text' }), (0, jsx_runtime_1.jsx)("span", { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 bottom-3 text-sm text-
|
|
15
|
+
}, type: 'text' }), (0, jsx_runtime_1.jsx)("span", { "aria-hidden": 'true', className: 'pointer-events-none absolute right-3 bottom-3 text-sm text-muted', children: ps_text_format_config_1.PsTextFormatConfig.percentSuffix })] }));
|
|
16
16
|
exports.PsPercentInput = PsPercentInput;
|
|
@@ -37,9 +37,9 @@ const PsPhoneInput = ({ className, defaultCountry = ps_phone_input_config_1.PsPh
|
|
|
37
37
|
emit(national, code);
|
|
38
38
|
document.getElementById(inputId)?.focus();
|
|
39
39
|
};
|
|
40
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('block', className), children: [(0, jsx_runtime_1.jsxs)("label", { className: hideLabel ? 'sr-only' : 'ps-input-label', htmlFor: inputId, children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] }), (0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.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: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { isOpen: isOpen, onOpenChange: setIsOpen, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { "aria-label": ps_phone_input_config_1.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, (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-3.5 w-3.5 text-ink/45', iconKey: ps_icons_1.PsIconKey.Chevron })] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel w-72 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: (0, jsx_runtime_1.jsxs)(react_aria_components_1.Dialog, { "aria-label": ps_phone_input_config_1.PsPhoneInputConfig.countryLabel, className: 'flex flex-col outline-none', children: [(0, jsx_runtime_1.jsx)("div", { className: 'border-b border-line p-2', children: (0, jsx_runtime_1.jsx)("input", { "aria-label": ps_phone_input_config_1.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: ps_phone_input_config_1.PsPhoneInputConfig.searchPlaceholder, type: 'search', value: query }) }), (0, jsx_runtime_1.jsx)("ul", { className: 'ps-scrollbar-hidden max-h-64 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? ((0, jsx_runtime_1.jsx)("li", { className: 'px-3 py-2.5 text-sm text-
|
|
40
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('block', className), children: [(0, jsx_runtime_1.jsxs)("label", { className: hideLabel ? 'sr-only' : 'ps-input-label', htmlFor: inputId, children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] }), (0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.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: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { isOpen: isOpen, onOpenChange: setIsOpen, children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { "aria-label": ps_phone_input_config_1.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, (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-3.5 w-3.5 text-ink/45', iconKey: ps_icons_1.PsIconKey.Chevron })] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel w-72 outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: (0, jsx_runtime_1.jsxs)(react_aria_components_1.Dialog, { "aria-label": ps_phone_input_config_1.PsPhoneInputConfig.countryLabel, className: 'flex flex-col outline-none', children: [(0, jsx_runtime_1.jsx)("div", { className: 'border-b border-line p-2', children: (0, jsx_runtime_1.jsx)("input", { "aria-label": ps_phone_input_config_1.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: ps_phone_input_config_1.PsPhoneInputConfig.searchPlaceholder, type: 'search', value: query }) }), (0, jsx_runtime_1.jsx)("ul", { className: 'ps-scrollbar-hidden max-h-64 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? ((0, jsx_runtime_1.jsx)("li", { className: 'px-3 py-2.5 text-sm text-muted', children: ps_phone_input_config_1.PsPhoneInputConfig.emptyMessage })) : (matches.map((option) => ((0, jsx_runtime_1.jsx)("li", { role: 'none', children: (0, jsx_runtime_1.jsxs)("button", { "aria-selected": option.code === country, className: ps_design_system_1.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
|
|
41
41
|
? 'bg-primary/10 text-ink'
|
|
42
|
-
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), onClick: () => choose(option.code), role: 'option', type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 truncate', children: ps_phone_input_service_1.PsPhoneInputService.highlight(option.label, query).map((part, index) => part.isMatch ? ((0, jsx_runtime_1.jsx)("strong", { className: 'font-semibold text-ink', children: part.text }, index)) : ((0, jsx_runtime_1.jsx)("span", { children: part.text }, index))) }), (0, jsx_runtime_1.jsxs)("span", { className: 'shrink-0 text-xs text-
|
|
42
|
+
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), onClick: () => choose(option.code), role: 'option', type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { className: 'min-w-0 truncate', children: ps_phone_input_service_1.PsPhoneInputService.highlight(option.label, query).map((part, index) => part.isMatch ? ((0, jsx_runtime_1.jsx)("strong", { className: 'font-semibold text-ink', children: part.text }, index)) : ((0, jsx_runtime_1.jsx)("span", { children: part.text }, index))) }), (0, jsx_runtime_1.jsxs)("span", { className: 'shrink-0 text-xs text-muted', children: ["+", option.callingCode] })] }) }, option.code)))) })] }) })] }), (0, jsx_runtime_1.jsxs)("span", { "aria-hidden": 'true', className: 'flex items-center pl-3 text-sm text-subtle', children: [ps_phone_input_config_1.PsPhoneInputConfig.plus, ps_phone_input_service_1.PsPhoneInputService.callingCode(country)] }), (0, jsx_runtime_1.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: () => {
|
|
43
43
|
setIsTouched(true);
|
|
44
44
|
if (onBlur)
|
|
45
45
|
onBlur();
|
|
@@ -11,13 +11,15 @@ export interface PsSelectInputProps {
|
|
|
11
11
|
helperText?: string;
|
|
12
12
|
hideLabel?: boolean;
|
|
13
13
|
isLoading?: boolean;
|
|
14
|
+
isSuggested?: boolean;
|
|
14
15
|
label: string;
|
|
15
16
|
name?: string;
|
|
16
17
|
onChange?: (value: string) => void;
|
|
17
18
|
options: PsSelectOption[];
|
|
18
19
|
placeholder?: string;
|
|
19
20
|
required?: boolean;
|
|
21
|
+
suggestedLabel?: string;
|
|
20
22
|
controlSize?: keyof typeof PsInputSizeClassNames;
|
|
21
23
|
value?: string;
|
|
22
24
|
}
|
|
23
|
-
export declare const PsSelectInput: ({ className, defaultValue, disabled, helperText, hideLabel, isLoading, label, name, onChange, options, placeholder, required, controlSize, value, }: PsSelectInputProps) => import("react").JSX.Element;
|
|
25
|
+
export declare const PsSelectInput: ({ className, defaultValue, disabled, helperText, hideLabel, isLoading, isSuggested, label, name, onChange, options, placeholder, required, suggestedLabel, controlSize, value, }: PsSelectInputProps) => import("react").JSX.Element;
|
|
@@ -9,10 +9,12 @@ const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
|
9
9
|
const react_aria_components_1 = require("react-aria-components");
|
|
10
10
|
const ps_input_size_class_names_1 = require("../constants/ps-input-size-class-names");
|
|
11
11
|
const ps_select_input_service_1 = require("../services/ps-select-input-service");
|
|
12
|
+
const ps_suggested_tag_service_1 = require("../services/ps-suggested-tag-service");
|
|
12
13
|
const ps_field_skeleton_1 = require("./ps-field-skeleton");
|
|
13
14
|
const ps_required_mark_1 = require("./ps-required-mark");
|
|
14
15
|
const ps_select_option_item_1 = require("./ps-select-option-item");
|
|
15
|
-
const
|
|
16
|
+
const ps_suggested_tag_1 = require("./ps-suggested-tag");
|
|
17
|
+
const PsSelectInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, isSuggested = false, label, name, onChange, options, placeholder = 'Select an option', required, suggestedLabel, controlSize = 'default', value, }) => {
|
|
16
18
|
if (isLoading)
|
|
17
19
|
return (0, jsx_runtime_1.jsx)(ps_field_skeleton_1.PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
18
20
|
const [uncontrolledValue, setUncontrolledValue] = (0, react_1.useState)(() => ps_select_input_service_1.PsSelectInputService.getDefaultValue(defaultValue, options));
|
|
@@ -25,6 +27,8 @@ const PsSelectInput = ({ className, defaultValue, disabled, helperText, hideLabe
|
|
|
25
27
|
setUncontrolledValue(nextValue);
|
|
26
28
|
onChange?.(nextValue);
|
|
27
29
|
};
|
|
28
|
-
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Select, { "aria-label": hideLabel
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Select, { "aria-label": hideLabel
|
|
31
|
+
? ps_suggested_tag_service_1.PsSuggestedTagService.accessibleLabel(label, isSuggested, suggestedLabel)
|
|
32
|
+
: undefined, className: ps_design_system_1.PallasoftClassNameService.merge('block', className), isDisabled: disabled, isRequired: required, name: name, onChange: handleChange, placeholder: placeholder, value: hasOption ? currentValue : null, children: [hideLabel ? null : ((0, jsx_runtime_1.jsxs)(react_aria_components_1.Label, { className: 'ps-input-label block', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required }), (0, jsx_runtime_1.jsx)(ps_suggested_tag_1.PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] })), (0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: ps_design_system_1.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', ps_input_size_class_names_1.PsInputSizeClassNames[controlSize]), children: [(0, jsx_runtime_1.jsx)(react_aria_components_1.SelectValue, { className: 'min-w-0 flex-1 truncate', children: ({ isPlaceholder, selectedText }) => isPlaceholder ? ((0, jsx_runtime_1.jsx)("span", { className: 'font-medium text-subtle', children: placeholder })) : (selectedText) }), (0, jsx_runtime_1.jsx)(ps_icons_1.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: ps_icons_1.PsIconKey.Chevron })] }), helperText ? ((0, jsx_runtime_1.jsx)(react_aria_components_1.Text, { className: 'ps-input-helper', slot: 'description', children: helperText })) : null, (0, jsx_runtime_1.jsx)(react_aria_components_1.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: (0, jsx_runtime_1.jsx)(react_aria_components_1.ListBox, { className: 'outline-none', items: options.map((option) => ({ ...option, id: option.value })), children: (option) => (0, jsx_runtime_1.jsx)(ps_select_option_item_1.PsSelectOptionItem, { option: option }) }) })] }));
|
|
29
33
|
};
|
|
30
34
|
exports.PsSelectInput = PsSelectInput;
|
|
@@ -4,5 +4,5 @@ exports.PsSelectOptionItem = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
6
6
|
const react_aria_components_1 = require("react-aria-components");
|
|
7
|
-
const PsSelectOptionItem = ({ option }) => ((0, jsx_runtime_1.jsx)(react_aria_components_1.ListBoxItem, { className: 'ps-floating-option text-ink', id: option.value, textValue: option.label, children: ({ isSelected }) => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: 'flex h-4 w-4 shrink-0 items-center justify-center text-primary', children: isSelected ? ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check })) : null }), (0, jsx_runtime_1.jsxs)("span", { className: 'min-w-0 flex-1', children: [(0, jsx_runtime_1.jsx)("span", { className: 'block truncate', children: option.label }), option.description ? ((0, jsx_runtime_1.jsx)("span", { className: 'mt-0.5 block text-xs font-normal text-
|
|
7
|
+
const PsSelectOptionItem = ({ option }) => ((0, jsx_runtime_1.jsx)(react_aria_components_1.ListBoxItem, { className: 'ps-floating-option text-ink', id: option.value, textValue: option.label, children: ({ isSelected }) => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: 'flex h-4 w-4 shrink-0 items-center justify-center text-primary', children: isSelected ? ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check })) : null }), (0, jsx_runtime_1.jsxs)("span", { className: 'min-w-0 flex-1', children: [(0, jsx_runtime_1.jsx)("span", { className: 'block truncate', children: option.label }), option.description ? ((0, jsx_runtime_1.jsx)("span", { className: 'mt-0.5 block text-xs font-normal text-muted', children: option.description })) : null] })] })) }));
|
|
8
8
|
exports.PsSelectOptionItem = PsSelectOptionItem;
|
|
@@ -4,11 +4,13 @@ export interface PsSelectWithCreateProps {
|
|
|
4
4
|
createOptionLabel: string;
|
|
5
5
|
errorText?: string;
|
|
6
6
|
hideLabel?: boolean;
|
|
7
|
+
isSuggested?: boolean;
|
|
7
8
|
label: string;
|
|
8
9
|
onChange: (value: string) => void;
|
|
9
10
|
options: PsSelectOption[];
|
|
10
11
|
placeholder: string;
|
|
11
12
|
required?: boolean;
|
|
13
|
+
suggestedLabel?: string;
|
|
12
14
|
value: string;
|
|
13
15
|
}
|
|
14
|
-
export declare const PsSelectWithCreate: ({ createHref, createOptionLabel, errorText, hideLabel, label, onChange, options, placeholder, required, value, }: PsSelectWithCreateProps) => import("react").JSX.Element;
|
|
16
|
+
export declare const PsSelectWithCreate: ({ createHref, createOptionLabel, errorText, hideLabel, isSuggested, label, onChange, options, placeholder, required, suggestedLabel, value, }: PsSelectWithCreateProps) => import("react").JSX.Element;
|
|
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
const ps_select_with_create_config_1 = require("../constants/ps-select-with-create-config");
|
|
6
6
|
const ps_form_control_1 = require("./ps-form-control");
|
|
7
7
|
const ps_select_input_1 = require("./ps-select-input");
|
|
8
|
-
const PsSelectWithCreate = ({ createHref, createOptionLabel, errorText, hideLabel, label, onChange, options, placeholder, required, value, }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: errorText, children: (0, jsx_runtime_1.jsx)(ps_select_input_1.PsSelectInput, { hideLabel: hideLabel, label: label, onChange: (next) => {
|
|
8
|
+
const PsSelectWithCreate = ({ createHref, createOptionLabel, errorText, hideLabel, isSuggested, label, onChange, options, placeholder, required, suggestedLabel, value, }) => ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { errorText: errorText, children: (0, jsx_runtime_1.jsx)(ps_select_input_1.PsSelectInput, { hideLabel: hideLabel, isSuggested: isSuggested, label: label, onChange: (next) => {
|
|
9
9
|
if (next !== ps_select_with_create_config_1.PsSelectWithCreateConfig.createValue) {
|
|
10
10
|
onChange(next);
|
|
11
11
|
return;
|
|
@@ -14,5 +14,5 @@ const PsSelectWithCreate = ({ createHref, createOptionLabel, errorText, hideLabe
|
|
|
14
14
|
}, options: [
|
|
15
15
|
...options,
|
|
16
16
|
{ label: createOptionLabel, value: ps_select_with_create_config_1.PsSelectWithCreateConfig.createValue },
|
|
17
|
-
], placeholder: placeholder, required: required, value: value }) }));
|
|
17
|
+
], placeholder: placeholder, required: required, suggestedLabel: suggestedLabel, value: value }) }));
|
|
18
18
|
exports.PsSelectWithCreate = PsSelectWithCreate;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsSuggestedTag = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
7
|
+
const PsSuggestedTag = ({ className, isSuggested = false, label }) => isSuggested && label !== undefined ? ((0, jsx_runtime_1.jsxs)("span", { className: ps_design_system_1.PallasoftClassNameService.merge('ml-2 inline-flex shrink-0 items-center gap-1 align-middle text-xs font-medium text-muted', className), children: [(0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: ", " }), (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-3 w-3 text-primary', iconKey: ps_icons_1.PsIconKey.Spark }), label] })) : null;
|
|
8
|
+
exports.PsSuggestedTag = PsSuggestedTag;
|
|
@@ -32,7 +32,7 @@ const PsTagInput = ({ className, errorText, helperText, hideLabel, isDisabled =
|
|
|
32
32
|
return ((0, jsx_runtime_1.jsx)(ps_form_control_1.PsFormControl, { className: className, errorText: errorText, helperText: helperText, children: (0, jsx_runtime_1.jsxs)("label", { className: 'block', children: [(0, jsx_runtime_1.jsxs)("span", { className: hideLabel ? 'sr-only' : 'ps-input-label', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] }), (0, jsx_runtime_1.jsxs)("span", { className: ps_design_system_1.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) => ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsActiveFilterChip, { label: value, onRemove: () => {
|
|
33
33
|
if (!isDisabled)
|
|
34
34
|
onChange(ps_tag_input_service_1.PsTagInputService.remove(values, value));
|
|
35
|
-
}, removeLabel: removeLabel(value) }, value))), (0, jsx_runtime_1.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-
|
|
35
|
+
}, removeLabel: removeLabel(value) }, value))), (0, jsx_runtime_1.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) => {
|
|
36
36
|
const text = event.target.value;
|
|
37
37
|
if (text.includes(ps_tag_input_config_1.PsTagInputConfig.separator))
|
|
38
38
|
commit(text);
|
|
@@ -5,6 +5,8 @@ export interface PsTextInputProps extends InputHTMLAttributes<HTMLInputElement>
|
|
|
5
5
|
hideLabel?: boolean;
|
|
6
6
|
label: string;
|
|
7
7
|
isLoading?: boolean;
|
|
8
|
+
isSuggested?: boolean;
|
|
9
|
+
suggestedLabel?: string;
|
|
8
10
|
controlSize?: keyof typeof PsInputSizeClassNames;
|
|
9
11
|
}
|
|
10
|
-
export declare const PsTextInput: ({ className, defaultValue, disabled, helperText, hideLabel, isLoading, label, name, onChange, required, controlSize, type, value, ...props }: PsTextInputProps) => import("react").JSX.Element;
|
|
12
|
+
export declare const PsTextInput: ({ className, defaultValue, disabled, helperText, hideLabel, isLoading, isSuggested, label, name, onChange, required, suggestedLabel, controlSize, type, value, ...props }: PsTextInputProps) => import("react").JSX.Element;
|
|
@@ -7,14 +7,15 @@ const ps_input_size_class_names_1 = require("../constants/ps-input-size-class-na
|
|
|
7
7
|
const ps_date_input_1 = require("./ps-date-input");
|
|
8
8
|
const ps_field_skeleton_1 = require("./ps-field-skeleton");
|
|
9
9
|
const ps_required_mark_1 = require("./ps-required-mark");
|
|
10
|
-
const
|
|
10
|
+
const ps_suggested_tag_1 = require("./ps-suggested-tag");
|
|
11
|
+
const PsTextInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, isSuggested = false, label, name, onChange, required, suggestedLabel, controlSize = 'default', type, value, ...props }) => {
|
|
11
12
|
if (isLoading)
|
|
12
13
|
return (0, jsx_runtime_1.jsx)(ps_field_skeleton_1.PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
13
14
|
if (type === 'date') {
|
|
14
15
|
return ((0, jsx_runtime_1.jsx)(ps_date_input_1.PsDateInput, { className: className, defaultValue: typeof defaultValue === 'string' ? defaultValue : undefined, disabled: disabled, helperText: helperText, hideLabel: hideLabel, label: label, name: name, onChange: (nextValue) => onChange?.({
|
|
15
16
|
target: { name, value: nextValue },
|
|
16
|
-
}), required: required, value: typeof value === 'string' ? value : undefined }));
|
|
17
|
+
}), isSuggested: isSuggested, required: required, suggestedLabel: suggestedLabel, value: typeof value === 'string' ? value : undefined }));
|
|
17
18
|
}
|
|
18
|
-
return ((0, jsx_runtime_1.jsxs)("label", { className: 'block', children: [(0, jsx_runtime_1.jsxs)("span", { className: hideLabel ? 'sr-only' : 'ps-input-label', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required })] }), (0, jsx_runtime_1.jsx)("input", { className: ps_design_system_1.PallasoftClassNameService.merge(hideLabel ? 'ps-input-control' : 'ps-input-control mt-2', ps_input_size_class_names_1.PsInputSizeClassNames[controlSize], className), defaultValue: defaultValue, disabled: disabled, name: name, onChange: onChange, required: required, type: type, value: value, ...props }), helperText ? (0, jsx_runtime_1.jsx)("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
19
|
+
return ((0, jsx_runtime_1.jsxs)("label", { className: 'block', children: [(0, jsx_runtime_1.jsxs)("span", { className: hideLabel ? 'sr-only' : 'ps-input-label', children: [label, (0, jsx_runtime_1.jsx)(ps_required_mark_1.PsRequiredMark, { isRequired: required }), (0, jsx_runtime_1.jsx)(ps_suggested_tag_1.PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] }), (0, jsx_runtime_1.jsx)("input", { className: ps_design_system_1.PallasoftClassNameService.merge(hideLabel ? 'ps-input-control' : 'ps-input-control mt-2', ps_input_size_class_names_1.PsInputSizeClassNames[controlSize], className), defaultValue: defaultValue, disabled: disabled, name: name, onChange: onChange, required: required, type: type, value: value, ...props }), helperText ? (0, jsx_runtime_1.jsx)("span", { className: 'ps-input-helper', children: helperText }) : null] }));
|
|
19
20
|
};
|
|
20
21
|
exports.PsTextInput = PsTextInput;
|
|
@@ -15,6 +15,6 @@ export declare const PsPortableTextEditorConfig: {
|
|
|
15
15
|
readonly code: "rounded bg-ink/10 px-1 font-mono text-[0.9em]";
|
|
16
16
|
readonly link: "text-primary underline";
|
|
17
17
|
readonly orderedList: "list-decimal pl-6";
|
|
18
|
-
readonly placeholder: "before:pointer-events-none before:float-left before:h-0 before:text-
|
|
18
|
+
readonly placeholder: "before:pointer-events-none before:float-left before:h-0 before:text-subtle before:content-[attr(data-placeholder)]";
|
|
19
19
|
};
|
|
20
20
|
};
|
|
@@ -18,6 +18,6 @@ exports.PsPortableTextEditorConfig = {
|
|
|
18
18
|
code: 'rounded bg-ink/10 px-1 font-mono text-[0.9em]',
|
|
19
19
|
link: 'text-primary underline',
|
|
20
20
|
orderedList: 'list-decimal pl-6',
|
|
21
|
-
placeholder: 'before:pointer-events-none before:float-left before:h-0 before:text-
|
|
21
|
+
placeholder: 'before:pointer-events-none before:float-left before:h-0 before:text-subtle before:content-[attr(data-placeholder)]',
|
|
22
22
|
},
|
|
23
23
|
};
|
|
@@ -6,9 +6,11 @@ import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
|
6
6
|
import { Button, Dialog, DialogTrigger, Popover } from 'react-aria-components';
|
|
7
7
|
import { PsCascaderConfig } from '../constants/ps-cascader-config';
|
|
8
8
|
import { PsCascaderService } from '../services/ps-cascader-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 { PsSuggestedTag } from './ps-suggested-tag';
|
|
13
|
+
export const PsCascaderInput = ({ className, disabled, groups, helperText, hideLabel, isLoading = false, isSuggested = false, label, onChange, placeholder = 'Select an option', preferredGroupKey, required, searchPlaceholder = 'Search', suggestedLabel, value, }) => {
|
|
12
14
|
if (isLoading)
|
|
13
15
|
return _jsx(PsFieldSkeleton, { className: className, hideLabel: hideLabel, label: label });
|
|
14
16
|
const zIndex = usePsLayerZIndex(PallasoftZIndex.Dropdown);
|
|
@@ -34,22 +36,24 @@ export const PsCascaderInput = ({ className, disabled, groups, helperText, hideL
|
|
|
34
36
|
close();
|
|
35
37
|
};
|
|
36
38
|
const renderOption = (option, groupLabel, close) => (_jsxs("button", { "aria-disabled": option.isDisabled, "aria-selected": option.value === value, className: PallasoftClassNameService.merge('ps-focus-ring flex w-full items-start gap-2 rounded-ps-control px-3 py-2.5 text-left text-sm font-medium transition-colors', option.isDisabled
|
|
37
|
-
? 'cursor-not-allowed text-
|
|
39
|
+
? 'cursor-not-allowed text-subtle'
|
|
38
40
|
: option.value === value
|
|
39
41
|
? 'bg-primary/10 text-ink'
|
|
40
|
-
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), disabled: option.isDisabled, onClick: () => select(option.value, close), role: 'option', type: 'button', children: [_jsx("span", { className: 'flex h-5 w-4 shrink-0 items-center justify-center text-primary', children: option.value === value ? (_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 break-words', children: option.label }), groupLabel ? (_jsx("span", { className: 'mt-0.5 block break-words text-xs font-normal text-
|
|
41
|
-
return (_jsxs("div", { className: PallasoftClassNameService.merge('block', className), children: [hideLabel ? null : (_jsxs("span", { className: 'ps-input-label block', children: [label, _jsx(PsRequiredMark, { isRequired: required })
|
|
42
|
+
: 'text-ink/80 hover:bg-mist/60 hover:text-ink'), disabled: option.isDisabled, onClick: () => select(option.value, close), role: 'option', type: 'button', children: [_jsx("span", { className: 'flex h-5 w-4 shrink-0 items-center justify-center text-primary', children: option.value === value ? (_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 break-words', children: option.label }), groupLabel ? (_jsx("span", { className: 'mt-0.5 block break-words text-xs font-normal text-muted', children: groupLabel })) : null, option.description ? (_jsx("span", { className: 'mt-0.5 block break-words text-xs font-normal text-muted', children: option.description })) : null] })] }, option.value));
|
|
43
|
+
return (_jsxs("div", { className: PallasoftClassNameService.merge('block', className), children: [hideLabel ? null : (_jsxs("span", { className: 'ps-input-label block', children: [label, _jsx(PsRequiredMark, { isRequired: required }), _jsx(PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel })] })), _jsxs(DialogTrigger, { isOpen: isOpen, onOpenChange: open, children: [_jsxs(Button, { "aria-label": hideLabel
|
|
44
|
+
? PsSuggestedTagService.accessibleLabel(label, isSuggested, suggestedLabel)
|
|
45
|
+
: undefined, 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'), isDisabled: disabled, children: [_jsx("span", { className: 'min-w-0 flex-1 truncate', children: selected ? (_jsxs(_Fragment, { children: [_jsx("span", { className: 'truncate', children: selected.option.label }), PsCascaderService.groupLabelFor(selected) === null ? null : (_jsx("span", { className: 'ml-2 text-xs font-medium text-subtle', children: selected.group.label }))] })) : (_jsx("span", { className: 'font-medium text-subtle', children: placeholder })) }), hideLabel ? _jsx(PsSuggestedTag, { isSuggested: isSuggested, label: suggestedLabel }) : null, _jsx(PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute top-1/2 right-3 h-4 w-4 -translate-y-1/2 text-primary', iconKey: PsIconKey.Chevron })] }), _jsx(Popover, { className: 'ps-floating-panel w-[min(calc(100vw-2rem),32rem)] min-w-[var(--trigger-width)] outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsx(Dialog, { "aria-label": label, className: 'flex flex-col outline-none', children: ({ close }) => (_jsx(_Fragment, { children: groups.length === 0 ? (_jsxs("div", { className: 'flex flex-col gap-1 px-4 py-8 text-center', children: [_jsx("p", { className: 'text-sm font-semibold text-ink', children: PsCascaderConfig.emptyLabel }), _jsx("p", { className: 'text-xs text-muted', children: PsCascaderConfig.emptyDescription })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: 'border-b border-line p-2', children: _jsx("input", { "aria-label": searchPlaceholder, autoFocus: true, className: 'ps-input-control ps-control-compact ps-focus-ring w-full text-sm', onChange: (event) => setQuery(event.target.value), placeholder: searchPlaceholder, type: 'search', value: query }) }), query.trim() === '' ? (_jsxs("div", { className: 'grid grid-cols-1 sm:grid-cols-[minmax(0,11rem)_minmax(0,1fr)]', children: [_jsx("div", { className: PallasoftClassNameService.merge('ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5 sm:border-r sm:border-line', activeGroupKey && groups.length > 1 ? 'hidden sm:block' : ''), children: groups.map((group) => {
|
|
42
46
|
const direct = PsCascaderService.directOption(group);
|
|
43
47
|
if (direct !== null)
|
|
44
48
|
return (_jsxs("button", { "aria-selected": direct.value === value, className: PallasoftClassNameService.merge('ps-focus-ring flex w-full items-center gap-2 rounded-ps-control px-3 py-2.5 text-left text-sm font-semibold transition-colors', direct.isDisabled
|
|
45
|
-
? 'cursor-not-allowed text-
|
|
49
|
+
? 'cursor-not-allowed text-subtle'
|
|
46
50
|
: direct.value === value
|
|
47
51
|
? 'bg-primary/10 text-ink'
|
|
48
52
|
: 'text-ink/70 hover:bg-mist/60 hover:text-ink'), disabled: direct.isDisabled, onClick: () => select(direct.value, close), role: 'option', type: 'button', children: [_jsx("span", { className: 'min-w-0 flex-1 truncate', children: direct.label }), direct.value === value ? (_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 shrink-0 text-primary', iconKey: PsIconKey.Check })) : null] }, group.key));
|
|
49
53
|
return (_jsxs("button", { className: PallasoftClassNameService.merge('ps-focus-ring flex w-full items-center gap-2 rounded-ps-control px-3 py-2.5 text-left text-sm font-semibold transition-colors', activeGroup?.key === group.key
|
|
50
54
|
? 'bg-mist text-ink'
|
|
51
|
-
: 'text-ink/70 hover:bg-mist/60 hover:text-ink'), onClick: () => setActiveGroupKey(group.key), type: 'button', children: [_jsx("span", { className: 'min-w-0 flex-1 truncate', children: group.label }), _jsx("span", { className: 'text-xs font-medium text-
|
|
55
|
+
: 'text-ink/70 hover:bg-mist/60 hover:text-ink'), onClick: () => setActiveGroupKey(group.key), type: 'button', children: [_jsx("span", { className: 'min-w-0 flex-1 truncate', children: group.label }), _jsx("span", { className: 'text-xs font-medium text-subtle', children: group.options.length }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 shrink-0 -rotate-90 text-ink/35', iconKey: PsIconKey.Chevron })] }, group.key));
|
|
52
56
|
}) }), _jsxs("div", { className: PallasoftClassNameService.merge('ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5', activeGroupKey && groups.length > 1 ? '' : 'hidden sm:block'), role: 'listbox', children: [groups.length > 1 ? (_jsxs("button", { className: 'ps-focus-ring mb-1 flex w-full items-center gap-2 rounded-ps-control px-3 py-2 text-left text-xs font-semibold text-ink/60 hover:text-ink sm:hidden', onClick: () => setActiveGroupKey(null), type: 'button', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 rotate-90', iconKey: PsIconKey.Chevron }), "All groups"] })) : null, activeGroup
|
|
53
57
|
? activeGroup.options.map((option) => renderOption(option, null, close))
|
|
54
|
-
: null] })] })) : (_jsx("div", { className: 'ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? (_jsx("p", { className: 'px-3 py-6 text-center text-sm text-
|
|
58
|
+
: null] })] })) : (_jsx("div", { className: 'ps-scrollbar-hidden max-h-72 overflow-y-auto p-1.5', role: 'listbox', children: matches.length === 0 ? (_jsx("p", { className: 'px-3 py-6 text-center text-sm text-muted', children: PsCascaderConfig.noMatchesLabel })) : (matches.map((match) => renderOption(match.option, PsCascaderService.groupLabelFor(match), close))) }))] })) })) }) })] }), helperText ? _jsx("span", { className: 'ps-input-helper mt-2 block', children: helperText }) : null] }));
|
|
55
59
|
};
|
|
@@ -10,7 +10,7 @@ export const PsCheckboxMatrix = ({ columns, defaultOpenGroupId = null, groups, i
|
|
|
10
10
|
const selected = PsCheckboxMatrixService.selectedCount(group, value);
|
|
11
11
|
const usedColumns = columns.filter((column) => group.rows.some((row) => row.cells.some((cell) => cell.columnId === column.id)));
|
|
12
12
|
const isComplete = PsCheckboxMatrixService.isGroupComplete(group, value);
|
|
13
|
-
return (_jsx(PsAccordion, { isOpen: openGroupId === group.id, label: group.label, onToggle: () => setOpenGroupId(openGroupId === group.id ? null : group.id), trailing: _jsx("span", { className: 'text-xs font-normal text-
|
|
13
|
+
return (_jsx(PsAccordion, { isOpen: openGroupId === group.id, label: group.label, onToggle: () => setOpenGroupId(openGroupId === group.id ? null : group.id), trailing: _jsx("span", { className: 'text-xs font-normal text-muted', children: labels.count(selected, total) }), children: _jsxs("div", { className: 'flex flex-col gap-3 px-4 pb-4', children: [_jsx(PsCheckbox, { isDisabled: isReadOnly || PsCheckboxMatrixService.enabledValues(group).length === 0, isIndeterminate: selected > 0 && !isComplete, isSelected: isComplete, label: labels.selectGroup(group), onChange: (isSelected) => onChange(PsCheckboxMatrixService.toggleGroup(value, group, isSelected)), children: _jsx("span", { className: 'text-sm font-medium text-ink', children: labels.selectGroup(group) }) }), _jsx("div", { className: 'overflow-x-auto', children: _jsxs("table", { className: 'w-full border-collapse text-sm', children: [_jsx("thead", { children: _jsxs("tr", { className: 'text-xs text-muted', children: [_jsx("th", { className: 'py-1.5 pr-3 text-left font-medium', scope: 'col', children: labels.rowHeading }), usedColumns.map((column) => (_jsx("th", { className: 'w-14 px-1 py-1.5 text-center font-medium', scope: 'col', title: column.hint === null ? undefined : column.hint, children: column.label }, column.id)))] }) }), _jsx("tbody", { children: group.rows.map((row) => (_jsxs("tr", { className: 'border-t border-line/70', children: [_jsx("th", { className: 'py-2 pr-3 text-left font-normal text-ink', scope: 'row', children: row.label }), usedColumns.map((column) => {
|
|
14
14
|
const cell = row.cells.find((item) => item.columnId === column.id);
|
|
15
15
|
return (_jsx("td", { className: 'px-1 py-2 text-center', children: cell === undefined ? null : (_jsx("span", { className: 'inline-flex', title: cell.reason === null ? undefined : cell.reason, children: _jsx(PsCheckbox, { isDisabled: isReadOnly || cell.isDisabled, isSelected: value.includes(cell.value), label: cell.reason === null
|
|
16
16
|
? labels.cell(row, column)
|