@ryuzaki13/react-foundation-ui 1.0.5 → 1.0.7

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 (106) hide show
  1. package/dist/advanced-search/index.js +3 -3
  2. package/dist/chunks/{DateInput--tfofQ2x.js → DateInput-CaKGXluL.js} +2 -2
  3. package/dist/chunks/{DateInput--tfofQ2x.js.map → DateInput-CaKGXluL.js.map} +1 -1
  4. package/dist/chunks/{DropZone-kJfbZU5g.js → DropZone-DdFdnC9X.js} +2 -2
  5. package/dist/chunks/{DropZone-kJfbZU5g.js.map → DropZone-DdFdnC9X.js.map} +1 -1
  6. package/dist/chunks/{Input-BmjlpA09.js → Input-BYUl3UFn.js} +2 -4
  7. package/dist/chunks/{Input-BmjlpA09.js.map → Input-BYUl3UFn.js.map} +1 -1
  8. package/dist/chunks/{InputDateTime-CxfAFe2L.js → InputDateTime-DBkWb0lk.js} +2 -2
  9. package/dist/chunks/{InputDateTime-CxfAFe2L.js.map → InputDateTime-DBkWb0lk.js.map} +1 -1
  10. package/dist/chunks/{InputFile-CyZu__B_.js → InputFile-Bo3CN73O.js} +2 -2
  11. package/dist/chunks/{InputFile-CyZu__B_.js.map → InputFile-Bo3CN73O.js.map} +1 -1
  12. package/dist/chunks/{InputFiles-CrTJV27R.js → InputFiles-gIxOPv5y.js} +2 -2
  13. package/dist/chunks/{InputFiles-CrTJV27R.js.map → InputFiles-gIxOPv5y.js.map} +1 -1
  14. package/dist/chunks/{InputImage-Cw8rPYQu.js → InputImage-k4l1J_tm.js} +2 -2
  15. package/dist/chunks/{InputImage-Cw8rPYQu.js.map → InputImage-k4l1J_tm.js.map} +1 -1
  16. package/dist/chunks/{MultiSelect-D1XYuwH1.js → MultiSelect-B0nfMSpS.js} +2 -2
  17. package/dist/chunks/{MultiSelect-D1XYuwH1.js.map → MultiSelect-B0nfMSpS.js.map} +1 -1
  18. package/dist/chunks/{PresetRangeDateInput-CapirptQ.js → PresetRangeDateInput-C5HqkOCG.js} +2 -2
  19. package/dist/chunks/{PresetRangeDateInput-CapirptQ.js.map → PresetRangeDateInput-C5HqkOCG.js.map} +1 -1
  20. package/dist/chunks/{Select-BJ5OqTe7.js → Select-B6kxgxK2.js} +2 -2
  21. package/dist/chunks/{Select-BJ5OqTe7.js.map → Select-B6kxgxK2.js.map} +1 -1
  22. package/dist/chunks/{SerializableSelect-CNe728Qa.js → SerializableSelect-CVGFjCGK.js} +2 -2
  23. package/dist/chunks/{SerializableSelect-CNe728Qa.js.map → SerializableSelect-CVGFjCGK.js.map} +1 -1
  24. package/dist/chunks/{SingleDateTimeInput-BmeuVGQT.js → SingleDateTimeInput-D2fDMQnI.js} +2 -2
  25. package/dist/chunks/{SingleDateTimeInput-BmeuVGQT.js.map → SingleDateTimeInput-D2fDMQnI.js.map} +1 -1
  26. package/dist/chunks/{StateSelect-ujAre258.js → StateSelect-CEp7kGGg.js} +2 -2
  27. package/dist/chunks/{StateSelect-ujAre258.js.map → StateSelect-CEp7kGGg.js.map} +1 -1
  28. package/dist/chunks/{TextEditorLexicalClient-CovUSRag.js → TextEditorLexicalClient-uvFboXlh.js} +2 -2
  29. package/dist/chunks/{TextEditorLexicalClient-CovUSRag.js.map → TextEditorLexicalClient-uvFboXlh.js.map} +1 -1
  30. package/dist/chunks/{Textarea-C9UdUueF.js → Textarea-T8gXua35.js} +2 -2
  31. package/dist/chunks/{Textarea-C9UdUueF.js.map → Textarea-T8gXua35.js.map} +1 -1
  32. package/dist/chunks/{TreeMultiSelect-CfQhlfnC.js → TreeMultiSelect-BcPr2Phe.js} +2 -2
  33. package/dist/chunks/{TreeMultiSelect-CfQhlfnC.js.map → TreeMultiSelect-BcPr2Phe.js.map} +1 -1
  34. package/dist/chunks/{TreePickerBase-BBUOWsSu.js → TreePickerBase-ClXn2q3u.js} +3 -3
  35. package/dist/chunks/{TreePickerBase-BBUOWsSu.js.map → TreePickerBase-ClXn2q3u.js.map} +1 -1
  36. package/dist/chunks/{TreeSelect-2wUXs90E.js → TreeSelect-DYWkgryS.js} +2 -2
  37. package/dist/chunks/{TreeSelect-2wUXs90E.js.map → TreeSelect-DYWkgryS.js.map} +1 -1
  38. package/dist/chunks/{input-search-Dw4rnJBq.js → input-search-BR4LDmyb.js} +2 -2
  39. package/dist/chunks/{input-search-Dw4rnJBq.js.map → input-search-BR4LDmyb.js.map} +1 -1
  40. package/dist/chunks/{layout-picker-MWaImn3L.js → layout-picker-C1sizRYa.js} +2 -2
  41. package/dist/chunks/{layout-picker-MWaImn3L.js.map → layout-picker-C1sizRYa.js.map} +1 -1
  42. package/dist/chunks/{multi-select-BYsbh2ca.js → multi-select-DCY3fonG.js} +2 -2
  43. package/dist/chunks/{multi-select-BYsbh2ca.js.map → multi-select-DCY3fonG.js.map} +1 -1
  44. package/dist/chunks/{picker-Dg55Ss-B.js → picker-DGXq3ikg.js} +2 -2
  45. package/dist/chunks/{picker-Dg55Ss-B.js.map → picker-DGXq3ikg.js.map} +1 -1
  46. package/dist/chunks/{select-BkLc6dyx.js → select-Di99RAVO.js} +3 -3
  47. package/dist/chunks/{select-BkLc6dyx.js.map → select-Di99RAVO.js.map} +1 -1
  48. package/dist/chunks/{slider-CFKsfxFp.js → slider-BqeYbdrg.js} +3 -3
  49. package/dist/chunks/{slider-CFKsfxFp.js.map → slider-BqeYbdrg.js.map} +1 -1
  50. package/dist/date-input/index.js +1 -1
  51. package/dist/date-input/stories/DateInput.stories.js +1 -1
  52. package/dist/date-range-preset-select/stories/DateRangePresetSelect.stories.js +1 -1
  53. package/dist/date-time-input/index.js +1 -1
  54. package/dist/date-time-input/stories/SingleDateTimeInput.stories.js +1 -1
  55. package/dist/drop-zone/index.js +1 -1
  56. package/dist/drop-zone/stories/DropZone.stories.js +1 -1
  57. package/dist/expandable-action-panel/stories/ExpandableActionPanel.stories.js +2 -2
  58. package/dist/image/index.js +2 -2
  59. package/dist/input/Input.d.ts +1 -1
  60. package/dist/input/Input.d.ts.map +1 -1
  61. package/dist/input/InputErrorComponent.d.ts +6 -0
  62. package/dist/input/InputErrorComponent.d.ts.map +1 -0
  63. package/dist/input/index.d.ts +1 -0
  64. package/dist/input/index.d.ts.map +1 -1
  65. package/dist/input/index.js +14 -2
  66. package/dist/input/index.js.map +1 -0
  67. package/dist/input/stories/Input.stories.js +2 -2
  68. package/dist/input/stories/Input.stories.js.map +1 -1
  69. package/dist/input-date-time/index.js +1 -1
  70. package/dist/input-date-time/stories/InputDateTime.stories.js +1 -1
  71. package/dist/input-file/index.js +1 -1
  72. package/dist/input-file/stories/InputFile.stories.js +1 -1
  73. package/dist/input-files/index.js +1 -1
  74. package/dist/input-files/stories/InputFiles.stories.js +1 -1
  75. package/dist/input-image/index.js +1 -1
  76. package/dist/input-image/stories/InputImage.stories.js +1 -1
  77. package/dist/input-search/index.js +1 -1
  78. package/dist/layout-picker/index.js +1 -1
  79. package/dist/layout-picker/stories/LayoutPicker.stories.js +1 -1
  80. package/dist/modal/stories/Modal.stories.js +1 -1
  81. package/dist/multi-select/index.js +2 -2
  82. package/dist/multi-select/ui/stories/MultiSelect.stories.js +1 -1
  83. package/dist/period-select/stories/PeriodSelect.stories.js +1 -1
  84. package/dist/picker/index.js +1 -1
  85. package/dist/popover/stories/Popover.stories.js +1 -1
  86. package/dist/preset-range-date-input/index.js +1 -1
  87. package/dist/preset-range-date-input/ui/stories/PresetRangeDateInput.stories.js +1 -1
  88. package/dist/preset-select/index.js +1 -1
  89. package/dist/select/index.js +3 -3
  90. package/dist/select/stories/Select.stories.js +1 -1
  91. package/dist/select/stories/SerializableSelect.stories.js +1 -1
  92. package/dist/slider/SliderInput.d.ts +2 -2
  93. package/dist/slider/SliderInput.d.ts.map +1 -1
  94. package/dist/slider/index.js +1 -1
  95. package/dist/slider/stories/Slider.stories.js +1 -1
  96. package/dist/slider/stories/SliderInput.stories.js +1 -1
  97. package/dist/slider/stories/SliderInput.stories.js.map +1 -1
  98. package/dist/state-select/index.js +1 -1
  99. package/dist/state-select/stories/StateSelect.stories.js +1 -1
  100. package/dist/text-editor/index.js +1 -1
  101. package/dist/textarea/index.js +1 -1
  102. package/dist/textarea/stories/Textarea.stories.js +1 -1
  103. package/dist/tree-select/index.js +2 -2
  104. package/dist/tree-select/stories/TreeMultiSelect.stories.js +1 -1
  105. package/dist/tree-select/stories/TreeSelect.stories.js +1 -1
  106. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"picker-Dg55Ss-B.js","names":[],"sources":["../../src/picker/PickerField.tsx","../../src/picker/Picker.module.scss","../../src/picker/PickerPopup.tsx","../../src/picker/PickerStatus.tsx","../../src/picker/PickerTriggerActions.tsx","../../src/picker/PickerTriggerInput.tsx","../../src/picker/model/createPickerTriggerPolicy.ts","../../src/picker/model/extractPickerTextContent.ts","../../src/picker/model/usePickerDefaultFilter.ts","../../src/picker/model/usePickerFloatingListbox.ts","../../src/picker/model/usePickerQuery.ts","../../src/picker/model/usePickerSelectionLifecycle.ts","../../src/picker/model/usePickerTriggerController.ts"],"sourcesContent":["import { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { InputUI } from \"../input\";\nimport { useInputFieldIds } from \"../input/lib/useInputFieldIds\";\n\nimport { PickerFieldProps } from \"./types\";\n\nexport function PickerField<TValue extends InputType>({\n\tid,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tclassName,\n\terror,\n\tchildren\n}: PickerFieldProps<TValue>) {\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t{children({ controlId, labelId, descriptionId, errorId, describedBy })}\n\t\t</InputUI>\n\t);\n}\n",".popupLayout {\n\tdisplay: grid;\n\tgrid-template-rows: auto 1fr;\n\tmin-height: 0;\n\tmax-height: 75vh;\n\toverflow: hidden;\n\n\tflex: 1 1 auto;\n}\n\n.popupBody {\n\tmin-height: 0;\n}\n\n.status {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n}\n\n.statusError {\n\tcolor: var(--status-error-text);\n}\n\n.triggerContainer {\n\tposition: relative;\n}\n","import { type CSSProperties, type KeyboardEvent, type MouseEvent, type ReactNode } from \"react\";\n\nimport { FloatingContext, FloatingFocusManager, FloatingPortal } from \"@floating-ui/react\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { AnimatePresence, motion } from \"motion/react\";\n\nimport { Separator } from \"../separator\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerPopupProps {\n\topen: boolean;\n\tcontext: FloatingContext;\n\tfloatingStyles: CSSProperties;\n\tlistId: string;\n\tlabelId?: string;\n\tdescriptionId?: string;\n\tactiveOptionId?: string;\n\tsetFloating: (node: HTMLElement | null) => void;\n\tgetFloatingProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n\tonKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n\tinitialFocus?: number;\n\treturnFocus?: boolean;\n\ttabIndex?: number;\n\tclassName?: string;\n\tlayoutClassName?: string;\n\theaderClassName?: string;\n\tbodyClassName?: string;\n\theader?: ReactNode;\n\tchildren: ReactNode;\n}\n\nfunction stopNestedFloatingMouseDown(event: MouseEvent<HTMLElement>): void {\n\tevent.stopPropagation();\n}\n\nexport function PickerPopup({\n\topen,\n\tcontext,\n\tfloatingStyles,\n\tlistId,\n\tlabelId,\n\tdescriptionId,\n\tactiveOptionId,\n\tsetFloating,\n\tgetFloatingProps,\n\tonKeyDown,\n\tinitialFocus = -1,\n\treturnFocus = false,\n\ttabIndex = 0,\n\tclassName,\n\tlayoutClassName,\n\theaderClassName,\n\tbodyClassName,\n\theader,\n\tchildren\n}: PickerPopupProps) {\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t{open && (\n\t\t\t\t<FloatingPortal>\n\t\t\t\t\t<FloatingFocusManager context={context} modal={false} initialFocus={initialFocus} returnFocus={returnFocus}>\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tref={setFloating}\n\t\t\t\t\t\t\tstyle={floatingStyles}\n\t\t\t\t\t\t\tinitial={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1 }}\n\t\t\t\t\t\t\texit={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\t{...getFloatingProps({\n\t\t\t\t\t\t\t\tid: listId,\n\t\t\t\t\t\t\t\ttabIndex,\n\t\t\t\t\t\t\t\t\"aria-labelledby\": labelId,\n\t\t\t\t\t\t\t\t\"aria-describedby\": descriptionId,\n\t\t\t\t\t\t\t\t\"aria-activedescendant\": activeOptionId,\n\t\t\t\t\t\t\t\tonMouseDown: stopNestedFloatingMouseDown,\n\t\t\t\t\t\t\t\tonKeyDown,\n\t\t\t\t\t\t\t\tclassName\n\t\t\t\t\t\t\t})}>\n\t\t\t\t\t\t\t<div className={cn(styles.popupLayout, layoutClassName)}>\n\t\t\t\t\t\t\t\t{header ? (\n\t\t\t\t\t\t\t\t\t<div className={headerClassName}>\n\t\t\t\t\t\t\t\t\t\t{header}\n\t\t\t\t\t\t\t\t\t\t<Separator className=\"marginBlockSm\" />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<div />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<div className={cn(styles.popupBody, bodyClassName)}>{children}</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t</FloatingFocusManager>\n\t\t\t\t</FloatingPortal>\n\t\t\t)}\n\t\t</AnimatePresence>\n\t);\n}\n","import { ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerStatusProps {\n\temptyState?: ReactNode;\n\tloadingState?: ReactNode;\n\terrorState?: ReactNode;\n}\n\nexport function PickerStatus({ emptyState, loadingState, errorState }: PickerStatusProps) {\n\tconst content = errorState ?? loadingState ?? emptyState;\n\n\tif (content === undefined || content === null) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className={cn(uiStyles.uiPopupOption, styles.status, errorState !== undefined && styles.statusError)} aria-disabled={true}>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n","import { MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ninterface PickerTriggerActionsProps {\n\topen: boolean;\n\tdisabled?: boolean;\n\tchildren?: ReactNode;\n\tonToggleMouseDown?: (event: MouseEvent<HTMLButtonElement>) => void;\n\tonToggleClick: () => void;\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\nexport function PickerTriggerActions({\n\topen,\n\tdisabled,\n\tchildren,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel = \"Открыть список\",\n\tcloseAriaLabel = \"Закрыть список\"\n}: PickerTriggerActionsProps) {\n\treturn (\n\t\t<div className={uiStyles.uiToggleButtonContainer} data-disabled={disabled || undefined}>\n\t\t\t{children}\n\n\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label={open ? closeAriaLabel : openAriaLabel}\n\t\t\t\tclassName={uiStyles.uiToggleButton}\n\t\t\t\tonMouseDown={onToggleMouseDown}\n\t\t\t\tonClick={onToggleClick}>\n\t\t\t\t<ChevronDownIcon className={cn(uiStyles.uiToggleIcon, open && uiStyles.uiToggleIconOpen)} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","import { ComponentPropsWithoutRef, forwardRef, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl } from \"../input\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerTriggerInputProps extends Omit<ComponentPropsWithoutRef<\"input\">, \"size\"> {\n\trootRef?: (node: HTMLDivElement | null) => void;\n\tendAdornment?: ReactNode;\n\toverlay?: ReactNode;\n\trootClassName?: string;\n\tinputClassName?: string;\n}\n\nexport const PickerTriggerInput = forwardRef<HTMLInputElement, PickerTriggerInputProps>(\n\t({ rootRef, endAdornment, overlay, rootClassName, inputClassName, ...props }, ref) => {\n\t\treturn (\n\t\t\t<div ref={rootRef} className={cn(uiStyles.uiInputContainer, styles.triggerContainer, rootClassName)}>\n\t\t\t\t<InputControl endAdornment={endAdornment}>\n\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t<input {...props} ref={ref} className={cn(uiStyles.uiInputWithToggle, controlClassName, inputClassName)} />\n\t\t\t\t\t)}\n\t\t\t\t</InputControl>\n\t\t\t\t{overlay}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nPickerTriggerInput.displayName = \"PickerTriggerInput\";\n","export type PickerTriggerMode = \"display\" | \"search-single\" | \"search-multi\";\n\ninterface PickerTriggerTextFocusParams {\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n}\n\nexport interface PickerTriggerPolicy {\n\tfocusFloatingOnOpen: boolean;\n\trestoreFocusOnClose: boolean;\n\tresetQueryOnClose: boolean;\n\tshouldOpenOnTriggerClick: (open: boolean) => boolean;\n\tshouldOpenOnInputChange: (open: boolean) => boolean;\n\tshouldFocusReferenceOnToggle: (open: boolean) => boolean;\n\tshouldSelectTriggerTextOnFocus: (params: PickerTriggerTextFocusParams) => boolean;\n}\n\n/**\n * Единая политика поведения trigger-input для picker-компонентов.\n * Нормализует различия между display-режимом, single-search и multi-search.\n */\nexport function createPickerTriggerPolicy(mode: PickerTriggerMode): PickerTriggerPolicy {\n\tswitch (mode) {\n\t\tcase \"search-single\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: ({ open, currentQuery, hasDisplayValue }) =>\n\t\t\t\t\t!open && currentQuery.length === 0 && hasDisplayValue\n\t\t\t};\n\t\tcase \"search-multi\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t\tcase \"display\":\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: true,\n\t\t\t\trestoreFocusOnClose: true,\n\t\t\t\tresetQueryOnClose: false,\n\t\t\t\tshouldOpenOnTriggerClick: (open) => !open,\n\t\t\t\tshouldOpenOnInputChange: () => false,\n\t\t\t\tshouldFocusReferenceOnToggle: () => false,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t}\n}\n","import { ReactNode } from \"react\";\n\nexport function extractPickerTextContent(node: ReactNode): string | undefined {\n\tif (typeof node === \"string\" || typeof node === \"number\") {\n\t\treturn String(node);\n\t}\n\n\tif (Array.isArray(node)) {\n\t\tconst values = node.map(extractPickerTextContent).filter((value): value is string => Boolean(value));\n\t\treturn values.length ? values.join(\" \") : undefined;\n\t}\n\n\treturn undefined;\n}\n","import { useMemo } from \"react\";\n\nimport { normalizeTextToLower } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\ninterface UsePickerDefaultFilterOptions<T> {\n\toptions: readonly T[];\n\tquery: string;\n\tenabled?: boolean;\n\tgetSearchText: (option: T) => unknown;\n}\n\nfunction normalizeSearchText(value: unknown) {\n\tconst parts = Array.isArray(value) ? value : [value];\n\n\treturn normalizeTextToLower(parts.filter(Boolean).join(\" \"));\n}\n\nexport function usePickerDefaultFilter<T>({ options, query, enabled = true, getSearchText }: UsePickerDefaultFilterOptions<T>) {\n\tconst normalizedQuery = normalizeTextToLower(query);\n\n\treturn useMemo(() => {\n\t\tif (!enabled || !normalizedQuery) {\n\t\t\treturn [...options];\n\t\t}\n\n\t\treturn options.filter((option) => normalizeSearchText(getSearchText(option)).includes(normalizedQuery));\n\t}, [enabled, getSearchText, normalizedQuery, options]);\n}\n","import { Placement } from \"@floating-ui/react\";\nimport { useFloatingListbox } from \"@ryuzaki13/react-foundation-lib/hooks\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerFloatingListboxParams<T> {\n\toptions: readonly T[];\n\tselectedIndex: number;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tgetOptionDisabled?: (option: T) => boolean;\n\tonSelect?: (option: T) => void;\n\tdisabled?: boolean;\n\tplacement?: Placement;\n\tcloseOnSelect?: boolean;\n\tfocusFloatingOnOpen?: boolean;\n\tallowOpenWithoutOptions?: boolean;\n\trestoreFocusOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\n/**\n * Единая точка входа для popup/listbox поведения во всех picker-компонентах.\n */\nexport function usePickerFloatingListbox<T>(params: UsePickerFloatingListboxParams<T>) {\n\tconst triggerPolicy = params.triggerMode ? createPickerTriggerPolicy(params.triggerMode) : undefined;\n\n\treturn useFloatingListbox({\n\t\t...params,\n\t\tfocusFloatingOnOpen: params.focusFloatingOnOpen ?? triggerPolicy?.focusFloatingOnOpen,\n\t\trestoreFocusOnClose: params.restoreFocusOnClose ?? triggerPolicy?.restoreFocusOnClose\n\t});\n}\n","import { useEffect, useEffectEvent, useRef, useState } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerQueryOptions {\n\topen: boolean;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tresetOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\nexport function usePickerQuery({ open, query, defaultQuery, onQuery, resetOnClose, triggerMode }: UsePickerQueryOptions) {\n\tconst previousOpenRef = useRef(false);\n\tconst isControlled = query !== undefined;\n\tconst [internalQuery, setInternalQuery] = useState(defaultQuery ?? \"\");\n\tconst currentQuery = isControlled ? (query ?? \"\") : internalQuery;\n\tconst syncResetInternalQuery = useEffectEvent(() => setInternalQuery(\"\"));\n\tconst resolvedResetOnClose = resetOnClose ?? (triggerMode ? createPickerTriggerPolicy(triggerMode).resetQueryOnClose : true);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open && resolvedResetOnClose) {\n\t\t\tif (!isControlled) {\n\t\t\t\tsyncResetInternalQuery();\n\t\t\t}\n\n\t\t\tonQuery?.(\"\");\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [isControlled, onQuery, open, resolvedResetOnClose]);\n\n\tconst setQuery = (nextValue: string) => {\n\t\tif (!isControlled) {\n\t\t\tsetInternalQuery(nextValue);\n\t\t}\n\n\t\tonQuery?.(nextValue);\n\t};\n\n\treturn {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tclearQuery: () => setQuery(\"\")\n\t};\n}\n","import { useEffect, useEffectEvent, useRef, useState } from \"react\";\n\ninterface UsePickerSelectionLifecycleOptions<TValue> {\n\tvalue: TValue;\n\topen: boolean;\n\tonCommit: (value: TValue) => void;\n\tonOpen?: () => void;\n\tonClose?: (value: TValue) => void;\n\tisEqual: (left: TValue, right: TValue) => boolean;\n}\n\n/**\n * Общий жизненный цикл чернового выбора для picker-компонентов,\n * где изменения подтверждаются при закрытии popup.\n */\nexport function usePickerSelectionLifecycle<TValue>({\n\tvalue,\n\topen,\n\tonCommit,\n\tonOpen,\n\tonClose,\n\tisEqual\n}: UsePickerSelectionLifecycleOptions<TValue>) {\n\tconst previousOpenRef = useRef(false);\n\tconst [draftValue, setDraftValue] = useState(value);\n\tconst syncDraftValue = useEffectEvent((value: TValue) => setDraftValue(value));\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\tsyncDraftValue(value);\n\t\t}\n\t}, [open, value]);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open) {\n\t\t\tif (!isEqual(draftValue, value)) {\n\t\t\t\tonCommit(draftValue);\n\t\t\t}\n\n\t\t\tonClose?.(draftValue);\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [draftValue, isEqual, onClose, onCommit, open, value]);\n\n\tconst prepareOpen = () => {\n\t\tsetDraftValue(value);\n\t\tonOpen?.();\n\t};\n\n\treturn {\n\t\tdraftValue,\n\t\tsetDraftValue,\n\t\tprepareOpen\n\t};\n}\n","import { MouseEvent, RefObject } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerTriggerControllerOptions {\n\tmode: PickerTriggerMode;\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n\tinputRef: RefObject<HTMLInputElement | null>;\n\tsetQuery?: (value: string) => void;\n\topenList?: () => void;\n\tclose?: () => void;\n\ttoggleOpen?: () => void;\n\tonBeforeOpen?: () => void;\n}\n\ninterface HandleTriggerKeyDownOptions {\n\tevent: React.KeyboardEvent<HTMLElement>;\n\tonActivateWhenOpen?: () => void;\n\tenableSpaceActivation?: boolean;\n\tenableClosedArrowDownOpen?: boolean;\n\tsuppressClosedArrowUp?: boolean;\n}\n\nfunction focusInput(inputRef: RefObject<HTMLInputElement | null>) {\n\trequestAnimationFrame(() => {\n\t\tinputRef.current?.focus();\n\t});\n}\n\n/**\n * Единый контроллер пользовательских действий на trigger-input.\n * Держит поведение display/search-single/search-multi в одном месте.\n */\nexport function usePickerTriggerController({\n\tmode,\n\topen,\n\tcurrentQuery,\n\thasDisplayValue,\n\tinputRef,\n\tsetQuery,\n\topenList,\n\tclose,\n\ttoggleOpen,\n\tonBeforeOpen\n}: UsePickerTriggerControllerOptions) {\n\tconst policy = createPickerTriggerPolicy(mode);\n\n\tconst openTrigger = () => {\n\t\tonBeforeOpen?.();\n\n\t\tif (openList) {\n\t\t\topenList();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst closeTrigger = () => {\n\t\tif (close) {\n\t\t\tclose();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst toggleTrigger = () => {\n\t\tif (open) {\n\t\t\tcloseTrigger();\n\t\t} else {\n\t\t\topenTrigger();\n\t\t}\n\n\t\tif (policy.shouldFocusReferenceOnToggle(open)) {\n\t\t\tfocusInput(inputRef);\n\t\t}\n\t};\n\n\treturn {\n\t\tpolicy,\n\t\thandleTriggerInputChange: (nextValue: string) => {\n\t\t\tsetQuery?.(nextValue);\n\n\t\t\tif (policy.shouldOpenOnInputChange(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerClick: () => {\n\t\t\tif (policy.shouldOpenOnTriggerClick(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerFocus: (input: HTMLInputElement) => {\n\t\t\tif (\n\t\t\t\tpolicy.shouldSelectTriggerTextOnFocus({\n\t\t\t\t\topen,\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\thasDisplayValue\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tinput.select();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\thandleToggleMouseDown: (event: MouseEvent<HTMLButtonElement>) => {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\thandleToggleClick: () => {\n\t\t\ttoggleTrigger();\n\t\t},\n\t\thandleTriggerKeyDown: ({\n\t\t\tevent,\n\t\t\tonActivateWhenOpen,\n\t\t\tenableSpaceActivation = false,\n\t\t\tenableClosedArrowDownOpen = false,\n\t\t\tsuppressClosedArrowUp = false\n\t\t}: HandleTriggerKeyDownOptions) => {\n\t\t\tif (!open && suppressClosedArrowUp && event.key === \"ArrowUp\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!open && enableClosedArrowDownOpen && event.key === \"ArrowDown\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\ttoggleTrigger();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.key === \"Enter\") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (enableSpaceActivation && event.key === \" \") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttoggleTrigger\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"picker-DGXq3ikg.js","names":[],"sources":["../../src/picker/PickerField.tsx","../../src/picker/Picker.module.scss","../../src/picker/PickerPopup.tsx","../../src/picker/PickerStatus.tsx","../../src/picker/PickerTriggerActions.tsx","../../src/picker/PickerTriggerInput.tsx","../../src/picker/model/createPickerTriggerPolicy.ts","../../src/picker/model/extractPickerTextContent.ts","../../src/picker/model/usePickerDefaultFilter.ts","../../src/picker/model/usePickerFloatingListbox.ts","../../src/picker/model/usePickerQuery.ts","../../src/picker/model/usePickerSelectionLifecycle.ts","../../src/picker/model/usePickerTriggerController.ts"],"sourcesContent":["import { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { InputUI } from \"../input\";\nimport { useInputFieldIds } from \"../input/lib/useInputFieldIds\";\n\nimport { PickerFieldProps } from \"./types\";\n\nexport function PickerField<TValue extends InputType>({\n\tid,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tclassName,\n\terror,\n\tchildren\n}: PickerFieldProps<TValue>) {\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t{children({ controlId, labelId, descriptionId, errorId, describedBy })}\n\t\t</InputUI>\n\t);\n}\n",".popupLayout {\n\tdisplay: grid;\n\tgrid-template-rows: auto 1fr;\n\tmin-height: 0;\n\tmax-height: 75vh;\n\toverflow: hidden;\n\n\tflex: 1 1 auto;\n}\n\n.popupBody {\n\tmin-height: 0;\n}\n\n.status {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n}\n\n.statusError {\n\tcolor: var(--status-error-text);\n}\n\n.triggerContainer {\n\tposition: relative;\n}\n","import { type CSSProperties, type KeyboardEvent, type MouseEvent, type ReactNode } from \"react\";\n\nimport { FloatingContext, FloatingFocusManager, FloatingPortal } from \"@floating-ui/react\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { AnimatePresence, motion } from \"motion/react\";\n\nimport { Separator } from \"../separator\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerPopupProps {\n\topen: boolean;\n\tcontext: FloatingContext;\n\tfloatingStyles: CSSProperties;\n\tlistId: string;\n\tlabelId?: string;\n\tdescriptionId?: string;\n\tactiveOptionId?: string;\n\tsetFloating: (node: HTMLElement | null) => void;\n\tgetFloatingProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n\tonKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n\tinitialFocus?: number;\n\treturnFocus?: boolean;\n\ttabIndex?: number;\n\tclassName?: string;\n\tlayoutClassName?: string;\n\theaderClassName?: string;\n\tbodyClassName?: string;\n\theader?: ReactNode;\n\tchildren: ReactNode;\n}\n\nfunction stopNestedFloatingMouseDown(event: MouseEvent<HTMLElement>): void {\n\tevent.stopPropagation();\n}\n\nexport function PickerPopup({\n\topen,\n\tcontext,\n\tfloatingStyles,\n\tlistId,\n\tlabelId,\n\tdescriptionId,\n\tactiveOptionId,\n\tsetFloating,\n\tgetFloatingProps,\n\tonKeyDown,\n\tinitialFocus = -1,\n\treturnFocus = false,\n\ttabIndex = 0,\n\tclassName,\n\tlayoutClassName,\n\theaderClassName,\n\tbodyClassName,\n\theader,\n\tchildren\n}: PickerPopupProps) {\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t{open && (\n\t\t\t\t<FloatingPortal>\n\t\t\t\t\t<FloatingFocusManager context={context} modal={false} initialFocus={initialFocus} returnFocus={returnFocus}>\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tref={setFloating}\n\t\t\t\t\t\t\tstyle={floatingStyles}\n\t\t\t\t\t\t\tinitial={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1 }}\n\t\t\t\t\t\t\texit={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\t{...getFloatingProps({\n\t\t\t\t\t\t\t\tid: listId,\n\t\t\t\t\t\t\t\ttabIndex,\n\t\t\t\t\t\t\t\t\"aria-labelledby\": labelId,\n\t\t\t\t\t\t\t\t\"aria-describedby\": descriptionId,\n\t\t\t\t\t\t\t\t\"aria-activedescendant\": activeOptionId,\n\t\t\t\t\t\t\t\tonMouseDown: stopNestedFloatingMouseDown,\n\t\t\t\t\t\t\t\tonKeyDown,\n\t\t\t\t\t\t\t\tclassName\n\t\t\t\t\t\t\t})}>\n\t\t\t\t\t\t\t<div className={cn(styles.popupLayout, layoutClassName)}>\n\t\t\t\t\t\t\t\t{header ? (\n\t\t\t\t\t\t\t\t\t<div className={headerClassName}>\n\t\t\t\t\t\t\t\t\t\t{header}\n\t\t\t\t\t\t\t\t\t\t<Separator className=\"marginBlockSm\" />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<div />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<div className={cn(styles.popupBody, bodyClassName)}>{children}</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t</FloatingFocusManager>\n\t\t\t\t</FloatingPortal>\n\t\t\t)}\n\t\t</AnimatePresence>\n\t);\n}\n","import { ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerStatusProps {\n\temptyState?: ReactNode;\n\tloadingState?: ReactNode;\n\terrorState?: ReactNode;\n}\n\nexport function PickerStatus({ emptyState, loadingState, errorState }: PickerStatusProps) {\n\tconst content = errorState ?? loadingState ?? emptyState;\n\n\tif (content === undefined || content === null) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className={cn(uiStyles.uiPopupOption, styles.status, errorState !== undefined && styles.statusError)} aria-disabled={true}>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n","import { MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ninterface PickerTriggerActionsProps {\n\topen: boolean;\n\tdisabled?: boolean;\n\tchildren?: ReactNode;\n\tonToggleMouseDown?: (event: MouseEvent<HTMLButtonElement>) => void;\n\tonToggleClick: () => void;\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\nexport function PickerTriggerActions({\n\topen,\n\tdisabled,\n\tchildren,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel = \"Открыть список\",\n\tcloseAriaLabel = \"Закрыть список\"\n}: PickerTriggerActionsProps) {\n\treturn (\n\t\t<div className={uiStyles.uiToggleButtonContainer} data-disabled={disabled || undefined}>\n\t\t\t{children}\n\n\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label={open ? closeAriaLabel : openAriaLabel}\n\t\t\t\tclassName={uiStyles.uiToggleButton}\n\t\t\t\tonMouseDown={onToggleMouseDown}\n\t\t\t\tonClick={onToggleClick}>\n\t\t\t\t<ChevronDownIcon className={cn(uiStyles.uiToggleIcon, open && uiStyles.uiToggleIconOpen)} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","import { ComponentPropsWithoutRef, forwardRef, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl } from \"../input\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerTriggerInputProps extends Omit<ComponentPropsWithoutRef<\"input\">, \"size\"> {\n\trootRef?: (node: HTMLDivElement | null) => void;\n\tendAdornment?: ReactNode;\n\toverlay?: ReactNode;\n\trootClassName?: string;\n\tinputClassName?: string;\n}\n\nexport const PickerTriggerInput = forwardRef<HTMLInputElement, PickerTriggerInputProps>(\n\t({ rootRef, endAdornment, overlay, rootClassName, inputClassName, ...props }, ref) => {\n\t\treturn (\n\t\t\t<div ref={rootRef} className={cn(uiStyles.uiInputContainer, styles.triggerContainer, rootClassName)}>\n\t\t\t\t<InputControl endAdornment={endAdornment}>\n\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t<input {...props} ref={ref} className={cn(uiStyles.uiInputWithToggle, controlClassName, inputClassName)} />\n\t\t\t\t\t)}\n\t\t\t\t</InputControl>\n\t\t\t\t{overlay}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nPickerTriggerInput.displayName = \"PickerTriggerInput\";\n","export type PickerTriggerMode = \"display\" | \"search-single\" | \"search-multi\";\n\ninterface PickerTriggerTextFocusParams {\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n}\n\nexport interface PickerTriggerPolicy {\n\tfocusFloatingOnOpen: boolean;\n\trestoreFocusOnClose: boolean;\n\tresetQueryOnClose: boolean;\n\tshouldOpenOnTriggerClick: (open: boolean) => boolean;\n\tshouldOpenOnInputChange: (open: boolean) => boolean;\n\tshouldFocusReferenceOnToggle: (open: boolean) => boolean;\n\tshouldSelectTriggerTextOnFocus: (params: PickerTriggerTextFocusParams) => boolean;\n}\n\n/**\n * Единая политика поведения trigger-input для picker-компонентов.\n * Нормализует различия между display-режимом, single-search и multi-search.\n */\nexport function createPickerTriggerPolicy(mode: PickerTriggerMode): PickerTriggerPolicy {\n\tswitch (mode) {\n\t\tcase \"search-single\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: ({ open, currentQuery, hasDisplayValue }) =>\n\t\t\t\t\t!open && currentQuery.length === 0 && hasDisplayValue\n\t\t\t};\n\t\tcase \"search-multi\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t\tcase \"display\":\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: true,\n\t\t\t\trestoreFocusOnClose: true,\n\t\t\t\tresetQueryOnClose: false,\n\t\t\t\tshouldOpenOnTriggerClick: (open) => !open,\n\t\t\t\tshouldOpenOnInputChange: () => false,\n\t\t\t\tshouldFocusReferenceOnToggle: () => false,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t}\n}\n","import { ReactNode } from \"react\";\n\nexport function extractPickerTextContent(node: ReactNode): string | undefined {\n\tif (typeof node === \"string\" || typeof node === \"number\") {\n\t\treturn String(node);\n\t}\n\n\tif (Array.isArray(node)) {\n\t\tconst values = node.map(extractPickerTextContent).filter((value): value is string => Boolean(value));\n\t\treturn values.length ? values.join(\" \") : undefined;\n\t}\n\n\treturn undefined;\n}\n","import { useMemo } from \"react\";\n\nimport { normalizeTextToLower } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\ninterface UsePickerDefaultFilterOptions<T> {\n\toptions: readonly T[];\n\tquery: string;\n\tenabled?: boolean;\n\tgetSearchText: (option: T) => unknown;\n}\n\nfunction normalizeSearchText(value: unknown) {\n\tconst parts = Array.isArray(value) ? value : [value];\n\n\treturn normalizeTextToLower(parts.filter(Boolean).join(\" \"));\n}\n\nexport function usePickerDefaultFilter<T>({ options, query, enabled = true, getSearchText }: UsePickerDefaultFilterOptions<T>) {\n\tconst normalizedQuery = normalizeTextToLower(query);\n\n\treturn useMemo(() => {\n\t\tif (!enabled || !normalizedQuery) {\n\t\t\treturn [...options];\n\t\t}\n\n\t\treturn options.filter((option) => normalizeSearchText(getSearchText(option)).includes(normalizedQuery));\n\t}, [enabled, getSearchText, normalizedQuery, options]);\n}\n","import { Placement } from \"@floating-ui/react\";\nimport { useFloatingListbox } from \"@ryuzaki13/react-foundation-lib/hooks\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerFloatingListboxParams<T> {\n\toptions: readonly T[];\n\tselectedIndex: number;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tgetOptionDisabled?: (option: T) => boolean;\n\tonSelect?: (option: T) => void;\n\tdisabled?: boolean;\n\tplacement?: Placement;\n\tcloseOnSelect?: boolean;\n\tfocusFloatingOnOpen?: boolean;\n\tallowOpenWithoutOptions?: boolean;\n\trestoreFocusOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\n/**\n * Единая точка входа для popup/listbox поведения во всех picker-компонентах.\n */\nexport function usePickerFloatingListbox<T>(params: UsePickerFloatingListboxParams<T>) {\n\tconst triggerPolicy = params.triggerMode ? createPickerTriggerPolicy(params.triggerMode) : undefined;\n\n\treturn useFloatingListbox({\n\t\t...params,\n\t\tfocusFloatingOnOpen: params.focusFloatingOnOpen ?? triggerPolicy?.focusFloatingOnOpen,\n\t\trestoreFocusOnClose: params.restoreFocusOnClose ?? triggerPolicy?.restoreFocusOnClose\n\t});\n}\n","import { useEffect, useEffectEvent, useRef, useState } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerQueryOptions {\n\topen: boolean;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tresetOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\nexport function usePickerQuery({ open, query, defaultQuery, onQuery, resetOnClose, triggerMode }: UsePickerQueryOptions) {\n\tconst previousOpenRef = useRef(false);\n\tconst isControlled = query !== undefined;\n\tconst [internalQuery, setInternalQuery] = useState(defaultQuery ?? \"\");\n\tconst currentQuery = isControlled ? (query ?? \"\") : internalQuery;\n\tconst syncResetInternalQuery = useEffectEvent(() => setInternalQuery(\"\"));\n\tconst resolvedResetOnClose = resetOnClose ?? (triggerMode ? createPickerTriggerPolicy(triggerMode).resetQueryOnClose : true);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open && resolvedResetOnClose) {\n\t\t\tif (!isControlled) {\n\t\t\t\tsyncResetInternalQuery();\n\t\t\t}\n\n\t\t\tonQuery?.(\"\");\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [isControlled, onQuery, open, resolvedResetOnClose]);\n\n\tconst setQuery = (nextValue: string) => {\n\t\tif (!isControlled) {\n\t\t\tsetInternalQuery(nextValue);\n\t\t}\n\n\t\tonQuery?.(nextValue);\n\t};\n\n\treturn {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tclearQuery: () => setQuery(\"\")\n\t};\n}\n","import { useEffect, useEffectEvent, useRef, useState } from \"react\";\n\ninterface UsePickerSelectionLifecycleOptions<TValue> {\n\tvalue: TValue;\n\topen: boolean;\n\tonCommit: (value: TValue) => void;\n\tonOpen?: () => void;\n\tonClose?: (value: TValue) => void;\n\tisEqual: (left: TValue, right: TValue) => boolean;\n}\n\n/**\n * Общий жизненный цикл чернового выбора для picker-компонентов,\n * где изменения подтверждаются при закрытии popup.\n */\nexport function usePickerSelectionLifecycle<TValue>({\n\tvalue,\n\topen,\n\tonCommit,\n\tonOpen,\n\tonClose,\n\tisEqual\n}: UsePickerSelectionLifecycleOptions<TValue>) {\n\tconst previousOpenRef = useRef(false);\n\tconst [draftValue, setDraftValue] = useState(value);\n\tconst syncDraftValue = useEffectEvent((value: TValue) => setDraftValue(value));\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\tsyncDraftValue(value);\n\t\t}\n\t}, [open, value]);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open) {\n\t\t\tif (!isEqual(draftValue, value)) {\n\t\t\t\tonCommit(draftValue);\n\t\t\t}\n\n\t\t\tonClose?.(draftValue);\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [draftValue, isEqual, onClose, onCommit, open, value]);\n\n\tconst prepareOpen = () => {\n\t\tsetDraftValue(value);\n\t\tonOpen?.();\n\t};\n\n\treturn {\n\t\tdraftValue,\n\t\tsetDraftValue,\n\t\tprepareOpen\n\t};\n}\n","import { MouseEvent, RefObject } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerTriggerControllerOptions {\n\tmode: PickerTriggerMode;\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n\tinputRef: RefObject<HTMLInputElement | null>;\n\tsetQuery?: (value: string) => void;\n\topenList?: () => void;\n\tclose?: () => void;\n\ttoggleOpen?: () => void;\n\tonBeforeOpen?: () => void;\n}\n\ninterface HandleTriggerKeyDownOptions {\n\tevent: React.KeyboardEvent<HTMLElement>;\n\tonActivateWhenOpen?: () => void;\n\tenableSpaceActivation?: boolean;\n\tenableClosedArrowDownOpen?: boolean;\n\tsuppressClosedArrowUp?: boolean;\n}\n\nfunction focusInput(inputRef: RefObject<HTMLInputElement | null>) {\n\trequestAnimationFrame(() => {\n\t\tinputRef.current?.focus();\n\t});\n}\n\n/**\n * Единый контроллер пользовательских действий на trigger-input.\n * Держит поведение display/search-single/search-multi в одном месте.\n */\nexport function usePickerTriggerController({\n\tmode,\n\topen,\n\tcurrentQuery,\n\thasDisplayValue,\n\tinputRef,\n\tsetQuery,\n\topenList,\n\tclose,\n\ttoggleOpen,\n\tonBeforeOpen\n}: UsePickerTriggerControllerOptions) {\n\tconst policy = createPickerTriggerPolicy(mode);\n\n\tconst openTrigger = () => {\n\t\tonBeforeOpen?.();\n\n\t\tif (openList) {\n\t\t\topenList();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst closeTrigger = () => {\n\t\tif (close) {\n\t\t\tclose();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst toggleTrigger = () => {\n\t\tif (open) {\n\t\t\tcloseTrigger();\n\t\t} else {\n\t\t\topenTrigger();\n\t\t}\n\n\t\tif (policy.shouldFocusReferenceOnToggle(open)) {\n\t\t\tfocusInput(inputRef);\n\t\t}\n\t};\n\n\treturn {\n\t\tpolicy,\n\t\thandleTriggerInputChange: (nextValue: string) => {\n\t\t\tsetQuery?.(nextValue);\n\n\t\t\tif (policy.shouldOpenOnInputChange(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerClick: () => {\n\t\t\tif (policy.shouldOpenOnTriggerClick(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerFocus: (input: HTMLInputElement) => {\n\t\t\tif (\n\t\t\t\tpolicy.shouldSelectTriggerTextOnFocus({\n\t\t\t\t\topen,\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\thasDisplayValue\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tinput.select();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\thandleToggleMouseDown: (event: MouseEvent<HTMLButtonElement>) => {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\thandleToggleClick: () => {\n\t\t\ttoggleTrigger();\n\t\t},\n\t\thandleTriggerKeyDown: ({\n\t\t\tevent,\n\t\t\tonActivateWhenOpen,\n\t\t\tenableSpaceActivation = false,\n\t\t\tenableClosedArrowDownOpen = false,\n\t\t\tsuppressClosedArrowUp = false\n\t\t}: HandleTriggerKeyDownOptions) => {\n\t\t\tif (!open && suppressClosedArrowUp && event.key === \"ArrowUp\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!open && enableClosedArrowDownOpen && event.key === \"ArrowDown\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\ttoggleTrigger();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.key === \"Enter\") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (enableSpaceActivation && event.key === \" \") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttoggleTrigger\n\t};\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { a as e } from "./odata-DSW7z3nh.js";
2
- import { s as t } from "./Input-BmjlpA09.js";
2
+ import { s as t } from "./Input-BYUl3UFn.js";
3
3
  import { t as n } from "./SelectOptionContent-CI7wq9Oi.js";
4
4
  import { n as r } from "./useODataSelectBase-BbeKdq6x.js";
5
- import { t as i } from "./Select-BJ5OqTe7.js";
5
+ import { t as i } from "./Select-B6kxgxK2.js";
6
6
  import { useMemo as a } from "react";
7
7
  import { jsx as o } from "react/jsx-runtime";
8
8
  //#region src/select/model/useODataSelect.ts
@@ -78,4 +78,4 @@ var l = ({ odata: r, segment: a, model: l, size: u, label: d, description: f, di
78
78
  //#endregion
79
79
  export { l as t };
80
80
 
81
- //# sourceMappingURL=select-BkLc6dyx.js.map
81
+ //# sourceMappingURL=select-Di99RAVO.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"select-BkLc6dyx.js","names":[],"sources":["../../src/select/model/useODataSelect.ts","../../src/select/ODataSelect.tsx"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport { ODataCollectionModel, ODataSingleSelectProps } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { useODataSelectBase } from \"./useODataSelectBase\";\n\ninterface UseODataSelectOptions extends Omit<ODataSingleSelectProps, \"model\"> {\n\tmodel: Required<ODataCollectionModel>;\n\tonChange: (value: string | undefined) => void;\n}\n\nexport function useODataSelect({ odata, segment, model, value, dependencies, onChange }: UseODataSelectOptions) {\n\tconst odataModel = useODataSelectBase({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue: value ? [value] : [],\n\t\tdependencies\n\t});\n\n\tconst selectedItem = odataModel.selectedItems[0];\n\tconst options = useMemo(() => {\n\t\tif (!selectedItem) {\n\t\t\treturn odataModel.filteredItems;\n\t\t}\n\n\t\treturn [selectedItem, ...odataModel.filteredItems];\n\t}, [odataModel.filteredItems, selectedItem]);\n\n\tconst handleChange = (item: CollectionItem | undefined) => {\n\t\tonChange(item?.[odataModel.selectionKey]);\n\t};\n\n\treturn {\n\t\t...odataModel,\n\t\tselectedItem,\n\t\toptions,\n\t\thandleChange\n\t};\n}\n","import React from \"react\";\n\nimport { ODataSingleSelectProps, useODataCollectionModel } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { InputUILoading } from \"../input\";\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataSelect } from \"./model/useODataSelect\";\nimport { Select } from \"./Select\";\nimport { SelectOptionContent } from \"./SelectOptionContent\";\n\ntype ODataSelectProps = Omit<ODataSingleSelectProps, \"value\"> & UiBaseProps<string | undefined> & { clearable?: boolean };\n\nfunction getODataOptionTextKey(item: CollectionItem | undefined, textKey: string, codeKey: string) {\n\tif (!item) {\n\t\treturn textKey || codeKey;\n\t}\n\n\treturn textKey || Object.keys(item).find((key) => key !== codeKey) || codeKey;\n}\n\nexport const ODataSelect: React.FC<ODataSelectProps> = ({\n\todata,\n\tsegment,\n\tmodel: initialModel,\n\tsize,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tvalue,\n\tdependencies,\n\tonChange,\n\tclearable\n}) => {\n\tconst model = useODataCollectionModel(initialModel);\n\tconst odataModel = useODataSelect({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue,\n\t\tdependencies,\n\t\tonChange\n\t});\n\n\tif (odataModel.isLoading) {\n\t\treturn <InputUILoading size={size} label={label} description={description} />;\n\t}\n\n\tconst hideCode = segment.hideCode ?? odata.hideCode;\n\tconst resolvedTextKey = getODataOptionTextKey(odataModel.selectedItem ?? odataModel.options[0], odataModel.textKey, odataModel.codeKey);\n\n\treturn (\n\t\t<Select\n\t\t\tsize={size}\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\toptions={odataModel.options}\n\t\t\tvalue={odataModel.selectedItem}\n\t\t\tonChange={odataModel.handleChange}\n\t\t\tgetOptionKey={(item) => item[odataModel.codeKey]}\n\t\t\tgetOptionLabel={(item) => item[resolvedTextKey]}\n\t\t\tgetOptionCode={hideCode ? undefined : (item) => item[odataModel.codeKey]}\n\t\t\tgetOptionAriaLabel={(item) =>\n\t\t\t\thideCode || item[resolvedTextKey] === item[odataModel.codeKey]\n\t\t\t\t\t? String(item[resolvedTextKey])\n\t\t\t\t\t: `${item[resolvedTextKey]} ${item[odataModel.codeKey]}`\n\t\t\t}\n\t\t\trenderValue={(item) => (\n\t\t\t\t<SelectOptionContent label={item[resolvedTextKey]} code={hideCode ? undefined : item[odataModel.codeKey]} />\n\t\t\t)}\n\t\t\trenderOption={(item) => (\n\t\t\t\t<SelectOptionContent\n\t\t\t\t\tlabel={item[resolvedTextKey]}\n\t\t\t\t\tcode={hideCode ? undefined : item[odataModel.codeKey]}\n\t\t\t\t\thighlight={odataModel.debouncedQuery}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\tsearchable\n\t\t\tquery={odataModel.query}\n\t\t\tonQuery={odataModel.setQuery}\n\t\t\tdefaultFilter={false}\n\t\t\tdisabled={disabled || odataModel.isLoading}\n\t\t\tplaceholder={odataModel.placeholder}\n\t\t\tloadingState=\"Загрузка...\"\n\t\t\terrorState={odataModel.isError ? \"Ошибка загрузки\" : undefined}\n\t\t\temptyState={!odataModel.isLoading && !odataModel.isError ? \"Нет данных\" : undefined}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n};\n"],"mappings":";;;;;;;;AAYA,SAAgB,EAAe,EAAE,UAAO,YAAS,UAAO,UAAO,iBAAc,eAAmC;CAC/G,IAAM,IAAa,EAAmB;EACrC;EACA;EACA;EACA,OAAO,IAAQ,CAAC,CAAK,IAAI,CAAC;EAC1B;CACD,CAAC,GAEK,IAAe,EAAW,cAAc,IACxC,IAAU,QACV,IAIE,CAAC,GAAc,GAAG,EAAW,aAAa,IAHzC,EAAW,eAIjB,CAAC,EAAW,eAAe,CAAY,CAAC,GAErC,KAAgB,MAAqC;EAC1D,EAAS,IAAO,EAAW,aAAa;CACzC;CAEA,OAAO;EACN,GAAG;EACH;EACA;EACA;CACD;AACD;;;AC1BA,SAAS,EAAsB,GAAkC,GAAiB,GAAiB;CAKlG,OAJK,IAIE,KAAW,OAAO,KAAK,CAAI,CAAC,CAAC,MAAM,MAAQ,MAAQ,CAAO,KAAK,IAH9D,KAAW;AAIpB;AAEA,IAAa,KAA2C,EACvD,UACA,YACA,OAAO,GACP,SACA,UACA,gBACA,aACA,UACA,iBACA,aACA,mBACK;CAEL,IAAM,IAAa,EAAe;EACjC;EACA;EACA,OAJa,EAAwB,CAIrC;EACA;EACA;EACA;CACD,CAAC;CAED,IAAI,EAAW,WACd,OAAO,kBAAC,GAAD;EAAsB;EAAa;EAAoB;CAAc,CAAA;CAG7E,IAAM,IAAW,EAAQ,YAAY,EAAM,UACrC,IAAkB,EAAsB,EAAW,gBAAgB,EAAW,QAAQ,IAAI,EAAW,SAAS,EAAW,OAAO;CAEtI,OACC,kBAAC,GAAD;EACO;EACC;EACM;EACb,SAAS,EAAW;EACpB,OAAO,EAAW;EAClB,UAAU,EAAW;EACrB,eAAe,MAAS,EAAK,EAAW;EACxC,iBAAiB,MAAS,EAAK;EAC/B,eAAe,IAAW,KAAA,KAAa,MAAS,EAAK,EAAW;EAChE,qBAAqB,MACpB,KAAY,EAAK,OAAqB,EAAK,EAAW,WACnD,OAAO,EAAK,EAAgB,IAC5B,GAAG,EAAK,GAAiB,GAAG,EAAK,EAAW;EAEhD,cAAc,MACb,kBAAC,GAAD;GAAqB,OAAO,EAAK;GAAkB,MAAM,IAAW,KAAA,IAAY,EAAK,EAAW;EAAW,CAAA;EAE5G,eAAe,MACd,kBAAC,GAAD;GACC,OAAO,EAAK;GACZ,MAAM,IAAW,KAAA,IAAY,EAAK,EAAW;GAC7C,WAAW,EAAW;EACtB,CAAA;EAEF,YAAA;EACA,OAAO,EAAW;EAClB,SAAS,EAAW;EACpB,eAAe;EACf,UAAU,KAAY,EAAW;EACjC,aAAa,EAAW;EACxB,cAAa;EACb,YAAY,EAAW,UAAU,oBAAoB,KAAA;EACrD,YAAY,CAAC,EAAW,aAAa,CAAC,EAAW,UAAU,eAAe,KAAA;EAC/D;CACX,CAAA;AAEH"}
1
+ {"version":3,"file":"select-Di99RAVO.js","names":[],"sources":["../../src/select/model/useODataSelect.ts","../../src/select/ODataSelect.tsx"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport { ODataCollectionModel, ODataSingleSelectProps } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { useODataSelectBase } from \"./useODataSelectBase\";\n\ninterface UseODataSelectOptions extends Omit<ODataSingleSelectProps, \"model\"> {\n\tmodel: Required<ODataCollectionModel>;\n\tonChange: (value: string | undefined) => void;\n}\n\nexport function useODataSelect({ odata, segment, model, value, dependencies, onChange }: UseODataSelectOptions) {\n\tconst odataModel = useODataSelectBase({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue: value ? [value] : [],\n\t\tdependencies\n\t});\n\n\tconst selectedItem = odataModel.selectedItems[0];\n\tconst options = useMemo(() => {\n\t\tif (!selectedItem) {\n\t\t\treturn odataModel.filteredItems;\n\t\t}\n\n\t\treturn [selectedItem, ...odataModel.filteredItems];\n\t}, [odataModel.filteredItems, selectedItem]);\n\n\tconst handleChange = (item: CollectionItem | undefined) => {\n\t\tonChange(item?.[odataModel.selectionKey]);\n\t};\n\n\treturn {\n\t\t...odataModel,\n\t\tselectedItem,\n\t\toptions,\n\t\thandleChange\n\t};\n}\n","import React from \"react\";\n\nimport { ODataSingleSelectProps, useODataCollectionModel } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { InputUILoading } from \"../input\";\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataSelect } from \"./model/useODataSelect\";\nimport { Select } from \"./Select\";\nimport { SelectOptionContent } from \"./SelectOptionContent\";\n\ntype ODataSelectProps = Omit<ODataSingleSelectProps, \"value\"> & UiBaseProps<string | undefined> & { clearable?: boolean };\n\nfunction getODataOptionTextKey(item: CollectionItem | undefined, textKey: string, codeKey: string) {\n\tif (!item) {\n\t\treturn textKey || codeKey;\n\t}\n\n\treturn textKey || Object.keys(item).find((key) => key !== codeKey) || codeKey;\n}\n\nexport const ODataSelect: React.FC<ODataSelectProps> = ({\n\todata,\n\tsegment,\n\tmodel: initialModel,\n\tsize,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tvalue,\n\tdependencies,\n\tonChange,\n\tclearable\n}) => {\n\tconst model = useODataCollectionModel(initialModel);\n\tconst odataModel = useODataSelect({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue,\n\t\tdependencies,\n\t\tonChange\n\t});\n\n\tif (odataModel.isLoading) {\n\t\treturn <InputUILoading size={size} label={label} description={description} />;\n\t}\n\n\tconst hideCode = segment.hideCode ?? odata.hideCode;\n\tconst resolvedTextKey = getODataOptionTextKey(odataModel.selectedItem ?? odataModel.options[0], odataModel.textKey, odataModel.codeKey);\n\n\treturn (\n\t\t<Select\n\t\t\tsize={size}\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\toptions={odataModel.options}\n\t\t\tvalue={odataModel.selectedItem}\n\t\t\tonChange={odataModel.handleChange}\n\t\t\tgetOptionKey={(item) => item[odataModel.codeKey]}\n\t\t\tgetOptionLabel={(item) => item[resolvedTextKey]}\n\t\t\tgetOptionCode={hideCode ? undefined : (item) => item[odataModel.codeKey]}\n\t\t\tgetOptionAriaLabel={(item) =>\n\t\t\t\thideCode || item[resolvedTextKey] === item[odataModel.codeKey]\n\t\t\t\t\t? String(item[resolvedTextKey])\n\t\t\t\t\t: `${item[resolvedTextKey]} ${item[odataModel.codeKey]}`\n\t\t\t}\n\t\t\trenderValue={(item) => (\n\t\t\t\t<SelectOptionContent label={item[resolvedTextKey]} code={hideCode ? undefined : item[odataModel.codeKey]} />\n\t\t\t)}\n\t\t\trenderOption={(item) => (\n\t\t\t\t<SelectOptionContent\n\t\t\t\t\tlabel={item[resolvedTextKey]}\n\t\t\t\t\tcode={hideCode ? undefined : item[odataModel.codeKey]}\n\t\t\t\t\thighlight={odataModel.debouncedQuery}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\tsearchable\n\t\t\tquery={odataModel.query}\n\t\t\tonQuery={odataModel.setQuery}\n\t\t\tdefaultFilter={false}\n\t\t\tdisabled={disabled || odataModel.isLoading}\n\t\t\tplaceholder={odataModel.placeholder}\n\t\t\tloadingState=\"Загрузка...\"\n\t\t\terrorState={odataModel.isError ? \"Ошибка загрузки\" : undefined}\n\t\t\temptyState={!odataModel.isLoading && !odataModel.isError ? \"Нет данных\" : undefined}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n};\n"],"mappings":";;;;;;;;AAYA,SAAgB,EAAe,EAAE,UAAO,YAAS,UAAO,UAAO,iBAAc,eAAmC;CAC/G,IAAM,IAAa,EAAmB;EACrC;EACA;EACA;EACA,OAAO,IAAQ,CAAC,CAAK,IAAI,CAAC;EAC1B;CACD,CAAC,GAEK,IAAe,EAAW,cAAc,IACxC,IAAU,QACV,IAIE,CAAC,GAAc,GAAG,EAAW,aAAa,IAHzC,EAAW,eAIjB,CAAC,EAAW,eAAe,CAAY,CAAC,GAErC,KAAgB,MAAqC;EAC1D,EAAS,IAAO,EAAW,aAAa;CACzC;CAEA,OAAO;EACN,GAAG;EACH;EACA;EACA;CACD;AACD;;;AC1BA,SAAS,EAAsB,GAAkC,GAAiB,GAAiB;CAKlG,OAJK,IAIE,KAAW,OAAO,KAAK,CAAI,CAAC,CAAC,MAAM,MAAQ,MAAQ,CAAO,KAAK,IAH9D,KAAW;AAIpB;AAEA,IAAa,KAA2C,EACvD,UACA,YACA,OAAO,GACP,SACA,UACA,gBACA,aACA,UACA,iBACA,aACA,mBACK;CAEL,IAAM,IAAa,EAAe;EACjC;EACA;EACA,OAJa,EAAwB,CAIrC;EACA;EACA;EACA;CACD,CAAC;CAED,IAAI,EAAW,WACd,OAAO,kBAAC,GAAD;EAAsB;EAAa;EAAoB;CAAc,CAAA;CAG7E,IAAM,IAAW,EAAQ,YAAY,EAAM,UACrC,IAAkB,EAAsB,EAAW,gBAAgB,EAAW,QAAQ,IAAI,EAAW,SAAS,EAAW,OAAO;CAEtI,OACC,kBAAC,GAAD;EACO;EACC;EACM;EACb,SAAS,EAAW;EACpB,OAAO,EAAW;EAClB,UAAU,EAAW;EACrB,eAAe,MAAS,EAAK,EAAW;EACxC,iBAAiB,MAAS,EAAK;EAC/B,eAAe,IAAW,KAAA,KAAa,MAAS,EAAK,EAAW;EAChE,qBAAqB,MACpB,KAAY,EAAK,OAAqB,EAAK,EAAW,WACnD,OAAO,EAAK,EAAgB,IAC5B,GAAG,EAAK,GAAiB,GAAG,EAAK,EAAW;EAEhD,cAAc,MACb,kBAAC,GAAD;GAAqB,OAAO,EAAK;GAAkB,MAAM,IAAW,KAAA,IAAY,EAAK,EAAW;EAAW,CAAA;EAE5G,eAAe,MACd,kBAAC,GAAD;GACC,OAAO,EAAK;GACZ,MAAM,IAAW,KAAA,IAAY,EAAK,EAAW;GAC7C,WAAW,EAAW;EACtB,CAAA;EAEF,YAAA;EACA,OAAO,EAAW;EAClB,SAAS,EAAW;EACpB,eAAe;EACf,UAAU,KAAY,EAAW;EACjC,aAAa,EAAW;EACxB,cAAa;EACb,YAAY,EAAW,UAAU,oBAAoB,KAAA;EACrD,YAAY,CAAC,EAAW,aAAa,CAAC,EAAW,UAAU,eAAe,KAAA;EAC/D;CACX,CAAA;AAEH"}
@@ -1,7 +1,7 @@
1
1
  import { n as e, r as t } from "./popover-xJJqy1v6.js";
2
2
  import { t as n } from "./ui.module-BisoTevy.js";
3
- import { a as r, c as i, o as a, r as o } from "./Input-BmjlpA09.js";
4
- import { l as s } from "./picker-Dg55Ss-B.js";
3
+ import { a as r, c as i, o as a, r as o } from "./Input-BYUl3UFn.js";
4
+ import { l as s } from "./picker-DGXq3ikg.js";
5
5
  import { useCallback as c, useEffect as l, useEffectEvent as u, useMemo as d, useRef as f, useState as p } from "react";
6
6
  import { cn as ee } from "@ryuzaki13/react-foundation-lib/utils";
7
7
  import { toFiniteNumber as m } from "@ryuzaki13/react-foundation-lib/formatters";
@@ -692,4 +692,4 @@ function ue(e, t) {
692
692
  //#endregion
693
693
  export { q as i, le as n, K as r, ce as t };
694
694
 
695
- //# sourceMappingURL=slider-CFKsfxFp.js.map
695
+ //# sourceMappingURL=slider-BqeYbdrg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"slider-CFKsfxFp.js","names":[],"sources":["../../src/slider/lib/sliderMath.ts","../../src/slider/Slider.module.scss","../../src/slider/Slider.tsx","../../src/slider/SliderInput.tsx"],"sourcesContent":["import {\n\tfindClosestNumberScaleMark,\n\tfindClosestNumberScaleMarkByPercent,\n\tgetNumberScaleMarkPercent,\n\tprepareNumberScaleMarks,\n\tresolveNumberScaleBounds,\n\tsnapNumberScaleValue,\n\tsnapNumberScaleValueToStep,\n\tvalueToNumberScalePercent\n} from \"@ryuzaki13/react-foundation-lib/number-scale\";\nimport { resolveRangeOutputValue } from \"@ryuzaki13/react-foundation-lib/range-output\";\n\nimport { SliderFillRange, SliderMark, SliderMathOptions, SliderRangeMark, SliderRangeOutputValueFallback, SliderRangeValue } from \"./types\";\n\nexport function prepareSliderMarks<TMark extends SliderMark>(marks: readonly TMark[] | undefined, min: number, max: number): TMark[] {\n\treturn prepareNumberScaleMarks(marks, min, max);\n}\n\nexport function getSliderMarkPercent<TMark extends SliderMark>(mark: TMark, marks: readonly TMark[], options: SliderMathOptions<TMark>) {\n\tconst markIndex = marks.findIndex((item) => item.value === mark.value);\n\treturn getNumberScaleMarkPercent(Math.max(0, markIndex), marks, options.min, options.max, options.marksPosition);\n}\n\n/**\n * Возвращает визуальную позицию значения: по шкале min/max или по позиции ближайшей mark.\n */\nexport function valueToSliderVisualPercent<TMark extends SliderMark>(value: number, options: SliderMathOptions<TMark>) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\tif (marks.length > 0) {\n\t\tconst exactMark = marks.find((mark) => mark.value === value);\n\t\tconst mark = exactMark ?? findClosestNumberScaleMark(value, marks);\n\n\t\tif (mark) {\n\t\t\treturn getSliderMarkPercent(mark, marks, { ...options, min, max, marks });\n\t\t}\n\t}\n\n\treturn valueToNumberScalePercent(value, min, max);\n}\n\n/**\n * Возвращает mark, который визуально ближе всего к pointer percent.\n */\nexport function getClosestSliderMarkByPercent<TMark extends SliderMark>(percent: number, options: SliderMathOptions<TMark>) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\treturn findClosestNumberScaleMarkByPercent(percent, marks, min, max, options.marksPosition);\n}\n\nexport function snapSliderValue<TMark extends SliderMark>(value: number, options: SliderMathOptions<TMark>) {\n\treturn snapNumberScaleValue(value, options);\n}\n\nexport function normalizeSingleSliderValue(value: number | undefined, options: SliderMathOptions) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\n\tif (value === undefined) {\n\t\treturn min;\n\t}\n\n\treturn snapSliderValue(value, { ...options, min, max });\n}\n\n/**\n * Возвращает публичное значение mark: `outputValue`, если оно задано, иначе координату `value`.\n */\nexport function getRangeMarkOutputValue(mark: SliderRangeMark | undefined): number | null | undefined {\n\tif (!mark) {\n\t\treturn undefined;\n\t}\n\n\tif (!Object.hasOwn(mark, \"outputValue\") || mark.outputValue === undefined) {\n\t\treturn mark.value;\n\t}\n\n\treturn mark.outputValue;\n}\n\n/**\n * Готовит range-значение к внешней сериализации, заменяя открытые границы на заданные подстановки.\n *\n * Функция не участвует во внутренней логике слайдера: `SliderRange` и `SliderRangeInput`\n * продолжают отдавать `null` через `onChange`, а потребитель явно применяет подстановку\n * рядом со своим обработчиком сохранения/отправки.\n */\nexport function resolveSliderRangeOutputValue(\n\tvalue: SliderRangeValue,\n\tfallback: SliderRangeOutputValueFallback | undefined\n): SliderRangeValue {\n\treturn resolveRangeOutputValue(value, fallback);\n}\n\nfunction findRangeMarkByOutputValue(\n\tvalue: number | null,\n\tmarks: readonly SliderRangeMark[],\n\tthumbIndex: number\n): SliderRangeMark | undefined {\n\tconst matchingMarks = marks.filter((mark) => getRangeMarkOutputValue(mark) === value);\n\n\tif (!matchingMarks.length) {\n\t\treturn undefined;\n\t}\n\n\tif (value === null) {\n\t\treturn thumbIndex === 0 ? matchingMarks[0] : matchingMarks[matchingMarks.length - 1];\n\t}\n\n\treturn matchingMarks[0];\n}\n\n/**\n * Ищет ближайшую mark по публичному output-значению, а не по координате шкалы.\n */\nfunction findClosestRangeMarkByOutputValue(\n\tvalue: number,\n\tmarks: readonly SliderRangeMark[],\n\tthumbIndex: number\n): SliderRangeMark | undefined {\n\tconst exactMark = findRangeMarkByOutputValue(value, marks, thumbIndex);\n\tif (exactMark) {\n\t\treturn exactMark;\n\t}\n\n\tlet nearestMark: SliderRangeMark | undefined;\n\tlet nearestDistance = Number.POSITIVE_INFINITY;\n\n\tfor (const mark of marks) {\n\t\tconst outputValue = getRangeMarkOutputValue(mark);\n\t\tif (typeof outputValue !== \"number\" || !Number.isFinite(outputValue)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst distance = Math.abs(value - outputValue);\n\t\tif (distance < nearestDistance) {\n\t\t\tnearestMark = mark;\n\t\t\tnearestDistance = distance;\n\t\t}\n\t}\n\n\treturn nearestMark;\n}\n\nfunction normalizeRangeEndpoint(\n\tvalue: number | null,\n\tfallbackVisualValue: number,\n\tthumbIndex: number,\n\toptions: SliderMathOptions<SliderRangeMark>\n) {\n\tif (value === null) {\n\t\treturn null;\n\t}\n\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\tconst publicValue = Number.isFinite(value) ? value : fallbackVisualValue;\n\n\tif (marks.length > 0) {\n\t\tconst snappedMark = findClosestRangeMarkByOutputValue(publicValue, marks, thumbIndex);\n\t\tconst outputValue = getRangeMarkOutputValue(snappedMark);\n\n\t\treturn outputValue !== undefined ? outputValue : (snappedMark?.value ?? fallbackVisualValue);\n\t}\n\n\treturn snapNumberScaleValueToStep(publicValue, min, max, options.step);\n}\n\n/**\n * Нормализует публичное range-значение, сохраняя null как открытую границу.\n */\nexport function normalizeRangeSliderValue(\n\tvalue: SliderRangeValue | undefined,\n\toptions: SliderMathOptions<SliderRangeMark>\n): SliderRangeValue {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\n\tif (!value) {\n\t\treturn [null, null];\n\t}\n\n\tconst start = normalizeRangeEndpoint(value[0], min, 0, { ...options, min, max });\n\tconst end = normalizeRangeEndpoint(value[1], max, 1, { ...options, min, max });\n\n\tif (start !== null && end !== null && start > end) {\n\t\treturn [end, start];\n\t}\n\n\treturn [start, end];\n}\n\nfunction getRangeEndpointVisualValue(\n\tvalue: number | null,\n\tfallbackVisualValue: number,\n\tthumbIndex: number,\n\toptions: SliderMathOptions<SliderRangeMark>\n) {\n\tif (value === null) {\n\t\treturn fallbackVisualValue;\n\t}\n\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\tif (marks.length > 0) {\n\t\tconst exactOutputMark = findRangeMarkByOutputValue(value, marks, thumbIndex);\n\t\tconst outputMark =\n\t\t\texactOutputMark ?? (typeof value === \"number\" ? findClosestRangeMarkByOutputValue(value, marks, thumbIndex) : undefined);\n\n\t\treturn outputMark?.value ?? fallbackVisualValue;\n\t}\n\n\treturn snapNumberScaleValueToStep(value, min, max, options.step);\n}\n\n/**\n * Переводит публичный range tuple в finite-позиции thumb, где null стоит на краю шкалы.\n */\nexport function getRangeSliderVisualValue(\n\tvalue: SliderRangeValue | undefined,\n\toptions: SliderMathOptions<SliderRangeMark>\n): [number, number] {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst normalized = normalizeRangeSliderValue(value, { ...options, min, max });\n\tconst start = getRangeEndpointVisualValue(normalized[0], min, 0, { ...options, min, max });\n\tconst end = getRangeEndpointVisualValue(normalized[1], max, 1, { ...options, min, max });\n\n\treturn start <= end ? [start, end] : [end, start];\n}\n\n/**\n * Преобразует координату шкалы, выбранную pointer/keyboard, в публичное range-значение.\n */\nexport function visualValueToRangeEndpoint(value: number, options: SliderMathOptions<SliderRangeMark>) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\tif (marks.length > 0) {\n\t\tconst mark = findClosestNumberScaleMark(value, marks);\n\t\tconst outputValue = getRangeMarkOutputValue(mark);\n\n\t\treturn outputValue !== undefined ? outputValue : (mark?.value ?? value);\n\t}\n\n\treturn snapNumberScaleValueToStep(value, min, max, options.step);\n}\n\nexport function getClosestSliderThumb(targetValue: number, value: readonly [number, number]) {\n\tconst [start, end] = value;\n\treturn Math.abs(targetValue - start) <= Math.abs(targetValue - end) ? 0 : 1;\n}\n\nexport function resolveSliderFillRange(value: number | readonly [number, number], options: SliderMathOptions): SliderFillRange {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\n\tif (Array.isArray(value)) {\n\t\treturn {\n\t\t\tstartPercent: valueToSliderVisualPercent(value[0], { ...options, min, max }),\n\t\t\tendPercent: valueToSliderVisualPercent(value[1], { ...options, min, max })\n\t\t};\n\t}\n\n\treturn {\n\t\tstartPercent: 0,\n\t\tendPercent: valueToSliderVisualPercent(value as number, { ...options, min, max })\n\t};\n}\n","@use \"@/styles/mixins\" as *;\n\n.slider {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--space-sm);\n}\n\n.sliderCompact {\n\tgap: 0;\n}\n\n.trackShell {\n\tposition: relative;\n\tpadding-inline: calc((var(--control-height) - var(--space-xs)) / 2);\n}\n\n.track {\n\tposition: relative;\n\theight: var(--control-height);\n\tcursor: pointer;\n\ttouch-action: none;\n\tuser-select: none;\n}\n\n.rail,\n.fill {\n\tposition: absolute;\n\ttop: 50%;\n\ttransform: translateY(-50%);\n\theight: var(--space-xs);\n\tborder-radius: 999px;\n}\n\n.rail {\n\tleft: 0;\n\tright: 0;\n\tbackground-color: var(--surface-2);\n\tborder: var(--border);\n}\n\n.fill {\n\tbackground-color: var(--content-0);\n}\n\n.thumb {\n\tposition: absolute;\n\ttop: 50%;\n\ttransform: translate(-50%, -50%);\n\twidth: calc(var(--control-height) - var(--space-xs));\n\theight: calc(var(--control-height) - var(--space-xs));\n\tborder: var(--border);\n\tborder-radius: 50%;\n\tbackground-color: var(--surface-0);\n\tcolor: var(--content-0);\n\tbox-shadow: var(--shadow-sm);\n\tcursor: grab;\n\tz-index: 2;\n\ttransition:\n\t\ttransform var(--transition-fast) ease,\n\t\tborder-color var(--transition-fast) ease,\n\t\tbox-shadow var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease;\n\n\t&:active,\n\t&:hover {\n\t\tborder-color: var(--border-1);\n\t}\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t}\n\n\t&[data-dragging] {\n\t\tcursor: grabbing;\n\t\ttransform: translate(-50%, -50%) scale(1.04);\n\t\tbox-shadow: var(--shadow-md);\n\t}\n}\n\n.marks {\n\tposition: relative;\n\tmin-height: calc(var(--font-size-sm) + var(--space-md));\n\tmargin-inline: calc((var(--control-height) - var(--space-xs)) / 2);\n}\n\n.mark {\n\tposition: absolute;\n\ttop: 0;\n\ttransform: translateX(-50%);\n\tdisplay: inline-flex;\n\tflex-direction: column;\n\talign-items: center;\n\tgap: var(--space-xs);\n\tborder: none;\n\tbackground: transparent;\n\tpadding: 0;\n\tcolor: var(--content-2);\n\tcursor: pointer;\n\twhite-space: nowrap;\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t\tborder-radius: var(--radius-sm);\n\t}\n\n\t&[data-active] {\n\t\tcolor: var(--content-0);\n\t}\n}\n\n.compactMark {\n\tposition: absolute;\n\ttop: 50%;\n\ttransform: translate(-50%, -50%);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: var(--control-height);\n\theight: var(--control-height);\n\tborder: none;\n\tbackground: transparent;\n\tpadding: 0;\n\tcolor: var(--content-2);\n\tcursor: pointer;\n\tz-index: 1;\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t\tborder-radius: var(--radius-sm);\n\t}\n\n\t&[data-active] {\n\t\tcolor: var(--content-0);\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\t}\n}\n\n.markDot {\n\twidth: var(--space-sm);\n\theight: var(--space-sm);\n\tborder-radius: 50%;\n\tbackground-color: currentColor;\n\t// opacity: 0.55;\n}\n\n.markLabel {\n\tfont-size: var(--font-size-sm);\n}\n\n.popoverContent {\n\tmin-width: min(24em, calc(100vw - var(--space-xl)));\n}\n\n.rangeInputControl {\n\tgap: var(--space-xs);\n\tcursor: text;\n}\n\n.rangeSegmentInput {\n\tmin-width: 0;\n\twidth: 7ch;\n\tborder: none;\n\tbackground: transparent;\n\toutline: none;\n\tpadding: 0;\n\tmargin: 0;\n\tfont-family: var(--font-family-mono);\n\tcolor: inherit;\n\ttext-align: center;\n\tcaret-color: var(--content-0);\n\tfont-variant-numeric: tabular-nums;\n\n\t&::selection {\n\t\tbackground-color: var(--focus-ring);\n\t\tcolor: var(--surface-0);\n\t}\n\n\t&:disabled {\n\t\topacity: 0.25;\n\t}\n}\n\n.rangeSeparator {\n\tuser-select: none;\n\tcolor: var(--content-2);\n\tflex-shrink: 0;\n\n\t&[data-disabled] {\n\t\topacity: 0.25;\n\t}\n}\n","import React, { KeyboardEvent, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { offsetNumberScaleValue, percentToNumberScaleValue, resolveNumberScaleBounds } from \"@ryuzaki13/react-foundation-lib/number-scale\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputUI, useInputFieldIds } from \"../input\";\nimport { FloatingPopover } from \"../popover\";\nimport { UiBaseProps, UiSize } from \"../types\";\n\nimport {\n\tgetClosestSliderMarkByPercent,\n\tgetClosestSliderThumb,\n\tgetRangeSliderVisualValue,\n\tgetSliderMarkPercent,\n\tnormalizeRangeSliderValue,\n\tnormalizeSingleSliderValue,\n\tprepareSliderMarks,\n\tresolveSliderFillRange,\n\tvalueToSliderVisualPercent,\n\tvisualValueToRangeEndpoint,\n\ttype SliderMark,\n\ttype SliderMarksPosition,\n\ttype SliderRangeMark,\n\ttype SliderRangeValue\n} from \"./lib\";\nimport styles from \"./Slider.module.scss\";\n\ntype SliderMarksDisplay = \"compact\" | \"full\";\n\ninterface SliderCommonProps<TMark extends SliderMark> {\n\t/**\n\t * Минимальная координата шкалы. Marks вне этой границы отбрасываются.\n\t */\n\tmin: number;\n\t/**\n\t * Максимальная координата шкалы. Marks вне этой границы отбрасываются.\n\t */\n\tmax: number;\n\t/**\n\t * Шаг изменения, когда `marks` не заданы или после фильтрации не осталось валидных marks.\n\t */\n\tstep?: number;\n\t/**\n\t * Дискретные точки выбора. Если заданы, бегунок всегда ходит только по marks.\n\t */\n\tmarks?: readonly TMark[];\n\t/**\n\t * Способ визуального размещения marks и бегунка: по числовой координате `value` или равномерно по индексу.\n\t */\n\tmarksPosition?: SliderMarksPosition;\n\t/**\n\t * Внешний CSS-класс контейнера поля.\n\t */\n\tclassName?: string;\n\t/**\n\t * Текст внешней ошибки, отображается через общую `InputUI`-обёртку.\n\t */\n\terror?: string;\n\t/**\n\t * Вызывается после успешного изменения значения, чтобы потребитель мог сбросить внешнюю ошибку.\n\t */\n\tonClearError?: () => void;\n}\n\n/**\n * Single-value slider. Возвращает координату шкалы, потому что single marks не используют `outputValue`.\n */\nexport interface SliderProps extends Omit<UiBaseProps<number, number | undefined>, \"placeholder\">, SliderCommonProps<SliderMark> {}\n\n/**\n * Range slider. Возвращает бизнес-значения `SliderRangeMark.outputValue`, если они заданы, иначе координаты `value`.\n */\nexport interface SliderRangeProps\n\textends Omit<UiBaseProps<SliderRangeValue, SliderRangeValue | undefined>, \"placeholder\">, SliderCommonProps<SliderRangeMark> {}\n\ninterface SliderBaseCommonProps<TMark extends SliderMark> extends SliderCommonProps<TMark> {\n\t/**\n\t * Подпись поля в общей `InputUI`-обёртке.\n\t */\n\tlabel?: React.ReactNode;\n\t/**\n\t * Описание поля под подписью.\n\t */\n\tdescription?: string;\n\t/**\n\t * Блокирует pointer, keyboard и click-взаимодействие.\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Размер общей `InputUI`-обёртки.\n\t */\n\tsize?: UiSize;\n\t/**\n\t * Compact показывает только ticks/tooltip внутри высоты control, full добавляет строку labels для popover.\n\t */\n\tmarksDisplay?: SliderMarksDisplay;\n}\n\ninterface SliderBaseSingleProps extends SliderBaseCommonProps<SliderMark> {\n\tmode: \"single\";\n\tvalue: number | undefined;\n\tonChange: (value: number) => void;\n}\n\ninterface SliderBaseRangeProps extends SliderBaseCommonProps<SliderRangeMark> {\n\tmode: \"range\";\n\tvalue: SliderRangeValue | undefined;\n\tonChange: (value: SliderRangeValue) => void;\n}\n\nexport type SliderBaseProps = SliderBaseSingleProps | SliderBaseRangeProps;\n\nfunction resolveKeyboardOffset(eventKey: string) {\n\tif (eventKey === \"ArrowLeft\" || eventKey === \"ArrowDown\") {\n\t\treturn -1;\n\t}\n\n\tif (eventKey === \"ArrowRight\" || eventKey === \"ArrowUp\") {\n\t\treturn 1;\n\t}\n\n\tif (eventKey === \"PageDown\") {\n\t\treturn -10;\n\t}\n\n\tif (eventKey === \"PageUp\") {\n\t\treturn 10;\n\t}\n\n\treturn null;\n}\n\nfunction areRangeValuesEqual(left: SliderRangeValue | undefined, right: SliderRangeValue) {\n\treturn !!left && left[0] === right[0] && left[1] === right[1];\n}\n\nfunction formatRangeEndpoint(value: number | null, thumbIndex: number) {\n\tif (value === null) {\n\t\treturn thumbIndex === 0 ? \"-∞\" : \"∞\";\n\t}\n\n\treturn String(value);\n}\n\nfunction getMarkLabelByValue<TMark extends SliderMark>(value: number, marks: readonly TMark[]) {\n\treturn marks.find((mark) => mark.value === value)?.label ?? String(value);\n}\n\nfunction renderTooltipContent(content: React.ReactNode) {\n\treturn typeof content === \"string\" || typeof content === \"number\" ? <span className=\"textNoWrap\">{content}</span> : content;\n}\n\nexport function SliderBase(props: SliderBaseProps) {\n\tconst {\n\t\tmin: rawMin,\n\t\tmax: rawMax,\n\t\tstep,\n\t\tmarks,\n\t\tmarksPosition = \"value\",\n\t\tmarksDisplay = \"compact\",\n\t\tclassName,\n\t\terror,\n\t\tonClearError,\n\t\tlabel,\n\t\tdescription,\n\t\tdisabled,\n\t\tsize\n\t} = props;\n\tconst { min, max } = useMemo(() => resolveNumberScaleBounds(rawMin, rawMax), [rawMin, rawMax]);\n\tconst normalizedMarks = useMemo(() => prepareSliderMarks(marks, min, max), [marks, min, max]);\n\tconst sliderOptions = useMemo(\n\t\t() => ({\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tstep,\n\t\t\tmarks: normalizedMarks,\n\t\t\tmarksPosition\n\t\t}),\n\t\t[min, max, step, normalizedMarks, marksPosition]\n\t);\n\n\tconst isRange = props.mode === \"range\";\n\tconst currentSingleValue = !isRange ? normalizeSingleSliderValue(props.value, sliderOptions) : undefined;\n\tconst currentRangeValue = isRange ? normalizeRangeSliderValue(props.value, sliderOptions) : undefined;\n\tconst visualRangeValue = isRange ? getRangeSliderVisualValue(props.value, sliderOptions) : undefined;\n\tconst thumbValues = isRange ? visualRangeValue! : [currentSingleValue!];\n\tconst fillRange = resolveSliderFillRange(isRange ? visualRangeValue! : currentSingleValue!, sliderOptions);\n\n\tconst trackRef = useRef<HTMLDivElement | null>(null);\n\tconst thumbRefs = useRef<Array<HTMLButtonElement | null>>([]);\n\tconst dragThumbIndexRef = useRef<number | null>(null);\n\tconst dragPointerIdRef = useRef<number | null>(null);\n\tconst [dragThumbIndex, setDragThumbIndex] = useState<number | null>(null);\n\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\tconst emitSingleValue = (nextValue: number) => {\n\t\tif (disabled || props.mode !== \"single\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (props.value !== undefined && props.value === nextValue) {\n\t\t\treturn;\n\t\t}\n\n\t\tprops.onChange(nextValue);\n\t\tonClearError?.();\n\t};\n\n\tconst emitRangeValue = (nextValue: SliderRangeValue) => {\n\t\tif (disabled || props.mode !== \"range\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (areRangeValuesEqual(props.value, nextValue)) {\n\t\t\treturn;\n\t\t}\n\n\t\tprops.onChange(nextValue);\n\t\tonClearError?.();\n\t};\n\n\tconst applySliderValue = (rawValue: number, thumbIndex: number) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (props.mode === \"range\") {\n\t\t\tconst [startVisualValue, endVisualValue] = visualRangeValue!;\n\t\t\tconst [startValue, endValue] = currentRangeValue!;\n\t\t\tconst nextValue =\n\t\t\t\tthumbIndex === 0\n\t\t\t\t\t? normalizeRangeSliderValue(\n\t\t\t\t\t\t\t[visualValueToRangeEndpoint(Math.min(rawValue, endVisualValue), sliderOptions), endValue],\n\t\t\t\t\t\t\tsliderOptions\n\t\t\t\t\t\t)\n\t\t\t\t\t: normalizeRangeSliderValue(\n\t\t\t\t\t\t\t[startValue, visualValueToRangeEndpoint(Math.max(rawValue, startVisualValue), sliderOptions)],\n\t\t\t\t\t\t\tsliderOptions\n\t\t\t\t\t\t);\n\n\t\t\temitRangeValue(nextValue);\n\t\t\treturn;\n\t\t}\n\n\t\temitSingleValue(normalizeSingleSliderValue(rawValue, sliderOptions));\n\t};\n\n\tconst resolveValueFromPointer = (clientX: number) => {\n\t\tconst bounds = trackRef.current?.getBoundingClientRect();\n\t\tif (!bounds) {\n\t\t\treturn min;\n\t\t}\n\n\t\tconst percent = ((clientX - bounds.left) / bounds.width) * 100;\n\t\tconst closestMark = normalizedMarks.length > 0 ? getClosestSliderMarkByPercent(percent, sliderOptions) : undefined;\n\n\t\treturn closestMark?.value ?? percentToNumberScaleValue(percent, min, max);\n\t};\n\tconst applySliderValueRef = useRef(applySliderValue);\n\tconst resolveValueFromPointerRef = useRef(resolveValueFromPointer);\n\n\tuseEffect(() => {\n\t\tapplySliderValueRef.current = applySliderValue;\n\t\tresolveValueFromPointerRef.current = resolveValueFromPointer;\n\t});\n\n\tuseEffect(() => {\n\t\tconst onPointerUp = (event?: PointerEvent) => {\n\t\t\tif (dragPointerIdRef.current !== null && event && event.pointerId !== dragPointerIdRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdragPointerIdRef.current = null;\n\t\t\tdragThumbIndexRef.current = null;\n\t\t\tsetDragThumbIndex(null);\n\t\t};\n\n\t\tconst onPointerMove = (event: PointerEvent) => {\n\t\t\tif (dragThumbIndexRef.current === null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (dragPointerIdRef.current !== null && event.pointerId !== dragPointerIdRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tapplySliderValueRef.current(resolveValueFromPointerRef.current(event.clientX), dragThumbIndexRef.current);\n\t\t};\n\n\t\twindow.addEventListener(\"pointermove\", onPointerMove);\n\t\twindow.addEventListener(\"pointerup\", onPointerUp);\n\t\twindow.addEventListener(\"pointercancel\", onPointerUp);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"pointermove\", onPointerMove);\n\t\t\twindow.removeEventListener(\"pointerup\", onPointerUp);\n\t\t\twindow.removeEventListener(\"pointercancel\", onPointerUp);\n\t\t};\n\t}, []);\n\n\tconst beginPointerDrag = (pointerId: number, thumbIndex: number) => {\n\t\tdragPointerIdRef.current = pointerId;\n\t\tdragThumbIndexRef.current = thumbIndex;\n\t\tsetDragThumbIndex(thumbIndex);\n\t\tthumbRefs.current[thumbIndex]?.focus();\n\t};\n\n\tconst handleTrackPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\n\t\tconst rawValue = resolveValueFromPointer(event.clientX);\n\t\tconst thumbIndex = isRange ? getClosestSliderThumb(rawValue, visualRangeValue!) : 0;\n\n\t\tapplySliderValue(rawValue, thumbIndex);\n\t\tbeginPointerDrag(event.pointerId, thumbIndex);\n\t};\n\n\tconst handleThumbPointerDown = (thumbIndex: number) => (event: React.PointerEvent<HTMLButtonElement>) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tbeginPointerDrag(event.pointerId, thumbIndex);\n\t};\n\n\tconst handleThumbKeyDown = (thumbIndex: number) => (event: KeyboardEvent<HTMLButtonElement>) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst lowerBound = isRange && thumbIndex === 1 ? visualRangeValue![0] : min;\n\t\tconst upperBound = isRange && thumbIndex === 0 ? visualRangeValue![1] : max;\n\t\tconst keyboardOffset = resolveKeyboardOffset(event.key);\n\n\t\tif (event.key === \"Home\") {\n\t\t\tevent.preventDefault();\n\t\t\tapplySliderValue(lowerBound, thumbIndex);\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === \"End\") {\n\t\t\tevent.preventDefault();\n\t\t\tapplySliderValue(upperBound, thumbIndex);\n\t\t\treturn;\n\t\t}\n\n\t\tif (keyboardOffset === null) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tconst baseValue = thumbValues[thumbIndex];\n\t\tconst nextValue = offsetNumberScaleValue(baseValue, keyboardOffset, sliderOptions, lowerBound, upperBound);\n\t\tapplySliderValue(nextValue, thumbIndex);\n\t};\n\n\tconst handleMarkSelect = (markValue: number) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst thumbIndex = isRange ? getClosestSliderThumb(markValue, visualRangeValue!) : 0;\n\t\tapplySliderValue(markValue, thumbIndex);\n\t\tthumbRefs.current[thumbIndex]?.focus();\n\t};\n\n\tconst getThumbValueText = (thumbValue: number, thumbIndex: number) => {\n\t\tif (isRange) {\n\t\t\tconst publicValue = currentRangeValue![thumbIndex];\n\t\t\tconst exactMark = normalizedMarks.find((mark) => mark.value === thumbValue);\n\n\t\t\treturn exactMark?.label ?? formatRangeEndpoint(publicValue, thumbIndex);\n\t\t}\n\n\t\treturn getMarkLabelByValue(thumbValue, normalizedMarks);\n\t};\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tclassName={className}\n\t\t\tsize={size}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t<div id={controlId} className={cn(styles.slider, marksDisplay === \"compact\" && styles.sliderCompact)}>\n\t\t\t\t<div className={styles.trackShell}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={trackRef}\n\t\t\t\t\t\tdata-slot=\"track\"\n\t\t\t\t\t\tclassName={styles.track}\n\t\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\t\tonPointerDown={handleTrackPointerDown}>\n\t\t\t\t\t\t<div className={styles.rail} />\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tdata-slot=\"fill\"\n\t\t\t\t\t\t\tclassName={styles.fill}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tleft: `${fillRange.startPercent}%`,\n\t\t\t\t\t\t\t\twidth: `${fillRange.endPercent - fillRange.startPercent}%`\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t{marksDisplay === \"compact\" &&\n\t\t\t\t\t\t\tnormalizedMarks.map((mark) => {\n\t\t\t\t\t\t\t\tconst markPercent = getSliderMarkPercent(mark, normalizedMarks, sliderOptions);\n\t\t\t\t\t\t\t\tconst isActive = isRange\n\t\t\t\t\t\t\t\t\t? mark.value >= visualRangeValue![0] && mark.value <= visualRangeValue![1]\n\t\t\t\t\t\t\t\t\t: mark.value <= currentSingleValue!;\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<FloatingPopover key={mark.value} tooltip placement=\"top\" content={renderTooltipContent(mark.label)}>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tdata-slot=\"mark\"\n\t\t\t\t\t\t\t\t\t\t\tdata-active={isActive ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\t\t\tclassName={styles.compactMark}\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ left: `${markPercent}%` }}\n\t\t\t\t\t\t\t\t\t\t\taria-label={mark.ariaLabel}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleMarkSelect(mark.value)}>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.markDot} aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</FloatingPopover>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\n\t\t\t\t\t\t{thumbValues.map((thumbValue, thumbIndex) => {\n\t\t\t\t\t\t\tconst thumbLabel = getThumbValueText(thumbValue, thumbIndex);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<FloatingPopover\n\t\t\t\t\t\t\t\t\tkey={thumbIndex}\n\t\t\t\t\t\t\t\t\ttooltip\n\t\t\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t\t\t\tcontent={renderTooltipContent(thumbLabel)}\n\t\t\t\t\t\t\t\t\topenDelay={0}\n\t\t\t\t\t\t\t\t\tcloseDelay={100}>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\t\t\t\t\tthumbRefs.current[thumbIndex] = node;\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\trole=\"slider\"\n\t\t\t\t\t\t\t\t\t\tdata-slot=\"thumb\"\n\t\t\t\t\t\t\t\t\t\tdata-thumb-index={thumbIndex}\n\t\t\t\t\t\t\t\t\t\tdata-dragging={dragThumbIndex === thumbIndex ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\t\tclassName={styles.thumb}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\tstyle={{ left: `${valueToSliderVisualPercent(thumbValue, sliderOptions)}%` }}\n\t\t\t\t\t\t\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\t\t\t\t\t\t\taria-orientation=\"horizontal\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin={isRange && thumbIndex === 1 ? visualRangeValue![0] : min}\n\t\t\t\t\t\t\t\t\t\taria-valuemax={isRange && thumbIndex === 0 ? visualRangeValue![1] : max}\n\t\t\t\t\t\t\t\t\t\taria-valuenow={thumbValue}\n\t\t\t\t\t\t\t\t\t\taria-valuetext={\n\t\t\t\t\t\t\t\t\t\t\ttypeof thumbLabel === \"string\" || typeof thumbLabel === \"number\"\n\t\t\t\t\t\t\t\t\t\t\t\t? String(thumbLabel)\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\t\t\tlabelId\n\t\t\t\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t\t\t\t: isRange\n\t\t\t\t\t\t\t\t\t\t\t\t\t? thumbIndex === 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"Минимальное значение\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Максимальное значение\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Значение\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tonPointerDown={handleThumbPointerDown(thumbIndex)}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleThumbKeyDown(thumbIndex)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FloatingPopover>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{marksDisplay === \"full\" && normalizedMarks.length > 0 && (\n\t\t\t\t\t<div className={styles.marks}>\n\t\t\t\t\t\t{normalizedMarks.map((mark) => {\n\t\t\t\t\t\t\tconst isActive = isRange\n\t\t\t\t\t\t\t\t? mark.value >= visualRangeValue![0] && mark.value <= visualRangeValue![1]\n\t\t\t\t\t\t\t\t: mark.value <= currentSingleValue!;\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={mark.value}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdata-slot=\"mark\"\n\t\t\t\t\t\t\t\t\tdata-active={isActive ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\tclassName={styles.mark}\n\t\t\t\t\t\t\t\t\tstyle={{ left: `${getSliderMarkPercent(mark, normalizedMarks, sliderOptions)}%` }}\n\t\t\t\t\t\t\t\t\taria-label={mark.ariaLabel}\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonClick={() => handleMarkSelect(mark.value)}>\n\t\t\t\t\t\t\t\t\t<span className={styles.markDot} aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t<span className={styles.markLabel}>{mark.label}</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</InputUI>\n\t);\n}\n\nexport function Slider(props: SliderProps) {\n\treturn <SliderBase {...props} mode=\"single\" marksDisplay=\"compact\" />;\n}\n\nexport function SliderRange(props: SliderRangeProps) {\n\treturn <SliderBase {...props} mode=\"range\" marksDisplay=\"compact\" />;\n}\n","import { KeyboardEvent, useCallback, useEffect, useEffectEvent, useMemo, useState } from \"react\";\n\nimport { toFiniteNumber } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { resolveNumberScaleBounds } from \"@ryuzaki13/react-foundation-lib/number-scale\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputText, InputUI, useInputFieldIds } from \"../input\";\nimport { PickerTriggerActions } from \"../picker\";\nimport { Popover } from \"../popover\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport {\n\tgetRangeMarkOutputValue,\n\tnormalizeRangeSliderValue,\n\tnormalizeSingleSliderValue,\n\tprepareSliderMarks,\n\ttype SliderMark,\n\ttype SliderMarksPosition,\n\ttype SliderRangeMark,\n\ttype SliderRangeValue\n} from \"./lib\";\nimport { SliderBase } from \"./Slider\";\nimport styles from \"./Slider.module.scss\";\n\ninterface SliderInputCommonProps {\n\t/**\n\t * Минимальная координата шкалы. Marks вне этой границы не участвуют в выборе.\n\t */\n\tmin: number;\n\t/**\n\t * Максимальная координата шкалы. Marks вне этой границы не участвуют в выборе.\n\t */\n\tmax: number;\n\t/**\n\t * Шаг ручного ввода и слайдера, если не заданы marks.\n\t */\n\tstep?: number;\n\t/**\n\t * Способ визуального размещения marks и бегунка в popover.\n\t */\n\tmarksPosition?: SliderMarksPosition;\n\t/**\n\t * Внешний CSS-класс общей обёртки поля.\n\t */\n\tclassName?: string;\n\t/**\n\t * Текст внешней ошибки.\n\t */\n\terror?: string;\n\t/**\n\t * Сбрасывает внешнюю ошибку после успешного commit или выбора в popover.\n\t */\n\tonClearError?: () => void;\n}\n\nexport interface SliderInputProps extends UiBaseProps<number, number | undefined>, SliderInputCommonProps {\n\t/**\n\t * Marks single-слайдера. Single-компонент отдаёт наружу `mark.value`.\n\t */\n\tmarks?: readonly SliderMark[];\n}\n\nexport interface SliderRangeInputProps extends UiBaseProps<SliderRangeValue, SliderRangeValue | undefined>, SliderInputCommonProps {\n\t/**\n\t * Marks range-слайдера. `value` задаёт координату на шкале, `outputValue` задаёт публичное значение для потребителя.\n\t */\n\tmarks?: readonly SliderRangeMark[];\n\t/**\n\t * Показывает вместо ручных сегментов готовый текст по выбранным marks.\n\t * Popover остаётся единственным способом изменить значение через слайдер, а потребитель получает изменение при закрытии popover.\n\t */\n\treadonlyValueText?: boolean;\n}\n\nfunction createSliderToggle({\n\topen,\n\tdisabled,\n\tsetOpen\n}: {\n\topen: boolean;\n\tdisabled?: boolean;\n\tsetOpen: (nextOpen: boolean | ((prev: boolean) => boolean)) => void;\n}) {\n\treturn (\n\t\t<Popover.Trigger passive>\n\t\t\t<div>\n\t\t\t\t<PickerTriggerActions\n\t\t\t\t\topen={open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\topenAriaLabel=\"Открыть слайдер\"\n\t\t\t\t\tcloseAriaLabel=\"Закрыть слайдер\"\n\t\t\t\t\tonToggleMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\tonToggleClick={() => setOpen((prev) => !prev)}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</Popover.Trigger>\n\t);\n}\n\nfunction formatRangeDraft(\n\tvalue: SliderRangeValue | undefined,\n\toptions: {\n\t\tmin: number;\n\t\tmax: number;\n\t\tstep?: number;\n\t\tmarks?: readonly SliderRangeMark[];\n\t\tmarksPosition?: SliderMarksPosition;\n\t}\n) {\n\tconst normalized = normalizeRangeSliderValue(value, options);\n\n\treturn {\n\t\tstart: normalized[0] === null ? \"-∞\" : String(normalized[0]),\n\t\tend: normalized[1] === null ? \"∞\" : String(normalized[1])\n\t};\n}\n\nfunction parseRangeDraftSegment(value: string, infinityText: string) {\n\tconst trimmed = value.trim();\n\tif (trimmed === \"\" || trimmed === infinityText) {\n\t\treturn null;\n\t}\n\n\treturn toFiniteNumber(trimmed);\n}\n\nfunction getRangeMarkByOutputValue(value: number | null, marks: readonly SliderRangeMark[], endpoint: \"start\" | \"end\") {\n\tconst matchingMarks = marks.filter((mark) => getRangeMarkOutputValue(mark) === value);\n\n\tif (!matchingMarks.length) {\n\t\treturn undefined;\n\t}\n\n\treturn value === null && endpoint === \"end\" ? matchingMarks[matchingMarks.length - 1] : matchingMarks[0];\n}\n\nfunction getRangeMarkReadonlyLabel(mark: SliderRangeMark | undefined, value: number | null) {\n\tif (mark?.readonlyLabel?.trim()) {\n\t\treturn mark.readonlyLabel.trim();\n\t}\n\n\tif (typeof mark?.label === \"string\" || typeof mark?.label === \"number\") {\n\t\treturn String(mark.label);\n\t}\n\t// SHARE: lib/formatters/string.toSafeString\n\treturn value === null ? \"\" : String(value);\n}\n\nfunction getRangeEndpointLabel(value: number | null, marks: readonly SliderRangeMark[], endpoint: \"start\" | \"end\") {\n\tconst mark = getRangeMarkByOutputValue(value, marks, endpoint);\n\treturn getRangeMarkReadonlyLabel(mark, value);\n}\n\nfunction getRangeReadonlyText(value: SliderRangeValue, marks: readonly SliderRangeMark[], placeholder?: string) {\n\tconst [start, end] = value;\n\tconst isStartOpen = start === null;\n\tconst isEndOpen = end === null;\n\n\tif (isStartOpen && isEndOpen) {\n\t\treturn placeholder ?? \"\";\n\t}\n\n\tif (isStartOpen) {\n\t\treturn `Меньше ${getRangeEndpointLabel(end, marks, \"end\")}`;\n\t}\n\n\tif (isEndOpen) {\n\t\treturn `Больше ${getRangeEndpointLabel(start, marks, \"start\")}`;\n\t}\n\n\tif (start === end) {\n\t\treturn `Равно ${getRangeEndpointLabel(start, marks, \"start\")}`;\n\t}\n\n\treturn `От ${getRangeEndpointLabel(start, marks, \"start\")} до ${getRangeEndpointLabel(end, marks, \"end\")}`;\n}\n\nexport function SliderInput({\n\tvalue,\n\tonChange,\n\tmin: rawMin,\n\tmax: rawMax,\n\tstep,\n\tmarks,\n\tmarksPosition = \"value\",\n\tclassName,\n\terror,\n\tonClearError,\n\tlabel,\n\tdescription,\n\tplaceholder,\n\tdisabled,\n\tsize\n}: SliderInputProps) {\n\tconst { min, max } = useMemo(() => resolveNumberScaleBounds(rawMin, rawMax), [rawMin, rawMax]);\n\tconst normalizedMarks = useMemo(() => prepareSliderMarks(marks, min, max), [marks, min, max]);\n\tconst sliderOptions = useMemo(\n\t\t() => ({\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tstep,\n\t\t\tmarks: normalizedMarks,\n\t\t\tmarksPosition\n\t\t}),\n\t\t[min, max, step, normalizedMarks, marksPosition]\n\t);\n\tconst normalizedValue = normalizeSingleSliderValue(value, sliderOptions);\n\n\tconst [open, setOpen] = useState(false);\n\tconst [draftValue, setDraftValue] = useState(String(normalizedValue));\n\n\tconst syncDraftValue = useEffectEvent((nextValue: string) => {\n\t\tsetDraftValue(nextValue);\n\t});\n\n\tuseEffect(() => {\n\t\tsyncDraftValue(String(normalizedValue));\n\t}, [normalizedValue]);\n\n\tconst commitDraftValue = useCallback(() => {\n\t\tif (disabled) {\n\t\t\tsetDraftValue(String(normalizedValue));\n\t\t\treturn;\n\t\t}\n\n\t\tconst parsedValue = toFiniteNumber(draftValue);\n\t\tif (parsedValue === undefined) {\n\t\t\tsetDraftValue(String(normalizedValue));\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextValue = normalizeSingleSliderValue(parsedValue, sliderOptions);\n\t\tif (value !== nextValue) {\n\t\t\tonChange(nextValue);\n\t\t\tonClearError?.();\n\t\t}\n\n\t\tsetDraftValue(String(nextValue));\n\t}, [disabled, draftValue, normalizedValue, onChange, onClearError, sliderOptions, value]);\n\n\tconst handleDraftKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key !== \"Enter\") {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tcommitDraftValue();\n\t};\n\n\tconst handleSliderChange = (nextValue: number) => {\n\t\tonChange(nextValue);\n\t\tsetDraftValue(String(nextValue));\n\t\tonClearError?.();\n\t};\n\n\treturn (\n\t\t<Popover open={open} onOpenChange={setOpen}>\n\t\t\t<InputText\n\t\t\t\tlabel={label}\n\t\t\t\tdescription={description}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tsize={size}\n\t\t\t\tclassName={className}\n\t\t\t\terror={error}\n\t\t\t\tvalue={draftValue}\n\t\t\t\tonChange={setDraftValue}\n\t\t\t\tonBlur={commitDraftValue}\n\t\t\t\tonKeyDown={handleDraftKeyDown}\n\t\t\t\tendAdornmentWidth=\"var(--control-height)\"\n\t\t\t\tendAdornment={createSliderToggle({ open, disabled, setOpen })}\n\t\t\t/>\n\n\t\t\t<Popover.Content background=\"primary\">\n\t\t\t\t<div className={styles.popoverContent}>\n\t\t\t\t\t<SliderBase\n\t\t\t\t\t\tmode=\"single\"\n\t\t\t\t\t\tmin={min}\n\t\t\t\t\t\tmax={max}\n\t\t\t\t\t\tstep={step}\n\t\t\t\t\t\tmarks={normalizedMarks}\n\t\t\t\t\t\tmarksPosition={marksPosition}\n\t\t\t\t\t\tmarksDisplay=\"full\"\n\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\tonChange={handleSliderChange}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</Popover.Content>\n\t\t</Popover>\n\t);\n}\n\nexport function SliderRangeInput({\n\tvalue,\n\tonChange,\n\tmin: rawMin,\n\tmax: rawMax,\n\tstep,\n\tmarks,\n\tmarksPosition = \"value\",\n\tclassName,\n\terror,\n\tonClearError,\n\tlabel,\n\tdescription,\n\treadonlyValueText,\n\tplaceholder,\n\tdisabled,\n\tsize\n}: SliderRangeInputProps) {\n\tconst { min, max } = useMemo(() => resolveNumberScaleBounds(rawMin, rawMax), [rawMin, rawMax]);\n\tconst normalizedMarks = useMemo(() => prepareSliderMarks(marks, min, max), [marks, min, max]);\n\tconst sliderOptions = useMemo(\n\t\t() => ({\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tstep,\n\t\t\tmarks: normalizedMarks,\n\t\t\tmarksPosition\n\t\t}),\n\t\t[min, max, step, normalizedMarks, marksPosition]\n\t);\n\tconst normalizedValue = useMemo(() => normalizeRangeSliderValue(value, sliderOptions), [sliderOptions, value]);\n\tconst formattedValue = useMemo(() => formatRangeDraft(normalizedValue, sliderOptions), [normalizedValue, sliderOptions]);\n\n\tconst [open, setOpen] = useState(false);\n\tconst [draftStart, setDraftStart] = useState(formattedValue.start);\n\tconst [draftEnd, setDraftEnd] = useState(formattedValue.end);\n\tconst [popoverValue, setPopoverValue] = useState<SliderRangeValue>(normalizedValue);\n\n\tconst syncDraftValue = useEffectEvent((start: string, end: string) => {\n\t\tsetDraftStart(start);\n\t\tsetDraftEnd(end);\n\t});\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\treturn;\n\t\t}\n\n\t\tsyncDraftValue(formattedValue.start, formattedValue.end);\n\t}, [formattedValue.start, formattedValue.end, normalizedValue, open]);\n\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\tconst rollbackDraftValue = useCallback(() => {\n\t\tsetDraftStart(formattedValue.start);\n\t\tsetDraftEnd(formattedValue.end);\n\t}, [formattedValue.end, formattedValue.start]);\n\n\tconst commitDraftValue = useCallback(() => {\n\t\tif (disabled) {\n\t\t\trollbackDraftValue();\n\t\t\treturn;\n\t\t}\n\n\t\tconst parsedStart = parseRangeDraftSegment(draftStart, \"-∞\");\n\t\tconst parsedEnd = parseRangeDraftSegment(draftEnd, \"∞\");\n\n\t\tif (parsedStart === undefined || parsedEnd === undefined) {\n\t\t\trollbackDraftValue();\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextValue = normalizeRangeSliderValue([parsedStart, parsedEnd], sliderOptions);\n\t\tif (!areRangeDraftValuesEqual(normalizedValue, nextValue)) {\n\t\t\tonChange(nextValue);\n\t\t\tonClearError?.();\n\t\t}\n\n\t\tconst nextDraft = formatRangeDraft(nextValue, sliderOptions);\n\t\tsetDraftStart(nextDraft.start);\n\t\tsetDraftEnd(nextDraft.end);\n\t\tsetPopoverValue(nextValue);\n\t}, [disabled, draftEnd, draftStart, normalizedValue, onChange, onClearError, rollbackDraftValue, sliderOptions]);\n\n\tconst commitPopoverValue = useCallback(\n\t\t(nextValue: SliderRangeValue) => {\n\t\t\tconst normalizedNextValue = normalizeRangeSliderValue(nextValue, sliderOptions);\n\t\t\tif (!areRangeDraftValuesEqual(normalizedValue, normalizedNextValue)) {\n\t\t\t\tonChange(normalizedNextValue);\n\t\t\t\tonClearError?.();\n\t\t\t}\n\n\t\t\tconst nextDraft = formatRangeDraft(normalizedNextValue, sliderOptions);\n\t\t\tsetDraftStart(nextDraft.start);\n\t\t\tsetDraftEnd(nextDraft.end);\n\t\t\tsetPopoverValue(normalizedNextValue);\n\t\t},\n\t\t[normalizedValue, onChange, onClearError, sliderOptions]\n\t);\n\n\tconst handleOpenChange = (nextOpen: boolean) => {\n\t\tif (!open && nextOpen) {\n\t\t\tsetPopoverValue(normalizedValue);\n\t\t\tsetDraftStart(formattedValue.start);\n\t\t\tsetDraftEnd(formattedValue.end);\n\t\t}\n\n\t\tif (open && !nextOpen && !disabled) {\n\t\t\tcommitPopoverValue(popoverValue);\n\t\t}\n\n\t\tsetOpen(nextOpen);\n\t};\n\n\tconst handleDraftKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key !== \"Enter\") {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tcommitDraftValue();\n\t};\n\n\tconst handleSliderChange = (nextValue: SliderRangeValue) => {\n\t\tconst normalizedNextValue = normalizeRangeSliderValue(nextValue, sliderOptions);\n\t\tsetPopoverValue(normalizedNextValue);\n\t\tconst nextDraft = formatRangeDraft(normalizedNextValue, sliderOptions);\n\t\tsetDraftStart(nextDraft.start);\n\t\tsetDraftEnd(nextDraft.end);\n\t};\n\tconst displayValue = open ? popoverValue : normalizedValue;\n\tconst readonlyTextValue = readonlyValueText ? getRangeReadonlyText(displayValue, normalizedMarks, placeholder) : undefined;\n\tconst setRangeOpen = (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n\t\thandleOpenChange(typeof nextOpen === \"function\" ? nextOpen(open) : nextOpen);\n\t};\n\n\treturn (\n\t\t<Popover open={open} onOpenChange={handleOpenChange}>\n\t\t\t<InputUI\n\t\t\t\tlabel={label}\n\t\t\t\tdescription={description}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tclassName={className}\n\t\t\t\tsize={size}\n\t\t\t\terror={error}\n\t\t\t\tcontrolId={controlId}\n\t\t\t\tlabelId={labelId}\n\t\t\t\tdescriptionId={descriptionId}\n\t\t\t\terrorId={errorId}>\n\t\t\t\t<InputControl\n\t\t\t\t\tendAdornmentWidth=\"var(--control-height)\"\n\t\t\t\t\tendAdornment={createSliderToggle({ open, disabled, setOpen: setRangeOpen })}>\n\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tid={controlId}\n\t\t\t\t\t\t\tclassName={cn(uiStyles.uiInputControlFake, styles.rangeInputControl, controlClassName)}\n\t\t\t\t\t\t\tdata-invalid={error ? \"\" : undefined}\n\t\t\t\t\t\t\tdata-disabled={disabled || undefined}\n\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\taria-invalid={!!error || undefined}\n\t\t\t\t\t\t\taria-label={typeof label === \"string\" ? label : \"Диапазон\"}\n\t\t\t\t\t\t\taria-labelledby={typeof label === \"string\" ? undefined : labelId}\n\t\t\t\t\t\t\taria-describedby={describedBy}>\n\t\t\t\t\t\t\t{readonlyValueText ? (\n\t\t\t\t\t\t\t\t<span className={cn(\"flexEllipsis\", !readonlyTextValue && uiStyles.uiPlaceholder)}>\n\t\t\t\t\t\t\t\t\t{readonlyTextValue || placeholder}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\t\t\tclassName={styles.rangeSegmentInput}\n\t\t\t\t\t\t\t\t\t\tvalue={draftStart}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\taria-label=\"Начало диапазона\"\n\t\t\t\t\t\t\t\t\t\tonChange={(event) => setDraftStart(event.target.value)}\n\t\t\t\t\t\t\t\t\t\tonBlur={commitDraftValue}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleDraftKeyDown}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<span className={styles.rangeSeparator} data-disabled={disabled || undefined}>\n\t\t\t\t\t\t\t\t\t\t-\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\t\t\tclassName={styles.rangeSegmentInput}\n\t\t\t\t\t\t\t\t\t\tvalue={draftEnd}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\taria-label=\"Конец диапазона\"\n\t\t\t\t\t\t\t\t\t\tonChange={(event) => setDraftEnd(event.target.value)}\n\t\t\t\t\t\t\t\t\t\tonBlur={commitDraftValue}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleDraftKeyDown}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</InputControl>\n\t\t\t</InputUI>\n\n\t\t\t<Popover.Content background=\"primary\">\n\t\t\t\t<div className={styles.popoverContent}>\n\t\t\t\t\t<SliderBase\n\t\t\t\t\t\tmode=\"range\"\n\t\t\t\t\t\tmin={min}\n\t\t\t\t\t\tmax={max}\n\t\t\t\t\t\tstep={step}\n\t\t\t\t\t\tmarks={normalizedMarks}\n\t\t\t\t\t\tmarksPosition={marksPosition}\n\t\t\t\t\t\tmarksDisplay=\"full\"\n\t\t\t\t\t\tvalue={popoverValue}\n\t\t\t\t\t\tonChange={handleSliderChange}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</Popover.Content>\n\t\t</Popover>\n\t);\n}\n\nfunction areRangeDraftValuesEqual(left: SliderRangeValue, right: SliderRangeValue) {\n\treturn left[0] === right[0] && left[1] === right[1];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"slider-BqeYbdrg.js","names":[],"sources":["../../src/slider/lib/sliderMath.ts","../../src/slider/Slider.module.scss","../../src/slider/Slider.tsx","../../src/slider/SliderInput.tsx"],"sourcesContent":["import {\n\tfindClosestNumberScaleMark,\n\tfindClosestNumberScaleMarkByPercent,\n\tgetNumberScaleMarkPercent,\n\tprepareNumberScaleMarks,\n\tresolveNumberScaleBounds,\n\tsnapNumberScaleValue,\n\tsnapNumberScaleValueToStep,\n\tvalueToNumberScalePercent\n} from \"@ryuzaki13/react-foundation-lib/number-scale\";\nimport { resolveRangeOutputValue } from \"@ryuzaki13/react-foundation-lib/range-output\";\n\nimport { SliderFillRange, SliderMark, SliderMathOptions, SliderRangeMark, SliderRangeOutputValueFallback, SliderRangeValue } from \"./types\";\n\nexport function prepareSliderMarks<TMark extends SliderMark>(marks: readonly TMark[] | undefined, min: number, max: number): TMark[] {\n\treturn prepareNumberScaleMarks(marks, min, max);\n}\n\nexport function getSliderMarkPercent<TMark extends SliderMark>(mark: TMark, marks: readonly TMark[], options: SliderMathOptions<TMark>) {\n\tconst markIndex = marks.findIndex((item) => item.value === mark.value);\n\treturn getNumberScaleMarkPercent(Math.max(0, markIndex), marks, options.min, options.max, options.marksPosition);\n}\n\n/**\n * Возвращает визуальную позицию значения: по шкале min/max или по позиции ближайшей mark.\n */\nexport function valueToSliderVisualPercent<TMark extends SliderMark>(value: number, options: SliderMathOptions<TMark>) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\tif (marks.length > 0) {\n\t\tconst exactMark = marks.find((mark) => mark.value === value);\n\t\tconst mark = exactMark ?? findClosestNumberScaleMark(value, marks);\n\n\t\tif (mark) {\n\t\t\treturn getSliderMarkPercent(mark, marks, { ...options, min, max, marks });\n\t\t}\n\t}\n\n\treturn valueToNumberScalePercent(value, min, max);\n}\n\n/**\n * Возвращает mark, который визуально ближе всего к pointer percent.\n */\nexport function getClosestSliderMarkByPercent<TMark extends SliderMark>(percent: number, options: SliderMathOptions<TMark>) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\treturn findClosestNumberScaleMarkByPercent(percent, marks, min, max, options.marksPosition);\n}\n\nexport function snapSliderValue<TMark extends SliderMark>(value: number, options: SliderMathOptions<TMark>) {\n\treturn snapNumberScaleValue(value, options);\n}\n\nexport function normalizeSingleSliderValue(value: number | undefined, options: SliderMathOptions) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\n\tif (value === undefined) {\n\t\treturn min;\n\t}\n\n\treturn snapSliderValue(value, { ...options, min, max });\n}\n\n/**\n * Возвращает публичное значение mark: `outputValue`, если оно задано, иначе координату `value`.\n */\nexport function getRangeMarkOutputValue(mark: SliderRangeMark | undefined): number | null | undefined {\n\tif (!mark) {\n\t\treturn undefined;\n\t}\n\n\tif (!Object.hasOwn(mark, \"outputValue\") || mark.outputValue === undefined) {\n\t\treturn mark.value;\n\t}\n\n\treturn mark.outputValue;\n}\n\n/**\n * Готовит range-значение к внешней сериализации, заменяя открытые границы на заданные подстановки.\n *\n * Функция не участвует во внутренней логике слайдера: `SliderRange` и `SliderRangeInput`\n * продолжают отдавать `null` через `onChange`, а потребитель явно применяет подстановку\n * рядом со своим обработчиком сохранения/отправки.\n */\nexport function resolveSliderRangeOutputValue(\n\tvalue: SliderRangeValue,\n\tfallback: SliderRangeOutputValueFallback | undefined\n): SliderRangeValue {\n\treturn resolveRangeOutputValue(value, fallback);\n}\n\nfunction findRangeMarkByOutputValue(\n\tvalue: number | null,\n\tmarks: readonly SliderRangeMark[],\n\tthumbIndex: number\n): SliderRangeMark | undefined {\n\tconst matchingMarks = marks.filter((mark) => getRangeMarkOutputValue(mark) === value);\n\n\tif (!matchingMarks.length) {\n\t\treturn undefined;\n\t}\n\n\tif (value === null) {\n\t\treturn thumbIndex === 0 ? matchingMarks[0] : matchingMarks[matchingMarks.length - 1];\n\t}\n\n\treturn matchingMarks[0];\n}\n\n/**\n * Ищет ближайшую mark по публичному output-значению, а не по координате шкалы.\n */\nfunction findClosestRangeMarkByOutputValue(\n\tvalue: number,\n\tmarks: readonly SliderRangeMark[],\n\tthumbIndex: number\n): SliderRangeMark | undefined {\n\tconst exactMark = findRangeMarkByOutputValue(value, marks, thumbIndex);\n\tif (exactMark) {\n\t\treturn exactMark;\n\t}\n\n\tlet nearestMark: SliderRangeMark | undefined;\n\tlet nearestDistance = Number.POSITIVE_INFINITY;\n\n\tfor (const mark of marks) {\n\t\tconst outputValue = getRangeMarkOutputValue(mark);\n\t\tif (typeof outputValue !== \"number\" || !Number.isFinite(outputValue)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst distance = Math.abs(value - outputValue);\n\t\tif (distance < nearestDistance) {\n\t\t\tnearestMark = mark;\n\t\t\tnearestDistance = distance;\n\t\t}\n\t}\n\n\treturn nearestMark;\n}\n\nfunction normalizeRangeEndpoint(\n\tvalue: number | null,\n\tfallbackVisualValue: number,\n\tthumbIndex: number,\n\toptions: SliderMathOptions<SliderRangeMark>\n) {\n\tif (value === null) {\n\t\treturn null;\n\t}\n\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\tconst publicValue = Number.isFinite(value) ? value : fallbackVisualValue;\n\n\tif (marks.length > 0) {\n\t\tconst snappedMark = findClosestRangeMarkByOutputValue(publicValue, marks, thumbIndex);\n\t\tconst outputValue = getRangeMarkOutputValue(snappedMark);\n\n\t\treturn outputValue !== undefined ? outputValue : (snappedMark?.value ?? fallbackVisualValue);\n\t}\n\n\treturn snapNumberScaleValueToStep(publicValue, min, max, options.step);\n}\n\n/**\n * Нормализует публичное range-значение, сохраняя null как открытую границу.\n */\nexport function normalizeRangeSliderValue(\n\tvalue: SliderRangeValue | undefined,\n\toptions: SliderMathOptions<SliderRangeMark>\n): SliderRangeValue {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\n\tif (!value) {\n\t\treturn [null, null];\n\t}\n\n\tconst start = normalizeRangeEndpoint(value[0], min, 0, { ...options, min, max });\n\tconst end = normalizeRangeEndpoint(value[1], max, 1, { ...options, min, max });\n\n\tif (start !== null && end !== null && start > end) {\n\t\treturn [end, start];\n\t}\n\n\treturn [start, end];\n}\n\nfunction getRangeEndpointVisualValue(\n\tvalue: number | null,\n\tfallbackVisualValue: number,\n\tthumbIndex: number,\n\toptions: SliderMathOptions<SliderRangeMark>\n) {\n\tif (value === null) {\n\t\treturn fallbackVisualValue;\n\t}\n\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\tif (marks.length > 0) {\n\t\tconst exactOutputMark = findRangeMarkByOutputValue(value, marks, thumbIndex);\n\t\tconst outputMark =\n\t\t\texactOutputMark ?? (typeof value === \"number\" ? findClosestRangeMarkByOutputValue(value, marks, thumbIndex) : undefined);\n\n\t\treturn outputMark?.value ?? fallbackVisualValue;\n\t}\n\n\treturn snapNumberScaleValueToStep(value, min, max, options.step);\n}\n\n/**\n * Переводит публичный range tuple в finite-позиции thumb, где null стоит на краю шкалы.\n */\nexport function getRangeSliderVisualValue(\n\tvalue: SliderRangeValue | undefined,\n\toptions: SliderMathOptions<SliderRangeMark>\n): [number, number] {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst normalized = normalizeRangeSliderValue(value, { ...options, min, max });\n\tconst start = getRangeEndpointVisualValue(normalized[0], min, 0, { ...options, min, max });\n\tconst end = getRangeEndpointVisualValue(normalized[1], max, 1, { ...options, min, max });\n\n\treturn start <= end ? [start, end] : [end, start];\n}\n\n/**\n * Преобразует координату шкалы, выбранную pointer/keyboard, в публичное range-значение.\n */\nexport function visualValueToRangeEndpoint(value: number, options: SliderMathOptions<SliderRangeMark>) {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\tconst marks = prepareSliderMarks(options.marks, min, max);\n\n\tif (marks.length > 0) {\n\t\tconst mark = findClosestNumberScaleMark(value, marks);\n\t\tconst outputValue = getRangeMarkOutputValue(mark);\n\n\t\treturn outputValue !== undefined ? outputValue : (mark?.value ?? value);\n\t}\n\n\treturn snapNumberScaleValueToStep(value, min, max, options.step);\n}\n\nexport function getClosestSliderThumb(targetValue: number, value: readonly [number, number]) {\n\tconst [start, end] = value;\n\treturn Math.abs(targetValue - start) <= Math.abs(targetValue - end) ? 0 : 1;\n}\n\nexport function resolveSliderFillRange(value: number | readonly [number, number], options: SliderMathOptions): SliderFillRange {\n\tconst { min, max } = resolveNumberScaleBounds(options.min, options.max);\n\n\tif (Array.isArray(value)) {\n\t\treturn {\n\t\t\tstartPercent: valueToSliderVisualPercent(value[0], { ...options, min, max }),\n\t\t\tendPercent: valueToSliderVisualPercent(value[1], { ...options, min, max })\n\t\t};\n\t}\n\n\treturn {\n\t\tstartPercent: 0,\n\t\tendPercent: valueToSliderVisualPercent(value as number, { ...options, min, max })\n\t};\n}\n","@use \"@/styles/mixins\" as *;\n\n.slider {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--space-sm);\n}\n\n.sliderCompact {\n\tgap: 0;\n}\n\n.trackShell {\n\tposition: relative;\n\tpadding-inline: calc((var(--control-height) - var(--space-xs)) / 2);\n}\n\n.track {\n\tposition: relative;\n\theight: var(--control-height);\n\tcursor: pointer;\n\ttouch-action: none;\n\tuser-select: none;\n}\n\n.rail,\n.fill {\n\tposition: absolute;\n\ttop: 50%;\n\ttransform: translateY(-50%);\n\theight: var(--space-xs);\n\tborder-radius: 999px;\n}\n\n.rail {\n\tleft: 0;\n\tright: 0;\n\tbackground-color: var(--surface-2);\n\tborder: var(--border);\n}\n\n.fill {\n\tbackground-color: var(--content-0);\n}\n\n.thumb {\n\tposition: absolute;\n\ttop: 50%;\n\ttransform: translate(-50%, -50%);\n\twidth: calc(var(--control-height) - var(--space-xs));\n\theight: calc(var(--control-height) - var(--space-xs));\n\tborder: var(--border);\n\tborder-radius: 50%;\n\tbackground-color: var(--surface-0);\n\tcolor: var(--content-0);\n\tbox-shadow: var(--shadow-sm);\n\tcursor: grab;\n\tz-index: 2;\n\ttransition:\n\t\ttransform var(--transition-fast) ease,\n\t\tborder-color var(--transition-fast) ease,\n\t\tbox-shadow var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease;\n\n\t&:active,\n\t&:hover {\n\t\tborder-color: var(--border-1);\n\t}\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t}\n\n\t&[data-dragging] {\n\t\tcursor: grabbing;\n\t\ttransform: translate(-50%, -50%) scale(1.04);\n\t\tbox-shadow: var(--shadow-md);\n\t}\n}\n\n.marks {\n\tposition: relative;\n\tmin-height: calc(var(--font-size-sm) + var(--space-md));\n\tmargin-inline: calc((var(--control-height) - var(--space-xs)) / 2);\n}\n\n.mark {\n\tposition: absolute;\n\ttop: 0;\n\ttransform: translateX(-50%);\n\tdisplay: inline-flex;\n\tflex-direction: column;\n\talign-items: center;\n\tgap: var(--space-xs);\n\tborder: none;\n\tbackground: transparent;\n\tpadding: 0;\n\tcolor: var(--content-2);\n\tcursor: pointer;\n\twhite-space: nowrap;\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t\tborder-radius: var(--radius-sm);\n\t}\n\n\t&[data-active] {\n\t\tcolor: var(--content-0);\n\t}\n}\n\n.compactMark {\n\tposition: absolute;\n\ttop: 50%;\n\ttransform: translate(-50%, -50%);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: var(--control-height);\n\theight: var(--control-height);\n\tborder: none;\n\tbackground: transparent;\n\tpadding: 0;\n\tcolor: var(--content-2);\n\tcursor: pointer;\n\tz-index: 1;\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t\tborder-radius: var(--radius-sm);\n\t}\n\n\t&[data-active] {\n\t\tcolor: var(--content-0);\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\t}\n}\n\n.markDot {\n\twidth: var(--space-sm);\n\theight: var(--space-sm);\n\tborder-radius: 50%;\n\tbackground-color: currentColor;\n\t// opacity: 0.55;\n}\n\n.markLabel {\n\tfont-size: var(--font-size-sm);\n}\n\n.popoverContent {\n\tmin-width: min(24em, calc(100vw - var(--space-xl)));\n}\n\n.rangeInputControl {\n\tgap: var(--space-xs);\n\tcursor: text;\n}\n\n.rangeSegmentInput {\n\tmin-width: 0;\n\twidth: 7ch;\n\tborder: none;\n\tbackground: transparent;\n\toutline: none;\n\tpadding: 0;\n\tmargin: 0;\n\tfont-family: var(--font-family-mono);\n\tcolor: inherit;\n\ttext-align: center;\n\tcaret-color: var(--content-0);\n\tfont-variant-numeric: tabular-nums;\n\n\t&::selection {\n\t\tbackground-color: var(--focus-ring);\n\t\tcolor: var(--surface-0);\n\t}\n\n\t&:disabled {\n\t\topacity: 0.25;\n\t}\n}\n\n.rangeSeparator {\n\tuser-select: none;\n\tcolor: var(--content-2);\n\tflex-shrink: 0;\n\n\t&[data-disabled] {\n\t\topacity: 0.25;\n\t}\n}\n","import React, { KeyboardEvent, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { offsetNumberScaleValue, percentToNumberScaleValue, resolveNumberScaleBounds } from \"@ryuzaki13/react-foundation-lib/number-scale\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputUI, useInputFieldIds } from \"../input\";\nimport { FloatingPopover } from \"../popover\";\nimport { UiBaseProps, UiSize } from \"../types\";\n\nimport {\n\tgetClosestSliderMarkByPercent,\n\tgetClosestSliderThumb,\n\tgetRangeSliderVisualValue,\n\tgetSliderMarkPercent,\n\tnormalizeRangeSliderValue,\n\tnormalizeSingleSliderValue,\n\tprepareSliderMarks,\n\tresolveSliderFillRange,\n\tvalueToSliderVisualPercent,\n\tvisualValueToRangeEndpoint,\n\ttype SliderMark,\n\ttype SliderMarksPosition,\n\ttype SliderRangeMark,\n\ttype SliderRangeValue\n} from \"./lib\";\nimport styles from \"./Slider.module.scss\";\n\ntype SliderMarksDisplay = \"compact\" | \"full\";\n\ninterface SliderCommonProps<TMark extends SliderMark> {\n\t/**\n\t * Минимальная координата шкалы. Marks вне этой границы отбрасываются.\n\t */\n\tmin: number;\n\t/**\n\t * Максимальная координата шкалы. Marks вне этой границы отбрасываются.\n\t */\n\tmax: number;\n\t/**\n\t * Шаг изменения, когда `marks` не заданы или после фильтрации не осталось валидных marks.\n\t */\n\tstep?: number;\n\t/**\n\t * Дискретные точки выбора. Если заданы, бегунок всегда ходит только по marks.\n\t */\n\tmarks?: readonly TMark[];\n\t/**\n\t * Способ визуального размещения marks и бегунка: по числовой координате `value` или равномерно по индексу.\n\t */\n\tmarksPosition?: SliderMarksPosition;\n\t/**\n\t * Внешний CSS-класс контейнера поля.\n\t */\n\tclassName?: string;\n\t/**\n\t * Текст внешней ошибки, отображается через общую `InputUI`-обёртку.\n\t */\n\terror?: string;\n\t/**\n\t * Вызывается после успешного изменения значения, чтобы потребитель мог сбросить внешнюю ошибку.\n\t */\n\tonClearError?: () => void;\n}\n\n/**\n * Single-value slider. Возвращает координату шкалы, потому что single marks не используют `outputValue`.\n */\nexport interface SliderProps extends Omit<UiBaseProps<number, number | undefined>, \"placeholder\">, SliderCommonProps<SliderMark> {}\n\n/**\n * Range slider. Возвращает бизнес-значения `SliderRangeMark.outputValue`, если они заданы, иначе координаты `value`.\n */\nexport interface SliderRangeProps\n\textends Omit<UiBaseProps<SliderRangeValue, SliderRangeValue | undefined>, \"placeholder\">, SliderCommonProps<SliderRangeMark> {}\n\ninterface SliderBaseCommonProps<TMark extends SliderMark> extends SliderCommonProps<TMark> {\n\t/**\n\t * Подпись поля в общей `InputUI`-обёртке.\n\t */\n\tlabel?: React.ReactNode;\n\t/**\n\t * Описание поля под подписью.\n\t */\n\tdescription?: string;\n\t/**\n\t * Блокирует pointer, keyboard и click-взаимодействие.\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Размер общей `InputUI`-обёртки.\n\t */\n\tsize?: UiSize;\n\t/**\n\t * Compact показывает только ticks/tooltip внутри высоты control, full добавляет строку labels для popover.\n\t */\n\tmarksDisplay?: SliderMarksDisplay;\n}\n\ninterface SliderBaseSingleProps extends SliderBaseCommonProps<SliderMark> {\n\tmode: \"single\";\n\tvalue: number | undefined;\n\tonChange: (value: number) => void;\n}\n\ninterface SliderBaseRangeProps extends SliderBaseCommonProps<SliderRangeMark> {\n\tmode: \"range\";\n\tvalue: SliderRangeValue | undefined;\n\tonChange: (value: SliderRangeValue) => void;\n}\n\nexport type SliderBaseProps = SliderBaseSingleProps | SliderBaseRangeProps;\n\nfunction resolveKeyboardOffset(eventKey: string) {\n\tif (eventKey === \"ArrowLeft\" || eventKey === \"ArrowDown\") {\n\t\treturn -1;\n\t}\n\n\tif (eventKey === \"ArrowRight\" || eventKey === \"ArrowUp\") {\n\t\treturn 1;\n\t}\n\n\tif (eventKey === \"PageDown\") {\n\t\treturn -10;\n\t}\n\n\tif (eventKey === \"PageUp\") {\n\t\treturn 10;\n\t}\n\n\treturn null;\n}\n\nfunction areRangeValuesEqual(left: SliderRangeValue | undefined, right: SliderRangeValue) {\n\treturn !!left && left[0] === right[0] && left[1] === right[1];\n}\n\nfunction formatRangeEndpoint(value: number | null, thumbIndex: number) {\n\tif (value === null) {\n\t\treturn thumbIndex === 0 ? \"-∞\" : \"∞\";\n\t}\n\n\treturn String(value);\n}\n\nfunction getMarkLabelByValue<TMark extends SliderMark>(value: number, marks: readonly TMark[]) {\n\treturn marks.find((mark) => mark.value === value)?.label ?? String(value);\n}\n\nfunction renderTooltipContent(content: React.ReactNode) {\n\treturn typeof content === \"string\" || typeof content === \"number\" ? <span className=\"textNoWrap\">{content}</span> : content;\n}\n\nexport function SliderBase(props: SliderBaseProps) {\n\tconst {\n\t\tmin: rawMin,\n\t\tmax: rawMax,\n\t\tstep,\n\t\tmarks,\n\t\tmarksPosition = \"value\",\n\t\tmarksDisplay = \"compact\",\n\t\tclassName,\n\t\terror,\n\t\tonClearError,\n\t\tlabel,\n\t\tdescription,\n\t\tdisabled,\n\t\tsize\n\t} = props;\n\tconst { min, max } = useMemo(() => resolveNumberScaleBounds(rawMin, rawMax), [rawMin, rawMax]);\n\tconst normalizedMarks = useMemo(() => prepareSliderMarks(marks, min, max), [marks, min, max]);\n\tconst sliderOptions = useMemo(\n\t\t() => ({\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tstep,\n\t\t\tmarks: normalizedMarks,\n\t\t\tmarksPosition\n\t\t}),\n\t\t[min, max, step, normalizedMarks, marksPosition]\n\t);\n\n\tconst isRange = props.mode === \"range\";\n\tconst currentSingleValue = !isRange ? normalizeSingleSliderValue(props.value, sliderOptions) : undefined;\n\tconst currentRangeValue = isRange ? normalizeRangeSliderValue(props.value, sliderOptions) : undefined;\n\tconst visualRangeValue = isRange ? getRangeSliderVisualValue(props.value, sliderOptions) : undefined;\n\tconst thumbValues = isRange ? visualRangeValue! : [currentSingleValue!];\n\tconst fillRange = resolveSliderFillRange(isRange ? visualRangeValue! : currentSingleValue!, sliderOptions);\n\n\tconst trackRef = useRef<HTMLDivElement | null>(null);\n\tconst thumbRefs = useRef<Array<HTMLButtonElement | null>>([]);\n\tconst dragThumbIndexRef = useRef<number | null>(null);\n\tconst dragPointerIdRef = useRef<number | null>(null);\n\tconst [dragThumbIndex, setDragThumbIndex] = useState<number | null>(null);\n\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\tconst emitSingleValue = (nextValue: number) => {\n\t\tif (disabled || props.mode !== \"single\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (props.value !== undefined && props.value === nextValue) {\n\t\t\treturn;\n\t\t}\n\n\t\tprops.onChange(nextValue);\n\t\tonClearError?.();\n\t};\n\n\tconst emitRangeValue = (nextValue: SliderRangeValue) => {\n\t\tif (disabled || props.mode !== \"range\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (areRangeValuesEqual(props.value, nextValue)) {\n\t\t\treturn;\n\t\t}\n\n\t\tprops.onChange(nextValue);\n\t\tonClearError?.();\n\t};\n\n\tconst applySliderValue = (rawValue: number, thumbIndex: number) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (props.mode === \"range\") {\n\t\t\tconst [startVisualValue, endVisualValue] = visualRangeValue!;\n\t\t\tconst [startValue, endValue] = currentRangeValue!;\n\t\t\tconst nextValue =\n\t\t\t\tthumbIndex === 0\n\t\t\t\t\t? normalizeRangeSliderValue(\n\t\t\t\t\t\t\t[visualValueToRangeEndpoint(Math.min(rawValue, endVisualValue), sliderOptions), endValue],\n\t\t\t\t\t\t\tsliderOptions\n\t\t\t\t\t\t)\n\t\t\t\t\t: normalizeRangeSliderValue(\n\t\t\t\t\t\t\t[startValue, visualValueToRangeEndpoint(Math.max(rawValue, startVisualValue), sliderOptions)],\n\t\t\t\t\t\t\tsliderOptions\n\t\t\t\t\t\t);\n\n\t\t\temitRangeValue(nextValue);\n\t\t\treturn;\n\t\t}\n\n\t\temitSingleValue(normalizeSingleSliderValue(rawValue, sliderOptions));\n\t};\n\n\tconst resolveValueFromPointer = (clientX: number) => {\n\t\tconst bounds = trackRef.current?.getBoundingClientRect();\n\t\tif (!bounds) {\n\t\t\treturn min;\n\t\t}\n\n\t\tconst percent = ((clientX - bounds.left) / bounds.width) * 100;\n\t\tconst closestMark = normalizedMarks.length > 0 ? getClosestSliderMarkByPercent(percent, sliderOptions) : undefined;\n\n\t\treturn closestMark?.value ?? percentToNumberScaleValue(percent, min, max);\n\t};\n\tconst applySliderValueRef = useRef(applySliderValue);\n\tconst resolveValueFromPointerRef = useRef(resolveValueFromPointer);\n\n\tuseEffect(() => {\n\t\tapplySliderValueRef.current = applySliderValue;\n\t\tresolveValueFromPointerRef.current = resolveValueFromPointer;\n\t});\n\n\tuseEffect(() => {\n\t\tconst onPointerUp = (event?: PointerEvent) => {\n\t\t\tif (dragPointerIdRef.current !== null && event && event.pointerId !== dragPointerIdRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdragPointerIdRef.current = null;\n\t\t\tdragThumbIndexRef.current = null;\n\t\t\tsetDragThumbIndex(null);\n\t\t};\n\n\t\tconst onPointerMove = (event: PointerEvent) => {\n\t\t\tif (dragThumbIndexRef.current === null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (dragPointerIdRef.current !== null && event.pointerId !== dragPointerIdRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tapplySliderValueRef.current(resolveValueFromPointerRef.current(event.clientX), dragThumbIndexRef.current);\n\t\t};\n\n\t\twindow.addEventListener(\"pointermove\", onPointerMove);\n\t\twindow.addEventListener(\"pointerup\", onPointerUp);\n\t\twindow.addEventListener(\"pointercancel\", onPointerUp);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"pointermove\", onPointerMove);\n\t\t\twindow.removeEventListener(\"pointerup\", onPointerUp);\n\t\t\twindow.removeEventListener(\"pointercancel\", onPointerUp);\n\t\t};\n\t}, []);\n\n\tconst beginPointerDrag = (pointerId: number, thumbIndex: number) => {\n\t\tdragPointerIdRef.current = pointerId;\n\t\tdragThumbIndexRef.current = thumbIndex;\n\t\tsetDragThumbIndex(thumbIndex);\n\t\tthumbRefs.current[thumbIndex]?.focus();\n\t};\n\n\tconst handleTrackPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\n\t\tconst rawValue = resolveValueFromPointer(event.clientX);\n\t\tconst thumbIndex = isRange ? getClosestSliderThumb(rawValue, visualRangeValue!) : 0;\n\n\t\tapplySliderValue(rawValue, thumbIndex);\n\t\tbeginPointerDrag(event.pointerId, thumbIndex);\n\t};\n\n\tconst handleThumbPointerDown = (thumbIndex: number) => (event: React.PointerEvent<HTMLButtonElement>) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tbeginPointerDrag(event.pointerId, thumbIndex);\n\t};\n\n\tconst handleThumbKeyDown = (thumbIndex: number) => (event: KeyboardEvent<HTMLButtonElement>) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst lowerBound = isRange && thumbIndex === 1 ? visualRangeValue![0] : min;\n\t\tconst upperBound = isRange && thumbIndex === 0 ? visualRangeValue![1] : max;\n\t\tconst keyboardOffset = resolveKeyboardOffset(event.key);\n\n\t\tif (event.key === \"Home\") {\n\t\t\tevent.preventDefault();\n\t\t\tapplySliderValue(lowerBound, thumbIndex);\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === \"End\") {\n\t\t\tevent.preventDefault();\n\t\t\tapplySliderValue(upperBound, thumbIndex);\n\t\t\treturn;\n\t\t}\n\n\t\tif (keyboardOffset === null) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tconst baseValue = thumbValues[thumbIndex];\n\t\tconst nextValue = offsetNumberScaleValue(baseValue, keyboardOffset, sliderOptions, lowerBound, upperBound);\n\t\tapplySliderValue(nextValue, thumbIndex);\n\t};\n\n\tconst handleMarkSelect = (markValue: number) => {\n\t\tif (disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst thumbIndex = isRange ? getClosestSliderThumb(markValue, visualRangeValue!) : 0;\n\t\tapplySliderValue(markValue, thumbIndex);\n\t\tthumbRefs.current[thumbIndex]?.focus();\n\t};\n\n\tconst getThumbValueText = (thumbValue: number, thumbIndex: number) => {\n\t\tif (isRange) {\n\t\t\tconst publicValue = currentRangeValue![thumbIndex];\n\t\t\tconst exactMark = normalizedMarks.find((mark) => mark.value === thumbValue);\n\n\t\t\treturn exactMark?.label ?? formatRangeEndpoint(publicValue, thumbIndex);\n\t\t}\n\n\t\treturn getMarkLabelByValue(thumbValue, normalizedMarks);\n\t};\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tclassName={className}\n\t\t\tsize={size}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t<div id={controlId} className={cn(styles.slider, marksDisplay === \"compact\" && styles.sliderCompact)}>\n\t\t\t\t<div className={styles.trackShell}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={trackRef}\n\t\t\t\t\t\tdata-slot=\"track\"\n\t\t\t\t\t\tclassName={styles.track}\n\t\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\t\tonPointerDown={handleTrackPointerDown}>\n\t\t\t\t\t\t<div className={styles.rail} />\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tdata-slot=\"fill\"\n\t\t\t\t\t\t\tclassName={styles.fill}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tleft: `${fillRange.startPercent}%`,\n\t\t\t\t\t\t\t\twidth: `${fillRange.endPercent - fillRange.startPercent}%`\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t{marksDisplay === \"compact\" &&\n\t\t\t\t\t\t\tnormalizedMarks.map((mark) => {\n\t\t\t\t\t\t\t\tconst markPercent = getSliderMarkPercent(mark, normalizedMarks, sliderOptions);\n\t\t\t\t\t\t\t\tconst isActive = isRange\n\t\t\t\t\t\t\t\t\t? mark.value >= visualRangeValue![0] && mark.value <= visualRangeValue![1]\n\t\t\t\t\t\t\t\t\t: mark.value <= currentSingleValue!;\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<FloatingPopover key={mark.value} tooltip placement=\"top\" content={renderTooltipContent(mark.label)}>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tdata-slot=\"mark\"\n\t\t\t\t\t\t\t\t\t\t\tdata-active={isActive ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\t\t\tclassName={styles.compactMark}\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ left: `${markPercent}%` }}\n\t\t\t\t\t\t\t\t\t\t\taria-label={mark.ariaLabel}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleMarkSelect(mark.value)}>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.markDot} aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</FloatingPopover>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\n\t\t\t\t\t\t{thumbValues.map((thumbValue, thumbIndex) => {\n\t\t\t\t\t\t\tconst thumbLabel = getThumbValueText(thumbValue, thumbIndex);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<FloatingPopover\n\t\t\t\t\t\t\t\t\tkey={thumbIndex}\n\t\t\t\t\t\t\t\t\ttooltip\n\t\t\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t\t\t\tcontent={renderTooltipContent(thumbLabel)}\n\t\t\t\t\t\t\t\t\topenDelay={0}\n\t\t\t\t\t\t\t\t\tcloseDelay={100}>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\t\t\t\t\tthumbRefs.current[thumbIndex] = node;\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\trole=\"slider\"\n\t\t\t\t\t\t\t\t\t\tdata-slot=\"thumb\"\n\t\t\t\t\t\t\t\t\t\tdata-thumb-index={thumbIndex}\n\t\t\t\t\t\t\t\t\t\tdata-dragging={dragThumbIndex === thumbIndex ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\t\tclassName={styles.thumb}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\tstyle={{ left: `${valueToSliderVisualPercent(thumbValue, sliderOptions)}%` }}\n\t\t\t\t\t\t\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\t\t\t\t\t\t\taria-orientation=\"horizontal\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin={isRange && thumbIndex === 1 ? visualRangeValue![0] : min}\n\t\t\t\t\t\t\t\t\t\taria-valuemax={isRange && thumbIndex === 0 ? visualRangeValue![1] : max}\n\t\t\t\t\t\t\t\t\t\taria-valuenow={thumbValue}\n\t\t\t\t\t\t\t\t\t\taria-valuetext={\n\t\t\t\t\t\t\t\t\t\t\ttypeof thumbLabel === \"string\" || typeof thumbLabel === \"number\"\n\t\t\t\t\t\t\t\t\t\t\t\t? String(thumbLabel)\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\t\t\tlabelId\n\t\t\t\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t\t\t\t: isRange\n\t\t\t\t\t\t\t\t\t\t\t\t\t? thumbIndex === 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"Минимальное значение\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Максимальное значение\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Значение\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tonPointerDown={handleThumbPointerDown(thumbIndex)}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleThumbKeyDown(thumbIndex)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FloatingPopover>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{marksDisplay === \"full\" && normalizedMarks.length > 0 && (\n\t\t\t\t\t<div className={styles.marks}>\n\t\t\t\t\t\t{normalizedMarks.map((mark) => {\n\t\t\t\t\t\t\tconst isActive = isRange\n\t\t\t\t\t\t\t\t? mark.value >= visualRangeValue![0] && mark.value <= visualRangeValue![1]\n\t\t\t\t\t\t\t\t: mark.value <= currentSingleValue!;\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={mark.value}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdata-slot=\"mark\"\n\t\t\t\t\t\t\t\t\tdata-active={isActive ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\tclassName={styles.mark}\n\t\t\t\t\t\t\t\t\tstyle={{ left: `${getSliderMarkPercent(mark, normalizedMarks, sliderOptions)}%` }}\n\t\t\t\t\t\t\t\t\taria-label={mark.ariaLabel}\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonClick={() => handleMarkSelect(mark.value)}>\n\t\t\t\t\t\t\t\t\t<span className={styles.markDot} aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t<span className={styles.markLabel}>{mark.label}</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</InputUI>\n\t);\n}\n\nexport function Slider(props: SliderProps) {\n\treturn <SliderBase {...props} mode=\"single\" marksDisplay=\"compact\" />;\n}\n\nexport function SliderRange(props: SliderRangeProps) {\n\treturn <SliderBase {...props} mode=\"range\" marksDisplay=\"compact\" />;\n}\n","import { KeyboardEvent, useCallback, useEffect, useEffectEvent, useMemo, useState } from \"react\";\n\nimport { toFiniteNumber } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { resolveNumberScaleBounds } from \"@ryuzaki13/react-foundation-lib/number-scale\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputText, InputUI, useInputFieldIds } from \"../input\";\nimport { PickerTriggerActions } from \"../picker\";\nimport { Popover } from \"../popover\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport {\n\tgetRangeMarkOutputValue,\n\tnormalizeRangeSliderValue,\n\tnormalizeSingleSliderValue,\n\tprepareSliderMarks,\n\ttype SliderMark,\n\ttype SliderMarksPosition,\n\ttype SliderRangeMark,\n\ttype SliderRangeValue\n} from \"./lib\";\nimport { SliderBase } from \"./Slider\";\nimport styles from \"./Slider.module.scss\";\n\ninterface SliderInputCommonProps {\n\t/**\n\t * Минимальная координата шкалы. Marks вне этой границы не участвуют в выборе.\n\t */\n\tmin: number;\n\t/**\n\t * Максимальная координата шкалы. Marks вне этой границы не участвуют в выборе.\n\t */\n\tmax: number;\n\t/**\n\t * Шаг ручного ввода и слайдера, если не заданы marks.\n\t */\n\tstep?: number;\n\t/**\n\t * Способ визуального размещения marks и бегунка в popover.\n\t */\n\tmarksPosition?: SliderMarksPosition;\n\t/**\n\t * Внешний CSS-класс общей обёртки поля.\n\t */\n\tclassName?: string;\n\t/**\n\t * Текст внешней ошибки.\n\t */\n\terror?: string;\n\t/**\n\t * Сбрасывает внешнюю ошибку после успешного commit или выбора в popover.\n\t */\n\tonClearError?: () => void;\n}\n\nexport interface SliderInputProps extends UiBaseProps<number>, SliderInputCommonProps {\n\t/**\n\t * Marks single-слайдера. Single-компонент отдаёт наружу `mark.value`.\n\t */\n\tmarks?: readonly SliderMark[];\n}\n\nexport interface SliderRangeInputProps extends UiBaseProps<SliderRangeValue>, SliderInputCommonProps {\n\t/**\n\t * Marks range-слайдера. `value` задаёт координату на шкале, `outputValue` задаёт публичное значение для потребителя.\n\t */\n\tmarks?: readonly SliderRangeMark[];\n\t/**\n\t * Показывает вместо ручных сегментов готовый текст по выбранным marks.\n\t * Popover остаётся единственным способом изменить значение через слайдер, а потребитель получает изменение при закрытии popover.\n\t */\n\treadonlyValueText?: boolean;\n}\n\nfunction createSliderToggle({\n\topen,\n\tdisabled,\n\tsetOpen\n}: {\n\topen: boolean;\n\tdisabled?: boolean;\n\tsetOpen: (nextOpen: boolean | ((prev: boolean) => boolean)) => void;\n}) {\n\treturn (\n\t\t<Popover.Trigger passive>\n\t\t\t<div>\n\t\t\t\t<PickerTriggerActions\n\t\t\t\t\topen={open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\topenAriaLabel=\"Открыть слайдер\"\n\t\t\t\t\tcloseAriaLabel=\"Закрыть слайдер\"\n\t\t\t\t\tonToggleMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\tonToggleClick={() => setOpen((prev) => !prev)}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</Popover.Trigger>\n\t);\n}\n\nfunction formatRangeDraft(\n\tvalue: SliderRangeValue | undefined,\n\toptions: {\n\t\tmin: number;\n\t\tmax: number;\n\t\tstep?: number;\n\t\tmarks?: readonly SliderRangeMark[];\n\t\tmarksPosition?: SliderMarksPosition;\n\t}\n) {\n\tconst normalized = normalizeRangeSliderValue(value, options);\n\n\treturn {\n\t\tstart: normalized[0] === null ? \"-∞\" : String(normalized[0]),\n\t\tend: normalized[1] === null ? \"∞\" : String(normalized[1])\n\t};\n}\n\nfunction parseRangeDraftSegment(value: string, infinityText: string) {\n\tconst trimmed = value.trim();\n\tif (trimmed === \"\" || trimmed === infinityText) {\n\t\treturn null;\n\t}\n\n\treturn toFiniteNumber(trimmed);\n}\n\nfunction getRangeMarkByOutputValue(value: number | null, marks: readonly SliderRangeMark[], endpoint: \"start\" | \"end\") {\n\tconst matchingMarks = marks.filter((mark) => getRangeMarkOutputValue(mark) === value);\n\n\tif (!matchingMarks.length) {\n\t\treturn undefined;\n\t}\n\n\treturn value === null && endpoint === \"end\" ? matchingMarks[matchingMarks.length - 1] : matchingMarks[0];\n}\n\nfunction getRangeMarkReadonlyLabel(mark: SliderRangeMark | undefined, value: number | null) {\n\tif (mark?.readonlyLabel?.trim()) {\n\t\treturn mark.readonlyLabel.trim();\n\t}\n\n\tif (typeof mark?.label === \"string\" || typeof mark?.label === \"number\") {\n\t\treturn String(mark.label);\n\t}\n\t// SHARE: lib/formatters/string.toSafeString\n\treturn value === null ? \"\" : String(value);\n}\n\nfunction getRangeEndpointLabel(value: number | null, marks: readonly SliderRangeMark[], endpoint: \"start\" | \"end\") {\n\tconst mark = getRangeMarkByOutputValue(value, marks, endpoint);\n\treturn getRangeMarkReadonlyLabel(mark, value);\n}\n\nfunction getRangeReadonlyText(value: SliderRangeValue, marks: readonly SliderRangeMark[], placeholder?: string) {\n\tconst [start, end] = value;\n\tconst isStartOpen = start === null;\n\tconst isEndOpen = end === null;\n\n\tif (isStartOpen && isEndOpen) {\n\t\treturn placeholder ?? \"\";\n\t}\n\n\tif (isStartOpen) {\n\t\treturn `Меньше ${getRangeEndpointLabel(end, marks, \"end\")}`;\n\t}\n\n\tif (isEndOpen) {\n\t\treturn `Больше ${getRangeEndpointLabel(start, marks, \"start\")}`;\n\t}\n\n\tif (start === end) {\n\t\treturn `Равно ${getRangeEndpointLabel(start, marks, \"start\")}`;\n\t}\n\n\treturn `От ${getRangeEndpointLabel(start, marks, \"start\")} до ${getRangeEndpointLabel(end, marks, \"end\")}`;\n}\n\nexport function SliderInput({\n\tvalue,\n\tonChange,\n\tmin: rawMin,\n\tmax: rawMax,\n\tstep,\n\tmarks,\n\tmarksPosition = \"value\",\n\tclassName,\n\terror,\n\tonClearError,\n\tlabel,\n\tdescription,\n\tplaceholder,\n\tdisabled,\n\tsize\n}: SliderInputProps) {\n\tconst { min, max } = useMemo(() => resolveNumberScaleBounds(rawMin, rawMax), [rawMin, rawMax]);\n\tconst normalizedMarks = useMemo(() => prepareSliderMarks(marks, min, max), [marks, min, max]);\n\tconst sliderOptions = useMemo(\n\t\t() => ({\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tstep,\n\t\t\tmarks: normalizedMarks,\n\t\t\tmarksPosition\n\t\t}),\n\t\t[min, max, step, normalizedMarks, marksPosition]\n\t);\n\tconst normalizedValue = normalizeSingleSliderValue(value, sliderOptions);\n\n\tconst [open, setOpen] = useState(false);\n\tconst [draftValue, setDraftValue] = useState(String(normalizedValue));\n\n\tconst syncDraftValue = useEffectEvent((nextValue: string) => {\n\t\tsetDraftValue(nextValue);\n\t});\n\n\tuseEffect(() => {\n\t\tsyncDraftValue(String(normalizedValue));\n\t}, [normalizedValue]);\n\n\tconst commitDraftValue = useCallback(() => {\n\t\tif (disabled) {\n\t\t\tsetDraftValue(String(normalizedValue));\n\t\t\treturn;\n\t\t}\n\n\t\tconst parsedValue = toFiniteNumber(draftValue);\n\t\tif (parsedValue === undefined) {\n\t\t\tsetDraftValue(String(normalizedValue));\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextValue = normalizeSingleSliderValue(parsedValue, sliderOptions);\n\t\tif (value !== nextValue) {\n\t\t\tonChange(nextValue);\n\t\t\tonClearError?.();\n\t\t}\n\n\t\tsetDraftValue(String(nextValue));\n\t}, [disabled, draftValue, normalizedValue, onChange, onClearError, sliderOptions, value]);\n\n\tconst handleDraftKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key !== \"Enter\") {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tcommitDraftValue();\n\t};\n\n\tconst handleSliderChange = (nextValue: number) => {\n\t\tonChange(nextValue);\n\t\tsetDraftValue(String(nextValue));\n\t\tonClearError?.();\n\t};\n\n\treturn (\n\t\t<Popover open={open} onOpenChange={setOpen}>\n\t\t\t<InputText\n\t\t\t\tlabel={label}\n\t\t\t\tdescription={description}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tsize={size}\n\t\t\t\tclassName={className}\n\t\t\t\terror={error}\n\t\t\t\tvalue={draftValue}\n\t\t\t\tonChange={setDraftValue}\n\t\t\t\tonBlur={commitDraftValue}\n\t\t\t\tonKeyDown={handleDraftKeyDown}\n\t\t\t\tendAdornmentWidth=\"var(--control-height)\"\n\t\t\t\tendAdornment={createSliderToggle({ open, disabled, setOpen })}\n\t\t\t/>\n\n\t\t\t<Popover.Content background=\"primary\">\n\t\t\t\t<div className={styles.popoverContent}>\n\t\t\t\t\t<SliderBase\n\t\t\t\t\t\tmode=\"single\"\n\t\t\t\t\t\tmin={min}\n\t\t\t\t\t\tmax={max}\n\t\t\t\t\t\tstep={step}\n\t\t\t\t\t\tmarks={normalizedMarks}\n\t\t\t\t\t\tmarksPosition={marksPosition}\n\t\t\t\t\t\tmarksDisplay=\"full\"\n\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\tonChange={handleSliderChange}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</Popover.Content>\n\t\t</Popover>\n\t);\n}\n\nexport function SliderRangeInput({\n\tvalue,\n\tonChange,\n\tmin: rawMin,\n\tmax: rawMax,\n\tstep,\n\tmarks,\n\tmarksPosition = \"value\",\n\tclassName,\n\terror,\n\tonClearError,\n\tlabel,\n\tdescription,\n\treadonlyValueText,\n\tplaceholder,\n\tdisabled,\n\tsize\n}: SliderRangeInputProps) {\n\tconst { min, max } = useMemo(() => resolveNumberScaleBounds(rawMin, rawMax), [rawMin, rawMax]);\n\tconst normalizedMarks = useMemo(() => prepareSliderMarks(marks, min, max), [marks, min, max]);\n\tconst sliderOptions = useMemo(\n\t\t() => ({\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tstep,\n\t\t\tmarks: normalizedMarks,\n\t\t\tmarksPosition\n\t\t}),\n\t\t[min, max, step, normalizedMarks, marksPosition]\n\t);\n\tconst normalizedValue = useMemo(() => normalizeRangeSliderValue(value, sliderOptions), [sliderOptions, value]);\n\tconst formattedValue = useMemo(() => formatRangeDraft(normalizedValue, sliderOptions), [normalizedValue, sliderOptions]);\n\n\tconst [open, setOpen] = useState(false);\n\tconst [draftStart, setDraftStart] = useState(formattedValue.start);\n\tconst [draftEnd, setDraftEnd] = useState(formattedValue.end);\n\tconst [popoverValue, setPopoverValue] = useState<SliderRangeValue>(normalizedValue);\n\n\tconst syncDraftValue = useEffectEvent((start: string, end: string) => {\n\t\tsetDraftStart(start);\n\t\tsetDraftEnd(end);\n\t});\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\treturn;\n\t\t}\n\n\t\tsyncDraftValue(formattedValue.start, formattedValue.end);\n\t}, [formattedValue.start, formattedValue.end, normalizedValue, open]);\n\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\tconst rollbackDraftValue = useCallback(() => {\n\t\tsetDraftStart(formattedValue.start);\n\t\tsetDraftEnd(formattedValue.end);\n\t}, [formattedValue.end, formattedValue.start]);\n\n\tconst commitDraftValue = useCallback(() => {\n\t\tif (disabled) {\n\t\t\trollbackDraftValue();\n\t\t\treturn;\n\t\t}\n\n\t\tconst parsedStart = parseRangeDraftSegment(draftStart, \"-∞\");\n\t\tconst parsedEnd = parseRangeDraftSegment(draftEnd, \"∞\");\n\n\t\tif (parsedStart === undefined || parsedEnd === undefined) {\n\t\t\trollbackDraftValue();\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextValue = normalizeRangeSliderValue([parsedStart, parsedEnd], sliderOptions);\n\t\tif (!areRangeDraftValuesEqual(normalizedValue, nextValue)) {\n\t\t\tonChange(nextValue);\n\t\t\tonClearError?.();\n\t\t}\n\n\t\tconst nextDraft = formatRangeDraft(nextValue, sliderOptions);\n\t\tsetDraftStart(nextDraft.start);\n\t\tsetDraftEnd(nextDraft.end);\n\t\tsetPopoverValue(nextValue);\n\t}, [disabled, draftEnd, draftStart, normalizedValue, onChange, onClearError, rollbackDraftValue, sliderOptions]);\n\n\tconst commitPopoverValue = useCallback(\n\t\t(nextValue: SliderRangeValue) => {\n\t\t\tconst normalizedNextValue = normalizeRangeSliderValue(nextValue, sliderOptions);\n\t\t\tif (!areRangeDraftValuesEqual(normalizedValue, normalizedNextValue)) {\n\t\t\t\tonChange(normalizedNextValue);\n\t\t\t\tonClearError?.();\n\t\t\t}\n\n\t\t\tconst nextDraft = formatRangeDraft(normalizedNextValue, sliderOptions);\n\t\t\tsetDraftStart(nextDraft.start);\n\t\t\tsetDraftEnd(nextDraft.end);\n\t\t\tsetPopoverValue(normalizedNextValue);\n\t\t},\n\t\t[normalizedValue, onChange, onClearError, sliderOptions]\n\t);\n\n\tconst handleOpenChange = (nextOpen: boolean) => {\n\t\tif (!open && nextOpen) {\n\t\t\tsetPopoverValue(normalizedValue);\n\t\t\tsetDraftStart(formattedValue.start);\n\t\t\tsetDraftEnd(formattedValue.end);\n\t\t}\n\n\t\tif (open && !nextOpen && !disabled) {\n\t\t\tcommitPopoverValue(popoverValue);\n\t\t}\n\n\t\tsetOpen(nextOpen);\n\t};\n\n\tconst handleDraftKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key !== \"Enter\") {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tcommitDraftValue();\n\t};\n\n\tconst handleSliderChange = (nextValue: SliderRangeValue) => {\n\t\tconst normalizedNextValue = normalizeRangeSliderValue(nextValue, sliderOptions);\n\t\tsetPopoverValue(normalizedNextValue);\n\t\tconst nextDraft = formatRangeDraft(normalizedNextValue, sliderOptions);\n\t\tsetDraftStart(nextDraft.start);\n\t\tsetDraftEnd(nextDraft.end);\n\t};\n\tconst displayValue = open ? popoverValue : normalizedValue;\n\tconst readonlyTextValue = readonlyValueText ? getRangeReadonlyText(displayValue, normalizedMarks, placeholder) : undefined;\n\tconst setRangeOpen = (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n\t\thandleOpenChange(typeof nextOpen === \"function\" ? nextOpen(open) : nextOpen);\n\t};\n\n\treturn (\n\t\t<Popover open={open} onOpenChange={handleOpenChange}>\n\t\t\t<InputUI\n\t\t\t\tlabel={label}\n\t\t\t\tdescription={description}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tclassName={className}\n\t\t\t\tsize={size}\n\t\t\t\terror={error}\n\t\t\t\tcontrolId={controlId}\n\t\t\t\tlabelId={labelId}\n\t\t\t\tdescriptionId={descriptionId}\n\t\t\t\terrorId={errorId}>\n\t\t\t\t<InputControl\n\t\t\t\t\tendAdornmentWidth=\"var(--control-height)\"\n\t\t\t\t\tendAdornment={createSliderToggle({ open, disabled, setOpen: setRangeOpen })}>\n\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tid={controlId}\n\t\t\t\t\t\t\tclassName={cn(uiStyles.uiInputControlFake, styles.rangeInputControl, controlClassName)}\n\t\t\t\t\t\t\tdata-invalid={error ? \"\" : undefined}\n\t\t\t\t\t\t\tdata-disabled={disabled || undefined}\n\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\taria-invalid={!!error || undefined}\n\t\t\t\t\t\t\taria-label={typeof label === \"string\" ? label : \"Диапазон\"}\n\t\t\t\t\t\t\taria-labelledby={typeof label === \"string\" ? undefined : labelId}\n\t\t\t\t\t\t\taria-describedby={describedBy}>\n\t\t\t\t\t\t\t{readonlyValueText ? (\n\t\t\t\t\t\t\t\t<span className={cn(\"flexEllipsis\", !readonlyTextValue && uiStyles.uiPlaceholder)}>\n\t\t\t\t\t\t\t\t\t{readonlyTextValue || placeholder}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\t\t\tclassName={styles.rangeSegmentInput}\n\t\t\t\t\t\t\t\t\t\tvalue={draftStart}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\taria-label=\"Начало диапазона\"\n\t\t\t\t\t\t\t\t\t\tonChange={(event) => setDraftStart(event.target.value)}\n\t\t\t\t\t\t\t\t\t\tonBlur={commitDraftValue}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleDraftKeyDown}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<span className={styles.rangeSeparator} data-disabled={disabled || undefined}>\n\t\t\t\t\t\t\t\t\t\t-\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\t\t\tclassName={styles.rangeSegmentInput}\n\t\t\t\t\t\t\t\t\t\tvalue={draftEnd}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\taria-label=\"Конец диапазона\"\n\t\t\t\t\t\t\t\t\t\tonChange={(event) => setDraftEnd(event.target.value)}\n\t\t\t\t\t\t\t\t\t\tonBlur={commitDraftValue}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleDraftKeyDown}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</InputControl>\n\t\t\t</InputUI>\n\n\t\t\t<Popover.Content background=\"primary\">\n\t\t\t\t<div className={styles.popoverContent}>\n\t\t\t\t\t<SliderBase\n\t\t\t\t\t\tmode=\"range\"\n\t\t\t\t\t\tmin={min}\n\t\t\t\t\t\tmax={max}\n\t\t\t\t\t\tstep={step}\n\t\t\t\t\t\tmarks={normalizedMarks}\n\t\t\t\t\t\tmarksPosition={marksPosition}\n\t\t\t\t\t\tmarksDisplay=\"full\"\n\t\t\t\t\t\tvalue={popoverValue}\n\t\t\t\t\t\tonChange={handleSliderChange}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</Popover.Content>\n\t\t</Popover>\n\t);\n}\n\nfunction areRangeDraftValuesEqual(left: SliderRangeValue, right: SliderRangeValue) {\n\treturn left[0] === right[0] && left[1] === right[1];\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import { a as e, c as t, i as n, n as r, o as i, r as a, s as o, t as s } from "../chunks/CalendarView-DjeTJkTT.js";
2
- import { a as c, c as l, d as u, f as d, h as f, i as p, l as m, m as h, n as g, o as _, p as v, r as y, s as b, t as x, u as S } from "../chunks/DateInput--tfofQ2x.js";
2
+ import { a as c, c as l, d as u, f as d, h as f, i as p, l as m, m as h, n as g, o as _, p as v, r as y, s as b, t as x, u as S } from "../chunks/DateInput-CaKGXluL.js";
3
3
  export { s as CalendarView, r as DATE_INPUT_SELECTION_MODES, a as DATE_INPUT_WEEK_END_DAYS, n as DATE_PICKER_LEVELS, y as DEFAULT_DATE_INPUT_FORMAT, p as DEFAULT_DATE_INPUT_PRESET, x as RangeDateInput, g as SingleDateInput, c as areRangeDateValuesEqual, _ as areSingleDateValuesEqual, b as formatDateInputValue, l as formatRangeDateValue, m as formatSingleDateValue, e as getDatePickerLevelForSelectionMode, i as isDatePickerLevelAvailable, S as normalizeRangeDateValue, u as normalizeRangeEndDateValue, d as normalizeSingleDateValue, v as parseRangeDateValue, h as parseRangeEndDateValue, f as parseSingleDateValue, o as resolveAvailableDatePickerLevel, t as resolveDateInputPeriodRangeState };
@@ -1,5 +1,5 @@
1
1
  import { n as e, r as t } from "../../chunks/CalendarView-DjeTJkTT.js";
2
- import { n, t as r } from "../../chunks/DateInput--tfofQ2x.js";
2
+ import { n, t as r } from "../../chunks/DateInput-CaKGXluL.js";
3
3
  import { jsx as i } from "react/jsx-runtime";
4
4
  import { useArgs as a } from "storybook/preview-api";
5
5
  //#region src/date-input/stories/DateInput.stories.tsx
@@ -1,5 +1,5 @@
1
1
  import { r as e } from "../../chunks/Grid-ByIIytjh.js";
2
- import { t } from "../../chunks/DateInput--tfofQ2x.js";
2
+ import { t } from "../../chunks/DateInput-CaKGXluL.js";
3
3
  import { t as n } from "../../chunks/DateRangePresetSelect-UgsfaOeM.js";
4
4
  import { useState as r } from "react";
5
5
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
@@ -1,2 +1,2 @@
1
- import { t as e } from "../chunks/SingleDateTimeInput-BmeuVGQT.js";
1
+ import { t as e } from "../chunks/SingleDateTimeInput-D2fDMQnI.js";
2
2
  export { e as SingleDateTimeInput };
@@ -1,4 +1,4 @@
1
- import { t as e } from "../../chunks/SingleDateTimeInput-BmeuVGQT.js";
1
+ import { t as e } from "../../chunks/SingleDateTimeInput-D2fDMQnI.js";
2
2
  import { useState as t } from "react";
3
3
  import { formatDateAsDateTime as n, formatDateAsODataDatetime as r, formatDateAsTime as i } from "@ryuzaki13/react-foundation-lib/formatters";
4
4
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
@@ -1,2 +1,2 @@
1
- import { t as e } from "../chunks/DropZone-kJfbZU5g.js";
1
+ import { t as e } from "../chunks/DropZone-DdFdnC9X.js";
2
2
  export { e as DropZone };
@@ -1,4 +1,4 @@
1
- import { t as e } from "../../chunks/DropZone-kJfbZU5g.js";
1
+ import { t as e } from "../../chunks/DropZone-DdFdnC9X.js";
2
2
  import { useState as t } from "react";
3
3
  import { UploadCloudIcon as n } from "lucide-react";
4
4
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
@@ -1,7 +1,7 @@
1
1
  import { t as e } from "../../chunks/Button-CCWuggdA.js";
2
- import { a as t } from "../../chunks/Input-BmjlpA09.js";
2
+ import { a as t } from "../../chunks/Input-BYUl3UFn.js";
3
3
  import { t as n } from "../../chunks/CheckBox-BowNqqd3.js";
4
- import { t as r } from "../../chunks/Select-BJ5OqTe7.js";
4
+ import { t as r } from "../../chunks/Select-B6kxgxK2.js";
5
5
  import { n as i, t as a } from "../../chunks/LabeledExpandableActionPanel-D3kUvmFH.js";
6
6
  import { useState as o } from "react";
7
7
  import { CheckIcon as s, RefreshCwIcon as c, SearchIcon as l, Settings2Icon as u } from "lucide-react";
@@ -1,8 +1,8 @@
1
1
  import { t as e } from "../chunks/Button-CCWuggdA.js";
2
2
  import { r as t } from "../chunks/Grid-ByIIytjh.js";
3
- import { a as n } from "../chunks/Input-BmjlpA09.js";
3
+ import { a as n } from "../chunks/Input-BYUl3UFn.js";
4
4
  import { i as r, n as i, r as a } from "../chunks/modal-ByNRME3b.js";
5
- import { t as o } from "../chunks/InputFiles-CrTJV27R.js";
5
+ import { t as o } from "../chunks/InputFiles-gIxOPv5y.js";
6
6
  import { useCallback as s, useEffect as c, useMemo as l, useRef as u, useState as d } from "react";
7
7
  import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
8
8
  import h from "react-easy-crop";