@mantine/core 9.6.2 → 9.6.3
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/ComboboxPopover/ComboboxPopover.cjs.map +1 -1
- package/cjs/components/Input/InputWrapper/InputWrapper.cjs +1 -1
- package/cjs/components/Input/InputWrapper/InputWrapper.cjs.map +1 -1
- package/cjs/components/Marquee/Marquee.cjs.map +1 -1
- package/cjs/components/Marquee/Marquee.module.cjs.map +1 -1
- package/cjs/components/PasswordInput/PasswordInput.cjs +10 -5
- package/cjs/components/PasswordInput/PasswordInput.cjs.map +1 -1
- package/cjs/components/PinInput/PinInput.cjs.map +1 -1
- package/cjs/components/Portal/Portal.cjs +10 -1
- package/cjs/components/Portal/Portal.cjs.map +1 -1
- package/cjs/components/Rating/Rating.cjs +35 -12
- package/cjs/components/Rating/Rating.cjs.map +1 -1
- package/cjs/components/Select/Select.cjs +1 -1
- package/cjs/components/Select/Select.cjs.map +1 -1
- package/cjs/components/Slider/Thumb/Thumb.cjs +7 -2
- package/cjs/components/Slider/Thumb/Thumb.cjs.map +1 -1
- package/cjs/components/Table/Table.cjs +23 -10
- package/cjs/components/Table/Table.cjs.map +1 -1
- package/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
- package/cjs/core/Box/Box.cjs +1 -1
- package/cjs/core/Box/Box.cjs.map +1 -1
- package/cjs/core/Box/style-props/style-props-data.cjs +2 -2
- package/cjs/core/Box/style-props/style-props-data.cjs.map +1 -1
- package/cjs/core/styles-api/use-styles/use-styles.cjs +32 -2
- package/cjs/core/styles-api/use-styles/use-styles.cjs.map +1 -1
- package/cjs/core/utils/shallow-equal/shallow-equal.cjs +19 -0
- package/cjs/core/utils/shallow-equal/shallow-equal.cjs.map +1 -0
- package/cjs/index.cjs +1 -1
- package/esm/components/ComboboxPopover/ComboboxPopover.mjs.map +1 -1
- package/esm/components/Input/InputWrapper/InputWrapper.mjs +1 -1
- package/esm/components/Input/InputWrapper/InputWrapper.mjs.map +1 -1
- package/esm/components/Marquee/Marquee.mjs.map +1 -1
- package/esm/components/Marquee/Marquee.module.mjs.map +1 -1
- package/esm/components/PasswordInput/PasswordInput.mjs +12 -7
- package/esm/components/PasswordInput/PasswordInput.mjs.map +1 -1
- package/esm/components/PinInput/PinInput.mjs.map +1 -1
- package/esm/components/Portal/Portal.mjs +10 -1
- package/esm/components/Portal/Portal.mjs.map +1 -1
- package/esm/components/Rating/Rating.mjs +35 -12
- package/esm/components/Rating/Rating.mjs.map +1 -1
- package/esm/components/Select/Select.mjs +1 -1
- package/esm/components/Select/Select.mjs.map +1 -1
- package/esm/components/Slider/Thumb/Thumb.mjs +7 -2
- package/esm/components/Slider/Thumb/Thumb.mjs.map +1 -1
- package/esm/components/Table/Table.mjs +23 -10
- package/esm/components/Table/Table.mjs.map +1 -1
- package/esm/components/Tooltip/Tooltip.mjs.map +1 -1
- package/esm/core/Box/Box.mjs +2 -2
- package/esm/core/Box/Box.mjs.map +1 -1
- package/esm/core/Box/style-props/style-props-data.mjs +2 -2
- package/esm/core/Box/style-props/style-props-data.mjs.map +1 -1
- package/esm/core/styles-api/use-styles/use-styles.mjs +32 -2
- package/esm/core/styles-api/use-styles/use-styles.mjs.map +1 -1
- package/esm/core/utils/shallow-equal/shallow-equal.mjs +19 -0
- package/esm/core/utils/shallow-equal/shallow-equal.mjs.map +1 -0
- package/esm/index.mjs +2 -2
- package/lib/components/Combobox/Combobox.types.d.ts +1 -1
- package/lib/components/ComboboxPopover/ComboboxPopover.d.ts +1 -1
- package/lib/components/Marquee/Marquee.d.ts +1 -1
- package/lib/components/PinInput/PinInput.d.ts +1 -1
- package/lib/components/Slider/Thumb/Thumb.d.ts +1 -1
- package/lib/components/Tooltip/Tooltip.d.ts +1 -1
- package/lib/core/Box/style-props/index.d.ts +1 -1
- package/lib/core/Box/style-props/style-props-data.d.ts +1 -1
- package/lib/core/styles-api/use-styles/use-styles.d.ts +2 -1
- package/lib/core/utils/shallow-equal/shallow-equal.d.ts +1 -0
- package/package.json +2 -2
- package/styles/Marquee.css +1 -1
- package/styles/Marquee.layer.css +1 -1
- package/styles.css +1 -1
- package/styles.layer.css +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxPopover.cjs","names":["isOptionsGroup","Combobox","CheckIcon","comboboxClasses","cx","defaultOptionsFilter","isEmptyComboboxData","ScrollArea","genericFactory","useProps","useMemo","getParsedComboboxData","getOptionsLockup","useUncontrolled","useCombobox","useResolvedStylesApi","OptionsDropdown","ComboboxPopoverTarget"],"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":";;;;;;;;;;;;;;;;;;;;;;;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,IAAIA,yBAAAA,eAAe,IAAI,GAAG;EACxB,MAAM,UAAU,KAAK,MAAM,KAAK,SAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GACE,MAAM;GACC;GAEG;GACK;GACI;GACA;GACL;EACf,GANM,GAAG,KAAK,OAMd,CACF;EACD,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,iBAAAA,SAAS,OAAV;GAAgB,OAAO,KAAK;GAAQ,UAAA;EAAwB,CAAA;CACrE;CAEA,MAAM,UAAU,eAAe,OAAO,KAAK,KAAK;CAChD,MAAM,QACJ,kBACC,UACC,iBAAA,GAAA,kBAAA,IAAA,CAACC,kBAAAA,WAAD,EAAW,WAAWC,wBAAAA,QAAgB,yBAA2B,CAAA,IAC/D,oBACF,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAK,WAAWA,wBAAAA,QAAgB,gCAAkC,CAAA,IAChE;CAEN,MAAM,iBACJ,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;EACG,sBAAsB,UAAU;EACjC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,KAAK,MAAY,CAAA;EACvB,sBAAsB,WAAW;CAClC,EAAA,CAAA;CAGJ,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACF,iBAAAA,SAAS,QAAV;EACE,OAAO,KAAK;EACZ,UAAU,KAAK;EACf,YAAA,GAAWG,KAAAA,QAAAA,CAAG,GAAGD,wBAAAA,QAAgB,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,UAAUE,+BAAAA,qBAAAA,CAAsB;EACpD,SAAS;EACT;EACA,OAAO,SAAS;CAClB,CAAC;CACD,MAAM,UAAUC,+BAAAA,oBAAoB,YAAY;CAEhD,MAAM,UAAU,aAAa,KAAK,MAAM,UACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EACE,MAAM;EAMS;EACI;EACZ;EACY;EACT;EACI;CACf,GAVGN,yBAAAA,eAAe,IAAI,IACf,SAAS,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,UACvD,GAAG,KAAK,OAQf,CACF;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAACC,iBAAAA,SAAS,UAAV;EAAmB,iBAAA;EAAnB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,iBAAAA,SAAS,QAAV;GAAiB,OAAO;GAAQ,UAAU;GAAgB,aAAY;EAAa,CAAA,GACnF,iBAAA,GAAA,kBAAA,KAAA,CAACA,iBAAAA,SAAS,SAAV,EAAA,UAAA,CACG,iBACC,iBAAA,GAAA,kBAAA,IAAA,CAACM,mBAAAA,WAAW,UAAZ;GACE,KAAK,qBAAqB;GAC1B,MAAK;GACL,eAAc;GACd,kBAAiB;GACjB,GAAI;GAEH,UAAA;EACkB,CAAA,IAErB,SAED,WAAW,uBAAuB,iBAAA,GAAA,kBAAA,IAAA,CAACN,iBAAAA,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,kBAAkBO,gBAAAA,gBAAwC,WAAW;CAChF,MAAM,QAAQC,kBAAAA,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,cAAA,GAAaC,MAAAA,QAAAA,OAAcC,iCAAAA,sBAAsB,IAAI,GAAG,CAAC,IAAI,CAAC;CACpE,MAAM,iBAAA,GAAgBD,MAAAA,QAAAA,OAAcE,2BAAAA,iBAAiB,UAAU,GAAG,CAAC,UAAU,CAAC;CAE9E,MAAM,CAAC,QAAQ,aAAA,GAAYC,eAAAA,gBAAAA,CAAgB;EACzC;EACA;EACA,YAAY,WAAY,CAAC,IAAY;EACrC;CACF,CAAC;CAED,MAAM,CAAC,cAAc,mBAAA,GAAkBA,eAAAA,gBAAAA,CAAgB;EACrD,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU;CACZ,CAAC;CAED,MAAM,WAAWC,qBAAAA,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;EAC/B;CACF,CAAC;CAED,MAAM,sBAAsB,QAAgB;EAC1C,eAAe,GAAG;EAClB,SAAS,oBAAoB;CAC/B;CAEA,MAAM,EAAE,oBAAoB,mBAAmBC,gCAAAA,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,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAACd,iBAAAA,UAAD;EACE,OAAO;EACP,kBAAiB;EACjB,YAAY;EACZ,QAAQ;EACE;EACE;EACZ,gBAAgB;EAChB,aAAA;EACA,GAAI;EACJ,GAAI;EAVN,UAAA,CAYG,UACA,aACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,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,iBAAA,GAAA,kBAAA,IAAA,CAACe,wBAAAA,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,iBAAA,GAAA,kBAAA,IAAA,CAACf,iBAAAA,SAAS,aAAV;EACQ;EACN,OAAO;EACD;EACN,eAAe;EACf,GAAI;CACL,CAAA,CACD,EAAA,CAAA;AAEN,CAAC;AAED,gBAAgB,UAAUA,iBAAAA,SAAS;AACnC,gBAAgB,cAAc;AAC9B,gBAAgB,SAASgB,8BAAAA"}
|
|
1
|
+
{"version":3,"file":"ComboboxPopover.cjs","names":["isOptionsGroup","Combobox","CheckIcon","comboboxClasses","cx","defaultOptionsFilter","isEmptyComboboxData","ScrollArea","genericFactory","useProps","useMemo","getParsedComboboxData","getOptionsLockup","useUncontrolled","useCombobox","useResolvedStylesApi","OptionsDropdown","ComboboxPopoverTarget"],"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 220 */\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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"}
|
|
@@ -117,7 +117,7 @@ const InputWrapper = require_factory.factory((_props) => {
|
|
|
117
117
|
getStyles,
|
|
118
118
|
describedBy,
|
|
119
119
|
inputId,
|
|
120
|
-
labelId,
|
|
120
|
+
labelId: _label && inputWrapperOrder.includes("label") ? labelId : void 0,
|
|
121
121
|
...require_get_input_offsets.getInputOffsets(inputWrapperOrder, {
|
|
122
122
|
hasDescription,
|
|
123
123
|
hasError: hasError || hasSuccess
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputWrapper.cjs","names":["createVarsResolver","getFontSize","rem","factory","useProps","useStyles","useId","InputLabel","InputDescription","Fragment","InputError","InputSuccess","InputWrapperContext","getInputOffsets","Box","classes"],"sources":["../../../../src/components/Input/InputWrapper/InputWrapper.tsx"],"sourcesContent":["import { Fragment } from 'react';\nimport { useId } from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n factory,\n Factory,\n getFontSize,\n MantineFontSize,\n PlaceholderPolymorphicProps,\n rem,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../../core';\nimport {\n InputDescription,\n InputDescriptionCssVariables,\n InputDescriptionProps,\n InputDescriptionStylesNames,\n} from '../InputDescription/InputDescription';\nimport {\n InputError,\n InputErrorCssVariables,\n InputErrorProps,\n InputErrorStylesNames,\n} from '../InputError/InputError';\nimport {\n InputLabel,\n InputLabelCssVariables,\n InputLabelProps,\n InputLabelStylesNames,\n} from '../InputLabel/InputLabel';\nimport {\n InputSuccess,\n InputSuccessCssVariables,\n InputSuccessProps,\n InputSuccessStylesNames,\n} from '../InputSuccess/InputSuccess';\nimport { InputWrapperContext } from '../InputWrapper.context';\nimport { getInputOffsets } from './get-input-offsets/get-input-offsets';\nimport classes from '../Input.module.css';\n\nexport type InputWrapperCssVariables = InputLabelCssVariables &\n InputErrorCssVariables &\n InputSuccessCssVariables &\n InputDescriptionCssVariables;\n\nexport type InputWrapperStylesNames =\n | 'root'\n | InputLabelStylesNames\n | InputDescriptionStylesNames\n | InputErrorStylesNames\n | InputSuccessStylesNames;\n\nexport interface __InputWrapperProps {\n /** Contents of `Input.Label` component. If not set, label is not displayed. */\n label?: React.ReactNode;\n\n /** Contents of `Input.Description` component. If not set, description is not displayed. */\n description?: React.ReactNode;\n\n /** Contents of `Input.Error` component. If not set, error is not displayed. */\n error?: React.ReactNode;\n\n /** Contents of `Input.Success` component. If not set, success is not displayed. */\n success?: React.ReactNode;\n\n /** Adds required attribute to the input and a red asterisk on the right side of label @default false */\n required?: boolean;\n\n /** If set, the required asterisk is displayed next to the label. Overrides `required` prop. Does not add required attribute to the input. @default false */\n withAsterisk?: boolean;\n\n /** Props passed down to the `Input.Label` component */\n labelProps?: InputLabelProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Props passed down to the `Input.Description` component */\n descriptionProps?: InputDescriptionProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Props passed down to the `Input.Error` component */\n errorProps?: InputErrorProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Props passed down to the `Input.Success` component */\n successProps?: InputSuccessProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Render function to wrap the input element. Useful for adding tooltips, popovers, or other wrappers around the input. @default React.Fragment */\n inputContainer?: (children: React.ReactNode) => React.ReactNode;\n\n /** Controls order and visibility of wrapper elements. Only elements included in this array will be rendered. @default ['label', 'description', 'input', 'error'] */\n inputWrapperOrder?: ('label' | 'input' | 'description' | 'error')[];\n}\n\nexport interface InputWrapperProps\n extends __InputWrapperProps, BoxProps, StylesApiProps<InputWrapperFactory>, ElementProps<'div'> {\n __staticSelector?: string;\n\n /** Props passed to Styles API context, replaces Input.Wrapper props */\n __stylesApiProps?: Record<string, any>;\n\n /** Static id used as base to generate `aria-` attributes, by default generates random id */\n id?: string;\n\n /** Controls size of `Input.Label`, `Input.Description` and `Input.Error` components */\n size?: MantineFontSize;\n\n /** Root element for the label. Use `'div'` when wrapper contains multiple input elements and you need to handle `htmlFor` manually. @default 'label' */\n labelElement?: 'label' | 'div';\n}\n\nexport type InputWrapperFactory = Factory<{\n props: InputWrapperProps;\n ref: HTMLDivElement;\n stylesNames: InputWrapperStylesNames;\n vars: InputWrapperCssVariables;\n}>;\n\nconst defaultProps = {\n labelElement: 'label',\n inputContainer: (children) => children,\n inputWrapperOrder: ['label', 'description', 'input', 'error'],\n} satisfies Partial<InputWrapperProps>;\n\nconst varsResolver = createVarsResolver<InputWrapperFactory>((_, { size }) => ({\n label: {\n '--input-label-size': getFontSize(size),\n '--input-asterisk-color': undefined,\n },\n\n error: {\n '--input-error-size': size === undefined ? undefined : `calc(${getFontSize(size)} - ${rem(2)})`,\n },\n\n success: {\n '--input-success-size':\n size === undefined ? undefined : `calc(${getFontSize(size)} - ${rem(2)})`,\n },\n\n description: {\n '--input-description-size':\n size === undefined ? undefined : `calc(${getFontSize(size)} - ${rem(2)})`,\n },\n}));\n\nexport const InputWrapper = factory<InputWrapperFactory>((_props) => {\n const props = useProps('InputWrapper', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n size,\n variant,\n __staticSelector,\n inputContainer,\n inputWrapperOrder,\n label,\n error,\n success,\n description,\n labelProps,\n descriptionProps,\n errorProps,\n successProps,\n labelElement,\n children,\n withAsterisk,\n id,\n required,\n __stylesApiProps,\n mod,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<InputWrapperFactory>({\n name: ['InputWrapper', __staticSelector],\n props: __stylesApiProps || props,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const sharedProps = {\n size,\n variant,\n __staticSelector,\n };\n\n const idBase = useId(id);\n const isRequired = typeof withAsterisk === 'boolean' ? withAsterisk : required;\n const errorId = errorProps?.id || `${idBase}-error`;\n const successId = successProps?.id || `${idBase}-success`;\n const descriptionId = descriptionProps?.id || `${idBase}-description`;\n const inputId = idBase;\n const hasError = !!error && typeof error !== 'boolean';\n const hasSuccess = !!success && typeof success !== 'boolean' && !error;\n const hasDescription = !!description;\n const errorRendered = hasError && inputWrapperOrder.includes('error');\n const successRendered = hasSuccess && inputWrapperOrder.includes('error');\n const descriptionRendered = hasDescription && inputWrapperOrder.includes('description');\n const _describedBy = `${errorRendered ? errorId : ''} ${successRendered ? successId : ''} ${descriptionRendered ? descriptionId : ''}`;\n const describedBy = _describedBy.trim().length > 0 ? _describedBy.trim() : undefined;\n const labelId = labelProps?.id || `${idBase}-label`;\n\n const _label = label && (\n <InputLabel\n key=\"label\"\n labelElement={labelElement}\n id={labelId}\n htmlFor={inputId}\n required={isRequired}\n {...sharedProps}\n {...labelProps}\n >\n {label}\n </InputLabel>\n );\n\n const _description = hasDescription && (\n <InputDescription\n key=\"description\"\n {...descriptionProps}\n {...sharedProps}\n size={descriptionProps?.size || sharedProps.size}\n id={descriptionProps?.id || descriptionId}\n >\n {description}\n </InputDescription>\n );\n\n const _input = <Fragment key=\"input\">{inputContainer(children)}</Fragment>;\n\n const _error = hasError && (\n <InputError\n {...errorProps}\n {...sharedProps}\n size={errorProps?.size || sharedProps.size}\n key=\"error\"\n id={errorProps?.id || errorId}\n >\n {error}\n </InputError>\n );\n\n const _success = hasSuccess && (\n <InputSuccess\n {...successProps}\n {...sharedProps}\n size={successProps?.size || sharedProps.size}\n key=\"success\"\n id={successProps?.id || successId}\n >\n {success}\n </InputSuccess>\n );\n\n const content = inputWrapperOrder.map((part) => {\n switch (part) {\n case 'label':\n return _label;\n case 'input':\n return _input;\n case 'description':\n return _description;\n case 'error':\n return _error || _success;\n default:\n return null;\n }\n });\n\n return (\n <InputWrapperContext\n value={{\n getStyles,\n describedBy,\n inputId,\n labelId,\n ...getInputOffsets(inputWrapperOrder, { hasDescription, hasError: hasError || hasSuccess }),\n }}\n >\n <Box\n variant={variant}\n size={size}\n mod={[{ error: !!error, success: !!success && !error }, mod]}\n id={labelElement === 'label' ? undefined : id}\n {...getStyles('root')}\n {...others}\n >\n {content}\n </Box>\n </InputWrapperContext>\n );\n});\n\nInputWrapper.classes = classes;\nInputWrapper.varsResolver = varsResolver;\nInputWrapper.displayName = '@mantine/core/InputWrapper';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InputWrapper.cjs","names":["createVarsResolver","getFontSize","rem","factory","useProps","useStyles","useId","InputLabel","InputDescription","Fragment","InputError","InputSuccess","InputWrapperContext","getInputOffsets","Box","classes"],"sources":["../../../../src/components/Input/InputWrapper/InputWrapper.tsx"],"sourcesContent":["import { Fragment } from 'react';\nimport { useId } from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n factory,\n Factory,\n getFontSize,\n MantineFontSize,\n PlaceholderPolymorphicProps,\n rem,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../../core';\nimport {\n InputDescription,\n InputDescriptionCssVariables,\n InputDescriptionProps,\n InputDescriptionStylesNames,\n} from '../InputDescription/InputDescription';\nimport {\n InputError,\n InputErrorCssVariables,\n InputErrorProps,\n InputErrorStylesNames,\n} from '../InputError/InputError';\nimport {\n InputLabel,\n InputLabelCssVariables,\n InputLabelProps,\n InputLabelStylesNames,\n} from '../InputLabel/InputLabel';\nimport {\n InputSuccess,\n InputSuccessCssVariables,\n InputSuccessProps,\n InputSuccessStylesNames,\n} from '../InputSuccess/InputSuccess';\nimport { InputWrapperContext } from '../InputWrapper.context';\nimport { getInputOffsets } from './get-input-offsets/get-input-offsets';\nimport classes from '../Input.module.css';\n\nexport type InputWrapperCssVariables = InputLabelCssVariables &\n InputErrorCssVariables &\n InputSuccessCssVariables &\n InputDescriptionCssVariables;\n\nexport type InputWrapperStylesNames =\n | 'root'\n | InputLabelStylesNames\n | InputDescriptionStylesNames\n | InputErrorStylesNames\n | InputSuccessStylesNames;\n\nexport interface __InputWrapperProps {\n /** Contents of `Input.Label` component. If not set, label is not displayed. */\n label?: React.ReactNode;\n\n /** Contents of `Input.Description` component. If not set, description is not displayed. */\n description?: React.ReactNode;\n\n /** Contents of `Input.Error` component. If not set, error is not displayed. */\n error?: React.ReactNode;\n\n /** Contents of `Input.Success` component. If not set, success is not displayed. */\n success?: React.ReactNode;\n\n /** Adds required attribute to the input and a red asterisk on the right side of label @default false */\n required?: boolean;\n\n /** If set, the required asterisk is displayed next to the label. Overrides `required` prop. Does not add required attribute to the input. @default false */\n withAsterisk?: boolean;\n\n /** Props passed down to the `Input.Label` component */\n labelProps?: InputLabelProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Props passed down to the `Input.Description` component */\n descriptionProps?: InputDescriptionProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Props passed down to the `Input.Error` component */\n errorProps?: InputErrorProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Props passed down to the `Input.Success` component */\n successProps?: InputSuccessProps & DataAttributes & PlaceholderPolymorphicProps;\n\n /** Render function to wrap the input element. Useful for adding tooltips, popovers, or other wrappers around the input. @default React.Fragment */\n inputContainer?: (children: React.ReactNode) => React.ReactNode;\n\n /** Controls order and visibility of wrapper elements. Only elements included in this array will be rendered. @default ['label', 'description', 'input', 'error'] */\n inputWrapperOrder?: ('label' | 'input' | 'description' | 'error')[];\n}\n\nexport interface InputWrapperProps\n extends __InputWrapperProps, BoxProps, StylesApiProps<InputWrapperFactory>, ElementProps<'div'> {\n __staticSelector?: string;\n\n /** Props passed to Styles API context, replaces Input.Wrapper props */\n __stylesApiProps?: Record<string, any>;\n\n /** Static id used as base to generate `aria-` attributes, by default generates random id */\n id?: string;\n\n /** Controls size of `Input.Label`, `Input.Description` and `Input.Error` components */\n size?: MantineFontSize;\n\n /** Root element for the label. Use `'div'` when wrapper contains multiple input elements and you need to handle `htmlFor` manually. @default 'label' */\n labelElement?: 'label' | 'div';\n}\n\nexport type InputWrapperFactory = Factory<{\n props: InputWrapperProps;\n ref: HTMLDivElement;\n stylesNames: InputWrapperStylesNames;\n vars: InputWrapperCssVariables;\n}>;\n\nconst defaultProps = {\n labelElement: 'label',\n inputContainer: (children) => children,\n inputWrapperOrder: ['label', 'description', 'input', 'error'],\n} satisfies Partial<InputWrapperProps>;\n\nconst varsResolver = createVarsResolver<InputWrapperFactory>((_, { size }) => ({\n label: {\n '--input-label-size': getFontSize(size),\n '--input-asterisk-color': undefined,\n },\n\n error: {\n '--input-error-size': size === undefined ? undefined : `calc(${getFontSize(size)} - ${rem(2)})`,\n },\n\n success: {\n '--input-success-size':\n size === undefined ? undefined : `calc(${getFontSize(size)} - ${rem(2)})`,\n },\n\n description: {\n '--input-description-size':\n size === undefined ? undefined : `calc(${getFontSize(size)} - ${rem(2)})`,\n },\n}));\n\nexport const InputWrapper = factory<InputWrapperFactory>((_props) => {\n const props = useProps('InputWrapper', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n size,\n variant,\n __staticSelector,\n inputContainer,\n inputWrapperOrder,\n label,\n error,\n success,\n description,\n labelProps,\n descriptionProps,\n errorProps,\n successProps,\n labelElement,\n children,\n withAsterisk,\n id,\n required,\n __stylesApiProps,\n mod,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<InputWrapperFactory>({\n name: ['InputWrapper', __staticSelector],\n props: __stylesApiProps || props,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const sharedProps = {\n size,\n variant,\n __staticSelector,\n };\n\n const idBase = useId(id);\n const isRequired = typeof withAsterisk === 'boolean' ? withAsterisk : required;\n const errorId = errorProps?.id || `${idBase}-error`;\n const successId = successProps?.id || `${idBase}-success`;\n const descriptionId = descriptionProps?.id || `${idBase}-description`;\n const inputId = idBase;\n const hasError = !!error && typeof error !== 'boolean';\n const hasSuccess = !!success && typeof success !== 'boolean' && !error;\n const hasDescription = !!description;\n const errorRendered = hasError && inputWrapperOrder.includes('error');\n const successRendered = hasSuccess && inputWrapperOrder.includes('error');\n const descriptionRendered = hasDescription && inputWrapperOrder.includes('description');\n const _describedBy = `${errorRendered ? errorId : ''} ${successRendered ? successId : ''} ${descriptionRendered ? descriptionId : ''}`;\n const describedBy = _describedBy.trim().length > 0 ? _describedBy.trim() : undefined;\n const labelId = labelProps?.id || `${idBase}-label`;\n\n const _label = label && (\n <InputLabel\n key=\"label\"\n labelElement={labelElement}\n id={labelId}\n htmlFor={inputId}\n required={isRequired}\n {...sharedProps}\n {...labelProps}\n >\n {label}\n </InputLabel>\n );\n\n const _description = hasDescription && (\n <InputDescription\n key=\"description\"\n {...descriptionProps}\n {...sharedProps}\n size={descriptionProps?.size || sharedProps.size}\n id={descriptionProps?.id || descriptionId}\n >\n {description}\n </InputDescription>\n );\n\n const _input = <Fragment key=\"input\">{inputContainer(children)}</Fragment>;\n\n const _error = hasError && (\n <InputError\n {...errorProps}\n {...sharedProps}\n size={errorProps?.size || sharedProps.size}\n key=\"error\"\n id={errorProps?.id || errorId}\n >\n {error}\n </InputError>\n );\n\n const _success = hasSuccess && (\n <InputSuccess\n {...successProps}\n {...sharedProps}\n size={successProps?.size || sharedProps.size}\n key=\"success\"\n id={successProps?.id || successId}\n >\n {success}\n </InputSuccess>\n );\n\n const content = inputWrapperOrder.map((part) => {\n switch (part) {\n case 'label':\n return _label;\n case 'input':\n return _input;\n case 'description':\n return _description;\n case 'error':\n return _error || _success;\n default:\n return null;\n }\n });\n\n return (\n <InputWrapperContext\n value={{\n getStyles,\n describedBy,\n inputId,\n labelId: _label && inputWrapperOrder.includes('label') ? labelId : undefined,\n ...getInputOffsets(inputWrapperOrder, { hasDescription, hasError: hasError || hasSuccess }),\n }}\n >\n <Box\n variant={variant}\n size={size}\n mod={[{ error: !!error, success: !!success && !error }, mod]}\n id={labelElement === 'label' ? undefined : id}\n {...getStyles('root')}\n {...others}\n >\n {content}\n </Box>\n </InputWrapperContext>\n );\n});\n\nInputWrapper.classes = classes;\nInputWrapper.varsResolver = varsResolver;\nInputWrapper.displayName = '@mantine/core/InputWrapper';\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Marquee.cjs","names":["createVarsResolver","getSpacing","factory","useProps","useStyles","Box","classes"],"sources":["../../../src/components/Marquee/Marquee.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getSpacing,\n MantineSpacing,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../core';\nimport classes from './Marquee.module.css';\n\nexport type MarqueeStylesNames = 'root' | 'content' | 'group';\nexport type MarqueeCssVariables = {\n root:\n | '--marquee-duration'\n | '--marquee-gap'\n | '--marquee-repeat'\n | '--marquee-fade-color'\n | '--marquee-fade-size';\n};\n\nexport interface MarqueeProps\n extends BoxProps, StylesApiProps<MarqueeFactory>, ElementProps<'div'> {\n /** Reverses animation direction @default false */\n reverse?: boolean;\n\n /** Pauses animation on hover @default false */\n pauseOnHover?: boolean;\n\n /** Content to scroll */\n children: React.ReactNode;\n\n /** Scroll orientation @default 'horizontal' */\n orientation?: 'horizontal' | 'vertical';\n\n /** Number of times children are repeated inline for seamless scrolling @default 4 */\n repeat?: number;\n\n /** Animation duration in ms @default
|
|
1
|
+
{"version":3,"file":"Marquee.cjs","names":["createVarsResolver","getSpacing","factory","useProps","useStyles","Box","classes"],"sources":["../../../src/components/Marquee/Marquee.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getSpacing,\n MantineSpacing,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../core';\nimport classes from './Marquee.module.css';\n\nexport type MarqueeStylesNames = 'root' | 'content' | 'group';\nexport type MarqueeCssVariables = {\n root:\n | '--marquee-duration'\n | '--marquee-gap'\n | '--marquee-repeat'\n | '--marquee-fade-color'\n | '--marquee-fade-size';\n};\n\nexport interface MarqueeProps\n extends BoxProps, StylesApiProps<MarqueeFactory>, ElementProps<'div'> {\n /** Reverses animation direction @default false */\n reverse?: boolean;\n\n /** Pauses animation on hover @default false */\n pauseOnHover?: boolean;\n\n /** Content to scroll */\n children: React.ReactNode;\n\n /** Scroll orientation @default 'horizontal' */\n orientation?: 'horizontal' | 'vertical';\n\n /** Number of times children are repeated inline for seamless scrolling @default 4 */\n repeat?: number;\n\n /** Animation duration in ms @default 100000 */\n duration?: number;\n\n /** Gap between repeated children, key of `theme.spacing` or any valid CSS value @default 'md' */\n gap?: MantineSpacing;\n\n /** Whether to show gradient fade on edges, @default true */\n fadeEdges?: boolean;\n\n /** Color of the fade gradient, @default 'var(--mantine-color-body)' */\n fadeEdgeColor?: string;\n\n /** Size of the fade gradient, @default '5%' */\n fadeEdgeSize?: string;\n}\n\nexport type MarqueeFactory = Factory<{\n props: MarqueeProps;\n ref: HTMLDivElement;\n stylesNames: MarqueeStylesNames;\n vars: MarqueeCssVariables;\n}>;\n\nconst defaultProps = {\n repeat: 4,\n duration: 100_000,\n orientation: 'horizontal',\n fadeEdges: true,\n} satisfies Partial<MarqueeProps>;\n\nconst varsResolver = createVarsResolver<MarqueeFactory>(\n (_, { duration, gap, repeat, fadeEdgeColor, fadeEdgeSize }) => ({\n root: {\n '--marquee-duration': `${duration}ms`,\n '--marquee-gap': getSpacing(gap),\n '--marquee-repeat': (repeat ?? 4).toString(),\n '--marquee-fade-color': fadeEdgeColor,\n '--marquee-fade-size': fadeEdgeSize,\n },\n })\n);\n\nexport const Marquee = factory<MarqueeFactory>((_props) => {\n const props = useProps('Marquee', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n children,\n reverse,\n pauseOnHover,\n orientation,\n repeat,\n duration,\n gap,\n fadeEdges,\n fadeEdgeColor,\n fadeEdgeSize,\n mod,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<MarqueeFactory>({\n name: 'Marquee',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const repeatedChildren = Array(repeat)\n .fill(0)\n .map((_, index) => (\n <div key={index} {...getStyles('group')}>\n {children}\n </div>\n ));\n\n return (\n <Box\n {...getStyles('root')}\n mod={[{ orientation, reverse, pauseOnHover, 'fade-edges': fadeEdges }, mod]}\n {...others}\n >\n <div {...getStyles('content')}>{repeatedChildren}</div>\n </Box>\n );\n});\n\nMarquee.classes = classes;\nMarquee.varsResolver = varsResolver;\nMarquee.displayName = '@mantine/core/Marquee';\n\nexport namespace Marquee {\n export type Props = MarqueeProps;\n export type StylesNames = MarqueeStylesNames;\n export type CssVariables = MarqueeCssVariables;\n export type Factory = MarqueeFactory;\n}\n"],"mappings":";;;;;;;;;;AAiEA,MAAM,eAAe;CACnB,QAAQ;CACR,UAAU;CACV,aAAa;CACb,WAAW;AACb;AAEA,MAAM,eAAeA,6BAAAA,oBAClB,GAAG,EAAE,UAAU,KAAK,QAAQ,eAAe,oBAAoB,EAC9D,MAAM;CACJ,sBAAsB,GAAG,SAAS;CAClC,iBAAiBC,iBAAAA,WAAW,GAAG;CAC/B,qBAAqB,UAAU,EAAA,CAAG,SAAS;CAC3C,wBAAwB;CACxB,uBAAuB;AACzB,EACF,EACF;AAEA,MAAa,UAAUC,gBAAAA,SAAyB,WAAW;CACzD,MAAM,QAAQC,kBAAAA,SAAS,WAAW,cAAc,MAAM;CACtD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,UACA,SACA,cACA,aACA,QACA,UACA,KACA,WACA,eACA,cACA,KACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAYC,mBAAAA,UAA0B;EAC1C,MAAM;EACN,SAAA,uBAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,mBAAmB,MAAM,MAAM,CAAC,CACnC,KAAK,CAAC,CAAC,CACP,KAAK,GAAG,UACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAiB,GAAI,UAAU,OAAO;EACnC;CACE,GAFK,KAEL,CACN;CAEH,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,YAAAA,KAAD;EACE,GAAI,UAAU,MAAM;EACpB,KAAK,CAAC;GAAE;GAAa;GAAS;GAAc,cAAc;EAAU,GAAG,GAAG;EAC1E,GAAI;EAEJ,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,GAAI,UAAU,SAAS;GAAI,UAAA;EAAsB,CAAA;CACnD,CAAA;AAET,CAAC;AAED,QAAQ,UAAUC,uBAAAA;AAClB,QAAQ,eAAe;AACvB,QAAQ,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Marquee.module.cjs","names":[],"sources":["../../../src/components/Marquee/Marquee.module.css"],"sourcesContent":["@keyframes marquee-horizontal {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(\n calc(\n -100% / var(--marquee-repeat, 4) - var(--marquee-gap, var(--mantine-spacing-md)) /\n var(--marquee-repeat, 4)\n )\n );\n }\n}\n\n@keyframes marquee-vertical {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(\n calc(\n -100% / var(--marquee-repeat, 4) - var(--marquee-gap, var(--mantine-spacing-md)) /\n var(--marquee-repeat, 4)\n )\n );\n }\n}\n\n.root {\n --_fade-color: var(--marquee-fade-color, var(--mantine-color-body));\n --_fade-size: var(--marquee-fade-size, 5%);\n\n position: relative;\n overflow: hidden;\n display: flex;\n max-height: 100%;\n max-width: 100%;\n\n &:where([data-orientation='horizontal']) {\n flex-direction: row;\n }\n\n &:where([data-orientation='vertical']) {\n flex-direction: column;\n }\n\n /* Fade edges using pseudo-elements */\n &[data-fade-edges]::before,\n &[data-fade-edges]::after {\n content: '';\n position: absolute;\n z-index: 1;\n pointer-events: none;\n }\n\n /* Horizontal fade edges */\n &[data-orientation='horizontal'][data-fade-edges]::before,\n &[data-orientation='horizontal'][data-fade-edges]::after {\n top: 0;\n bottom: 0;\n width: var(--_fade-size);\n }\n\n &[data-orientation='horizontal'][data-fade-edges]::before {\n left: 0;\n background: linear-gradient(to right, var(--_fade-color), transparent);\n }\n\n &[data-orientation='horizontal'][data-fade-edges]::after {\n right: 0;\n background: linear-gradient(to left, var(--_fade-color), transparent);\n }\n\n /* Vertical fade edges */\n &[data-orientation='vertical'][data-fade-edges]::before,\n &[data-orientation='vertical'][data-fade-edges]::after {\n left: 0;\n right: 0;\n height: var(--_fade-size);\n }\n\n &[data-orientation='vertical'][data-fade-edges]::before {\n top: 0;\n background: linear-gradient(to bottom, var(--_fade-color), transparent);\n }\n\n &[data-orientation='vertical'][data-fade-edges]::after {\n bottom: 0;\n background: linear-gradient(to top, var(--_fade-color), transparent);\n }\n}\n\n.content {\n display: flex;\n gap: var(--marquee-gap, var(--mantine-spacing-md));\n animation-duration: var(--marquee-duration,
|
|
1
|
+
{"version":3,"file":"Marquee.module.cjs","names":[],"sources":["../../../src/components/Marquee/Marquee.module.css"],"sourcesContent":["@keyframes marquee-horizontal {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(\n calc(\n -100% / var(--marquee-repeat, 4) - var(--marquee-gap, var(--mantine-spacing-md)) /\n var(--marquee-repeat, 4)\n )\n );\n }\n}\n\n@keyframes marquee-vertical {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(\n calc(\n -100% / var(--marquee-repeat, 4) - var(--marquee-gap, var(--mantine-spacing-md)) /\n var(--marquee-repeat, 4)\n )\n );\n }\n}\n\n.root {\n --_fade-color: var(--marquee-fade-color, var(--mantine-color-body));\n --_fade-size: var(--marquee-fade-size, 5%);\n\n position: relative;\n overflow: hidden;\n display: flex;\n max-height: 100%;\n max-width: 100%;\n\n &:where([data-orientation='horizontal']) {\n flex-direction: row;\n }\n\n &:where([data-orientation='vertical']) {\n flex-direction: column;\n }\n\n /* Fade edges using pseudo-elements */\n &[data-fade-edges]::before,\n &[data-fade-edges]::after {\n content: '';\n position: absolute;\n z-index: 1;\n pointer-events: none;\n }\n\n /* Horizontal fade edges */\n &[data-orientation='horizontal'][data-fade-edges]::before,\n &[data-orientation='horizontal'][data-fade-edges]::after {\n top: 0;\n bottom: 0;\n width: var(--_fade-size);\n }\n\n &[data-orientation='horizontal'][data-fade-edges]::before {\n left: 0;\n background: linear-gradient(to right, var(--_fade-color), transparent);\n }\n\n &[data-orientation='horizontal'][data-fade-edges]::after {\n right: 0;\n background: linear-gradient(to left, var(--_fade-color), transparent);\n }\n\n /* Vertical fade edges */\n &[data-orientation='vertical'][data-fade-edges]::before,\n &[data-orientation='vertical'][data-fade-edges]::after {\n left: 0;\n right: 0;\n height: var(--_fade-size);\n }\n\n &[data-orientation='vertical'][data-fade-edges]::before {\n top: 0;\n background: linear-gradient(to bottom, var(--_fade-color), transparent);\n }\n\n &[data-orientation='vertical'][data-fade-edges]::after {\n bottom: 0;\n background: linear-gradient(to top, var(--_fade-color), transparent);\n }\n}\n\n.content {\n display: flex;\n gap: var(--marquee-gap, var(--mantine-spacing-md));\n animation-duration: var(--marquee-duration, 100000ms);\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n\n .root[data-orientation='horizontal'] > & {\n flex-direction: row;\n animation-name: marquee-horizontal;\n }\n\n .root[data-orientation='vertical'] > & {\n flex-direction: column;\n animation-name: marquee-vertical;\n }\n\n .root[data-reverse] > & {\n animation-direction: reverse;\n }\n\n .root[data-pause-on-hover]:hover > & {\n animation-play-state: paused;\n }\n}\n\n.group {\n display: flex;\n flex-shrink: 0;\n gap: var(--marquee-gap, var(--mantine-spacing-md));\n\n .root[data-orientation='horizontal'] & {\n flex-direction: row;\n }\n\n .root[data-orientation='vertical'] & {\n flex-direction: column;\n }\n}\n"],"mappings":""}
|
|
@@ -8,10 +8,12 @@ const require_use_styles = require("../../core/styles-api/use-styles/use-styles.
|
|
|
8
8
|
const require_extract_style_props = require("../../core/Box/style-props/extract-style-props/extract-style-props.cjs");
|
|
9
9
|
const require_factory = require("../../core/factory/factory.cjs");
|
|
10
10
|
const require_ActionIcon = require("../ActionIcon/ActionIcon.cjs");
|
|
11
|
+
const require_InputWrapper_context = require("../Input/InputWrapper.context.cjs");
|
|
11
12
|
const require_Input = require("../Input/Input.cjs");
|
|
12
13
|
const require_InputBase = require("../InputBase/InputBase.cjs");
|
|
13
14
|
const require_PasswordToggleIcon = require("./PasswordToggleIcon.cjs");
|
|
14
15
|
const require_PasswordInput_module = require("./PasswordInput.module.cjs");
|
|
16
|
+
let react = require("react");
|
|
15
17
|
let _mantine_hooks = require("@mantine/hooks");
|
|
16
18
|
let clsx = require("clsx");
|
|
17
19
|
clsx = require_runtime.__toESM(clsx);
|
|
@@ -26,6 +28,13 @@ const varsResolver = require_create_vars_resolver.createVarsResolver((_, { size
|
|
|
26
28
|
"--psi-icon-size": require_get_size.getSize(size, "psi-icon-size"),
|
|
27
29
|
"--psi-button-size": require_get_size.getSize(size, "psi-button-size")
|
|
28
30
|
} }));
|
|
31
|
+
function PasswordInputField(props) {
|
|
32
|
+
const ctx = (0, react.use)(require_InputWrapper_context.InputWrapperContext);
|
|
33
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
34
|
+
...props,
|
|
35
|
+
"aria-describedby": ctx?.describedBy
|
|
36
|
+
});
|
|
37
|
+
}
|
|
29
38
|
const PasswordInput = require_factory.factory((_props) => {
|
|
30
39
|
const props = require_use_props.useProps([
|
|
31
40
|
"Input",
|
|
@@ -63,9 +72,6 @@ const PasswordInput = require_factory.factory((_props) => {
|
|
|
63
72
|
const errorId = errorProps?.id || `${uuid}-error`;
|
|
64
73
|
const successId = successProps?.id || `${uuid}-success`;
|
|
65
74
|
const descriptionId = descriptionProps?.id || `${uuid}-description`;
|
|
66
|
-
const hasError = !!error && typeof error !== "boolean";
|
|
67
|
-
const _describedBy = `${hasError ? errorId : ""} ${!!success && typeof success !== "boolean" && !hasError ? successId : ""} ${!!description ? descriptionId : ""}`;
|
|
68
|
-
const describedBy = _describedBy.trim().length > 0 ? _describedBy.trim() : void 0;
|
|
69
75
|
const visibilityToggleButton = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ActionIcon.ActionIcon, {
|
|
70
76
|
...getStyles("visibilityToggle"),
|
|
71
77
|
disabled,
|
|
@@ -163,7 +169,7 @@ const PasswordInput = require_factory.factory((_props) => {
|
|
|
163
169
|
withErrorStyles,
|
|
164
170
|
withSuccessStyles,
|
|
165
171
|
attributes,
|
|
166
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
172
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PasswordInputField, {
|
|
167
173
|
required,
|
|
168
174
|
"data-invalid": !!error || void 0,
|
|
169
175
|
"data-with-left-section": !!leftSection || void 0,
|
|
@@ -172,7 +178,6 @@ const PasswordInput = require_factory.factory((_props) => {
|
|
|
172
178
|
id: uuid,
|
|
173
179
|
dir,
|
|
174
180
|
...rest,
|
|
175
|
-
"aria-describedby": describedBy,
|
|
176
181
|
autoComplete: rest.autoComplete || "off",
|
|
177
182
|
type: _visible ? "text" : "password"
|
|
178
183
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordInput.cjs","names":["PasswordToggleIcon","createVarsResolver","getSize","factory","useProps","useId","useUncontrolled","useStyles","useResolvedStylesApi","extractStyleProps","ActionIcon","Input","cx","classes","InputBase"],"sources":["../../../src/components/PasswordInput/PasswordInput.tsx"],"sourcesContent":["import cx from 'clsx';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n extractStyleProps,\n factory,\n Factory,\n getSize,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { ActionIcon } from '../ActionIcon';\nimport { __BaseInputProps, __InputStylesNames, Input, InputVariant } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { PasswordToggleIcon } from './PasswordToggleIcon';\nimport classes from './PasswordInput.module.css';\n\nexport type PasswordInputStylesNames =\n | 'root'\n | 'visibilityToggle'\n | 'innerInput'\n | __InputStylesNames;\nexport type PasswordInputCssVariables = {\n root: '--psi-icon-size' | '--psi-button-size';\n};\n\nexport interface PasswordInputProps\n extends\n BoxProps,\n Omit<__BaseInputProps, 'pointer'>,\n StylesApiProps<PasswordInputFactory>,\n ElementProps<'input', 'size'> {\n /** A component to replace the visibility toggle icon */\n visibilityToggleIcon?: React.FC<{ reveal: boolean }>;\n\n /** Props passed down to the visibility toggle button */\n visibilityToggleButtonProps?: Record<string, any>;\n\n /** If set, the visibility toggle button is focusable with keyboard @default `false` */\n visibilityToggleFocusable?: boolean;\n\n /** If set, the input value is visible */\n visible?: boolean;\n\n /** If set, the input value is visible by default */\n defaultVisible?: boolean;\n\n /** Called when visibility changes */\n onVisibilityChange?: (visible: boolean) => void;\n}\n\nexport type PasswordInputFactory = Factory<{\n props: PasswordInputProps;\n ref: HTMLInputElement;\n stylesNames: PasswordInputStylesNames;\n vars: PasswordInputCssVariables;\n variant: InputVariant;\n}>;\n\nconst defaultProps = {\n visibilityToggleIcon: PasswordToggleIcon,\n visibilityToggleFocusable: false,\n size: 'sm',\n} satisfies Partial<PasswordInputProps>;\n\nconst varsResolver = createVarsResolver<PasswordInputFactory>((_, { size }) => ({\n root: {\n '--psi-icon-size': getSize(size, 'psi-icon-size'),\n '--psi-button-size': getSize(size, 'psi-button-size'),\n },\n}));\n\nexport const PasswordInput = factory<PasswordInputFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'PasswordInput'], defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n required,\n error,\n success,\n leftSection,\n disabled,\n id,\n variant,\n inputContainer,\n description,\n label,\n size,\n errorProps,\n successProps,\n descriptionProps,\n labelProps,\n withAsterisk,\n inputWrapperOrder,\n wrapperProps,\n radius,\n rightSection,\n rightSectionWidth,\n rightSectionPointerEvents,\n leftSectionWidth,\n visible,\n defaultVisible,\n onVisibilityChange,\n visibilityToggleIcon: VisibilityToggleIcon,\n visibilityToggleButtonProps,\n visibilityToggleFocusable,\n rightSectionProps,\n leftSectionProps,\n leftSectionPointerEvents,\n withErrorStyles,\n withSuccessStyles,\n mod,\n attributes,\n dir,\n ...others\n } = props;\n\n const uuid = useId(id);\n\n const [_visible, setVisibility] = useUncontrolled({\n value: visible,\n defaultValue: defaultVisible,\n finalValue: false,\n onChange: onVisibilityChange,\n });\n\n const toggleVisibility = () => setVisibility(!_visible);\n\n const getStyles = useStyles<PasswordInputFactory>({\n name: 'PasswordInput',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<PasswordInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const { styleProps, rest } = extractStyleProps(others);\n const errorId = errorProps?.id || `${uuid}-error`;\n const successId = successProps?.id || `${uuid}-success`;\n const descriptionId = descriptionProps?.id || `${uuid}-description`;\n const hasError = !!error && typeof error !== 'boolean';\n const hasSuccess = !!success && typeof success !== 'boolean';\n const hasDescription = !!description;\n const _describedBy = `${hasError ? errorId : ''} ${hasSuccess && !hasError ? successId : ''} ${hasDescription ? descriptionId : ''}`;\n const describedBy = _describedBy.trim().length > 0 ? _describedBy.trim() : undefined;\n\n const visibilityToggleButton = (\n <ActionIcon<'button'>\n {...getStyles('visibilityToggle')}\n disabled={disabled}\n radius={radius}\n aria-pressed={_visible}\n tabIndex={visibilityToggleFocusable ? 0 : -1}\n aria-label=\"Toggle password visibility\"\n {...visibilityToggleButtonProps}\n variant={visibilityToggleButtonProps?.variant ?? 'subtle'}\n color=\"gray\"\n unstyled={unstyled}\n onTouchEnd={(event) => {\n event.preventDefault();\n visibilityToggleButtonProps?.onTouchEnd?.(event);\n toggleVisibility();\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n visibilityToggleButtonProps?.onMouseDown?.(event);\n toggleVisibility();\n }}\n onKeyDown={(event) => {\n visibilityToggleButtonProps?.onKeyDown?.(event);\n if (event.key === ' ' || event.key === 'Enter') {\n event.preventDefault();\n toggleVisibility();\n }\n }}\n >\n <VisibilityToggleIcon reveal={_visible} />\n </ActionIcon>\n );\n\n return (\n <Input.Wrapper\n required={required}\n id={uuid}\n label={label}\n error={error}\n success={success}\n description={description}\n size={size}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n __staticSelector=\"PasswordInput\"\n __stylesApiProps={props}\n unstyled={unstyled}\n withAsterisk={withAsterisk}\n inputWrapperOrder={inputWrapperOrder}\n inputContainer={inputContainer}\n variant={variant}\n labelProps={{ ...labelProps, htmlFor: uuid }}\n descriptionProps={{ ...descriptionProps, id: descriptionId }}\n errorProps={{ ...errorProps, id: errorId }}\n successProps={{ ...successProps, id: successId }}\n mod={mod}\n attributes={attributes}\n {...getStyles('root')}\n {...styleProps}\n {...wrapperProps}\n >\n <Input\n component=\"div\"\n dir={dir}\n error={error}\n success={success}\n leftSection={leftSection}\n size={size}\n classNames={{ ...resolvedClassNames, input: cx(classes.input, resolvedClassNames?.input) }}\n styles={resolvedStyles}\n radius={radius}\n disabled={disabled}\n __staticSelector=\"PasswordInput\"\n __stylesApiProps={props}\n rightSectionWidth={rightSectionWidth}\n rightSection={rightSection ?? visibilityToggleButton}\n variant={variant}\n unstyled={unstyled}\n leftSectionWidth={leftSectionWidth}\n rightSectionPointerEvents={rightSectionPointerEvents || 'all'}\n rightSectionProps={rightSectionProps}\n leftSectionProps={leftSectionProps}\n leftSectionPointerEvents={leftSectionPointerEvents}\n withAria={false}\n withErrorStyles={withErrorStyles}\n withSuccessStyles={withSuccessStyles}\n attributes={attributes}\n >\n <input\n required={required}\n data-invalid={!!error || undefined}\n data-with-left-section={!!leftSection || undefined}\n {...getStyles('innerInput')}\n disabled={disabled}\n id={uuid}\n dir={dir}\n {...rest}\n aria-describedby={describedBy}\n autoComplete={rest.autoComplete || 'off'}\n type={_visible ? 'text' : 'password'}\n />\n </Input>\n </Input.Wrapper>\n );\n});\n\nPasswordInput.classes = { ...InputBase.classes, ...classes };\nPasswordInput.varsResolver = varsResolver;\nPasswordInput.displayName = '@mantine/core/PasswordInput';\n\nexport namespace PasswordInput {\n export type Props = PasswordInputProps;\n export type StylesNames = PasswordInputStylesNames;\n export type CssVariables = PasswordInputCssVariables;\n export type Factory = PasswordInputFactory;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PasswordInput.cjs","names":["PasswordToggleIcon","createVarsResolver","getSize","use","InputWrapperContext","factory","useProps","useId","useUncontrolled","useStyles","useResolvedStylesApi","extractStyleProps","ActionIcon","Input","cx","classes","InputBase"],"sources":["../../../src/components/PasswordInput/PasswordInput.tsx"],"sourcesContent":["import { use } from 'react';\nimport cx from 'clsx';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n ElementProps,\n extractStyleProps,\n factory,\n Factory,\n getSize,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { ActionIcon } from '../ActionIcon';\nimport {\n __BaseInputProps,\n __InputStylesNames,\n Input,\n InputVariant,\n InputWrapperContext,\n} from '../Input';\nimport { InputBase } from '../InputBase';\nimport { PasswordToggleIcon } from './PasswordToggleIcon';\nimport classes from './PasswordInput.module.css';\n\nexport type PasswordInputStylesNames =\n | 'root'\n | 'visibilityToggle'\n | 'innerInput'\n | __InputStylesNames;\nexport type PasswordInputCssVariables = {\n root: '--psi-icon-size' | '--psi-button-size';\n};\n\nexport interface PasswordInputProps\n extends\n BoxProps,\n Omit<__BaseInputProps, 'pointer'>,\n StylesApiProps<PasswordInputFactory>,\n ElementProps<'input', 'size'> {\n /** A component to replace the visibility toggle icon */\n visibilityToggleIcon?: React.FC<{ reveal: boolean }>;\n\n /** Props passed down to the visibility toggle button */\n visibilityToggleButtonProps?: Record<string, any>;\n\n /** If set, the visibility toggle button is focusable with keyboard @default `false` */\n visibilityToggleFocusable?: boolean;\n\n /** If set, the input value is visible */\n visible?: boolean;\n\n /** If set, the input value is visible by default */\n defaultVisible?: boolean;\n\n /** Called when visibility changes */\n onVisibilityChange?: (visible: boolean) => void;\n}\n\nexport type PasswordInputFactory = Factory<{\n props: PasswordInputProps;\n ref: HTMLInputElement;\n stylesNames: PasswordInputStylesNames;\n vars: PasswordInputCssVariables;\n variant: InputVariant;\n}>;\n\nconst defaultProps = {\n visibilityToggleIcon: PasswordToggleIcon,\n visibilityToggleFocusable: false,\n size: 'sm',\n} satisfies Partial<PasswordInputProps>;\n\nconst varsResolver = createVarsResolver<PasswordInputFactory>((_, { size }) => ({\n root: {\n '--psi-icon-size': getSize(size, 'psi-icon-size'),\n '--psi-button-size': getSize(size, 'psi-button-size'),\n },\n}));\n\nfunction PasswordInputField(props: React.ComponentProps<'input'>) {\n const ctx = use(InputWrapperContext);\n return <input {...props} aria-describedby={ctx?.describedBy} />;\n}\n\nexport const PasswordInput = factory<PasswordInputFactory>((_props) => {\n const props = useProps(['Input', 'InputWrapper', 'PasswordInput'], defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n required,\n error,\n success,\n leftSection,\n disabled,\n id,\n variant,\n inputContainer,\n description,\n label,\n size,\n errorProps,\n successProps,\n descriptionProps,\n labelProps,\n withAsterisk,\n inputWrapperOrder,\n wrapperProps,\n radius,\n rightSection,\n rightSectionWidth,\n rightSectionPointerEvents,\n leftSectionWidth,\n visible,\n defaultVisible,\n onVisibilityChange,\n visibilityToggleIcon: VisibilityToggleIcon,\n visibilityToggleButtonProps,\n visibilityToggleFocusable,\n rightSectionProps,\n leftSectionProps,\n leftSectionPointerEvents,\n withErrorStyles,\n withSuccessStyles,\n mod,\n attributes,\n dir,\n ...others\n } = props;\n\n const uuid = useId(id);\n\n const [_visible, setVisibility] = useUncontrolled({\n value: visible,\n defaultValue: defaultVisible,\n finalValue: false,\n onChange: onVisibilityChange,\n });\n\n const toggleVisibility = () => setVisibility(!_visible);\n\n const getStyles = useStyles<PasswordInputFactory>({\n name: 'PasswordInput',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<PasswordInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const { styleProps, rest } = extractStyleProps(others);\n const errorId = errorProps?.id || `${uuid}-error`;\n const successId = successProps?.id || `${uuid}-success`;\n const descriptionId = descriptionProps?.id || `${uuid}-description`;\n\n const visibilityToggleButton = (\n <ActionIcon<'button'>\n {...getStyles('visibilityToggle')}\n disabled={disabled}\n radius={radius}\n aria-pressed={_visible}\n tabIndex={visibilityToggleFocusable ? 0 : -1}\n aria-label=\"Toggle password visibility\"\n {...visibilityToggleButtonProps}\n variant={visibilityToggleButtonProps?.variant ?? 'subtle'}\n color=\"gray\"\n unstyled={unstyled}\n onTouchEnd={(event) => {\n event.preventDefault();\n visibilityToggleButtonProps?.onTouchEnd?.(event);\n toggleVisibility();\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n visibilityToggleButtonProps?.onMouseDown?.(event);\n toggleVisibility();\n }}\n onKeyDown={(event) => {\n visibilityToggleButtonProps?.onKeyDown?.(event);\n if (event.key === ' ' || event.key === 'Enter') {\n event.preventDefault();\n toggleVisibility();\n }\n }}\n >\n <VisibilityToggleIcon reveal={_visible} />\n </ActionIcon>\n );\n\n return (\n <Input.Wrapper\n required={required}\n id={uuid}\n label={label}\n error={error}\n success={success}\n description={description}\n size={size}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n __staticSelector=\"PasswordInput\"\n __stylesApiProps={props}\n unstyled={unstyled}\n withAsterisk={withAsterisk}\n inputWrapperOrder={inputWrapperOrder}\n inputContainer={inputContainer}\n variant={variant}\n labelProps={{ ...labelProps, htmlFor: uuid }}\n descriptionProps={{ ...descriptionProps, id: descriptionId }}\n errorProps={{ ...errorProps, id: errorId }}\n successProps={{ ...successProps, id: successId }}\n mod={mod}\n attributes={attributes}\n {...getStyles('root')}\n {...styleProps}\n {...wrapperProps}\n >\n <Input\n component=\"div\"\n dir={dir}\n error={error}\n success={success}\n leftSection={leftSection}\n size={size}\n classNames={{ ...resolvedClassNames, input: cx(classes.input, resolvedClassNames?.input) }}\n styles={resolvedStyles}\n radius={radius}\n disabled={disabled}\n __staticSelector=\"PasswordInput\"\n __stylesApiProps={props}\n rightSectionWidth={rightSectionWidth}\n rightSection={rightSection ?? visibilityToggleButton}\n variant={variant}\n unstyled={unstyled}\n leftSectionWidth={leftSectionWidth}\n rightSectionPointerEvents={rightSectionPointerEvents || 'all'}\n rightSectionProps={rightSectionProps}\n leftSectionProps={leftSectionProps}\n leftSectionPointerEvents={leftSectionPointerEvents}\n withAria={false}\n withErrorStyles={withErrorStyles}\n withSuccessStyles={withSuccessStyles}\n attributes={attributes}\n >\n <PasswordInputField\n required={required}\n data-invalid={!!error || undefined}\n data-with-left-section={!!leftSection || undefined}\n {...getStyles('innerInput')}\n disabled={disabled}\n id={uuid}\n dir={dir}\n {...rest}\n autoComplete={rest.autoComplete || 'off'}\n type={_visible ? 'text' : 'password'}\n />\n </Input>\n </Input.Wrapper>\n );\n});\n\nPasswordInput.classes = { ...InputBase.classes, ...classes };\nPasswordInput.varsResolver = varsResolver;\nPasswordInput.displayName = '@mantine/core/PasswordInput';\n\nexport namespace PasswordInput {\n export type Props = PasswordInputProps;\n export type StylesNames = PasswordInputStylesNames;\n export type CssVariables = PasswordInputCssVariables;\n export type Factory = PasswordInputFactory;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinInput.cjs","names":["createVarsResolver","getSize","factory","useProps","useId","useStyles","useResolvedStylesApi","useState","useRef","useUncontrolled","createPinArray","Group","Input","assignRef","classes","InputBase"],"sources":["../../../src/components/PinInput/PinInput.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { assignRef, useId, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n Factory,\n factory,\n getSize,\n MantineRadius,\n MantineSize,\n MantineSpacing,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { Group } from '../Group';\nimport { Input, InputProps } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { createPinArray } from './create-pin-array/create-pin-array';\nimport classes from './PinInput.module.css';\n\nconst regex = {\n number: /^[0-9]+$/,\n alphanumeric: /^[a-zA-Z0-9]+$/i,\n};\n\nexport type PinInputStylesNames = 'root' | 'pinInput' | 'input';\n\nexport type PinInputCssVariables = {\n root: '--pin-input-size';\n};\n\nexport interface PinInputProps\n extends BoxProps, StylesApiProps<PinInputFactory>, ElementProps<'div', 'onChange' | 'ref'> {\n ref?: React.Ref<HTMLInputElement>;\n\n /** Hidden input `name` attribute */\n name?: string;\n\n /** Hidden input `form` attribute */\n form?: string;\n\n /** Key of `theme.spacing` or any valid CSS value to set `gap` between inputs, numbers are converted to rem @default 'md' */\n gap?: MantineSpacing;\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 /** Controls inputs `width` and `height` @default 'sm' */\n size?: MantineSize;\n\n /** If set, the first input is focused when component is mounted @default false */\n autoFocus?: boolean;\n\n /** Controlled component value */\n value?: string;\n\n /** Uncontrolled component default value */\n defaultValue?: string;\n\n /** Called when value changes */\n onChange?: (value: string) => void;\n\n /** Called when all inputs have value */\n onComplete?: (value: string) => void;\n\n /** Inputs placeholder @default '○' */\n placeholder?: string;\n\n /** Determines whether focus should be moved automatically to the next input once filled @default true */\n manageFocus?: boolean;\n\n /** Determines whether `autocomplete=\"one-time-code\"` attribute should be set on all inputs @default true */\n oneTimeCode?: boolean;\n\n /** Base id used to generate unique ids for inputs */\n id?: string;\n\n /** Adds disabled attribute to all inputs */\n disabled?: boolean;\n\n /** Sets `aria-invalid` attribute and applies error styles to all inputs */\n error?: boolean;\n\n /** Applies success styles to all inputs */\n success?: boolean;\n\n /** Determines which values can be entered @default 'alphanumeric' */\n type?: 'alphanumeric' | 'number' | RegExp;\n\n /** Changes input type to `\"password\"` @default false */\n mask?: boolean;\n\n /** Number of inputs @default 4 */\n length?: number;\n\n /** If set, the user cannot edit the value */\n readOnly?: boolean;\n\n /** Inputs `type` attribute, inferred from the `type` prop if not specified */\n inputType?: React.HTMLInputTypeAttribute;\n\n /** `inputmode` attribute, inferred from the `type` prop if not specified */\n inputMode?:\n | 'none'\n | 'text'\n | 'tel'\n | 'url'\n | 'email'\n | 'numeric'\n | 'decimal'\n | 'search'\n | undefined;\n\n /** `aria-label` attribute */\n ariaLabel?: string;\n\n /** Props passed down to the hidden input */\n hiddenInputProps?: React.ComponentProps<'input'>;\n\n /** Assigns ref of the root element */\n rootRef?: React.Ref<HTMLDivElement>;\n\n /** Props added to the input element depending on its index */\n getInputProps?: (index: number) => InputProps & ElementProps<'input', 'size'> & DataAttributes;\n}\n\nexport type PinInputFactory = Factory<{\n props: PinInputProps;\n ref: HTMLDivElement;\n stylesNames: PinInputStylesNames;\n vars: PinInputCssVariables;\n}>;\n\nconst defaultProps = {\n gap: 'sm',\n length: 4,\n manageFocus: true,\n oneTimeCode: true,\n placeholder: '○',\n type: 'alphanumeric',\n ariaLabel: 'PinInput',\n size: 'sm',\n} satisfies Partial<PinInputProps>;\n\nconst varsResolver = createVarsResolver<PinInputFactory>((_, { size }) => ({\n root: {\n '--pin-input-size': getSize(size ?? 'sm', 'pin-input-size'),\n },\n}));\n\nexport const PinInput = factory<PinInputFactory>((props) => {\n const {\n name,\n form,\n className,\n value,\n defaultValue,\n variant,\n gap,\n style,\n size,\n classNames,\n styles,\n unstyled,\n length,\n onChange,\n onComplete,\n manageFocus,\n autoFocus,\n error,\n success,\n radius,\n disabled,\n oneTimeCode,\n placeholder,\n type,\n mask,\n readOnly,\n inputType,\n inputMode,\n ariaLabel,\n vars,\n id,\n hiddenInputProps,\n rootRef,\n getInputProps,\n attributes,\n ref,\n ...others\n } = useProps(['Input', 'PinInput'], defaultProps, props);\n\n const uuid = useId(id);\n\n const getStyles = useStyles<PinInputFactory>({\n name: 'PinInput',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<PinInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const [focusedIndex, setFocusedIndex] = useState(-1);\n const inputsRef = useRef<Array<HTMLInputElement>>([]);\n const currentLength = length ?? 4;\n\n const completedRef = useRef(false);\n\n const [_value, setValues] = useUncontrolled<string[]>({\n value: value !== undefined ? createPinArray(currentLength, value) : undefined,\n defaultValue: defaultValue?.split('').slice(0, currentLength),\n finalValue: createPinArray(currentLength, ''),\n onChange: (val) => {\n const stringValue = val.join('').trim();\n onChange?.(stringValue);\n if (stringValue.length === currentLength && !completedRef.current) {\n completedRef.current = true;\n onComplete?.(stringValue);\n } else if (stringValue.length < currentLength) {\n completedRef.current = false;\n }\n },\n });\n\n const currentValue =\n _value.length !== currentLength ? createPinArray(currentLength, _value.join('')) : _value;\n\n const _valueToString = currentValue.join('').trim();\n\n const validate = (code: string) => {\n const re = type instanceof RegExp ? type : type && type in regex ? regex[type] : null;\n return re?.test(code);\n };\n\n const focusInputField = (dir: 'next' | 'prev', index: number) => {\n if (!manageFocus) {\n return;\n }\n\n if (dir === 'next') {\n const nextIndex = index + 1;\n if (nextIndex < currentLength) {\n inputsRef.current[nextIndex]?.focus();\n }\n } else if (dir === 'prev') {\n const prevIndex = index - 1;\n if (prevIndex >= 0) {\n inputsRef.current[prevIndex]?.focus();\n }\n }\n };\n\n const setFieldValue = (val: string, index: number) => {\n const values = [...currentValue];\n values[index] = val;\n setValues(values);\n return values;\n };\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {\n const inputValue = event.target.value;\n\n if (inputValue.length > 1) {\n const isPaste = inputValue.length > 2;\n if (isPaste) {\n const isValid = validate(inputValue);\n if (isValid) {\n setValues(createPinArray(currentLength, inputValue));\n const filledCount = Math.min(inputValue.length, currentLength);\n if (filledCount < currentLength) {\n focusInputField('next', filledCount - 1);\n }\n }\n return;\n }\n\n const newChar = inputValue.split('')[inputValue.length - 1];\n if (validate(newChar)) {\n setFieldValue(newChar, index);\n focusInputField('next', index);\n }\n return;\n }\n\n if (inputValue.length === 1) {\n if (validate(inputValue)) {\n setFieldValue(inputValue, index);\n focusInputField('next', index);\n } else {\n setFieldValue('', index);\n }\n } else if (inputValue.length === 0) {\n setFieldValue('', index);\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, index: number) => {\n const { ctrlKey, metaKey, key, shiftKey, target } = event;\n const inputValue = (target as HTMLInputElement).value;\n\n if (inputMode === 'numeric') {\n const allowedKeys = ['Backspace', 'Tab', 'Control', 'Delete', 'ArrowLeft', 'ArrowRight'];\n const isModifierShortcut = ctrlKey || metaKey;\n const isAllowedKey =\n allowedKeys.includes(key) || isModifierShortcut || !Number.isNaN(Number(key));\n\n if (!isAllowedKey) {\n event.preventDefault();\n return;\n }\n }\n\n switch (key) {\n case 'ArrowLeft':\n event.preventDefault();\n focusInputField('prev', index);\n break;\n\n case 'ArrowRight':\n event.preventDefault();\n focusInputField('next', index);\n break;\n\n case 'Tab':\n if (shiftKey) {\n if (index > 0 && manageFocus) {\n event.preventDefault();\n focusInputField('prev', index);\n }\n }\n break;\n\n case ' ':\n event.preventDefault();\n focusInputField('next', index);\n break;\n\n case 'Delete':\n event.preventDefault();\n setFieldValue('', index);\n break;\n\n case 'Backspace':\n if (inputValue === '') {\n event.preventDefault();\n focusInputField('prev', index);\n } else {\n setFieldValue('', index);\n if (index < currentLength - 1) {\n event.preventDefault();\n focusInputField('prev', index);\n }\n }\n break;\n\n default:\n if (inputValue.length > 0 && key === currentValue[index]) {\n event.preventDefault();\n focusInputField('next', index);\n }\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>, index: number) => {\n event.target.select();\n setFocusedIndex(index);\n };\n\n const handleBlur = () => {\n setFocusedIndex(-1);\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n event.preventDefault();\n const pasteData = event.clipboardData.getData('text/plain').replace(/[\\n\\r\\s]+/g, '');\n const isValid = validate(pasteData.trim());\n\n if (isValid) {\n const pasteArray = createPinArray(currentLength, pasteData);\n setValues(pasteArray);\n const filledCount = pasteArray.filter((val) => val !== '').length;\n if (filledCount >= currentLength) {\n inputsRef.current[currentLength - 1]?.focus();\n } else {\n inputsRef.current[filledCount]?.focus();\n }\n }\n };\n\n return (\n <>\n <Group\n {...others}\n {...getStyles('root')}\n ref={rootRef}\n role=\"group\"\n id={uuid}\n gap={gap}\n unstyled={unstyled}\n wrap=\"nowrap\"\n variant={variant}\n __size={size}\n dir=\"ltr\"\n >\n {currentValue.map((char: string, index: number) => (\n <Input\n component=\"input\"\n {...getStyles('pinInput', {\n style: {\n '--input-padding': '0',\n '--input-text-align': 'center',\n } as React.CSSProperties,\n })}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n size={size}\n __staticSelector=\"PinInput\"\n id={`${uuid}-${index + 1}`}\n key={`${uuid}-${index}`}\n inputMode={inputMode || (type === 'number' ? 'numeric' : 'text')}\n onChange={(event) => handleChange(event, index)}\n onKeyDown={(event) => handleKeyDown(event, index)}\n onFocus={(event) => handleFocus(event, index)}\n onBlur={handleBlur}\n onPaste={handlePaste}\n type={inputType || (mask ? 'password' : type === 'number' ? 'tel' : 'text')}\n radius={radius}\n error={error}\n success={success}\n variant={variant}\n disabled={disabled}\n ref={(node) => {\n if (node) {\n index === 0 && assignRef(ref, node);\n inputsRef.current[index] = node;\n }\n }}\n autoComplete={oneTimeCode ? 'one-time-code' : 'off'}\n placeholder={focusedIndex === index ? '' : placeholder}\n value={char}\n autoFocus={autoFocus && index === 0}\n unstyled={unstyled}\n aria-label={ariaLabel}\n readOnly={readOnly}\n {...getInputProps?.(index)}\n />\n ))}\n </Group>\n\n <input type=\"hidden\" name={name} form={form} value={_valueToString} {...hiddenInputProps} />\n </>\n );\n});\n\nPinInput.classes = { ...classes, ...InputBase.classes };\nPinInput.varsResolver = varsResolver;\nPinInput.displayName = '@mantine/core/PinInput';\n\nexport namespace PinInput {\n export type Props = PinInputProps;\n export type StylesNames = PinInputStylesNames;\n export type Factory = PinInputFactory;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PinInput.cjs","names":["createVarsResolver","getSize","factory","useProps","useId","useStyles","useResolvedStylesApi","useState","useRef","useUncontrolled","createPinArray","Group","Input","assignRef","classes","InputBase"],"sources":["../../../src/components/PinInput/PinInput.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { assignRef, useId, useUncontrolled } from '@mantine/hooks';\nimport {\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n Factory,\n factory,\n getSize,\n MantineRadius,\n MantineSize,\n MantineSpacing,\n StylesApiProps,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '../../core';\nimport { Group } from '../Group';\nimport { Input, InputProps } from '../Input';\nimport { InputBase } from '../InputBase';\nimport { createPinArray } from './create-pin-array/create-pin-array';\nimport classes from './PinInput.module.css';\n\nconst regex = {\n number: /^[0-9]+$/,\n alphanumeric: /^[a-zA-Z0-9]+$/i,\n};\n\nexport type PinInputStylesNames = 'root' | 'pinInput' | 'input';\n\nexport type PinInputCssVariables = {\n root: '--pin-input-size';\n};\n\nexport interface PinInputProps\n extends BoxProps, StylesApiProps<PinInputFactory>, ElementProps<'div', 'onChange' | 'ref'> {\n ref?: React.Ref<HTMLInputElement>;\n\n /** Hidden input `name` attribute */\n name?: string;\n\n /** Hidden input `form` attribute */\n form?: string;\n\n /** Key of `theme.spacing` or any valid CSS value to set `gap` between inputs, numbers are converted to rem @default 'sm' */\n gap?: MantineSpacing;\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 /** Controls inputs `width` and `height` @default 'sm' */\n size?: MantineSize;\n\n /** If set, the first input is focused when component is mounted @default false */\n autoFocus?: boolean;\n\n /** Controlled component value */\n value?: string;\n\n /** Uncontrolled component default value */\n defaultValue?: string;\n\n /** Called when value changes */\n onChange?: (value: string) => void;\n\n /** Called when all inputs have value */\n onComplete?: (value: string) => void;\n\n /** Inputs placeholder @default '○' */\n placeholder?: string;\n\n /** Determines whether focus should be moved automatically to the next input once filled @default true */\n manageFocus?: boolean;\n\n /** Determines whether `autocomplete=\"one-time-code\"` attribute should be set on all inputs @default true */\n oneTimeCode?: boolean;\n\n /** Base id used to generate unique ids for inputs */\n id?: string;\n\n /** Adds disabled attribute to all inputs */\n disabled?: boolean;\n\n /** Sets `aria-invalid` attribute and applies error styles to all inputs */\n error?: boolean;\n\n /** Applies success styles to all inputs */\n success?: boolean;\n\n /** Determines which values can be entered @default 'alphanumeric' */\n type?: 'alphanumeric' | 'number' | RegExp;\n\n /** Changes input type to `\"password\"` @default false */\n mask?: boolean;\n\n /** Number of inputs @default 4 */\n length?: number;\n\n /** If set, the user cannot edit the value */\n readOnly?: boolean;\n\n /** Inputs `type` attribute, inferred from the `type` prop if not specified */\n inputType?: React.HTMLInputTypeAttribute;\n\n /** `inputmode` attribute, inferred from the `type` prop if not specified */\n inputMode?:\n | 'none'\n | 'text'\n | 'tel'\n | 'url'\n | 'email'\n | 'numeric'\n | 'decimal'\n | 'search'\n | undefined;\n\n /** `aria-label` attribute */\n ariaLabel?: string;\n\n /** Props passed down to the hidden input */\n hiddenInputProps?: React.ComponentProps<'input'>;\n\n /** Assigns ref of the root element */\n rootRef?: React.Ref<HTMLDivElement>;\n\n /** Props added to the input element depending on its index */\n getInputProps?: (index: number) => InputProps & ElementProps<'input', 'size'> & DataAttributes;\n}\n\nexport type PinInputFactory = Factory<{\n props: PinInputProps;\n ref: HTMLDivElement;\n stylesNames: PinInputStylesNames;\n vars: PinInputCssVariables;\n}>;\n\nconst defaultProps = {\n gap: 'sm',\n length: 4,\n manageFocus: true,\n oneTimeCode: true,\n placeholder: '○',\n type: 'alphanumeric',\n ariaLabel: 'PinInput',\n size: 'sm',\n} satisfies Partial<PinInputProps>;\n\nconst varsResolver = createVarsResolver<PinInputFactory>((_, { size }) => ({\n root: {\n '--pin-input-size': getSize(size ?? 'sm', 'pin-input-size'),\n },\n}));\n\nexport const PinInput = factory<PinInputFactory>((props) => {\n const {\n name,\n form,\n className,\n value,\n defaultValue,\n variant,\n gap,\n style,\n size,\n classNames,\n styles,\n unstyled,\n length,\n onChange,\n onComplete,\n manageFocus,\n autoFocus,\n error,\n success,\n radius,\n disabled,\n oneTimeCode,\n placeholder,\n type,\n mask,\n readOnly,\n inputType,\n inputMode,\n ariaLabel,\n vars,\n id,\n hiddenInputProps,\n rootRef,\n getInputProps,\n attributes,\n ref,\n ...others\n } = useProps(['Input', 'PinInput'], defaultProps, props);\n\n const uuid = useId(id);\n\n const getStyles = useStyles<PinInputFactory>({\n name: 'PinInput',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<PinInputFactory>({\n classNames,\n styles,\n props,\n });\n\n const [focusedIndex, setFocusedIndex] = useState(-1);\n const inputsRef = useRef<Array<HTMLInputElement>>([]);\n const currentLength = length ?? 4;\n\n const completedRef = useRef(false);\n\n const [_value, setValues] = useUncontrolled<string[]>({\n value: value !== undefined ? createPinArray(currentLength, value) : undefined,\n defaultValue: defaultValue?.split('').slice(0, currentLength),\n finalValue: createPinArray(currentLength, ''),\n onChange: (val) => {\n const stringValue = val.join('').trim();\n onChange?.(stringValue);\n if (stringValue.length === currentLength && !completedRef.current) {\n completedRef.current = true;\n onComplete?.(stringValue);\n } else if (stringValue.length < currentLength) {\n completedRef.current = false;\n }\n },\n });\n\n const currentValue =\n _value.length !== currentLength ? createPinArray(currentLength, _value.join('')) : _value;\n\n const _valueToString = currentValue.join('').trim();\n\n const validate = (code: string) => {\n const re = type instanceof RegExp ? type : type && type in regex ? regex[type] : null;\n return re?.test(code);\n };\n\n const focusInputField = (dir: 'next' | 'prev', index: number) => {\n if (!manageFocus) {\n return;\n }\n\n if (dir === 'next') {\n const nextIndex = index + 1;\n if (nextIndex < currentLength) {\n inputsRef.current[nextIndex]?.focus();\n }\n } else if (dir === 'prev') {\n const prevIndex = index - 1;\n if (prevIndex >= 0) {\n inputsRef.current[prevIndex]?.focus();\n }\n }\n };\n\n const setFieldValue = (val: string, index: number) => {\n const values = [...currentValue];\n values[index] = val;\n setValues(values);\n return values;\n };\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {\n const inputValue = event.target.value;\n\n if (inputValue.length > 1) {\n const isPaste = inputValue.length > 2;\n if (isPaste) {\n const isValid = validate(inputValue);\n if (isValid) {\n setValues(createPinArray(currentLength, inputValue));\n const filledCount = Math.min(inputValue.length, currentLength);\n if (filledCount < currentLength) {\n focusInputField('next', filledCount - 1);\n }\n }\n return;\n }\n\n const newChar = inputValue.split('')[inputValue.length - 1];\n if (validate(newChar)) {\n setFieldValue(newChar, index);\n focusInputField('next', index);\n }\n return;\n }\n\n if (inputValue.length === 1) {\n if (validate(inputValue)) {\n setFieldValue(inputValue, index);\n focusInputField('next', index);\n } else {\n setFieldValue('', index);\n }\n } else if (inputValue.length === 0) {\n setFieldValue('', index);\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, index: number) => {\n const { ctrlKey, metaKey, key, shiftKey, target } = event;\n const inputValue = (target as HTMLInputElement).value;\n\n if (inputMode === 'numeric') {\n const allowedKeys = ['Backspace', 'Tab', 'Control', 'Delete', 'ArrowLeft', 'ArrowRight'];\n const isModifierShortcut = ctrlKey || metaKey;\n const isAllowedKey =\n allowedKeys.includes(key) || isModifierShortcut || !Number.isNaN(Number(key));\n\n if (!isAllowedKey) {\n event.preventDefault();\n return;\n }\n }\n\n switch (key) {\n case 'ArrowLeft':\n event.preventDefault();\n focusInputField('prev', index);\n break;\n\n case 'ArrowRight':\n event.preventDefault();\n focusInputField('next', index);\n break;\n\n case 'Tab':\n if (shiftKey) {\n if (index > 0 && manageFocus) {\n event.preventDefault();\n focusInputField('prev', index);\n }\n }\n break;\n\n case ' ':\n event.preventDefault();\n focusInputField('next', index);\n break;\n\n case 'Delete':\n event.preventDefault();\n setFieldValue('', index);\n break;\n\n case 'Backspace':\n if (inputValue === '') {\n event.preventDefault();\n focusInputField('prev', index);\n } else {\n setFieldValue('', index);\n if (index < currentLength - 1) {\n event.preventDefault();\n focusInputField('prev', index);\n }\n }\n break;\n\n default:\n if (inputValue.length > 0 && key === currentValue[index]) {\n event.preventDefault();\n focusInputField('next', index);\n }\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>, index: number) => {\n event.target.select();\n setFocusedIndex(index);\n };\n\n const handleBlur = () => {\n setFocusedIndex(-1);\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n event.preventDefault();\n const pasteData = event.clipboardData.getData('text/plain').replace(/[\\n\\r\\s]+/g, '');\n const isValid = validate(pasteData.trim());\n\n if (isValid) {\n const pasteArray = createPinArray(currentLength, pasteData);\n setValues(pasteArray);\n const filledCount = pasteArray.filter((val) => val !== '').length;\n if (filledCount >= currentLength) {\n inputsRef.current[currentLength - 1]?.focus();\n } else {\n inputsRef.current[filledCount]?.focus();\n }\n }\n };\n\n return (\n <>\n <Group\n {...others}\n {...getStyles('root')}\n ref={rootRef}\n role=\"group\"\n id={uuid}\n gap={gap}\n unstyled={unstyled}\n wrap=\"nowrap\"\n variant={variant}\n __size={size}\n dir=\"ltr\"\n >\n {currentValue.map((char: string, index: number) => (\n <Input\n component=\"input\"\n {...getStyles('pinInput', {\n style: {\n '--input-padding': '0',\n '--input-text-align': 'center',\n } as React.CSSProperties,\n })}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n size={size}\n __staticSelector=\"PinInput\"\n id={`${uuid}-${index + 1}`}\n key={`${uuid}-${index}`}\n inputMode={inputMode || (type === 'number' ? 'numeric' : 'text')}\n onChange={(event) => handleChange(event, index)}\n onKeyDown={(event) => handleKeyDown(event, index)}\n onFocus={(event) => handleFocus(event, index)}\n onBlur={handleBlur}\n onPaste={handlePaste}\n type={inputType || (mask ? 'password' : type === 'number' ? 'tel' : 'text')}\n radius={radius}\n error={error}\n success={success}\n variant={variant}\n disabled={disabled}\n ref={(node) => {\n if (node) {\n index === 0 && assignRef(ref, node);\n inputsRef.current[index] = node;\n }\n }}\n autoComplete={oneTimeCode ? 'one-time-code' : 'off'}\n placeholder={focusedIndex === index ? '' : placeholder}\n value={char}\n autoFocus={autoFocus && index === 0}\n unstyled={unstyled}\n aria-label={ariaLabel}\n readOnly={readOnly}\n {...getInputProps?.(index)}\n />\n ))}\n </Group>\n\n <input type=\"hidden\" name={name} form={form} value={_valueToString} {...hiddenInputProps} />\n </>\n );\n});\n\nPinInput.classes = { ...classes, ...InputBase.classes };\nPinInput.varsResolver = varsResolver;\nPinInput.displayName = '@mantine/core/PinInput';\n\nexport namespace PinInput {\n export type Props = PinInputProps;\n export type StylesNames = PinInputStylesNames;\n export type Factory = PinInputFactory;\n}\n"],"mappings":"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"}
|
|
@@ -14,17 +14,26 @@ function createPortalNode(props) {
|
|
|
14
14
|
typeof props.id === "string" && node.setAttribute("id", props.id);
|
|
15
15
|
return node;
|
|
16
16
|
}
|
|
17
|
+
let cachedSharedPortalNode = null;
|
|
17
18
|
function getTargetNode({ target, reuseTargetNode, ...others }) {
|
|
18
19
|
if (target) {
|
|
19
20
|
if (typeof target === "string") return document.querySelector(target) || createPortalNode(others);
|
|
20
21
|
return target;
|
|
21
22
|
}
|
|
22
23
|
if (reuseTargetNode) {
|
|
24
|
+
if (cachedSharedPortalNode) {
|
|
25
|
+
if (document.body.contains(cachedSharedPortalNode)) return cachedSharedPortalNode;
|
|
26
|
+
cachedSharedPortalNode = null;
|
|
27
|
+
}
|
|
23
28
|
const existingNode = document.querySelector("[data-mantine-shared-portal-node]");
|
|
24
|
-
if (existingNode)
|
|
29
|
+
if (existingNode) {
|
|
30
|
+
cachedSharedPortalNode = existingNode;
|
|
31
|
+
return existingNode;
|
|
32
|
+
}
|
|
25
33
|
const node = createPortalNode(others);
|
|
26
34
|
node.setAttribute("data-mantine-shared-portal-node", "true");
|
|
27
35
|
document.body.appendChild(node);
|
|
36
|
+
cachedSharedPortalNode = node;
|
|
28
37
|
return node;
|
|
29
38
|
}
|
|
30
39
|
return createPortalNode(others);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Portal.cjs","names":["factory","useProps","useState","useRef","createPortal"],"sources":["../../../src/components/Portal/Portal.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { assignRef, useIsomorphicEffect } from '@mantine/hooks';\nimport { Factory, factory, useProps } from '../../core';\n\nfunction createPortalNode(props: React.ComponentProps<'div'>) {\n const node = document.createElement('div');\n node.setAttribute('data-portal', 'true');\n typeof props.className === 'string' &&\n node.classList.add(...props.className.split(' ').filter(Boolean));\n typeof props.style === 'object' && Object.assign(node.style, props.style);\n typeof props.id === 'string' && node.setAttribute('id', props.id);\n return node;\n}\n\nexport interface BasePortalProps extends React.ComponentProps<'div'> {\n /**\n * Target element where portal should be rendered. Accepts:\n * - HTMLElement: Renders portal inside this element\n * - string: CSS selector - renders inside first matching element\n * - undefined: Uses shared portal node or creates new one based on `reuseTargetNode`\n *\n * Note: If selector doesn't match any element, portal will not render\n */\n target?: HTMLElement | string;\n\n /**\n * When true and target is not specified, all Portal instances share a single\n * container node appended to document.body. When false, each Portal creates\n * its own container node.\n *\n * Has no effect when target is specified.\n *\n * @default true\n */\n reuseTargetNode?: boolean;\n}\n\nexport interface PortalProps extends BasePortalProps {\n /** Content to render inside the portal */\n children: React.ReactNode;\n}\n\nfunction getTargetNode({ target, reuseTargetNode, ...others }: BasePortalProps): HTMLElement {\n if (target) {\n if (typeof target === 'string') {\n return document.querySelector<HTMLElement>(target) || createPortalNode(others);\n }\n\n return target;\n }\n\n if (reuseTargetNode) {\n const existingNode = document.querySelector<HTMLElement>('[data-mantine-shared-portal-node]');\n\n if (existingNode) {\n return existingNode;\n }\n\n const node = createPortalNode(others);\n node.setAttribute('data-mantine-shared-portal-node', 'true');\n document.body.appendChild(node);\n return node;\n }\n\n return createPortalNode(others);\n}\n\nexport type PortalFactory = Factory<{\n props: PortalProps;\n ref: HTMLDivElement;\n}>;\n\nconst defaultProps = {\n reuseTargetNode: true,\n} satisfies Partial<PortalProps>;\n\nexport const Portal = factory<PortalFactory>((props) => {\n const { children, target, reuseTargetNode, ref, ...others } = useProps(\n 'Portal',\n defaultProps,\n props\n );\n\n const [mounted, setMounted] = useState(false);\n const nodeRef = useRef<HTMLElement | null>(null);\n\n useIsomorphicEffect(() => {\n setMounted(true);\n nodeRef.current = getTargetNode({ target, reuseTargetNode, ...others });\n assignRef(ref, nodeRef.current);\n\n if (!target && !reuseTargetNode && nodeRef.current) {\n document.body.appendChild(nodeRef.current);\n }\n\n return () => {\n if (!target && !reuseTargetNode && nodeRef.current) {\n document.body.removeChild(nodeRef.current);\n }\n };\n }, [target]);\n\n if (!mounted || !nodeRef.current) {\n return null;\n }\n\n return createPortal(<>{children}</>, nodeRef.current);\n});\n\nPortal.displayName = '@mantine/core/Portal';\n\nexport namespace Portal {\n export type Props = PortalProps;\n}\n"],"mappings":";;;;;;;;AAKA,SAAS,iBAAiB,OAAoC;CAC5D,MAAM,OAAO,SAAS,cAAc,KAAK;CACzC,KAAK,aAAa,eAAe,MAAM;CACvC,OAAO,MAAM,cAAc,YACzB,KAAK,UAAU,IAAI,GAAG,MAAM,UAAU,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC;CAClE,OAAO,MAAM,UAAU,YAAY,OAAO,OAAO,KAAK,OAAO,MAAM,KAAK;CACxE,OAAO,MAAM,OAAO,YAAY,KAAK,aAAa,MAAM,MAAM,EAAE;CAChE,OAAO;AACT;AA8BA,SAAS,cAAc,EAAE,QAAQ,iBAAiB,GAAG,UAAwC;CAC3F,IAAI,QAAQ;EACV,IAAI,OAAO,WAAW,UACpB,OAAO,SAAS,cAA2B,MAAM,KAAK,iBAAiB,MAAM;EAG/E,OAAO;CACT;CAEA,IAAI,iBAAiB;EACnB,MAAM,eAAe,SAAS,cAA2B,mCAAmC;EAE5F,IAAI,
|
|
1
|
+
{"version":3,"file":"Portal.cjs","names":["factory","useProps","useState","useRef","createPortal"],"sources":["../../../src/components/Portal/Portal.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { assignRef, useIsomorphicEffect } from '@mantine/hooks';\nimport { Factory, factory, useProps } from '../../core';\n\nfunction createPortalNode(props: React.ComponentProps<'div'>) {\n const node = document.createElement('div');\n node.setAttribute('data-portal', 'true');\n typeof props.className === 'string' &&\n node.classList.add(...props.className.split(' ').filter(Boolean));\n typeof props.style === 'object' && Object.assign(node.style, props.style);\n typeof props.id === 'string' && node.setAttribute('id', props.id);\n return node;\n}\n\nexport interface BasePortalProps extends React.ComponentProps<'div'> {\n /**\n * Target element where portal should be rendered. Accepts:\n * - HTMLElement: Renders portal inside this element\n * - string: CSS selector - renders inside first matching element\n * - undefined: Uses shared portal node or creates new one based on `reuseTargetNode`\n *\n * Note: If selector doesn't match any element, portal will not render\n */\n target?: HTMLElement | string;\n\n /**\n * When true and target is not specified, all Portal instances share a single\n * container node appended to document.body. When false, each Portal creates\n * its own container node.\n *\n * Has no effect when target is specified.\n *\n * @default true\n */\n reuseTargetNode?: boolean;\n}\n\nexport interface PortalProps extends BasePortalProps {\n /** Content to render inside the portal */\n children: React.ReactNode;\n}\n\nlet cachedSharedPortalNode: HTMLElement | null = null;\n\nfunction getTargetNode({ target, reuseTargetNode, ...others }: BasePortalProps): HTMLElement {\n if (target) {\n if (typeof target === 'string') {\n return document.querySelector<HTMLElement>(target) || createPortalNode(others);\n }\n\n return target;\n }\n\n if (reuseTargetNode) {\n if (cachedSharedPortalNode) {\n if (document.body.contains(cachedSharedPortalNode)) {\n return cachedSharedPortalNode;\n }\n\n cachedSharedPortalNode = null;\n }\n\n const existingNode = document.querySelector<HTMLElement>('[data-mantine-shared-portal-node]');\n\n if (existingNode) {\n cachedSharedPortalNode = existingNode;\n return existingNode;\n }\n\n const node = createPortalNode(others);\n node.setAttribute('data-mantine-shared-portal-node', 'true');\n document.body.appendChild(node);\n cachedSharedPortalNode = node;\n return node;\n }\n\n return createPortalNode(others);\n}\n\nexport type PortalFactory = Factory<{\n props: PortalProps;\n ref: HTMLDivElement;\n}>;\n\nconst defaultProps = {\n reuseTargetNode: true,\n} satisfies Partial<PortalProps>;\n\nexport const Portal = factory<PortalFactory>((props) => {\n const { children, target, reuseTargetNode, ref, ...others } = useProps(\n 'Portal',\n defaultProps,\n props\n );\n\n const [mounted, setMounted] = useState(false);\n const nodeRef = useRef<HTMLElement | null>(null);\n\n useIsomorphicEffect(() => {\n setMounted(true);\n nodeRef.current = getTargetNode({ target, reuseTargetNode, ...others });\n assignRef(ref, nodeRef.current);\n\n if (!target && !reuseTargetNode && nodeRef.current) {\n document.body.appendChild(nodeRef.current);\n }\n\n return () => {\n if (!target && !reuseTargetNode && nodeRef.current) {\n document.body.removeChild(nodeRef.current);\n }\n };\n }, [target]);\n\n if (!mounted || !nodeRef.current) {\n return null;\n }\n\n return createPortal(<>{children}</>, nodeRef.current);\n});\n\nPortal.displayName = '@mantine/core/Portal';\n\nexport namespace Portal {\n export type Props = PortalProps;\n}\n"],"mappings":";;;;;;;;AAKA,SAAS,iBAAiB,OAAoC;CAC5D,MAAM,OAAO,SAAS,cAAc,KAAK;CACzC,KAAK,aAAa,eAAe,MAAM;CACvC,OAAO,MAAM,cAAc,YACzB,KAAK,UAAU,IAAI,GAAG,MAAM,UAAU,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC;CAClE,OAAO,MAAM,UAAU,YAAY,OAAO,OAAO,KAAK,OAAO,MAAM,KAAK;CACxE,OAAO,MAAM,OAAO,YAAY,KAAK,aAAa,MAAM,MAAM,EAAE;CAChE,OAAO;AACT;AA8BA,IAAI,yBAA6C;AAEjD,SAAS,cAAc,EAAE,QAAQ,iBAAiB,GAAG,UAAwC;CAC3F,IAAI,QAAQ;EACV,IAAI,OAAO,WAAW,UACpB,OAAO,SAAS,cAA2B,MAAM,KAAK,iBAAiB,MAAM;EAG/E,OAAO;CACT;CAEA,IAAI,iBAAiB;EACnB,IAAI,wBAAwB;GAC1B,IAAI,SAAS,KAAK,SAAS,sBAAsB,GAC/C,OAAO;GAGT,yBAAyB;EAC3B;EAEA,MAAM,eAAe,SAAS,cAA2B,mCAAmC;EAE5F,IAAI,cAAc;GAChB,yBAAyB;GACzB,OAAO;EACT;EAEA,MAAM,OAAO,iBAAiB,MAAM;EACpC,KAAK,aAAa,mCAAmC,MAAM;EAC3D,SAAS,KAAK,YAAY,IAAI;EAC9B,yBAAyB;EACzB,OAAO;CACT;CAEA,OAAO,iBAAiB,MAAM;AAChC;AAOA,MAAM,eAAe,EACnB,iBAAiB,KACnB;AAEA,MAAa,SAASA,gBAAAA,SAAwB,UAAU;CACtD,MAAM,EAAE,UAAU,QAAQ,iBAAiB,KAAK,GAAG,WAAWC,kBAAAA,SAC5D,UACA,cACA,KACF;CAEA,MAAM,CAAC,SAAS,eAAA,GAAcC,MAAAA,SAAAA,CAAS,KAAK;CAC5C,MAAM,WAAA,GAAUC,MAAAA,OAAAA,CAA2B,IAAI;CAE/C,CAAA,GAAA,eAAA,oBAAA,OAA0B;EACxB,WAAW,IAAI;EACf,QAAQ,UAAU,cAAc;GAAE;GAAQ;GAAiB,GAAG;EAAO,CAAC;EACtE,CAAA,GAAA,eAAA,UAAA,CAAU,KAAK,QAAQ,OAAO;EAE9B,IAAI,CAAC,UAAU,CAAC,mBAAmB,QAAQ,SACzC,SAAS,KAAK,YAAY,QAAQ,OAAO;EAG3C,aAAa;GACX,IAAI,CAAC,UAAU,CAAC,mBAAmB,QAAQ,SACzC,SAAS,KAAK,YAAY,QAAQ,OAAO;EAE7C;CACF,GAAG,CAAC,MAAM,CAAC;CAEX,IAAI,CAAC,WAAW,CAAC,QAAQ,SACvB,OAAO;CAGT,QAAA,GAAOC,UAAAA,aAAAA,CAAa,iBAAA,GAAA,kBAAA,IAAA,CAAA,kBAAA,UAAA,EAAG,SAAW,CAAA,GAAG,QAAQ,OAAO;AACtD,CAAC;AAED,OAAO,cAAc"}
|
|
@@ -19,6 +19,8 @@ function roundValueTo(value, to) {
|
|
|
19
19
|
const precision = `${to}`.split(".")[1]?.length || 0;
|
|
20
20
|
return Number(rounded.toFixed(precision));
|
|
21
21
|
}
|
|
22
|
+
const TOUCH_MOVE_THRESHOLD = 10;
|
|
23
|
+
const EMULATED_CLICK_TIMEOUT = 500;
|
|
22
24
|
const defaultProps = {
|
|
23
25
|
size: "sm",
|
|
24
26
|
getSymbolLabel: (value) => `${value}`,
|
|
@@ -32,7 +34,7 @@ const varsResolver = require_create_vars_resolver.createVarsResolver((theme, { s
|
|
|
32
34
|
} }));
|
|
33
35
|
const Rating = require_factory.factory((_props) => {
|
|
34
36
|
const props = require_use_props.useProps("Rating", defaultProps, _props);
|
|
35
|
-
const { classNames, className, style, styles, unstyled, vars, name, id, value, defaultValue, onChange, fractions, count, onMouseEnter, readOnly, allowClear, onMouseMove, onHover, onMouseLeave, onTouchStart, onTouchEnd, size, variant, getSymbolLabel, color, emptySymbol, fullSymbol, highlightSelectedOnly, attributes, ref, ...others } = props;
|
|
37
|
+
const { classNames, className, style, styles, unstyled, vars, name, id, value, defaultValue, onChange, fractions, count, onMouseEnter, readOnly, allowClear, onMouseMove, onHover, onMouseLeave, onTouchStart, onTouchMove, onTouchCancel, onTouchEnd, size, variant, getSymbolLabel, color, emptySymbol, fullSymbol, highlightSelectedOnly, attributes, ref, ...others } = props;
|
|
36
38
|
const getStyles = require_use_styles.useStyles({
|
|
37
39
|
name: "Rating",
|
|
38
40
|
classes: require_Rating_module.default,
|
|
@@ -50,6 +52,8 @@ const Rating = require_factory.factory((_props) => {
|
|
|
50
52
|
const _name = (0, _mantine_hooks.useId)(name);
|
|
51
53
|
const _id = (0, _mantine_hooks.useId)(id);
|
|
52
54
|
const rootRef = (0, react.useRef)(null);
|
|
55
|
+
const touchStartPosition = (0, react.useRef)(null);
|
|
56
|
+
const lastTouchTimestamp = (0, react.useRef)(0);
|
|
53
57
|
const [_value, setValue] = (0, _mantine_hooks.useUncontrolled)({
|
|
54
58
|
value,
|
|
55
59
|
defaultValue,
|
|
@@ -70,6 +74,10 @@ const Rating = require_factory.factory((_props) => {
|
|
|
70
74
|
const hoverValue = (dir === "rtl" ? right - x : x - left) / symbolWidth;
|
|
71
75
|
return (0, _mantine_hooks.clamp)(roundValueTo(hoverValue + decimalUnit / 2, decimalUnit), decimalUnit, _count);
|
|
72
76
|
};
|
|
77
|
+
const applyValue = (newValue) => {
|
|
78
|
+
if (allowClear && newValue === stableValueRounded) setValue(0);
|
|
79
|
+
else setValue(newValue);
|
|
80
|
+
};
|
|
73
81
|
const handleMouseEnter = (event) => {
|
|
74
82
|
onMouseEnter?.(event);
|
|
75
83
|
!readOnly && setOutside(false);
|
|
@@ -90,15 +98,31 @@ const Rating = require_factory.factory((_props) => {
|
|
|
90
98
|
};
|
|
91
99
|
const handleTouchStart = (event) => {
|
|
92
100
|
const { touches } = event;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
101
|
+
touchStartPosition.current = touches.length === 1 ? {
|
|
102
|
+
x: touches[0].clientX,
|
|
103
|
+
y: touches[0].clientY
|
|
104
|
+
} : null;
|
|
98
105
|
onTouchStart?.(event);
|
|
99
106
|
};
|
|
107
|
+
const handleTouchMove = (event) => {
|
|
108
|
+
const startPosition = touchStartPosition.current;
|
|
109
|
+
const touch = event.touches[0];
|
|
110
|
+
if (startPosition && touch && Math.hypot(touch.clientX - startPosition.x, touch.clientY - startPosition.y) > TOUCH_MOVE_THRESHOLD) touchStartPosition.current = null;
|
|
111
|
+
onTouchMove?.(event);
|
|
112
|
+
};
|
|
113
|
+
const handleTouchCancel = (event) => {
|
|
114
|
+
touchStartPosition.current = null;
|
|
115
|
+
onTouchCancel?.(event);
|
|
116
|
+
};
|
|
100
117
|
const handleTouchEnd = (event) => {
|
|
101
|
-
|
|
118
|
+
const startPosition = touchStartPosition.current;
|
|
119
|
+
const touch = event.changedTouches[0];
|
|
120
|
+
touchStartPosition.current = null;
|
|
121
|
+
if (startPosition && touch && !readOnly) {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
applyValue(getRatingFromCoordinates(touch.clientX));
|
|
124
|
+
lastTouchTimestamp.current = Date.now();
|
|
125
|
+
}
|
|
102
126
|
onTouchEnd?.(event);
|
|
103
127
|
};
|
|
104
128
|
const handleItemBlur = () => isOutside && setHovered(-1);
|
|
@@ -109,11 +133,8 @@ const Rating = require_factory.factory((_props) => {
|
|
|
109
133
|
}
|
|
110
134
|
};
|
|
111
135
|
const handleChange = (event) => {
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
if (allowClear && newValue === stableValueRounded) setValue(0);
|
|
115
|
-
else setValue(newValue);
|
|
116
|
-
}
|
|
136
|
+
if (readOnly || Date.now() - lastTouchTimestamp.current < EMULATED_CLICK_TIMEOUT) return;
|
|
137
|
+
applyValue(typeof event === "number" ? event : parseFloat(event.target.value));
|
|
117
138
|
};
|
|
118
139
|
const items = Array(_count).fill(0).map((_, index) => {
|
|
119
140
|
const integerValue = index + 1;
|
|
@@ -152,6 +173,8 @@ const Rating = require_factory.factory((_props) => {
|
|
|
152
173
|
onMouseEnter: handleMouseEnter,
|
|
153
174
|
onMouseLeave: handleMouseLeave,
|
|
154
175
|
onTouchStart: handleTouchStart,
|
|
176
|
+
onTouchMove: handleTouchMove,
|
|
177
|
+
onTouchCancel: handleTouchCancel,
|
|
155
178
|
onTouchEnd: handleTouchEnd,
|
|
156
179
|
variant,
|
|
157
180
|
size,
|