@spear-ai/spectral 1.16.4 → 1.16.6
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/dist/Button.js +2 -2
- package/dist/ControlGroup/ControlGroupSelect.js +2 -2
- package/dist/ControlGroup/ControlGroupSelect.js.map +1 -1
- package/dist/Dialog.d.ts +2 -0
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js +38 -7
- package/dist/Dialog.js.map +1 -1
- package/dist/Drawer.d.ts +4 -2
- package/dist/Drawer.d.ts.map +1 -1
- package/dist/Drawer.js +52 -15
- package/dist/Drawer.js.map +1 -1
- package/dist/InputOTP.js +2 -2
- package/dist/InputOTP.js.map +1 -1
- package/dist/InputSearch.d.ts +68 -0
- package/dist/InputSearch.d.ts.map +1 -0
- package/dist/InputSearch.js +373 -0
- package/dist/InputSearch.js.map +1 -0
- package/dist/MultiSelect/MultiSelectBase.js +2 -2
- package/dist/Select.js +2 -2
- package/dist/Select.js.map +1 -1
- package/dist/Switch/SwitchBase.js +2 -2
- package/dist/Switch/SwitchBase.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js +2 -2
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js.map +1 -1
- package/dist/components/SpectralProvider/SpectralProvider.js +2 -2
- package/dist/components/SpectralProvider/SpectralProvider.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/primitives/slot.js +2 -2
- package/dist/primitives/slot.js.map +1 -1
- package/dist/styles/spectral.css +1 -1
- package/package.json +1 -1
package/dist/Button.js
CHANGED
|
@@ -3,7 +3,7 @@ import { LoaderIcon } from "./Icons/LoaderIcon.js";
|
|
|
3
3
|
import { cn } from "./utils/twUtils.js";
|
|
4
4
|
import { Slot } from "./primitives/slot.js";
|
|
5
5
|
import { Children, isValidElement } from "react";
|
|
6
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
8
8
|
|
|
9
9
|
//#region src/components/Button/Button.tsx
|
|
@@ -78,7 +78,7 @@ const Button = ({ asChild = false, children, className, dataTestId, disabled, en
|
|
|
78
78
|
tabIndex: canUseAsChild && disabled ? -1 : void 0,
|
|
79
79
|
type: canUseAsChild ? void 0 : type,
|
|
80
80
|
...props,
|
|
81
|
-
children: canUseAsChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
81
|
+
children: canUseAsChild ? children : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
82
82
|
startIcon && /* @__PURE__ */ jsx("span", {
|
|
83
83
|
className: cn("flex", variant !== "unstyled" && "pr-1"),
|
|
84
84
|
"aria-hidden": true,
|
|
@@ -6,7 +6,7 @@ import { Input } from "../primitives/input.js";
|
|
|
6
6
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../primitives/select.js";
|
|
7
7
|
import { ControlGroup, ControlGroupItem, useControlGroup } from "../ControlGroup.js";
|
|
8
8
|
import { useId } from "react";
|
|
9
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
|
|
11
11
|
//#region src/components/ControlGroup/ControlGroupSelect.tsx
|
|
12
12
|
const numberInputNoSpinner = "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none";
|
|
@@ -127,7 +127,7 @@ const ControlGroupSelectInner = ({ amountStep, dataTestId, dropdownWidth, inputA
|
|
|
127
127
|
placeholder: selectCaption
|
|
128
128
|
})
|
|
129
129
|
});
|
|
130
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ControlGroupItem, {
|
|
130
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ControlGroupItem, {
|
|
131
131
|
className: cn(useAboveLabels ? firstItemAboveLabelClasses : void 0, inputItemClassName),
|
|
132
132
|
children: useAboveLabels ? /* @__PURE__ */ jsxs("div", {
|
|
133
133
|
className: fieldStackClass,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroupSelect.js","names":[],"sources":["../../src/components/ControlGroup/ControlGroupSelect.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { Input } from '@primitives/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@primitives/select'\nimport { getStateClasses, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useId, type ComponentProps } from 'react'\nimport { ControlGroup, ControlGroupItem, useControlGroup, type ControlGroupProps } from './ControlGroup'\n\nconst numberInputNoSpinner = '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'\nconst defaultInputLabel = 'Amount'\nconst defaultSelectLabel = 'Select an option'\n\nexport interface SelectOptionType {\n disabled?: boolean\n label: string\n value: string\n}\n\n/** `inline`: `inputPlaceholder` / `selectPlaceholder` show inside the fields. `above`: same strings render as labels above each control (no inner placeholders). */\nexport type ControlGroupSelectCaptionLayout = 'above' | 'inline'\n\ntype ControlGroupSelectInputControlProps =\n | {\n inputValue: ComponentProps<typeof Input>['value']\n onInputChange: ComponentProps<typeof Input>['onChange']\n }\n | {\n inputValue?: undefined\n onInputChange?: undefined\n }\n\ntype ControlGroupSelectBaseProps = ComponentProps<typeof Select> &\n Pick<ControlGroupProps, 'orientation'> & {\n amountStep?: number\n /** Accessible name for the group wrapper (use when there is no visible group heading). */\n ariaLabel?: string\n captionLayout?: ControlGroupSelectCaptionLayout\n className?: string\n dataTestId?: string\n disabled?: boolean\n dropdownWidth?: DropdownWidth\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n /** Class applied to the input `ControlGroupItem` segment for width/split composition. */\n inputItemClassName?: string\n /** When `captionLayout` is `inline`, overrides the input's accessible name (defaults to `inputPlaceholder` when set). */\n inputAriaLabel?: string\n inputPlaceholder?: string\n maxAmount?: number\n /** Number of message lines to reserve (default: 1). */\n messageReserveLines?: number\n /** Whether to keep message space reserved when hidden (default: false). */\n messageReserveSpace?: boolean\n minAmount?: number\n selectPlaceholder?: string\n /** When `captionLayout` is `inline` and `selectPlaceholder` is empty, sets the select trigger's accessible name. */\n selectAriaLabel?: string\n /** Class applied to the select `ControlGroupItem` segment for width/split composition. */\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n state?: Exclude<FormFieldState, 'disabled'>\n type?: 'number' | 'text'\n warningMessage?: string | string[] | Record<string, unknown> | null\n }\n\nexport type ControlGroupSelectProps = ControlGroupSelectBaseProps & ControlGroupSelectInputControlProps\n\nconst fieldStackClass = 'flex w-full min-w-0 flex-col gap-1.5'\nconst groupedFieldBaseClasses =\n 'h-12! min-h-12! border-2! border-input-border bg-input-bg text-base text-input-text transition duration-200 placeholder:text-input-text-placeholder hover:border-input-border--hover focus-visible:border-input-border--focus focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus disabled:pointer-events-none disabled:border-input-border--disabled disabled:bg-input-bg--disabled disabled:text-input-text--disabled'\n\nconst getFieldMinWidth = (caption?: string, extraCharacters: number = 0): string | undefined => {\n const normalizedCaption = caption?.trim()\n if (!normalizedCaption) return undefined\n return `${Math.max(normalizedCaption.length + extraCharacters, 8)}ch`\n}\n\nconst getReadableLabel = (label: string | undefined, fallback: string): string => {\n const normalizedLabel = label?.trim()\n return normalizedLabel && normalizedLabel.length > 0 ? normalizedLabel : fallback\n}\n\nexport const ControlGroupSelect = ({\n amountStep,\n ariaLabel,\n captionLayout = 'inline',\n className,\n dataTestId = 'spectral-control-group-select',\n disabled,\n errorMessage,\n id,\n dropdownWidth = 'trigger',\n inputAriaLabel,\n inputPlaceholder,\n inputItemClassName,\n inputValue,\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxAmount = 1000000,\n minAmount = 0,\n onInputChange,\n orientation = 'horizontal',\n selectAriaLabel,\n selectItemClassName,\n selectOptions,\n selectPlaceholder,\n state = 'default',\n type = 'number',\n warningMessage,\n ...selectProps\n}: ControlGroupSelectProps) => {\n const baseId = useId()\n const idPrefix = id ?? baseId\n const inputId = `${idPrefix}-amount`\n const selectTriggerId = `${idPrefix}-select`\n const inputLabelId = `${inputId}-label`\n const selectLabelId = `${selectTriggerId}-label`\n\n const useAboveLabels = captionLayout === 'above'\n const inputCaption = useAboveLabels ? undefined : inputPlaceholder\n const selectCaption = useAboveLabels ? undefined : selectPlaceholder\n const inputLabelText = getReadableLabel(inputPlaceholder, defaultInputLabel)\n const selectLabelText = getReadableLabel(selectPlaceholder, defaultSelectLabel)\n\n const inputAccessibleName = inputAriaLabel ?? (useAboveLabels ? undefined : inputLabelText)\n const selectTriggerAriaLabel = selectAriaLabel ?? (useAboveLabels ? undefined : selectLabelText)\n const inputMinWidth = getFieldMinWidth(inputPlaceholder, 3)\n const selectTriggerMinWidth = getFieldMinWidth(selectPlaceholder, 5)\n const groupAriaLabel = ariaLabel ?? `${inputLabelText} and ${selectLabelText}`\n\n const isDisabled = !!disabled\n const isInputControlled = inputValue !== undefined && onInputChange !== undefined\n\n return (\n <ControlGroup\n aria-label={groupAriaLabel}\n className={className}\n data-testid={dataTestId}\n disabled={disabled}\n errorMessage={errorMessage}\n id={idPrefix}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n orientation={orientation}\n state={state}\n warningMessage={warningMessage}\n >\n <ControlGroupSelectInner\n amountStep={amountStep}\n dataTestId={dataTestId}\n inputAccessibleName={inputAccessibleName}\n inputCaption={inputCaption}\n inputId={inputId}\n inputLabelId={inputLabelId}\n inputLabelText={inputLabelText}\n inputItemClassName={inputItemClassName}\n inputMinWidth={inputMinWidth}\n inputValue={isInputControlled ? inputValue : undefined}\n isDisabled={isDisabled}\n maxAmount={maxAmount}\n minAmount={minAmount}\n onInputChange={isInputControlled ? onInputChange : undefined}\n dropdownWidth={dropdownWidth}\n selectCaption={selectCaption}\n selectOptions={selectOptions}\n selectLabelId={selectLabelId}\n selectLabelText={selectLabelText}\n selectItemClassName={selectItemClassName}\n selectProps={selectProps}\n selectTriggerAriaLabel={selectTriggerAriaLabel}\n selectTriggerId={selectTriggerId}\n selectTriggerMinWidth={selectTriggerMinWidth}\n type={type}\n useAboveLabels={useAboveLabels}\n />\n </ControlGroup>\n )\n}\n\ninterface ControlGroupSelectInnerProps {\n amountStep?: number\n dataTestId: string\n dropdownWidth: DropdownWidth\n inputAccessibleName?: string\n inputCaption?: string\n inputId: string\n inputLabelId: string\n inputLabelText: string\n inputItemClassName?: string\n inputMinWidth?: string\n inputValue?: ComponentProps<typeof Input>['value']\n isDisabled: boolean\n maxAmount: number\n minAmount: number\n onInputChange?: ComponentProps<typeof Input>['onChange']\n selectCaption?: string\n selectLabelId: string\n selectLabelText: string\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n selectProps: Omit<ComponentProps<typeof Select>, 'children'>\n selectTriggerAriaLabel?: string\n selectTriggerId: string\n selectTriggerMinWidth?: string\n type: 'number' | 'text'\n useAboveLabels: boolean\n}\n\nconst ControlGroupSelectInner = ({\n amountStep,\n dataTestId,\n dropdownWidth,\n inputAccessibleName,\n inputCaption,\n inputId,\n inputLabelId,\n inputLabelText,\n inputItemClassName,\n inputMinWidth,\n inputValue,\n isDisabled,\n maxAmount,\n minAmount,\n onInputChange,\n selectCaption,\n selectLabelId,\n selectLabelText,\n selectItemClassName,\n selectOptions,\n selectProps,\n selectTriggerAriaLabel,\n selectTriggerId,\n selectTriggerMinWidth,\n type,\n useAboveLabels,\n}: ControlGroupSelectInnerProps) => {\n const { messageId, orientation, state } = useControlGroup()\n const isSelectOpenControlled = selectProps.open !== undefined\n const handleSelectOpenChange: NonNullable<ComponentProps<typeof Select>['onOpenChange']> = (nextOpen) => {\n selectProps.onOpenChange?.(nextOpen)\n }\n\n const inputRadiusClasses = orientation === 'horizontal' ? 'rounded-s-md rounded-e-none' : 'rounded-ss-md rounded-se-md rounded-es-none rounded-ee-none'\n const selectRadiusClasses = orientation === 'horizontal' ? 'rounded-s-none rounded-e-md' : 'rounded-ss-none rounded-se-none rounded-es-md rounded-ee-md'\n const firstItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0' : 'mbe-0'\n const secondItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0 [&>*:last-child]:-ms-0.5' : 'mbe-0 [&>*:last-child]:-mt-0.5'\n\n const inputElement = (\n <Input\n aria-describedby={messageId}\n aria-label={inputAccessibleName}\n aria-labelledby={useAboveLabels ? inputLabelId : undefined}\n className={cn(groupedFieldBaseClasses, inputRadiusClasses, getStateClasses(state), type === 'number' && numberInputNoSpinner, type === 'number' && 'tabular-nums')}\n data-testid={`${dataTestId}-input`}\n disabled={isDisabled}\n id={useAboveLabels ? inputId : undefined}\n type={type === 'number' ? 'number' : 'text'}\n placeholder={inputCaption}\n style={inputMinWidth ? { minWidth: inputMinWidth } : undefined}\n min={minAmount ?? 0}\n max={maxAmount ?? 1000000}\n {...(inputValue !== undefined && onInputChange !== undefined ? { value: inputValue, onChange: onInputChange } : {})}\n step={amountStep ?? 1}\n />\n )\n\n const selectTriggerElement = (\n <SelectTrigger\n aria-describedby={messageId}\n aria-label={selectTriggerAriaLabel}\n aria-labelledby={useAboveLabels ? selectLabelId : undefined}\n className={cn(\n 'text-input-text data-placeholder:text-input-text-placeholder!',\n selectRadiusClasses,\n 'px-4 w-full justify-between focus-visible:border-input-border--focus focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus',\n getStateClasses(state),\n )}\n data-testid={`${dataTestId}-select-trigger`}\n disabled={isDisabled}\n id={useAboveLabels ? selectTriggerId : undefined}\n style={selectTriggerMinWidth ? { minWidth: selectTriggerMinWidth } : undefined}\n >\n <SelectValue className='min-w-0 block max-w-full truncate text-left whitespace-nowrap text-input-text! data-placeholder:text-input-text-placeholder!' placeholder={selectCaption} />\n </SelectTrigger>\n )\n\n return (\n <>\n <ControlGroupItem className={cn(useAboveLabels ? firstItemAboveLabelClasses : undefined, inputItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={inputId} id={inputLabelId}>\n {inputLabelText}\n </Label>\n {inputElement}\n </div>\n ) : (\n inputElement\n )}\n </ControlGroupItem>\n <Select {...selectProps} data-testid={`${dataTestId}-select-root`} disabled={isDisabled} {...(isSelectOpenControlled ? { open: selectProps.open } : {})} onOpenChange={handleSelectOpenChange}>\n <ControlGroupItem className={cn(useAboveLabels ? secondItemAboveLabelClasses : undefined, selectItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={selectTriggerId} id={selectLabelId}>\n {selectLabelText}\n </Label>\n {selectTriggerElement}\n </div>\n ) : (\n selectTriggerElement\n )}\n </ControlGroupItem>\n <SelectContent data-testid={`${dataTestId}-select-content`} dropdownWidth={dropdownWidth}>\n {selectOptions.map((option) => (\n <SelectItem disabled={option.disabled} key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ControlGroupSelect.js","names":[],"sources":["../../src/components/ControlGroup/ControlGroupSelect.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { Input } from '@primitives/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@primitives/select'\nimport { getStateClasses, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useId, type ComponentProps } from 'react'\nimport { ControlGroup, ControlGroupItem, useControlGroup, type ControlGroupProps } from './ControlGroup'\n\nconst numberInputNoSpinner = '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'\nconst defaultInputLabel = 'Amount'\nconst defaultSelectLabel = 'Select an option'\n\nexport interface SelectOptionType {\n disabled?: boolean\n label: string\n value: string\n}\n\n/** `inline`: `inputPlaceholder` / `selectPlaceholder` show inside the fields. `above`: same strings render as labels above each control (no inner placeholders). */\nexport type ControlGroupSelectCaptionLayout = 'above' | 'inline'\n\ntype ControlGroupSelectInputControlProps =\n | {\n inputValue: ComponentProps<typeof Input>['value']\n onInputChange: ComponentProps<typeof Input>['onChange']\n }\n | {\n inputValue?: undefined\n onInputChange?: undefined\n }\n\ntype ControlGroupSelectBaseProps = ComponentProps<typeof Select> &\n Pick<ControlGroupProps, 'orientation'> & {\n amountStep?: number\n /** Accessible name for the group wrapper (use when there is no visible group heading). */\n ariaLabel?: string\n captionLayout?: ControlGroupSelectCaptionLayout\n className?: string\n dataTestId?: string\n disabled?: boolean\n dropdownWidth?: DropdownWidth\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n /** Class applied to the input `ControlGroupItem` segment for width/split composition. */\n inputItemClassName?: string\n /** When `captionLayout` is `inline`, overrides the input's accessible name (defaults to `inputPlaceholder` when set). */\n inputAriaLabel?: string\n inputPlaceholder?: string\n maxAmount?: number\n /** Number of message lines to reserve (default: 1). */\n messageReserveLines?: number\n /** Whether to keep message space reserved when hidden (default: false). */\n messageReserveSpace?: boolean\n minAmount?: number\n selectPlaceholder?: string\n /** When `captionLayout` is `inline` and `selectPlaceholder` is empty, sets the select trigger's accessible name. */\n selectAriaLabel?: string\n /** Class applied to the select `ControlGroupItem` segment for width/split composition. */\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n state?: Exclude<FormFieldState, 'disabled'>\n type?: 'number' | 'text'\n warningMessage?: string | string[] | Record<string, unknown> | null\n }\n\nexport type ControlGroupSelectProps = ControlGroupSelectBaseProps & ControlGroupSelectInputControlProps\n\nconst fieldStackClass = 'flex w-full min-w-0 flex-col gap-1.5'\nconst groupedFieldBaseClasses =\n 'h-12! min-h-12! border-2! border-input-border bg-input-bg text-base text-input-text transition duration-200 placeholder:text-input-text-placeholder hover:border-input-border--hover focus-visible:border-input-border--focus focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus disabled:pointer-events-none disabled:border-input-border--disabled disabled:bg-input-bg--disabled disabled:text-input-text--disabled'\n\nconst getFieldMinWidth = (caption?: string, extraCharacters: number = 0): string | undefined => {\n const normalizedCaption = caption?.trim()\n if (!normalizedCaption) return undefined\n return `${Math.max(normalizedCaption.length + extraCharacters, 8)}ch`\n}\n\nconst getReadableLabel = (label: string | undefined, fallback: string): string => {\n const normalizedLabel = label?.trim()\n return normalizedLabel && normalizedLabel.length > 0 ? normalizedLabel : fallback\n}\n\nexport const ControlGroupSelect = ({\n amountStep,\n ariaLabel,\n captionLayout = 'inline',\n className,\n dataTestId = 'spectral-control-group-select',\n disabled,\n errorMessage,\n id,\n dropdownWidth = 'trigger',\n inputAriaLabel,\n inputPlaceholder,\n inputItemClassName,\n inputValue,\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxAmount = 1000000,\n minAmount = 0,\n onInputChange,\n orientation = 'horizontal',\n selectAriaLabel,\n selectItemClassName,\n selectOptions,\n selectPlaceholder,\n state = 'default',\n type = 'number',\n warningMessage,\n ...selectProps\n}: ControlGroupSelectProps) => {\n const baseId = useId()\n const idPrefix = id ?? baseId\n const inputId = `${idPrefix}-amount`\n const selectTriggerId = `${idPrefix}-select`\n const inputLabelId = `${inputId}-label`\n const selectLabelId = `${selectTriggerId}-label`\n\n const useAboveLabels = captionLayout === 'above'\n const inputCaption = useAboveLabels ? undefined : inputPlaceholder\n const selectCaption = useAboveLabels ? undefined : selectPlaceholder\n const inputLabelText = getReadableLabel(inputPlaceholder, defaultInputLabel)\n const selectLabelText = getReadableLabel(selectPlaceholder, defaultSelectLabel)\n\n const inputAccessibleName = inputAriaLabel ?? (useAboveLabels ? undefined : inputLabelText)\n const selectTriggerAriaLabel = selectAriaLabel ?? (useAboveLabels ? undefined : selectLabelText)\n const inputMinWidth = getFieldMinWidth(inputPlaceholder, 3)\n const selectTriggerMinWidth = getFieldMinWidth(selectPlaceholder, 5)\n const groupAriaLabel = ariaLabel ?? `${inputLabelText} and ${selectLabelText}`\n\n const isDisabled = !!disabled\n const isInputControlled = inputValue !== undefined && onInputChange !== undefined\n\n return (\n <ControlGroup\n aria-label={groupAriaLabel}\n className={className}\n data-testid={dataTestId}\n disabled={disabled}\n errorMessage={errorMessage}\n id={idPrefix}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n orientation={orientation}\n state={state}\n warningMessage={warningMessage}\n >\n <ControlGroupSelectInner\n amountStep={amountStep}\n dataTestId={dataTestId}\n inputAccessibleName={inputAccessibleName}\n inputCaption={inputCaption}\n inputId={inputId}\n inputLabelId={inputLabelId}\n inputLabelText={inputLabelText}\n inputItemClassName={inputItemClassName}\n inputMinWidth={inputMinWidth}\n inputValue={isInputControlled ? inputValue : undefined}\n isDisabled={isDisabled}\n maxAmount={maxAmount}\n minAmount={minAmount}\n onInputChange={isInputControlled ? onInputChange : undefined}\n dropdownWidth={dropdownWidth}\n selectCaption={selectCaption}\n selectOptions={selectOptions}\n selectLabelId={selectLabelId}\n selectLabelText={selectLabelText}\n selectItemClassName={selectItemClassName}\n selectProps={selectProps}\n selectTriggerAriaLabel={selectTriggerAriaLabel}\n selectTriggerId={selectTriggerId}\n selectTriggerMinWidth={selectTriggerMinWidth}\n type={type}\n useAboveLabels={useAboveLabels}\n />\n </ControlGroup>\n )\n}\n\ninterface ControlGroupSelectInnerProps {\n amountStep?: number\n dataTestId: string\n dropdownWidth: DropdownWidth\n inputAccessibleName?: string\n inputCaption?: string\n inputId: string\n inputLabelId: string\n inputLabelText: string\n inputItemClassName?: string\n inputMinWidth?: string\n inputValue?: ComponentProps<typeof Input>['value']\n isDisabled: boolean\n maxAmount: number\n minAmount: number\n onInputChange?: ComponentProps<typeof Input>['onChange']\n selectCaption?: string\n selectLabelId: string\n selectLabelText: string\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n selectProps: Omit<ComponentProps<typeof Select>, 'children'>\n selectTriggerAriaLabel?: string\n selectTriggerId: string\n selectTriggerMinWidth?: string\n type: 'number' | 'text'\n useAboveLabels: boolean\n}\n\nconst ControlGroupSelectInner = ({\n amountStep,\n dataTestId,\n dropdownWidth,\n inputAccessibleName,\n inputCaption,\n inputId,\n inputLabelId,\n inputLabelText,\n inputItemClassName,\n inputMinWidth,\n inputValue,\n isDisabled,\n maxAmount,\n minAmount,\n onInputChange,\n selectCaption,\n selectLabelId,\n selectLabelText,\n selectItemClassName,\n selectOptions,\n selectProps,\n selectTriggerAriaLabel,\n selectTriggerId,\n selectTriggerMinWidth,\n type,\n useAboveLabels,\n}: ControlGroupSelectInnerProps) => {\n const { messageId, orientation, state } = useControlGroup()\n const isSelectOpenControlled = selectProps.open !== undefined\n const handleSelectOpenChange: NonNullable<ComponentProps<typeof Select>['onOpenChange']> = (nextOpen) => {\n selectProps.onOpenChange?.(nextOpen)\n }\n\n const inputRadiusClasses = orientation === 'horizontal' ? 'rounded-s-md rounded-e-none' : 'rounded-ss-md rounded-se-md rounded-es-none rounded-ee-none'\n const selectRadiusClasses = orientation === 'horizontal' ? 'rounded-s-none rounded-e-md' : 'rounded-ss-none rounded-se-none rounded-es-md rounded-ee-md'\n const firstItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0' : 'mbe-0'\n const secondItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0 [&>*:last-child]:-ms-0.5' : 'mbe-0 [&>*:last-child]:-mt-0.5'\n\n const inputElement = (\n <Input\n aria-describedby={messageId}\n aria-label={inputAccessibleName}\n aria-labelledby={useAboveLabels ? inputLabelId : undefined}\n className={cn(groupedFieldBaseClasses, inputRadiusClasses, getStateClasses(state), type === 'number' && numberInputNoSpinner, type === 'number' && 'tabular-nums')}\n data-testid={`${dataTestId}-input`}\n disabled={isDisabled}\n id={useAboveLabels ? inputId : undefined}\n type={type === 'number' ? 'number' : 'text'}\n placeholder={inputCaption}\n style={inputMinWidth ? { minWidth: inputMinWidth } : undefined}\n min={minAmount ?? 0}\n max={maxAmount ?? 1000000}\n {...(inputValue !== undefined && onInputChange !== undefined ? { value: inputValue, onChange: onInputChange } : {})}\n step={amountStep ?? 1}\n />\n )\n\n const selectTriggerElement = (\n <SelectTrigger\n aria-describedby={messageId}\n aria-label={selectTriggerAriaLabel}\n aria-labelledby={useAboveLabels ? selectLabelId : undefined}\n className={cn(\n 'text-input-text data-placeholder:text-input-text-placeholder!',\n selectRadiusClasses,\n 'px-4 w-full justify-between focus-visible:border-input-border--focus focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus',\n getStateClasses(state),\n )}\n data-testid={`${dataTestId}-select-trigger`}\n disabled={isDisabled}\n id={useAboveLabels ? selectTriggerId : undefined}\n style={selectTriggerMinWidth ? { minWidth: selectTriggerMinWidth } : undefined}\n >\n <SelectValue className='min-w-0 block max-w-full truncate text-left whitespace-nowrap text-input-text! data-placeholder:text-input-text-placeholder!' placeholder={selectCaption} />\n </SelectTrigger>\n )\n\n return (\n <>\n <ControlGroupItem className={cn(useAboveLabels ? firstItemAboveLabelClasses : undefined, inputItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={inputId} id={inputLabelId}>\n {inputLabelText}\n </Label>\n {inputElement}\n </div>\n ) : (\n inputElement\n )}\n </ControlGroupItem>\n <Select {...selectProps} data-testid={`${dataTestId}-select-root`} disabled={isDisabled} {...(isSelectOpenControlled ? { open: selectProps.open } : {})} onOpenChange={handleSelectOpenChange}>\n <ControlGroupItem className={cn(useAboveLabels ? secondItemAboveLabelClasses : undefined, selectItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={selectTriggerId} id={selectLabelId}>\n {selectLabelText}\n </Label>\n {selectTriggerElement}\n </div>\n ) : (\n selectTriggerElement\n )}\n </ControlGroupItem>\n <SelectContent data-testid={`${dataTestId}-select-content`} dropdownWidth={dropdownWidth}>\n {selectOptions.map((option) => (\n <SelectItem disabled={option.disabled} key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )\n}\n"],"mappings":"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"}
|
package/dist/Dialog.d.ts
CHANGED
|
@@ -51,10 +51,12 @@ declare const DialogFooter: ({
|
|
|
51
51
|
...props
|
|
52
52
|
}: ComponentProps<'div'>) => _$react_jsx_runtime0.JSX.Element;
|
|
53
53
|
declare const DialogTitle: ({
|
|
54
|
+
children,
|
|
54
55
|
className,
|
|
55
56
|
...props
|
|
56
57
|
}: ComponentProps<typeof DialogPrimitive.Title>) => _$react_jsx_runtime0.JSX.Element;
|
|
57
58
|
declare const DialogDescription: ({
|
|
59
|
+
children,
|
|
58
60
|
className,
|
|
59
61
|
...props
|
|
60
62
|
}: ComponentProps<typeof DialogPrimitive.Description>) => _$react_jsx_runtime0.JSX.Element;
|
package/dist/Dialog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","names":[],"sources":["../src/components/Dialog/Dialog.tsx"],"mappings":";;;;;;cAMM,MAAA;EAAM,MAAA;EAAA,KAAA;EAAA,GAAA;AAAA,GAIT,IAAA,CAAK,cAAA,QAAsB,eAAA,CAAgB,IAAA;EAC5C,MAAA;EACA,aAAA;AAAA,MACD,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIK,aAAA;EAAA,GAAa;AAAA,GAAkB,cAAA,QAAsB,eAAA,CAAgB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI7E,YAAA;EAAA,GAAY;AAAA,GAAkB,cAAA,QAAsB,eAAA,CAAgB,MAAA,MAAO,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI3E,WAAA;EAAW,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,QAAsB,eAAA,CAAgB,KAAA,MAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIpF,aAAA;EAAa,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,QAAsB,eAAA,CAAgB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAYxF,aAAA;EAAa,QAAA;EAAA,SAAA;EAAA,aAAA;EAAA,eAAA;EAAA,iBAAA;EAAA,oBAAA;EAAA,eAAA;EAAA,GAAA;AAAA,GAShB,cAAA,QAAsB,eAAA,CAAgB,OAAA;EACvC,aAAA;EACA,eAAA,IAAmB,KAAA,EAAO,aAAA;EAC1B,iBAAA,IAAqB,KAAA,EAAO,YAAA,GAAe,UAAA;EAC3C,oBAAA,IAAwB,KAAA,EAAO,YAAA;EAC/B,eAAA;AAAA,MACD,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAmCK,YAAA;EAAY,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,YAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI9D,YAAA;EAAY,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,YAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","names":[],"sources":["../src/components/Dialog/Dialog.tsx"],"mappings":";;;;;;cAMM,MAAA;EAAM,MAAA;EAAA,KAAA;EAAA,GAAA;AAAA,GAIT,IAAA,CAAK,cAAA,QAAsB,eAAA,CAAgB,IAAA;EAC5C,MAAA;EACA,aAAA;AAAA,MACD,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIK,aAAA;EAAA,GAAa;AAAA,GAAkB,cAAA,QAAsB,eAAA,CAAgB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI7E,YAAA;EAAA,GAAY;AAAA,GAAkB,cAAA,QAAsB,eAAA,CAAgB,MAAA,MAAO,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI3E,WAAA;EAAW,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,QAAsB,eAAA,CAAgB,KAAA,MAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIpF,aAAA;EAAa,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,QAAsB,eAAA,CAAgB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAYxF,aAAA;EAAa,QAAA;EAAA,SAAA;EAAA,aAAA;EAAA,eAAA;EAAA,iBAAA;EAAA,oBAAA;EAAA,eAAA;EAAA,GAAA;AAAA,GAShB,cAAA,QAAsB,eAAA,CAAgB,OAAA;EACvC,aAAA;EACA,eAAA,IAAmB,KAAA,EAAO,aAAA;EAC1B,iBAAA,IAAqB,KAAA,EAAO,YAAA,GAAe,UAAA;EAC3C,oBAAA,IAAwB,KAAA,EAAO,YAAA;EAC/B,eAAA;AAAA,MACD,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAmCK,YAAA;EAAY,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,YAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI9D,YAAA;EAAY,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,YAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAM9D,WAAA;EAAW,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAuC,cAAA,QAAsB,eAAA,CAAgB,KAAA,MAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAY9F,iBAAA;EAAiB,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAuC,cAAA,QAAsB,eAAA,CAAgB,WAAA,MAAY,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/Dialog.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { CloseIcon } from "./Icons/CloseIcon.js";
|
|
3
3
|
import { cn } from "./utils/twUtils.js";
|
|
4
|
-
import "react";
|
|
4
|
+
import { isValidElement } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
7
7
|
import { RemoveScroll } from "react-remove-scroll";
|
|
@@ -87,20 +87,51 @@ const DialogFooter = ({ className, ...props }) => {
|
|
|
87
87
|
...props
|
|
88
88
|
});
|
|
89
89
|
};
|
|
90
|
-
const
|
|
91
|
-
|
|
90
|
+
const hasTextContent = (value) => typeof value === "string" ? value.trim().length > 0 : typeof value === "number";
|
|
91
|
+
const DialogTitle = ({ children, className, ...props }) => {
|
|
92
|
+
if (hasTextContent(children)) return /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
92
93
|
className: cn("text-2xl font-semibold leading-none", className),
|
|
93
94
|
"data-slot": "dialog-title",
|
|
94
95
|
"data-testid": "spectral-dialog-title",
|
|
95
|
-
...props
|
|
96
|
+
...props,
|
|
97
|
+
children
|
|
98
|
+
});
|
|
99
|
+
if (isValidElement(children)) return /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
100
|
+
asChild: true,
|
|
101
|
+
"data-slot": "dialog-title",
|
|
102
|
+
"data-testid": "spectral-dialog-title",
|
|
103
|
+
...props,
|
|
104
|
+
children
|
|
105
|
+
});
|
|
106
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
107
|
+
className,
|
|
108
|
+
"data-slot": "dialog-title",
|
|
109
|
+
"data-testid": "spectral-dialog-title",
|
|
110
|
+
...props,
|
|
111
|
+
children
|
|
96
112
|
});
|
|
97
113
|
};
|
|
98
|
-
const DialogDescription = ({ className, ...props }) => {
|
|
99
|
-
return /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
114
|
+
const DialogDescription = ({ children, className, ...props }) => {
|
|
115
|
+
if (hasTextContent(children)) return /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
100
116
|
className: cn("text-muted-foreground text-sm", className),
|
|
101
117
|
"data-slot": "dialog-description",
|
|
102
118
|
"data-testid": "spectral-dialog-description",
|
|
103
|
-
...props
|
|
119
|
+
...props,
|
|
120
|
+
children
|
|
121
|
+
});
|
|
122
|
+
if (isValidElement(children)) return /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
123
|
+
asChild: true,
|
|
124
|
+
"data-slot": "dialog-description",
|
|
125
|
+
"data-testid": "spectral-dialog-description",
|
|
126
|
+
...props,
|
|
127
|
+
children
|
|
128
|
+
});
|
|
129
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
130
|
+
className,
|
|
131
|
+
"data-slot": "dialog-description",
|
|
132
|
+
"data-testid": "spectral-dialog-description",
|
|
133
|
+
...props,
|
|
134
|
+
children
|
|
104
135
|
});
|
|
105
136
|
};
|
|
106
137
|
|
package/dist/Dialog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","names":[],"sources":["../src/components/Dialog/Dialog.tsx"],"sourcesContent":["import { CloseIcon } from '@components/Icons/CloseIcon'\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\nimport { RemoveScroll } from 'react-remove-scroll'\n\nconst Dialog = ({\n isOpen,\n modal = false,\n ...props\n}: Omit<ComponentProps<typeof DialogPrimitive.Root>, 'open'> & {\n isOpen?: boolean\n dialogOverlay?: boolean\n}) => {\n return <DialogPrimitive.Root open={isOpen} modal={modal} data-slot='dialog' data-testid='spectral-dialog' {...props} />\n}\n\nconst DialogTrigger = ({ ...props }: ComponentProps<typeof DialogPrimitive.Trigger>) => {\n return <DialogPrimitive.Trigger asChild data-testid='spectral-dialog-trigger' {...props} />\n}\n\nconst DialogPortal = ({ ...props }: ComponentProps<typeof DialogPrimitive.Portal>) => {\n return <DialogPrimitive.Portal data-slot='dialog-portal' data-testid='dialog-portal' {...props} />\n}\n\nconst DialogClose = ({ className, ...props }: ComponentProps<typeof DialogPrimitive.Close>) => {\n return <DialogPrimitive.Close asChild data-slot='dialog-close' data-testid='spectral-dialog-close' {...props} className={cn('hover:cursor-pointer', className)} />\n}\n\nconst DialogOverlay = ({ className, ...props }: ComponentProps<typeof DialogPrimitive.Overlay>) => {\n return (\n <DialogPrimitive.Overlay\n className={cn('inset-0 bg-black/50 backdrop-blur-sm fixed z-50 motion-safe:data-[state=open]:animate-in motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=closed]:animate-out',\n 'motion-safe:data-[state=closed]:fade-out-0', className)}\n data-slot='dialog-overlay'\n data-testid='spectral-dialog-overlay'\n {...props}\n />\n )\n}\n\nconst DialogContent = ({\n children,\n className,\n dialogOverlay = true,\n onEscapeKeyDown,\n onInteractOutside,\n onPointerDownOutside,\n showCloseButton = true,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Content> & {\n dialogOverlay?: boolean\n onEscapeKeyDown?: (event: KeyboardEvent) => void\n onInteractOutside?: (event: PointerEvent | FocusEvent) => void\n onPointerDownOutside?: (event: PointerEvent) => void\n showCloseButton?: boolean\n}) => {\n return (\n <DialogPortal data-slot='dialog-portal' data-testid='spectral-dialog-portal'>\n {dialogOverlay && <DialogOverlay />}\n <DialogPrimitive.Content\n className={cn(\n 'max-w-xl gap-4 rounded-lg p-6 shadow-lg has-[[data-slot=dialog-footer]]:pb-0 fixed top-[50%] left-[50%] z-50 flex max-h-[90vh] w-full -translate-x-1/2 -translate-y-1/2 flex-col overflow-y-auto overscroll-contain bg-dialog-bg',\n 'motion-safe:data-[state=open]:duration-200 motion-safe:data-[state=open]:animate-in motion-safe:data-[state=open]:slide-in-from-bottom-20 motion-safe:data-[state=open]:zoom-in-100!',\n 'motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=closed]:zoom-out-95',\n RemoveScroll.classNames.fullWidth,\n className,\n )}\n data-slot='dialog-content'\n data-testid='spectral-dialog-content'\n onEscapeKeyDown={onEscapeKeyDown}\n onInteractOutside={onInteractOutside}\n onPointerDownOutside={onPointerDownOutside}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n className={`focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-accent data-[state=open]:text-text-primary top-4 right-4 rounded-xs absolute opacity-70 transition-opacity hover:opacity-100 hover:cursor-pointer disabled:pointer-events-none data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:shrink-0`}\n data-slot='dialog-close'\n data-testid='spectral-dialog-close'\n >\n <CloseIcon size={18} />\n <span className='sr-only'>Close dialog</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nconst DialogHeader = ({ className, ...props }: ComponentProps<'div'>) => {\n return <div className={cn('gap-2 sm:text-left flex flex-col text-center', className)} data-slot='dialog-header' data-testid='spectral-dialog-header' {...props} />\n}\n\nconst DialogFooter = ({ className, ...props }: ComponentProps<'div'>) => {\n return <div className={cn('gap-2 sm:flex-row sm:justify-end bottom-0 py-4 px-6 -mx-6 sticky z-10 flex flex-col-reverse bg-dialog-bg/85', className)} data-slot='dialog-footer' data-testid='spectral-dialog-footer' {...props} />\n}\n\nconst DialogTitle = ({ className, ...props }: ComponentProps<typeof DialogPrimitive.Title>) => {\n return <DialogPrimitive.Title className={cn('text-2xl font-semibold leading-none', className)} data-slot='dialog-title' data-testid='spectral-dialog-title' {...props}
|
|
1
|
+
{"version":3,"file":"Dialog.js","names":[],"sources":["../src/components/Dialog/Dialog.tsx"],"sourcesContent":["import { CloseIcon } from '@components/Icons/CloseIcon'\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { cn } from '@utils/twUtils'\nimport { isValidElement, type ComponentProps, type ReactNode } from 'react'\nimport { RemoveScroll } from 'react-remove-scroll'\n\nconst Dialog = ({\n isOpen,\n modal = false,\n ...props\n}: Omit<ComponentProps<typeof DialogPrimitive.Root>, 'open'> & {\n isOpen?: boolean\n dialogOverlay?: boolean\n}) => {\n return <DialogPrimitive.Root open={isOpen} modal={modal} data-slot='dialog' data-testid='spectral-dialog' {...props} />\n}\n\nconst DialogTrigger = ({ ...props }: ComponentProps<typeof DialogPrimitive.Trigger>) => {\n return <DialogPrimitive.Trigger asChild data-testid='spectral-dialog-trigger' {...props} />\n}\n\nconst DialogPortal = ({ ...props }: ComponentProps<typeof DialogPrimitive.Portal>) => {\n return <DialogPrimitive.Portal data-slot='dialog-portal' data-testid='dialog-portal' {...props} />\n}\n\nconst DialogClose = ({ className, ...props }: ComponentProps<typeof DialogPrimitive.Close>) => {\n return <DialogPrimitive.Close asChild data-slot='dialog-close' data-testid='spectral-dialog-close' {...props} className={cn('hover:cursor-pointer', className)} />\n}\n\nconst DialogOverlay = ({ className, ...props }: ComponentProps<typeof DialogPrimitive.Overlay>) => {\n return (\n <DialogPrimitive.Overlay\n className={cn('inset-0 bg-black/50 backdrop-blur-sm fixed z-50 motion-safe:data-[state=open]:animate-in motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=closed]:animate-out',\n 'motion-safe:data-[state=closed]:fade-out-0', className)}\n data-slot='dialog-overlay'\n data-testid='spectral-dialog-overlay'\n {...props}\n />\n )\n}\n\nconst DialogContent = ({\n children,\n className,\n dialogOverlay = true,\n onEscapeKeyDown,\n onInteractOutside,\n onPointerDownOutside,\n showCloseButton = true,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Content> & {\n dialogOverlay?: boolean\n onEscapeKeyDown?: (event: KeyboardEvent) => void\n onInteractOutside?: (event: PointerEvent | FocusEvent) => void\n onPointerDownOutside?: (event: PointerEvent) => void\n showCloseButton?: boolean\n}) => {\n return (\n <DialogPortal data-slot='dialog-portal' data-testid='spectral-dialog-portal'>\n {dialogOverlay && <DialogOverlay />}\n <DialogPrimitive.Content\n className={cn(\n 'max-w-xl gap-4 rounded-lg p-6 shadow-lg has-[[data-slot=dialog-footer]]:pb-0 fixed top-[50%] left-[50%] z-50 flex max-h-[90vh] w-full -translate-x-1/2 -translate-y-1/2 flex-col overflow-y-auto overscroll-contain bg-dialog-bg',\n 'motion-safe:data-[state=open]:duration-200 motion-safe:data-[state=open]:animate-in motion-safe:data-[state=open]:slide-in-from-bottom-20 motion-safe:data-[state=open]:zoom-in-100!',\n 'motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=closed]:zoom-out-95',\n RemoveScroll.classNames.fullWidth,\n className,\n )}\n data-slot='dialog-content'\n data-testid='spectral-dialog-content'\n onEscapeKeyDown={onEscapeKeyDown}\n onInteractOutside={onInteractOutside}\n onPointerDownOutside={onPointerDownOutside}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n className={`focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-accent data-[state=open]:text-text-primary top-4 right-4 rounded-xs absolute opacity-70 transition-opacity hover:opacity-100 hover:cursor-pointer disabled:pointer-events-none data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:shrink-0`}\n data-slot='dialog-close'\n data-testid='spectral-dialog-close'\n >\n <CloseIcon size={18} />\n <span className='sr-only'>Close dialog</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nconst DialogHeader = ({ className, ...props }: ComponentProps<'div'>) => {\n return <div className={cn('gap-2 sm:text-left flex flex-col text-center', className)} data-slot='dialog-header' data-testid='spectral-dialog-header' {...props} />\n}\n\nconst DialogFooter = ({ className, ...props }: ComponentProps<'div'>) => {\n return <div className={cn('gap-2 sm:flex-row sm:justify-end bottom-0 py-4 px-6 -mx-6 sticky z-10 flex flex-col-reverse bg-dialog-bg/85', className)} data-slot='dialog-footer' data-testid='spectral-dialog-footer' {...props} />\n}\n\nconst hasTextContent = (value: ReactNode) => (typeof value === 'string' ? value.trim().length > 0 : typeof value === 'number')\n\nconst DialogTitle = ({ children, className, ...props }: ComponentProps<typeof DialogPrimitive.Title>) => {\n if (hasTextContent(children)) {\n return <DialogPrimitive.Title className={cn('text-2xl font-semibold leading-none', className)} data-slot='dialog-title' data-testid='spectral-dialog-title' {...props}>{children}</DialogPrimitive.Title>\n }\n\n if (isValidElement(children)) {\n return <DialogPrimitive.Title asChild data-slot='dialog-title' data-testid='spectral-dialog-title' {...props}>{children}</DialogPrimitive.Title>\n }\n\n return <DialogPrimitive.Title className={className} data-slot='dialog-title' data-testid='spectral-dialog-title' {...props}>{children}</DialogPrimitive.Title>\n}\n\nconst DialogDescription = ({ children, className, ...props }: ComponentProps<typeof DialogPrimitive.Description>) => {\n if (hasTextContent(children)) {\n return <DialogPrimitive.Description className={cn('text-muted-foreground text-sm', className)} data-slot='dialog-description' data-testid='spectral-dialog-description' {...props}>{children}</DialogPrimitive.Description>\n }\n\n if (isValidElement(children)) {\n return <DialogPrimitive.Description asChild data-slot='dialog-description' data-testid='spectral-dialog-description' {...props}>{children}</DialogPrimitive.Description>\n }\n\n return <DialogPrimitive.Description className={className} data-slot='dialog-description' data-testid='spectral-dialog-description' {...props}>{children}</DialogPrimitive.Description>\n}\n\nexport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger }\n"],"mappings":"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"}
|
package/dist/Drawer.d.ts
CHANGED
|
@@ -7,14 +7,15 @@ interface DrawerProps {
|
|
|
7
7
|
className?: string;
|
|
8
8
|
children?: ReactNode;
|
|
9
9
|
defaultOpen?: boolean;
|
|
10
|
-
description?:
|
|
10
|
+
description?: ReactNode;
|
|
11
11
|
direction?: 'left' | 'right' | 'top' | 'bottom';
|
|
12
12
|
dismissible?: boolean;
|
|
13
|
+
dragBehavior?: 'surface' | 'handle' | 'none';
|
|
13
14
|
modal?: boolean;
|
|
14
15
|
onOpenChange?: (open: boolean) => void;
|
|
15
16
|
open?: boolean;
|
|
16
17
|
size?: string;
|
|
17
|
-
title?:
|
|
18
|
+
title?: ReactNode;
|
|
18
19
|
trigger: ReactNode;
|
|
19
20
|
}
|
|
20
21
|
declare const Drawer: ({
|
|
@@ -24,6 +25,7 @@ declare const Drawer: ({
|
|
|
24
25
|
description,
|
|
25
26
|
direction,
|
|
26
27
|
dismissible,
|
|
28
|
+
dragBehavior,
|
|
27
29
|
modal,
|
|
28
30
|
onOpenChange,
|
|
29
31
|
open,
|
package/dist/Drawer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.d.ts","names":[],"sources":["../src/components/Drawer/Drawer.tsx"],"mappings":";;;;;UAKiB,WAAA;EACf,SAAA;EACA,QAAA,GAAW,SAAA;EACX,WAAA;EACA,WAAA;
|
|
1
|
+
{"version":3,"file":"Drawer.d.ts","names":[],"sources":["../src/components/Drawer/Drawer.tsx"],"mappings":";;;;;UAKiB,WAAA;EACf,SAAA;EACA,QAAA,GAAW,SAAA;EACX,WAAA;EACA,WAAA,GAAc,SAAA;EACd,SAAA;EACA,WAAA;EACA,YAAA;EACA,KAAA;EACA,YAAA,IAAgB,IAAA;EAChB,IAAA;EACA,IAAA;EACA,KAAA,GAAQ,SAAA;EACR,OAAA,EAAS,SAAA;AAAA;AAAA,cAmBE,MAAA;EAAM,QAAA;EAAA,SAAA;EAAA,WAAA;EAAA,WAAA;EAAA,SAAA;EAAA,WAAA;EAAA,YAAA;EAAA,KAAA;EAAA,YAAA;EAAA,IAAA;EAAA,IAAA;EAAA,KAAA;EAAA;AAAA,GAahB,WAAA,KAAW,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/Drawer.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { cn } from "./utils/twUtils.js";
|
|
3
3
|
import { SpectralProvider } from "./components/SpectralProvider/SpectralProvider.js";
|
|
4
|
-
import "react";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { Fragment, isValidElement } from "react";
|
|
5
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Drawer as Drawer$1 } from "vaul";
|
|
7
7
|
|
|
8
8
|
//#region src/components/Drawer/Drawer.tsx
|
|
9
|
-
const
|
|
9
|
+
const hasRenderableText = (value) => typeof value === "string" ? value.trim().length > 0 : typeof value === "number";
|
|
10
|
+
const hasRenderableContent = (value) => {
|
|
11
|
+
if (hasRenderableText(value)) return true;
|
|
12
|
+
if (value === null || value === void 0 || typeof value === "boolean" || typeof value === "string") return false;
|
|
13
|
+
return true;
|
|
14
|
+
};
|
|
15
|
+
const isElementAndNotFragment = (element) => isValidElement(element) && element.type !== Fragment;
|
|
16
|
+
const Drawer = ({ children, className, defaultOpen = false, description, direction = "right", dismissible = true, dragBehavior = "surface", modal = true, onOpenChange, open, size = "380px", title, trigger }) => {
|
|
10
17
|
const baseStyles = "font-sans! fixed";
|
|
11
|
-
const hasTitle =
|
|
12
|
-
const hasDescription =
|
|
18
|
+
const hasTitle = hasRenderableContent(title);
|
|
19
|
+
const hasDescription = hasRenderableContent(description);
|
|
20
|
+
const isTextTitle = hasRenderableText(title);
|
|
21
|
+
const isTextDescription = hasRenderableText(description);
|
|
22
|
+
const isCustomTitleElement = isElementAndNotFragment(title);
|
|
23
|
+
const isCustomDescriptionElement = isElementAndNotFragment(description);
|
|
24
|
+
const handleOnly = dragBehavior === "handle" || dragBehavior === "none";
|
|
25
|
+
const shouldRenderHandle = dragBehavior === "handle";
|
|
13
26
|
const { className: directionClassName, style } = {
|
|
14
27
|
left: {
|
|
15
28
|
className: cn(baseStyles, "top-0 bottom-0 left-0 shadow-[20px_0_20px_var(--color-black-40)]"),
|
|
@@ -33,6 +46,7 @@ const Drawer = ({ children, className, defaultOpen = false, description, directi
|
|
|
33
46
|
defaultOpen,
|
|
34
47
|
direction,
|
|
35
48
|
dismissible,
|
|
49
|
+
handleOnly,
|
|
36
50
|
modal,
|
|
37
51
|
onOpenChange,
|
|
38
52
|
open,
|
|
@@ -53,16 +67,39 @@ const Drawer = ({ children, className, defaultOpen = false, description, directi
|
|
|
53
67
|
className: "flex h-full min-h-0 flex-col",
|
|
54
68
|
children: [
|
|
55
69
|
/* @__PURE__ */ jsx(Drawer$1.Close, {}),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
shouldRenderHandle && /* @__PURE__ */ jsx(Drawer$1.Handle, { "data-testid": "spectral-drawer-handle" }),
|
|
71
|
+
hasTitle && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
72
|
+
isTextTitle && /* @__PURE__ */ jsx(Drawer$1.Title, {
|
|
73
|
+
className: "px-3 pt-4 text-xl font-semibold text-text-primary",
|
|
74
|
+
"data-testid": "spectral-drawer-title",
|
|
75
|
+
children: title
|
|
76
|
+
}),
|
|
77
|
+
!isTextTitle && isCustomTitleElement && /* @__PURE__ */ jsx(Drawer$1.Title, {
|
|
78
|
+
asChild: true,
|
|
79
|
+
"data-testid": "spectral-drawer-title",
|
|
80
|
+
children: title
|
|
81
|
+
}),
|
|
82
|
+
!isTextTitle && !isCustomTitleElement && /* @__PURE__ */ jsx(Drawer$1.Title, {
|
|
83
|
+
"data-testid": "spectral-drawer-title",
|
|
84
|
+
children: title
|
|
85
|
+
})
|
|
86
|
+
] }),
|
|
87
|
+
hasDescription && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
88
|
+
isTextDescription && /* @__PURE__ */ jsx(Drawer$1.Description, {
|
|
89
|
+
className: "mb-2 px-3 text-xs! text-text-secondary! uppercase",
|
|
90
|
+
"data-testid": "spectral-drawer-description",
|
|
91
|
+
children: description
|
|
92
|
+
}),
|
|
93
|
+
!isTextDescription && isCustomDescriptionElement && /* @__PURE__ */ jsx(Drawer$1.Description, {
|
|
94
|
+
asChild: true,
|
|
95
|
+
"data-testid": "spectral-drawer-description",
|
|
96
|
+
children: description
|
|
97
|
+
}),
|
|
98
|
+
!isTextDescription && !isCustomDescriptionElement && /* @__PURE__ */ jsx(Drawer$1.Description, {
|
|
99
|
+
"data-testid": "spectral-drawer-description",
|
|
100
|
+
children: description
|
|
101
|
+
})
|
|
102
|
+
] }),
|
|
66
103
|
/* @__PURE__ */ jsx("div", {
|
|
67
104
|
className: "py-2 px-3 min-w-0 [&>*]:min-w-0 [&_*]:min-w-0 flex-1 min-h-0 overflow-y-auto overflow-x-hidden overscroll-contain *:box-border",
|
|
68
105
|
"data-testid": "spectral-drawer-body",
|
package/dist/Drawer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.js","names":["DrawerBase"],"sources":["../src/components/Drawer/Drawer.tsx"],"sourcesContent":["import { SpectralProvider } from '@components/SpectralProvider/SpectralProvider'\nimport { cn } from '@utils/twUtils'\nimport { type ReactNode } from 'react'\nimport { Drawer as DrawerBase } from 'vaul'\n\nexport interface DrawerProps {\n className?: string\n children?: ReactNode\n defaultOpen?: boolean\n description?:
|
|
1
|
+
{"version":3,"file":"Drawer.js","names":["DrawerBase"],"sources":["../src/components/Drawer/Drawer.tsx"],"sourcesContent":["import { SpectralProvider } from '@components/SpectralProvider/SpectralProvider'\nimport { cn } from '@utils/twUtils'\nimport { Fragment, isValidElement, type ReactNode } from 'react'\nimport { Drawer as DrawerBase } from 'vaul'\n\nexport interface DrawerProps {\n className?: string\n children?: ReactNode\n defaultOpen?: boolean\n description?: ReactNode\n direction?: 'left' | 'right' | 'top' | 'bottom'\n dismissible?: boolean\n dragBehavior?: 'surface' | 'handle' | 'none'\n modal?: boolean\n onOpenChange?: (open: boolean) => void\n open?: boolean\n size?: string\n title?: ReactNode\n trigger: ReactNode\n}\n\nconst hasRenderableText = (value: ReactNode) => (typeof value === 'string' ? value.trim().length > 0 : typeof value === 'number')\n\nconst hasRenderableContent = (value: ReactNode) => {\n if (hasRenderableText(value)) {\n return true\n }\n\n if (value === null || value === undefined || typeof value === 'boolean' || typeof value === 'string') {\n return false\n }\n\n return true\n}\n\nconst isElementAndNotFragment = (element: ReactNode) => isValidElement(element) && element.type !== Fragment\n\nexport const Drawer = ({\n children,\n className,\n defaultOpen = false,\n description, direction = 'right',\n dismissible = true,\n dragBehavior = 'surface',\n modal = true,\n onOpenChange,\n open,\n size = '380px',\n title,\n trigger,\n}: DrawerProps) => {\n const baseStyles = 'font-sans! fixed'\n const hasTitle = hasRenderableContent(title)\n const hasDescription = hasRenderableContent(description)\n const isTextTitle = hasRenderableText(title)\n const isTextDescription = hasRenderableText(description)\n const isCustomTitleElement = isElementAndNotFragment(title)\n const isCustomDescriptionElement = isElementAndNotFragment(description)\n const handleOnly = dragBehavior === 'handle' || dragBehavior === 'none'\n const shouldRenderHandle = dragBehavior === 'handle'\n\n const directionStyles = {\n left: {\n className: cn(baseStyles, 'top-0 bottom-0 left-0 shadow-[20px_0_20px_var(--color-black-40)]'),\n style: { width: size },\n },\n right: {\n className: cn(baseStyles, 'top-0 bottom-0 right-0 shadow-[-20px_0_20px_var(--color-black-40)]'),\n style: { width: size },\n },\n top: {\n className: cn(baseStyles, 'top-0 left-0 right-0 shadow-[0_20px_20px_var(--color-black-40)]'),\n style: { height: size },\n },\n bottom: {\n className: cn(baseStyles, 'bottom-0 left-0 right-0 shadow-[0_-20px_20px_var(--color-black-40)]'),\n style: { height: size },\n },\n }\n\n const { className: directionClassName, style } = directionStyles[direction]\n\n return (\n <SpectralProvider>\n <DrawerBase.Root data-testid='spectral-drawer' defaultOpen={defaultOpen} direction={direction} dismissible={dismissible} handleOnly={handleOnly} modal={modal} onOpenChange={onOpenChange} open={open}>\n <DrawerBase.Trigger asChild data-testid='spectral-drawer-trigger'>\n {trigger}\n </DrawerBase.Trigger>\n <DrawerBase.Portal>\n <DrawerBase.Overlay className='inset-0 fixed bg-transparent' data-testid='spectral-drawer-overlay' />\n <DrawerBase.Content\n asChild\n aria-label={!hasTitle && !hasDescription ? 'Drawer' : undefined}\n className={cn(\n 'z-10 flex flex-col overscroll-contain bg-drawer-bg focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent **:box-border',\n directionClassName,\n className,\n )}\n style={style}\n data-testid='spectral-drawer-content'\n >\n <div className='flex h-full min-h-0 flex-col'>\n <DrawerBase.Close />\n {shouldRenderHandle && <DrawerBase.Handle data-testid='spectral-drawer-handle' />}\n {hasTitle && (\n <>\n {isTextTitle && (\n <DrawerBase.Title className='px-3 pt-4 text-xl font-semibold text-text-primary' data-testid='spectral-drawer-title'>\n {title}\n </DrawerBase.Title>\n )}\n {!isTextTitle && isCustomTitleElement && (\n <DrawerBase.Title asChild data-testid='spectral-drawer-title'>\n {title}\n </DrawerBase.Title>\n )}\n {!isTextTitle && !isCustomTitleElement && (\n <DrawerBase.Title data-testid='spectral-drawer-title'>\n {title}\n </DrawerBase.Title>\n )}\n </>\n )}\n {hasDescription && (\n <>\n {isTextDescription && (\n <DrawerBase.Description className='mb-2 px-3 text-xs! text-text-secondary! uppercase' data-testid='spectral-drawer-description'>\n {description}\n </DrawerBase.Description>\n )}\n {!isTextDescription && isCustomDescriptionElement && (\n <DrawerBase.Description asChild data-testid='spectral-drawer-description'>\n {description}\n </DrawerBase.Description>\n )}\n {!isTextDescription && !isCustomDescriptionElement && (\n <DrawerBase.Description data-testid='spectral-drawer-description'>\n {description}\n </DrawerBase.Description>\n )}\n </>\n )}\n <div className='py-2 px-3 min-w-0 [&>*]:min-w-0 [&_*]:min-w-0 flex-1 min-h-0 overflow-y-auto overflow-x-hidden overscroll-contain *:box-border' data-testid='spectral-drawer-body'>\n {children}\n </div>\n </div>\n </DrawerBase.Content>\n </DrawerBase.Portal>\n </DrawerBase.Root>\n </SpectralProvider>\n )\n}\n"],"mappings":";;;;;;;;AAqBA,MAAM,qBAAqB,UAAsB,OAAO,UAAU,WAAW,MAAM,MAAM,CAAC,SAAS,IAAI,OAAO,UAAU;AAExH,MAAM,wBAAwB,UAAqB;AACjD,KAAI,kBAAkB,MAAM,CAC1B,QAAO;AAGT,KAAI,UAAU,QAAQ,UAAU,UAAa,OAAO,UAAU,aAAa,OAAO,UAAU,SAC1F,QAAO;AAGT,QAAO;;AAGT,MAAM,2BAA2B,YAAuB,eAAe,QAAQ,IAAI,QAAQ,SAAS;AAEpG,MAAa,UAAU,EACrB,UACA,WACA,cAAc,OACd,aAAa,YAAY,SACzB,cAAc,MACd,eAAe,WACf,QAAQ,MACR,cACA,MACA,OAAO,SACP,OACA,cACiB;CACjB,MAAM,aAAa;CACnB,MAAM,WAAW,qBAAqB,MAAM;CAC5C,MAAM,iBAAiB,qBAAqB,YAAY;CACxD,MAAM,cAAc,kBAAkB,MAAM;CAC5C,MAAM,oBAAoB,kBAAkB,YAAY;CACxD,MAAM,uBAAuB,wBAAwB,MAAM;CAC3D,MAAM,6BAA6B,wBAAwB,YAAY;CACvE,MAAM,aAAa,iBAAiB,YAAY,iBAAiB;CACjE,MAAM,qBAAqB,iBAAiB;CAqB5C,MAAM,EAAE,WAAW,oBAAoB,UAAU;EAlB/C,MAAM;GACJ,WAAW,GAAG,YAAY,mEAAmE;GAC7F,OAAO,EAAE,OAAO,MAAM;GACvB;EACD,OAAO;GACL,WAAW,GAAG,YAAY,qEAAqE;GAC/F,OAAO,EAAE,OAAO,MAAM;GACvB;EACD,KAAK;GACH,WAAW,GAAG,YAAY,kEAAkE;GAC5F,OAAO,EAAE,QAAQ,MAAM;GACxB;EACD,QAAQ;GACN,WAAW,GAAG,YAAY,sEAAsE;GAChG,OAAO,EAAE,QAAQ,MAAM;GACxB;EAG6D,CAAC;AAEjE,QACE,oBAAC,kBAAD,YACE,qBAACA,SAAW,MAAZ;EAAiB,eAAY;EAA+B;EAAwB;EAAwB;EAAyB;EAAmB;EAAqB;EAAoB;YAAjM,CACE,oBAACA,SAAW,SAAZ;GAAoB;GAAQ,eAAY;aACrC;GACkB,GACrB,qBAACA,SAAW,QAAZ,aACE,oBAACA,SAAW,SAAZ;GAAoB,WAAU;GAA+B,eAAY;GAA4B,GACrG,oBAACA,SAAW,SAAZ;GACE;GACA,cAAY,CAAC,YAAY,CAAC,iBAAiB,WAAW;GACtD,WAAW,GACT,2KACA,oBACA,UACD;GACM;GACP,eAAY;aAEZ,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAACA,SAAW,OAAZ,EAAoB;KACnB,sBAAsB,oBAACA,SAAW,QAAZ,EAAmB,eAAY,0BAA2B;KAChF,YACC;MACG,eACC,oBAACA,SAAW,OAAZ;OAAkB,WAAU;OAAoD,eAAY;iBACzF;OACgB;MAEpB,CAAC,eAAe,wBACf,oBAACA,SAAW,OAAZ;OAAkB;OAAQ,eAAY;iBACnC;OACgB;MAEpB,CAAC,eAAe,CAAC,wBAChB,oBAACA,SAAW,OAAZ;OAAkB,eAAY;iBAC3B;OACgB;MAEpB;KAEJ,kBACC;MACG,qBACC,oBAACA,SAAW,aAAZ;OAAwB,WAAU;OAAoD,eAAY;iBAC/F;OACsB;MAE1B,CAAC,qBAAqB,8BACrB,oBAACA,SAAW,aAAZ;OAAwB;OAAQ,eAAY;iBACzC;OACsB;MAE1B,CAAC,qBAAqB,CAAC,8BACtB,oBAACA,SAAW,aAAZ;OAAwB,eAAY;iBACjC;OACsB;MAE1B;KAEL,oBAAC,OAAD;MAAK,WAAU;MAAiI,eAAY;MACzJ;MACG;KACF;;GACa,EACH,IACJ;KACD"}
|
package/dist/InputOTP.js
CHANGED
|
@@ -4,7 +4,7 @@ import { cn } from "./utils/twUtils.js";
|
|
|
4
4
|
import { ErrorMessage } from "./FormFieldMessage.js";
|
|
5
5
|
import { getErrorMessageId, useFormFieldId, useFormFieldState } from "./utils/formFieldUtils.js";
|
|
6
6
|
import { createContext, useContext } from "react";
|
|
7
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { OTPInput, REGEXP_ONLY_DIGITS } from "input-otp";
|
|
9
9
|
|
|
10
10
|
//#region src/components/InputOTP/InputOTP.tsx
|
|
@@ -127,7 +127,7 @@ Slot.displayName = "InputOTP.Slot";
|
|
|
127
127
|
const Slots = ({ start = 0, count, className }) => {
|
|
128
128
|
const { maxLength = 0 } = useRoot();
|
|
129
129
|
const end = count !== void 0 ? start + count : maxLength;
|
|
130
|
-
return /* @__PURE__ */ jsx(Fragment, { children: Array.from({ length: end - start }, (_, i) => start + i).map((index) => /* @__PURE__ */ jsx(Slot, {
|
|
130
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: Array.from({ length: end - start }, (_, i) => start + i).map((index) => /* @__PURE__ */ jsx(Slot, {
|
|
131
131
|
index,
|
|
132
132
|
className
|
|
133
133
|
}, index)) });
|
package/dist/InputOTP.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputOTP.js","names":[],"sources":["../src/components/InputOTP/InputOTP.tsx"],"sourcesContent":["import { MinusIcon } from '@components/Icons'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId, useFormFieldState, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { OTPInput, REGEXP_ONLY_DIGITS, type OTPInputProps } from 'input-otp'\nimport { createContext, useContext, type ClipboardEvent, type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\n\nexport interface InputOTPBaseProps extends Omit<OTPInputProps, 'textAlign' | 'pushPasswordManagerStrategy' | 'pasteTransformer' | 'noScriptCSSFallback' | 'placeholder' | 'containerClassName' | 'render' | 'pattern'> {\n onComplete?: (...args: unknown[]) => void\n className?: string\n errorMessage?: string | undefined\n inputMode?: 'numeric' | 'text' | 'decimal' | 'tel' | 'search' | 'email' | 'url'\n messageReserveLines?: number\n messageReserveSpace?: boolean\n /**\n * Regex pattern string to restrict allowed characters.\n * When `inputMode=\"numeric\"`, defaults to digits-only pattern.\n * Set to `undefined` to allow any characters.\n */\n pattern?: string | undefined\n separator?: boolean\n state?: FormFieldState\n variant?: 'outlined' | 'filled'\n}\n\nexport type InputOTPProps = InputOTPBaseProps & ({ value: number | string; onChange: (newValue: number | string) => void } | { value?: never; onChange?: never })\n\nconst InputOTPStateContext = createContext<{ isInvalid?: boolean }>({})\n\nconst OTPInputContext = createContext<{\n maxLength?: number\n slots?: { char: string | null; hasFakeCaret: boolean; isActive: boolean }[]\n variant?: 'outlined' | 'filled'\n} | null>(null)\n\nconst useRoot = () => {\n const context = useContext(OTPInputContext)\n if (!context) {\n throw new Error('useRoot must be used within an InputOTP')\n }\n return context\n}\n\nconst Root = ({\n autoFocus = false,\n children,\n className,\n errorMessage,\n id,\n inputMode = 'numeric',\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxLength,\n name,\n onChange,\n onComplete,\n pattern,\n ref,\n state = 'default',\n value,\n variant = 'outlined',\n ...props\n}: InputOTPProps & {\n ref?: Ref<ComponentRef<typeof OTPInput>>\n}) => {\n const inputId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(inputId)\n const { isInvalid } = useFormFieldState(false, state)\n\n // Apply digits-only pattern when inputMode is numeric (unless explicitly overridden)\n const effectivePattern = pattern ?? (inputMode === 'numeric' ? REGEXP_ONLY_DIGITS : undefined)\n\n const handlePaste = (e: ClipboardEvent<HTMLDivElement>): void => {\n let pasteData = e.clipboardData.getData('text/plain').trim().replaceAll('-', '')\n\n // Filter to digits only when in numeric mode\n if (inputMode === 'numeric') {\n pasteData = pasteData.replace(/\\D/g, '')\n }\n\n if (pasteData.length === maxLength && typeof onChange === 'function') {\n onChange(pasteData)\n }\n }\n\n return (\n <InputOTPStateContext.Provider value={{ isInvalid }}>\n <div className='gap-y-1 flex w-max flex-col'>\n <OTPInput\n /* eslint-disable-next-line jsx-a11y/no-autofocus -- intentional: consumers can opt in for OTP-first flows; defaults to false */\n autoFocus={autoFocus}\n containerClassName={cn('gap-2 flex items-center disabled:cursor-not-allowed has-[disabled]:opacity-50', className)}\n data-1p-ignore='true'\n data-dashlane-disabled-on-field='true'\n data-lpignore='true'\n data-protonpass-ignore='true'\n data-testid='spectral-input-otp'\n id={inputId}\n inputMode={inputMode}\n maxLength={maxLength}\n onChange={onChange}\n onComplete={onComplete}\n onPaste={handlePaste}\n pasteTransformer={(pasted) => pasted.replaceAll('-', '')}\n pattern={effectivePattern}\n pushPasswordManagerStrategy='none'\n ref={ref}\n aria-describedby={isInvalid && errorMessage ? errorMessageId : undefined}\n aria-invalid={isInvalid}\n textAlign='center'\n value={value}\n {...props}\n render={({ slots }) => (\n <OTPInputContext.Provider value={{ slots, variant, maxLength }}>\n {children ?? (\n <Group>\n <Slots />\n </Group>\n )}\n </OTPInputContext.Provider>\n )}\n />\n <ErrorMessage\n dataTestId='spectral-input-otp-error-message'\n id={errorMessageId}\n message={isInvalid ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n />\n </div>\n </InputOTPStateContext.Provider>\n )\n}\nRoot.displayName = 'InputOTP'\n\nconst Group = ({\n ref,\n ...props\n}: ComponentPropsWithoutRef<'div'> & {\n ref?: Ref<ComponentRef<'div'>>\n}) => <div className='gap-x-2 flex items-center justify-center' data-testid='spectral-input-otp-group' ref={ref} {...props} />\nGroup.displayName = 'InputOTP.Group'\n\nconst Slot = ({\n className,\n index,\n ref,\n ...props\n}: ComponentPropsWithoutRef<'div'> & {\n index: number\n ref?: Ref<ComponentRef<'div'>>\n}) => {\n const { variant = 'outlined', slots = [] } = useRoot()\n const { isInvalid } = useContext(InputOTPStateContext)\n const slot = slots[index] || { char: '', hasFakeCaret: true, isActive: false }\n\n return (\n <div\n className={cn(\n 'h-12 w-10 relative z-10 flex items-center justify-center rounded-[8px] border tabular-nums transition duration-200 focus:outline-none',\n variant === 'filled' ? 'border-level-one bg-level-one' : 'border-input-otp-border bg-transparent',\n !isInvalid && 'border',\n isInvalid && 'border-2 border-danger-400',\n slot.isActive && !isInvalid && 'z-10 border-input-otp-border--focus',\n slot.isActive && isInvalid && 'z-10 border-danger-400 focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-danger-400',\n className,\n )}\n data-index={index}\n data-testid='spectral-input-otp-slot'\n data-variant={variant}\n ref={ref}\n {...props}\n >\n {slot.char}\n {slot.hasFakeCaret && (\n <div className='inset-0 pointer-events-none absolute flex items-center justify-center motion-safe:animate-caret-blink'>\n <div className='h-8 w-px bg-input-otp-caret' />\n </div>\n )}\n </div>\n )\n}\nSlot.displayName = 'InputOTP.Slot'\n\ninterface SlotsProps {\n className?: string\n count?: number\n start?: number\n}\n\n/**\n * Helper component that automatically renders multiple InputOTP.Slot components.\n * Uses the maxLength from the parent InputOTP to determine how many slots to render.\n *\n * @example\n * // Render all 6 slots\n * <InputOTP maxLength={6}>\n * <InputOTP.Group>\n * <InputOTP.Slots />\n * </InputOTP.Group>\n * </InputOTP>\n *\n * @example\n * // Render slots in groups with a separator (3-3 split)\n * <InputOTP maxLength={6}>\n * <InputOTP.Group>\n * <InputOTP.Slots count={3} />\n * </InputOTP.Group>\n * <InputOTP.Separator />\n * <InputOTP.Group>\n * <InputOTP.Slots start={3} />\n * </InputOTP.Group>\n * </InputOTP>\n */\nconst Slots = ({ start = 0, count, className }: SlotsProps) => {\n const { maxLength = 0 } = useRoot()\n const end = count !== undefined ? start + count : maxLength\n const indices = Array.from({ length: end - start }, (_, i) => start + i)\n\n return (\n <>\n {indices.map((index) => (\n <Slot key={index} index={index} className={className} />\n ))}\n </>\n )\n}\nSlots.displayName = 'InputOTP.Slots'\n\nconst Separator = ({\n ref,\n ...props\n}: ComponentPropsWithoutRef<'div'> & {\n ref?: Ref<ComponentRef<'div'>>\n}) => {\n const { variant = 'outlined' } = useRoot()\n\n return (\n <div ref={ref} role='separator' {...props} data-testid='spectral-input-otp-separator' data-variant={variant}>\n <MinusIcon size={24} color={variant === 'filled' ? 'var(--color-input-otp-filled-separator)' : 'var(--color-input-otp-border)'} />\n </div>\n )\n}\nSeparator.displayName = 'InputOTP.Separator'\n\nexport const InputOTP = Object.assign(Root, {\n Group,\n Slot,\n Slots,\n Separator,\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InputOTP.js","names":[],"sources":["../src/components/InputOTP/InputOTP.tsx"],"sourcesContent":["import { MinusIcon } from '@components/Icons'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId, useFormFieldState, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { OTPInput, REGEXP_ONLY_DIGITS, type OTPInputProps } from 'input-otp'\nimport { createContext, useContext, type ClipboardEvent, type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\n\nexport interface InputOTPBaseProps extends Omit<OTPInputProps, 'textAlign' | 'pushPasswordManagerStrategy' | 'pasteTransformer' | 'noScriptCSSFallback' | 'placeholder' | 'containerClassName' | 'render' | 'pattern'> {\n onComplete?: (...args: unknown[]) => void\n className?: string\n errorMessage?: string | undefined\n inputMode?: 'numeric' | 'text' | 'decimal' | 'tel' | 'search' | 'email' | 'url'\n messageReserveLines?: number\n messageReserveSpace?: boolean\n /**\n * Regex pattern string to restrict allowed characters.\n * When `inputMode=\"numeric\"`, defaults to digits-only pattern.\n * Set to `undefined` to allow any characters.\n */\n pattern?: string | undefined\n separator?: boolean\n state?: FormFieldState\n variant?: 'outlined' | 'filled'\n}\n\nexport type InputOTPProps = InputOTPBaseProps & ({ value: number | string; onChange: (newValue: number | string) => void } | { value?: never; onChange?: never })\n\nconst InputOTPStateContext = createContext<{ isInvalid?: boolean }>({})\n\nconst OTPInputContext = createContext<{\n maxLength?: number\n slots?: { char: string | null; hasFakeCaret: boolean; isActive: boolean }[]\n variant?: 'outlined' | 'filled'\n} | null>(null)\n\nconst useRoot = () => {\n const context = useContext(OTPInputContext)\n if (!context) {\n throw new Error('useRoot must be used within an InputOTP')\n }\n return context\n}\n\nconst Root = ({\n autoFocus = false,\n children,\n className,\n errorMessage,\n id,\n inputMode = 'numeric',\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxLength,\n name,\n onChange,\n onComplete,\n pattern,\n ref,\n state = 'default',\n value,\n variant = 'outlined',\n ...props\n}: InputOTPProps & {\n ref?: Ref<ComponentRef<typeof OTPInput>>\n}) => {\n const inputId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(inputId)\n const { isInvalid } = useFormFieldState(false, state)\n\n // Apply digits-only pattern when inputMode is numeric (unless explicitly overridden)\n const effectivePattern = pattern ?? (inputMode === 'numeric' ? REGEXP_ONLY_DIGITS : undefined)\n\n const handlePaste = (e: ClipboardEvent<HTMLDivElement>): void => {\n let pasteData = e.clipboardData.getData('text/plain').trim().replaceAll('-', '')\n\n // Filter to digits only when in numeric mode\n if (inputMode === 'numeric') {\n pasteData = pasteData.replace(/\\D/g, '')\n }\n\n if (pasteData.length === maxLength && typeof onChange === 'function') {\n onChange(pasteData)\n }\n }\n\n return (\n <InputOTPStateContext.Provider value={{ isInvalid }}>\n <div className='gap-y-1 flex w-max flex-col'>\n <OTPInput\n /* eslint-disable-next-line jsx-a11y/no-autofocus -- intentional: consumers can opt in for OTP-first flows; defaults to false */\n autoFocus={autoFocus}\n containerClassName={cn('gap-2 flex items-center disabled:cursor-not-allowed has-[disabled]:opacity-50', className)}\n data-1p-ignore='true'\n data-dashlane-disabled-on-field='true'\n data-lpignore='true'\n data-protonpass-ignore='true'\n data-testid='spectral-input-otp'\n id={inputId}\n inputMode={inputMode}\n maxLength={maxLength}\n onChange={onChange}\n onComplete={onComplete}\n onPaste={handlePaste}\n pasteTransformer={(pasted) => pasted.replaceAll('-', '')}\n pattern={effectivePattern}\n pushPasswordManagerStrategy='none'\n ref={ref}\n aria-describedby={isInvalid && errorMessage ? errorMessageId : undefined}\n aria-invalid={isInvalid}\n textAlign='center'\n value={value}\n {...props}\n render={({ slots }) => (\n <OTPInputContext.Provider value={{ slots, variant, maxLength }}>\n {children ?? (\n <Group>\n <Slots />\n </Group>\n )}\n </OTPInputContext.Provider>\n )}\n />\n <ErrorMessage\n dataTestId='spectral-input-otp-error-message'\n id={errorMessageId}\n message={isInvalid ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n />\n </div>\n </InputOTPStateContext.Provider>\n )\n}\nRoot.displayName = 'InputOTP'\n\nconst Group = ({\n ref,\n ...props\n}: ComponentPropsWithoutRef<'div'> & {\n ref?: Ref<ComponentRef<'div'>>\n}) => <div className='gap-x-2 flex items-center justify-center' data-testid='spectral-input-otp-group' ref={ref} {...props} />\nGroup.displayName = 'InputOTP.Group'\n\nconst Slot = ({\n className,\n index,\n ref,\n ...props\n}: ComponentPropsWithoutRef<'div'> & {\n index: number\n ref?: Ref<ComponentRef<'div'>>\n}) => {\n const { variant = 'outlined', slots = [] } = useRoot()\n const { isInvalid } = useContext(InputOTPStateContext)\n const slot = slots[index] || { char: '', hasFakeCaret: true, isActive: false }\n\n return (\n <div\n className={cn(\n 'h-12 w-10 relative z-10 flex items-center justify-center rounded-[8px] border tabular-nums transition duration-200 focus:outline-none',\n variant === 'filled' ? 'border-level-one bg-level-one' : 'border-input-otp-border bg-transparent',\n !isInvalid && 'border',\n isInvalid && 'border-2 border-danger-400',\n slot.isActive && !isInvalid && 'z-10 border-input-otp-border--focus',\n slot.isActive && isInvalid && 'z-10 border-danger-400 focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-danger-400',\n className,\n )}\n data-index={index}\n data-testid='spectral-input-otp-slot'\n data-variant={variant}\n ref={ref}\n {...props}\n >\n {slot.char}\n {slot.hasFakeCaret && (\n <div className='inset-0 pointer-events-none absolute flex items-center justify-center motion-safe:animate-caret-blink'>\n <div className='h-8 w-px bg-input-otp-caret' />\n </div>\n )}\n </div>\n )\n}\nSlot.displayName = 'InputOTP.Slot'\n\ninterface SlotsProps {\n className?: string\n count?: number\n start?: number\n}\n\n/**\n * Helper component that automatically renders multiple InputOTP.Slot components.\n * Uses the maxLength from the parent InputOTP to determine how many slots to render.\n *\n * @example\n * // Render all 6 slots\n * <InputOTP maxLength={6}>\n * <InputOTP.Group>\n * <InputOTP.Slots />\n * </InputOTP.Group>\n * </InputOTP>\n *\n * @example\n * // Render slots in groups with a separator (3-3 split)\n * <InputOTP maxLength={6}>\n * <InputOTP.Group>\n * <InputOTP.Slots count={3} />\n * </InputOTP.Group>\n * <InputOTP.Separator />\n * <InputOTP.Group>\n * <InputOTP.Slots start={3} />\n * </InputOTP.Group>\n * </InputOTP>\n */\nconst Slots = ({ start = 0, count, className }: SlotsProps) => {\n const { maxLength = 0 } = useRoot()\n const end = count !== undefined ? start + count : maxLength\n const indices = Array.from({ length: end - start }, (_, i) => start + i)\n\n return (\n <>\n {indices.map((index) => (\n <Slot key={index} index={index} className={className} />\n ))}\n </>\n )\n}\nSlots.displayName = 'InputOTP.Slots'\n\nconst Separator = ({\n ref,\n ...props\n}: ComponentPropsWithoutRef<'div'> & {\n ref?: Ref<ComponentRef<'div'>>\n}) => {\n const { variant = 'outlined' } = useRoot()\n\n return (\n <div ref={ref} role='separator' {...props} data-testid='spectral-input-otp-separator' data-variant={variant}>\n <MinusIcon size={24} color={variant === 'filled' ? 'var(--color-input-otp-filled-separator)' : 'var(--color-input-otp-border)'} />\n </div>\n )\n}\nSeparator.displayName = 'InputOTP.Separator'\n\nexport const InputOTP = Object.assign(Root, {\n Group,\n Slot,\n Slots,\n Separator,\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { BaseFormFieldProps, BaseOption, DropdownWidth, FormFieldState } from "./utils/formFieldUtils.js";
|
|
3
|
+
import { ReactNode, Ref } from "react";
|
|
4
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/components/InputSearch/InputSearch.d.ts
|
|
7
|
+
type InputSearchOption = BaseOption;
|
|
8
|
+
interface InputSearchProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'> {
|
|
9
|
+
className?: string;
|
|
10
|
+
createOptionLabel?: (query: string) => ReactNode;
|
|
11
|
+
creatingLabel?: string;
|
|
12
|
+
defaultValue?: string;
|
|
13
|
+
dropdownWidth?: DropdownWidth;
|
|
14
|
+
emptyMessage?: string;
|
|
15
|
+
isCreating?: boolean;
|
|
16
|
+
labelClassName?: string;
|
|
17
|
+
onChange?: (value: string) => void;
|
|
18
|
+
onCreate?: (query: string) => void;
|
|
19
|
+
onValueChange?: (value: string) => void;
|
|
20
|
+
openOnFocus?: boolean;
|
|
21
|
+
options: InputSearchOption[];
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
renderOption?: (option: InputSearchOption) => ReactNode;
|
|
24
|
+
showSearchIcon?: boolean;
|
|
25
|
+
state?: Exclude<FormFieldState, 'disabled'>;
|
|
26
|
+
value?: string;
|
|
27
|
+
warningMessage?: BaseFormFieldProps['errorMessage'];
|
|
28
|
+
}
|
|
29
|
+
declare function InputSearch({
|
|
30
|
+
className,
|
|
31
|
+
createOptionLabel,
|
|
32
|
+
creatingLabel,
|
|
33
|
+
defaultValue,
|
|
34
|
+
disabled,
|
|
35
|
+
dropdownWidth,
|
|
36
|
+
emptyMessage,
|
|
37
|
+
errorMessage,
|
|
38
|
+
id,
|
|
39
|
+
isCreating,
|
|
40
|
+
label,
|
|
41
|
+
labelClassName,
|
|
42
|
+
messageReserveLines,
|
|
43
|
+
messageReserveSpace,
|
|
44
|
+
name,
|
|
45
|
+
onChange,
|
|
46
|
+
onCreate,
|
|
47
|
+
onValueChange,
|
|
48
|
+
openOnFocus,
|
|
49
|
+
options,
|
|
50
|
+
placeholder,
|
|
51
|
+
ref,
|
|
52
|
+
renderOption,
|
|
53
|
+
required,
|
|
54
|
+
showSearchIcon,
|
|
55
|
+
state,
|
|
56
|
+
value: valueProp,
|
|
57
|
+
warningMessage,
|
|
58
|
+
'aria-describedby': ariaDescribedBy,
|
|
59
|
+
'aria-label': ariaLabel
|
|
60
|
+
}: InputSearchProps & {
|
|
61
|
+
ref?: Ref<HTMLDivElement>;
|
|
62
|
+
}): _$react_jsx_runtime0.JSX.Element;
|
|
63
|
+
declare namespace InputSearch {
|
|
64
|
+
var displayName: string;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { InputSearch, InputSearchOption, InputSearchProps };
|
|
68
|
+
//# sourceMappingURL=InputSearch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputSearch.d.ts","names":[],"sources":["../src/components/InputSearch/InputSearch.tsx"],"mappings":";;;;;;KA0BY,iBAAA,GAAoB,UAAA;AAAA,UAEf,gBAAA,SAAyB,IAAA,CAAK,kBAAA;EAC7C,SAAA;EACA,iBAAA,IAAqB,KAAA,aAAkB,SAAA;EACvC,aAAA;EACA,YAAA;EACA,aAAA,GAAgB,aAAA;EAChB,YAAA;EACA,UAAA;EACA,cAAA;EACA,QAAA,IAAY,KAAA;EACZ,QAAA,IAAY,KAAA;EACZ,aAAA,IAAiB,KAAA;EACjB,WAAA;EACA,OAAA,EAAS,iBAAA;EACT,WAAA;EACA,YAAA,IAAgB,MAAA,EAAQ,iBAAA,KAAsB,SAAA;EAC9C,cAAA;EACA,KAAA,GAAQ,OAAA,CAAQ,cAAA;EAChB,KAAA;EACA,cAAA,GAAiB,kBAAA;AAAA;AAAA;EAajB,SAAA;EACA,iBAAA;EACA,aAAA;EACA,YAAA;EACA,QAAA;EACA,aAAA;EACA,YAAA;EACA,YAAA;EACA,EAAA;EACA,UAAA;EACA,KAAA;EACA,cAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,QAAA;EACA,QAAA;EACA,aAAA;EACA,WAAA;EACA,OAAA;EACA,WAAA;EACA,GAAA;EACA,YAAA;EACA,QAAA;EACA,cAAA;EACA,KAAA;EACA,KAAA,EAAO,SAAA;EACP,cAAA;EAAA,oBACoB,eAAA;EAAA,cACN;AAAA,GACb,gBAAA;EAAqB,GAAA,GAAM,GAAA,CAAI,cAAA;AAAA,IAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|