@mantine/core 9.5.1-alpha.0 → 9.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/cjs/components/Cascader/Cascader.cjs +4 -2
  2. package/cjs/components/Cascader/Cascader.cjs.map +1 -1
  3. package/cjs/components/Cascader/CascaderColumns.cjs +34 -3
  4. package/cjs/components/Cascader/CascaderColumns.cjs.map +1 -1
  5. package/cjs/components/Cascader/use-cascader-safe-area.cjs +76 -0
  6. package/cjs/components/Cascader/use-cascader-safe-area.cjs.map +1 -0
  7. package/cjs/components/Checkbox/CheckboxCard/CheckboxCard.cjs +8 -4
  8. package/cjs/components/Checkbox/CheckboxCard/CheckboxCard.cjs.map +1 -1
  9. package/cjs/components/Checkbox/CheckboxIndicator/CheckboxIndicator.cjs +3 -2
  10. package/cjs/components/Checkbox/CheckboxIndicator/CheckboxIndicator.cjs.map +1 -1
  11. package/cjs/components/ColorInput/ColorInput.cjs +4 -2
  12. package/cjs/components/ColorInput/ColorInput.cjs.map +1 -1
  13. package/cjs/components/ColorPicker/ColorPicker.cjs.map +1 -1
  14. package/cjs/components/FloatingIndicator/use-floating-indicator.cjs +6 -4
  15. package/cjs/components/FloatingIndicator/use-floating-indicator.cjs.map +1 -1
  16. package/cjs/components/PasswordInput/PasswordInput.cjs +4 -3
  17. package/cjs/components/PasswordInput/PasswordInput.cjs.map +1 -1
  18. package/cjs/components/Tooltip/Tooltip.cjs +11 -3
  19. package/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
  20. package/cjs/components/Tooltip/Tooltip.module.cjs.map +1 -1
  21. package/cjs/components/Tooltip/use-tooltip.cjs +2 -1
  22. package/cjs/components/Tooltip/use-tooltip.cjs.map +1 -1
  23. package/esm/components/Cascader/Cascader.mjs +4 -2
  24. package/esm/components/Cascader/Cascader.mjs.map +1 -1
  25. package/esm/components/Cascader/CascaderColumns.mjs +35 -4
  26. package/esm/components/Cascader/CascaderColumns.mjs.map +1 -1
  27. package/esm/components/Cascader/use-cascader-safe-area.mjs +76 -0
  28. package/esm/components/Cascader/use-cascader-safe-area.mjs.map +1 -0
  29. package/esm/components/Checkbox/CheckboxCard/CheckboxCard.mjs +8 -4
  30. package/esm/components/Checkbox/CheckboxCard/CheckboxCard.mjs.map +1 -1
  31. package/esm/components/Checkbox/CheckboxIndicator/CheckboxIndicator.mjs +3 -2
  32. package/esm/components/Checkbox/CheckboxIndicator/CheckboxIndicator.mjs.map +1 -1
  33. package/esm/components/ColorInput/ColorInput.mjs +4 -2
  34. package/esm/components/ColorInput/ColorInput.mjs.map +1 -1
  35. package/esm/components/ColorPicker/ColorPicker.mjs.map +1 -1
  36. package/esm/components/FloatingIndicator/use-floating-indicator.mjs +6 -4
  37. package/esm/components/FloatingIndicator/use-floating-indicator.mjs.map +1 -1
  38. package/esm/components/PasswordInput/PasswordInput.mjs +4 -3
  39. package/esm/components/PasswordInput/PasswordInput.mjs.map +1 -1
  40. package/esm/components/Tooltip/Tooltip.mjs +11 -3
  41. package/esm/components/Tooltip/Tooltip.mjs.map +1 -1
  42. package/esm/components/Tooltip/Tooltip.module.mjs.map +1 -1
  43. package/esm/components/Tooltip/use-tooltip.mjs +3 -2
  44. package/esm/components/Tooltip/use-tooltip.mjs.map +1 -1
  45. package/lib/components/Cascader/Cascader.d.ts +4 -0
  46. package/lib/components/Cascader/CascaderColumns.d.ts +3 -2
  47. package/lib/components/Cascader/use-cascader-safe-area.d.ts +20 -0
  48. package/lib/components/Checkbox/CheckboxCard/CheckboxCard.d.ts +3 -0
  49. package/lib/components/ColorPicker/ColorPicker.d.ts +2 -2
  50. package/lib/components/PasswordInput/PasswordInput.d.ts +2 -0
  51. package/lib/components/Tooltip/Tooltip.d.ts +2 -0
  52. package/lib/components/Tooltip/use-tooltip.d.ts +1 -0
  53. package/package.json +2 -2
  54. package/styles/Tooltip.css +4 -0
  55. package/styles/Tooltip.layer.css +4 -0
  56. package/styles.css +4 -0
  57. package/styles.layer.css +4 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Cascader.mjs","names":["useId","classes"],"sources":["../../../src/components/Cascader/Cascader.tsx"],"sourcesContent":["import { Fragment, useEffect, useMemo } from 'react';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n ElementProps,\n extractStyleProps,\n Factory,\n factory,\n MantineColor,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { CheckIcon } from '../Checkbox/CheckIcon';\nimport { Combobox, ComboboxLikeStylesNames, useCombobox } from '../Combobox';\nimport {\n __BaseInputProps,\n __InputStylesNames,\n ClearSectionMode,\n InputClearButtonProps,\n InputVariant,\n} from '../Input';\nimport { InputBase } from '../InputBase';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { CascaderColumns } from './CascaderColumns';\nimport { flattenCascaderPaths } from './flatten-cascader-paths';\nimport { getCascaderPathOptions } from './get-cascader-path-options';\nimport { useCascader } from './use-cascader';\nimport classes from './Cascader.module.css';\n\nexport interface CascaderOption {\n /** Option value, must be unique across the whole data tree */\n value: string;\n\n /** Option label, if not set `value` is used instead */\n label?: React.ReactNode;\n\n /** Nested options */\n children?: CascaderOption[];\n\n /** If set, the option cannot be selected or expanded */\n disabled?: boolean;\n}\n\nexport interface CascaderFormatValueInput {\n /** Selected path from root to node */\n value: string[];\n\n /** Option chain resolved from the selected path */\n options: CascaderOption[];\n}\n\nexport type CascaderFormatValue = (input: CascaderFormatValueInput) => React.ReactNode;\n\nexport type CascaderStylesNames =\n | __InputStylesNames\n | ComboboxLikeStylesNames\n | 'columnsList'\n | 'columnsOverflow'\n | 'column'\n | 'columnScroll'\n | 'columnOption'\n | 'columnOptionLabel'\n | 'columnOptionIcon'\n | 'columnOptionCheck'\n | 'columnEmpty'\n | 'flatOption';\n\nexport interface CascaderProps\n extends\n BoxProps,\n __BaseInputProps,\n StylesApiProps<CascaderFactory>,\n ElementProps<'input', 'size' | 'value' | 'defaultValue' | 'onChange'> {\n /** Hierarchical options data */\n data: CascaderOption[];\n\n /** Controlled selected path from root to node */\n value?: string[] | null;\n\n /** Uncontrolled selected path from root to node */\n defaultValue?: string[] | null;\n\n /** Called when the selected path changes with the path and the resolved option chain */\n onChange?: (value: string[] | null, options: CascaderOption[]) => void;\n\n /** If set, any intermediate option can be selected, not only leaf options @default false */\n changeOnSelect?: boolean;\n\n /** Determines whether the dropdown should be closed when a value is selected, defaults to `!allowDeselect` */\n closeOnSelect?: boolean;\n\n /** If set, the selected value can be deselected by selecting it again @default true */\n allowDeselect?: boolean;\n\n /** If set, the check icon is displayed on the selected option @default true */\n withCheckIcon?: boolean;\n\n /** Position of the check icon relative to the option label @default 'right' */\n checkIconPosition?: 'left' | 'right';\n\n /** Renders the dropdown as cascading columns. When `false`, options are rendered as a flat list of paths, the same way as search results (useful for narrow/mobile layouts) @default true */\n withColumns?: boolean;\n\n /** Determines how the next column is opened @default 'click' */\n expandTrigger?: 'click' | 'hover';\n\n /** If set, options can be searched by their flattened paths @default false */\n searchable?: boolean;\n\n /** Controlled search value */\n searchValue?: string;\n\n /** Uncontrolled search value */\n defaultSearchValue?: string;\n\n /** Called when the search value changes */\n onSearchChange?: (value: string) => void;\n\n /** Custom search filter, matched against the full option path */\n filter?: (query: string, options: CascaderOption[]) => boolean;\n\n /** Custom rendering of a search result row */\n renderSearchOption?: (query: string, options: CascaderOption[]) => React.ReactNode;\n\n /** A function to format the selected path displayed in the input, should return a string */\n formatValue?: CascaderFormatValue;\n\n /** Custom rendering of an option in columns */\n renderOption?: (option: CascaderOption, level: number) => React.ReactNode;\n\n /** Path separator displayed in the input and search results @default '/' */\n separator?: React.ReactNode;\n\n /** Width of each column */\n columnWidth?: number | string;\n\n /** Maximum number of columns (levels) displayed next to each other, deeper levels replace earlier ones @default 3 */\n maxDisplayedLevels?: number;\n\n /** `aria-label` and `title` of the control that reveals levels hidden before the visible ones by `maxDisplayedLevels` @default 'Show previous levels' */\n previousLevelsControlLabel?: string;\n\n /** `aria-label` and `title` of the control that reveals levels hidden after the visible ones by `maxDisplayedLevels` @default 'Show next levels' */\n nextLevelsControlLabel?: string;\n\n /** Max height of a column before it becomes scrollable @default 260 */\n maxDropdownHeight?: number | string;\n\n /** Message displayed when there are no options or search results */\n nothingFoundMessage?: React.ReactNode;\n\n /** If set, the clear button is displayed when a value is selected @default false */\n clearable?: boolean;\n\n /** Determines how the clear button and `rightSection` are rendered @default 'both' */\n clearSectionMode?: ClearSectionMode;\n\n /** Props passed down to the clear button */\n clearButtonProps?: InputClearButtonProps;\n\n /** Called when the clear button is clicked */\n onClear?: () => void;\n\n /** Controlled dropdown opened state */\n dropdownOpened?: boolean;\n\n /** Uncontrolled dropdown opened state */\n defaultDropdownOpened?: boolean;\n\n /** Called when the dropdown opens */\n onDropdownOpen?: () => void;\n\n /** Called when the dropdown closes */\n onDropdownClose?: () => void;\n\n /** Props passed down to the underlying `Combobox` component */\n comboboxProps?: Record<string, any>;\n\n /** Props passed down to the dropdown `ScrollArea` */\n scrollAreaProps?: ScrollAreaProps;\n\n /** Controls the default chevron color */\n chevronColor?: MantineColor;\n\n /** Props passed down to the hidden input */\n hiddenInputProps?: Omit<React.ComponentProps<'input'>, 'value'>;\n\n /** Opens the dropdown when the input is focused in `searchable` mode @default true */\n openOnFocus?: boolean;\n}\n\nexport type CascaderFactory = Factory<{\n props: CascaderProps;\n ref: HTMLInputElement;\n stylesNames: CascaderStylesNames;\n variant: InputVariant;\n}>;\n\nconst defaultProps = {\n expandTrigger: 'click',\n changeOnSelect: false,\n allowDeselect: true,\n withCheckIcon: true,\n checkIconPosition: 'right',\n withColumns: true,\n searchable: false,\n separator: '/',\n maxDisplayedLevels: 3,\n previousLevelsControlLabel: 'Show previous levels',\n nextLevelsControlLabel: 'Show next levels',\n maxDropdownHeight: 260,\n openOnFocus: true,\n size: 'sm',\n} satisfies Partial<CascaderProps>;\n\nfunction optionLabelToString(option: CascaderOption): string {\n return typeof option.label === 'string' || typeof option.label === 'number'\n ? String(option.label)\n : option.value;\n}\n\nfunction firstEnabledOptionIndex(options: CascaderOption[]): number {\n return options.findIndex((option) => !option.disabled);\n}\n\nfunction lastEnabledOptionIndex(options: CascaderOption[]): number {\n for (let index = options.length - 1; index >= 0; index -= 1) {\n if (!options[index].disabled) {\n return index;\n }\n }\n return -1;\n}\n\nfunction joinPathLabels(options: CascaderOption[], separator: string): string {\n return options.map(optionLabelToString).join(` ${separator} `);\n}\n\nfunction defaultCascaderFilter(\n query: string,\n options: CascaderOption[],\n separator: string\n): boolean {\n const trimmed = query.trim().toLowerCase();\n if (trimmed.length === 0) {\n return true;\n }\n return joinPathLabels(options, separator).toLowerCase().includes(trimmed);\n}\n\nfunction defaultRenderSearchOption(\n options: CascaderOption[],\n separator: React.ReactNode\n): React.ReactNode {\n return options.map((option, index) => (\n <Fragment key={option.value}>\n {index > 0 && <span data-cascader-separator> {separator} </span>}\n {option.label ?? option.value}\n </Fragment>\n ));\n}\n\nexport const Cascader = factory<CascaderFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'Cascader'], defaultProps as any, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n size,\n data,\n value,\n defaultValue,\n onChange,\n changeOnSelect,\n closeOnSelect,\n allowDeselect,\n withCheckIcon,\n checkIconPosition,\n withColumns,\n expandTrigger,\n searchable,\n searchValue,\n defaultSearchValue,\n onSearchChange,\n filter,\n renderSearchOption,\n formatValue,\n renderOption,\n separator,\n columnWidth,\n maxDisplayedLevels,\n previousLevelsControlLabel,\n nextLevelsControlLabel,\n maxDropdownHeight,\n nothingFoundMessage,\n clearable,\n clearSectionMode,\n clearButtonProps,\n onClear,\n dropdownOpened,\n defaultDropdownOpened,\n onDropdownOpen,\n onDropdownClose,\n comboboxProps,\n scrollAreaProps,\n chevronColor,\n hiddenInputProps,\n openOnFocus,\n variant,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n readOnly,\n disabled,\n radius,\n rightSection,\n rightSectionWidth,\n rightSectionPointerEvents,\n rightSectionProps,\n leftSection,\n leftSectionWidth,\n leftSectionPointerEvents,\n leftSectionProps,\n inputContainer,\n inputWrapperOrder,\n withAsterisk,\n labelProps,\n descriptionProps,\n errorProps,\n successProps,\n wrapperProps,\n description,\n label,\n error,\n success,\n withErrorStyles,\n withSuccessStyles,\n name,\n form,\n id,\n placeholder,\n required,\n mod,\n attributes,\n ...others\n } = props;\n\n const _id = useId(id);\n const separatorString =\n typeof separator === 'string' || typeof separator === 'number' ? String(separator) : '/';\n\n const combobox = useCombobox({\n opened: dropdownOpened,\n defaultOpened: defaultDropdownOpened,\n onDropdownOpen: () => {\n onDropdownOpen?.();\n cascader.resetActivePath();\n },\n onDropdownClose: () => {\n onDropdownClose?.();\n if (searchable) {\n setSearchValue(cascader.value ? displayString : '');\n }\n },\n });\n\n // When `allowDeselect` is enabled, keep the dropdown open by default so the value can be toggled\n const shouldCloseOnSelect = closeOnSelect ?? !allowDeselect;\n\n const cascader = useCascader({\n data,\n value,\n defaultValue,\n onChange,\n changeOnSelect,\n allowDeselect,\n expandTrigger,\n onLeafSelect: () => {\n if (shouldCloseOnSelect) {\n combobox.closeDropdown();\n }\n },\n });\n\n const getStyles = useStyles<CascaderFactory>({\n name: 'Cascader',\n classes,\n props: props as any,\n classNames,\n styles,\n unstyled,\n attributes,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<CascaderFactory>({\n props,\n styles,\n classNames,\n });\n\n const {\n styleProps,\n rest: { type, autoComplete, ...rest },\n } = extractStyleProps(others);\n\n const displayString = useMemo(() => {\n if (cascader.pathOptions.length === 0 || !cascader.value) {\n return '';\n }\n if (formatValue) {\n const rendered = formatValue({ value: cascader.value, options: cascader.pathOptions });\n if (typeof rendered === 'string' || typeof rendered === 'number') {\n return String(rendered);\n }\n }\n return joinPathLabels(cascader.pathOptions, separatorString);\n }, [cascader.pathOptions, cascader.value, formatValue, separatorString]);\n\n const initialSearchValue = useMemo(() => {\n if (!searchable || !defaultValue) {\n return '';\n }\n return joinPathLabels(getCascaderPathOptions(data, defaultValue), separatorString);\n }, []);\n\n const [_searchValue, setSearchValue] = useUncontrolled({\n value: searchValue,\n defaultValue: defaultSearchValue,\n finalValue: initialSearchValue,\n onChange: onSearchChange,\n });\n\n const isSearching =\n !!searchable && _searchValue.trim().length > 0 && _searchValue !== displayString;\n\n useEffect(() => {\n if (searchable) {\n setSearchValue(cascader.value ? displayString : '');\n }\n }, [cascader.value]);\n\n // The dropdown renders a flat list of paths when searching or when `withColumns` is disabled\n const showFlatList = isSearching || !withColumns;\n\n const flatPaths = useMemo(() => flattenCascaderPaths(data), [data]);\n\n const flatListItems = useMemo(() => {\n if (!showFlatList) {\n return [];\n }\n const base = flatPaths.filter((flatPath) => (changeOnSelect ? true : flatPath.leaf));\n if (!isSearching) {\n return base;\n }\n return base.filter((flatPath) =>\n filter\n ? filter(_searchValue, flatPath.options)\n : defaultCascaderFilter(_searchValue, flatPath.options, separatorString)\n );\n }, [flatPaths, showFlatList, isSearching, _searchValue, changeOnSelect, filter, separatorString]);\n\n const canInteract = !readOnly && !disabled;\n\n const handleSearchChange = (nextValue: string) => {\n setSearchValue(nextValue);\n if (canInteract) {\n combobox.openDropdown();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n\n if (event.key === 'Escape') {\n combobox.closeDropdown();\n return;\n }\n\n if (showFlatList || !canInteract) {\n return;\n }\n\n if (!combobox.dropdownOpened) {\n const opensDropdown =\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp' ||\n event.key === 'ArrowRight' ||\n event.key === 'Enter' ||\n (!searchable && event.key === ' ');\n\n if (opensDropdown) {\n event.preventDefault();\n cascader.setKeyboardNav(true);\n combobox.openDropdown();\n\n if (!cascader.value && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n const rootIndex =\n event.key === 'ArrowDown'\n ? firstEnabledOptionIndex(data)\n : lastEnabledOptionIndex(data);\n if (rootIndex >= 0) {\n cascader.setActivePath([data[rootIndex].value]);\n }\n }\n }\n return;\n }\n\n if (cascader.handleColumnsKeyDown(event)) {\n event.preventDefault();\n } else if (!searchable && event.key === ' ') {\n event.preventDefault();\n }\n };\n\n const clearButton = (\n <Combobox.ClearButton\n {...clearButtonProps}\n onClear={() => {\n onClear?.();\n cascader.setValue(null);\n cascader.setActivePath([]);\n setSearchValue('');\n combobox.focusTarget();\n }}\n />\n );\n\n const hasValue = Array.isArray(cascader.value) && cascader.value.length > 0;\n const _clearable = clearable && hasValue && !disabled && !readOnly;\n\n const listId = _id ? `${_id}-cascader-list` : undefined;\n const valueKey = cascader.value ? JSON.stringify(cascader.value) : null;\n\n const dropdown = (\n <Combobox.Dropdown\n hidden={readOnly || disabled}\n style={showFlatList ? undefined : { padding: 0 }}\n >\n {showFlatList ? (\n <Combobox.Options aria-label={typeof label === 'string' ? label : undefined}>\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 260}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n offsetScrollbars=\"y\"\n {...scrollAreaProps}\n >\n {flatListItems.map((flatPath, index) => {\n const pathKey = JSON.stringify(flatPath.path);\n const active = valueKey !== null && pathKey === valueKey;\n return (\n <Combobox.Option\n key={pathKey}\n value={`${index}`}\n active={active}\n disabled={flatPath.disabled}\n >\n <span {...getStyles('flatOption')}>\n {active && withCheckIcon && checkIconPosition === 'left' && (\n <CheckIcon {...getStyles('columnOptionCheck')} />\n )}\n <span {...getStyles('columnOptionLabel')}>\n {renderSearchOption\n ? renderSearchOption(_searchValue, flatPath.options)\n : defaultRenderSearchOption(flatPath.options, separator)}\n </span>\n {active && withCheckIcon && checkIconPosition !== 'left' && (\n <CheckIcon {...getStyles('columnOptionCheck')} />\n )}\n </span>\n </Combobox.Option>\n );\n })}\n </ScrollArea.Autosize>\n {flatListItems.length === 0 && nothingFoundMessage && (\n <Combobox.Empty>{nothingFoundMessage}</Combobox.Empty>\n )}\n </Combobox.Options>\n ) : (\n <CascaderColumns\n data={data}\n activePath={cascader.activePath}\n value={cascader.value}\n keyboardNav={cascader.keyboardNav}\n withCheckIcon={withCheckIcon}\n checkIconPosition={checkIconPosition}\n renderOption={renderOption}\n columnWidth={columnWidth}\n maxDisplayedLevels={maxDisplayedLevels}\n previousLevelsControlLabel={previousLevelsControlLabel}\n nextLevelsControlLabel={nextLevelsControlLabel}\n maxDropdownHeight={maxDropdownHeight}\n nothingFoundMessage={nothingFoundMessage}\n getStyles={getStyles}\n unstyled={unstyled}\n scrollAreaProps={scrollAreaProps}\n onOptionClick={cascader.handleOptionClick}\n onOptionMouseEnter={cascader.handleOptionMouseEnter}\n onColumnsMouseLeave={() => {\n if (expandTrigger === 'hover') {\n cascader.setActivePath(cascader.value ?? []);\n }\n }}\n onPointerActivity={() => cascader.setKeyboardNav(false)}\n listId={listId}\n />\n )}\n </Combobox.Dropdown>\n );\n\n return (\n <>\n <Combobox\n store={combobox}\n __staticSelector=\"Cascader\"\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n readOnly={readOnly}\n size={size}\n attributes={attributes}\n width={showFlatList ? 'target' : 'max-content'}\n position=\"bottom-start\"\n onOptionSubmit={(val) => {\n const index = Number(val);\n const flatPath = flatListItems[index];\n if (!flatPath || flatPath.disabled) {\n return;\n }\n cascader.selectPath(flatPath.path);\n cascader.setActivePath(flatPath.path);\n if (shouldCloseOnSelect) {\n combobox.closeDropdown();\n }\n }}\n {...comboboxProps}\n >\n <Combobox.Target\n targetType={searchable ? 'input' : 'button'}\n withKeyboardNavigation={showFlatList}\n autoComplete={autoComplete}\n >\n <InputBase\n id={_id}\n __defaultRightSection={\n <Combobox.Chevron\n size={size}\n error={error}\n unstyled={unstyled}\n color={chevronColor}\n />\n }\n __clearSection={clearButton}\n __clearable={_clearable}\n __clearSectionMode={clearSectionMode}\n rightSection={rightSection}\n rightSectionPointerEvents={rightSectionPointerEvents || 'none'}\n {...rest}\n {...styleProps}\n size={size}\n __staticSelector=\"Cascader\"\n disabled={disabled}\n readOnly={readOnly || !searchable}\n value={searchable ? _searchValue : displayString}\n onChange={(event) => handleSearchChange(event.currentTarget.value)}\n onFocus={(event) => {\n if (openOnFocus && searchable && canInteract) {\n combobox.openDropdown();\n }\n onFocus?.(event);\n }}\n onBlur={(event) => {\n combobox.closeDropdown();\n onBlur?.(event);\n }}\n onClick={(event) => {\n if (canInteract) {\n cascader.setKeyboardNav(false);\n if (searchable) {\n combobox.openDropdown();\n } else {\n combobox.toggleDropdown();\n }\n }\n onClick?.(event);\n }}\n onKeyDown={handleKeyDown}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n pointer={!searchable}\n error={error}\n success={success}\n attributes={attributes}\n className={className}\n style={style}\n variant={variant}\n radius={radius}\n leftSection={leftSection}\n leftSectionWidth={leftSectionWidth}\n leftSectionPointerEvents={leftSectionPointerEvents}\n leftSectionProps={leftSectionProps}\n rightSectionWidth={rightSectionWidth}\n rightSectionProps={rightSectionProps}\n inputContainer={inputContainer}\n inputWrapperOrder={inputWrapperOrder}\n withAsterisk={withAsterisk}\n labelProps={labelProps}\n descriptionProps={descriptionProps}\n errorProps={errorProps}\n successProps={successProps}\n wrapperProps={wrapperProps}\n description={description}\n label={label}\n withErrorStyles={withErrorStyles}\n withSuccessStyles={withSuccessStyles}\n placeholder={placeholder}\n required={required}\n mod={mod}\n />\n </Combobox.Target>\n {dropdown}\n </Combobox>\n <Combobox.HiddenInput\n value={cascader.value}\n name={name}\n form={form}\n disabled={disabled}\n {...hiddenInputProps}\n />\n </>\n );\n});\n\nCascader.classes = { ...InputBase.classes, ...Combobox.classes, ...classes };\nCascader.displayName = '@mantine/core/Cascader';\n"],"mappings":"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"}
