@mantine/core 9.5.1-alpha.1 → 9.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/components/Cascader/Cascader.cjs +9 -3
- package/cjs/components/Cascader/Cascader.cjs.map +1 -1
- package/cjs/components/Cascader/CascaderColumns.cjs +34 -3
- package/cjs/components/Cascader/CascaderColumns.cjs.map +1 -1
- package/cjs/components/Cascader/use-cascader-safe-area.cjs +76 -0
- package/cjs/components/Cascader/use-cascader-safe-area.cjs.map +1 -0
- package/cjs/components/Checkbox/CheckboxCard/CheckboxCard.cjs +8 -4
- package/cjs/components/Checkbox/CheckboxCard/CheckboxCard.cjs.map +1 -1
- package/cjs/components/Checkbox/CheckboxIndicator/CheckboxIndicator.cjs +3 -2
- package/cjs/components/Checkbox/CheckboxIndicator/CheckboxIndicator.cjs.map +1 -1
- package/cjs/components/ColorInput/ColorInput.cjs +4 -2
- package/cjs/components/ColorInput/ColorInput.cjs.map +1 -1
- package/cjs/components/ColorPicker/ColorPicker.cjs.map +1 -1
- package/cjs/components/Combobox/get-options-lockup/get-option-by-label.cjs +17 -0
- package/cjs/components/Combobox/get-options-lockup/get-option-by-label.cjs.map +1 -0
- package/cjs/components/Combobox/is-external-input-change/is-external-input-change.cjs +17 -0
- package/cjs/components/Combobox/is-external-input-change/is-external-input-change.cjs.map +1 -0
- package/cjs/components/ComboboxPopover/ComboboxPopover.cjs.map +1 -1
- package/cjs/components/FloatingIndicator/use-floating-indicator.cjs +6 -4
- package/cjs/components/FloatingIndicator/use-floating-indicator.cjs.map +1 -1
- package/cjs/components/MultiSelect/MultiSelect.cjs +9 -0
- package/cjs/components/MultiSelect/MultiSelect.cjs.map +1 -1
- package/cjs/components/Notification/Notification.cjs.map +1 -1
- package/cjs/components/PasswordInput/PasswordInput.cjs +4 -3
- package/cjs/components/PasswordInput/PasswordInput.cjs.map +1 -1
- package/cjs/components/RollingNumber/RollingNumber.cjs +7 -3
- package/cjs/components/RollingNumber/RollingNumber.cjs.map +1 -1
- package/cjs/components/RollingNumber/RollingNumber.module.cjs +1 -0
- package/cjs/components/RollingNumber/RollingNumber.module.cjs.map +1 -1
- package/cjs/components/Select/Select.cjs +12 -0
- package/cjs/components/Select/Select.cjs.map +1 -1
- package/cjs/components/TagsInput/TagsInput.cjs +5 -1
- package/cjs/components/TagsInput/TagsInput.cjs.map +1 -1
- package/cjs/components/Tooltip/Tooltip.cjs +11 -3
- package/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
- package/cjs/components/Tooltip/Tooltip.module.cjs.map +1 -1
- package/cjs/components/Tooltip/TooltipFloating/TooltipFloating.cjs +2 -2
- package/cjs/components/Tooltip/TooltipFloating/TooltipFloating.cjs.map +1 -1
- package/cjs/components/Tooltip/TooltipFloating/use-floating-tooltip.cjs +1 -0
- package/cjs/components/Tooltip/TooltipFloating/use-floating-tooltip.cjs.map +1 -1
- package/cjs/components/Tooltip/use-tooltip.cjs +2 -1
- package/cjs/components/Tooltip/use-tooltip.cjs.map +1 -1
- package/cjs/components/TreeSelect/TreeSelect.cjs +3 -0
- package/cjs/components/TreeSelect/TreeSelect.cjs.map +1 -1
- package/esm/components/Cascader/Cascader.mjs +9 -3
- package/esm/components/Cascader/Cascader.mjs.map +1 -1
- package/esm/components/Cascader/CascaderColumns.mjs +35 -4
- package/esm/components/Cascader/CascaderColumns.mjs.map +1 -1
- package/esm/components/Cascader/use-cascader-safe-area.mjs +76 -0
- package/esm/components/Cascader/use-cascader-safe-area.mjs.map +1 -0
- package/esm/components/Checkbox/CheckboxCard/CheckboxCard.mjs +8 -4
- package/esm/components/Checkbox/CheckboxCard/CheckboxCard.mjs.map +1 -1
- package/esm/components/Checkbox/CheckboxIndicator/CheckboxIndicator.mjs +3 -2
- package/esm/components/Checkbox/CheckboxIndicator/CheckboxIndicator.mjs.map +1 -1
- package/esm/components/ColorInput/ColorInput.mjs +4 -2
- package/esm/components/ColorInput/ColorInput.mjs.map +1 -1
- package/esm/components/ColorPicker/ColorPicker.mjs.map +1 -1
- package/esm/components/Combobox/get-options-lockup/get-option-by-label.mjs +17 -0
- package/esm/components/Combobox/get-options-lockup/get-option-by-label.mjs.map +1 -0
- package/esm/components/Combobox/is-external-input-change/is-external-input-change.mjs +17 -0
- package/esm/components/Combobox/is-external-input-change/is-external-input-change.mjs.map +1 -0
- package/esm/components/ComboboxPopover/ComboboxPopover.mjs.map +1 -1
- package/esm/components/FloatingIndicator/use-floating-indicator.mjs +6 -4
- package/esm/components/FloatingIndicator/use-floating-indicator.mjs.map +1 -1
- package/esm/components/MultiSelect/MultiSelect.mjs +9 -0
- package/esm/components/MultiSelect/MultiSelect.mjs.map +1 -1
- package/esm/components/Notification/Notification.mjs.map +1 -1
- package/esm/components/PasswordInput/PasswordInput.mjs +4 -3
- package/esm/components/PasswordInput/PasswordInput.mjs.map +1 -1
- package/esm/components/RollingNumber/RollingNumber.mjs +8 -4
- package/esm/components/RollingNumber/RollingNumber.mjs.map +1 -1
- package/esm/components/RollingNumber/RollingNumber.module.mjs +1 -0
- package/esm/components/RollingNumber/RollingNumber.module.mjs.map +1 -1
- package/esm/components/Select/Select.mjs +12 -0
- package/esm/components/Select/Select.mjs.map +1 -1
- package/esm/components/TagsInput/TagsInput.mjs +5 -1
- package/esm/components/TagsInput/TagsInput.mjs.map +1 -1
- package/esm/components/Tooltip/Tooltip.mjs +11 -3
- package/esm/components/Tooltip/Tooltip.mjs.map +1 -1
- package/esm/components/Tooltip/Tooltip.module.mjs.map +1 -1
- package/esm/components/Tooltip/TooltipFloating/TooltipFloating.mjs +2 -2
- package/esm/components/Tooltip/TooltipFloating/TooltipFloating.mjs.map +1 -1
- package/esm/components/Tooltip/TooltipFloating/use-floating-tooltip.mjs +1 -0
- package/esm/components/Tooltip/TooltipFloating/use-floating-tooltip.mjs.map +1 -1
- package/esm/components/Tooltip/use-tooltip.mjs +3 -2
- package/esm/components/Tooltip/use-tooltip.mjs.map +1 -1
- package/esm/components/TreeSelect/TreeSelect.mjs +3 -0
- package/esm/components/TreeSelect/TreeSelect.mjs.map +1 -1
- package/lib/components/Cascader/Cascader.d.ts +4 -0
- package/lib/components/Cascader/CascaderColumns.d.ts +3 -2
- package/lib/components/Cascader/use-cascader-safe-area.d.ts +20 -0
- package/lib/components/Checkbox/CheckboxCard/CheckboxCard.d.ts +3 -0
- package/lib/components/ColorPicker/ColorPicker.d.ts +2 -2
- package/lib/components/Combobox/get-options-lockup/get-option-by-label.d.ts +8 -0
- package/lib/components/Combobox/is-external-input-change/is-external-input-change.d.ts +7 -0
- package/lib/components/ComboboxPopover/ComboboxPopover.d.ts +1 -1
- package/lib/components/Notification/Notification.d.ts +2 -1
- package/lib/components/PasswordInput/PasswordInput.d.ts +2 -0
- package/lib/components/RollingNumber/RollingNumber.d.ts +1 -1
- package/lib/components/Tooltip/Tooltip.d.ts +2 -0
- package/lib/components/Tooltip/use-tooltip.d.ts +1 -0
- package/package.json +2 -2
- package/styles/RollingNumber.css +21 -0
- package/styles/RollingNumber.layer.css +21 -0
- package/styles/Tooltip.css +4 -0
- package/styles/Tooltip.layer.css +4 -0
- package/styles.css +25 -0
- package/styles.layer.css +25 -0
|
@@ -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: {
|
|
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":";;;;;;;;;;;;;
|
|
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
|
|
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={
|
|
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":";;;;;;;;;;;;;;;;;;;;;;AAoFA,MAAM,eAAe;CACnB,QAAQ;CACR,WAAW;CACX,aAAa;CACb,gBAAgB;CAChB,YAAY;CACZ,cAAc,EAAE,iBAAiB;EAAE,YAAY;EAAQ,UAAU;CAAE,EAAE;CACrE,gBAAgB;CAChB,MAAM;CACN,0BAA0B;AAC5B;AAEA,MAAM,eAAe,oBAAuC,GAAG,EAAE,YAAY;CAC3E,gBAAgB,EACd,8BAA8B,QAAQ,MAAM,0BAA0B,EACxE;CAEA,kBAAkB,EAChB,oBAAoB,QAAQ,MAAM,gBAAgB,EACpD;CAEA,cAAc,EACZ,qBAAqB,QAAQ,MAAM,iBAAiB,EACtD;AACF,EAAE;AAEF,MAAa,aAAa,SAA4B,WAAW;CAC/D,MAAM,QAAQ,SAAS;EAAC;EAAS;EAAgB;CAAY,GAAG,cAAc,MAAM;CACpF,MAAM,EACJ,YACA,QACA,UACA,eACA,WACA,cACA,aACA,gBACA,gBACA,yBACA,uBACA,OACA,cACA,UACA,aACA,SACA,SACA,QACA,YACA,SAAS,OACT,cACA,UACA,YACA,UACA,UACA,aACA,cACA,gBACA,WACA,GAAG,WACD,cAAc,cAAc,cAAc,MAAM;CAEpD,MAAM,YAAY,UAA6B;EAC7C,MAAM;EACN;EACA,SAAA;EACA;EACA;EACA;EACA,cAAc;EACd,MAAM,MAAM;EACZ;CACF,CAAC;CAED,MAAM,EAAE,oBAAoB,mBAAmB,qBAAwC;EACrF;EACA;EACA;CACF,CAAC;CAED,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,KAAK;CAC1D,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,EAAE;CACvD,MAAM,CAAC,QAAQ,YAAY,gBAAgB;EACzC;EACA;EACA,YAAY;EACZ;CACF,CAAC;CAED,MAAM,EAAE,WAAW,qBAAqB,MAAM,mBAAmB,cAAc;CAE/E,MAAM,aACJ,oBAAC,YAAD;EACE,GAAI;EACJ,GAAI,UAAU,oBAAoB;GAChC,WAAW,uBAAuB;GAClC,OAAO,uBAAuB;EAChC,CAAC;EACD,SAAQ;EACR,OAAM;EACI;EACV,eACE,eAAe,CAAC,CACb,MAAM,YAAY;GACjB,IAAI,SAAS,SAAS;IACpB,MAAM,QAAQ,cAAc,QAAQ,WAAW,QAAQ,OAAO,CAAC;IAC/D,SAAS,KAAK;IACd,cAAc,KAAK;GACrB;EACF,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;YAGlB,kBAAkB,oBAAC,gBAAD,EAAgB,GAAI,UAAU,gBAAgB,EAAI,CAAA;CAC3D,CAAA;CAGd,MAAM,oBAAoB,UAA8C;EACtE,UAAU,KAAK;EACf,kBAAkB,IAAI;CACxB;CAEA,MAAM,mBAAmB,UAA8C;EACrE,aAAa,SAAS,cAAc;EACpC,SAAS,KAAK;EACd,kBAAkB,KAAK;CACzB;CAEA,MAAM,oBAAoB,UAA8C;EACtE,UAAU,KAAK;EACf,kBAAkB,IAAI;CACxB;CAEA,gBAAgB;EACd,IAAI,aAAa,MAAM,KAAK,OAAO,KAAK,MAAM,IAC5C,kBAAkB,MAAM;CAE5B,GAAG,CAAC,MAAM,CAAC;CAEX,mBAAmB;EACjB,IAAI,aAAa,MAAM,GACrB,SAAS,cAAc,QAAQ,WAAW,MAAM,CAAC,CAAC;CAEtD,GAAG,CAAC,MAAM,CAAC;CAEX,OACE,oBAAC,MAAM,SAAP;EACE,GAAI;EACJ,YAAY;EACZ,QAAQ;EACR,kBAAiB;YAEjB,qBAAC,SAAD;GACE,kBAAiB;GACjB,UAAS;GACT,QAAQ;GACR,QAAQ;GACR,OAAO,YAAY,WAAW,KAAA;GAC9B,GAAI;GACJ,YAAY;GACZ,QAAQ;GACE;GACV,WAAW;GACX,UACE,YAAa,eAAe,UAAU,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW;aAZ1F,CAeE,oBAAC,QAAQ,QAAT,EAAA,UACE,oBAAC,OAAD;IACE,cAAa;IACb,GAAI;IACJ,GAAI;IACJ,YAAY;IACZ,QAAQ;IACE;IACV,kBAAiB;IACjB,SAAS;IACT,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,OAAO;IACP,WAAW,UAAU;KACnB,MAAM,aAAa,MAAM,cAAc;KACvC,SAAS,UAAU;KACnB,IAAI,aAAa,UAAU,GACzB,cAAc,cAAc,QAAQ,WAAW,UAAU,CAAC,CAAC;IAE/D;IACA,aACE,gBACC,cACC,oBAAC,aAAD;KACE,OAAO,aAAa,MAAM,IAAI,SAAS;KACvC,MAAK;KACL,GAAI,UAAU,cAAc;IAC7B,CAAA,IACC;IAEN,UAAU,iBAAiB;IAC3B,SAAS;IACC;IACV,cACE,iBACC,kBAAkB,CAAC,YAAY,CAAC,YAAY,sBAAsB,aAAa;GAEnF,CAAA,EACa,CAAA,GAEhB,oBAAC,QAAQ,UAAT;IACE,cAAc,UAAU,MAAM,eAAe;IAC7C,WAAWA,0BAAQ;cAEnB,oBAAC,aAAD;KACE,kBAAiB;KACjB,OAAO;KACP,UAAU;KACG;KACL;KACE;KACM;KACJ;KACZ,MAAM,WAAW;KACjB,WAAW;KACD;KACV,QAAQ;KACR,YAAY;KACZ,0BAA0B,2BAA2B,kBAAkB,KAAK;KAC5E,YAAY,aAAa;KACd;IACZ,CAAA;GACe,CAAA,CACX;;CACI,CAAA;AAEnB,CAAC;AAED,WAAW,UAAU,UAAU;AAC/B,WAAW,eAAe;AAC1B,WAAW,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPicker.mjs","names":["classes"],"sources":["../../../src/components/ColorPicker/ColorPicker.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { useDidUpdate, useUncontrolled } from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n factory,\n Factory,\n getSize,\n getSpacing,\n MantineSize,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../core';\nimport { ColorSwatch } from '../ColorSwatch';\nimport { AlphaSlider } from './AlphaSlider/AlphaSlider';\nimport { ColorPickerContext } from './ColorPicker.context';\nimport { ColorFormat, HsvaColor } from './ColorPicker.types';\nimport { convertHsvaTo, isColorValid, parseColor } from './converters';\nimport { HueSlider } from './HueSlider/HueSlider';\nimport { Saturation } from './Saturation/Saturation';\nimport { Swatches } from './Swatches/Swatches';\nimport classes from './ColorPicker.module.css';\n\nexport type ColorPickerStylesNames =\n | 'wrapper'\n | 'preview'\n | 'body'\n | 'sliders'\n | 'slider'\n | 'sliderOverlay'\n | 'thumb'\n | 'saturation'\n | 'thumb'\n | 'saturationOverlay'\n | 'thumb'\n | 'swatches'\n | 'swatch';\n\nexport type ColorPickerCssVariables = {\n wrapper:\n | '--cp-preview-size'\n | '--cp-width'\n | '--cp-body-spacing'\n | '--cp-swatch-size'\n | '--cp-thumb-size'\n | '--cp-saturation-height';\n};\n\nexport interface __ColorPickerProps {\n /** Controlled component value */\n value?: string;\n\n /** Uncontrolled component default value */\n defaultValue?: string;\n\n /** Called when value changes */\n onChange?: (value: string) => void;\n\n /** Called when the user stops dragging one of the sliders or changes the value with keyboard */\n onChangeEnd?: (value: string) => void;\n\n /** Color format. `hexa`, `rgba`, `hsla` values render alpha channel slider @default 'hex' */\n format?: ColorFormat;\n\n /** If `false`, the component displays only swatches @default true */\n withPicker?: boolean;\n\n /** A list of colors used to display swatches list below the color picker */\n swatches?: string[];\n\n /** Number of swatches per row @default 7 */\n swatchesPerRow?: number;\n\n /** Component size @default 'md' */\n size?: MantineSize | (string & {});\n}\n\nexport interface ColorPickerProps\n extends\n BoxProps,\n __ColorPickerProps,\n StylesApiProps<ColorPickerFactory>,\n ElementProps<'div', 'onChange' | 'value' | 'defaultValue'> {\n __staticSelector?: string;\n\n /** If set, the component takes 100% width of its container @default false */\n fullWidth?: boolean;\n\n /** If set, interactive elements (sliders thumbs and swatches) are focusable with keyboard @default true */\n focusable?: boolean;\n\n /** Saturation slider `aria-label` */\n saturationLabel?: string;\n\n /** Hue slider `aria-label` */\n hueLabel?: string;\n\n /** Alpha slider `aria-label` */\n alphaLabel?: string;\n\n /** Called when one of the color swatches is clicked */\n onColorSwatchClick?: (color: string) => void;\n\n /** Hidden input `name` attribute, if not set, the input will not be rendered */\n name?: string;\n\n /** Props spread to the hidden input */\n hiddenInputProps?: React.ComponentProps<'input'> & DataAttributes;\n}\n\nexport type ColorPickerFactory = Factory<{\n props: ColorPickerProps;\n ref: HTMLDivElement;\n stylesNames: ColorPickerStylesNames;\n vars: ColorPickerCssVariables;\n}>;\n\nconst defaultProps = {\n swatchesPerRow: 7,\n withPicker: true,\n focusable: true,\n size: 'md',\n __staticSelector: 'ColorPicker',\n} satisfies Partial<ColorPickerProps>;\n\nconst varsResolver = createVarsResolver<ColorPickerFactory>((_, { size, swatchesPerRow }) => ({\n wrapper: {\n '--cp-preview-size': getSize(size, 'cp-preview-size'),\n '--cp-width': getSize(size, 'cp-width'),\n '--cp-body-spacing': getSpacing(size),\n '--cp-swatch-size': `${100 / swatchesPerRow!}%`,\n '--cp-thumb-size': getSize(size, 'cp-thumb-size'),\n '--cp-saturation-height': getSize(size, 'cp-saturation-height'),\n },\n}));\n\nexport const ColorPicker = factory<ColorPickerFactory>((_props) => {\n const props = useProps('ColorPicker', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n format = 'hex',\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n withPicker,\n size,\n saturationLabel,\n hueLabel,\n alphaLabel,\n focusable,\n swatches,\n swatchesPerRow,\n fullWidth,\n onColorSwatchClick,\n __staticSelector,\n mod,\n attributes,\n name,\n hiddenInputProps,\n ...others\n } = props;\n\n const getStyles = useStyles<ColorPickerFactory>({\n name: __staticSelector,\n props,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n rootSelector: 'wrapper',\n vars,\n varsResolver,\n });\n\n const formatRef = useRef(format || 'hex');\n const valueRef = useRef<string>('');\n const scrubTimeoutRef = useRef<number>(-1);\n const isScrubbingRef = useRef(false);\n const withAlpha = format === 'hexa' || format === 'rgba' || format === 'hsla';\n\n const [_value, setValue, controlled] = useUncontrolled({\n value,\n defaultValue,\n finalValue: '#FFFFFF',\n onChange,\n });\n\n const [parsed, setParsed] = useState<HsvaColor>(parseColor(_value));\n\n const startScrubbing = () => {\n window.clearTimeout(scrubTimeoutRef.current);\n isScrubbingRef.current = true;\n };\n\n const stopScrubbing = () => {\n window.clearTimeout(scrubTimeoutRef.current);\n scrubTimeoutRef.current = window.setTimeout(() => {\n isScrubbingRef.current = false;\n }, 200);\n };\n\n const handleChange = (color: Partial<HsvaColor>) => {\n setParsed((current) => {\n const next = { ...current, ...color };\n valueRef.current = convertHsvaTo(formatRef.current, next);\n return next;\n });\n\n setValue(valueRef.current);\n };\n\n useDidUpdate(() => {\n if (typeof value === 'string' && isColorValid(value) && !isScrubbingRef.current) {\n setParsed(parseColor(value));\n }\n }, [value]);\n\n useDidUpdate(() => {\n formatRef.current = format || 'hex';\n setValue(convertHsvaTo(formatRef.current, parsed));\n }, [format]);\n\n return (\n <ColorPickerContext value={{ getStyles, unstyled }}>\n <Box\n {...getStyles('wrapper')}\n size={size}\n mod={[{ 'full-width': fullWidth }, mod]}\n {...others}\n >\n {name && <input type=\"hidden\" name={name} value={_value} {...hiddenInputProps} />}\n\n {withPicker && (\n <>\n <Saturation\n value={parsed}\n onChange={handleChange}\n onChangeEnd={({ s, v }) =>\n onChangeEnd?.(convertHsvaTo(formatRef.current, { ...parsed, s: s!, v: v! }))\n }\n color={_value}\n size={size}\n focusable={focusable}\n saturationLabel={saturationLabel}\n onScrubStart={startScrubbing}\n onScrubEnd={stopScrubbing}\n />\n\n <div {...getStyles('body')}>\n <div {...getStyles('sliders')}>\n <HueSlider\n value={parsed.h}\n onChange={(h) => handleChange({ h })}\n onChangeEnd={(h) =>\n onChangeEnd?.(convertHsvaTo(formatRef.current, { ...parsed, h }))\n }\n size={size}\n focusable={focusable}\n aria-label={hueLabel}\n onScrubStart={startScrubbing}\n onScrubEnd={stopScrubbing}\n />\n\n {withAlpha && (\n <AlphaSlider\n value={parsed.a}\n onChange={(a) => handleChange({ a })}\n onChangeEnd={(a) => {\n onChangeEnd?.(convertHsvaTo(formatRef.current, { ...parsed, a }));\n }}\n size={size}\n color={convertHsvaTo('hex', parsed)}\n focusable={focusable}\n aria-label={alphaLabel}\n onScrubStart={startScrubbing}\n onScrubEnd={stopScrubbing}\n />\n )}\n </div>\n\n {withAlpha && (\n <ColorSwatch\n color={_value}\n radius=\"sm\"\n size=\"var(--cp-preview-size)\"\n {...getStyles('preview')}\n />\n )}\n </div>\n </>\n )}\n\n {Array.isArray(swatches) && (\n <Swatches\n data={swatches}\n swatchesPerRow={swatchesPerRow}\n focusable={focusable}\n setValue={setValue}\n value={_value}\n onChangeEnd={(color) => {\n const convertedColor = convertHsvaTo(format, parseColor(color));\n onColorSwatchClick?.(convertedColor);\n onChangeEnd?.(convertedColor);\n if (!controlled) {\n setParsed(parseColor(color));\n }\n }}\n />\n )}\n </Box>\n </ColorPickerContext>\n );\n});\n\nColorPicker.classes = classes;\nColorPicker.varsResolver = varsResolver;\nColorPicker.displayName = '@mantine/core/ColorPicker';\n\nexport namespace ColorPicker {\n export type Props = ColorPickerProps;\n export type CssVariables = ColorPickerCssVariables;\n export type Factory = ColorPickerFactory;\n export type StylesNames = ColorPickerStylesNames;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ColorPicker.mjs","names":["classes"],"sources":["../../../src/components/ColorPicker/ColorPicker.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { useDidUpdate, useUncontrolled } from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n factory,\n Factory,\n getSize,\n getSpacing,\n MantineSize,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../core';\nimport { ColorSwatch } from '../ColorSwatch';\nimport { AlphaSlider } from './AlphaSlider/AlphaSlider';\nimport { ColorPickerContext } from './ColorPicker.context';\nimport { ColorFormat, HsvaColor } from './ColorPicker.types';\nimport { convertHsvaTo, isColorValid, parseColor } from './converters';\nimport { HueSlider } from './HueSlider/HueSlider';\nimport { Saturation } from './Saturation/Saturation';\nimport { Swatches } from './Swatches/Swatches';\nimport classes from './ColorPicker.module.css';\n\nexport type ColorPickerStylesNames =\n | 'wrapper'\n | 'preview'\n | 'body'\n | 'sliders'\n | 'slider'\n | 'sliderOverlay'\n | 'thumb'\n | 'saturation'\n | 'thumb'\n | 'saturationOverlay'\n | 'thumb'\n | 'swatches'\n | 'swatch';\n\nexport type ColorPickerCssVariables = {\n wrapper:\n | '--cp-preview-size'\n | '--cp-width'\n | '--cp-body-spacing'\n | '--cp-swatch-size'\n | '--cp-thumb-size'\n | '--cp-saturation-height';\n};\n\nexport interface __ColorPickerProps {\n /** Controlled component value */\n value?: string;\n\n /** Uncontrolled component default value */\n defaultValue?: string;\n\n /** Called when value changes */\n onChange?: (value: string) => void;\n\n /** Called when the user stops dragging one of the sliders or changes the value with keyboard */\n onChangeEnd?: (value: string) => void;\n\n /** Color format. `hexa`, `rgba`, `hsla` values render alpha channel slider @default 'hex' */\n format?: ColorFormat;\n\n /** If `false`, the component displays only swatches @default true */\n withPicker?: boolean;\n\n /** A list of colors used to display swatches list below the color picker */\n swatches?: string[];\n\n /** Number of swatches per row @default 7 */\n swatchesPerRow?: number;\n\n /** Component size @default 'md' */\n size?: MantineSize | (string & {});\n\n /** If set, the component takes 100% width of its container @default false */\n fullWidth?: boolean;\n}\n\nexport interface ColorPickerProps\n extends\n BoxProps,\n __ColorPickerProps,\n StylesApiProps<ColorPickerFactory>,\n ElementProps<'div', 'onChange' | 'value' | 'defaultValue'> {\n __staticSelector?: string;\n\n /** If set, interactive elements (sliders thumbs and swatches) are focusable with keyboard @default true */\n focusable?: boolean;\n\n /** Saturation slider `aria-label` */\n saturationLabel?: string;\n\n /** Hue slider `aria-label` */\n hueLabel?: string;\n\n /** Alpha slider `aria-label` */\n alphaLabel?: string;\n\n /** Called when one of the color swatches is clicked */\n onColorSwatchClick?: (color: string) => void;\n\n /** Hidden input `name` attribute, if not set, the input will not be rendered */\n name?: string;\n\n /** Props spread to the hidden input */\n hiddenInputProps?: React.ComponentProps<'input'> & DataAttributes;\n}\n\nexport type ColorPickerFactory = Factory<{\n props: ColorPickerProps;\n ref: HTMLDivElement;\n stylesNames: ColorPickerStylesNames;\n vars: ColorPickerCssVariables;\n}>;\n\nconst defaultProps = {\n swatchesPerRow: 7,\n withPicker: true,\n focusable: true,\n size: 'md',\n __staticSelector: 'ColorPicker',\n} satisfies Partial<ColorPickerProps>;\n\nconst varsResolver = createVarsResolver<ColorPickerFactory>((_, { size, swatchesPerRow }) => ({\n wrapper: {\n '--cp-preview-size': getSize(size, 'cp-preview-size'),\n '--cp-width': getSize(size, 'cp-width'),\n '--cp-body-spacing': getSpacing(size),\n '--cp-swatch-size': `${100 / swatchesPerRow!}%`,\n '--cp-thumb-size': getSize(size, 'cp-thumb-size'),\n '--cp-saturation-height': getSize(size, 'cp-saturation-height'),\n },\n}));\n\nexport const ColorPicker = factory<ColorPickerFactory>((_props) => {\n const props = useProps('ColorPicker', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n format = 'hex',\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n withPicker,\n size,\n saturationLabel,\n hueLabel,\n alphaLabel,\n focusable,\n swatches,\n swatchesPerRow,\n fullWidth,\n onColorSwatchClick,\n __staticSelector,\n mod,\n attributes,\n name,\n hiddenInputProps,\n ...others\n } = props;\n\n const getStyles = useStyles<ColorPickerFactory>({\n name: __staticSelector,\n props,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n rootSelector: 'wrapper',\n vars,\n varsResolver,\n });\n\n const formatRef = useRef(format || 'hex');\n const valueRef = useRef<string>('');\n const scrubTimeoutRef = useRef<number>(-1);\n const isScrubbingRef = useRef(false);\n const withAlpha = format === 'hexa' || format === 'rgba' || format === 'hsla';\n\n const [_value, setValue, controlled] = useUncontrolled({\n value,\n defaultValue,\n finalValue: '#FFFFFF',\n onChange,\n });\n\n const [parsed, setParsed] = useState<HsvaColor>(parseColor(_value));\n\n const startScrubbing = () => {\n window.clearTimeout(scrubTimeoutRef.current);\n isScrubbingRef.current = true;\n };\n\n const stopScrubbing = () => {\n window.clearTimeout(scrubTimeoutRef.current);\n scrubTimeoutRef.current = window.setTimeout(() => {\n isScrubbingRef.current = false;\n }, 200);\n };\n\n const handleChange = (color: Partial<HsvaColor>) => {\n setParsed((current) => {\n const next = { ...current, ...color };\n valueRef.current = convertHsvaTo(formatRef.current, next);\n return next;\n });\n\n setValue(valueRef.current);\n };\n\n useDidUpdate(() => {\n if (typeof value === 'string' && isColorValid(value) && !isScrubbingRef.current) {\n setParsed(parseColor(value));\n }\n }, [value]);\n\n useDidUpdate(() => {\n formatRef.current = format || 'hex';\n setValue(convertHsvaTo(formatRef.current, parsed));\n }, [format]);\n\n return (\n <ColorPickerContext value={{ getStyles, unstyled }}>\n <Box\n {...getStyles('wrapper')}\n size={size}\n mod={[{ 'full-width': fullWidth }, mod]}\n {...others}\n >\n {name && <input type=\"hidden\" name={name} value={_value} {...hiddenInputProps} />}\n\n {withPicker && (\n <>\n <Saturation\n value={parsed}\n onChange={handleChange}\n onChangeEnd={({ s, v }) =>\n onChangeEnd?.(convertHsvaTo(formatRef.current, { ...parsed, s: s!, v: v! }))\n }\n color={_value}\n size={size}\n focusable={focusable}\n saturationLabel={saturationLabel}\n onScrubStart={startScrubbing}\n onScrubEnd={stopScrubbing}\n />\n\n <div {...getStyles('body')}>\n <div {...getStyles('sliders')}>\n <HueSlider\n value={parsed.h}\n onChange={(h) => handleChange({ h })}\n onChangeEnd={(h) =>\n onChangeEnd?.(convertHsvaTo(formatRef.current, { ...parsed, h }))\n }\n size={size}\n focusable={focusable}\n aria-label={hueLabel}\n onScrubStart={startScrubbing}\n onScrubEnd={stopScrubbing}\n />\n\n {withAlpha && (\n <AlphaSlider\n value={parsed.a}\n onChange={(a) => handleChange({ a })}\n onChangeEnd={(a) => {\n onChangeEnd?.(convertHsvaTo(formatRef.current, { ...parsed, a }));\n }}\n size={size}\n color={convertHsvaTo('hex', parsed)}\n focusable={focusable}\n aria-label={alphaLabel}\n onScrubStart={startScrubbing}\n onScrubEnd={stopScrubbing}\n />\n )}\n </div>\n\n {withAlpha && (\n <ColorSwatch\n color={_value}\n radius=\"sm\"\n size=\"var(--cp-preview-size)\"\n {...getStyles('preview')}\n />\n )}\n </div>\n </>\n )}\n\n {Array.isArray(swatches) && (\n <Swatches\n data={swatches}\n swatchesPerRow={swatchesPerRow}\n focusable={focusable}\n setValue={setValue}\n value={_value}\n onChangeEnd={(color) => {\n const convertedColor = convertHsvaTo(format, parseColor(color));\n onColorSwatchClick?.(convertedColor);\n onChangeEnd?.(convertedColor);\n if (!controlled) {\n setParsed(parseColor(color));\n }\n }}\n />\n )}\n </Box>\n </ColorPickerContext>\n );\n});\n\nColorPicker.classes = classes;\nColorPicker.varsResolver = varsResolver;\nColorPicker.displayName = '@mantine/core/ColorPicker';\n\nexport namespace ColorPicker {\n export type Props = ColorPickerProps;\n export type CssVariables = ColorPickerCssVariables;\n export type Factory = ColorPickerFactory;\n export type StylesNames = ColorPickerStylesNames;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/core/src/components/Combobox/get-options-lockup/get-option-by-label.ts
|
|
3
|
+
/**
|
|
4
|
+
* Finds an enabled option by its label, ignoring casing and surrounding whitespace. Returns
|
|
5
|
+
* `undefined` when the label is ambiguous: options with duplicate labels are valid data, and there
|
|
6
|
+
* is no way to tell which of them was meant.
|
|
7
|
+
*/
|
|
8
|
+
function getOptionByLabel(optionsLockup, label) {
|
|
9
|
+
const normalizedLabel = label.trim().toLowerCase();
|
|
10
|
+
if (normalizedLabel === "") return;
|
|
11
|
+
const matchedOptions = Object.values(optionsLockup).filter((option) => !option.disabled && option.label.trim().toLowerCase() === normalizedLabel);
|
|
12
|
+
return matchedOptions.length === 1 ? matchedOptions[0] : void 0;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { getOptionByLabel };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=get-option-by-label.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-option-by-label.mjs","names":[],"sources":["../../../../src/components/Combobox/get-options-lockup/get-option-by-label.ts"],"sourcesContent":["import { Primitive } from '../../../core';\nimport { ComboboxItem } from '../Combobox.types';\n\n/**\n * Finds an enabled option by its label, ignoring casing and surrounding whitespace. Returns\n * `undefined` when the label is ambiguous: options with duplicate labels are valid data, and there\n * is no way to tell which of them was meant.\n */\nexport function getOptionByLabel<Value extends Primitive = string>(\n optionsLockup: Record<PropertyKey, ComboboxItem<Value>>,\n label: string\n): ComboboxItem<Value> | undefined {\n const normalizedLabel = label.trim().toLowerCase();\n\n if (normalizedLabel === '') {\n return undefined;\n }\n\n const matchedOptions = Object.values(optionsLockup).filter(\n (option) => !option.disabled && option.label.trim().toLowerCase() === normalizedLabel\n );\n\n return matchedOptions.length === 1 ? matchedOptions[0] : undefined;\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,iBACd,eACA,OACiC;CACjC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,YAAY;CAEjD,IAAI,oBAAoB,IACtB;CAGF,MAAM,iBAAiB,OAAO,OAAO,aAAa,CAAC,CAAC,QACjD,WAAW,CAAC,OAAO,YAAY,OAAO,MAAM,KAAK,CAAC,CAAC,YAAY,MAAM,eACxE;CAEA,OAAO,eAAe,WAAW,IAAI,eAAe,KAAK,KAAA;AAC3D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { getRootElement } from "../../../core/utils/find-element-in-shadow-dom/find-element-in-shadow-dom.mjs";
|
|
3
|
+
//#region packages/@mantine/core/src/components/Combobox/is-external-input-change/is-external-input-change.ts
|
|
4
|
+
/**
|
|
5
|
+
* Determines whether an input change was produced by something other than the user typing into the
|
|
6
|
+
* input – browser autofill, password managers and browser extensions all write to inputs without
|
|
7
|
+
* focusing them first. Combobox components reconcile the search value with the selected value on
|
|
8
|
+
* blur, which never happens for such writes.
|
|
9
|
+
*/
|
|
10
|
+
function isExternalInputChange(event) {
|
|
11
|
+
const target = event.currentTarget;
|
|
12
|
+
return getRootElement(target).activeElement !== target;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { isExternalInputChange };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=is-external-input-change.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-external-input-change.mjs","names":[],"sources":["../../../../src/components/Combobox/is-external-input-change/is-external-input-change.ts"],"sourcesContent":["import { getRootElement } from '../../../core';\n\n/**\n * Determines whether an input change was produced by something other than the user typing into the\n * input – browser autofill, password managers and browser extensions all write to inputs without\n * focusing them first. Combobox components reconcile the search value with the selected value on\n * blur, which never happens for such writes.\n */\nexport function isExternalInputChange(event: React.ChangeEvent<HTMLInputElement>) {\n const target = event.currentTarget;\n return getRootElement(target).activeElement !== target;\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,sBAAsB,OAA4C;CAChF,MAAM,SAAS,MAAM;CACrB,OAAO,eAAe,MAAM,CAAC,CAAC,kBAAkB;AAClD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxPopover.mjs","names":["comboboxClasses"],"sources":["../../../src/components/ComboboxPopover/ComboboxPopover.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport cx from 'clsx';\nimport { useUncontrolled } from '@mantine/hooks';\nimport {\n Factory,\n genericFactory,\n Primitive,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n} from '../../core';\nimport { CheckIcon } from '../Checkbox';\nimport {\n Combobox,\n ComboboxData,\n ComboboxItem,\n ComboboxLikeRenderOptionInput,\n ComboboxLikeStylesNames,\n ComboboxProps,\n defaultOptionsFilter,\n getOptionsLockup,\n getParsedComboboxData,\n isOptionsGroup,\n OptionsDropdown,\n OptionsFilter,\n useCombobox,\n} from '../Combobox';\nimport { ComboboxParsedItem } from '../Combobox/Combobox.types';\nimport { isEmptyComboboxData } from '../Combobox/OptionsDropdown/is-empty-combobox-data';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { ComboboxPopoverValue } from './ComboboxPopover.types';\nimport { ComboboxPopoverTarget } from './ComboboxPopoverTarget';\nimport comboboxClasses from '../Combobox/Combobox.module.css';\n\nfunction isValueChecked(value: Primitive | Primitive[] | undefined | null, optionValue: Primitive) {\n return Array.isArray(value) ? value.includes(optionValue) : value === optionValue;\n}\n\ninterface OptionProps {\n data: ComboboxParsedItem<Primitive>;\n withCheckIcon?: boolean;\n withAlignedLabels?: boolean;\n value?: Primitive | Primitive[] | null;\n checkIconPosition?: 'left' | 'right';\n unstyled: boolean | undefined;\n renderOption?: (input: ComboboxLikeRenderOptionInput<any>) => React.ReactNode;\n}\n\nfunction Option({\n data,\n withCheckIcon,\n withAlignedLabels,\n value,\n checkIconPosition,\n unstyled,\n renderOption,\n}: OptionProps) {\n if (isOptionsGroup(data)) {\n const options = data.items.map((item) => (\n <Option\n data={item}\n value={value}\n key={`${item.value}`}\n unstyled={unstyled}\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n checkIconPosition={checkIconPosition}\n renderOption={renderOption}\n />\n ));\n return <Combobox.Group label={data.group}>{options}</Combobox.Group>;\n }\n\n const checked = isValueChecked(value, data.value);\n const check =\n withCheckIcon &&\n (checked ? (\n <CheckIcon className={comboboxClasses.optionsDropdownCheckIcon} />\n ) : withAlignedLabels ? (\n <div className={comboboxClasses.optionsDropdownCheckPlaceholder} />\n ) : null);\n\n const defaultContent = (\n <>\n {checkIconPosition === 'left' && check}\n <span>{data.label}</span>\n {checkIconPosition === 'right' && check}\n </>\n );\n\n return (\n <Combobox.Option\n value={data.value}\n disabled={data.disabled}\n className={cx({ [comboboxClasses.optionsDropdownOption]: !unstyled })}\n data-reverse={checkIconPosition === 'right' || undefined}\n data-checked={checked || undefined}\n aria-selected={checked}\n active={checked}\n >\n {typeof renderOption === 'function'\n ? renderOption({ option: data, checked })\n : defaultContent}\n </Combobox.Option>\n );\n}\n\ninterface SearchableDropdownProps {\n data: ComboboxParsedItem<Primitive>[];\n filter: OptionsFilter<Primitive> | undefined;\n search: string;\n limit: number | undefined;\n nothingFoundMessage: React.ReactNode | undefined;\n withScrollArea: boolean | undefined;\n maxDropdownHeight: number | string | undefined;\n value: Primitive | Primitive[] | null;\n checkIconPosition: 'left' | 'right' | undefined;\n withCheckIcon: boolean | undefined;\n withAlignedLabels: boolean | undefined;\n unstyled: boolean | undefined;\n renderOption?: (input: ComboboxLikeRenderOptionInput<any>) => React.ReactNode;\n scrollAreaProps: ScrollAreaProps | undefined;\n onSearchChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nfunction SearchableDropdown({\n data,\n filter,\n search,\n limit,\n nothingFoundMessage,\n withScrollArea = true,\n maxDropdownHeight,\n value,\n checkIconPosition,\n withCheckIcon = false,\n withAlignedLabels = false,\n unstyled,\n renderOption,\n scrollAreaProps,\n onSearchChange,\n}: SearchableDropdownProps) {\n const filteredData = (filter || defaultOptionsFilter)({\n options: data,\n search,\n limit: limit ?? Infinity,\n });\n const isEmpty = isEmptyComboboxData(filteredData);\n\n const options = filteredData.map((item, index) => (\n <Option\n data={item}\n key={\n isOptionsGroup(item)\n ? `group-${typeof item.group === 'string' ? item.group : index}`\n : `${item.value}`\n }\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n value={value}\n checkIconPosition={checkIconPosition}\n unstyled={unstyled}\n renderOption={renderOption}\n />\n ));\n\n return (\n <Combobox.Dropdown data-composed>\n <Combobox.Search value={search} onChange={onSearchChange} placeholder=\"Search...\" />\n <Combobox.Options>\n {withScrollArea ? (\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 220}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n offsetScrollbars=\"y\"\n {...scrollAreaProps}\n >\n {options}\n </ScrollArea.Autosize>\n ) : (\n options\n )}\n {isEmpty && nothingFoundMessage && <Combobox.Empty>{nothingFoundMessage}</Combobox.Empty>}\n </Combobox.Options>\n </Combobox.Dropdown>\n );\n}\n\nexport type ComboboxPopoverStylesNames = ComboboxLikeStylesNames;\n\nexport interface ComboboxPopoverProps<\n Multiple extends boolean = false,\n Value extends Primitive = string,\n> extends StylesApiProps<ComboboxPopoverFactory> {\n /** If set, multiple items can be selected at the same time */\n multiple?: Multiple;\n\n /** Controlled component value */\n value?: ComboboxPopoverValue<Multiple, Value>;\n\n /** Uncontrolled component default value */\n defaultValue?: ComboboxPopoverValue<Multiple, Value>;\n\n /** Called when value changes */\n onChange?: (value: ComboboxPopoverValue<Multiple, Value>) => void;\n\n /** Data used to generate options */\n data?: ComboboxData<Value>;\n\n /** Controlled dropdown opened state */\n dropdownOpened?: boolean;\n\n /** Uncontrolled dropdown initial opened state */\n defaultDropdownOpened?: boolean;\n\n /** Called when dropdown opens */\n onDropdownOpen?: () => void;\n\n /** Called when dropdown closes */\n onDropdownClose?: () => void;\n\n /** Called when option is submitted from dropdown with mouse click or Enter key */\n onOptionSubmit?: (value: Value) => void;\n\n /** Props passed down to Combobox component */\n comboboxProps?: ComboboxProps;\n\n /** Function based on which items are filtered and sorted */\n filter?: OptionsFilter<Value>;\n\n /** Maximum number of options displayed at a time @default Infinity */\n limit?: number;\n\n /** Determines whether the options should be wrapped with ScrollArea.AutoSize @default true */\n withScrollArea?: boolean;\n\n /** max-height of the dropdown @default 250 */\n maxDropdownHeight?: number | string;\n\n /** If set, the first option is selected when dropdown opens @default false */\n selectFirstOptionOnDropdownOpen?: boolean;\n\n /** Displays check icon near the selected option label @default true */\n withCheckIcon?: boolean;\n\n /** Aligns unchecked labels with the checked one @default false */\n withAlignedLabels?: boolean;\n\n /** Position of the check icon relative to the option label @default 'left' */\n checkIconPosition?: 'left' | 'right';\n\n /** Message displayed when no options match the search query or when there is no data */\n nothingFoundMessage?: React.ReactNode;\n\n /** Allows searching through options @default false */\n searchable?: boolean;\n\n /** Controlled search value */\n searchValue?: string;\n\n /** Default search value */\n defaultSearchValue?: string;\n\n /** Called when search changes */\n onSearchChange?: (value: string) => void;\n\n /** Allows deselecting the selected option by clicking it (only for single mode) @default true */\n allowDeselect?: boolean;\n\n /** A function to render content of the option, replaces the default content of the option */\n renderOption?: (item: ComboboxLikeRenderOptionInput<ComboboxItem>) => React.ReactNode;\n\n /** Props passed down to the underlying ScrollArea component in the dropdown */\n scrollAreaProps?: ScrollAreaProps;\n\n /** Props passed down to the hidden input */\n hiddenInputProps?: Omit<React.ComponentProps<'input'>, 'value'>;\n\n /** Hidden input name for form submission */\n name?: string;\n\n /** Hidden input form for form submission */\n form?: string;\n\n /** Content of the component */\n children?: React.ReactNode;\n\n /** Divider used to separate values in the hidden input value attribute @default ',' */\n hiddenInputValuesDivider?: string;\n}\n\nexport type ComboboxPopoverFactory = Factory<{\n props: ComboboxPopoverProps;\n ref: HTMLDivElement;\n stylesNames: ComboboxPopoverStylesNames;\n signature: <Multiple extends boolean = false, Value extends Primitive = string>(\n props: ComboboxPopoverProps<Multiple, Value>\n ) => React.JSX.Element;\n staticComponents: {\n Target: typeof ComboboxPopoverTarget;\n };\n}>;\n\nconst defaultProps = {\n withCheckIcon: true,\n allowDeselect: true,\n checkIconPosition: 'left',\n hiddenInputValuesDivider: ',',\n} satisfies Partial<ComboboxPopoverProps>;\n\nexport const ComboboxPopover = genericFactory<ComboboxPopoverFactory>((_props) => {\n const props = useProps('ComboboxPopover', defaultProps as any, _props);\n const {\n classNames,\n styles,\n unstyled,\n vars,\n children,\n multiple,\n value,\n defaultValue,\n onChange,\n data,\n dropdownOpened,\n defaultDropdownOpened,\n onDropdownOpen,\n onDropdownClose,\n onOptionSubmit,\n comboboxProps,\n filter,\n limit,\n withScrollArea,\n maxDropdownHeight,\n selectFirstOptionOnDropdownOpen,\n withCheckIcon,\n withAlignedLabels,\n checkIconPosition,\n nothingFoundMessage,\n searchable,\n searchValue,\n defaultSearchValue,\n onSearchChange,\n allowDeselect,\n renderOption,\n scrollAreaProps,\n hiddenInputProps,\n name,\n form,\n hiddenInputValuesDivider,\n attributes,\n ...others\n } = props;\n\n const parsedData = useMemo(() => getParsedComboboxData(data), [data]);\n const optionsLockup = useMemo(() => getOptionsLockup(parsedData), [parsedData]);\n\n const [_value, setValue] = useUncontrolled({\n value,\n defaultValue,\n finalValue: multiple ? ([] as any) : null,\n onChange,\n });\n\n const [_searchValue, setSearchValue] = useUncontrolled({\n value: searchValue,\n defaultValue: defaultSearchValue,\n finalValue: '',\n onChange: onSearchChange,\n });\n\n const combobox = useCombobox({\n opened: dropdownOpened,\n defaultOpened: defaultDropdownOpened,\n onDropdownOpen: () => {\n onDropdownOpen?.();\n if (searchable) {\n combobox.focusSearchInput();\n }\n if (selectFirstOptionOnDropdownOpen) {\n combobox.selectFirstOption();\n }\n },\n onDropdownClose: () => {\n onDropdownClose?.();\n combobox.resetSelectedOption();\n if (searchable) {\n combobox.focusTarget();\n }\n },\n });\n\n const handleSearchChange = (val: string) => {\n setSearchValue(val);\n combobox.resetSelectedOption();\n };\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<ComboboxPopoverFactory>({\n props,\n styles,\n classNames,\n });\n\n const handleOptionSubmit = (val: string) => {\n onOptionSubmit?.(val as any);\n const option = optionsLockup[val];\n\n if (multiple) {\n const currentValue = Array.isArray(_value) ? _value : [];\n if (currentValue.includes(option.value)) {\n setValue(currentValue.filter((v: any) => v !== option.value) as any);\n } else {\n setValue([...currentValue, option.value] as any);\n }\n combobox.updateSelectedOptionIndex('selected');\n } else {\n const nextValue = allowDeselect && `${option.value}` === `${_value}` ? null : option.value;\n setValue(nextValue as any);\n combobox.closeDropdown();\n }\n\n if (searchable) {\n handleSearchChange('');\n }\n };\n\n return (\n <>\n <Combobox\n store={combobox}\n __staticSelector=\"ComboboxPopover\"\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n attributes={attributes}\n onOptionSubmit={handleOptionSubmit}\n {...comboboxProps}\n {...others}\n >\n {children}\n {searchable ? (\n <SearchableDropdown\n data={parsedData as any}\n filter={filter as OptionsFilter<Primitive> | undefined}\n search={_searchValue}\n limit={limit}\n nothingFoundMessage={nothingFoundMessage}\n withScrollArea={withScrollArea}\n maxDropdownHeight={maxDropdownHeight}\n value={_value}\n checkIconPosition={checkIconPosition}\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n unstyled={unstyled}\n renderOption={renderOption}\n scrollAreaProps={scrollAreaProps}\n onSearchChange={(event) => {\n handleSearchChange(event.currentTarget.value);\n }}\n />\n ) : (\n <OptionsDropdown\n data={parsedData as any}\n filter={filter as OptionsFilter<Primitive> | undefined}\n search={undefined}\n limit={limit}\n hiddenWhenEmpty={!nothingFoundMessage}\n withScrollArea={withScrollArea}\n maxDropdownHeight={maxDropdownHeight}\n filterOptions={false}\n value={_value}\n checkIconPosition={checkIconPosition}\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n nothingFoundMessage={nothingFoundMessage}\n unstyled={unstyled}\n renderOption={renderOption}\n scrollAreaProps={scrollAreaProps}\n labelId={undefined}\n aria-label={undefined}\n />\n )}\n </Combobox>\n <Combobox.HiddenInput\n name={name}\n value={_value}\n form={form}\n valuesDivider={hiddenInputValuesDivider}\n {...hiddenInputProps}\n />\n </>\n );\n});\n\nComboboxPopover.classes = Combobox.classes;\nComboboxPopover.displayName = '@mantine/core/ComboboxPopover';\nComboboxPopover.Target = ComboboxPopoverTarget;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComboboxPopover.mjs","names":["comboboxClasses"],"sources":["../../../src/components/ComboboxPopover/ComboboxPopover.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport cx from 'clsx';\nimport { useUncontrolled } from '@mantine/hooks';\nimport {\n Factory,\n genericFactory,\n Primitive,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n} from '../../core';\nimport { CheckIcon } from '../Checkbox';\nimport {\n Combobox,\n ComboboxData,\n ComboboxItem,\n ComboboxLikeRenderOptionInput,\n ComboboxLikeStylesNames,\n ComboboxProps,\n defaultOptionsFilter,\n getOptionsLockup,\n getParsedComboboxData,\n isOptionsGroup,\n OptionsDropdown,\n OptionsFilter,\n useCombobox,\n} from '../Combobox';\nimport { ComboboxParsedItem } from '../Combobox/Combobox.types';\nimport { isEmptyComboboxData } from '../Combobox/OptionsDropdown/is-empty-combobox-data';\nimport { ScrollArea, ScrollAreaProps } from '../ScrollArea';\nimport { ComboboxPopoverValue } from './ComboboxPopover.types';\nimport { ComboboxPopoverTarget } from './ComboboxPopoverTarget';\nimport comboboxClasses from '../Combobox/Combobox.module.css';\n\nfunction isValueChecked(value: Primitive | Primitive[] | undefined | null, optionValue: Primitive) {\n return Array.isArray(value) ? value.includes(optionValue) : value === optionValue;\n}\n\ninterface OptionProps {\n data: ComboboxParsedItem<Primitive>;\n withCheckIcon?: boolean;\n withAlignedLabels?: boolean;\n value?: Primitive | Primitive[] | null;\n checkIconPosition?: 'left' | 'right';\n unstyled: boolean | undefined;\n renderOption?: (input: ComboboxLikeRenderOptionInput<any>) => React.ReactNode;\n}\n\nfunction Option({\n data,\n withCheckIcon,\n withAlignedLabels,\n value,\n checkIconPosition,\n unstyled,\n renderOption,\n}: OptionProps) {\n if (isOptionsGroup(data)) {\n const options = data.items.map((item) => (\n <Option\n data={item}\n value={value}\n key={`${item.value}`}\n unstyled={unstyled}\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n checkIconPosition={checkIconPosition}\n renderOption={renderOption}\n />\n ));\n return <Combobox.Group label={data.group}>{options}</Combobox.Group>;\n }\n\n const checked = isValueChecked(value, data.value);\n const check =\n withCheckIcon &&\n (checked ? (\n <CheckIcon className={comboboxClasses.optionsDropdownCheckIcon} />\n ) : withAlignedLabels ? (\n <div className={comboboxClasses.optionsDropdownCheckPlaceholder} />\n ) : null);\n\n const defaultContent = (\n <>\n {checkIconPosition === 'left' && check}\n <span>{data.label}</span>\n {checkIconPosition === 'right' && check}\n </>\n );\n\n return (\n <Combobox.Option\n value={data.value}\n disabled={data.disabled}\n className={cx({ [comboboxClasses.optionsDropdownOption]: !unstyled })}\n data-reverse={checkIconPosition === 'right' || undefined}\n data-checked={checked || undefined}\n aria-selected={checked}\n active={checked}\n >\n {typeof renderOption === 'function'\n ? renderOption({ option: data, checked })\n : defaultContent}\n </Combobox.Option>\n );\n}\n\ninterface SearchableDropdownProps {\n data: ComboboxParsedItem<Primitive>[];\n filter: OptionsFilter<Primitive> | undefined;\n search: string;\n limit: number | undefined;\n nothingFoundMessage: React.ReactNode | undefined;\n withScrollArea: boolean | undefined;\n maxDropdownHeight: number | string | undefined;\n value: Primitive | Primitive[] | null;\n checkIconPosition: 'left' | 'right' | undefined;\n withCheckIcon: boolean | undefined;\n withAlignedLabels: boolean | undefined;\n unstyled: boolean | undefined;\n renderOption?: (input: ComboboxLikeRenderOptionInput<any>) => React.ReactNode;\n scrollAreaProps: ScrollAreaProps | undefined;\n onSearchChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nfunction SearchableDropdown({\n data,\n filter,\n search,\n limit,\n nothingFoundMessage,\n withScrollArea = true,\n maxDropdownHeight,\n value,\n checkIconPosition,\n withCheckIcon = false,\n withAlignedLabels = false,\n unstyled,\n renderOption,\n scrollAreaProps,\n onSearchChange,\n}: SearchableDropdownProps) {\n const filteredData = (filter || defaultOptionsFilter)({\n options: data,\n search,\n limit: limit ?? Infinity,\n });\n const isEmpty = isEmptyComboboxData(filteredData);\n\n const options = filteredData.map((item, index) => (\n <Option\n data={item}\n key={\n isOptionsGroup(item)\n ? `group-${typeof item.group === 'string' ? item.group : index}`\n : `${item.value}`\n }\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n value={value}\n checkIconPosition={checkIconPosition}\n unstyled={unstyled}\n renderOption={renderOption}\n />\n ));\n\n return (\n <Combobox.Dropdown data-composed>\n <Combobox.Search value={search} onChange={onSearchChange} placeholder=\"Search...\" />\n <Combobox.Options>\n {withScrollArea ? (\n <ScrollArea.Autosize\n mah={maxDropdownHeight ?? 220}\n type=\"scroll\"\n scrollbarSize=\"var(--combobox-padding)\"\n offsetScrollbars=\"y\"\n {...scrollAreaProps}\n >\n {options}\n </ScrollArea.Autosize>\n ) : (\n options\n )}\n {isEmpty && nothingFoundMessage && <Combobox.Empty>{nothingFoundMessage}</Combobox.Empty>}\n </Combobox.Options>\n </Combobox.Dropdown>\n );\n}\n\nexport type ComboboxPopoverStylesNames = ComboboxLikeStylesNames | 'search';\n\nexport interface ComboboxPopoverProps<\n Multiple extends boolean = false,\n Value extends Primitive = string,\n> extends StylesApiProps<ComboboxPopoverFactory> {\n /** If set, multiple items can be selected at the same time */\n multiple?: Multiple;\n\n /** Controlled component value */\n value?: ComboboxPopoverValue<Multiple, Value>;\n\n /** Uncontrolled component default value */\n defaultValue?: ComboboxPopoverValue<Multiple, Value>;\n\n /** Called when value changes */\n onChange?: (value: ComboboxPopoverValue<Multiple, Value>) => void;\n\n /** Data used to generate options */\n data?: ComboboxData<Value>;\n\n /** Controlled dropdown opened state */\n dropdownOpened?: boolean;\n\n /** Uncontrolled dropdown initial opened state */\n defaultDropdownOpened?: boolean;\n\n /** Called when dropdown opens */\n onDropdownOpen?: () => void;\n\n /** Called when dropdown closes */\n onDropdownClose?: () => void;\n\n /** Called when option is submitted from dropdown with mouse click or Enter key */\n onOptionSubmit?: (value: Value) => void;\n\n /** Props passed down to Combobox component */\n comboboxProps?: ComboboxProps;\n\n /** Function based on which items are filtered and sorted */\n filter?: OptionsFilter<Value>;\n\n /** Maximum number of options displayed at a time @default Infinity */\n limit?: number;\n\n /** Determines whether the options should be wrapped with ScrollArea.AutoSize @default true */\n withScrollArea?: boolean;\n\n /** max-height of the dropdown @default 250 */\n maxDropdownHeight?: number | string;\n\n /** If set, the first option is selected when dropdown opens @default false */\n selectFirstOptionOnDropdownOpen?: boolean;\n\n /** Displays check icon near the selected option label @default true */\n withCheckIcon?: boolean;\n\n /** Aligns unchecked labels with the checked one @default false */\n withAlignedLabels?: boolean;\n\n /** Position of the check icon relative to the option label @default 'left' */\n checkIconPosition?: 'left' | 'right';\n\n /** Message displayed when no options match the search query or when there is no data */\n nothingFoundMessage?: React.ReactNode;\n\n /** Allows searching through options @default false */\n searchable?: boolean;\n\n /** Controlled search value */\n searchValue?: string;\n\n /** Default search value */\n defaultSearchValue?: string;\n\n /** Called when search changes */\n onSearchChange?: (value: string) => void;\n\n /** Allows deselecting the selected option by clicking it (only for single mode) @default true */\n allowDeselect?: boolean;\n\n /** A function to render content of the option, replaces the default content of the option */\n renderOption?: (item: ComboboxLikeRenderOptionInput<ComboboxItem>) => React.ReactNode;\n\n /** Props passed down to the underlying ScrollArea component in the dropdown */\n scrollAreaProps?: ScrollAreaProps;\n\n /** Props passed down to the hidden input */\n hiddenInputProps?: Omit<React.ComponentProps<'input'>, 'value'>;\n\n /** Hidden input name for form submission */\n name?: string;\n\n /** Hidden input form for form submission */\n form?: string;\n\n /** Content of the component */\n children?: React.ReactNode;\n\n /** Divider used to separate values in the hidden input value attribute @default ',' */\n hiddenInputValuesDivider?: string;\n}\n\nexport type ComboboxPopoverFactory = Factory<{\n props: ComboboxPopoverProps;\n ref: HTMLDivElement;\n stylesNames: ComboboxPopoverStylesNames;\n signature: <Multiple extends boolean = false, Value extends Primitive = string>(\n props: ComboboxPopoverProps<Multiple, Value>\n ) => React.JSX.Element;\n staticComponents: {\n Target: typeof ComboboxPopoverTarget;\n };\n}>;\n\nconst defaultProps = {\n withCheckIcon: true,\n allowDeselect: true,\n checkIconPosition: 'left',\n hiddenInputValuesDivider: ',',\n} satisfies Partial<ComboboxPopoverProps>;\n\nexport const ComboboxPopover = genericFactory<ComboboxPopoverFactory>((_props) => {\n const props = useProps('ComboboxPopover', defaultProps as any, _props);\n const {\n classNames,\n styles,\n unstyled,\n vars,\n children,\n multiple,\n value,\n defaultValue,\n onChange,\n data,\n dropdownOpened,\n defaultDropdownOpened,\n onDropdownOpen,\n onDropdownClose,\n onOptionSubmit,\n comboboxProps,\n filter,\n limit,\n withScrollArea,\n maxDropdownHeight,\n selectFirstOptionOnDropdownOpen,\n withCheckIcon,\n withAlignedLabels,\n checkIconPosition,\n nothingFoundMessage,\n searchable,\n searchValue,\n defaultSearchValue,\n onSearchChange,\n allowDeselect,\n renderOption,\n scrollAreaProps,\n hiddenInputProps,\n name,\n form,\n hiddenInputValuesDivider,\n attributes,\n ...others\n } = props;\n\n const parsedData = useMemo(() => getParsedComboboxData(data), [data]);\n const optionsLockup = useMemo(() => getOptionsLockup(parsedData), [parsedData]);\n\n const [_value, setValue] = useUncontrolled({\n value,\n defaultValue,\n finalValue: multiple ? ([] as any) : null,\n onChange,\n });\n\n const [_searchValue, setSearchValue] = useUncontrolled({\n value: searchValue,\n defaultValue: defaultSearchValue,\n finalValue: '',\n onChange: onSearchChange,\n });\n\n const combobox = useCombobox({\n opened: dropdownOpened,\n defaultOpened: defaultDropdownOpened,\n onDropdownOpen: () => {\n onDropdownOpen?.();\n if (searchable) {\n combobox.focusSearchInput();\n }\n if (selectFirstOptionOnDropdownOpen) {\n combobox.selectFirstOption();\n }\n },\n onDropdownClose: () => {\n onDropdownClose?.();\n combobox.resetSelectedOption();\n if (searchable) {\n combobox.focusTarget();\n }\n },\n });\n\n const handleSearchChange = (val: string) => {\n setSearchValue(val);\n combobox.resetSelectedOption();\n };\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<ComboboxPopoverFactory>({\n props,\n styles,\n classNames,\n });\n\n const handleOptionSubmit = (val: string) => {\n onOptionSubmit?.(val as any);\n const option = optionsLockup[val];\n\n if (multiple) {\n const currentValue = Array.isArray(_value) ? _value : [];\n if (currentValue.includes(option.value)) {\n setValue(currentValue.filter((v: any) => v !== option.value) as any);\n } else {\n setValue([...currentValue, option.value] as any);\n }\n combobox.updateSelectedOptionIndex('selected');\n } else {\n const nextValue = allowDeselect && `${option.value}` === `${_value}` ? null : option.value;\n setValue(nextValue as any);\n combobox.closeDropdown();\n }\n\n if (searchable) {\n handleSearchChange('');\n }\n };\n\n return (\n <>\n <Combobox\n store={combobox}\n __staticSelector=\"ComboboxPopover\"\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n unstyled={unstyled}\n attributes={attributes}\n onOptionSubmit={handleOptionSubmit}\n {...comboboxProps}\n {...others}\n >\n {children}\n {searchable ? (\n <SearchableDropdown\n data={parsedData as any}\n filter={filter as OptionsFilter<Primitive> | undefined}\n search={_searchValue}\n limit={limit}\n nothingFoundMessage={nothingFoundMessage}\n withScrollArea={withScrollArea}\n maxDropdownHeight={maxDropdownHeight}\n value={_value}\n checkIconPosition={checkIconPosition}\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n unstyled={unstyled}\n renderOption={renderOption}\n scrollAreaProps={scrollAreaProps}\n onSearchChange={(event) => {\n handleSearchChange(event.currentTarget.value);\n }}\n />\n ) : (\n <OptionsDropdown\n data={parsedData as any}\n filter={filter as OptionsFilter<Primitive> | undefined}\n search={undefined}\n limit={limit}\n hiddenWhenEmpty={!nothingFoundMessage}\n withScrollArea={withScrollArea}\n maxDropdownHeight={maxDropdownHeight}\n filterOptions={false}\n value={_value}\n checkIconPosition={checkIconPosition}\n withCheckIcon={withCheckIcon}\n withAlignedLabels={withAlignedLabels}\n nothingFoundMessage={nothingFoundMessage}\n unstyled={unstyled}\n renderOption={renderOption}\n scrollAreaProps={scrollAreaProps}\n labelId={undefined}\n aria-label={undefined}\n />\n )}\n </Combobox>\n <Combobox.HiddenInput\n name={name}\n value={_value}\n form={form}\n valuesDivider={hiddenInputValuesDivider}\n {...hiddenInputProps}\n />\n </>\n );\n});\n\nComboboxPopover.classes = Combobox.classes;\nComboboxPopover.displayName = '@mantine/core/ComboboxPopover';\nComboboxPopover.Target = ComboboxPopoverTarget;\n"],"mappings":"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"}
|
|
@@ -22,15 +22,17 @@ function useFloatingIndicator({ target, parent, ref, displayAfterTransitionEnd,
|
|
|
22
22
|
if (!target || !parent || !ref.current) return;
|
|
23
23
|
const targetRect = target.getBoundingClientRect();
|
|
24
24
|
const parentRect = parent.getBoundingClientRect();
|
|
25
|
+
const scaleX = parent.offsetWidth === 0 ? 1 : parentRect.width / parent.offsetWidth;
|
|
26
|
+
const scaleY = parent.offsetHeight === 0 ? 1 : parentRect.height / parent.offsetHeight;
|
|
25
27
|
const targetComputedStyle = window.getComputedStyle(target);
|
|
26
28
|
const parentComputedStyle = window.getComputedStyle(parent);
|
|
27
29
|
const borderTopWidth = toInt(targetComputedStyle.borderTopWidth) + toInt(parentComputedStyle.borderTopWidth);
|
|
28
30
|
const borderLeftWidth = toInt(targetComputedStyle.borderLeftWidth) + toInt(parentComputedStyle.borderLeftWidth);
|
|
29
31
|
const position = {
|
|
30
|
-
top: targetRect.top - parentRect.top - borderTopWidth,
|
|
31
|
-
left: targetRect.left - parentRect.left - borderLeftWidth,
|
|
32
|
-
width: targetRect.width,
|
|
33
|
-
height: targetRect.height
|
|
32
|
+
top: (targetRect.top - parentRect.top) / scaleY - borderTopWidth,
|
|
33
|
+
left: (targetRect.left - parentRect.left) / scaleX - borderLeftWidth,
|
|
34
|
+
width: targetRect.width / scaleX,
|
|
35
|
+
height: targetRect.height / scaleY
|
|
34
36
|
};
|
|
35
37
|
ref.current.style.transform = `translateY(${position.top}px) translateX(${position.left}px)`;
|
|
36
38
|
ref.current.style.width = `${position.width}px`;
|