@pallasoft/ps-input-components 3.9.1 → 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.
Files changed (60) hide show
  1. package/dist/components/ps-cascader-input.d.ts +2 -1
  2. package/dist/components/ps-cascader-input.js +11 -7
  3. package/dist/components/ps-checkbox-matrix.js +1 -1
  4. package/dist/components/ps-combobox-input.d.ts +3 -1
  5. package/dist/components/ps-combobox-input.js +7 -3
  6. package/dist/components/ps-date-input.d.ts +3 -1
  7. package/dist/components/ps-date-input.js +3 -2
  8. package/dist/components/ps-grouped-switcher.js +2 -2
  9. package/dist/components/ps-multi-select-input.js +1 -1
  10. package/dist/components/ps-percent-input.js +1 -1
  11. package/dist/components/ps-phone-input.js +2 -2
  12. package/dist/components/ps-select-input.d.ts +3 -1
  13. package/dist/components/ps-select-input.js +6 -2
  14. package/dist/components/ps-select-option-item.js +1 -1
  15. package/dist/components/ps-select-with-create.d.ts +3 -1
  16. package/dist/components/ps-select-with-create.js +2 -2
  17. package/dist/components/ps-suggested-tag.d.ts +6 -0
  18. package/dist/components/ps-suggested-tag.js +8 -0
  19. package/dist/components/ps-tag-input.js +1 -1
  20. package/dist/components/ps-text-input.d.ts +3 -1
  21. package/dist/components/ps-text-input.js +4 -3
  22. package/dist/constants/ps-portable-text-editor-config.d.ts +1 -1
  23. package/dist/constants/ps-portable-text-editor-config.js +1 -1
  24. package/dist/esm/components/ps-cascader-input.js +11 -7
  25. package/dist/esm/components/ps-checkbox-matrix.js +1 -1
  26. package/dist/esm/components/ps-combobox-input.js +7 -3
  27. package/dist/esm/components/ps-date-input.js +3 -2
  28. package/dist/esm/components/ps-grouped-switcher.js +2 -2
  29. package/dist/esm/components/ps-multi-select-input.js +1 -1
  30. package/dist/esm/components/ps-percent-input.js +1 -1
  31. package/dist/esm/components/ps-phone-input.js +2 -2
  32. package/dist/esm/components/ps-select-input.js +6 -2
  33. package/dist/esm/components/ps-select-option-item.js +1 -1
  34. package/dist/esm/components/ps-select-with-create.js +2 -2
  35. package/dist/esm/components/ps-suggested-tag.js +4 -0
  36. package/dist/esm/components/ps-tag-input.js +1 -1
  37. package/dist/esm/components/ps-text-input.js +4 -3
  38. package/dist/esm/constants/ps-portable-text-editor-config.js +1 -1
  39. package/dist/esm/form/components/ps-form-cascader-field.js +1 -1
  40. package/dist/esm/form/components/ps-form-date-field.js +1 -1
  41. package/dist/esm/form/components/ps-form-money-field.js +2 -2
  42. package/dist/esm/form/components/ps-form-select-field.js +2 -2
  43. package/dist/esm/form/components/ps-form-text-field.js +3 -1
  44. package/dist/esm/index.js +2 -0
  45. package/dist/esm/services/ps-suggested-tag-service.js +5 -0
  46. package/dist/form/components/ps-form-cascader-field.d.ts +3 -1
  47. package/dist/form/components/ps-form-cascader-field.js +1 -1
  48. package/dist/form/components/ps-form-date-field.d.ts +3 -1
  49. package/dist/form/components/ps-form-date-field.js +1 -1
  50. package/dist/form/components/ps-form-money-field.d.ts +3 -1
  51. package/dist/form/components/ps-form-money-field.js +2 -2
  52. package/dist/form/components/ps-form-select-field.d.ts +3 -1
  53. package/dist/form/components/ps-form-select-field.js +2 -2
  54. package/dist/form/components/ps-form-text-field.d.ts +3 -1
  55. package/dist/form/components/ps-form-text-field.js +3 -1
  56. package/dist/index.d.ts +2 -0
  57. package/dist/index.js +2 -0
  58. package/dist/services/ps-suggested-tag-service.d.ts +3 -0
  59. package/dist/services/ps-suggested-tag-service.js +9 -0
  60. 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 PsCascaderInput = ({ className, disabled, groups, helperText, hideLabel, isLoading = false, isSuggested = false, label, onChange, placeholder = 'Select an option', preferredGroupKey, required, searchPlaceholder = 'Search', value, }) => {
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-ink/40'
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-ink/50', children: groupLabel })) : null, option.description ? ((0, jsx_runtime_1.jsx)("span", { className: 'mt-0.5 block break-words text-xs font-normal text-ink/55', children: option.description })) : null] })] }, option.value));
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 })] })), (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 ? label : 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', isSuggested ? 'border-dashed border-primary/60 bg-primary/5' : ''), 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-ink/45', children: selected.group.label }))] })) : ((0, jsx_runtime_1.jsx)("span", { className: 'font-medium text-ink/45', children: placeholder })) }), (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-ink/55', 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
+ : '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-ink/40'
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-ink/45', 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));
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-ink/55', 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] }));
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-ink/55', 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-ink/55', 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) => {
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)
@@ -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 PsComboboxInput = ({ className, emptyText, getItemKey, getItemLabel, hideLabel = false, inputValue, isDisabled = false, isLoading = false, items, label, menuTrigger = 'input', onInputChange, onScan, onSelectionChange, placeholder, renderItem, required, selectedKey, }) => {
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 ? label : 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) => {
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-ink/55', 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) })) })) })] }));
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 PsDateInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, label, max, min, name, onChange, placeholder = ps_date_input_config_1.PsDateInputConfig.placeholder, required, value, }) => {
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-ink/55', children: emptyText })), selectedKeys: [
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-ink/50 uppercase', children: renderSectionLabel === undefined
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-ink/45', children: placeholder })) : (currentValue
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-ink/50', children: ps_text_format_config_1.PsTextFormatConfig.percentSuffix })] }));
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-ink/50', 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
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-ink/50', children: ["+", option.callingCode] })] }) }, option.code)))) })] }) })] }), (0, jsx_runtime_1.jsxs)("span", { "aria-hidden": 'true', className: 'flex items-center pl-3 text-sm text-ink/45', 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: () => {
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 PsSelectInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, label, name, onChange, options, placeholder = 'Select an option', required, controlSize = 'default', value, }) => {
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 ? label : 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.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-ink/45', 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 }) }) })] }));
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-ink/55', children: option.description })) : null] })] })) }));
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,6 @@
1
+ export interface PsSuggestedTagProps {
2
+ className?: string;
3
+ isSuggested?: boolean;
4
+ label?: string;
5
+ }
6
+ export declare const PsSuggestedTag: ({ className, isSuggested, label }: PsSuggestedTagProps) => import("react").JSX.Element | null;
@@ -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-ink/45 disabled:cursor-not-allowed', disabled: isDisabled || isFull, name: name, onBlur: () => commit(draft), onChange: (event) => {
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 PsTextInput = ({ className, defaultValue, disabled, helperText, hideLabel, isLoading = false, label, name, onChange, required, controlSize = 'default', type, value, ...props }) => {
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-ink/45 before:content-[attr(data-placeholder)]";
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-ink/45 before:content-[attr(data-placeholder)]',
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
- export const PsCascaderInput = ({ className, disabled, groups, helperText, hideLabel, isLoading = false, isSuggested = false, label, onChange, placeholder = 'Select an option', preferredGroupKey, required, searchPlaceholder = 'Search', value, }) => {
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-ink/40'
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-ink/50', children: groupLabel })) : null, option.description ? (_jsx("span", { className: 'mt-0.5 block break-words text-xs font-normal text-ink/55', children: option.description })) : null] })] }, option.value));
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 })] })), _jsxs(DialogTrigger, { isOpen: isOpen, onOpenChange: open, children: [_jsxs(Button, { "aria-label": hideLabel ? label : 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', isSuggested ? 'border-dashed border-primary/60 bg-primary/5' : ''), 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-ink/45', children: selected.group.label }))] })) : (_jsx("span", { className: 'font-medium text-ink/45', children: placeholder })) }), _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-ink/55', 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
+ : '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-ink/40'
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-ink/45', 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));
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-ink/55', 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] }));
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-ink/55', 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-ink/55', 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) => {
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)