1
+ {"version":3,"file":"Cascader.mjs","names":["useId","classes"],"sources":["../../../src/components/Cascader/Cascader.tsx"],"sourcesContent":["import { Fragment, useEffect, useMemo } from 'react';\nimport type { SafePolygonOptions } from '@floating-ui/react';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n ElementProps,\n extractStyleProps,\n Factory,\n factory,\n MantineColor,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { CheckIcon } from '../Checkbox/CheckIcon';\nimport { Combobox, ComboboxLikeStylesNames, useCombobox } from '../Combobox';\nimport {\n __BaseInputProps,\n __InputStylesNames,\n ClearSectionMode,\n InputClearButtonProps,\n InputVariant,\n} from '../Input';\nimport { InputBase } from '../InputBase';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { CascaderColumns } from './CascaderColumns';\nimport { flattenCascaderPaths } from './flatten-cascader-paths';\nimport { getCascaderPathOptions } from './get-cascader-path-options';\nimport { useCascader } from './use-cascader';\nimport classes from './Cascader.module.css';\n\nexport interface CascaderOption {\n /** Option value, must be unique across the whole data tree */\n value: string;\n\n /** Option label, if not set `value` is used instead */\n label?: React.ReactNode;\n\n /** Nested options */\n children?: CascaderOption[];\n\n /** If set, the option cannot be selected or expanded */\n disabled?: boolean;\n}\n\nexport interface CascaderFormatValueInput {\n /** Selected path from root to node */\n value: string[];\n\n /** Option chain resolved from the selected path */\n options: CascaderOption[];\n}\n\nexport type CascaderFormatValue = (input: CascaderFormatValueInput) => React.ReactNode;\n\nexport type CascaderSafeAreaPolygonOptions = Omit<SafePolygonOptions, 'blockPointerEvents'>;\n\nexport type CascaderStylesNames =\n | __InputStylesNames\n | ComboboxLikeStylesNames\n | 'columnsList'\n | 'columnsOverflow'\n | 'column'\n | 'columnScroll'\n | 'columnOption'\n | 'columnOptionLabel'\n | 'columnOptionIcon'\n | 'columnOptionCheck'\n | 'columnEmpty'\n | 'flatOption';\n\nexport interface CascaderProps\n extends\n BoxProps,\n __BaseInputProps,\n StylesApiProps<CascaderFactory>,\n ElementProps<'input', 'size' | 'value' | 'defaultValue' | 'onChange'> {\n /** Hierarchical options data */\n data: CascaderOption[];\n\n /** Controlled selected path from root to node */\n value?: string[] | null;\n\n /** Uncontrolled selected path from root to node */\n defaultValue?: string[] | null;\n\n /** Called when the selected path changes with the path and the resolved option chain */\n onChange?: (value: string[] | null, options: CascaderOption[]) => void;\n\n /** If set, any intermediate option can be selected, not only leaf options @default false */\n changeOnSelect?: boolean;\n\n /** Determines whether the dropdown should be closed when a value is selected, defaults to `!allowDeselect` */\n closeOnSelect?: boolean;\n\n /** If set, the selected value can be deselected by selecting it again @default true */\n allowDeselect?: boolean;\n\n /** If set, the check icon is displayed on the selected option @default true */\n withCheckIcon?: boolean;\n\n /** Position of the check icon relative to the option label @default 'right' */\n checkIconPosition?: 'left' | 'right';\n\n /** Renders the dropdown as cascading columns. When `false`, options are rendered as a flat list of paths, the same way as search results (useful for narrow/mobile layouts) @default true */\n withColumns?: boolean;\n\n /** Determines how the next column is opened @default 'click' */\n expandTrigger?: 'click' | 'hover';\n\n /** Determines whether the next column stays open while the cursor moves toward it, applicable only when `expandTrigger=\"hover\"`. Pass an object to configure safe polygon behavior. @default true */\n safeAreaPolygon?: boolean | CascaderSafeAreaPolygonOptions;\n\n /** If set, options can be searched by their flattened paths @default false */\n searchable?: boolean;\n\n /** Controlled search value */\n searchValue?: string;\n\n /** Uncontrolled search value */\n defaultSearchValue?: string;\n\n /** Called when the search value changes */\n onSearchChange?: (value: string) => void;\n\n /** Custom search filter, matched against the full option path */\n filter?: (query: string, options: CascaderOption[]) => boolean;\n\n /** Custom rendering of a search result row */\n renderSearchOption?: (query: string, options: CascaderOption[]) => React.ReactNode;\n\n /** A function to format the selected path displayed in the input, should return a string */\n formatValue?: CascaderFormatValue;\n\n /** Custom rendering of an option in columns */\n renderOption?: (option: CascaderOption, level: number) => React.ReactNode;\n\n /** Path separator displayed in the input and search results @default '/' */\n separator?: React.ReactNode;\n\n /** Width of each column */\n columnWidth?: number | string;\n\n /** Maximum number of columns (levels) displayed next to each other, deeper levels replace earlier ones @default 3 */\n maxDisplayedLevels?: number;\n\n /** `aria-label` and `title` of the control that reveals levels hidden before the visible ones by `maxDisplayedLevels` @default 'Show previous levels' */\n previousLevelsControlLabel?: string;\n\n /** `aria-label` and `title` of the control that reveals levels hidden after the visible ones by `maxDisplayedLevels` @default 'Show next levels' */\n nextLevelsControlLabel?: string;\n\n /** Max height of a column before it becomes scrollable @default 260 */\n maxDropdownHeight?: number | string;\n\n /** Message displayed when there are no options or search results */\n nothingFoundMessage?: React.ReactNode;\n\n /** If set, the clear button is displayed when a value is selected @default false */\n clearable?: boolean;\n\n /** Determines how the clear button and `rightSection` are rendered @default 'both' */\n clearSectionMode?: ClearSectionMode;\n\n /** Props passed down to the clear button */\n clearButtonProps?: InputClearButtonProps;\n\n /** Called when the clear button is clicked */\n onClear?: () => void;\n\n /** Controlled dropdown opened state */\n dropdownOpened?: boolean;\n\n /** Uncontrolled dropdown opened state */\n defaultDropdownOpened?: boolean;\n\n /** Called when the dropdown opens */\n onDropdownOpen?: () => void;\n\n /** Called when the dropdown closes */\n onDropdownClose?: () => void;\n\n /** Props passed down to the underlying `Combobox` component */\n comboboxProps?: Record<string, any>;\n\n /** Props passed down to the dropdown `ScrollArea` */\n scrollAreaProps?: ScrollAreaProps;\n\n /** Controls the default chevron color */\n chevronColor?: MantineColor;\n\n /** Props passed down to the hidden input */\n hiddenInputProps?: Omit<React.ComponentProps<'input'>, 'value'>;\n\n /** Opens the dropdown when the input is focused in `searchable` mode @default true */\n openOnFocus?: boolean;\n}\n\nexport type CascaderFactory = Factory<{\n props: CascaderProps;\n ref: HTMLInputElement;\n stylesNames: CascaderStylesNames;\n variant: InputVariant;\n}>;\n\nconst defaultProps = {\n expandTrigger: 'click',\n safeAreaPolygon: true,\n changeOnSelect: false,\n allowDeselect: true,\n withCheckIcon: true,\n checkIconPosition: 'right',\n withColumns: true,\n searchable: false,\n separator: '/',\n maxDisplayedLevels: 3,\n previousLevelsControlLabel: 'Show previous levels',\n nextLevelsControlLabel: 'Show next levels',\n maxDropdownHeight: 260,\n openOnFocus: true,\n size: 'sm',\n} satisfies Partial<CascaderProps>;\n\nfunction optionLabelToString(option: CascaderOption): string {\n return typeof option.label === 'string' || typeof option.label === 'number'\n ? String(option.label)\n : option.value;\n}\n\nfunction firstEnabledOptionIndex(options: CascaderOption[]): number {\n return options.findIndex((option) => !option.disabled);\n}\n\nfunction lastEnabledOptionIndex(options: CascaderOption[]): number {\n for (let index = options.length - 1; index >= 0; index -= 1) {\n if (!options[index].disabled) {\n return index;\n }\n }\n return -1;\n}\n\nfunction joinPathLabels(options: CascaderOption[], separator: string): string {\n return options.map(optionLabelToString).join(` ${separator} `);\n}\n\nfunction defaultCascaderFilter(\n query: string,\n options: CascaderOption[],\n separator: string\n): boolean {\n const trimmed = query.trim().toLowerCase();\n if (trimmed.length === 0) {\n return true;\n }\n return joinPathLabels(options, separator).toLowerCase().includes(trimmed);\n}\n\nfunction defaultRenderSearchOption(\n options: CascaderOption[],\n separator: React.ReactNode\n): React.ReactNode {\n return options.map((option, index) => (\n <Fragment key={option.value}>\n {index > 0 && <span data-cascader-separator> {separator} </span>}\n {option.label ?? option.value}\n </Fragment>\n ));\n}\n\nexport const Cascader = factory<CascaderFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'Cascader'], defaultProps as any, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n size,\n data,\n value,\n defaultValue,\n onChange,\n changeOnSelect,\n closeOnSelect,\n allowDeselect,\n withCheckIcon,\n checkIconPosition,\n withColumns,\n expandTrigger,\n safeAreaPolygon,\n searchable,\n searchValue,\n defaultSearchValue,\n onSearchChange,\n filter,\n renderSearchOption,\n formatValue,\n renderOption,\n separator,\n columnWidth,\n maxDisplayedLevels,\n previousLevelsControlLabel,\n nextLevelsControlLabel,\n maxDropdownHeight,\n nothingFoundMessage,\n clearable,\n clearSectionMode,\n clearButtonProps,\n onClear,\n dropdownOpened,\n defaultDropdownOpened,\n onDropdownOpen,\n onDropdownClose,\n comboboxProps,\n scrollAreaProps,\n chevronColor,\n hiddenInputProps,\n openOnFocus,\n variant,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n readOnly,\n disabled,\n radius,\n rightSection,\n rightSectionWidth,\n rightSectionPointerEvents,\n rightSectionProps,\n leftSection,\n leftSectionWidth,\n leftSectionPointerEvents,\n leftSectionProps,\n inputContainer,\n inputWrapperOrder,\n withAsterisk,\n labelProps,\n descriptionProps,\n errorProps,\n successProps,\n wrapperProps,\n description,\n label,\n error,\n success,\n withErrorStyles,\n withSuccessStyles,\n name,\n form,\n id,\n placeholder,\n required,\n mod,\n attributes,\n ...others\n } = props;\n\n const _id = useId(id);\n const separatorString =\n typeof separator === 'string' || typeof separator === 'number' ? String(separator) : '/';\n\n const combobox = useCombobox({\n opened: dropdownOpened,\n defaultOpened: defaultDropdownOpened,\n onDropdownOpen: () => {\n onDropdownOpen?.();\n cascader.resetActivePath();\n },\n onDropdownClose: () => {\n onDropdownClose?.();\n if (searchable) {\n setSearchValue(cascader.value ? displayString : '');\n }\n },\n });\n\n // When `allowDeselect` is enabled, keep the dropdown open by default so the value can be toggled\n const shouldCloseOnSelect = closeOnSelect ?? !allowDeselect;\n\n const cascader = useCascader({\n data,\n value,\n defaultValue,\n onChange,\n changeOnSelect,\n allowDeselect,\n expandTrigger,\n onLeafSelect: () => {\n if (shouldCloseOnSelect) {\n combobox.closeDropdown();\n }\n },\n });\n\n const getStyles = useStyles<CascaderFactory>({\n name: 'Cascader',\n classes,\n props: props as any,\n classNames,\n styles,\n unstyled,\n attributes,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<CascaderFactory>({\n props,\n styles,\n classNames,\n });\n\n const {\n styleProps,\n rest: { type, autoComplete, ...rest },\n } = extractStyleProps(others);\n\n const displayString = useMemo(() => {\n if (cascader.pathOptions.length === 0 || !cascader.value) {\n return '';\n }\n if (formatValue) {\n const rendered = formatValue({ value: cascader.value, options: cascader.pathOptions });\n if (typeof rendered === 'string' || typeof rendered === 'number') {\n return String(rendered);\n }\n }\n return joinPathLabels(cascader.pathOptions, separatorString);\n }, [cascader.pathOptions, cascader.value, formatValue, separatorString]);\n\n const initialSearchValue = useMemo(() => {\n if (!searchable || !defaultValue) {\n return '';\n }\n return joinPathLabels(getCascaderPathOptions(data, defaultValue), separatorString);\n }, []);\n\n const [_searchValue, setSearchValue] = useUncontrolled({\n value: searchValue,\n defaultValue: defaultSearchValue,\n finalValue: initialSearchValue,\n onChange: onSearchChange,\n });\n\n const isSearching =\n !!searchable && _searchValue.trim().length > 0 && _searchValue !== displayString;\n\n useEffect(() => {\n if (searchable) {\n setSearchValue(cascader.value ? displayString : '');\n }\n }, [cascader.value]);\n\n // The dropdown renders a flat list of paths when searching or when `withColumns` is disabled\n const showFlatList = isSearching || !withColumns;\n\n const flatPaths = useMemo(() => flattenCascaderPaths(data), [data]);\n\n const flatListItems = useMemo(() => {\n if (!showFlatList) {\n return [];\n }\n const base = flatPaths.filter((flatPath) => (changeOnSelect ? true : flatPath.leaf));\n if (!isSearching) {\n return base;\n }\n return base.filter((flatPath) =>\n filter\n ? filter(_searchValue, flatPath.options)\n : defaultCascaderFilter(_searchValue, flatPath.options, separatorString)\n );\n }, [flatPaths, showFlatList, isSearching, _searchValue, changeOnSelect, filter, separatorString]);\n\n const canInteract = !readOnly && !disabled;\n\n const handleSearchChange = (nextValue: string) => {\n setSearchValue(nextValue);\n if (canInteract) {\n combobox.openDropdown();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n\n if (event.key === 'Escape') {\n combobox.closeDropdown();\n return;\n }\n\n if (showFlatList || !canInteract) {\n return;\n }\n\n if (!combobox.dropdownOpened) {\n const opensDropdown =\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp' ||\n event.key === 'ArrowRight' ||\n event.key === 'Enter' ||\n (!searchable && event.key === ' ');\n\n if (opensDropdown) {\n event.preventDefault();\n cascader.setKeyboardNav(true);\n combobox.openDropdown();\n\n if (!cascader.value && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n const rootIndex =\n event.key === 'ArrowDown'\n ? firstEnabledOptionIndex(data)\n : lastEnabledOptionIndex(data);\n if (rootIndex >= 0) {\n cascader.setActivePath([data[rootIndex].value]);\n }\n }\n }\n return;\n }\n\n if (cascader.handleColumnsKeyDown(event)) {\n event.preventDefault();\n } else if (!searchable && event.key === ' ') {\n event.preventDefault();\n }\n };\n\n const clearButton = (\n <Combobox.ClearButton\n {...clearButtonProps}\n onClear={() => {\n onClear?.();\n cascader.setValue(null);\n cascader.setActivePath([]);\n setSearchValue('');\n combobox.focusTarget();\n }}\n />\n );\n\n const hasValue = Array.isArray(cascader.value) && cascader.value.length > 0;\n const _clearable = clearable && hasValue && !disabled && !readOnly;\n\n const listId = _id ? `${_id}-cascader-list` : undefined;\n const valueKey = cascader.value ? JSON.stringify(cascader.value) : null;\n\n const dropdown = (\n <Combobox.Dropdown\n hidden={readOnly || disabled}\n style={showFlatList ? undefined : { padding: 0 }}\n >\n {showFlatList ? (\n <Combobox.Options aria-label={typeof label === 'string' ? label : undefined}>\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 260}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n offsetScrollbars=\"y\"\n {...scrollAreaProps}\n >\n {flatListItems.map((flatPath, index) => {\n const pathKey = JSON.stringify(flatPath.path);\n const active = valueKey !== null && pathKey === valueKey;\n return (\n <Combobox.Option\n key={pathKey}\n value={`${index}`}\n active={active}\n disabled={flatPath.disabled}\n >\n <span {...getStyles('flatOption')}>\n {active && withCheckIcon && checkIconPosition === 'left' && (\n <CheckIcon {...getStyles('columnOptionCheck')} />\n )}\n <span {...getStyles('columnOptionLabel')}>\n {renderSearchOption\n ? renderSearchOption(_searchValue, flatPath.options)\n : defaultRenderSearchOption(flatPath.options, separator)}\n </span>\n {active && withCheckIcon && checkIconPosition !== 'left' && (\n <CheckIcon {...getStyles('columnOptionCheck')} />\n )}\n </span>\n </Combobox.Option>\n );\n })}\n </ScrollArea.Autosize>\n {flatListItems.length === 0 && nothingFoundMessage && (\n <Combobox.Empty>{nothingFoundMessage}</Combobox.Empty>\n )}\n </Combobox.Options>\n ) : (\n <CascaderColumns\n data={data}\n activePath={cascader.activePath}\n value={cascader.value}\n keyboardNav={cascader.keyboardNav}\n withCheckIcon={withCheckIcon}\n checkIconPosition={checkIconPosition}\n renderOption={renderOption}\n columnWidth={columnWidth}\n maxDisplayedLevels={maxDisplayedLevels}\n previousLevelsControlLabel={previousLevelsControlLabel}\n nextLevelsControlLabel={nextLevelsControlLabel}\n maxDropdownHeight={maxDropdownHeight}\n nothingFoundMessage={nothingFoundMessage}\n getStyles={getStyles}\n unstyled={unstyled}\n scrollAreaProps={scrollAreaProps}\n onOptionClick={cascader.handleOptionClick}\n onOptionMouseEnter={cascader.handleOptionMouseEnter}\n onColumnsMouseLeave={() => {\n if (expandTrigger === 'hover') {\n cascader.setActivePath(cascader.value ?? []);\n }\n }}\n onPointerActivity={() => cascader.setKeyboardNav(false)}\n listId={listId}\n safeAreaPolygon={expandTrigger === 'hover' ? safeAreaPolygon : false}\n />\n )}\n </Combobox.Dropdown>\n );\n\n return (\n <>\n <Combobox\n store={combobox}\n __staticSelector=\"Cascader\"\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n readOnly={readOnly}\n size={size}\n attributes={attributes}\n width={showFlatList ? 'target' : 'max-content'}\n position=\"bottom-start\"\n onOptionSubmit={(val) => {\n const index = Number(val);\n const flatPath = flatListItems[index];\n if (!flatPath || flatPath.disabled) {\n return;\n }\n cascader.selectPath(flatPath.path);\n cascader.setActivePath(flatPath.path);\n if (shouldCloseOnSelect) {\n combobox.closeDropdown();\n }\n }}\n {...comboboxProps}\n >\n <Combobox.Target\n targetType={searchable ? 'input' : 'button'}\n withKeyboardNavigation={showFlatList}\n autoComplete={autoComplete}\n >\n <InputBase\n id={_id}\n __defaultRightSection={\n <Combobox.Chevron\n size={size}\n error={error}\n unstyled={unstyled}\n color={chevronColor}\n />\n }\n __clearSection={clearButton}\n __clearable={_clearable}\n __clearSectionMode={clearSectionMode}\n rightSection={rightSection}\n rightSectionPointerEvents={rightSectionPointerEvents || 'none'}\n {...rest}\n {...styleProps}\n size={size}\n __staticSelector=\"Cascader\"\n disabled={disabled}\n readOnly={readOnly || !searchable}\n value={searchable ? _searchValue : displayString}\n onChange={(event) => handleSearchChange(event.currentTarget.value)}\n onFocus={(event) => {\n if (openOnFocus && searchable && canInteract) {\n combobox.openDropdown();\n }\n onFocus?.(event);\n }}\n onBlur={(event) => {\n combobox.closeDropdown();\n onBlur?.(event);\n }}\n onClick={(event) => {\n if (canInteract) {\n cascader.setKeyboardNav(false);\n if (searchable) {\n combobox.openDropdown();\n } else {\n combobox.toggleDropdown();\n }\n }\n onClick?.(event);\n }}\n onKeyDown={handleKeyDown}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n pointer={!searchable}\n error={error}\n success={success}\n attributes={attributes}\n className={className}\n style={style}\n variant={variant}\n radius={radius}\n leftSection={leftSection}\n leftSectionWidth={leftSectionWidth}\n leftSectionPointerEvents={leftSectionPointerEvents}\n leftSectionProps={leftSectionProps}\n rightSectionWidth={rightSectionWidth}\n rightSectionProps={rightSectionProps}\n inputContainer={inputContainer}\n inputWrapperOrder={inputWrapperOrder}\n withAsterisk={withAsterisk}\n labelProps={labelProps}\n descriptionProps={descriptionProps}\n errorProps={errorProps}\n successProps={successProps}\n wrapperProps={wrapperProps}\n description={description}\n label={label}\n withErrorStyles={withErrorStyles}\n withSuccessStyles={withSuccessStyles}\n placeholder={placeholder}\n required={required}\n mod={mod}\n />\n </Combobox.Target>\n {dropdown}\n </Combobox>\n <Combobox.HiddenInput\n value={cascader.value}\n name={name}\n form={form}\n disabled={disabled}\n {...hiddenInputProps}\n />\n </>\n );\n});\n\nCascader.classes = { ...InputBase.classes, ...Combobox.classes, ...classes };\nCascader.displayName = '@mantine/core/Cascader';\n"],"mappings":"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"}
@@ -4,13 +4,14 @@ import { UnstyledButton } from "../UnstyledButton/UnstyledButton.mjs";
4
4
  import { AccordionChevron } from "../Accordion/AccordionChevron.mjs";
