@mantine/core 9.6.0 → 9.6.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/Accordion/Accordion.module.cjs.map +1 -1
- package/cjs/components/Combobox/use-combobox/use-combobox.cjs +1 -4
- package/cjs/components/Combobox/use-combobox/use-combobox.cjs.map +1 -1
- package/cjs/components/ComboboxPopover/ComboboxPopover.cjs +1 -1
- package/cjs/components/ComboboxPopover/ComboboxPopover.cjs.map +1 -1
- package/cjs/components/Drawer/Drawer.cjs +2 -1
- package/cjs/components/Drawer/Drawer.cjs.map +1 -1
- package/cjs/components/Drawer/DrawerStack.cjs +3 -1
- package/cjs/components/Drawer/DrawerStack.cjs.map +1 -1
- package/cjs/components/Menu/MenuSub/MenuSub.cjs +1 -1
- package/cjs/components/Menu/MenuSub/MenuSub.cjs.map +1 -1
- package/cjs/components/Modal/Modal.cjs +2 -1
- package/cjs/components/Modal/Modal.cjs.map +1 -1
- package/cjs/components/Modal/ModalStack.cjs +3 -1
- package/cjs/components/Modal/ModalStack.cjs.map +1 -1
- package/cjs/components/ModalBase/ModalBase.cjs +3 -2
- package/cjs/components/ModalBase/ModalBase.cjs.map +1 -1
- package/cjs/components/ModalBase/use-modal.cjs +7 -2
- package/cjs/components/ModalBase/use-modal.cjs.map +1 -1
- package/cjs/components/NumberInput/NumberInput.cjs +32 -22
- package/cjs/components/NumberInput/NumberInput.cjs.map +1 -1
- package/cjs/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.cjs +19 -0
- package/cjs/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.cjs.map +1 -0
- package/cjs/components/NumberInput/normalize-pasted-value/normalize-pasted-value.cjs +35 -0
- package/cjs/components/NumberInput/normalize-pasted-value/normalize-pasted-value.cjs.map +1 -0
- package/cjs/components/OverflowList/use-dimensions.cjs +9 -9
- package/cjs/components/OverflowList/use-dimensions.cjs.map +1 -1
- package/cjs/components/Popover/use-popover.cjs +7 -1
- package/cjs/components/Popover/use-popover.cjs.map +1 -1
- package/cjs/components/SegmentedControl/SegmentedControl.cjs +12 -1
- package/cjs/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
- package/cjs/components/Textarea/Autosize.cjs +8 -2
- package/cjs/components/Textarea/Autosize.cjs.map +1 -1
- package/esm/components/Accordion/Accordion.module.mjs.map +1 -1
- package/esm/components/Combobox/use-combobox/use-combobox.mjs +1 -4
- package/esm/components/Combobox/use-combobox/use-combobox.mjs.map +1 -1
- package/esm/components/ComboboxPopover/ComboboxPopover.mjs +1 -1
- package/esm/components/ComboboxPopover/ComboboxPopover.mjs.map +1 -1
- package/esm/components/Drawer/Drawer.mjs +2 -1
- package/esm/components/Drawer/Drawer.mjs.map +1 -1
- package/esm/components/Drawer/DrawerStack.mjs +3 -1
- package/esm/components/Drawer/DrawerStack.mjs.map +1 -1
- package/esm/components/Menu/MenuSub/MenuSub.mjs +1 -1
- package/esm/components/Menu/MenuSub/MenuSub.mjs.map +1 -1
- package/esm/components/Modal/Modal.mjs +2 -1
- package/esm/components/Modal/Modal.mjs.map +1 -1
- package/esm/components/Modal/ModalStack.mjs +3 -1
- package/esm/components/Modal/ModalStack.mjs.map +1 -1
- package/esm/components/ModalBase/ModalBase.mjs +3 -2
- package/esm/components/ModalBase/ModalBase.mjs.map +1 -1
- package/esm/components/ModalBase/use-modal.mjs +7 -2
- package/esm/components/ModalBase/use-modal.mjs.map +1 -1
- package/esm/components/NumberInput/NumberInput.mjs +32 -22
- package/esm/components/NumberInput/NumberInput.mjs.map +1 -1
- package/esm/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.mjs +19 -0
- package/esm/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.mjs.map +1 -0
- package/esm/components/NumberInput/normalize-pasted-value/normalize-pasted-value.mjs +35 -0
- package/esm/components/NumberInput/normalize-pasted-value/normalize-pasted-value.mjs.map +1 -0
- package/esm/components/OverflowList/use-dimensions.mjs +9 -9
- package/esm/components/OverflowList/use-dimensions.mjs.map +1 -1
- package/esm/components/Popover/use-popover.mjs +7 -1
- package/esm/components/Popover/use-popover.mjs.map +1 -1
- package/esm/components/SegmentedControl/SegmentedControl.mjs +12 -1
- package/esm/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
- package/esm/components/Textarea/Autosize.mjs +9 -3
- package/esm/components/Textarea/Autosize.mjs.map +1 -1
- package/lib/components/Drawer/DrawerStack.d.ts +1 -0
- package/lib/components/Menu/MenuSub/MenuSub.d.ts +3 -1
- package/lib/components/Modal/ModalStack.d.ts +1 -0
- package/lib/components/ModalBase/ModalBase.d.ts +2 -1
- package/lib/components/ModalBase/use-modal.d.ts +2 -1
- package/lib/components/NumberInput/get-caret-position-after-paste/get-caret-position-after-paste.d.ts +1 -0
- package/lib/components/NumberInput/normalize-pasted-value/normalize-pasted-value.d.ts +7 -0
- package/package.json +2 -2
- package/styles/Accordion.css +4 -2
- package/styles/Accordion.layer.css +4 -2
- package/styles.css +4 -2
- package/styles.layer.css +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl.cjs","names":["createVarsResolver","getRadius","getThemeColor","getSize","getFontSize","genericFactory","useProps","useStyles","useMantineTheme","isPrimitive","useMounted","useState","randomId","useUncontrolled","useId","Box","getContrastColor","useMergedRef","FloatingIndicator","classes"],"sources":["../../../src/components/SegmentedControl/SegmentedControl.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n randomId,\n useId,\n useMergedRef,\n useMounted,\n useShallowEffect,\n useUncontrolled,\n} from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n Factory,\n genericFactory,\n getContrastColor,\n getFontSize,\n getRadius,\n getSize,\n getThemeColor,\n isPrimitive,\n MantineColor,\n MantineRadius,\n MantineSize,\n Primitive,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '../../core';\nimport { FloatingIndicator } from '../FloatingIndicator';\nimport classes from './SegmentedControl.module.css';\n\nexport type SegmentedControlStylesNames =\n | 'root'\n | 'input'\n | 'label'\n | 'control'\n | 'indicator'\n | 'innerLabel';\nexport type SegmentedControlCssVariables = {\n root:\n | '--sc-radius'\n | '--sc-color'\n | '--sc-font-size'\n | '--sc-padding'\n | '--sc-shadow'\n | '--sc-transition-duration'\n | '--sc-transition-timing-function';\n};\n\nexport interface SegmentedControlItem<Value = string> {\n value: Value;\n label: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps<Value extends Primitive = string>\n extends\n BoxProps,\n StylesApiProps<SegmentedControlFactory>,\n ElementProps<'div', 'onChange' | 'value' | 'defaultValue'> {\n /** Data based on which controls are rendered */\n data: (Value | SegmentedControlItem<Value>)[];\n\n /** Controlled component value */\n value?: Value;\n\n /** Uncontrolled component default value */\n defaultValue?: Value;\n\n /** Called when value changes */\n onChange?: (value: Value) => void;\n\n /** Determines whether the component is disabled */\n disabled?: boolean;\n\n /** Name attribute for the radio group. A random name is auto-generated if not provided */\n name?: string;\n\n /** Determines whether the component should take 100% width of its parent @default false */\n fullWidth?: boolean;\n\n /** Key of `theme.colors` or any valid CSS color, changes indicator background color. By default, uses white in light mode and dark.5 in dark mode */\n color?: MantineColor;\n\n /** Controls `font-size`, `padding` and `height` properties @default 'sm' */\n size?: MantineSize | (string & {});\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 /** Indicator `transition-duration` in ms, set `0` to turn off transitions @default 200 */\n transitionDuration?: number;\n\n /** Indicator `transition-timing-function` property @default ease */\n transitionTimingFunction?: string;\n\n /** Component orientation @default 'horizontal' */\n orientation?: 'vertical' | 'horizontal';\n\n /** If set to `false`, prevents changing the value */\n readOnly?: boolean;\n\n /** If set, automatically adjusts label text color for optimal contrast against the indicator background color */\n autoContrast?: boolean;\n\n /** Determines whether there should be borders between items @default true */\n withItemsBorders?: boolean;\n}\n\nexport type SegmentedControlFactory = Factory<{\n props: SegmentedControlProps;\n ref: HTMLDivElement;\n stylesNames: SegmentedControlStylesNames;\n vars: SegmentedControlCssVariables;\n signature: <Value extends Primitive = string>(\n props: SegmentedControlProps<Value>\n ) => React.JSX.Element | null;\n}>;\n\nconst defaultProps = {\n withItemsBorders: true,\n} satisfies Partial<SegmentedControlProps>;\n\nconst varsResolver = createVarsResolver<SegmentedControlFactory>(\n (theme, { radius, color, transitionDuration, size, transitionTimingFunction }) => ({\n root: {\n '--sc-radius': radius === undefined ? undefined : getRadius(radius),\n '--sc-color': color ? getThemeColor(color, theme) : undefined,\n '--sc-shadow': color ? undefined : 'var(--mantine-shadow-xs)',\n '--sc-transition-duration':\n transitionDuration === undefined ? undefined : `${transitionDuration}ms`,\n '--sc-transition-timing-function': transitionTimingFunction,\n '--sc-padding': getSize(size, 'sc-padding'),\n '--sc-font-size': getFontSize(size),\n },\n })\n);\n\nexport const SegmentedControl = genericFactory<SegmentedControlFactory>((_props) => {\n const props = useProps('SegmentedControl', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n value,\n defaultValue,\n onChange,\n size,\n name,\n disabled,\n readOnly,\n fullWidth,\n orientation,\n radius,\n color,\n transitionDuration,\n transitionTimingFunction,\n variant,\n autoContrast,\n withItemsBorders,\n mod,\n attributes,\n ref,\n ...others\n } = props;\n\n const getStyles = useStyles<SegmentedControlFactory>({\n name: 'SegmentedControl',\n props: props as any,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const theme = useMantineTheme();\n\n const _data = data.map((item) => (isPrimitive(item) ? { label: `${item}`, value: item } : item));\n\n const initialized = useMounted();\n const [key, setKey] = useState(randomId());\n const [parent, setParent] = useState<HTMLElement | null>(null);\n const [refs, setRefs] = useState<Record<string, HTMLElement | null>>({});\n const setElementRef = (element: HTMLElement | null, val: string) => {\n refs[val] = element;\n setRefs(refs);\n };\n\n const [_value, handleValueChange] = useUncontrolled({\n value,\n defaultValue,\n finalValue: Array.isArray(data)\n ? (_data.find((item) => !item.disabled)?.value ?? (data[0] as any)?.value ?? null)\n : null,\n onChange,\n });\n\n const uuid = useId(name);\n\n const controls = _data.map((item) => (\n <Box\n {...getStyles('control')}\n mod={{ active: _value === item.value, orientation }}\n key={`${item.value}`}\n >\n <input\n {...getStyles('input')}\n disabled={disabled || item.disabled}\n type=\"radio\"\n name={uuid}\n value={`${item.value}`}\n id={`${uuid}-${item.value}`}\n checked={_value === item.value}\n onChange={() => !readOnly && handleValueChange(item.value)}\n data-focus-ring={theme.focusRing}\n key={`${item.value}-input`}\n />\n\n <Box\n component=\"label\"\n {...getStyles('label')}\n mod={{\n active: _value === item.value && !(disabled || item.disabled),\n disabled: disabled || item.disabled,\n 'read-only': readOnly,\n }}\n htmlFor={`${uuid}-${item.value}`}\n ref={(node) => setElementRef(node, `${item.value}`)}\n __vars={{\n '--sc-label-color':\n color !== undefined ? getContrastColor({ color, theme, autoContrast }) : undefined,\n }}\n key={`${item.value}-label`}\n >\n <span {...getStyles('innerLabel')}>{item.label}</span>\n </Box>\n </Box>\n ));\n\n const mergedRef = useMergedRef(ref, setParent);\n\n useShallowEffect(() => {\n setKey(randomId());\n }, [data.length]);\n\n if (data.length === 0) {\n return null;\n }\n\n return (\n <Box\n {...getStyles('root')}\n variant={variant}\n size={size}\n ref={mergedRef}\n mod={[\n {\n 'full-width': fullWidth,\n orientation,\n initialized,\n 'with-items-borders': withItemsBorders,\n },\n mod,\n ]}\n {...others}\n role=\"radiogroup\"\n data-disabled={disabled}\n >\n {typeof _value !== 'undefined' && (\n <FloatingIndicator\n target={refs[`${_value}`]}\n parent={parent}\n component=\"span\"\n transitionDuration=\"var(--sc-transition-duration)\"\n key={key}\n {...getStyles('indicator')}\n />\n )}\n\n {controls}\n </Box>\n );\n});\n\nSegmentedControl.classes = classes;\nSegmentedControl.varsResolver = varsResolver;\nSegmentedControl.displayName = '@mantine/core/SegmentedControl';\n\nexport namespace SegmentedControl {\n export type CssVariables = SegmentedControlCssVariables;\n export type Factory = SegmentedControlFactory;\n export type Item<Value extends Primitive = string> = SegmentedControlItem<Value>;\n export type Props<Value extends Primitive = string> = SegmentedControlProps<Value>;\n export type StylesNames = SegmentedControlStylesNames;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SegmentedControl.cjs","names":["createVarsResolver","getRadius","getThemeColor","getSize","getFontSize","genericFactory","useProps","useStyles","useMantineTheme","isPrimitive","useMounted","useState","randomId","useUncontrolled","useId","Box","getContrastColor","useMergedRef","FloatingIndicator","classes"],"sources":["../../../src/components/SegmentedControl/SegmentedControl.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n randomId,\n useId,\n useMergedRef,\n useMounted,\n useShallowEffect,\n useUncontrolled,\n} from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n Factory,\n genericFactory,\n getContrastColor,\n getFontSize,\n getRadius,\n getSize,\n getThemeColor,\n isPrimitive,\n MantineColor,\n MantineRadius,\n MantineSize,\n Primitive,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '../../core';\nimport { FloatingIndicator } from '../FloatingIndicator';\nimport classes from './SegmentedControl.module.css';\n\nexport type SegmentedControlStylesNames =\n | 'root'\n | 'input'\n | 'label'\n | 'control'\n | 'indicator'\n | 'innerLabel';\nexport type SegmentedControlCssVariables = {\n root:\n | '--sc-radius'\n | '--sc-color'\n | '--sc-font-size'\n | '--sc-padding'\n | '--sc-shadow'\n | '--sc-transition-duration'\n | '--sc-transition-timing-function';\n};\n\nexport interface SegmentedControlItem<Value = string> {\n value: Value;\n label: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps<Value extends Primitive = string>\n extends\n BoxProps,\n StylesApiProps<SegmentedControlFactory>,\n ElementProps<'div', 'onChange' | 'value' | 'defaultValue'> {\n /** Data based on which controls are rendered */\n data: (Value | SegmentedControlItem<Value>)[];\n\n /** Controlled component value */\n value?: Value;\n\n /** Uncontrolled component default value */\n defaultValue?: Value;\n\n /** Called when value changes */\n onChange?: (value: Value) => void;\n\n /** Determines whether the component is disabled */\n disabled?: boolean;\n\n /** Name attribute for the radio group. A random name is auto-generated if not provided */\n name?: string;\n\n /** Determines whether the component should take 100% width of its parent @default false */\n fullWidth?: boolean;\n\n /** Key of `theme.colors` or any valid CSS color, changes indicator background color. By default, uses white in light mode and dark.5 in dark mode */\n color?: MantineColor;\n\n /** Controls `font-size`, `padding` and `height` properties @default 'sm' */\n size?: MantineSize | (string & {});\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 /** Indicator `transition-duration` in ms, set `0` to turn off transitions @default 200 */\n transitionDuration?: number;\n\n /** Indicator `transition-timing-function` property @default ease */\n transitionTimingFunction?: string;\n\n /** Component orientation @default 'horizontal' */\n orientation?: 'vertical' | 'horizontal';\n\n /** If set to `false`, prevents changing the value */\n readOnly?: boolean;\n\n /** If set, automatically adjusts label text color for optimal contrast against the indicator background color */\n autoContrast?: boolean;\n\n /** Determines whether there should be borders between items @default true */\n withItemsBorders?: boolean;\n}\n\nexport type SegmentedControlFactory = Factory<{\n props: SegmentedControlProps;\n ref: HTMLDivElement;\n stylesNames: SegmentedControlStylesNames;\n vars: SegmentedControlCssVariables;\n signature: <Value extends Primitive = string>(\n props: SegmentedControlProps<Value>\n ) => React.JSX.Element | null;\n}>;\n\nconst defaultProps = {\n withItemsBorders: true,\n} satisfies Partial<SegmentedControlProps>;\n\nconst varsResolver = createVarsResolver<SegmentedControlFactory>(\n (theme, { radius, color, transitionDuration, size, transitionTimingFunction }) => ({\n root: {\n '--sc-radius': radius === undefined ? undefined : getRadius(radius),\n '--sc-color': color ? getThemeColor(color, theme) : undefined,\n '--sc-shadow': color ? undefined : 'var(--mantine-shadow-xs)',\n '--sc-transition-duration':\n transitionDuration === undefined ? undefined : `${transitionDuration}ms`,\n '--sc-transition-timing-function': transitionTimingFunction,\n '--sc-padding': getSize(size, 'sc-padding'),\n '--sc-font-size': getFontSize(size),\n },\n })\n);\n\nexport const SegmentedControl = genericFactory<SegmentedControlFactory>((_props) => {\n const props = useProps('SegmentedControl', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n value,\n defaultValue,\n onChange,\n size,\n name,\n disabled,\n readOnly,\n fullWidth,\n orientation,\n radius,\n color,\n transitionDuration,\n transitionTimingFunction,\n variant,\n autoContrast,\n withItemsBorders,\n mod,\n attributes,\n ref,\n ...others\n } = props;\n\n const getStyles = useStyles<SegmentedControlFactory>({\n name: 'SegmentedControl',\n props: props as any,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const theme = useMantineTheme();\n\n const _data = data.map((item) => (isPrimitive(item) ? { label: `${item}`, value: item } : item));\n\n const initialized = useMounted();\n const [key, setKey] = useState(randomId());\n const [parent, setParent] = useState<HTMLElement | null>(null);\n const [refs, setRefs] = useState<Record<string, HTMLElement | null>>({});\n const setElementRef = (element: HTMLElement | null, val: string) => {\n if (element === null || refs[val] === element) {\n return;\n }\n\n refs[val] = element;\n setRefs({ ...refs });\n };\n\n const [_value, handleValueChange] = useUncontrolled({\n value,\n defaultValue,\n finalValue: Array.isArray(data)\n ? (_data.find((item) => !item.disabled)?.value ?? (data[0] as any)?.value ?? null)\n : null,\n onChange,\n });\n\n const uuid = useId(name);\n\n const dataValues = _data.map((item) => `${item.value}`);\n\n const controls = _data.map((item) => (\n <Box\n {...getStyles('control')}\n mod={{ active: _value === item.value, orientation }}\n key={`${item.value}`}\n >\n <input\n {...getStyles('input')}\n disabled={disabled || item.disabled}\n type=\"radio\"\n name={uuid}\n value={`${item.value}`}\n id={`${uuid}-${item.value}`}\n checked={_value === item.value}\n onChange={() => !readOnly && handleValueChange(item.value)}\n data-focus-ring={theme.focusRing}\n key={`${item.value}-input`}\n />\n\n <Box\n component=\"label\"\n {...getStyles('label')}\n mod={{\n active: _value === item.value && !(disabled || item.disabled),\n disabled: disabled || item.disabled,\n 'read-only': readOnly,\n }}\n htmlFor={`${uuid}-${item.value}`}\n ref={(node) => setElementRef(node, `${item.value}`)}\n __vars={{\n '--sc-label-color':\n color !== undefined ? getContrastColor({ color, theme, autoContrast }) : undefined,\n }}\n key={`${item.value}-label`}\n >\n <span {...getStyles('innerLabel')}>{item.label}</span>\n </Box>\n </Box>\n ));\n\n const mergedRef = useMergedRef(ref, setParent);\n\n useShallowEffect(() => {\n setKey(randomId());\n }, [data.length]);\n\n useShallowEffect(() => {\n setRefs((current) => {\n const next: Record<string, HTMLElement | null> = {};\n dataValues.forEach((value) => {\n if (value in current) {\n next[value] = current[value];\n }\n });\n\n return Object.keys(next).length === Object.keys(current).length ? current : next;\n });\n }, [dataValues]);\n\n if (data.length === 0) {\n return null;\n }\n\n return (\n <Box\n {...getStyles('root')}\n variant={variant}\n size={size}\n ref={mergedRef}\n mod={[\n {\n 'full-width': fullWidth,\n orientation,\n initialized,\n 'with-items-borders': withItemsBorders,\n },\n mod,\n ]}\n {...others}\n role=\"radiogroup\"\n data-disabled={disabled}\n >\n {typeof _value !== 'undefined' && (\n <FloatingIndicator\n target={refs[`${_value}`]}\n parent={parent}\n component=\"span\"\n transitionDuration=\"var(--sc-transition-duration)\"\n key={key}\n {...getStyles('indicator')}\n />\n )}\n\n {controls}\n </Box>\n );\n});\n\nSegmentedControl.classes = classes;\nSegmentedControl.varsResolver = varsResolver;\nSegmentedControl.displayName = '@mantine/core/SegmentedControl';\n\nexport namespace SegmentedControl {\n export type CssVariables = SegmentedControlCssVariables;\n export type Factory = SegmentedControlFactory;\n export type Item<Value extends Primitive = string> = SegmentedControlItem<Value>;\n export type Props<Value extends Primitive = string> = SegmentedControlProps<Value>;\n export type StylesNames = SegmentedControlStylesNames;\n}\n"],"mappings":"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"}
|
|
@@ -106,6 +106,7 @@ function TextareaAutosize({ maxRows, minRows, onChange, ref: userRef, ...props }
|
|
|
106
106
|
node.style.setProperty("height", `${height}px`, "important");
|
|
107
107
|
}
|
|
108
108
|
};
|
|
109
|
+
const handleResize = (0, react.useEffectEvent)(resizeTextarea);
|
|
109
110
|
const handleChange = (event) => {
|
|
110
111
|
if (!isControlled) resizeTextarea();
|
|
111
112
|
onChange?.(event);
|
|
@@ -120,14 +121,19 @@ function TextareaAutosize({ maxRows, minRows, onChange, ref: userRef, ...props }
|
|
|
120
121
|
const node = libRef.current;
|
|
121
122
|
if (!node || typeof ResizeObserver === "undefined") return;
|
|
122
123
|
widthRef.current = node.offsetWidth;
|
|
124
|
+
let frame = 0;
|
|
123
125
|
const observer = new ResizeObserver(() => {
|
|
124
126
|
if (libRef.current && libRef.current.offsetWidth !== widthRef.current) {
|
|
125
127
|
widthRef.current = libRef.current.offsetWidth;
|
|
126
|
-
|
|
128
|
+
cancelAnimationFrame(frame);
|
|
129
|
+
frame = requestAnimationFrame(handleResize);
|
|
127
130
|
}
|
|
128
131
|
});
|
|
129
132
|
observer.observe(node);
|
|
130
|
-
return () =>
|
|
133
|
+
return () => {
|
|
134
|
+
cancelAnimationFrame(frame);
|
|
135
|
+
observer.disconnect();
|
|
136
|
+
};
|
|
131
137
|
}, []);
|
|
132
138
|
(0, react.useEffect)(() => {
|
|
133
139
|
const handleFontsLoaded = () => resizeTextarea();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Autosize.cjs","names":["useRef","useMergedRef"],"sources":["../../../src/components/Textarea/Autosize.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef } from 'react';\nimport { useMergedRef } from '@mantine/hooks';\n\ntype TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nexport interface TextareaAutosizeProps extends Omit<TextareaProps, 'style'> {\n ref?: React.Ref<HTMLTextAreaElement>;\n maxRows?: number;\n minRows?: number;\n style?: Omit<NonNullable<TextareaProps['style']>, 'maxHeight' | 'minHeight'> & {\n height?: number;\n };\n}\n\nconst SIZING_STYLE_KEYS = [\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderRightWidth',\n 'borderTopWidth',\n 'boxSizing',\n 'fontFamily',\n 'fontSize',\n 'fontStyle',\n 'fontWeight',\n 'letterSpacing',\n 'lineHeight',\n 'paddingBottom',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'tabSize',\n 'textIndent',\n 'textRendering',\n 'textTransform',\n 'width',\n 'wordBreak',\n 'wordSpacing',\n 'scrollbarGutter',\n] as const;\n\ntype SizingStyleKey = (typeof SIZING_STYLE_KEYS)[number];\n\ninterface SizingData {\n sizingStyle: Pick<CSSStyleDeclaration, Extract<SizingStyleKey, keyof CSSStyleDeclaration>>;\n paddingSize: number;\n borderSize: number;\n}\n\nconst HIDDEN_TEXTAREA_STYLE: Record<string, string> = {\n 'min-height': '0',\n 'max-height': 'none',\n height: '0',\n visibility: 'hidden',\n overflow: 'hidden',\n position: 'absolute',\n 'z-index': '-1000',\n top: '0',\n right: '0',\n display: 'block',\n};\n\nfunction forceHiddenStyles(node: HTMLElement) {\n Object.keys(HIDDEN_TEXTAREA_STYLE).forEach((key) => {\n node.style.setProperty(key, HIDDEN_TEXTAREA_STYLE[key], 'important');\n });\n}\n\nfunction getSizingData(node: HTMLElement): SizingData | null {\n const style = window.getComputedStyle(node);\n\n if (style === null) {\n return null;\n }\n\n const sizingStyle = {} as SizingData['sizingStyle'];\n for (const key of SIZING_STYLE_KEYS) {\n (sizingStyle as any)[key] = style[key as keyof CSSStyleDeclaration];\n }\n\n if ((sizingStyle as any).boxSizing === '') {\n return null;\n }\n\n const paddingSize = parseFloat(sizingStyle.paddingBottom!) + parseFloat(sizingStyle.paddingTop!);\n\n const borderSize =\n parseFloat(sizingStyle.borderBottomWidth!) + parseFloat(sizingStyle.borderTopWidth!);\n\n return { sizingStyle, paddingSize, borderSize };\n}\n\nlet hiddenTextarea: HTMLTextAreaElement | null = null;\n\nfunction calculateNodeHeight(\n sizingData: SizingData,\n value: string,\n minRows = 1,\n maxRows = Infinity\n): [number, number] {\n if (!hiddenTextarea) {\n hiddenTextarea = document.createElement('textarea');\n hiddenTextarea.setAttribute('tabindex', '-1');\n hiddenTextarea.setAttribute('aria-hidden', 'true');\n hiddenTextarea.setAttribute('aria-label', 'autosize measurement');\n forceHiddenStyles(hiddenTextarea);\n }\n\n if (hiddenTextarea.parentNode === null) {\n document.body.appendChild(hiddenTextarea);\n }\n\n const { paddingSize, borderSize, sizingStyle } = sizingData;\n const { boxSizing } = sizingStyle;\n\n Object.keys(sizingStyle).forEach((key) => {\n (hiddenTextarea!.style as any)[key] = (sizingStyle as any)[key];\n });\n\n forceHiddenStyles(hiddenTextarea);\n\n hiddenTextarea.value = value;\n let height =\n boxSizing === 'border-box'\n ? hiddenTextarea.scrollHeight + borderSize\n : hiddenTextarea.scrollHeight - paddingSize;\n\n // Double set and calc due to Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1795904\n hiddenTextarea.value = value;\n height =\n boxSizing === 'border-box'\n ? hiddenTextarea.scrollHeight + borderSize\n : hiddenTextarea.scrollHeight - paddingSize;\n\n hiddenTextarea.value = 'x';\n const rowHeight = hiddenTextarea.scrollHeight - paddingSize;\n\n let minHeight = rowHeight * minRows;\n if (boxSizing === 'border-box') {\n minHeight = minHeight + paddingSize + borderSize;\n }\n height = Math.max(minHeight, height);\n\n let maxHeight = rowHeight * maxRows;\n if (boxSizing === 'border-box') {\n maxHeight = maxHeight + paddingSize + borderSize;\n }\n height = Math.min(maxHeight, height);\n\n return [height, rowHeight];\n}\n\nexport function TextareaAutosize({\n maxRows,\n minRows,\n onChange,\n ref: userRef,\n ...props\n}: TextareaAutosizeProps) {\n const isControlled = props.value !== undefined;\n const libRef = useRef<HTMLTextAreaElement | null>(null);\n const ref = useMergedRef(libRef, userRef);\n const heightRef = useRef(0);\n const widthRef = useRef(0);\n\n const resizeTextarea = () => {\n const node = libRef.current;\n\n if (!node) {\n return;\n }\n\n const nodeSizingData = getSizingData(node);\n\n if (!nodeSizingData) {\n return;\n }\n\n const [height] = calculateNodeHeight(\n nodeSizingData,\n node.value || node.placeholder || 'x',\n minRows,\n maxRows\n );\n\n if (heightRef.current !== height) {\n heightRef.current = height;\n node.style.setProperty('height', `${height}px`, 'important');\n }\n };\n\n const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) {\n resizeTextarea();\n }\n onChange?.(event);\n };\n\n useLayoutEffect(resizeTextarea);\n\n useEffect(() => {\n const handleResize = () => resizeTextarea();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n useEffect(() => {\n const node = libRef.current;\n\n if (!node || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n widthRef.current = node.offsetWidth;\n\n const observer = new ResizeObserver(() => {\n if (libRef.current && libRef.current.offsetWidth !== widthRef.current) {\n widthRef.current = libRef.current.offsetWidth;\n resizeTextarea();\n }\n });\n\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n useEffect(() => {\n const handleFontsLoaded = () => resizeTextarea();\n document.fonts.addEventListener('loadingdone', handleFontsLoaded);\n return () => document.fonts.removeEventListener('loadingdone', handleFontsLoaded);\n }, []);\n\n useEffect(() => {\n const handleReset = (event: Event) => {\n if (libRef.current?.form === event.target && !isControlled) {\n const currentValue = libRef.current!.value;\n requestAnimationFrame(() => {\n if (libRef.current && currentValue !== libRef.current.value) {\n resizeTextarea();\n }\n });\n }\n };\n document.body.addEventListener('reset', handleReset);\n return () => document.body.removeEventListener('reset', handleReset);\n }, [isControlled]);\n\n return <textarea rows={minRows} {...props} onChange={handleChange} ref={ref} />;\n}\n"],"mappings":";;;;;;;AAcA,MAAM,oBAAoB;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAUA,MAAM,wBAAgD;CACpD,cAAc;CACd,cAAc;CACd,QAAQ;CACR,YAAY;CACZ,UAAU;CACV,UAAU;CACV,WAAW;CACX,KAAK;CACL,OAAO;CACP,SAAS;AACX;AAEA,SAAS,kBAAkB,MAAmB;CAC5C,OAAO,KAAK,qBAAqB,CAAC,CAAC,SAAS,QAAQ;EAClD,KAAK,MAAM,YAAY,KAAK,sBAAsB,MAAM,WAAW;CACrE,CAAC;AACH;AAEA,SAAS,cAAc,MAAsC;CAC3D,MAAM,QAAQ,OAAO,iBAAiB,IAAI;CAE1C,IAAI,UAAU,MACZ,OAAO;CAGT,MAAM,cAAc,CAAC;CACrB,KAAK,MAAM,OAAO,mBAChB,YAAqB,OAAO,MAAM;CAGpC,IAAK,YAAoB,cAAc,IACrC,OAAO;CAQT,OAAO;EAAE;EAAa,aALF,WAAW,YAAY,aAAc,IAAI,WAAW,YAAY,UAAW;EAK5D,YAFjC,WAAW,YAAY,iBAAkB,IAAI,WAAW,YAAY,cAAe;CAEvC;AAChD;AAEA,IAAI,iBAA6C;AAEjD,SAAS,oBACP,YACA,OACA,UAAU,GACV,UAAU,UACQ;CAClB,IAAI,CAAC,gBAAgB;EACnB,iBAAiB,SAAS,cAAc,UAAU;EAClD,eAAe,aAAa,YAAY,IAAI;EAC5C,eAAe,aAAa,eAAe,MAAM;EACjD,eAAe,aAAa,cAAc,sBAAsB;EAChE,kBAAkB,cAAc;CAClC;CAEA,IAAI,eAAe,eAAe,MAChC,SAAS,KAAK,YAAY,cAAc;CAG1C,MAAM,EAAE,aAAa,YAAY,gBAAgB;CACjD,MAAM,EAAE,cAAc;CAEtB,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,QAAQ;EACxC,eAAiB,MAAc,OAAQ,YAAoB;CAC7D,CAAC;CAED,kBAAkB,cAAc;CAEhC,eAAe,QAAQ;CACvB,IAAI,SACF,cAAc,eACV,eAAe,eAAe,aAC9B,eAAe,eAAe;CAGpC,eAAe,QAAQ;CACvB,SACE,cAAc,eACV,eAAe,eAAe,aAC9B,eAAe,eAAe;CAEpC,eAAe,QAAQ;CACvB,MAAM,YAAY,eAAe,eAAe;CAEhD,IAAI,YAAY,YAAY;CAC5B,IAAI,cAAc,cAChB,YAAY,YAAY,cAAc;CAExC,SAAS,KAAK,IAAI,WAAW,MAAM;CAEnC,IAAI,YAAY,YAAY;CAC5B,IAAI,cAAc,cAChB,YAAY,YAAY,cAAc;CAExC,SAAS,KAAK,IAAI,WAAW,MAAM;CAEnC,OAAO,CAAC,QAAQ,SAAS;AAC3B;AAEA,SAAgB,iBAAiB,EAC/B,SACA,SACA,UACA,KAAK,SACL,GAAG,SACqB;CACxB,MAAM,eAAe,MAAM,UAAU,KAAA;CACrC,MAAM,UAAA,GAASA,MAAAA,OAAAA,CAAmC,IAAI;CACtD,MAAM,OAAA,GAAMC,eAAAA,aAAAA,CAAa,QAAQ,OAAO;CACxC,MAAM,aAAA,GAAYD,MAAAA,OAAAA,CAAO,CAAC;CAC1B,MAAM,YAAA,GAAWA,MAAAA,OAAAA,CAAO,CAAC;CAEzB,MAAM,uBAAuB;EAC3B,MAAM,OAAO,OAAO;EAEpB,IAAI,CAAC,MACH;EAGF,MAAM,iBAAiB,cAAc,IAAI;EAEzC,IAAI,CAAC,gBACH;EAGF,MAAM,CAAC,UAAU,oBACf,gBACA,KAAK,SAAS,KAAK,eAAe,KAClC,SACA,OACF;EAEA,IAAI,UAAU,YAAY,QAAQ;GAChC,UAAU,UAAU;GACpB,KAAK,MAAM,YAAY,UAAU,GAAG,OAAO,KAAK,WAAW;EAC7D;CACF;CAEA,MAAM,gBAAgB,UAAkD;EACtE,IAAI,CAAC,cACH,eAAe;EAEjB,WAAW,KAAK;CAClB;CAEA,CAAA,GAAA,MAAA,gBAAA,CAAgB,cAAc;CAE9B,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,qBAAqB,eAAe;EAC1C,OAAO,iBAAiB,UAAU,YAAY;EAC9C,aAAa,OAAO,oBAAoB,UAAU,YAAY;CAChE,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,OAAO,OAAO;EAEpB,IAAI,CAAC,QAAQ,OAAO,mBAAmB,aACrC;EAGF,SAAS,UAAU,KAAK;EAExB,MAAM,WAAW,IAAI,qBAAqB;GACxC,IAAI,OAAO,WAAW,OAAO,QAAQ,gBAAgB,SAAS,SAAS;IACrE,SAAS,UAAU,OAAO,QAAQ;IAClC,eAAe;GACjB;EACF,CAAC;EAED,SAAS,QAAQ,IAAI;EACrB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,0BAA0B,eAAe;EAC/C,SAAS,MAAM,iBAAiB,eAAe,iBAAiB;EAChE,aAAa,SAAS,MAAM,oBAAoB,eAAe,iBAAiB;CAClF,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,eAAe,UAAiB;GACpC,IAAI,OAAO,SAAS,SAAS,MAAM,UAAU,CAAC,cAAc;IAC1D,MAAM,eAAe,OAAO,QAAS;IACrC,4BAA4B;KAC1B,IAAI,OAAO,WAAW,iBAAiB,OAAO,QAAQ,OACpD,eAAe;IAEnB,CAAC;GACH;EACF;EACA,SAAS,KAAK,iBAAiB,SAAS,WAAW;EACnD,aAAa,SAAS,KAAK,oBAAoB,SAAS,WAAW;CACrE,GAAG,CAAC,YAAY,CAAC;CAEjB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;EAAU,MAAM;EAAS,GAAI;EAAO,UAAU;EAAmB;CAAM,CAAA;AAChF"}
|
|
1
|
+
{"version":3,"file":"Autosize.cjs","names":["useRef","useMergedRef","useEffectEvent"],"sources":["../../../src/components/Textarea/Autosize.tsx"],"sourcesContent":["import React, { useEffect, useEffectEvent, useLayoutEffect, useRef } from 'react';\nimport { useMergedRef } from '@mantine/hooks';\n\ntype TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nexport interface TextareaAutosizeProps extends Omit<TextareaProps, 'style'> {\n ref?: React.Ref<HTMLTextAreaElement>;\n maxRows?: number;\n minRows?: number;\n style?: Omit<NonNullable<TextareaProps['style']>, 'maxHeight' | 'minHeight'> & {\n height?: number;\n };\n}\n\nconst SIZING_STYLE_KEYS = [\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderRightWidth',\n 'borderTopWidth',\n 'boxSizing',\n 'fontFamily',\n 'fontSize',\n 'fontStyle',\n 'fontWeight',\n 'letterSpacing',\n 'lineHeight',\n 'paddingBottom',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'tabSize',\n 'textIndent',\n 'textRendering',\n 'textTransform',\n 'width',\n 'wordBreak',\n 'wordSpacing',\n 'scrollbarGutter',\n] as const;\n\ntype SizingStyleKey = (typeof SIZING_STYLE_KEYS)[number];\n\ninterface SizingData {\n sizingStyle: Pick<CSSStyleDeclaration, Extract<SizingStyleKey, keyof CSSStyleDeclaration>>;\n paddingSize: number;\n borderSize: number;\n}\n\nconst HIDDEN_TEXTAREA_STYLE: Record<string, string> = {\n 'min-height': '0',\n 'max-height': 'none',\n height: '0',\n visibility: 'hidden',\n overflow: 'hidden',\n position: 'absolute',\n 'z-index': '-1000',\n top: '0',\n right: '0',\n display: 'block',\n};\n\nfunction forceHiddenStyles(node: HTMLElement) {\n Object.keys(HIDDEN_TEXTAREA_STYLE).forEach((key) => {\n node.style.setProperty(key, HIDDEN_TEXTAREA_STYLE[key], 'important');\n });\n}\n\nfunction getSizingData(node: HTMLElement): SizingData | null {\n const style = window.getComputedStyle(node);\n\n if (style === null) {\n return null;\n }\n\n const sizingStyle = {} as SizingData['sizingStyle'];\n for (const key of SIZING_STYLE_KEYS) {\n (sizingStyle as any)[key] = style[key as keyof CSSStyleDeclaration];\n }\n\n if ((sizingStyle as any).boxSizing === '') {\n return null;\n }\n\n const paddingSize = parseFloat(sizingStyle.paddingBottom!) + parseFloat(sizingStyle.paddingTop!);\n\n const borderSize =\n parseFloat(sizingStyle.borderBottomWidth!) + parseFloat(sizingStyle.borderTopWidth!);\n\n return { sizingStyle, paddingSize, borderSize };\n}\n\nlet hiddenTextarea: HTMLTextAreaElement | null = null;\n\nfunction calculateNodeHeight(\n sizingData: SizingData,\n value: string,\n minRows = 1,\n maxRows = Infinity\n): [number, number] {\n if (!hiddenTextarea) {\n hiddenTextarea = document.createElement('textarea');\n hiddenTextarea.setAttribute('tabindex', '-1');\n hiddenTextarea.setAttribute('aria-hidden', 'true');\n hiddenTextarea.setAttribute('aria-label', 'autosize measurement');\n forceHiddenStyles(hiddenTextarea);\n }\n\n if (hiddenTextarea.parentNode === null) {\n document.body.appendChild(hiddenTextarea);\n }\n\n const { paddingSize, borderSize, sizingStyle } = sizingData;\n const { boxSizing } = sizingStyle;\n\n Object.keys(sizingStyle).forEach((key) => {\n (hiddenTextarea!.style as any)[key] = (sizingStyle as any)[key];\n });\n\n forceHiddenStyles(hiddenTextarea);\n\n hiddenTextarea.value = value;\n let height =\n boxSizing === 'border-box'\n ? hiddenTextarea.scrollHeight + borderSize\n : hiddenTextarea.scrollHeight - paddingSize;\n\n // Double set and calc due to Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1795904\n hiddenTextarea.value = value;\n height =\n boxSizing === 'border-box'\n ? hiddenTextarea.scrollHeight + borderSize\n : hiddenTextarea.scrollHeight - paddingSize;\n\n hiddenTextarea.value = 'x';\n const rowHeight = hiddenTextarea.scrollHeight - paddingSize;\n\n let minHeight = rowHeight * minRows;\n if (boxSizing === 'border-box') {\n minHeight = minHeight + paddingSize + borderSize;\n }\n height = Math.max(minHeight, height);\n\n let maxHeight = rowHeight * maxRows;\n if (boxSizing === 'border-box') {\n maxHeight = maxHeight + paddingSize + borderSize;\n }\n height = Math.min(maxHeight, height);\n\n return [height, rowHeight];\n}\n\nexport function TextareaAutosize({\n maxRows,\n minRows,\n onChange,\n ref: userRef,\n ...props\n}: TextareaAutosizeProps) {\n const isControlled = props.value !== undefined;\n const libRef = useRef<HTMLTextAreaElement | null>(null);\n const ref = useMergedRef(libRef, userRef);\n const heightRef = useRef(0);\n const widthRef = useRef(0);\n\n const resizeTextarea = () => {\n const node = libRef.current;\n\n if (!node) {\n return;\n }\n\n const nodeSizingData = getSizingData(node);\n\n if (!nodeSizingData) {\n return;\n }\n\n const [height] = calculateNodeHeight(\n nodeSizingData,\n node.value || node.placeholder || 'x',\n minRows,\n maxRows\n );\n\n if (heightRef.current !== height) {\n heightRef.current = height;\n node.style.setProperty('height', `${height}px`, 'important');\n }\n };\n\n const handleResize = useEffectEvent(resizeTextarea);\n\n const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) {\n resizeTextarea();\n }\n onChange?.(event);\n };\n\n useLayoutEffect(resizeTextarea);\n\n useEffect(() => {\n const handleResize = () => resizeTextarea();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n useEffect(() => {\n const node = libRef.current;\n\n if (!node || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n widthRef.current = node.offsetWidth;\n\n let frame = 0;\n\n const observer = new ResizeObserver(() => {\n if (libRef.current && libRef.current.offsetWidth !== widthRef.current) {\n widthRef.current = libRef.current.offsetWidth;\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(handleResize);\n }\n });\n\n observer.observe(node);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, []);\n\n useEffect(() => {\n const handleFontsLoaded = () => resizeTextarea();\n document.fonts.addEventListener('loadingdone', handleFontsLoaded);\n return () => document.fonts.removeEventListener('loadingdone', handleFontsLoaded);\n }, []);\n\n useEffect(() => {\n const handleReset = (event: Event) => {\n if (libRef.current?.form === event.target && !isControlled) {\n const currentValue = libRef.current!.value;\n requestAnimationFrame(() => {\n if (libRef.current && currentValue !== libRef.current.value) {\n resizeTextarea();\n }\n });\n }\n };\n document.body.addEventListener('reset', handleReset);\n return () => document.body.removeEventListener('reset', handleReset);\n }, [isControlled]);\n\n return <textarea rows={minRows} {...props} onChange={handleChange} ref={ref} />;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.module.mjs","names":[],"sources":["../../../src/components/Accordion/Accordion.module.css"],"sourcesContent":[".root {\n --accordion-radius: var(--mantine-radius-default);\n}\n\n.panel {\n overflow-wrap: break-word;\n}\n\n.content {\n padding: var(--mantine-spacing-md);\n padding-top: calc(var(--mantine-spacing-xs) / 2);\n}\n\n.itemTitle {\n margin: 0;\n padding: 0;\n width: 100%;\n}\n\n.control {\n width: 100%;\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n padding-inline: var(--mantine-spacing-md);\n opacity: 1;\n cursor: pointer;\n background-color: transparent;\n color: var(--mantine-color-bright);\n\n &:where([data-chevron-position='left']) {\n flex-direction: row;\n padding-inline-start: 0;\n }\n\n &:where(:disabled, [data-disabled]) {\n opacity: 0.4;\n cursor: not-allowed;\n }\n}\n\n.control--default,\n.control--contained {\n &:where(:not(:disabled, [data-disabled])) {\n @mixin hover {\n @mixin where-light {\n background-color: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-6);\n }\n }\n }\n}\n\n.label {\n color: inherit;\n font-weight: var(--mantine-font-weight-regular);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n padding-top: var(--mantine-spacing-sm);\n padding-bottom: var(--mantine-spacing-sm);\n}\n\n.chevron {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n transition: transform var(--accordion-transition-duration, 200ms) ease;\n width: var(--accordion-chevron-size, rem(15px));\n min-width: var(--accordion-chevron-size, rem(15px));\n transform: rotate(0deg);\n\n &:where([data-rotate]) {\n transform: rotate(180deg);\n }\n\n &:where([data-position='left']) {\n margin-inline-end: var(--mantine-spacing-md);\n margin-inline-start: var(--mantine-spacing-md);\n }\n}\n\n.icon {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-inline-end: var(--mantine-spacing-sm);\n\n &:where([data-chevron-position='left']) {\n margin-inline-end: 0;\n margin-inline-start: var(--mantine-spacing-lg);\n }\n}\n\n.item {\n @mixin where-light {\n --item-border-color: var(--mantine-color-gray-3);\n --item-filled-color: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n --item-border-color: var(--mantine-color-dark-4);\n --item-filled-color: var(--mantine-color-dark-6);\n }\n}\n\n.item--default {\n border-bottom: 1px solid var(--item-border-color);\n}\n\n.item--contained {\n border: 1px solid var(--item-border-color);\n transition: background-color 150ms ease;\n\n &:where([data-active]) {\n background-color: var(--item-filled-color);\n }\n\n &:first-of-type {\n border-start-start-radius: var(--accordion-radius);\n border-start-end-radius: var(--accordion-radius);\n\n & > [data-accordion-control] {\n border-start-start-radius: var(--accordion-radius);\n border-start-end-radius: var(--accordion-radius);\n }\n }\n\n &:last-of-type {\n border-end-start-radius: var(--accordion-radius);\n border-end-end-radius: var(--accordion-radius);\n\n & > [data-accordion-control] {\n border-end-start-radius: var(--accordion-radius);\n border-end-end-radius: var(--accordion-radius);\n }\n }\n\n & + & {\n border-top: 0;\n }\n}\n\n.item--filled {\n border-radius: var(--accordion-radius);\n\n &:where([data-active]) {\n background-color: var(--item-filled-color);\n }\n}\n\n.item--separated {\n background-color: var(--item-filled-color);\n border-radius: var(--accordion-radius);\n border: 1px solid transparent;\n transition: background-color 150ms ease;\n\n &[data-active] {\n border-color: var(--item-border-color);\n\n @mixin where-light {\n background-color: var(--mantine-color-white);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-7);\n }\n }\n\n & + & {\n margin-top: var(--mantine-spacing-md);\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Accordion.module.mjs","names":[],"sources":["../../../src/components/Accordion/Accordion.module.css"],"sourcesContent":[".root {\n --accordion-radius: var(--mantine-radius-default);\n}\n\n.panel {\n overflow-wrap: break-word;\n}\n\n.content {\n padding: var(--mantine-spacing-md);\n padding-top: calc(var(--mantine-spacing-xs) / 2);\n}\n\n.itemTitle {\n margin: 0;\n padding: 0;\n width: 100%;\n}\n\n.control {\n width: 100%;\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n padding-inline: var(--mantine-spacing-md);\n opacity: 1;\n cursor: pointer;\n background-color: transparent;\n color: var(--mantine-color-bright);\n\n &:where([data-chevron-position='left']) {\n flex-direction: row;\n padding-inline-start: 0;\n }\n\n &:where(:disabled, [data-disabled]) {\n opacity: 0.4;\n cursor: not-allowed;\n }\n}\n\n.control--default,\n.control--contained {\n &:where(:not(:disabled, [data-disabled])) {\n @mixin hover {\n @mixin where-light {\n background-color: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-6);\n }\n }\n }\n}\n\n.label {\n color: inherit;\n font-weight: var(--mantine-font-weight-regular);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n padding-top: var(--mantine-spacing-sm);\n padding-bottom: var(--mantine-spacing-sm);\n}\n\n.chevron {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n transition: transform var(--accordion-transition-duration, 200ms) ease;\n width: var(--accordion-chevron-size, rem(15px));\n min-width: var(--accordion-chevron-size, rem(15px));\n transform: rotate(0deg);\n\n &:where([data-rotate]) {\n transform: rotate(180deg);\n }\n\n &:where([data-position='left']) {\n margin-inline-end: var(--mantine-spacing-md);\n margin-inline-start: var(--mantine-spacing-md);\n }\n}\n\n.icon {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-inline-end: var(--mantine-spacing-sm);\n\n &:where([data-chevron-position='left']) {\n margin-inline-end: 0;\n margin-inline-start: var(--mantine-spacing-lg);\n }\n}\n\n.item {\n @mixin where-light {\n --item-border-color: var(--mantine-color-gray-3);\n --item-filled-color: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n --item-border-color: var(--mantine-color-dark-4);\n --item-filled-color: var(--mantine-color-dark-6);\n }\n}\n\n.item--default {\n border-bottom: 1px solid var(--item-border-color);\n}\n\n.item--contained {\n border: 1px solid var(--item-border-color);\n transition: background-color 150ms ease;\n\n &:where([data-active]) {\n background-color: var(--item-filled-color);\n }\n\n &:first-of-type {\n border-start-start-radius: var(--accordion-radius);\n border-start-end-radius: var(--accordion-radius);\n\n & > [data-accordion-control],\n & > .itemTitle > [data-accordion-control] {\n border-start-start-radius: var(--accordion-radius);\n border-start-end-radius: var(--accordion-radius);\n }\n }\n\n &:last-of-type {\n border-end-start-radius: var(--accordion-radius);\n border-end-end-radius: var(--accordion-radius);\n\n & > [data-accordion-control],\n & > .itemTitle > [data-accordion-control] {\n border-end-start-radius: var(--accordion-radius);\n border-end-end-radius: var(--accordion-radius);\n }\n }\n\n & + & {\n border-top: 0;\n }\n}\n\n.item--filled {\n border-radius: var(--accordion-radius);\n\n &:where([data-active]) {\n background-color: var(--item-filled-color);\n }\n}\n\n.item--separated {\n background-color: var(--item-filled-color);\n border-radius: var(--accordion-radius);\n border: 1px solid transparent;\n transition: background-color 150ms ease;\n\n &[data-active] {\n border-color: var(--item-border-color);\n\n @mixin where-light {\n background-color: var(--mantine-color-white);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-7);\n }\n }\n\n & + & {\n margin-top: var(--mantine-spacing-md);\n }\n}\n"],"mappings":""}
|
|
@@ -48,9 +48,7 @@ function useCombobox({ defaultOpened, opened, onOpenedChange, onDropdownClose, o
|
|
|
48
48
|
]);
|
|
49
49
|
const clearSelectedItem = useCallback(() => {
|
|
50
50
|
const root = getRootElement(targetRef.current);
|
|
51
|
-
|
|
52
|
-
selected?.removeAttribute("data-combobox-selected");
|
|
53
|
-
selected?.removeAttribute("aria-selected");
|
|
51
|
+
findElementBySelector(`#${listId.current} [data-combobox-selected]`, root)?.removeAttribute("data-combobox-selected");
|
|
54
52
|
}, []);
|
|
55
53
|
const selectOption = useCallback((index) => {
|
|
56
54
|
const root = getRootElement(targetRef.current);
|
|
@@ -62,7 +60,6 @@ function useCombobox({ defaultOpened, opened, onOpenedChange, onDropdownClose, o
|
|
|
62
60
|
if (items?.[nextIndex] && !items[nextIndex].hasAttribute("data-combobox-disabled")) {
|
|
63
61
|
clearSelectedItem();
|
|
64
62
|
items[nextIndex].setAttribute("data-combobox-selected", "true");
|
|
65
|
-
items[nextIndex].setAttribute("aria-selected", "true");
|
|
66
63
|
items[nextIndex].scrollIntoView({
|
|
67
64
|
block: "nearest",
|
|
68
65
|
behavior: scrollBehavior
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-combobox.mjs","names":[],"sources":["../../../../src/components/Combobox/use-combobox/use-combobox.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport { findElementBySelector, findElementsBySelector, getRootElement } from '../../../core/utils';\nimport { getFirstIndex, getNextIndex, getPreviousIndex } from './get-index/get-index';\n\nexport type ComboboxDropdownEventSource = 'keyboard' | 'mouse' | 'unknown';\n\nexport interface ComboboxStore {\n /** Current dropdown opened state */\n dropdownOpened: boolean;\n\n /** Opens dropdown */\n openDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Closes dropdown */\n closeDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Toggles dropdown opened state */\n toggleDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Selected option index ref */\n selectedOptionIndex: number;\n\n /** Returns currently selected option index or `-1` if none of the options is selected */\n getSelectedOptionIndex: () => number;\n\n /** Selects `Combobox.Option` by index */\n selectOption: (index: number) => void;\n\n /** Selects first `Combobox.Option` with `active` prop.\n * If there are no such options, the function does nothing.\n */\n selectActiveOption: () => string | null;\n\n /** Selects first `Combobox.Option` that is not disabled.\n * If there are no such options, the function does nothing.\n * */\n selectFirstOption: () => string | null;\n\n /** Selects next `Combobox.Option` that is not disabled.\n * If the current option is the last one, the function selects first option, if `loop` is true.\n */\n selectNextOption: () => string | null;\n\n /** Selects previous `Combobox.Option` that is not disabled.\n * If the current option is the first one, the function selects last option, if `loop` is true.\n * */\n selectPreviousOption: () => string | null;\n\n /** Resets selected option index to -1, removes `data-combobox-selected` from selected option */\n resetSelectedOption: () => void;\n\n /** Triggers `onClick` event of selected option.\n * If there is no selected option, the function does nothing.\n */\n clickSelectedOption: () => void;\n\n /** Updates selected option index to currently selected or active option.\n * The function is required to be used with searchable components to update selected option index\n * when options list changes based on search query.\n */\n updateSelectedOptionIndex: (\n target?: 'active' | 'selected' | number,\n options?: { scrollIntoView?: boolean }\n ) => void;\n\n /** List id, used for `aria-*` attributes */\n listId: string | null;\n\n /** Sets list id */\n setListId: (id: string) => void;\n\n /** Ref of `Combobox.Search` input */\n searchRef: React.RefObject<HTMLInputElement | null>;\n\n /** Moves focus to `Combobox.Search` input */\n focusSearchInput: () => void;\n\n /** Ref of the target element */\n targetRef: React.RefObject<HTMLElement | null>;\n\n /** Moves focus to the target element */\n focusTarget: () => void;\n}\n\nexport interface UseComboboxOptions {\n /** Default value for `dropdownOpened`, `false` by default. Used when the component is uncontrolled */\n defaultOpened?: boolean;\n\n /** Controlled `dropdownOpened` state. When set, the dropdown opened state is controlled by the parent component */\n opened?: boolean;\n\n /** Called when `dropdownOpened` state changes. Required for controlled mode */\n onOpenedChange?: (opened: boolean) => void;\n\n /** Called when dropdown closes with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown closure */\n onDropdownClose?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Called when dropdown opens with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown opening */\n onDropdownOpen?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Determines whether arrow key presses should loop through items (first to last and last to first). Defaults to `true` */\n loop?: boolean;\n\n /** `behavior` passed down to `element.scrollIntoView`. Controls the scrolling animation when options are scrolled into view. Defaults to `'instant'` */\n scrollBehavior?: ScrollBehavior;\n}\n\nexport function useCombobox({\n defaultOpened,\n opened,\n onOpenedChange,\n onDropdownClose,\n onDropdownOpen,\n loop = true,\n scrollBehavior = 'instant',\n}: UseComboboxOptions = {}): ComboboxStore {\n const [dropdownOpened, setDropdownOpened] = useUncontrolled({\n value: opened,\n defaultValue: defaultOpened,\n finalValue: false,\n onChange: onOpenedChange,\n });\n\n const listId = useRef<string | null>(null);\n const selectedOptionIndex = useRef<number>(-1);\n const searchRef = useRef<HTMLInputElement | null>(null);\n const targetRef = useRef<HTMLElement | null>(null);\n const focusSearchTimeout = useRef<number>(-1);\n const focusTargetTimeout = useRef<number>(-1);\n const selectedIndexUpdateTimeout = useRef<number>(-1);\n\n const openDropdown: ComboboxStore['openDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (!dropdownOpened) {\n setDropdownOpened(true);\n onDropdownOpen?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownOpen, dropdownOpened]\n );\n\n const closeDropdown: ComboboxStore['closeDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n setDropdownOpened(false);\n onDropdownClose?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownClose, dropdownOpened]\n );\n\n const toggleDropdown: ComboboxStore['toggleDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n closeDropdown(eventSource);\n } else {\n openDropdown(eventSource);\n }\n },\n [closeDropdown, openDropdown, dropdownOpened]\n );\n\n const clearSelectedItem = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const selected = findElementBySelector(`#${listId.current} [data-combobox-selected]`, root);\n selected?.removeAttribute('data-combobox-selected');\n selected?.removeAttribute('aria-selected');\n }, []);\n\n const selectOption = useCallback(\n (index: number) => {\n const root = getRootElement(targetRef.current);\n const list = findElementBySelector(`#${listId.current!}`, root);\n const items = list\n ? findElementsBySelector<HTMLDivElement>('[data-combobox-option]', list)\n : null;\n\n if (!items) {\n return null;\n }\n\n const nextIndex = index >= items!.length ? 0 : index < 0 ? items!.length - 1 : index;\n selectedOptionIndex.current = nextIndex;\n\n if (items?.[nextIndex] && !items[nextIndex].hasAttribute('data-combobox-disabled')) {\n clearSelectedItem();\n items[nextIndex].setAttribute('data-combobox-selected', 'true');\n items[nextIndex].setAttribute('aria-selected', 'true');\n items[nextIndex].scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n return items[nextIndex].id;\n }\n\n return null;\n },\n [scrollBehavior, clearSelectedItem]\n );\n\n const selectActiveOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const activeOption = findElementBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-active]`,\n root\n );\n\n if (activeOption) {\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option === activeOption);\n return selectOption(index);\n }\n\n return selectOption(0);\n }, [selectOption]);\n\n const selectNextOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getNextIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectPreviousOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getPreviousIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectFirstOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getFirstIndex(items));\n }, [selectOption]);\n\n const updateSelectedOptionIndex: ComboboxStore['updateSelectedOptionIndex'] = useCallback(\n (target = 'selected', options) => {\n if (typeof target === 'number') {\n selectedOptionIndex.current = target;\n const root = getRootElement(targetRef.current);\n\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n\n if (options?.scrollIntoView) {\n items[target]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n return;\n }\n\n selectedIndexUpdateTimeout.current = window.setTimeout(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option.hasAttribute(`data-combobox-${target}`));\n\n selectedOptionIndex.current = index;\n\n if (options?.scrollIntoView) {\n items[index]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n }, 0);\n },\n []\n );\n\n const resetSelectedOption = useCallback(() => {\n selectedOptionIndex.current = -1;\n clearSelectedItem();\n }, [clearSelectedItem]);\n\n const clickSelectedOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const item = items?.[selectedOptionIndex.current];\n item?.click();\n }, []);\n\n const setListId = useCallback((id: string) => {\n listId.current = id;\n }, []);\n\n const focusSearchInput = useCallback(() => {\n focusSearchTimeout.current = window.setTimeout(() => searchRef.current?.focus(), 0);\n }, []);\n\n const focusTarget = useCallback(() => {\n focusTargetTimeout.current = window.setTimeout(() => targetRef.current?.focus(), 0);\n }, []);\n\n const getSelectedOptionIndex = useCallback(() => selectedOptionIndex.current, []);\n\n useEffect(\n () => () => {\n window.clearTimeout(focusSearchTimeout.current);\n window.clearTimeout(focusTargetTimeout.current);\n window.clearTimeout(selectedIndexUpdateTimeout.current);\n },\n []\n );\n\n return {\n dropdownOpened,\n openDropdown,\n closeDropdown,\n toggleDropdown,\n\n selectedOptionIndex: selectedOptionIndex.current,\n getSelectedOptionIndex,\n selectOption,\n selectFirstOption,\n selectActiveOption,\n selectNextOption,\n selectPreviousOption,\n resetSelectedOption,\n updateSelectedOptionIndex,\n\n listId: listId.current,\n setListId,\n clickSelectedOption,\n\n searchRef,\n focusSearchInput,\n\n targetRef,\n focusTarget,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-combobox.mjs","names":[],"sources":["../../../../src/components/Combobox/use-combobox/use-combobox.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport { findElementBySelector, findElementsBySelector, getRootElement } from '../../../core/utils';\nimport { getFirstIndex, getNextIndex, getPreviousIndex } from './get-index/get-index';\n\nexport type ComboboxDropdownEventSource = 'keyboard' | 'mouse' | 'unknown';\n\nexport interface ComboboxStore {\n /** Current dropdown opened state */\n dropdownOpened: boolean;\n\n /** Opens dropdown */\n openDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Closes dropdown */\n closeDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Toggles dropdown opened state */\n toggleDropdown: (eventSource?: ComboboxDropdownEventSource) => void;\n\n /** Selected option index ref */\n selectedOptionIndex: number;\n\n /** Returns currently selected option index or `-1` if none of the options is selected */\n getSelectedOptionIndex: () => number;\n\n /** Selects `Combobox.Option` by index */\n selectOption: (index: number) => void;\n\n /** Selects first `Combobox.Option` with `active` prop.\n * If there are no such options, the function does nothing.\n */\n selectActiveOption: () => string | null;\n\n /** Selects first `Combobox.Option` that is not disabled.\n * If there are no such options, the function does nothing.\n * */\n selectFirstOption: () => string | null;\n\n /** Selects next `Combobox.Option` that is not disabled.\n * If the current option is the last one, the function selects first option, if `loop` is true.\n */\n selectNextOption: () => string | null;\n\n /** Selects previous `Combobox.Option` that is not disabled.\n * If the current option is the first one, the function selects last option, if `loop` is true.\n * */\n selectPreviousOption: () => string | null;\n\n /** Resets selected option index to -1, removes `data-combobox-selected` from selected option */\n resetSelectedOption: () => void;\n\n /** Triggers `onClick` event of selected option.\n * If there is no selected option, the function does nothing.\n */\n clickSelectedOption: () => void;\n\n /** Updates selected option index to currently selected or active option.\n * The function is required to be used with searchable components to update selected option index\n * when options list changes based on search query.\n */\n updateSelectedOptionIndex: (\n target?: 'active' | 'selected' | number,\n options?: { scrollIntoView?: boolean }\n ) => void;\n\n /** List id, used for `aria-*` attributes */\n listId: string | null;\n\n /** Sets list id */\n setListId: (id: string) => void;\n\n /** Ref of `Combobox.Search` input */\n searchRef: React.RefObject<HTMLInputElement | null>;\n\n /** Moves focus to `Combobox.Search` input */\n focusSearchInput: () => void;\n\n /** Ref of the target element */\n targetRef: React.RefObject<HTMLElement | null>;\n\n /** Moves focus to the target element */\n focusTarget: () => void;\n}\n\nexport interface UseComboboxOptions {\n /** Default value for `dropdownOpened`, `false` by default. Used when the component is uncontrolled */\n defaultOpened?: boolean;\n\n /** Controlled `dropdownOpened` state. When set, the dropdown opened state is controlled by the parent component */\n opened?: boolean;\n\n /** Called when `dropdownOpened` state changes. Required for controlled mode */\n onOpenedChange?: (opened: boolean) => void;\n\n /** Called when dropdown closes with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown closure */\n onDropdownClose?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Called when dropdown opens with event source: keyboard, mouse or unknown. Useful for analytics or side effects on dropdown opening */\n onDropdownOpen?: (eventSource: ComboboxDropdownEventSource) => void;\n\n /** Determines whether arrow key presses should loop through items (first to last and last to first). Defaults to `true` */\n loop?: boolean;\n\n /** `behavior` passed down to `element.scrollIntoView`. Controls the scrolling animation when options are scrolled into view. Defaults to `'instant'` */\n scrollBehavior?: ScrollBehavior;\n}\n\nexport function useCombobox({\n defaultOpened,\n opened,\n onOpenedChange,\n onDropdownClose,\n onDropdownOpen,\n loop = true,\n scrollBehavior = 'instant',\n}: UseComboboxOptions = {}): ComboboxStore {\n const [dropdownOpened, setDropdownOpened] = useUncontrolled({\n value: opened,\n defaultValue: defaultOpened,\n finalValue: false,\n onChange: onOpenedChange,\n });\n\n const listId = useRef<string | null>(null);\n const selectedOptionIndex = useRef<number>(-1);\n const searchRef = useRef<HTMLInputElement | null>(null);\n const targetRef = useRef<HTMLElement | null>(null);\n const focusSearchTimeout = useRef<number>(-1);\n const focusTargetTimeout = useRef<number>(-1);\n const selectedIndexUpdateTimeout = useRef<number>(-1);\n\n const openDropdown: ComboboxStore['openDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (!dropdownOpened) {\n setDropdownOpened(true);\n onDropdownOpen?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownOpen, dropdownOpened]\n );\n\n const closeDropdown: ComboboxStore['closeDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n setDropdownOpened(false);\n onDropdownClose?.(eventSource);\n }\n },\n [setDropdownOpened, onDropdownClose, dropdownOpened]\n );\n\n const toggleDropdown: ComboboxStore['toggleDropdown'] = useCallback(\n (eventSource = 'unknown') => {\n if (dropdownOpened) {\n closeDropdown(eventSource);\n } else {\n openDropdown(eventSource);\n }\n },\n [closeDropdown, openDropdown, dropdownOpened]\n );\n\n const clearSelectedItem = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const selected = findElementBySelector(`#${listId.current} [data-combobox-selected]`, root);\n selected?.removeAttribute('data-combobox-selected');\n }, []);\n\n const selectOption = useCallback(\n (index: number) => {\n const root = getRootElement(targetRef.current);\n const list = findElementBySelector(`#${listId.current!}`, root);\n const items = list\n ? findElementsBySelector<HTMLDivElement>('[data-combobox-option]', list)\n : null;\n\n if (!items) {\n return null;\n }\n\n const nextIndex = index >= items!.length ? 0 : index < 0 ? items!.length - 1 : index;\n selectedOptionIndex.current = nextIndex;\n\n if (items?.[nextIndex] && !items[nextIndex].hasAttribute('data-combobox-disabled')) {\n clearSelectedItem();\n items[nextIndex].setAttribute('data-combobox-selected', 'true');\n items[nextIndex].scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n return items[nextIndex].id;\n }\n\n return null;\n },\n [scrollBehavior, clearSelectedItem]\n );\n\n const selectActiveOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const activeOption = findElementBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-active]`,\n root\n );\n\n if (activeOption) {\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option === activeOption);\n return selectOption(index);\n }\n\n return selectOption(0);\n }, [selectOption]);\n\n const selectNextOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getNextIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectPreviousOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getPreviousIndex(selectedOptionIndex.current, items, loop));\n }, [selectOption, loop]);\n\n const selectFirstOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n return selectOption(getFirstIndex(items));\n }, [selectOption]);\n\n const updateSelectedOptionIndex: ComboboxStore['updateSelectedOptionIndex'] = useCallback(\n (target = 'selected', options) => {\n if (typeof target === 'number') {\n selectedOptionIndex.current = target;\n const root = getRootElement(targetRef.current);\n\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n\n if (options?.scrollIntoView) {\n items[target]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n return;\n }\n\n selectedIndexUpdateTimeout.current = window.setTimeout(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const index = items.findIndex((option) => option.hasAttribute(`data-combobox-${target}`));\n\n selectedOptionIndex.current = index;\n\n if (options?.scrollIntoView) {\n items[index]?.scrollIntoView({ block: 'nearest', behavior: scrollBehavior });\n }\n }, 0);\n },\n []\n );\n\n const resetSelectedOption = useCallback(() => {\n selectedOptionIndex.current = -1;\n clearSelectedItem();\n }, [clearSelectedItem]);\n\n const clickSelectedOption = useCallback(() => {\n const root = getRootElement(targetRef.current);\n const items = findElementsBySelector<HTMLDivElement>(\n `#${listId.current} [data-combobox-option]`,\n root\n );\n const item = items?.[selectedOptionIndex.current];\n item?.click();\n }, []);\n\n const setListId = useCallback((id: string) => {\n listId.current = id;\n }, []);\n\n const focusSearchInput = useCallback(() => {\n focusSearchTimeout.current = window.setTimeout(() => searchRef.current?.focus(), 0);\n }, []);\n\n const focusTarget = useCallback(() => {\n focusTargetTimeout.current = window.setTimeout(() => targetRef.current?.focus(), 0);\n }, []);\n\n const getSelectedOptionIndex = useCallback(() => selectedOptionIndex.current, []);\n\n useEffect(\n () => () => {\n window.clearTimeout(focusSearchTimeout.current);\n window.clearTimeout(focusTargetTimeout.current);\n window.clearTimeout(selectedIndexUpdateTimeout.current);\n },\n []\n );\n\n return {\n dropdownOpened,\n openDropdown,\n closeDropdown,\n toggleDropdown,\n\n selectedOptionIndex: selectedOptionIndex.current,\n getSelectedOptionIndex,\n selectOption,\n selectFirstOption,\n selectActiveOption,\n selectNextOption,\n selectPreviousOption,\n resetSelectedOption,\n updateSelectedOptionIndex,\n\n listId: listId.current,\n setListId,\n clickSelectedOption,\n\n searchRef,\n focusSearchInput,\n\n targetRef,\n focusTarget,\n };\n}\n"],"mappings":"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"}
|
|
@@ -125,7 +125,6 @@ const ComboboxPopover = genericFactory((_props) => {
|
|
|
125
125
|
onDropdownClose: () => {
|
|
126
126
|
onDropdownClose?.();
|
|
127
127
|
combobox.resetSelectedOption();
|
|
128
|
-
if (searchable) combobox.focusTarget();
|
|
129
128
|
}
|
|
130
129
|
});
|
|
131
130
|
const handleSearchChange = (val) => {
|
|
@@ -160,6 +159,7 @@ const ComboboxPopover = genericFactory((_props) => {
|
|
|
160
159
|
unstyled,
|
|
161
160
|
attributes,
|
|
162
161
|
onOptionSubmit: handleOptionSubmit,
|
|
162
|
+
returnFocus: true,
|
|
163
163
|
...comboboxProps,
|
|
164
164
|
...others,
|
|
165
165
|
children: [children, searchable ? /* @__PURE__ */ jsx(SearchableDropdown, {
|
|
@@ -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 | '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":";;;;;;;;;;;;;;;;;;;;;AAkCA,SAAS,eAAe,OAAmD,aAAwB;CACjG,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS,WAAW,IAAI,UAAU;AACxE;AAYA,SAAS,OAAO,EACd,MACA,eACA,mBACA,OACA,mBACA,UACA,gBACc;CACd,IAAI,eAAe,IAAI,GAAG;EACxB,MAAM,UAAU,KAAK,MAAM,KAAK,SAC9B,oBAAC,QAAD;GACE,MAAM;GACC;GAEG;GACK;GACI;GACA;GACL;EACf,GANM,GAAG,KAAK,OAMd,CACF;EACD,OAAO,oBAAC,SAAS,OAAV;GAAgB,OAAO,KAAK;GAAQ,UAAA;EAAwB,CAAA;CACrE;CAEA,MAAM,UAAU,eAAe,OAAO,KAAK,KAAK;CAChD,MAAM,QACJ,kBACC,UACC,oBAAC,WAAD,EAAW,WAAWA,wBAAgB,yBAA2B,CAAA,IAC/D,oBACF,oBAAC,OAAD,EAAK,WAAWA,wBAAgB,gCAAkC,CAAA,IAChE;CAEN,MAAM,iBACJ,qBAAA,YAAA,EAAA,UAAA;EACG,sBAAsB,UAAU;EACjC,oBAAC,QAAD,EAAA,UAAO,KAAK,MAAY,CAAA;EACvB,sBAAsB,WAAW;CAClC,EAAA,CAAA;CAGJ,OACE,oBAAC,SAAS,QAAV;EACE,OAAO,KAAK;EACZ,UAAU,KAAK;EACf,WAAW,GAAG,GAAGA,wBAAgB,wBAAwB,CAAC,SAAS,CAAC;EACpE,gBAAc,sBAAsB,WAAW,KAAA;EAC/C,gBAAc,WAAW,KAAA;EACzB,iBAAe;EACf,QAAQ;EAEP,UAAA,OAAO,iBAAiB,aACrB,aAAa;GAAE,QAAQ;GAAM;EAAQ,CAAC,IACtC;CACW,CAAA;AAErB;AAoBA,SAAS,mBAAmB,EAC1B,MACA,QACA,QACA,OACA,qBACA,iBAAiB,MACjB,mBACA,OACA,mBACA,gBAAgB,OAChB,oBAAoB,OACpB,UACA,cACA,iBACA,kBAC0B;CAC1B,MAAM,gBAAgB,UAAU,qBAAA,CAAsB;EACpD,SAAS;EACT;EACA,OAAO,SAAS;CAClB,CAAC;CACD,MAAM,UAAU,oBAAoB,YAAY;CAEhD,MAAM,UAAU,aAAa,KAAK,MAAM,UACtC,oBAAC,QAAD;EACE,MAAM;EAMS;EACI;EACZ;EACY;EACT;EACI;CACf,GAVG,eAAe,IAAI,IACf,SAAS,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,UACvD,GAAG,KAAK,OAQf,CACF;CAED,OACE,qBAAC,SAAS,UAAV;EAAmB,iBAAA;EAAnB,UAAA,CACE,oBAAC,SAAS,QAAV;GAAiB,OAAO;GAAQ,UAAU;GAAgB,aAAY;EAAa,CAAA,GACnF,qBAAC,SAAS,SAAV,EAAA,UAAA,CACG,iBACC,oBAAC,WAAW,UAAZ;GACE,KAAK,qBAAqB;GAC1B,MAAK;GACL,eAAc;GACd,kBAAiB;GACjB,GAAI;GAEH,UAAA;EACkB,CAAA,IAErB,SAED,WAAW,uBAAuB,oBAAC,SAAS,OAAV,EAAA,UAAiB,oBAAoC,CAAA,CACxE,EAAA,CAAA,CACD;;AAEvB;AAqHA,MAAM,eAAe;CACnB,eAAe;CACf,eAAe;CACf,mBAAmB;CACnB,0BAA0B;AAC5B;AAEA,MAAa,kBAAkB,gBAAwC,WAAW;CAChF,MAAM,QAAQ,SAAS,mBAAmB,cAAqB,MAAM;CACrE,MAAM,EACJ,YACA,QACA,UACA,MACA,UACA,UACA,OACA,cACA,UACA,MACA,gBACA,uBACA,gBACA,iBACA,gBACA,eACA,QACA,OACA,gBACA,mBACA,iCACA,eACA,mBACA,mBACA,qBACA,YACA,aACA,oBACA,gBACA,eACA,cACA,iBACA,kBACA,MACA,MACA,0BACA,YACA,GAAG,WACD;CAEJ,MAAM,aAAa,cAAc,sBAAsB,IAAI,GAAG,CAAC,IAAI,CAAC;CACpE,MAAM,gBAAgB,cAAc,iBAAiB,UAAU,GAAG,CAAC,UAAU,CAAC;CAE9E,MAAM,CAAC,QAAQ,YAAY,gBAAgB;EACzC;EACA;EACA,YAAY,WAAY,CAAC,IAAY;EACrC;CACF,CAAC;CAED,MAAM,CAAC,cAAc,kBAAkB,gBAAgB;EACrD,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU;CACZ,CAAC;CAED,MAAM,WAAW,YAAY;EAC3B,QAAQ;EACR,eAAe;EACf,sBAAsB;GACpB,iBAAiB;GACjB,IAAI,YACF,SAAS,iBAAiB;GAE5B,IAAI,iCACF,SAAS,kBAAkB;EAE/B;EACA,uBAAuB;GACrB,kBAAkB;GAClB,SAAS,oBAAoB;GAC7B,IAAI,YACF,SAAS,YAAY;EAEzB;CACF,CAAC;CAED,MAAM,sBAAsB,QAAgB;EAC1C,eAAe,GAAG;EAClB,SAAS,oBAAoB;CAC/B;CAEA,MAAM,EAAE,oBAAoB,mBAAmB,qBAA6C;EAC1F;EACA;EACA;CACF,CAAC;CAED,MAAM,sBAAsB,QAAgB;EAC1C,iBAAiB,GAAU;EAC3B,MAAM,SAAS,cAAc;EAE7B,IAAI,UAAU;GACZ,MAAM,eAAe,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;GACvD,IAAI,aAAa,SAAS,OAAO,KAAK,GACpC,SAAS,aAAa,QAAQ,MAAW,MAAM,OAAO,KAAK,CAAQ;QAEnE,SAAS,CAAC,GAAG,cAAc,OAAO,KAAK,CAAQ;GAEjD,SAAS,0BAA0B,UAAU;EAC/C,OAAO;GACL,MAAM,YAAY,iBAAiB,GAAG,OAAO,YAAY,GAAG,WAAW,OAAO,OAAO;GACrF,SAAS,SAAgB;GACzB,SAAS,cAAc;EACzB;EAEA,IAAI,YACF,mBAAmB,EAAE;CAEzB;CAEA,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,UAAD;EACE,OAAO;EACP,kBAAiB;EACjB,YAAY;EACZ,QAAQ;EACE;EACE;EACZ,gBAAgB;EAChB,GAAI;EACJ,GAAI;EATN,UAAA,CAWG,UACA,aACC,oBAAC,oBAAD;GACE,MAAM;GACE;GACR,QAAQ;GACD;GACc;GACL;GACG;GACnB,OAAO;GACY;GACJ;GACI;GACT;GACI;GACG;GACjB,iBAAiB,UAAU;IACzB,mBAAmB,MAAM,cAAc,KAAK;GAC9C;EACD,CAAA,IAED,oBAAC,iBAAD;GACE,MAAM;GACE;GACR,QAAQ,KAAA;GACD;GACP,iBAAiB,CAAC;GACF;GACG;GACnB,eAAe;GACf,OAAO;GACY;GACJ;GACI;GACE;GACX;GACI;GACG;GACjB,SAAS,KAAA;GACT,cAAY,KAAA;EACb,CAAA,CAEK;CACV,CAAA,GAAA,oBAAC,SAAS,aAAV;EACQ;EACN,OAAO;EACD;EACN,eAAe;EACf,GAAI;CACL,CAAA,CACD,EAAA,CAAA;AAEN,CAAC;AAED,gBAAgB,UAAU,SAAS;AACnC,gBAAgB,cAAc;AAC9B,gBAAgB,SAAS"}
|
|
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 },\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 returnFocus\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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"}
|
|
@@ -33,7 +33,8 @@ const Drawer = factory((_props) => {
|
|
|
33
33
|
const stackProps = ctx && stackId ? {
|
|
34
34
|
closeOnEscape: ctx.currentId === stackId,
|
|
35
35
|
trapFocus: ctx.currentId === stackId,
|
|
36
|
-
zIndex: ctx.getZIndex(stackId)
|
|
36
|
+
zIndex: ctx.getZIndex(stackId),
|
|
37
|
+
__handledEscapeEvents: ctx.handledEscapeEvents
|
|
37
38
|
} : {};
|
|
38
39
|
const overlayVisible = withOverlay === false ? false : stackId && ctx ? ctx.currentId === stackId : opened;
|
|
39
40
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.mjs","names":["classes"],"sources":["../../../src/components/Drawer/Drawer.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\nimport { factory, Factory, getDefaultZIndex, useProps } from '../../core';\nimport { ModalBaseCloseButtonProps, ModalBaseOverlayProps } from '../ModalBase';\nimport { DrawerBody } from './DrawerBody';\nimport { DrawerCloseButton } from './DrawerCloseButton';\nimport { DrawerContent } from './DrawerContent';\nimport { DrawerHeader } from './DrawerHeader';\nimport { DrawerOverlay } from './DrawerOverlay';\nimport {\n DrawerRoot,\n DrawerRootCssVariables,\n DrawerRootProps,\n DrawerRootStylesNames,\n} from './DrawerRoot';\nimport { DrawerStack, DrawerStackContext } from './DrawerStack';\nimport { DrawerTitle } from './DrawerTitle';\nimport classes from './Drawer.module.css';\n\nexport type DrawerStylesNames = DrawerRootStylesNames;\nexport type DrawerCssVariables = DrawerRootCssVariables;\n\nexport interface DrawerProps extends DrawerRootProps {\n /** Drawer title */\n title?: React.ReactNode;\n\n /** If set, the overlay is displayed @default true */\n withOverlay?: boolean;\n\n /** Props passed down to the `Overlay` component, can be used to configure opacity, `background-color`, styles and other properties */\n overlayProps?: ModalBaseOverlayProps;\n\n /** Drawer content */\n children?: React.ReactNode;\n\n /** If set, the close button is displayed @default true */\n withCloseButton?: boolean;\n\n /** Props passed down to the close button */\n closeButtonProps?: ModalBaseCloseButtonProps;\n\n /** Id of the drawer in the `Drawer.Stack` */\n stackId?: string;\n}\n\nexport type DrawerFactory = Factory<{\n props: DrawerProps;\n ref: HTMLDivElement;\n stylesNames: DrawerStylesNames;\n vars: DrawerCssVariables;\n staticComponents: {\n Root: typeof DrawerRoot;\n Overlay: typeof DrawerOverlay;\n Content: typeof DrawerContent;\n Body: typeof DrawerBody;\n Header: typeof DrawerHeader;\n Title: typeof DrawerTitle;\n CloseButton: typeof DrawerCloseButton;\n Stack: typeof DrawerStack;\n };\n}>;\n\nconst defaultProps = {\n closeOnClickOutside: true,\n withinPortal: true,\n lockScroll: true,\n trapFocus: true,\n returnFocus: true,\n closeOnEscape: true,\n keepMounted: false,\n zIndex: getDefaultZIndex('modal'),\n withOverlay: true,\n withCloseButton: true,\n} satisfies Partial<DrawerProps>;\n\nexport const Drawer = factory<DrawerFactory>((_props) => {\n const {\n title,\n withOverlay,\n overlayProps,\n withCloseButton,\n closeButtonProps,\n children,\n opened,\n stackId,\n zIndex,\n ...others\n } = useProps('Drawer', defaultProps, _props);\n\n const ctx = use(DrawerStackContext);\n const hasHeader = !!title || withCloseButton;\n const stackProps =\n ctx && stackId\n ? {\n closeOnEscape: ctx.currentId === stackId,\n trapFocus: ctx.currentId === stackId,\n zIndex: ctx.getZIndex(stackId),\n }\n : {};\n\n const overlayVisible =\n withOverlay === false ? false : stackId && ctx ? ctx.currentId === stackId : opened;\n\n useEffect(() => {\n if (ctx && stackId) {\n opened\n ? ctx.addModal(stackId, zIndex || getDefaultZIndex('modal'))\n : ctx.removeModal(stackId);\n }\n }, [opened, stackId, zIndex]);\n\n return (\n <DrawerRoot\n opened={opened}\n zIndex={ctx && stackId ? ctx.getZIndex(stackId) : zIndex}\n {...others}\n {...stackProps}\n >\n {withOverlay && (\n <DrawerOverlay\n visible={overlayVisible}\n transitionProps={ctx && stackId ? { duration: 0 } : undefined}\n {...overlayProps}\n />\n )}\n <DrawerContent __hidden={ctx && stackId && opened ? stackId !== ctx.currentId : false}>\n {hasHeader && (\n <DrawerHeader>\n {title && <DrawerTitle>{title}</DrawerTitle>}\n {withCloseButton && <DrawerCloseButton {...closeButtonProps} />}\n </DrawerHeader>\n )}\n\n <DrawerBody>{children}</DrawerBody>\n </DrawerContent>\n </DrawerRoot>\n );\n});\n\nDrawer.classes = classes;\nDrawer.displayName = '@mantine/core/Drawer';\nDrawer.Root = DrawerRoot;\nDrawer.Overlay = DrawerOverlay;\nDrawer.Content = DrawerContent;\nDrawer.Body = DrawerBody;\nDrawer.Header = DrawerHeader;\nDrawer.Title = DrawerTitle;\nDrawer.CloseButton = DrawerCloseButton;\nDrawer.Stack = DrawerStack;\n"],"mappings":";;;;;;;;;;;;;;;;AA6DA,MAAM,eAAe;CACnB,qBAAqB;CACrB,cAAc;CACd,YAAY;CACZ,WAAW;CACX,aAAa;CACb,eAAe;CACf,aAAa;CACb,QAAQ,iBAAiB,OAAO;CAChC,aAAa;CACb,iBAAiB;AACnB;AAEA,MAAa,SAAS,SAAwB,WAAW;CACvD,MAAM,EACJ,OACA,aACA,cACA,iBACA,kBACA,UACA,QACA,SACA,QACA,GAAG,WACD,SAAS,UAAU,cAAc,MAAM;CAE3C,MAAM,MAAM,IAAI,kBAAkB;CAClC,MAAM,YAAY,CAAC,CAAC,SAAS;CAC7B,MAAM,aACJ,OAAO,UACH;EACE,eAAe,IAAI,cAAc;EACjC,WAAW,IAAI,cAAc;EAC7B,QAAQ,IAAI,UAAU,OAAO;
|
|
1
|
+
{"version":3,"file":"Drawer.mjs","names":["classes"],"sources":["../../../src/components/Drawer/Drawer.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\nimport { factory, Factory, getDefaultZIndex, useProps } from '../../core';\nimport { ModalBaseCloseButtonProps, ModalBaseOverlayProps } from '../ModalBase';\nimport { DrawerBody } from './DrawerBody';\nimport { DrawerCloseButton } from './DrawerCloseButton';\nimport { DrawerContent } from './DrawerContent';\nimport { DrawerHeader } from './DrawerHeader';\nimport { DrawerOverlay } from './DrawerOverlay';\nimport {\n DrawerRoot,\n DrawerRootCssVariables,\n DrawerRootProps,\n DrawerRootStylesNames,\n} from './DrawerRoot';\nimport { DrawerStack, DrawerStackContext } from './DrawerStack';\nimport { DrawerTitle } from './DrawerTitle';\nimport classes from './Drawer.module.css';\n\nexport type DrawerStylesNames = DrawerRootStylesNames;\nexport type DrawerCssVariables = DrawerRootCssVariables;\n\nexport interface DrawerProps extends DrawerRootProps {\n /** Drawer title */\n title?: React.ReactNode;\n\n /** If set, the overlay is displayed @default true */\n withOverlay?: boolean;\n\n /** Props passed down to the `Overlay` component, can be used to configure opacity, `background-color`, styles and other properties */\n overlayProps?: ModalBaseOverlayProps;\n\n /** Drawer content */\n children?: React.ReactNode;\n\n /** If set, the close button is displayed @default true */\n withCloseButton?: boolean;\n\n /** Props passed down to the close button */\n closeButtonProps?: ModalBaseCloseButtonProps;\n\n /** Id of the drawer in the `Drawer.Stack` */\n stackId?: string;\n}\n\nexport type DrawerFactory = Factory<{\n props: DrawerProps;\n ref: HTMLDivElement;\n stylesNames: DrawerStylesNames;\n vars: DrawerCssVariables;\n staticComponents: {\n Root: typeof DrawerRoot;\n Overlay: typeof DrawerOverlay;\n Content: typeof DrawerContent;\n Body: typeof DrawerBody;\n Header: typeof DrawerHeader;\n Title: typeof DrawerTitle;\n CloseButton: typeof DrawerCloseButton;\n Stack: typeof DrawerStack;\n };\n}>;\n\nconst defaultProps = {\n closeOnClickOutside: true,\n withinPortal: true,\n lockScroll: true,\n trapFocus: true,\n returnFocus: true,\n closeOnEscape: true,\n keepMounted: false,\n zIndex: getDefaultZIndex('modal'),\n withOverlay: true,\n withCloseButton: true,\n} satisfies Partial<DrawerProps>;\n\nexport const Drawer = factory<DrawerFactory>((_props) => {\n const {\n title,\n withOverlay,\n overlayProps,\n withCloseButton,\n closeButtonProps,\n children,\n opened,\n stackId,\n zIndex,\n ...others\n } = useProps('Drawer', defaultProps, _props);\n\n const ctx = use(DrawerStackContext);\n const hasHeader = !!title || withCloseButton;\n const stackProps =\n ctx && stackId\n ? {\n closeOnEscape: ctx.currentId === stackId,\n trapFocus: ctx.currentId === stackId,\n zIndex: ctx.getZIndex(stackId),\n __handledEscapeEvents: ctx.handledEscapeEvents,\n }\n : {};\n\n const overlayVisible =\n withOverlay === false ? false : stackId && ctx ? ctx.currentId === stackId : opened;\n\n useEffect(() => {\n if (ctx && stackId) {\n opened\n ? ctx.addModal(stackId, zIndex || getDefaultZIndex('modal'))\n : ctx.removeModal(stackId);\n }\n }, [opened, stackId, zIndex]);\n\n return (\n <DrawerRoot\n opened={opened}\n zIndex={ctx && stackId ? ctx.getZIndex(stackId) : zIndex}\n {...others}\n {...stackProps}\n >\n {withOverlay && (\n <DrawerOverlay\n visible={overlayVisible}\n transitionProps={ctx && stackId ? { duration: 0 } : undefined}\n {...overlayProps}\n />\n )}\n <DrawerContent __hidden={ctx && stackId && opened ? stackId !== ctx.currentId : false}>\n {hasHeader && (\n <DrawerHeader>\n {title && <DrawerTitle>{title}</DrawerTitle>}\n {withCloseButton && <DrawerCloseButton {...closeButtonProps} />}\n </DrawerHeader>\n )}\n\n <DrawerBody>{children}</DrawerBody>\n </DrawerContent>\n </DrawerRoot>\n );\n});\n\nDrawer.classes = classes;\nDrawer.displayName = '@mantine/core/Drawer';\nDrawer.Root = DrawerRoot;\nDrawer.Overlay = DrawerOverlay;\nDrawer.Content = DrawerContent;\nDrawer.Body = DrawerBody;\nDrawer.Header = DrawerHeader;\nDrawer.Title = DrawerTitle;\nDrawer.CloseButton = DrawerCloseButton;\nDrawer.Stack = DrawerStack;\n"],"mappings":";;;;;;;;;;;;;;;;AA6DA,MAAM,eAAe;CACnB,qBAAqB;CACrB,cAAc;CACd,YAAY;CACZ,WAAW;CACX,aAAa;CACb,eAAe;CACf,aAAa;CACb,QAAQ,iBAAiB,OAAO;CAChC,aAAa;CACb,iBAAiB;AACnB;AAEA,MAAa,SAAS,SAAwB,WAAW;CACvD,MAAM,EACJ,OACA,aACA,cACA,iBACA,kBACA,UACA,QACA,SACA,QACA,GAAG,WACD,SAAS,UAAU,cAAc,MAAM;CAE3C,MAAM,MAAM,IAAI,kBAAkB;CAClC,MAAM,YAAY,CAAC,CAAC,SAAS;CAC7B,MAAM,aACJ,OAAO,UACH;EACE,eAAe,IAAI,cAAc;EACjC,WAAW,IAAI,cAAc;EAC7B,QAAQ,IAAI,UAAU,OAAO;EAC7B,uBAAuB,IAAI;CAC7B,IACA,CAAC;CAEP,MAAM,iBACJ,gBAAgB,QAAQ,QAAQ,WAAW,MAAM,IAAI,cAAc,UAAU;CAE/E,gBAAgB;EACd,IAAI,OAAO,SACT,SACI,IAAI,SAAS,SAAS,UAAU,iBAAiB,OAAO,CAAC,IACzD,IAAI,YAAY,OAAO;CAE/B,GAAG;EAAC;EAAQ;EAAS;CAAM,CAAC;CAE5B,OACE,qBAAC,YAAD;EACU;EACR,QAAQ,OAAO,UAAU,IAAI,UAAU,OAAO,IAAI;EAClD,GAAI;EACJ,GAAI;EAJN,UAAA,CAMG,eACC,oBAAC,eAAD;GACE,SAAS;GACT,iBAAiB,OAAO,UAAU,EAAE,UAAU,EAAE,IAAI,KAAA;GACpD,GAAI;EACL,CAAA,GAEH,qBAAC,eAAD;GAAe,UAAU,OAAO,WAAW,SAAS,YAAY,IAAI,YAAY;GAAhF,UAAA,CACG,aACC,qBAAC,cAAD,EAAA,UAAA,CACG,SAAS,oBAAC,aAAD,EAAA,UAAc,MAAmB,CAAA,GAC1C,mBAAmB,oBAAC,mBAAD,EAAmB,GAAI,iBAAmB,CAAA,CAClD,EAAA,CAAA,GAGhB,oBAAC,YAAD,EAAa,SAAqB,CAAA,CACrB;EACL,CAAA,CAAA;;AAEhB,CAAC;AAED,OAAO,UAAUA;AACjB,OAAO,cAAc;AACrB,OAAO,OAAO;AACd,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,OAAO;AACd,OAAO,SAAS;AAChB,OAAO,QAAQ;AACf,OAAO,cAAc;AACrB,OAAO,QAAQ"}
|
|
@@ -7,6 +7,7 @@ const DrawerStackContext = createContext(null);
|
|
|
7
7
|
function DrawerStack({ children }) {
|
|
8
8
|
const [stack, setStack] = useState([]);
|
|
9
9
|
const [maxZIndex, setMaxZIndex] = useState(getDefaultZIndex("modal"));
|
|
10
|
+
const [handledEscapeEvents] = useState(() => /* @__PURE__ */ new WeakSet());
|
|
10
11
|
return /* @__PURE__ */ jsx(DrawerStackContext, {
|
|
11
12
|
value: {
|
|
12
13
|
stack,
|
|
@@ -17,7 +18,8 @@ function DrawerStack({ children }) {
|
|
|
17
18
|
removeModal: (id) => setStack((current) => current.filter((currentId) => currentId !== id)),
|
|
18
19
|
getZIndex: (id) => `calc(${maxZIndex} + ${stack.indexOf(id)} + 1)`,
|
|
19
20
|
currentId: stack[stack.length - 1],
|
|
20
|
-
maxZIndex
|
|
21
|
+
maxZIndex,
|
|
22
|
+
handledEscapeEvents
|
|
21
23
|
},
|
|
22
24
|
children
|
|
23
25
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawerStack.mjs","names":[],"sources":["../../../src/components/Drawer/DrawerStack.tsx"],"sourcesContent":["import { createContext, useState } from 'react';\nimport { getDefaultZIndex } from '../../core';\n\ninterface DrawerStackContext {\n stack: string[];\n addModal: (id: string, zIndex: number | string) => void;\n removeModal: (id: string) => void;\n getZIndex: (id: string) => string;\n currentId: string;\n maxZIndex: string | number;\n}\n\nexport const DrawerStackContext = createContext<DrawerStackContext | null>(null);\n\nexport interface DrawerStackProps {\n children: React.ReactNode;\n}\n\nexport function DrawerStack({ children }: DrawerStackProps) {\n const [stack, setStack] = useState<string[]>([]);\n const [maxZIndex, setMaxZIndex] = useState<number | string>(getDefaultZIndex('modal'));\n\n return (\n <DrawerStackContext\n value={{\n stack,\n addModal: (id, zIndex) => {\n setStack((current) => [...new Set([...current, id])]);\n setMaxZIndex((current) =>\n typeof zIndex === 'number' && typeof current === 'number'\n ? Math.max(current, zIndex)\n : current\n );\n },\n removeModal: (id) => setStack((current) => current.filter((currentId) => currentId !== id)),\n getZIndex: (id) => `calc(${maxZIndex} + ${stack.indexOf(id)} + 1)`,\n currentId: stack[stack.length - 1],\n maxZIndex,\n }}\n >\n {children}\n </DrawerStackContext>\n );\n}\n\nDrawerStack.displayName = '@mantine/core/DrawerStack';\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"DrawerStack.mjs","names":[],"sources":["../../../src/components/Drawer/DrawerStack.tsx"],"sourcesContent":["import { createContext, useState } from 'react';\nimport { getDefaultZIndex } from '../../core';\n\ninterface DrawerStackContext {\n stack: string[];\n addModal: (id: string, zIndex: number | string) => void;\n removeModal: (id: string) => void;\n getZIndex: (id: string) => string;\n currentId: string;\n maxZIndex: string | number;\n handledEscapeEvents: WeakSet<KeyboardEvent>;\n}\n\nexport const DrawerStackContext = createContext<DrawerStackContext | null>(null);\n\nexport interface DrawerStackProps {\n children: React.ReactNode;\n}\n\nexport function DrawerStack({ children }: DrawerStackProps) {\n const [stack, setStack] = useState<string[]>([]);\n const [maxZIndex, setMaxZIndex] = useState<number | string>(getDefaultZIndex('modal'));\n const [handledEscapeEvents] = useState(() => new WeakSet<KeyboardEvent>());\n\n return (\n <DrawerStackContext\n value={{\n stack,\n addModal: (id, zIndex) => {\n setStack((current) => [...new Set([...current, id])]);\n setMaxZIndex((current) =>\n typeof zIndex === 'number' && typeof current === 'number'\n ? Math.max(current, zIndex)\n : current\n );\n },\n removeModal: (id) => setStack((current) => current.filter((currentId) => currentId !== id)),\n getZIndex: (id) => `calc(${maxZIndex} + ${stack.indexOf(id)} + 1)`,\n currentId: stack[stack.length - 1],\n maxZIndex,\n handledEscapeEvents,\n }}\n >\n {children}\n </DrawerStackContext>\n );\n}\n\nDrawerStack.displayName = '@mantine/core/DrawerStack';\n"],"mappings":";;;;;AAaA,MAAa,qBAAqB,cAAyC,IAAI;AAM/E,SAAgB,YAAY,EAAE,YAA8B;CAC1D,MAAM,CAAC,OAAO,YAAY,SAAmB,CAAC,CAAC;CAC/C,MAAM,CAAC,WAAW,gBAAgB,SAA0B,iBAAiB,OAAO,CAAC;CACrF,MAAM,CAAC,uBAAuB,+BAAe,IAAI,QAAuB,CAAC;CAEzE,OACE,oBAAC,oBAAD;EACE,OAAO;GACL;GACA,WAAW,IAAI,WAAW;IACxB,UAAU,YAAY,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;IACpD,cAAc,YACZ,OAAO,WAAW,YAAY,OAAO,YAAY,WAC7C,KAAK,IAAI,SAAS,MAAM,IACxB,OACN;GACF;GACA,cAAc,OAAO,UAAU,YAAY,QAAQ,QAAQ,cAAc,cAAc,EAAE,CAAC;GAC1F,YAAY,OAAO,QAAQ,UAAU,KAAK,MAAM,QAAQ,EAAE,EAAE;GAC5D,WAAW,MAAM,MAAM,SAAS;GAChC;GACA;EACF;EAEC;CACiB,CAAA;AAExB;AAEA,YAAY,cAAc"}
|
|
@@ -93,11 +93,11 @@ function MenuSub(_props) {
|
|
|
93
93
|
children: /* @__PURE__ */ jsx(Popover, {
|
|
94
94
|
opened,
|
|
95
95
|
onChange: (nextOpened) => nextOpened ? handleOpen() : handleClose(),
|
|
96
|
-
withinPortal: false,
|
|
97
96
|
withArrow: false,
|
|
98
97
|
id,
|
|
99
98
|
position,
|
|
100
99
|
...others,
|
|
100
|
+
withinPortal: false,
|
|
101
101
|
children
|
|
102
102
|
})
|
|
103
103
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuSub.mjs","names":["useId"],"sources":["../../../../src/components/Menu/MenuSub/MenuSub.tsx"],"sourcesContent":["import { use, useCallback, useEffect, useRef } from 'react';\nimport {\n safePolygon,\n useFloating,\n useHover,\n useInteractions,\n type SafePolygonOptions,\n} from '@floating-ui/react';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport { ExtendComponent, Factory, useDirection, useProps } from '../../../core';\nimport {\n FloatingAxesOffsets,\n FloatingPosition,\n getFloatingPosition,\n} from '../../../utils/Floating';\nimport { __PopoverProps, Popover } from '../../Popover';\nimport { TransitionOverride } from '../../Transition';\nimport { useMenuContext } from '../Menu.context';\nimport { MenuSubDropdown } from '../MenuSubDropdown/MenuSubDropdown';\nimport { MenuSubItem } from '../MenuSubItem/MenuSubItem';\nimport { MenuSubTarget } from '../MenuSubTarget/MenuSubTarget';\nimport { SubMenuContext } from './MenuSub.context';\n\nexport type MenuSubFactory = Factory<{\n props: MenuSubProps;\n}>;\n\nexport interface MenuSubProps extends __PopoverProps {\n children: React.ReactNode;\n\n /** Controlled opened state */\n opened?: boolean;\n\n /** Called with current state when dropdown opens or closes */\n onChange?: (opened: boolean) => void;\n\n /** Open delay in ms, applicable when hover trigger is used */\n openDelay?: number;\n\n /** Close delay in ms, applicable when hover trigger is used */\n closeDelay?: number;\n\n /** Dropdown position relative to the target element @default 'right-start' */\n position?: FloatingPosition;\n\n /** Offset of the dropdown element @default 0 */\n offset?: number | FloatingAxesOffsets;\n\n /** Props passed down to the `Transition` component that used to animate dropdown presence, use to configure duration and animation type @default { duration: 0 } */\n transitionProps?: TransitionOverride;\n\n /** Determines whether submenu stays open while the cursor moves toward its dropdown. Pass an object to configure safe polygon behavior. @default true */\n safeAreaPolygon?: boolean | SafePolygonOptions;\n}\n\nconst defaultProps = {\n offset: 0,\n position: 'right-start',\n safeAreaPolygon: true,\n transitionProps: { duration: 0 },\n openDelay: 0,\n middlewares: {\n shift: {\n // Enable crossAxis shift to keep submenu dropdown within viewport bounds when positioned horizontally\n crossAxis: true,\n },\n },\n} satisfies Partial<MenuSubProps>;\n\nexport function MenuSub(_props: MenuSubProps) {\n const {\n children,\n closeDelay,\n openDelay,\n position,\n safeAreaPolygon,\n opened: openedProp,\n onChange,\n ...others\n } = useProps('MenuSub', defaultProps, _props);\n const id = useId();\n const [opened, setOpened] = useUncontrolled({\n value: openedProp,\n finalValue: false,\n onChange,\n });\n const parentSubCtx = use(SubMenuContext);\n const menuCtx = useMenuContext();\n const { dir } = useDirection();\n const resolvedPosition = getFloatingPosition(dir, position);\n\n const levelRegister = parentSubCtx?.registerOpenSub ?? menuCtx.registerOpenSub;\n\n const activeChildCloseRef = useRef<(() => void) | null>(null);\n const registerOpenSub = useCallback((closeFn: () => void) => {\n const prev = activeChildCloseRef.current;\n if (prev && prev !== closeFn) {\n prev();\n }\n activeChildCloseRef.current = closeFn;\n return () => {\n if (activeChildCloseRef.current === closeFn) {\n activeChildCloseRef.current = null;\n }\n };\n }, []);\n\n const setOpenedRef = useRef(setOpened);\n setOpenedRef.current = setOpened;\n\n const handleOpen = useCallback(() => setOpenedRef.current(true), []);\n const handleClose = useCallback(() => setOpenedRef.current(false), []);\n\n useEffect(() => {\n if (!opened) {\n return undefined;\n }\n\n return levelRegister(handleClose);\n }, [opened, levelRegister, handleClose]);\n\n const { context, refs } = useFloating({\n placement: resolvedPosition,\n open: opened,\n onOpenChange: (nextOpen) => {\n if (nextOpen) {\n handleOpen();\n } else {\n handleClose();\n }\n },\n });\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useHover(context, {\n handleClose: safeAreaPolygon\n ? safePolygon(typeof safeAreaPolygon === 'object' ? safeAreaPolygon : undefined)\n : undefined,\n delay: { open: openDelay, close: closeDelay },\n }),\n ]);\n\n const focusFirstItem = () =>\n window.setTimeout(() => {\n document\n .getElementById(`${id}-dropdown`)\n ?.querySelectorAll<HTMLButtonElement>('[data-menu-item]:not([data-disabled])')[0]\n ?.focus();\n }, 16);\n\n const focusParentItem = () =>\n window.setTimeout(() => {\n document.getElementById(`${id}-target`)?.focus();\n }, 16);\n\n return (\n <SubMenuContext\n value={{\n opened,\n close: handleClose,\n open: handleOpen,\n focusFirstItem,\n focusParentItem,\n parentContext: parentSubCtx,\n setReference: refs.setReference,\n setFloating: refs.setFloating,\n getReferenceProps,\n getFloatingProps,\n registerOpenSub,\n }}\n >\n <Popover\n opened={opened}\n onChange={(nextOpened) => (nextOpened ? handleOpen() : handleClose())}\n
|
|
1
|
+
{"version":3,"file":"MenuSub.mjs","names":["useId"],"sources":["../../../../src/components/Menu/MenuSub/MenuSub.tsx"],"sourcesContent":["import { use, useCallback, useEffect, useRef } from 'react';\nimport {\n safePolygon,\n useFloating,\n useHover,\n useInteractions,\n type SafePolygonOptions,\n} from '@floating-ui/react';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport { ExtendComponent, Factory, useDirection, useProps } from '../../../core';\nimport {\n FloatingAxesOffsets,\n FloatingPosition,\n getFloatingPosition,\n} from '../../../utils/Floating';\nimport { __PopoverProps, Popover } from '../../Popover';\nimport { TransitionOverride } from '../../Transition';\nimport { useMenuContext } from '../Menu.context';\nimport { MenuSubDropdown } from '../MenuSubDropdown/MenuSubDropdown';\nimport { MenuSubItem } from '../MenuSubItem/MenuSubItem';\nimport { MenuSubTarget } from '../MenuSubTarget/MenuSubTarget';\nimport { SubMenuContext } from './MenuSub.context';\n\nexport type MenuSubFactory = Factory<{\n props: MenuSubProps;\n}>;\n\n/** `Menu.Sub` dropdown is always rendered inside the parent dropdown: hover tracking and outside\n * clicks detection rely on it being a DOM descendant of the menu it belongs to. */\nexport interface MenuSubProps extends Omit<__PopoverProps, 'withinPortal' | 'portalProps'> {\n children: React.ReactNode;\n\n /** Controlled opened state */\n opened?: boolean;\n\n /** Called with current state when dropdown opens or closes */\n onChange?: (opened: boolean) => void;\n\n /** Open delay in ms, applicable when hover trigger is used */\n openDelay?: number;\n\n /** Close delay in ms, applicable when hover trigger is used */\n closeDelay?: number;\n\n /** Dropdown position relative to the target element @default 'right-start' */\n position?: FloatingPosition;\n\n /** Offset of the dropdown element @default 0 */\n offset?: number | FloatingAxesOffsets;\n\n /** Props passed down to the `Transition` component that used to animate dropdown presence, use to configure duration and animation type @default { duration: 0 } */\n transitionProps?: TransitionOverride;\n\n /** Determines whether submenu stays open while the cursor moves toward its dropdown. Pass an object to configure safe polygon behavior. @default true */\n safeAreaPolygon?: boolean | SafePolygonOptions;\n}\n\nconst defaultProps = {\n offset: 0,\n position: 'right-start',\n safeAreaPolygon: true,\n transitionProps: { duration: 0 },\n openDelay: 0,\n middlewares: {\n shift: {\n // Enable crossAxis shift to keep submenu dropdown within viewport bounds when positioned horizontally\n crossAxis: true,\n },\n },\n} satisfies Partial<MenuSubProps>;\n\nexport function MenuSub(_props: MenuSubProps) {\n const {\n children,\n closeDelay,\n openDelay,\n position,\n safeAreaPolygon,\n opened: openedProp,\n onChange,\n ...others\n } = useProps('MenuSub', defaultProps, _props);\n const id = useId();\n const [opened, setOpened] = useUncontrolled({\n value: openedProp,\n finalValue: false,\n onChange,\n });\n const parentSubCtx = use(SubMenuContext);\n const menuCtx = useMenuContext();\n const { dir } = useDirection();\n const resolvedPosition = getFloatingPosition(dir, position);\n\n const levelRegister = parentSubCtx?.registerOpenSub ?? menuCtx.registerOpenSub;\n\n const activeChildCloseRef = useRef<(() => void) | null>(null);\n const registerOpenSub = useCallback((closeFn: () => void) => {\n const prev = activeChildCloseRef.current;\n if (prev && prev !== closeFn) {\n prev();\n }\n activeChildCloseRef.current = closeFn;\n return () => {\n if (activeChildCloseRef.current === closeFn) {\n activeChildCloseRef.current = null;\n }\n };\n }, []);\n\n const setOpenedRef = useRef(setOpened);\n setOpenedRef.current = setOpened;\n\n const handleOpen = useCallback(() => setOpenedRef.current(true), []);\n const handleClose = useCallback(() => setOpenedRef.current(false), []);\n\n useEffect(() => {\n if (!opened) {\n return undefined;\n }\n\n return levelRegister(handleClose);\n }, [opened, levelRegister, handleClose]);\n\n const { context, refs } = useFloating({\n placement: resolvedPosition,\n open: opened,\n onOpenChange: (nextOpen) => {\n if (nextOpen) {\n handleOpen();\n } else {\n handleClose();\n }\n },\n });\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useHover(context, {\n handleClose: safeAreaPolygon\n ? safePolygon(typeof safeAreaPolygon === 'object' ? safeAreaPolygon : undefined)\n : undefined,\n delay: { open: openDelay, close: closeDelay },\n }),\n ]);\n\n const focusFirstItem = () =>\n window.setTimeout(() => {\n document\n .getElementById(`${id}-dropdown`)\n ?.querySelectorAll<HTMLButtonElement>('[data-menu-item]:not([data-disabled])')[0]\n ?.focus();\n }, 16);\n\n const focusParentItem = () =>\n window.setTimeout(() => {\n document.getElementById(`${id}-target`)?.focus();\n }, 16);\n\n return (\n <SubMenuContext\n value={{\n opened,\n close: handleClose,\n open: handleOpen,\n focusFirstItem,\n focusParentItem,\n parentContext: parentSubCtx,\n setReference: refs.setReference,\n setFloating: refs.setFloating,\n getReferenceProps,\n getFloatingProps,\n registerOpenSub,\n }}\n >\n <Popover\n opened={opened}\n onChange={(nextOpened) => (nextOpened ? handleOpen() : handleClose())}\n withArrow={false}\n id={id}\n position={position}\n {...others}\n withinPortal={false}\n >\n {children}\n </Popover>\n </SubMenuContext>\n );\n}\n\nMenuSub.extend = (input: ExtendComponent<MenuSubFactory>) => input;\nMenuSub.displayName = '@mantine/core/MenuSub';\nMenuSub.Target = MenuSubTarget;\nMenuSub.Dropdown = MenuSubDropdown;\nMenuSub.Item = MenuSubItem;\n"],"mappings":";;;;;;;;;;;;;;;AAyDA,MAAM,eAAe;CACnB,QAAQ;CACR,UAAU;CACV,iBAAiB;CACjB,iBAAiB,EAAE,UAAU,EAAE;CAC/B,WAAW;CACX,aAAa,EACX,OAAO,EAEL,WAAW,KACb,EACF;AACF;AAEA,SAAgB,QAAQ,QAAsB;CAC5C,MAAM,EACJ,UACA,YACA,WACA,UACA,iBACA,QAAQ,YACR,UACA,GAAG,WACD,SAAS,WAAW,cAAc,MAAM;CAC5C,MAAM,KAAKA,QAAM;CACjB,MAAM,CAAC,QAAQ,aAAa,gBAAgB;EAC1C,OAAO;EACP,YAAY;EACZ;CACF,CAAC;CACD,MAAM,eAAe,IAAI,cAAc;CACvC,MAAM,UAAU,eAAe;CAC/B,MAAM,EAAE,QAAQ,aAAa;CAC7B,MAAM,mBAAmB,oBAAoB,KAAK,QAAQ;CAE1D,MAAM,gBAAgB,cAAc,mBAAmB,QAAQ;CAE/D,MAAM,sBAAsB,OAA4B,IAAI;CAC5D,MAAM,kBAAkB,aAAa,YAAwB;EAC3D,MAAM,OAAO,oBAAoB;EACjC,IAAI,QAAQ,SAAS,SACnB,KAAK;EAEP,oBAAoB,UAAU;EAC9B,aAAa;GACX,IAAI,oBAAoB,YAAY,SAClC,oBAAoB,UAAU;EAElC;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,eAAe,OAAO,SAAS;CACrC,aAAa,UAAU;CAEvB,MAAM,aAAa,kBAAkB,aAAa,QAAQ,IAAI,GAAG,CAAC,CAAC;CACnE,MAAM,cAAc,kBAAkB,aAAa,QAAQ,KAAK,GAAG,CAAC,CAAC;CAErE,gBAAgB;EACd,IAAI,CAAC,QACH;EAGF,OAAO,cAAc,WAAW;CAClC,GAAG;EAAC;EAAQ;EAAe;CAAW,CAAC;CAEvC,MAAM,EAAE,SAAS,SAAS,YAAY;EACpC,WAAW;EACX,MAAM;EACN,eAAe,aAAa;GAC1B,IAAI,UACF,WAAW;QAEX,YAAY;EAEhB;CACF,CAAC;CAED,MAAM,EAAE,mBAAmB,qBAAqB,gBAAgB,CAC9D,SAAS,SAAS;EAChB,aAAa,kBACT,YAAY,OAAO,oBAAoB,WAAW,kBAAkB,KAAA,CAAS,IAC7E,KAAA;EACJ,OAAO;GAAE,MAAM;GAAW,OAAO;EAAW;CAC9C,CAAC,CACH,CAAC;CAED,MAAM,uBACJ,OAAO,iBAAiB;EACtB,SACG,eAAe,GAAG,GAAG,UAAU,CAAC,EAC/B,iBAAoC,uCAAuC,CAAC,CAAC,EAAE,EAC/E,MAAM;CACZ,GAAG,EAAE;CAEP,MAAM,wBACJ,OAAO,iBAAiB;EACtB,SAAS,eAAe,GAAG,GAAG,QAAQ,CAAC,EAAE,MAAM;CACjD,GAAG,EAAE;CAEP,OACE,oBAAC,gBAAD;EACE,OAAO;GACL;GACA,OAAO;GACP,MAAM;GACN;GACA;GACA,eAAe;GACf,cAAc,KAAK;GACnB,aAAa,KAAK;GAClB;GACA;GACA;EACF;EAEA,UAAA,oBAAC,SAAD;GACU;GACR,WAAW,eAAgB,aAAa,WAAW,IAAI,YAAY;GACnE,WAAW;GACP;GACM;GACV,GAAI;GACJ,cAAc;GAEb;EACM,CAAA;CACK,CAAA;AAEpB;AAEA,QAAQ,UAAU,UAA2C;AAC7D,QAAQ,cAAc;AACtB,QAAQ,SAAS;AACjB,QAAQ,WAAW;AACnB,QAAQ,OAAO"}
|
|
@@ -37,7 +37,8 @@ const Modal = factory((_props) => {
|
|
|
37
37
|
const stackProps = ctx && stackId ? {
|
|
38
38
|
closeOnEscape: ctx.currentId === stackId,
|
|
39
39
|
trapFocus: ctx.currentId === stackId,
|
|
40
|
-
zIndex: ctx.getZIndex(stackId)
|
|
40
|
+
zIndex: ctx.getZIndex(stackId),
|
|
41
|
+
__handledEscapeEvents: ctx.handledEscapeEvents
|
|
41
42
|
} : {};
|
|
42
43
|
const overlayVisible = withOverlay === false ? false : stackId && ctx ? ctx.currentId === stackId : opened;
|
|
43
44
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.mjs","names":["classes"],"sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\nimport { factory, Factory, getDefaultZIndex, useProps } from '../../core';\nimport { ModalBaseCloseButtonProps, ModalBaseOverlayProps } from '../ModalBase';\nimport { ModalBody, type ModalBodyProps } from './ModalBody';\nimport { ModalCloseButton, type ModalCloseButtonProps } from './ModalCloseButton';\nimport { ModalContent, type ModalContentProps } from './ModalContent';\nimport { ModalHeader, type ModalHeaderProps } from './ModalHeader';\nimport { ModalOverlay, type ModalOverlayProps } from './ModalOverlay';\nimport {\n ModalRoot,\n ModalRootCssVariables,\n ModalRootProps,\n ModalRootStylesNames,\n} from './ModalRoot';\nimport { ModalStack, ModalStackContext, type ModalStackProps } from './ModalStack';\nimport { ModalTitle, type ModalTitleProps } from './ModalTitle';\nimport classes from './Modal.module.css';\nexport type ModalStylesNames = ModalRootStylesNames;\nexport type ModalCssVariables = ModalRootCssVariables;\n\nexport interface ModalProps extends ModalRootProps {\n __staticSelector?: string;\n\n /** Modal title */\n title?: React.ReactNode;\n\n /** If set, the overlay is rendered @default true */\n withOverlay?: boolean;\n\n /** Props passed down to the `Overlay` component, use to configure opacity, `background-color`, styles and other properties */\n overlayProps?: ModalBaseOverlayProps;\n\n /** Modal content */\n children?: React.ReactNode;\n\n /** If set, the close button is rendered @default true */\n withCloseButton?: boolean;\n\n /** Props passed down to the close button */\n closeButtonProps?: ModalBaseCloseButtonProps;\n\n /** Id of the modal in the `Modal.Stack` */\n stackId?: string;\n}\n\nexport type ModalFactory = Factory<{\n props: ModalProps;\n ref: HTMLDivElement;\n stylesNames: ModalStylesNames;\n vars: ModalCssVariables;\n staticComponents: {\n Root: typeof ModalRoot;\n Overlay: typeof ModalOverlay;\n Content: typeof ModalContent;\n Body: typeof ModalBody;\n Header: typeof ModalHeader;\n Title: typeof ModalTitle;\n CloseButton: typeof ModalCloseButton;\n Stack: typeof ModalStack;\n };\n}>;\n\nconst defaultProps = {\n closeOnClickOutside: true,\n withinPortal: true,\n lockScroll: true,\n trapFocus: true,\n returnFocus: true,\n closeOnEscape: true,\n keepMounted: false,\n zIndex: getDefaultZIndex('modal'),\n transitionProps: { duration: 200, transition: 'fade-down' },\n withOverlay: true,\n withCloseButton: true,\n} satisfies Partial<ModalProps>;\n\nexport const Modal = factory<ModalFactory>((_props) => {\n const {\n title,\n withOverlay,\n overlayProps,\n withCloseButton,\n closeButtonProps,\n children,\n radius,\n opened,\n stackId,\n zIndex,\n ...others\n } = useProps('Modal', defaultProps, _props);\n const ctx = use(ModalStackContext);\n const hasHeader = !!title || withCloseButton;\n const stackProps =\n ctx && stackId\n ? {\n closeOnEscape: ctx.currentId === stackId,\n trapFocus: ctx.currentId === stackId,\n zIndex: ctx.getZIndex(stackId),\n }\n : {};\n\n const overlayVisible =\n withOverlay === false ? false : stackId && ctx ? ctx.currentId === stackId : opened;\n\n useEffect(() => {\n if (ctx && stackId) {\n opened\n ? ctx.addModal(stackId, zIndex || getDefaultZIndex('modal'))\n : ctx.removeModal(stackId);\n }\n }, [opened, stackId, zIndex]);\n\n return (\n <ModalRoot\n radius={radius}\n opened={opened}\n zIndex={ctx && stackId ? ctx.getZIndex(stackId) : zIndex}\n {...others}\n {...stackProps}\n >\n {withOverlay && (\n <ModalOverlay\n visible={overlayVisible}\n transitionProps={ctx && stackId ? { duration: 0 } : undefined}\n {...overlayProps}\n />\n )}\n <ModalContent\n radius={radius}\n __hidden={ctx && stackId && opened ? stackId !== ctx.currentId : false}\n >\n {hasHeader && (\n <ModalHeader>\n {title && <ModalTitle>{title}</ModalTitle>}\n {withCloseButton && <ModalCloseButton {...closeButtonProps} />}\n </ModalHeader>\n )}\n\n <ModalBody>{children}</ModalBody>\n </ModalContent>\n </ModalRoot>\n );\n});\n\nModal.classes = classes;\nModal.displayName = '@mantine/core/Modal';\nModal.Root = ModalRoot;\nModal.Overlay = ModalOverlay;\nModal.Content = ModalContent;\nModal.Body = ModalBody;\nModal.Header = ModalHeader;\nModal.Title = ModalTitle;\nModal.CloseButton = ModalCloseButton;\nModal.Stack = ModalStack;\n\nexport namespace Modal {\n export type Props = ModalProps;\n export type StylesNames = ModalStylesNames;\n export type CssVariables = ModalCssVariables;\n export type Factory = ModalFactory;\n\n export namespace Root {\n export type Props = ModalRootProps;\n }\n\n export namespace Body {\n export type Props = ModalBodyProps;\n }\n\n export namespace CloseButton {\n export type Props = ModalCloseButtonProps;\n }\n\n export namespace Content {\n export type Props = ModalContentProps;\n }\n\n export namespace Header {\n export type Props = ModalHeaderProps;\n }\n\n export namespace Overlay {\n export type Props = ModalOverlayProps;\n }\n\n export namespace Title {\n export type Props = ModalTitleProps;\n }\n\n export namespace Stack {\n export type Props = ModalStackProps;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8DA,MAAM,eAAe;CACnB,qBAAqB;CACrB,cAAc;CACd,YAAY;CACZ,WAAW;CACX,aAAa;CACb,eAAe;CACf,aAAa;CACb,QAAQ,iBAAiB,OAAO;CAChC,iBAAiB;EAAE,UAAU;EAAK,YAAY;CAAY;CAC1D,aAAa;CACb,iBAAiB;AACnB;AAEA,MAAa,QAAQ,SAAuB,WAAW;CACrD,MAAM,EACJ,OACA,aACA,cACA,iBACA,kBACA,UACA,QACA,QACA,SACA,QACA,GAAG,WACD,SAAS,SAAS,cAAc,MAAM;CAC1C,MAAM,MAAM,IAAI,iBAAiB;CACjC,MAAM,YAAY,CAAC,CAAC,SAAS;CAC7B,MAAM,aACJ,OAAO,UACH;EACE,eAAe,IAAI,cAAc;EACjC,WAAW,IAAI,cAAc;EAC7B,QAAQ,IAAI,UAAU,OAAO;
|
|
1
|
+
{"version":3,"file":"Modal.mjs","names":["classes"],"sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\nimport { factory, Factory, getDefaultZIndex, useProps } from '../../core';\nimport { ModalBaseCloseButtonProps, ModalBaseOverlayProps } from '../ModalBase';\nimport { ModalBody, type ModalBodyProps } from './ModalBody';\nimport { ModalCloseButton, type ModalCloseButtonProps } from './ModalCloseButton';\nimport { ModalContent, type ModalContentProps } from './ModalContent';\nimport { ModalHeader, type ModalHeaderProps } from './ModalHeader';\nimport { ModalOverlay, type ModalOverlayProps } from './ModalOverlay';\nimport {\n ModalRoot,\n ModalRootCssVariables,\n ModalRootProps,\n ModalRootStylesNames,\n} from './ModalRoot';\nimport { ModalStack, ModalStackContext, type ModalStackProps } from './ModalStack';\nimport { ModalTitle, type ModalTitleProps } from './ModalTitle';\nimport classes from './Modal.module.css';\nexport type ModalStylesNames = ModalRootStylesNames;\nexport type ModalCssVariables = ModalRootCssVariables;\n\nexport interface ModalProps extends ModalRootProps {\n __staticSelector?: string;\n\n /** Modal title */\n title?: React.ReactNode;\n\n /** If set, the overlay is rendered @default true */\n withOverlay?: boolean;\n\n /** Props passed down to the `Overlay` component, use to configure opacity, `background-color`, styles and other properties */\n overlayProps?: ModalBaseOverlayProps;\n\n /** Modal content */\n children?: React.ReactNode;\n\n /** If set, the close button is rendered @default true */\n withCloseButton?: boolean;\n\n /** Props passed down to the close button */\n closeButtonProps?: ModalBaseCloseButtonProps;\n\n /** Id of the modal in the `Modal.Stack` */\n stackId?: string;\n}\n\nexport type ModalFactory = Factory<{\n props: ModalProps;\n ref: HTMLDivElement;\n stylesNames: ModalStylesNames;\n vars: ModalCssVariables;\n staticComponents: {\n Root: typeof ModalRoot;\n Overlay: typeof ModalOverlay;\n Content: typeof ModalContent;\n Body: typeof ModalBody;\n Header: typeof ModalHeader;\n Title: typeof ModalTitle;\n CloseButton: typeof ModalCloseButton;\n Stack: typeof ModalStack;\n };\n}>;\n\nconst defaultProps = {\n closeOnClickOutside: true,\n withinPortal: true,\n lockScroll: true,\n trapFocus: true,\n returnFocus: true,\n closeOnEscape: true,\n keepMounted: false,\n zIndex: getDefaultZIndex('modal'),\n transitionProps: { duration: 200, transition: 'fade-down' },\n withOverlay: true,\n withCloseButton: true,\n} satisfies Partial<ModalProps>;\n\nexport const Modal = factory<ModalFactory>((_props) => {\n const {\n title,\n withOverlay,\n overlayProps,\n withCloseButton,\n closeButtonProps,\n children,\n radius,\n opened,\n stackId,\n zIndex,\n ...others\n } = useProps('Modal', defaultProps, _props);\n const ctx = use(ModalStackContext);\n const hasHeader = !!title || withCloseButton;\n const stackProps =\n ctx && stackId\n ? {\n closeOnEscape: ctx.currentId === stackId,\n trapFocus: ctx.currentId === stackId,\n zIndex: ctx.getZIndex(stackId),\n __handledEscapeEvents: ctx.handledEscapeEvents,\n }\n : {};\n\n const overlayVisible =\n withOverlay === false ? false : stackId && ctx ? ctx.currentId === stackId : opened;\n\n useEffect(() => {\n if (ctx && stackId) {\n opened\n ? ctx.addModal(stackId, zIndex || getDefaultZIndex('modal'))\n : ctx.removeModal(stackId);\n }\n }, [opened, stackId, zIndex]);\n\n return (\n <ModalRoot\n radius={radius}\n opened={opened}\n zIndex={ctx && stackId ? ctx.getZIndex(stackId) : zIndex}\n {...others}\n {...stackProps}\n >\n {withOverlay && (\n <ModalOverlay\n visible={overlayVisible}\n transitionProps={ctx && stackId ? { duration: 0 } : undefined}\n {...overlayProps}\n />\n )}\n <ModalContent\n radius={radius}\n __hidden={ctx && stackId && opened ? stackId !== ctx.currentId : false}\n >\n {hasHeader && (\n <ModalHeader>\n {title && <ModalTitle>{title}</ModalTitle>}\n {withCloseButton && <ModalCloseButton {...closeButtonProps} />}\n </ModalHeader>\n )}\n\n <ModalBody>{children}</ModalBody>\n </ModalContent>\n </ModalRoot>\n );\n});\n\nModal.classes = classes;\nModal.displayName = '@mantine/core/Modal';\nModal.Root = ModalRoot;\nModal.Overlay = ModalOverlay;\nModal.Content = ModalContent;\nModal.Body = ModalBody;\nModal.Header = ModalHeader;\nModal.Title = ModalTitle;\nModal.CloseButton = ModalCloseButton;\nModal.Stack = ModalStack;\n\nexport namespace Modal {\n export type Props = ModalProps;\n export type StylesNames = ModalStylesNames;\n export type CssVariables = ModalCssVariables;\n export type Factory = ModalFactory;\n\n export namespace Root {\n export type Props = ModalRootProps;\n }\n\n export namespace Body {\n export type Props = ModalBodyProps;\n }\n\n export namespace CloseButton {\n export type Props = ModalCloseButtonProps;\n }\n\n export namespace Content {\n export type Props = ModalContentProps;\n }\n\n export namespace Header {\n export type Props = ModalHeaderProps;\n }\n\n export namespace Overlay {\n export type Props = ModalOverlayProps;\n }\n\n export namespace Title {\n export type Props = ModalTitleProps;\n }\n\n export namespace Stack {\n export type Props = ModalStackProps;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8DA,MAAM,eAAe;CACnB,qBAAqB;CACrB,cAAc;CACd,YAAY;CACZ,WAAW;CACX,aAAa;CACb,eAAe;CACf,aAAa;CACb,QAAQ,iBAAiB,OAAO;CAChC,iBAAiB;EAAE,UAAU;EAAK,YAAY;CAAY;CAC1D,aAAa;CACb,iBAAiB;AACnB;AAEA,MAAa,QAAQ,SAAuB,WAAW;CACrD,MAAM,EACJ,OACA,aACA,cACA,iBACA,kBACA,UACA,QACA,QACA,SACA,QACA,GAAG,WACD,SAAS,SAAS,cAAc,MAAM;CAC1C,MAAM,MAAM,IAAI,iBAAiB;CACjC,MAAM,YAAY,CAAC,CAAC,SAAS;CAC7B,MAAM,aACJ,OAAO,UACH;EACE,eAAe,IAAI,cAAc;EACjC,WAAW,IAAI,cAAc;EAC7B,QAAQ,IAAI,UAAU,OAAO;EAC7B,uBAAuB,IAAI;CAC7B,IACA,CAAC;CAEP,MAAM,iBACJ,gBAAgB,QAAQ,QAAQ,WAAW,MAAM,IAAI,cAAc,UAAU;CAE/E,gBAAgB;EACd,IAAI,OAAO,SACT,SACI,IAAI,SAAS,SAAS,UAAU,iBAAiB,OAAO,CAAC,IACzD,IAAI,YAAY,OAAO;CAE/B,GAAG;EAAC;EAAQ;EAAS;CAAM,CAAC;CAE5B,OACE,qBAAC,WAAD;EACU;EACA;EACR,QAAQ,OAAO,UAAU,IAAI,UAAU,OAAO,IAAI;EAClD,GAAI;EACJ,GAAI;EALN,UAAA,CAOG,eACC,oBAAC,cAAD;GACE,SAAS;GACT,iBAAiB,OAAO,UAAU,EAAE,UAAU,EAAE,IAAI,KAAA;GACpD,GAAI;EACL,CAAA,GAEH,qBAAC,cAAD;GACU;GACR,UAAU,OAAO,WAAW,SAAS,YAAY,IAAI,YAAY;GAFnE,UAAA,CAIG,aACC,qBAAC,aAAD,EAAA,UAAA,CACG,SAAS,oBAAC,YAAD,EAAA,UAAa,MAAkB,CAAA,GACxC,mBAAmB,oBAAC,kBAAD,EAAkB,GAAI,iBAAmB,CAAA,CAClD,EAAA,CAAA,GAGf,oBAAC,WAAD,EAAY,SAAoB,CAAA,CACpB;EACL,CAAA,CAAA;;AAEf,CAAC;AAED,MAAM,UAAUA;AAChB,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,OAAO;AACb,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,cAAc;AACpB,MAAM,QAAQ"}
|
|
@@ -7,6 +7,7 @@ const ModalStackContext = createContext(null);
|
|
|
7
7
|
function ModalStack({ children }) {
|
|
8
8
|
const [stack, setStack] = useState([]);
|
|
9
9
|
const [maxZIndex, setMaxZIndex] = useState(getDefaultZIndex("modal"));
|
|
10
|
+
const [handledEscapeEvents] = useState(() => /* @__PURE__ */ new WeakSet());
|
|
10
11
|
return /* @__PURE__ */ jsx(ModalStackContext, {
|
|
11
12
|
value: {
|
|
12
13
|
stack,
|
|
@@ -17,7 +18,8 @@ function ModalStack({ children }) {
|
|
|
17
18
|
removeModal: (id) => setStack((current) => current.filter((currentId) => currentId !== id)),
|
|
18
19
|
getZIndex: (id) => `calc(${maxZIndex} + ${stack.indexOf(id)} + 1)`,
|
|
19
20
|
currentId: stack[stack.length - 1],
|
|
20
|
-
maxZIndex
|
|
21
|
+
maxZIndex,
|
|
22
|
+
handledEscapeEvents
|
|
21
23
|
},
|
|
22
24
|
children
|
|
23
25
|
});
|