5
5
  import { CheckIcon } from "../Checkbox/CheckIcon.mjs";
6
6
  import { cascaderOptionHasChildren, getCascaderColumns } from "./get-cascader-columns.mjs";
7
- import { useState } from "react";
7
+ import { useCascaderSafeArea } from "./use-cascader-safe-area.mjs";
8
+ import { useRef, useState } from "react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  //#region packages/@mantine/core/src/components/Cascader/CascaderColumns.tsx
10
11
  function getCascaderOptionId(listId, level, value) {
11
12
  return listId ? `${listId}-${level}-${value}` : void 0;
12
13
  }
13
- function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon, checkIconPosition, renderOption, columnWidth, maxDisplayedLevels, previousLevelsControlLabel, nextLevelsControlLabel, maxDropdownHeight, nothingFoundMessage, getStyles, unstyled, scrollAreaProps, onOptionClick, onOptionMouseEnter, onColumnsMouseLeave, onPointerActivity, listId }) {
14
+ function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon, checkIconPosition, renderOption, columnWidth, maxDisplayedLevels, previousLevelsControlLabel, nextLevelsControlLabel, maxDropdownHeight, nothingFoundMessage, getStyles, unstyled, scrollAreaProps, onOptionClick, onOptionMouseEnter, onColumnsMouseLeave, onPointerActivity, listId, safeAreaPolygon }) {
14
15
  const allColumns = getCascaderColumns(data, activePath);
15
16
  const totalColumns = allColumns.length;
16
17
  const maxLevels = maxDisplayedLevels && maxDisplayedLevels > 0 ? maxDisplayedLevels : totalColumns;
@@ -37,10 +38,18 @@ function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon,
37
38
  const hiddenBefore = windowStart;
38
39
  const hiddenAfter = totalColumns - windowEnd;
39
40
  const check = showCheckIcon ? /* @__PURE__ */ jsx(CheckIcon, { ...getStyles("columnOptionCheck") }) : null;
41
+ const columnRefs = useRef({});
42
+ const safeArea = useCascaderSafeArea({
43
+ safeAreaPolygon,
44
+ onFlush: onOptionMouseEnter
45
+ });
40
46
  return /* @__PURE__ */ jsxs("div", {
41
47
  ...getStyles("columnsList"),
42
48
  role: "presentation",
43
- onMouseLeave: onColumnsMouseLeave,
49
+ onMouseLeave: () => {
50
+ safeArea.disarm();
51
+ onColumnsMouseLeave?.();
52
+ },
44
53
  onMouseMove: onPointerActivity,
45
54
  children: [
46
55
  hiddenBefore > 0 && /* @__PURE__ */ jsx(UnstyledButton, {
@@ -57,6 +66,9 @@ function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon,
57
66
  visibleColumns.map((options, index) => {
58
67
  const level = windowStart + index;
59
68
  return /* @__PURE__ */ jsx("div", {
69
+ ref: (node) => {
70
+ columnRefs.current[level] = node;
71
+ },
60
72
  "data-last": index === visibleColumns.length - 1 && hiddenAfter === 0 || void 0,
61
73
  ...getStyles("column", { style: columnWidth ? {
62
74
  width: columnWidth,
@@ -94,7 +106,26 @@ function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon,
94
106
  if (!option.disabled) onOptionClick(level, option);
95
107
  },
96
108
  onMouseEnter: () => {
97
- if (!option.disabled) onOptionMouseEnter(level, option);
109
+ if (option.disabled) return;
110
+ if (safeArea.isBlocked(level)) {
111
+ safeArea.setPending(level, option);
112
+ return;
113
+ }
114
+ onOptionMouseEnter(level, option);
115
+ },
116
+ onMouseLeave: (event) => {
117
+ safeArea.clearPending(level, option);
118
+ if (!safeArea.enabled || option.disabled) return;
119
+ if (activePath[level] !== option.value) return;
120
+ const floating = columnRefs.current[level + 1];
121
+ if (!floating) return;
122
+ safeArea.arm({
123
+ level,
124
+ reference: event.currentTarget,
125
+ floating,
126
+ clientX: event.clientX,
127
+ clientY: event.clientY
128
+ });
98
129
  },
99
130
  ...getStyles("columnOption"),
100
131
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"CascaderColumns.mjs","names":[],"sources":["../../../src/components/Cascader/CascaderColumns.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { GetStylesApi } from '../../core';\nimport { AccordionChevron } from '../Accordion';\nimport { CheckIcon } from '../Checkbox/CheckIcon';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { UnstyledButton } from '../UnstyledButton';\nimport type { CascaderOption, CascaderStylesNames } from './Cascader';\nimport { cascaderOptionHasChildren, getCascaderColumns } from './get-cascader-columns';\n\ntype CascaderColumnsGetStyles = GetStylesApi<{ props: any; stylesNames: CascaderStylesNames }>;\n\nexport interface CascaderColumnsProps {\n data: CascaderOption[];\n activePath: string[];\n value: string[] | null;\n keyboardNav: boolean;\n withCheckIcon: boolean | undefined;\n checkIconPosition: 'left' | 'right' | undefined;\n renderOption: ((option: CascaderOption, level: number) => React.ReactNode) | undefined;\n columnWidth: number | string | undefined;\n maxDisplayedLevels: number | undefined;\n previousLevelsControlLabel: string | undefined;\n nextLevelsControlLabel: string | undefined;\n maxDropdownHeight: number | string | undefined;\n nothingFoundMessage: React.ReactNode;\n getStyles: CascaderColumnsGetStyles;\n unstyled: boolean | undefined;\n scrollAreaProps: ScrollAreaProps | undefined;\n onOptionClick: (level: number, option: CascaderOption) => void;\n onOptionMouseEnter: (level: number, option: CascaderOption) => void;\n onColumnsMouseLeave: (() => void) | undefined;\n onPointerActivity: (() => void) | undefined;\n listId: string | undefined;\n}\n\nexport function getCascaderOptionId(listId: string | undefined, level: number, value: string) {\n return listId ? `${listId}-${level}-${value}` : undefined;\n}\n\nexport function CascaderColumns({\n data,\n activePath,\n value,\n keyboardNav,\n withCheckIcon,\n checkIconPosition,\n renderOption,\n columnWidth,\n maxDisplayedLevels,\n previousLevelsControlLabel,\n nextLevelsControlLabel,\n maxDropdownHeight,\n nothingFoundMessage,\n getStyles,\n unstyled,\n scrollAreaProps,\n onOptionClick,\n onOptionMouseEnter,\n onColumnsMouseLeave,\n onPointerActivity,\n listId,\n}: CascaderColumnsProps) {\n const allColumns = getCascaderColumns(data, activePath);\n const totalColumns = allColumns.length;\n const maxLevels =\n maxDisplayedLevels && maxDisplayedLevels > 0 ? maxDisplayedLevels : totalColumns;\n const maxOffset = Math.max(0, totalColumns - maxLevels);\n const focusedLevel = activePath.length - 1;\n const showCheckIcon = withCheckIcon !== false;\n\n // Manual left/right scrolling of the visible window. It is reset synchronously whenever the\n // active path changes so that the focused column always stays visible during navigation.\n const activePathKey = JSON.stringify(activePath);\n const [windowState, setWindowState] = useState({ key: activePathKey, offset: 0 });\n const windowOffset = windowState.key === activePathKey ? windowState.offset : 0;\n if (windowState.key !== activePathKey) {\n setWindowState({ key: activePathKey, offset: 0 });\n }\n const setWindowOffset = (updater: (current: number) => number) =>\n setWindowState((current) => ({ key: activePathKey, offset: updater(current.offset) }));\n\n const clampedOffset = Math.min(windowOffset, maxOffset);\n const windowStart = Math.max(0, maxOffset - clampedOffset);\n const windowEnd = Math.min(totalColumns, windowStart + maxLevels);\n const visibleColumns = allColumns.slice(windowStart, windowEnd);\n const hiddenBefore = windowStart;\n const hiddenAfter = totalColumns - windowEnd;\n\n const check = showCheckIcon ? <CheckIcon {...getStyles('columnOptionCheck')} /> : null;\n\n return (\n <div\n {...getStyles('columnsList')}\n role=\"presentation\"\n onMouseLeave={onColumnsMouseLeave}\n onMouseMove={onPointerActivity}\n >\n {hiddenBefore > 0 && (\n <UnstyledButton\n {...getStyles('columnsOverflow')}\n data-position=\"start\"\n tabIndex={-1}\n unstyled={unstyled}\n aria-label={previousLevelsControlLabel}\n title={previousLevelsControlLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setWindowOffset((current) => Math.min(maxOffset, current + 1))}\n >\n <AccordionChevron />\n </UnstyledButton>\n )}\n\n {visibleColumns.map((options, index) => {\n const level = windowStart + index;\n const isLastColumn = index === visibleColumns.length - 1 && hiddenAfter === 0;\n\n return (\n <div\n key={level}\n data-last={isLastColumn || undefined}\n {...getStyles('column', {\n style: columnWidth ? { width: columnWidth, minWidth: columnWidth } : undefined,\n })}\n >\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 260}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n role=\"listbox\"\n {...scrollAreaProps}\n {...getStyles('columnScroll')}\n >\n {options.length === 0 ? (\n <div {...getStyles('columnEmpty')}>{nothingFoundMessage}</div>\n ) : (\n options.map((option) => {\n const isActive = activePath[level] === option.value;\n const isCurrent = isActive && level === focusedLevel && keyboardNav;\n // The trail only covers ancestor columns; the deepest column is not highlighted\n // during mouse navigation (only via the keyboard \"current\" state)\n const isInPath = isActive && level < focusedLevel;\n const hasChildren = cascaderOptionHasChildren(option);\n const isSelected =\n !!value && value.length === level + 1 && value[level] === option.value;\n\n return (\n <UnstyledButton\n key={option.value}\n id={getCascaderOptionId(listId, level, option.value)}\n role=\"option\"\n aria-selected={isCurrent || undefined}\n aria-disabled={option.disabled || undefined}\n data-active={isCurrent || undefined}\n data-in-path={isInPath || undefined}\n data-selected={isSelected || undefined}\n data-disabled={option.disabled || undefined}\n tabIndex={-1}\n unstyled={unstyled}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (!option.disabled) {\n onOptionClick(level, option);\n }\n }}\n onMouseEnter={() => {\n if (!option.disabled) {\n onOptionMouseEnter(level, option);\n }\n }}\n {...getStyles('columnOption')}\n >\n {isSelected && checkIconPosition === 'left' && check}\n\n <span {...getStyles('columnOptionLabel')}>\n {renderOption\n ? renderOption(option, level)\n : (option.label ?? option.value)}\n </span>\n\n {isSelected && checkIconPosition !== 'left' && check}\n\n {hasChildren && (\n <span {...getStyles('columnOptionIcon')}>\n <AccordionChevron />\n </span>\n )}\n </UnstyledButton>\n );\n })\n )}\n </ScrollArea.Autosize>\n </div>\n );\n })}\n\n {hiddenAfter > 0 && (\n <UnstyledButton\n {...getStyles('columnsOverflow')}\n data-position=\"end\"\n tabIndex={-1}\n unstyled={unstyled}\n aria-label={nextLevelsControlLabel}\n title={nextLevelsControlLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setWindowOffset((current) => Math.max(0, current - 1))}\n >\n <AccordionChevron />\n </UnstyledButton>\n )}\n </div>\n );\n}\n\nCascaderColumns.displayName = '@mantine/core/CascaderColumns';\n"],"mappings":"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"}
1
+ {"version":3,"file":"CascaderColumns.mjs","names":[],"sources":["../../../src/components/Cascader/CascaderColumns.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport type { GetStylesApi } from '../../core';\nimport { AccordionChevron } from '../Accordion';\nimport { CheckIcon } from '../Checkbox/CheckIcon';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { UnstyledButton } from '../UnstyledButton';\nimport type {\n CascaderOption,\n CascaderSafeAreaPolygonOptions,\n CascaderStylesNames,\n} from './Cascader';\nimport { cascaderOptionHasChildren, getCascaderColumns } from './get-cascader-columns';\nimport { useCascaderSafeArea } from './use-cascader-safe-area';\n\ntype CascaderColumnsGetStyles = GetStylesApi<{ props: any; stylesNames: CascaderStylesNames }>;\n\nexport interface CascaderColumnsProps {\n data: CascaderOption[];\n activePath: string[];\n value: string[] | null;\n keyboardNav: boolean;\n withCheckIcon: boolean | undefined;\n checkIconPosition: 'left' | 'right' | undefined;\n renderOption: ((option: CascaderOption, level: number) => React.ReactNode) | undefined;\n columnWidth: number | string | undefined;\n maxDisplayedLevels: number | undefined;\n previousLevelsControlLabel: string | undefined;\n nextLevelsControlLabel: string | undefined;\n maxDropdownHeight: number | string | undefined;\n nothingFoundMessage: React.ReactNode;\n getStyles: CascaderColumnsGetStyles;\n unstyled: boolean | undefined;\n scrollAreaProps: ScrollAreaProps | undefined;\n onOptionClick: (level: number, option: CascaderOption) => void;\n onOptionMouseEnter: (level: number, option: CascaderOption) => void;\n onColumnsMouseLeave: (() => void) | undefined;\n onPointerActivity: (() => void) | undefined;\n listId: string | undefined;\n safeAreaPolygon: boolean | CascaderSafeAreaPolygonOptions | undefined;\n}\n\nexport function getCascaderOptionId(listId: string | undefined, level: number, value: string) {\n return listId ? `${listId}-${level}-${value}` : undefined;\n}\n\nexport function CascaderColumns({\n data,\n activePath,\n value,\n keyboardNav,\n withCheckIcon,\n checkIconPosition,\n renderOption,\n columnWidth,\n maxDisplayedLevels,\n previousLevelsControlLabel,\n nextLevelsControlLabel,\n maxDropdownHeight,\n nothingFoundMessage,\n getStyles,\n unstyled,\n scrollAreaProps,\n onOptionClick,\n onOptionMouseEnter,\n onColumnsMouseLeave,\n onPointerActivity,\n listId,\n safeAreaPolygon,\n}: CascaderColumnsProps) {\n const allColumns = getCascaderColumns(data, activePath);\n const totalColumns = allColumns.length;\n const maxLevels =\n maxDisplayedLevels && maxDisplayedLevels > 0 ? maxDisplayedLevels : totalColumns;\n const maxOffset = Math.max(0, totalColumns - maxLevels);\n const focusedLevel = activePath.length - 1;\n const showCheckIcon = withCheckIcon !== false;\n\n // Manual left/right scrolling of the visible window. It is reset synchronously whenever the\n // active path changes so that the focused column always stays visible during navigation.\n const activePathKey = JSON.stringify(activePath);\n const [windowState, setWindowState] = useState({ key: activePathKey, offset: 0 });\n const windowOffset = windowState.key === activePathKey ? windowState.offset : 0;\n if (windowState.key !== activePathKey) {\n setWindowState({ key: activePathKey, offset: 0 });\n }\n const setWindowOffset = (updater: (current: number) => number) =>\n setWindowState((current) => ({ key: activePathKey, offset: updater(current.offset) }));\n\n const clampedOffset = Math.min(windowOffset, maxOffset);\n const windowStart = Math.max(0, maxOffset - clampedOffset);\n const windowEnd = Math.min(totalColumns, windowStart + maxLevels);\n const visibleColumns = allColumns.slice(windowStart, windowEnd);\n const hiddenBefore = windowStart;\n const hiddenAfter = totalColumns - windowEnd;\n\n const check = showCheckIcon ? <CheckIcon {...getStyles('columnOptionCheck')} /> : null;\n\n const columnRefs = useRef<Record<number, HTMLDivElement | null>>({});\n const safeArea = useCascaderSafeArea({ safeAreaPolygon, onFlush: onOptionMouseEnter });\n\n return (\n <div\n {...getStyles('columnsList')}\n role=\"presentation\"\n onMouseLeave={() => {\n safeArea.disarm();\n onColumnsMouseLeave?.();\n }}\n onMouseMove={onPointerActivity}\n >\n {hiddenBefore > 0 && (\n <UnstyledButton\n {...getStyles('columnsOverflow')}\n data-position=\"start\"\n tabIndex={-1}\n unstyled={unstyled}\n aria-label={previousLevelsControlLabel}\n title={previousLevelsControlLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setWindowOffset((current) => Math.min(maxOffset, current + 1))}\n >\n <AccordionChevron />\n </UnstyledButton>\n )}\n\n {visibleColumns.map((options, index) => {\n const level = windowStart + index;\n const isLastColumn = index === visibleColumns.length - 1 && hiddenAfter === 0;\n\n return (\n <div\n key={level}\n ref={(node) => {\n columnRefs.current[level] = node;\n }}\n data-last={isLastColumn || undefined}\n {...getStyles('column', {\n style: columnWidth ? { width: columnWidth, minWidth: columnWidth } : undefined,\n })}\n >\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 260}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n role=\"listbox\"\n {...scrollAreaProps}\n {...getStyles('columnScroll')}\n >\n {options.length === 0 ? (\n <div {...getStyles('columnEmpty')}>{nothingFoundMessage}</div>\n ) : (\n options.map((option) => {\n const isActive = activePath[level] === option.value;\n const isCurrent = isActive && level === focusedLevel && keyboardNav;\n // The trail only covers ancestor columns; the deepest column is not highlighted\n // during mouse navigation (only via the keyboard \"current\" state)\n const isInPath = isActive && level < focusedLevel;\n const hasChildren = cascaderOptionHasChildren(option);\n const isSelected =\n !!value && value.length === level + 1 && value[level] === option.value;\n\n return (\n <UnstyledButton\n key={option.value}\n id={getCascaderOptionId(listId, level, option.value)}\n role=\"option\"\n aria-selected={isCurrent || undefined}\n aria-disabled={option.disabled || undefined}\n data-active={isCurrent || undefined}\n data-in-path={isInPath || undefined}\n data-selected={isSelected || undefined}\n data-disabled={option.disabled || undefined}\n tabIndex={-1}\n unstyled={unstyled}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (!option.disabled) {\n onOptionClick(level, option);\n }\n }}\n onMouseEnter={() => {\n if (option.disabled) {\n return;\n }\n\n if (safeArea.isBlocked(level)) {\n safeArea.setPending(level, option);\n return;\n }\n\n onOptionMouseEnter(level, option);\n }}\n onMouseLeave={(event) => {\n safeArea.clearPending(level, option);\n\n if (!safeArea.enabled || option.disabled) {\n return;\n }\n\n if (activePath[level] !== option.value) {\n return;\n }\n\n const floating = columnRefs.current[level + 1];\n\n if (!floating) {\n return;\n }\n\n safeArea.arm({\n level,\n reference: event.currentTarget,\n floating,\n clientX: event.clientX,\n clientY: event.clientY,\n });\n }}\n {...getStyles('columnOption')}\n >\n {isSelected && checkIconPosition === 'left' && check}\n\n <span {...getStyles('columnOptionLabel')}>\n {renderOption\n ? renderOption(option, level)\n : (option.label ?? option.value)}\n </span>\n\n {isSelected && checkIconPosition !== 'left' && check}\n\n {hasChildren && (\n <span {...getStyles('columnOptionIcon')}>\n <AccordionChevron />\n </span>\n )}\n </UnstyledButton>\n );\n })\n )}\n </ScrollArea.Autosize>\n </div>\n );\n })}\n\n {hiddenAfter > 0 && (\n <UnstyledButton\n {...getStyles('columnsOverflow')}\n data-position=\"end\"\n tabIndex={-1}\n unstyled={unstyled}\n aria-label={nextLevelsControlLabel}\n title={nextLevelsControlLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setWindowOffset((current) => Math.max(0, current - 1))}\n >\n <AccordionChevron />\n </UnstyledButton>\n )}\n </div>\n );\n}\n\nCascaderColumns.displayName = '@mantine/core/CascaderColumns';\n"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ "use client";
2
+ import { useDirection } from "../../core/DirectionProvider/DirectionProvider.mjs";
3
+ import { useCallback, useEffect, useRef } from "react";
4
+ import { safePolygon } from "@floating-ui/react";
5
+ //#region packages/@mantine/core/src/components/Cascader/use-cascader-safe-area.ts
6
+ function useCascaderSafeArea({ safeAreaPolygon, onFlush }) {
7
+ const { dir } = useDirection();
8
+ const enabled = Boolean(safeAreaPolygon);
9
+ const optionsRef = useRef(void 0);
10
+ optionsRef.current = typeof safeAreaPolygon === "object" ? safeAreaPolygon : void 0;
11
+ const dirRef = useRef(dir);
12
+ dirRef.current = dir;
13
+ const onFlushRef = useRef(onFlush);
14
+ onFlushRef.current = onFlush;
15
+ const blockedLevelRef = useRef(null);
16
+ const pendingRef = useRef(null);
17
+ const cleanupRef = useRef(() => {});
18
+ const generationRef = useRef(0);
19
+ const disarm = useCallback(() => {
20
+ generationRef.current += 1;
21
+ cleanupRef.current();
22
+ cleanupRef.current = () => {};
23
+ blockedLevelRef.current = null;
24
+ pendingRef.current = null;
25
+ }, []);
26
+ const arm = useCallback(({ level, reference, floating, clientX, clientY }) => {
27
+ disarm();
28
+ const generation = generationRef.current;
29
+ const ownerDocument = floating.ownerDocument;
30
+ const handleMouseMove = safePolygon(optionsRef.current)({
31
+ x: clientX,
32
+ y: clientY,
33
+ placement: dirRef.current === "rtl" ? "left-start" : "right-start",
34
+ elements: {
35
+ domReference: reference,
36
+ floating
37
+ },
38
+ onClose: () => {
39
+ if (generationRef.current !== generation) return;
40
+ const pending = pendingRef.current;
41
+ pendingRef.current = null;
42
+ disarm();
43
+ if (pending) onFlushRef.current(pending.level, pending.option);
44
+ }
45
+ });
46
+ blockedLevelRef.current = level;
47
+ ownerDocument.addEventListener("mousemove", handleMouseMove);
48
+ cleanupRef.current = () => ownerDocument.removeEventListener("mousemove", handleMouseMove);
49
+ }, [disarm]);
50
+ useEffect(() => disarm, [disarm]);
51
+ useEffect(() => {
52
+ if (!enabled) disarm();
53
+ }, [enabled, disarm]);
54
+ const isBlocked = (level) => blockedLevelRef.current !== null && level <= blockedLevelRef.current;
55
+ const setPending = (level, option) => {
56
+ pendingRef.current = {
57
+ level,
58
+ option
59
+ };
60
+ };
61
+ const clearPending = (level, option) => {
62
+ if (pendingRef.current?.level === level && pendingRef.current?.option.value === option.value) pendingRef.current = null;
63
+ };
64
+ return {
65
+ enabled,
66
+ arm,
67
+ disarm,
68
+ isBlocked,
69
+ setPending,
70
+ clearPending
71
+ };
72
+ }
73
+ //#endregion
74
+ export { useCascaderSafeArea };
75
+
76
+ //# sourceMappingURL=use-cascader-safe-area.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-cascader-safe-area.mjs","names":[],"sources":["../../../src/components/Cascader/use-cascader-safe-area.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { safePolygon, type HandleCloseContext } from '@floating-ui/react';\nimport { useDirection } from '../../core';\nimport type { CascaderOption, CascaderSafeAreaPolygonOptions } from './Cascader';\n\nexport interface CascaderSafeAreaArmInput {\n level: number;\n reference: HTMLElement;\n floating: HTMLElement;\n clientX: number;\n clientY: number;\n}\n\nexport interface UseCascaderSafeAreaInput {\n safeAreaPolygon: boolean | CascaderSafeAreaPolygonOptions | undefined;\n onFlush: (level: number, option: CascaderOption) => void;\n}\n\nexport function useCascaderSafeArea({ safeAreaPolygon, onFlush }: UseCascaderSafeAreaInput) {\n const { dir } = useDirection();\n const enabled = Boolean(safeAreaPolygon);\n\n const optionsRef = useRef<CascaderSafeAreaPolygonOptions | undefined>(undefined);\n optionsRef.current = typeof safeAreaPolygon === 'object' ? safeAreaPolygon : undefined;\n\n const dirRef = useRef(dir);\n dirRef.current = dir;\n\n const onFlushRef = useRef(onFlush);\n onFlushRef.current = onFlush;\n\n const blockedLevelRef = useRef<number | null>(null);\n const pendingRef = useRef<{ level: number; option: CascaderOption } | null>(null);\n const cleanupRef = useRef<() => void>(() => {});\n const generationRef = useRef(0);\n\n const disarm = useCallback(() => {\n generationRef.current += 1;\n cleanupRef.current();\n cleanupRef.current = () => {};\n blockedLevelRef.current = null;\n pendingRef.current = null;\n }, []);\n\n const arm = useCallback(\n ({ level, reference, floating, clientX, clientY }: CascaderSafeAreaArmInput) => {\n disarm();\n const generation = generationRef.current;\n const ownerDocument = floating.ownerDocument;\n\n const handleMouseMove = safePolygon(optionsRef.current)({\n x: clientX,\n y: clientY,\n placement: dirRef.current === 'rtl' ? 'left-start' : 'right-start',\n elements: { domReference: reference, floating },\n onClose: () => {\n if (generationRef.current !== generation) {\n return;\n }\n\n const pending = pendingRef.current;\n pendingRef.current = null;\n disarm();\n\n if (pending) {\n onFlushRef.current(pending.level, pending.option);\n }\n },\n } as unknown as HandleCloseContext);\n\n blockedLevelRef.current = level;\n ownerDocument.addEventListener('mousemove', handleMouseMove);\n cleanupRef.current = () => ownerDocument.removeEventListener('mousemove', handleMouseMove);\n },\n [disarm]\n );\n\n useEffect(() => disarm, [disarm]);\n\n useEffect(() => {\n if (!enabled) {\n disarm();\n }\n }, [enabled, disarm]);\n\n const isBlocked = (level: number) =>\n blockedLevelRef.current !== null && level <= blockedLevelRef.current;\n\n const setPending = (level: number, option: CascaderOption) => {\n pendingRef.current = { level, option };\n };\n\n const clearPending = (level: number, option: CascaderOption) => {\n if (pendingRef.current?.level === level && pendingRef.current?.option.value === option.value) {\n pendingRef.current = null;\n }\n };\n\n return { enabled, arm, disarm, isBlocked, setPending, clearPending };\n}\n"],"mappings":";;;;;AAkBA,SAAgB,oBAAoB,EAAE,iBAAiB,WAAqC;CAC1F,MAAM,EAAE,QAAQ,aAAa;CAC7B,MAAM,UAAU,QAAQ,eAAe;CAEvC,MAAM,aAAa,OAAmD,KAAA,CAAS;CAC/E,WAAW,UAAU,OAAO,oBAAoB,WAAW,kBAAkB,KAAA;CAE7E,MAAM,SAAS,OAAO,GAAG;CACzB,OAAO,UAAU;CAEjB,MAAM,aAAa,OAAO,OAAO;CACjC,WAAW,UAAU;CAErB,MAAM,kBAAkB,OAAsB,IAAI;CAClD,MAAM,aAAa,OAAyD,IAAI;CAChF,MAAM,aAAa,aAAyB,CAAC,CAAC;CAC9C,MAAM,gBAAgB,OAAO,CAAC;CAE9B,MAAM,SAAS,kBAAkB;EAC/B,cAAc,WAAW;EACzB,WAAW,QAAQ;EACnB,WAAW,gBAAgB,CAAC;EAC5B,gBAAgB,UAAU;EAC1B,WAAW,UAAU;CACvB,GAAG,CAAC,CAAC;CAEL,MAAM,MAAM,aACT,EAAE,OAAO,WAAW,UAAU,SAAS,cAAwC;EAC9E,OAAO;EACP,MAAM,aAAa,cAAc;EACjC,MAAM,gBAAgB,SAAS;EAE/B,MAAM,kBAAkB,YAAY,WAAW,OAAO,CAAC,CAAC;GACtD,GAAG;GACH,GAAG;GACH,WAAW,OAAO,YAAY,QAAQ,eAAe;GACrD,UAAU;IAAE,cAAc;IAAW;GAAS;GAC9C,eAAe;IACb,IAAI,cAAc,YAAY,YAC5B;IAGF,MAAM,UAAU,WAAW;IAC3B,WAAW,UAAU;IACrB,OAAO;IAEP,IAAI,SACF,WAAW,QAAQ,QAAQ,OAAO,QAAQ,MAAM;GAEpD;EACF,CAAkC;EAElC,gBAAgB,UAAU;EAC1B,cAAc,iBAAiB,aAAa,eAAe;EAC3D,WAAW,gBAAgB,cAAc,oBAAoB,aAAa,eAAe;CAC3F,GACA,CAAC,MAAM,CACT;CAEA,gBAAgB,QAAQ,CAAC,MAAM,CAAC;CAEhC,gBAAgB;EACd,IAAI,CAAC,SACH,OAAO;CAEX,GAAG,CAAC,SAAS,MAAM,CAAC;CAEpB,MAAM,aAAa,UACjB,gBAAgB,YAAY,QAAQ,SAAS,gBAAgB;CAE/D,MAAM,cAAc,OAAe,WAA2B;EAC5D,WAAW,UAAU;GAAE;GAAO;EAAO;CACvC;CAEA,MAAM,gBAAgB,OAAe,WAA2B;EAC9D,IAAI,WAAW,SAAS,UAAU,SAAS,WAAW,SAAS,OAAO,UAAU,OAAO,OACrF,WAAW,UAAU;CAEzB;CAEA,OAAO;EAAE;EAAS;EAAK;EAAQ;EAAW;EAAY;CAAa;AACrE"}
@@ -16,7 +16,7 @@ const defaultProps = { withBorder: true };
16
16
  const varsResolver = createVarsResolver((_, { radius }) => ({ card: { "--card-radius": getRadius(radius) } }));
17
17
  const CheckboxCard = factory((_props) => {
18
18
  const props = useProps("CheckboxCard", defaultProps, _props);
19
- const { classNames, className, style, styles, unstyled, vars, checked, mod, withBorder, value, onClick, defaultChecked, onChange, attributes, ...others } = props;
19
+ const { classNames, className, style, styles, unstyled, vars, checked, mod, withBorder, value, onClick, defaultChecked, onChange, indeterminate, attributes, ...others } = props;
20
20
  const getStyles = useStyles({
21
21
  name: "CheckboxCard",
22
22
  classes: CheckboxCard_module_default,
@@ -39,16 +39,20 @@ const CheckboxCard = factory((_props) => {
39
39
  onChange
40
40
  });
41
41
  return /* @__PURE__ */ jsx(CheckboxCardContext, {
42
- value: { checked: _value },
42
+ value: {
43
+ checked: _value,
44
+ indeterminate
45
+ },
43
46
  children: /* @__PURE__ */ jsx(UnstyledButton, {
44
47
  mod: [{
45
48
  "with-border": withBorder,
46
- checked: _value
49
+ checked: _value,
50
+ indeterminate
47
51
  }, mod],
48
52
  ...getStyles("card"),
49
53
  ...others,
50
54
  role: "checkbox",
51
- "aria-checked": _value,
55
+ "aria-checked": indeterminate ? "mixed" : _value,
52
56
  onClick: (event) => {
53
57
  onClick?.(event);
54
58
  ctx?.onChange(value || "");
@@ -1 +1 @@
1
- {"version":3,"file":"CheckboxCard.mjs","names":["classes"],"sources":["../../../../src/components/Checkbox/CheckboxCard/CheckboxCard.tsx"],"sourcesContent":["import { createContext, use } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getRadius,\n MantineRadius,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../../core';\nimport { UnstyledButton } from '../../UnstyledButton';\nimport { CheckboxGroupContext } from '../CheckboxGroup/CheckboxGroup';\nimport classes from './CheckboxCard.module.css';\n\nexport interface CheckboxCardContextValue {\n checked: boolean;\n}\n\nexport const CheckboxCardContext = createContext<CheckboxCardContextValue | null>(null);\n\nexport type CheckboxCardStylesNames = 'card';\nexport type CheckboxCardCssVariables = {\n card: '--card-radius';\n};\n\nexport interface CheckboxCardProps\n extends BoxProps, StylesApiProps<CheckboxCardFactory>, ElementProps<'button', 'onChange'> {\n /** Controlled component value */\n checked?: boolean;\n\n /** Uncontrolled component default value */\n defaultChecked?: boolean;\n\n /** Called when value changes */\n onChange?: (checked: boolean) => void;\n\n /** Adds border to the root element */\n withBorder?: boolean;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Value of the checkbox, used with `Checkbox.Group` */\n value?: string;\n}\n\nexport type CheckboxCardFactory = Factory<{\n props: CheckboxCardProps;\n ref: HTMLButtonElement;\n stylesNames: CheckboxCardStylesNames;\n vars: CheckboxCardCssVariables;\n}>;\n\nconst defaultProps = {\n withBorder: true,\n} satisfies Partial<CheckboxCardProps>;\n\nconst varsResolver = createVarsResolver<CheckboxCardFactory>((_, { radius }) => ({\n card: {\n '--card-radius': getRadius(radius),\n },\n}));\n\nexport const CheckboxCard = factory<CheckboxCardFactory>((_props) => {\n const props = useProps('CheckboxCard', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n checked,\n mod,\n withBorder,\n value,\n onClick,\n defaultChecked,\n onChange,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<CheckboxCardFactory>({\n name: 'CheckboxCard',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n rootSelector: 'card',\n });\n\n const ctx = use(CheckboxGroupContext);\n const _checked =\n typeof checked === 'boolean' ? checked : ctx ? ctx.value.includes(value || '') : undefined;\n\n const [_value, setValue] = useUncontrolled({\n value: _checked,\n defaultValue: defaultChecked,\n finalValue: false,\n onChange,\n });\n\n return (\n <CheckboxCardContext value={{ checked: _value }}>\n {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus -- UnstyledButton renders a native <button> which is focusable */}\n <UnstyledButton\n mod={[{ 'with-border': withBorder, checked: _value }, mod]}\n {...getStyles('card')}\n {...others}\n role=\"checkbox\"\n aria-checked={_value}\n onClick={(event) => {\n onClick?.(event);\n ctx?.onChange(value || '');\n setValue(!_value);\n }}\n />\n </CheckboxCardContext>\n );\n});\n\nCheckboxCard.displayName = '@mantine/core/CheckboxCard';\nCheckboxCard.classes = classes;\nCheckboxCard.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAa,sBAAsB,cAA+C,IAAI;AAmCtF,MAAM,eAAe,EACnB,YAAY,KACd;AAEA,MAAM,eAAe,oBAAyC,GAAG,EAAE,cAAc,EAC/E,MAAM,EACJ,iBAAiB,UAAU,MAAM,EACnC,EACF,EAAE;AAEF,MAAa,eAAe,SAA8B,WAAW;CACnE,MAAM,QAAQ,SAAS,gBAAgB,cAAc,MAAM;CAC3D,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,SACA,KACA,YACA,OACA,SACA,gBACA,UACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAA+B;EAC/C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;CAChB,CAAC;CAED,MAAM,MAAM,IAAI,oBAAoB;CAIpC,MAAM,CAAC,QAAQ,YAAY,gBAAgB;EACzC,OAHA,OAAO,YAAY,YAAY,UAAU,MAAM,IAAI,MAAM,SAAS,SAAS,EAAE,IAAI,KAAA;EAIjF,cAAc;EACd,YAAY;EACZ;CACF,CAAC;CAED,OACE,oBAAC,qBAAD;EAAqB,OAAO,EAAE,SAAS,OAAO;YAE5C,oBAAC,gBAAD;GACE,KAAK,CAAC;IAAE,eAAe;IAAY,SAAS;GAAO,GAAG,GAAG;GACzD,GAAI,UAAU,MAAM;GACpB,GAAI;GACJ,MAAK;GACL,gBAAc;GACd,UAAU,UAAU;IAClB,UAAU,KAAK;IACf,KAAK,SAAS,SAAS,EAAE;IACzB,SAAS,CAAC,MAAM;GAClB;EACD,CAAA;CACkB,CAAA;AAEzB,CAAC;AAED,aAAa,cAAc;AAC3B,aAAa,UAAUA;AACvB,aAAa,eAAe"}
1
+ {"version":3,"file":"CheckboxCard.mjs","names":["classes"],"sources":["../../../../src/components/Checkbox/CheckboxCard/CheckboxCard.tsx"],"sourcesContent":["import { createContext, use } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getRadius,\n MantineRadius,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../../core';\nimport { UnstyledButton } from '../../UnstyledButton';\nimport { CheckboxGroupContext } from '../CheckboxGroup/CheckboxGroup';\nimport classes from './CheckboxCard.module.css';\n\nexport interface CheckboxCardContextValue {\n checked: boolean;\n indeterminate?: boolean;\n}\n\nexport const CheckboxCardContext = createContext<CheckboxCardContextValue | null>(null);\n\nexport type CheckboxCardStylesNames = 'card';\nexport type CheckboxCardCssVariables = {\n card: '--card-radius';\n};\n\nexport interface CheckboxCardProps\n extends BoxProps, StylesApiProps<CheckboxCardFactory>, ElementProps<'button', 'onChange'> {\n /** Controlled component value */\n checked?: boolean;\n\n /** Uncontrolled component default value */\n defaultChecked?: boolean;\n\n /** Called when value changes */\n onChange?: (checked: boolean) => void;\n\n /** Indeterminate state of the checkbox. If set, `checked` prop is ignored and `aria-checked` is set to `mixed` */\n indeterminate?: boolean;\n\n /** Adds border to the root element */\n withBorder?: boolean;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Value of the checkbox, used with `Checkbox.Group` */\n value?: string;\n}\n\nexport type CheckboxCardFactory = Factory<{\n props: CheckboxCardProps;\n ref: HTMLButtonElement;\n stylesNames: CheckboxCardStylesNames;\n vars: CheckboxCardCssVariables;\n}>;\n\nconst defaultProps = {\n withBorder: true,\n} satisfies Partial<CheckboxCardProps>;\n\nconst varsResolver = createVarsResolver<CheckboxCardFactory>((_, { radius }) => ({\n card: {\n '--card-radius': getRadius(radius),\n },\n}));\n\nexport const CheckboxCard = factory<CheckboxCardFactory>((_props) => {\n const props = useProps('CheckboxCard', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n checked,\n mod,\n withBorder,\n value,\n onClick,\n defaultChecked,\n onChange,\n indeterminate,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<CheckboxCardFactory>({\n name: 'CheckboxCard',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n rootSelector: 'card',\n });\n\n const ctx = use(CheckboxGroupContext);\n const _checked =\n typeof checked === 'boolean' ? checked : ctx ? ctx.value.includes(value || '') : undefined;\n\n const [_value, setValue] = useUncontrolled({\n value: _checked,\n defaultValue: defaultChecked,\n finalValue: false,\n onChange,\n });\n\n return (\n <CheckboxCardContext value={{ checked: _value, indeterminate }}>\n {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus -- UnstyledButton renders a native <button> which is focusable */}\n <UnstyledButton\n mod={[{ 'with-border': withBorder, checked: _value, indeterminate }, mod]}\n {...getStyles('card')}\n {...others}\n role=\"checkbox\"\n aria-checked={indeterminate ? 'mixed' : _value}\n onClick={(event) => {\n onClick?.(event);\n ctx?.onChange(value || '');\n setValue(!_value);\n }}\n />\n </CheckboxCardContext>\n );\n});\n\nCheckboxCard.displayName = '@mantine/core/CheckboxCard';\nCheckboxCard.classes = classes;\nCheckboxCard.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;;;;;;AAuBA,MAAa,sBAAsB,cAA+C,IAAI;AAsCtF,MAAM,eAAe,EACnB,YAAY,KACd;AAEA,MAAM,eAAe,oBAAyC,GAAG,EAAE,cAAc,EAC/E,MAAM,EACJ,iBAAiB,UAAU,MAAM,EACnC,EACF,EAAE;AAEF,MAAa,eAAe,SAA8B,WAAW;CACnE,MAAM,QAAQ,SAAS,gBAAgB,cAAc,MAAM;CAC3D,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,SACA,KACA,YACA,OACA,SACA,gBACA,UACA,eACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAA+B;EAC/C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;CAChB,CAAC;CAED,MAAM,MAAM,IAAI,oBAAoB;CAIpC,MAAM,CAAC,QAAQ,YAAY,gBAAgB;EACzC,OAHA,OAAO,YAAY,YAAY,UAAU,MAAM,IAAI,MAAM,SAAS,SAAS,EAAE,IAAI,KAAA;EAIjF,cAAc;EACd,YAAY;EACZ;CACF,CAAC;CAED,OACE,oBAAC,qBAAD;EAAqB,OAAO;GAAE,SAAS;GAAQ;EAAc;YAE3D,oBAAC,gBAAD;GACE,KAAK,CAAC;IAAE,eAAe;IAAY,SAAS;IAAQ;GAAc,GAAG,GAAG;GACxE,GAAI,UAAU,MAAM;GACpB,GAAI;GACJ,MAAK;GACL,gBAAc,gBAAgB,UAAU;GACxC,UAAU,UAAU;IAClB,UAAU,KAAK;IACf,KAAK,SAAS,SAAS,EAAE;IACzB,SAAS,CAAC,MAAM;GAClB;EACD,CAAA;CACkB,CAAA;AAEzB,CAAC;AAED,aAAa,cAAc;AAC3B,aAAa,UAAUA;AACvB,aAAa,eAAe"}
@@ -55,7 +55,8 @@ const CheckboxIndicator = factory((_props) => {
55
55
  rootSelector: "indicator"
56
56
  });
57
57
  const ctx = use(CheckboxCardContext);
58
- const _checked = typeof checked === "boolean" || typeof indeterminate === "boolean" ? checked || indeterminate : ctx?.checked || false;
58
+ const _indeterminate = typeof indeterminate === "boolean" ? indeterminate : ctx?.indeterminate;
59
+ const _checked = typeof checked === "boolean" || typeof indeterminate === "boolean" ? checked || indeterminate : ctx?.checked || ctx?.indeterminate || false;
59
60
  return /* @__PURE__ */ jsx(Box, {
60
61
  ...getStyles("indicator", { variant }),
61
62
  variant,
@@ -65,7 +66,7 @@ const CheckboxIndicator = factory((_props) => {
65
66
  }, mod],
66
67
  ...others,
67
68
  children: /* @__PURE__ */ jsx(Icon, {
68
- indeterminate,
69
+ indeterminate: _indeterminate,
69
70
  ...getStyles("icon")
70
71
  })
71
72
  });
@@ -1 +1 @@
1
- {"version":3,"file":"CheckboxIndicator.mjs","names":["classes"],"sources":["../../../../src/components/Checkbox/CheckboxIndicator/CheckboxIndicator.tsx"],"sourcesContent":["import { use } from 'react';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getAutoContrastValue,\n getContrastColor,\n getRadius,\n getSize,\n getThemeColor,\n MantineColor,\n MantineRadius,\n MantineSize,\n parseThemeColor,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../../core';\nimport type { CheckboxIconComponent } from '../Checkbox';\nimport { CheckboxCardContext } from '../CheckboxCard/CheckboxCard';\nimport { CheckboxIcon } from '../CheckIcon';\nimport classes from './CheckboxIndicator.module.css';\n\nexport type CheckboxIndicatorStylesNames = 'indicator' | 'icon';\nexport type CheckboxIndicatorVariant = 'filled' | 'outline';\nexport type CheckboxIndicatorCssVariables = {\n indicator: '--checkbox-size' | '--checkbox-radius' | '--checkbox-color' | '--checkbox-icon-color';\n};\n\nexport interface CheckboxIndicatorProps\n extends BoxProps, StylesApiProps<CheckboxIndicatorFactory>, ElementProps<'div'> {\n /** Key of `theme.colors` or any valid CSS color to set input background color in checked state @default theme.primaryColor */\n color?: MantineColor;\n\n /** Controls size of the component @default 'sm' */\n size?: MantineSize | (string & {}) | number;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius` @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Key of `theme.colors` or any valid CSS color to set icon color, by default value depends on `theme.autoContrast` */\n iconColor?: MantineColor;\n\n /** If set, adjusts icon color based on background color for `filled` variant */\n autoContrast?: boolean;\n\n /** Indeterminate state of the checkbox. If set, `checked` prop is ignored. */\n indeterminate?: boolean;\n\n /** Icon for checked or indeterminate state */\n icon?: CheckboxIconComponent;\n\n /** Determines whether the component should have checked styles */\n checked?: boolean;\n\n /** Indicates disabled state */\n disabled?: boolean;\n}\n\nexport type CheckboxIndicatorFactory = Factory<{\n props: CheckboxIndicatorProps;\n ref: HTMLDivElement;\n stylesNames: CheckboxIndicatorStylesNames;\n vars: CheckboxIndicatorCssVariables;\n variant: CheckboxIndicatorVariant;\n}>;\n\nconst defaultProps = {\n icon: CheckboxIcon,\n variant: 'filled',\n radius: 'sm',\n} satisfies Partial<CheckboxIndicatorProps>;\n\nconst varsResolver = createVarsResolver<CheckboxIndicatorFactory>(\n (theme, { radius, color, size, iconColor, variant, autoContrast }) => {\n const parsedColor = parseThemeColor({ color: color || theme.primaryColor, theme });\n const outlineColor =\n parsedColor.isThemeColor && parsedColor.shade === undefined\n ? `var(--mantine-color-${parsedColor.color}-outline)`\n : parsedColor.color;\n\n return {\n indicator: {\n '--checkbox-size': getSize(size, 'checkbox-size'),\n '--checkbox-radius': radius === undefined ? undefined : getRadius(radius),\n '--checkbox-color': variant === 'outline' ? outlineColor : getThemeColor(color, theme),\n '--checkbox-icon-color': iconColor\n ? getThemeColor(iconColor, theme)\n : getAutoContrastValue(autoContrast, theme)\n ? getContrastColor({ color, theme, autoContrast })\n : undefined,\n },\n };\n }\n);\n\nexport const CheckboxIndicator = factory<CheckboxIndicatorFactory>((_props) => {\n const props = useProps('CheckboxIndicator', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n icon: Icon,\n indeterminate,\n radius,\n color,\n iconColor,\n autoContrast,\n checked,\n mod,\n variant,\n disabled,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<CheckboxIndicatorFactory>({\n name: 'CheckboxIndicator',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n rootSelector: 'indicator',\n });\n\n const ctx = use(CheckboxCardContext);\n const _checked =\n typeof checked === 'boolean' || typeof indeterminate === 'boolean'\n ? checked || indeterminate\n : ctx?.checked || false;\n\n return (\n <Box\n {...getStyles('indicator', { variant })}\n variant={variant}\n mod={[{ checked: _checked, disabled }, mod]}\n {...others}\n >\n <Icon indeterminate={indeterminate} {...getStyles('icon')} />\n </Box>\n );\n});\n\nCheckboxIndicator.displayName = '@mantine/core/CheckboxIndicator';\nCheckboxIndicator.classes = classes;\nCheckboxIndicator.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;;;;;;;;;;AAsEA,MAAM,eAAe;CACnB,MAAM;CACN,SAAS;CACT,QAAQ;AACV;AAEA,MAAM,eAAe,oBAClB,OAAO,EAAE,QAAQ,OAAO,MAAM,WAAW,SAAS,mBAAmB;CACpE,MAAM,cAAc,gBAAgB;EAAE,OAAO,SAAS,MAAM;EAAc;CAAM,CAAC;CACjF,MAAM,eACJ,YAAY,gBAAgB,YAAY,UAAU,KAAA,IAC9C,uBAAuB,YAAY,MAAM,aACzC,YAAY;CAElB,OAAO,EACL,WAAW;EACT,mBAAmB,QAAQ,MAAM,eAAe;EAChD,qBAAqB,WAAW,KAAA,IAAY,KAAA,IAAY,UAAU,MAAM;EACxE,oBAAoB,YAAY,YAAY,eAAe,cAAc,OAAO,KAAK;EACrF,yBAAyB,YACrB,cAAc,WAAW,KAAK,IAC9B,qBAAqB,cAAc,KAAK,IACtC,iBAAiB;GAAE;GAAO;GAAO;EAAa,CAAC,IAC/C,KAAA;CACR,EACF;AACF,CACF;AAEA,MAAa,oBAAoB,SAAmC,WAAW;CAC7E,MAAM,QAAQ,SAAS,qBAAqB,cAAc,MAAM;CAChE,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MAAM,MACN,eACA,QACA,OACA,WACA,cACA,SACA,KACA,SACA,UACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAAoC;EACpD,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;CAChB,CAAC;CAED,MAAM,MAAM,IAAI,mBAAmB;CACnC,MAAM,WACJ,OAAO,YAAY,aAAa,OAAO,kBAAkB,YACrD,WAAW,gBACX,KAAK,WAAW;CAEtB,OACE,oBAAC,KAAD;EACE,GAAI,UAAU,aAAa,EAAE,QAAQ,CAAC;EAC7B;EACT,KAAK,CAAC;GAAE,SAAS;GAAU;EAAS,GAAG,GAAG;EAC1C,GAAI;YAEJ,oBAAC,MAAD;GAAqB;GAAe,GAAI,UAAU,MAAM;EAAI,CAAA;CACzD,CAAA;AAET,CAAC;AAED,kBAAkB,cAAc;AAChC,kBAAkB,UAAUA;AAC5B,kBAAkB,eAAe"}
1
+ {"version":3,"file":"CheckboxIndicator.mjs","names":["classes"],"sources":["../../../../src/components/Checkbox/CheckboxIndicator/CheckboxIndicator.tsx"],"sourcesContent":["import { use } from 'react';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getAutoContrastValue,\n getContrastColor,\n getRadius,\n getSize,\n getThemeColor,\n MantineColor,\n MantineRadius,\n MantineSize,\n parseThemeColor,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../../core';\nimport type { CheckboxIconComponent } from '../Checkbox';\nimport { CheckboxCardContext } from '../CheckboxCard/CheckboxCard';\nimport { CheckboxIcon } from '../CheckIcon';\nimport classes from './CheckboxIndicator.module.css';\n\nexport type CheckboxIndicatorStylesNames = 'indicator' | 'icon';\nexport type CheckboxIndicatorVariant = 'filled' | 'outline';\nexport type CheckboxIndicatorCssVariables = {\n indicator: '--checkbox-size' | '--checkbox-radius' | '--checkbox-color' | '--checkbox-icon-color';\n};\n\nexport interface CheckboxIndicatorProps\n extends BoxProps, StylesApiProps<CheckboxIndicatorFactory>, ElementProps<'div'> {\n /** Key of `theme.colors` or any valid CSS color to set input background color in checked state @default theme.primaryColor */\n color?: MantineColor;\n\n /** Controls size of the component @default 'sm' */\n size?: MantineSize | (string & {}) | number;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius` @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Key of `theme.colors` or any valid CSS color to set icon color, by default value depends on `theme.autoContrast` */\n iconColor?: MantineColor;\n\n /** If set, adjusts icon color based on background color for `filled` variant */\n autoContrast?: boolean;\n\n /** Indeterminate state of the checkbox. If set, `checked` prop is ignored. */\n indeterminate?: boolean;\n\n /** Icon for checked or indeterminate state */\n icon?: CheckboxIconComponent;\n\n /** Determines whether the component should have checked styles */\n checked?: boolean;\n\n /** Indicates disabled state */\n disabled?: boolean;\n}\n\nexport type CheckboxIndicatorFactory = Factory<{\n props: CheckboxIndicatorProps;\n ref: HTMLDivElement;\n stylesNames: CheckboxIndicatorStylesNames;\n vars: CheckboxIndicatorCssVariables;\n variant: CheckboxIndicatorVariant;\n}>;\n\nconst defaultProps = {\n icon: CheckboxIcon,\n variant: 'filled',\n radius: 'sm',\n} satisfies Partial<CheckboxIndicatorProps>;\n\nconst varsResolver = createVarsResolver<CheckboxIndicatorFactory>(\n (theme, { radius, color, size, iconColor, variant, autoContrast }) => {\n const parsedColor = parseThemeColor({ color: color || theme.primaryColor, theme });\n const outlineColor =\n parsedColor.isThemeColor && parsedColor.shade === undefined\n ? `var(--mantine-color-${parsedColor.color}-outline)`\n : parsedColor.color;\n\n return {\n indicator: {\n '--checkbox-size': getSize(size, 'checkbox-size'),\n '--checkbox-radius': radius === undefined ? undefined : getRadius(radius),\n '--checkbox-color': variant === 'outline' ? outlineColor : getThemeColor(color, theme),\n '--checkbox-icon-color': iconColor\n ? getThemeColor(iconColor, theme)\n : getAutoContrastValue(autoContrast, theme)\n ? getContrastColor({ color, theme, autoContrast })\n : undefined,\n },\n };\n }\n);\n\nexport const CheckboxIndicator = factory<CheckboxIndicatorFactory>((_props) => {\n const props = useProps('CheckboxIndicator', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n icon: Icon,\n indeterminate,\n radius,\n color,\n iconColor,\n autoContrast,\n checked,\n mod,\n variant,\n disabled,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<CheckboxIndicatorFactory>({\n name: 'CheckboxIndicator',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n rootSelector: 'indicator',\n });\n\n const ctx = use(CheckboxCardContext);\n const _indeterminate = typeof indeterminate === 'boolean' ? indeterminate : ctx?.indeterminate;\n const _checked =\n typeof checked === 'boolean' || typeof indeterminate === 'boolean'\n ? checked || indeterminate\n : ctx?.checked || ctx?.indeterminate || false;\n\n return (\n <Box\n {...getStyles('indicator', { variant })}\n variant={variant}\n mod={[{ checked: _checked, disabled }, mod]}\n {...others}\n >\n <Icon indeterminate={_indeterminate} {...getStyles('icon')} />\n </Box>\n );\n});\n\nCheckboxIndicator.displayName = '@mantine/core/CheckboxIndicator';\nCheckboxIndicator.classes = classes;\nCheckboxIndicator.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;;;;;;;;;;AAsEA,MAAM,eAAe;CACnB,MAAM;CACN,SAAS;CACT,QAAQ;AACV;AAEA,MAAM,eAAe,oBAClB,OAAO,EAAE,QAAQ,OAAO,MAAM,WAAW,SAAS,mBAAmB;CACpE,MAAM,cAAc,gBAAgB;EAAE,OAAO,SAAS,MAAM;EAAc;CAAM,CAAC;CACjF,MAAM,eACJ,YAAY,gBAAgB,YAAY,UAAU,KAAA,IAC9C,uBAAuB,YAAY,MAAM,aACzC,YAAY;CAElB,OAAO,EACL,WAAW;EACT,mBAAmB,QAAQ,MAAM,eAAe;EAChD,qBAAqB,WAAW,KAAA,IAAY,KAAA,IAAY,UAAU,MAAM;EACxE,oBAAoB,YAAY,YAAY,eAAe,cAAc,OAAO,KAAK;EACrF,yBAAyB,YACrB,cAAc,WAAW,KAAK,IAC9B,qBAAqB,cAAc,KAAK,IACtC,iBAAiB;GAAE;GAAO;GAAO;EAAa,CAAC,IAC/C,KAAA;CACR,EACF;AACF,CACF;AAEA,MAAa,oBAAoB,SAAmC,WAAW;CAC7E,MAAM,QAAQ,SAAS,qBAAqB,cAAc,MAAM;CAChE,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MAAM,MACN,eACA,QACA,OACA,WACA,cACA,SACA,KACA,SACA,UACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAAoC;EACpD,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;CAChB,CAAC;CAED,MAAM,MAAM,IAAI,mBAAmB;CACnC,MAAM,iBAAiB,OAAO,kBAAkB,YAAY,gBAAgB,KAAK;CACjF,MAAM,WACJ,OAAO,YAAY,aAAa,OAAO,kBAAkB,YACrD,WAAW,gBACX,KAAK,WAAW,KAAK,iBAAiB;CAE5C,OACE,oBAAC,KAAD;EACE,GAAI,UAAU,aAAa,EAAE,QAAQ,CAAC;EAC7B;EACT,KAAK,CAAC;GAAE,SAAS;GAAU;EAAS,GAAG,GAAG;EAC1C,GAAI;YAEJ,oBAAC,MAAD;GAAM,eAAe;GAAgB,GAAI,UAAU,MAAM;EAAI,CAAA;CAC1D,CAAA;AAET,CAAC;AAED,kBAAkB,cAAc;AAChC,kBAAkB,UAAUA;AAC5B,kBAAkB,eAAe"}
@@ -45,7 +45,7 @@ const ColorInput = factory((_props) => {
45
45
  "InputWrapper",
46
46
  "ColorInput"
47
47
  ], defaultProps, _props);
48
- const { classNames, styles, unstyled, disallowInput, fixOnBlur, popoverProps, withPreview, withEyeDropper, eyeDropperIcon, closeOnColorSwatchClick, eyeDropperButtonProps, value, defaultValue, onChange, onChangeEnd, onClick, onFocus, onBlur, inputProps, format = "hex", wrapperProps, readOnly, withPicker, swatches, disabled, leftSection, rightSection, swatchesPerRow, ...others } = useInputProps("ColorInput", defaultProps, _props);
48
+ const { classNames, styles, unstyled, disallowInput, fixOnBlur, popoverProps, withPreview, withEyeDropper, eyeDropperIcon, closeOnColorSwatchClick, eyeDropperButtonProps, value, defaultValue, onChange, onChangeEnd, onClick, onFocus, onBlur, inputProps, format = "hex", wrapperProps, readOnly, withPicker, swatches, disabled, leftSection, rightSection, swatchesPerRow, fullWidth, ...others } = useInputProps("ColorInput", defaultProps, _props);
49
49
  const getStyles = useStyles({
50
50
  name: "ColorInput",
51
51
  props,
@@ -118,6 +118,7 @@ const ColorInput = factory((_props) => {
118
118
  position: "bottom-start",
119
119
  offset: 5,
120
120
  opened: dropdownOpened,
121
+ width: fullWidth ? "target" : void 0,
121
122
  ...popoverProps,
122
123
  classNames: resolvedClassNames,
123
124
  styles: resolvedStyles,
@@ -169,7 +170,8 @@ const ColorInput = factory((_props) => {
169
170
  styles: resolvedStyles,
170
171
  classNames: resolvedClassNames,
171
172
  onColorSwatchClick: () => closeOnColorSwatchClick && setDropdownOpened(false),
172
- attributes: wrapperProps.attributes
173
+ attributes: wrapperProps.attributes,
174
+ fullWidth
173
175
  })
174
176
  })]
175
177
  })
@@ -1 +1 @@
1
- {"version":3,"file":"ColorInput.mjs","names":["classes"],"sources":["../../../src/components/ColorInput/ColorInput.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useDidUpdate, useEyeDropper, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getSize,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { ActionIcon } from '../ActionIcon';\nimport {\n __ColorPickerProps,\n ColorPicker,\n ColorPickerStylesNames,\n convertHsvaTo,\n isColorValid,\n parseColor,\n} from '../ColorPicker';\nimport { ColorSwatch } from '../ColorSwatch';\nimport { __BaseInputProps, __InputStylesNames, Input, InputVariant, useInputProps } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { Popover, PopoverProps } from '../Popover';\nimport { EyeDropperIcon } from './EyeDropperIcon';\nimport classes from './ColorInput.module.css';\n\nexport type ColorInputStylesNames =\n | 'dropdown'\n | 'eyeDropperButton'\n | 'eyeDropperIcon'\n | 'colorPreview'\n | ColorPickerStylesNames\n | __InputStylesNames;\n\nexport type ColorInputCssVariables = {\n eyeDropperIcon: '--ci-eye-dropper-icon-size';\n eyeDropperButton: '--ci-button-size';\n colorPreview: '--ci-preview-size';\n};\n\nexport interface ColorInputProps\n extends\n BoxProps,\n __BaseInputProps,\n __ColorPickerProps,\n StylesApiProps<ColorInputFactory>,\n ElementProps<'input', 'size' | 'onChange' | 'value' | 'defaultValue'> {\n /** If input is not allowed, the user can only pick value with color picker and swatches */\n disallowInput?: boolean;\n\n /** If set, the input value resets to the last known valid value when the input loses focus @default true */\n fixOnBlur?: boolean;\n\n /** Props passed down to the `Popover` component */\n popoverProps?: PopoverProps;\n\n /** If set, the preview color swatch is displayed in the left section of the input @default true */\n withPreview?: boolean;\n\n /** If set, the eye dropper button is displayed in the right section @default true */\n withEyeDropper?: boolean;\n\n /** An icon to replace the default eye dropper icon */\n eyeDropperIcon?: React.ReactNode;\n\n /** If set, the dropdown is closed when one of the color swatches is clicked @default false */\n closeOnColorSwatchClick?: boolean;\n\n /** Props passed down to the eye dropper button */\n eyeDropperButtonProps?: Record<string, any>;\n}\n\nexport type ColorInputFactory = Factory<{\n props: ColorInputProps;\n ref: HTMLInputElement;\n stylesNames: ColorInputStylesNames;\n vars: ColorInputCssVariables;\n variant: InputVariant;\n}>;\n\nconst defaultProps = {\n format: 'hex',\n fixOnBlur: true,\n withPreview: true,\n swatchesPerRow: 7,\n withPicker: true,\n popoverProps: { transitionProps: { transition: 'fade', duration: 0 } },\n withEyeDropper: true,\n size: 'sm',\n leftSectionPointerEvents: 'none',\n} satisfies Partial<ColorInputProps>;\n\nconst varsResolver = createVarsResolver<ColorInputFactory>((_, { size }) => ({\n eyeDropperIcon: {\n '--ci-eye-dropper-icon-size': getSize(size, 'ci-eye-dropper-icon-size'),\n },\n\n eyeDropperButton: {\n '--ci-button-size': getSize(size, 'ci-button-size'),\n },\n\n colorPreview: {\n '--ci-preview-size': getSize(size, 'ci-preview-size'),\n },\n}));\n\nexport const ColorInput = factory<ColorInputFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'ColorInput'], defaultProps, _props);\n const {\n classNames,\n styles,\n unstyled,\n disallowInput,\n fixOnBlur,\n popoverProps,\n withPreview,\n withEyeDropper,\n eyeDropperIcon,\n closeOnColorSwatchClick,\n eyeDropperButtonProps,\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n onClick,\n onFocus,\n onBlur,\n inputProps,\n format = 'hex',\n wrapperProps,\n readOnly,\n withPicker,\n swatches,\n disabled,\n leftSection,\n rightSection,\n swatchesPerRow,\n ...others\n } = useInputProps('ColorInput', defaultProps, _props);\n\n const getStyles = useStyles<ColorInputFactory>({\n name: 'ColorInput',\n props,\n classes,\n classNames,\n styles,\n unstyled,\n rootSelector: 'wrapper',\n vars: props.vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<ColorInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const [dropdownOpened, setDropdownOpened] = useState(false);\n const [lastValidValue, setLastValidValue] = useState('');\n const [_value, setValue] = useUncontrolled({\n value,\n defaultValue,\n finalValue: '',\n onChange,\n });\n\n const { supported: eyeDropperSupported, open: openEyeDropper } = useEyeDropper();\n\n const eyeDropper = (\n <ActionIcon\n {...eyeDropperButtonProps}\n {...getStyles('eyeDropperButton', {\n className: eyeDropperButtonProps?.className,\n style: eyeDropperButtonProps?.style,\n })}\n variant=\"subtle\"\n color=\"gray\"\n unstyled={unstyled}\n onClick={() =>\n openEyeDropper()\n .then((payload) => {\n if (payload?.sRGBHex) {\n const color = convertHsvaTo(format, parseColor(payload.sRGBHex));\n setValue(color);\n onChangeEnd?.(color);\n }\n })\n .catch(() => {})\n }\n >\n {eyeDropperIcon || <EyeDropperIcon {...getStyles('eyeDropperIcon')} />}\n </ActionIcon>\n );\n\n const handleInputFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n setDropdownOpened(true);\n };\n\n const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n fixOnBlur && setValue(lastValidValue);\n onBlur?.(event);\n setDropdownOpened(false);\n };\n\n const handleInputClick = (event: React.MouseEvent<HTMLInputElement>) => {\n onClick?.(event);\n setDropdownOpened(true);\n };\n\n useEffect(() => {\n if (isColorValid(_value) || _value.trim() === '') {\n setLastValidValue(_value);\n }\n }, [_value]);\n\n useDidUpdate(() => {\n if (isColorValid(_value)) {\n setValue(convertHsvaTo(format, parseColor(_value)));\n }\n }, [format]);\n\n return (\n <Input.Wrapper\n {...wrapperProps}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n __staticSelector=\"ColorInput\"\n >\n <Popover\n __staticSelector=\"ColorInput\"\n position=\"bottom-start\"\n offset={5}\n opened={dropdownOpened}\n {...popoverProps}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n withRoles={false}\n disabled={\n readOnly || (withPicker === false && (!Array.isArray(swatches) || swatches.length === 0))\n }\n >\n <Popover.Target>\n <Input<'input'>\n autoComplete=\"off\"\n {...others}\n {...inputProps}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n disabled={disabled}\n __staticSelector=\"ColorInput\"\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n onClick={handleInputClick}\n spellCheck={false}\n value={_value}\n onChange={(event) => {\n const inputValue = event.currentTarget.value;\n setValue(inputValue);\n if (isColorValid(inputValue)) {\n onChangeEnd?.(convertHsvaTo(format, parseColor(inputValue)));\n }\n }}\n leftSection={\n leftSection ||\n (withPreview ? (\n <ColorSwatch\n color={isColorValid(_value) ? _value : '#fff'}\n size=\"var(--ci-preview-size)\"\n {...getStyles('colorPreview')}\n />\n ) : null)\n }\n readOnly={disallowInput || readOnly}\n pointer={disallowInput}\n unstyled={unstyled}\n rightSection={\n rightSection ||\n (withEyeDropper && !disabled && !readOnly && eyeDropperSupported ? eyeDropper : null)\n }\n />\n </Popover.Target>\n\n <Popover.Dropdown\n onMouseDown={(event) => event.preventDefault()}\n className={classes.dropdown}\n >\n <ColorPicker\n __staticSelector=\"ColorInput\"\n value={_value}\n onChange={setValue}\n onChangeEnd={onChangeEnd}\n format={format}\n swatches={swatches}\n swatchesPerRow={swatchesPerRow}\n withPicker={withPicker}\n size={inputProps.size}\n focusable={false}\n unstyled={unstyled}\n styles={resolvedStyles}\n classNames={resolvedClassNames}\n onColorSwatchClick={() => closeOnColorSwatchClick && setDropdownOpened(false)}\n attributes={wrapperProps.attributes}\n />\n </Popover.Dropdown>\n </Popover>\n </Input.Wrapper>\n );\n});\n\nColorInput.classes = InputBase.classes;\nColorInput.varsResolver = varsResolver;\nColorInput.displayName = '@mantine/core/ColorInput';\n\nexport namespace ColorInput {\n export type Props = ColorInputProps;\n export type StylesNames = ColorInputStylesNames;\n export type CssVariables = ColorInputCssVariables;\n export type Factory = ColorInputFactory;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ColorInput.mjs","names":["classes"],"sources":["../../../src/components/ColorInput/ColorInput.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useDidUpdate, useEyeDropper, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getSize,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { ActionIcon } from '../ActionIcon';\nimport {\n __ColorPickerProps,\n ColorPicker,\n ColorPickerStylesNames,\n convertHsvaTo,\n isColorValid,\n parseColor,\n} from '../ColorPicker';\nimport { ColorSwatch } from '../ColorSwatch';\nimport { __BaseInputProps, __InputStylesNames, Input, InputVariant, useInputProps } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { Popover, PopoverProps } from '../Popover';\nimport { EyeDropperIcon } from './EyeDropperIcon';\nimport classes from './ColorInput.module.css';\n\nexport type ColorInputStylesNames =\n | 'dropdown'\n | 'eyeDropperButton'\n | 'eyeDropperIcon'\n | 'colorPreview'\n | ColorPickerStylesNames\n | __InputStylesNames;\n\nexport type ColorInputCssVariables = {\n eyeDropperIcon: '--ci-eye-dropper-icon-size';\n eyeDropperButton: '--ci-button-size';\n colorPreview: '--ci-preview-size';\n};\n\nexport interface ColorInputProps\n extends\n BoxProps,\n __BaseInputProps,\n __ColorPickerProps,\n StylesApiProps<ColorInputFactory>,\n ElementProps<'input', 'size' | 'onChange' | 'value' | 'defaultValue'> {\n /** If input is not allowed, the user can only pick value with color picker and swatches */\n disallowInput?: boolean;\n\n /** If set, the input value resets to the last known valid value when the input loses focus @default true */\n fixOnBlur?: boolean;\n\n /** Props passed down to the `Popover` component */\n popoverProps?: PopoverProps;\n\n /** If set, the preview color swatch is displayed in the left section of the input @default true */\n withPreview?: boolean;\n\n /** If set, the eye dropper button is displayed in the right section @default true */\n withEyeDropper?: boolean;\n\n /** An icon to replace the default eye dropper icon */\n eyeDropperIcon?: React.ReactNode;\n\n /** If set, the dropdown is closed when one of the color swatches is clicked @default false */\n closeOnColorSwatchClick?: boolean;\n\n /** Props passed down to the eye dropper button */\n eyeDropperButtonProps?: Record<string, any>;\n}\n\nexport type ColorInputFactory = Factory<{\n props: ColorInputProps;\n ref: HTMLInputElement;\n stylesNames: ColorInputStylesNames;\n vars: ColorInputCssVariables;\n variant: InputVariant;\n}>;\n\nconst defaultProps = {\n format: 'hex',\n fixOnBlur: true,\n withPreview: true,\n swatchesPerRow: 7,\n withPicker: true,\n popoverProps: { transitionProps: { transition: 'fade', duration: 0 } },\n withEyeDropper: true,\n size: 'sm',\n leftSectionPointerEvents: 'none',\n} satisfies Partial<ColorInputProps>;\n\nconst varsResolver = createVarsResolver<ColorInputFactory>((_, { size }) => ({\n eyeDropperIcon: {\n '--ci-eye-dropper-icon-size': getSize(size, 'ci-eye-dropper-icon-size'),\n },\n\n eyeDropperButton: {\n '--ci-button-size': getSize(size, 'ci-button-size'),\n },\n\n colorPreview: {\n '--ci-preview-size': getSize(size, 'ci-preview-size'),\n },\n}));\n\nexport const ColorInput = factory<ColorInputFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'ColorInput'], defaultProps, _props);\n const {\n classNames,\n styles,\n unstyled,\n disallowInput,\n fixOnBlur,\n popoverProps,\n withPreview,\n withEyeDropper,\n eyeDropperIcon,\n closeOnColorSwatchClick,\n eyeDropperButtonProps,\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n onClick,\n onFocus,\n onBlur,\n inputProps,\n format = 'hex',\n wrapperProps,\n readOnly,\n withPicker,\n swatches,\n disabled,\n leftSection,\n rightSection,\n swatchesPerRow,\n fullWidth,\n ...others\n } = useInputProps('ColorInput', defaultProps, _props);\n\n const getStyles = useStyles<ColorInputFactory>({\n name: 'ColorInput',\n props,\n classes,\n classNames,\n styles,\n unstyled,\n rootSelector: 'wrapper',\n vars: props.vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<ColorInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const [dropdownOpened, setDropdownOpened] = useState(false);\n const [lastValidValue, setLastValidValue] = useState('');\n const [_value, setValue] = useUncontrolled({\n value,\n defaultValue,\n finalValue: '',\n onChange,\n });\n\n const { supported: eyeDropperSupported, open: openEyeDropper } = useEyeDropper();\n\n const eyeDropper = (\n <ActionIcon\n {...eyeDropperButtonProps}\n {...getStyles('eyeDropperButton', {\n className: eyeDropperButtonProps?.className,\n style: eyeDropperButtonProps?.style,\n })}\n variant=\"subtle\"\n color=\"gray\"\n unstyled={unstyled}\n onClick={() =>\n openEyeDropper()\n .then((payload) => {\n if (payload?.sRGBHex) {\n const color = convertHsvaTo(format, parseColor(payload.sRGBHex));\n setValue(color);\n onChangeEnd?.(color);\n }\n })\n .catch(() => {})\n }\n >\n {eyeDropperIcon || <EyeDropperIcon {...getStyles('eyeDropperIcon')} />}\n </ActionIcon>\n );\n\n const handleInputFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n setDropdownOpened(true);\n };\n\n const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n fixOnBlur && setValue(lastValidValue);\n onBlur?.(event);\n setDropdownOpened(false);\n };\n\n const handleInputClick = (event: React.MouseEvent<HTMLInputElement>) => {\n onClick?.(event);\n setDropdownOpened(true);\n };\n\n useEffect(() => {\n if (isColorValid(_value) || _value.trim() === '') {\n setLastValidValue(_value);\n }\n }, [_value]);\n\n useDidUpdate(() => {\n if (isColorValid(_value)) {\n setValue(convertHsvaTo(format, parseColor(_value)));\n }\n }, [format]);\n\n return (\n <Input.Wrapper\n {...wrapperProps}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n __staticSelector=\"ColorInput\"\n >\n <Popover\n __staticSelector=\"ColorInput\"\n position=\"bottom-start\"\n offset={5}\n opened={dropdownOpened}\n width={fullWidth ? 'target' : undefined}\n {...popoverProps}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n withRoles={false}\n disabled={\n readOnly || (withPicker === false && (!Array.isArray(swatches) || swatches.length === 0))\n }\n >\n <Popover.Target>\n <Input<'input'>\n autoComplete=\"off\"\n {...others}\n {...inputProps}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n disabled={disabled}\n __staticSelector=\"ColorInput\"\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n onClick={handleInputClick}\n spellCheck={false}\n value={_value}\n onChange={(event) => {\n const inputValue = event.currentTarget.value;\n setValue(inputValue);\n if (isColorValid(inputValue)) {\n onChangeEnd?.(convertHsvaTo(format, parseColor(inputValue)));\n }\n }}\n leftSection={\n leftSection ||\n (withPreview ? (\n <ColorSwatch\n color={isColorValid(_value) ? _value : '#fff'}\n size=\"var(--ci-preview-size)\"\n {...getStyles('colorPreview')}\n />\n ) : null)\n }\n readOnly={disallowInput || readOnly}\n pointer={disallowInput}\n unstyled={unstyled}\n rightSection={\n rightSection ||\n (withEyeDropper && !disabled && !readOnly && eyeDropperSupported ? eyeDropper : null)\n }\n />\n </Popover.Target>\n\n <Popover.Dropdown\n onMouseDown={(event) => event.preventDefault()}\n className={classes.dropdown}\n >\n <ColorPicker\n __staticSelector=\"ColorInput\"\n value={_value}\n onChange={setValue}\n onChangeEnd={onChangeEnd}\n format={format}\n swatches={swatches}\n swatchesPerRow={swatchesPerRow}\n withPicker={withPicker}\n size={inputProps.size}\n focusable={false}\n unstyled={unstyled}\n styles={resolvedStyles}\n classNames={resolvedClassNames}\n onColorSwatchClick={() => closeOnColorSwatchClick && setDropdownOpened(false)}\n attributes={wrapperProps.attributes}\n fullWidth={fullWidth}\n />\n </Popover.Dropdown>\n </Popover>\n </Input.Wrapper>\n );\n});\n\nColorInput.classes = InputBase.classes;\nColorInput.varsResolver = varsResolver;\nColorInput.displayName = '@mantine/core/ColorInput';\n\nexport namespace ColorInput {\n export type Props = ColorInputProps;\n export type StylesNames = ColorInputStylesNames;\n export type CssVariables = ColorInputCssVariables;\n export type Factory = ColorInputFactory;\n}\n"],"mappings":"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"}