@react-md/core 6.3.0 → 6.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/dist/_base.scss +1 -1
  2. package/dist/app-bar/styles.d.ts +0 -2
  3. package/dist/app-bar/styles.js.map +1 -1
  4. package/dist/autocomplete/types.d.ts +12 -0
  5. package/dist/autocomplete/types.js.map +1 -1
  6. package/dist/avatar/Avatar.d.ts +0 -10
  7. package/dist/avatar/Avatar.js.map +1 -1
  8. package/dist/avatar/styles.d.ts +10 -0
  9. package/dist/avatar/styles.js.map +1 -1
  10. package/dist/badge/Badge.d.ts +11 -0
  11. package/dist/badge/Badge.js.map +1 -1
  12. package/dist/badge/styles.d.ts +0 -8
  13. package/dist/badge/styles.js.map +1 -1
  14. package/dist/box/_box.scss +8 -8
  15. package/dist/box/styles.d.ts +9 -0
  16. package/dist/box/styles.js.map +1 -1
  17. package/dist/button/_button.scss +4 -0
  18. package/dist/button/styles.d.ts +5 -1
  19. package/dist/button/styles.js.map +1 -1
  20. package/dist/card/Card.d.ts +0 -7
  21. package/dist/card/Card.js.map +1 -1
  22. package/dist/card/styles.d.ts +6 -0
  23. package/dist/card/styles.js +8 -8
  24. package/dist/card/styles.js.map +1 -1
  25. package/dist/chip/Chip.d.ts +6 -13
  26. package/dist/chip/Chip.js.map +1 -1
  27. package/dist/chip/styles.d.ts +26 -1
  28. package/dist/chip/styles.js.map +1 -1
  29. package/dist/dialog/Dialog.js +8 -8
  30. package/dist/dialog/Dialog.js.map +1 -1
  31. package/dist/dialog/styles.d.ts +5 -2
  32. package/dist/dialog/styles.js.map +1 -1
  33. package/dist/divider/styles.d.ts +1 -1
  34. package/dist/divider/styles.js.map +1 -1
  35. package/dist/error-boundary/ErrorBoundary.js.map +1 -1
  36. package/dist/files/validation.js.map +1 -1
  37. package/dist/focus/useFocusContainer.d.ts +11 -4
  38. package/dist/focus/useFocusContainer.js +3 -1
  39. package/dist/focus/useFocusContainer.js.map +1 -1
  40. package/dist/form/InputToggle.js.map +1 -1
  41. package/dist/form/Label.d.ts +0 -10
  42. package/dist/form/Label.js.map +1 -1
  43. package/dist/form/Slider.d.ts +4 -0
  44. package/dist/form/Slider.js.map +1 -1
  45. package/dist/form/Switch.js.map +1 -1
  46. package/dist/form/TextArea.js.map +1 -1
  47. package/dist/form/TextFieldContainer.d.ts +0 -13
  48. package/dist/form/TextFieldContainer.js.map +1 -1
  49. package/dist/form/_select.scss +5 -1
  50. package/dist/form/_text-area.scss +2 -1
  51. package/dist/form/_text-field.scss +1 -0
  52. package/dist/form/types.d.ts +20 -0
  53. package/dist/form/types.js.map +1 -1
  54. package/dist/hoverMode/useHoverModeProvider.d.ts +9 -1
  55. package/dist/hoverMode/useHoverModeProvider.js.map +1 -1
  56. package/dist/interaction/types.d.ts +5 -1
  57. package/dist/interaction/types.js.map +1 -1
  58. package/dist/link/Link.d.ts +0 -7
  59. package/dist/link/Link.js.map +1 -1
  60. package/dist/link/styles.d.ts +7 -0
  61. package/dist/link/styles.js.map +1 -1
  62. package/dist/list/List.d.ts +5 -20
  63. package/dist/list/List.js.map +1 -1
  64. package/dist/list/ListItem.d.ts +4 -38
  65. package/dist/list/ListItem.js.map +1 -1
  66. package/dist/list/listItemStyles.d.ts +24 -2
  67. package/dist/list/listItemStyles.js.map +1 -1
  68. package/dist/list/listStyles.d.ts +17 -2
  69. package/dist/list/listStyles.js.map +1 -1
  70. package/dist/menu/Menu.js +8 -6
  71. package/dist/menu/Menu.js.map +1 -1
  72. package/dist/navigation/NavItem.d.ts +4 -1
  73. package/dist/navigation/NavItem.js.map +1 -1
  74. package/dist/navigation/navItemStyles.d.ts +7 -0
  75. package/dist/navigation/navItemStyles.js.map +1 -1
  76. package/dist/overlay/Overlay.d.ts +4 -23
  77. package/dist/overlay/Overlay.js.map +1 -1
  78. package/dist/overlay/styles.d.ts +26 -8
  79. package/dist/overlay/styles.js.map +1 -1
  80. package/dist/progress/LinearProgress.d.ts +4 -9
  81. package/dist/progress/LinearProgress.js.map +1 -1
  82. package/dist/progress/circularProgressStyles.d.ts +6 -0
  83. package/dist/progress/circularProgressStyles.js.map +1 -1
  84. package/dist/progress/linearProgressStyles.d.ts +20 -5
  85. package/dist/progress/linearProgressStyles.js.map +1 -1
  86. package/dist/progress/types.d.ts +0 -9
  87. package/dist/progress/types.js.map +1 -1
  88. package/dist/segmented-button/SegmentedButton.d.ts +7 -12
  89. package/dist/segmented-button/SegmentedButton.js.map +1 -1
  90. package/dist/segmented-button/segmentedButtonStyles.d.ts +26 -3
  91. package/dist/segmented-button/segmentedButtonStyles.js.map +1 -1
  92. package/dist/sheet/Sheet.d.ts +0 -12
  93. package/dist/sheet/Sheet.js.map +1 -1
  94. package/dist/sheet/styles.d.ts +12 -0
  95. package/dist/sheet/styles.js.map +1 -1
  96. package/dist/snackbar/Toast.d.ts +2 -13
  97. package/dist/snackbar/Toast.js.map +1 -1
  98. package/dist/snackbar/ToastManager.js.map +1 -1
  99. package/dist/snackbar/toastStyles.d.ts +17 -2
  100. package/dist/snackbar/toastStyles.js.map +1 -1
  101. package/dist/tabs/Tab.d.ts +2 -41
  102. package/dist/tabs/Tab.js.map +1 -1
  103. package/dist/tabs/tabStyles.d.ts +45 -4
  104. package/dist/tabs/tabStyles.js.map +1 -1
  105. package/dist/test-utils/mocks/IntersectionObserver.js.map +1 -1
  106. package/dist/test-utils/mocks/ResizeObserver.js.map +1 -1
  107. package/dist/test-utils/utils/createFileList.js.map +1 -1
  108. package/dist/theme/_theme.scss +0 -1
  109. package/dist/theme/getDerivedTheme.d.ts +0 -24
  110. package/dist/theme/getDerivedTheme.js.map +1 -1
  111. package/dist/theme/types.d.ts +25 -0
  112. package/dist/theme/types.js.map +1 -1
  113. package/dist/tooltip/Tooltip.d.ts +4 -32
  114. package/dist/tooltip/Tooltip.js.map +1 -1
  115. package/dist/tooltip/styles.d.ts +38 -1
  116. package/dist/tooltip/styles.js +1 -1
  117. package/dist/tooltip/styles.js.map +1 -1
  118. package/dist/transition/SkeletonPlaceholder.d.ts +0 -7
  119. package/dist/transition/SkeletonPlaceholder.js.map +1 -1
  120. package/dist/transition/Slide.js.map +1 -1
  121. package/dist/transition/skeletonPlaceholderUtils.d.ts +7 -0
  122. package/dist/transition/skeletonPlaceholderUtils.js.map +1 -1
  123. package/dist/transition/useMaxWidthTransition.d.ts +14 -2
  124. package/dist/transition/useMaxWidthTransition.js.map +1 -1
  125. package/dist/transition/useSlideTransition.d.ts +5 -0
  126. package/dist/transition/useSlideTransition.js.map +1 -1
  127. package/dist/tree/Tree.d.ts +5 -9
  128. package/dist/tree/Tree.js.map +1 -1
  129. package/dist/tree/styles.d.ts +9 -1
  130. package/dist/tree/styles.js.map +1 -1
  131. package/dist/typography/Mark.d.ts +4 -1
  132. package/dist/typography/Mark.js.map +1 -1
  133. package/dist/typography/TextContainer.d.ts +0 -6
  134. package/dist/typography/TextContainer.js.map +1 -1
  135. package/dist/typography/markStyles.d.ts +5 -0
  136. package/dist/typography/markStyles.js.map +1 -1
  137. package/dist/typography/textContainerStyles.d.ts +6 -0
  138. package/dist/typography/textContainerStyles.js.map +1 -1
  139. package/dist/typography/typographyStyles.d.ts +9 -0
  140. package/dist/typography/typographyStyles.js.map +1 -1
  141. package/dist/useResizeObserver.js.map +1 -1
  142. package/dist/window-splitter/WindowSplitter.d.ts +5 -19
  143. package/dist/window-splitter/WindowSplitter.js.map +1 -1
  144. package/dist/window-splitter/styles.d.ts +27 -3
  145. package/dist/window-splitter/styles.js.map +1 -1
  146. package/package.json +13 -14
  147. package/src/app-bar/styles.ts +0 -2
  148. package/src/autocomplete/types.ts +17 -0
  149. package/src/avatar/Avatar.tsx +0 -11
  150. package/src/avatar/styles.ts +11 -0
  151. package/src/badge/Badge.tsx +12 -0
  152. package/src/badge/styles.ts +0 -9
  153. package/src/box/styles.ts +9 -0
  154. package/src/button/styles.ts +5 -1
  155. package/src/card/Card.tsx +0 -8
  156. package/src/card/styles.ts +15 -8
  157. package/src/chip/Chip.tsx +9 -15
  158. package/src/chip/styles.ts +29 -1
  159. package/src/dialog/Dialog.tsx +8 -8
  160. package/src/dialog/styles.ts +5 -2
  161. package/src/divider/styles.ts +1 -1
  162. package/src/focus/useFocusContainer.ts +19 -11
  163. package/src/form/InputToggle.tsx +2 -0
  164. package/src/form/Label.tsx +0 -11
  165. package/src/form/Slider.tsx +6 -0
  166. package/src/form/Switch.tsx +2 -0
  167. package/src/form/TextArea.tsx +2 -0
  168. package/src/form/TextFieldContainer.tsx +0 -14
  169. package/src/form/types.ts +29 -0
  170. package/src/hoverMode/useHoverModeProvider.ts +9 -1
  171. package/src/interaction/types.ts +5 -1
  172. package/src/link/Link.tsx +0 -8
  173. package/src/link/styles.ts +8 -0
  174. package/src/list/List.tsx +7 -24
  175. package/src/list/ListItem.tsx +7 -43
  176. package/src/list/listItemStyles.ts +26 -2
  177. package/src/list/listStyles.ts +18 -2
  178. package/src/menu/Menu.tsx +9 -5
  179. package/src/navigation/NavItem.tsx +6 -2
  180. package/src/navigation/navItemStyles.ts +8 -0
  181. package/src/overlay/Overlay.tsx +4 -26
  182. package/src/overlay/styles.ts +29 -10
  183. package/src/progress/LinearProgress.tsx +8 -10
  184. package/src/progress/circularProgressStyles.ts +7 -0
  185. package/src/progress/linearProgressStyles.ts +22 -5
  186. package/src/progress/types.ts +0 -10
  187. package/src/segmented-button/SegmentedButton.tsx +14 -15
  188. package/src/segmented-button/segmentedButtonStyles.ts +28 -3
  189. package/src/sheet/Sheet.tsx +0 -13
  190. package/src/sheet/styles.ts +13 -0
  191. package/src/snackbar/Toast.tsx +2 -15
  192. package/src/snackbar/toastStyles.ts +20 -2
  193. package/src/tabs/Tab.tsx +4 -49
  194. package/src/tabs/tabStyles.ts +52 -4
  195. package/src/theme/getDerivedTheme.ts +0 -26
  196. package/src/theme/types.ts +26 -0
  197. package/src/tooltip/Tooltip.tsx +4 -36
  198. package/src/tooltip/styles.ts +43 -2
  199. package/src/transition/SkeletonPlaceholder.tsx +0 -8
  200. package/src/transition/Slide.tsx +2 -0
  201. package/src/transition/skeletonPlaceholderUtils.ts +8 -0
  202. package/src/transition/useMaxWidthTransition.ts +17 -2
  203. package/src/transition/useSlideTransition.ts +8 -0
  204. package/src/tree/Tree.tsx +5 -10
  205. package/src/tree/styles.ts +10 -1
  206. package/src/typography/Mark.tsx +6 -2
  207. package/src/typography/TextContainer.tsx +0 -7
  208. package/src/typography/markStyles.ts +6 -0
  209. package/src/typography/textContainerStyles.ts +7 -0
  210. package/src/typography/typographyStyles.ts +10 -0
  211. package/src/window-splitter/WindowSplitter.tsx +9 -22
  212. package/src/window-splitter/styles.ts +31 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/files/validation.ts"],"sourcesContent":["import { nanoid } from \"nanoid\";\n\n/**\n * An error that will be created if a user tries dragging and dropping files\n * from a shared directory that they do not have access to. This error will not\n * occur much.\n *\n * @since 2.9.0\n */\nexport class FileAccessError extends Error {\n /**\n * A unique key generated by `nanoid` that can be used as a `React` key\n */\n public key: string;\n\n /**\n *\n * @param message - An optional message for the error.\n */\n constructor(message?: string) {\n super(message);\n this.key = nanoid();\n this.name = \"FileAccessError\";\n }\n}\n\n/**\n * An error that just requires a `File` to be passed as the first argument.\n *\n * @since 2.9.0\n */\nexport class GenericFileError extends Error {\n /**\n * A unique key generated by `nanoid` that can be used as a `React` key\n */\n public key: string;\n\n /**\n *\n * @param files - A list of files that caused the error.\n * @param reason - An optional reason for the error\n */\n constructor(\n public files: readonly File[],\n public reason?: string\n ) {\n super(\"Invalid files\");\n this.key = nanoid();\n this.name = \"GenericFileError\";\n }\n}\n\n/**\n * An error that is created during the upload process if the number of files\n * exceeds the {@link FileUploadOptions.maxFiles} amount.\n *\n * @since 2.9.0\n */\nexport class TooManyFilesError extends GenericFileError {\n /**\n *\n * @param files - The list of files that could not be uploaded due to the file\n * limit defined.\n * @param limit - The max limit of files allowed.\n */\n constructor(\n files: readonly File[],\n public limit: number\n ) {\n super(files, \"file limit\");\n this.name = \"TooManyFilesError\";\n }\n}\n\n/**\n * An error that will be created if a user tries to upload a file that\n * is either:\n * - less than the {@link FileValidationOptions.minFileSize}\n * - greater than the {@link FileValidationOptions.maxFileSize}\n * - including the file would be greater than the {@link FileValidationOptions.totalFileSize}\n *\n * @since 2.9.0\n */\nexport class FileSizeError extends GenericFileError {\n /**\n *\n * @param files - The list of files that have the file size error\n * @param type - The file size error type\n * @param limit - The number of bytes allowed based on the type\n */\n constructor(\n files: readonly File[],\n public type: \"min\" | \"max\" | \"total\",\n public limit: number\n ) {\n super(files, \"file size\");\n this.name = \"FileSizeError\";\n }\n}\n\n/**\n * An error that will be created if a user tries to upload a file that does not\n * end with one of the {@link FileValidationOptions.extensions}.\n *\n * @since 2.9.0\n */\nexport class FileExtensionError extends GenericFileError {\n /**\n *\n * @param files - The file that caused the error\n * @param extensions - The allowed list of file extensions\n */\n constructor(\n files: readonly File[],\n public extensions: readonly string[]\n ) {\n super(files, \"extension\");\n this.name = \"FileExtensionError\";\n }\n}\n\n/**\n * Mostly an internal type that is used to allow custom validation errors\n *\n * @since 2.9.0\n */\nexport type FileValidationError<E = GenericFileError> =\n | FileAccessError\n | TooManyFilesError\n | FileSizeError\n | FileExtensionError\n | E;\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link GenericFileError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileAccessError}\n */\nexport function isGenericFileError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is GenericFileError {\n return \"name\" in error && error.name === \"GenericFileError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link FileAccessError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileAccessError}\n */\nexport function isFileAccessError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is FileAccessError {\n return \"name\" in error && error.name === \"FileAccessError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link TooManyFilesError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link TooManyFilesError}\n */\nexport function isTooManyFilesError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is TooManyFilesError {\n return \"name\" in error && error.name === \"TooManyFilesError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link FileSizeError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileSizeError}\n */\nexport function isFileSizeError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is FileSizeError {\n return \"name\" in error && error.name === \"FileSizeError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link FileExtensionError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileExtensionError}\n */\nexport function isFileExtensionError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is FileExtensionError {\n return \"name\" in error && error.name === \"FileExtensionError\";\n}\n\n/**\n * This function is used to determine if a file should be added to the\n * {@link FileExtensionError}. The default implementation should work for most\n * use cases except when files that do not have extensions can be uploaded. i.e.\n * LICENSE files.\n *\n * @param file - The file being checked\n * @param extensionRegExp - A regex that will only be defined if the\n * `extensions` list had at least one value.\n * @param extensions - The list of extensions allowed\n * @returns true if the file has a valid name.\n * @since 3.1.0\n */\nexport type IsValidFileName = (\n file: File,\n extensionRegExp: RegExp | undefined,\n extensions: readonly string[]\n) => boolean;\n\n/**\n *\n * @defaultValue `matcher?.test(file.name) ?? true`\n * @since 3.1.0\n */\nexport const isValidFileName: IsValidFileName = (file, matcher) =>\n matcher?.test(file.name) ?? true;\n\n/** @since 2.9.0 */\nexport interface FileValidationOptions {\n /**\n * If the number of files should be limited, set this value to a number\n * greater than `0`.\n *\n * Note: This still allows \"infinite\" files when set to `0` since the\n * `<input>` element should normally be set to `disabled` if files should not\n * be able to be uploaded.\n *\n * @defaultValue `-1`\n */\n maxFiles?: number;\n\n /**\n * An optional minimum file size to enforce for each file. This will only be\n * used when it is greater than `0`.\n *\n * @defaultValue `-1`\n */\n minFileSize?: number;\n\n /**\n * An optional maximum file size to enforce for each file. This will only be\n * used when it is greater than `0`.\n *\n * @defaultValue `-1`\n */\n maxFileSize?: number;\n\n /**\n * An optional list of extensions to enforce when uploading files.\n *\n * Note: The extensions and file names will be compared ignoring case.\n *\n * @example Only Allow Images\n * ```ts\n * const extensions = [\"png\", \"jpeg\", \"jpg\", \"gif\"];\n * ```\n */\n extensions?: readonly string[];\n\n /** {@inheritDoc IsValidFileName} */\n isValidFileName?: IsValidFileName;\n\n /**\n * An optional total file size to enforce when the {@link maxFiles} option is\n * not set to `1`.\n *\n * @defaultValue `-1`\n */\n totalFileSize?: number;\n}\n\n/** @since 2.9.0 */\nexport interface FilesValidationOptions\n extends Required<FileValidationOptions> {\n /**\n * The total number of bytes in the {@link FileUploadHookReturnValue.stats}\n * list. This is really just:\n *\n * ```ts\n * const totalBytes = stats.reduce((total, stat) => total + stat.file.size, 0);\n * ```\n */\n totalBytes: number;\n\n /**\n * The total number of files in the {@link FileUploadHookReturnValue.stats}.\n */\n totalFiles: number;\n}\n\n/**\n * @since 2.9.0\n */\nexport interface ValidatedFilesResult<CustomError> {\n /**\n * A filtered list of files that have been validated and can be queued for the\n * upload process.\n */\n pending: readonly File[];\n\n /**\n * A list of {@link FileValidationError} that occurred during the validation\n * step.\n *\n * Note: If an error has occurred, the file **should not** be added to the\n * {@link pending} list of files.\n */\n errors: readonly FileValidationError<CustomError>[];\n}\n\n/**\n * This function will be called whenever a file has been uploaded by the user\n * either through an `<input type=\"file\">` or drag and drop behavior.\n *\n * @example Simple Example\n * ```ts\n * const validateFiles: FilesValidator = (files, options) => {\n * const invalid: File[] = [];\n * const pending: File[] = [];\n * for (const file of files) {\n * if (!/\\.(jpe?g|svg|png)$/i.test(name)) {\n * invalid.push(file);\n * } else {\n * pending.push(file);\n * }\n * }\n *\n * const errors: FileValidationError[] = [];\n * if (invalid.length) {\n * errors.push(new GenericFileError(invalid))\n * }\n *\n * return { pending, errors };\n * };\n * ```\n *\n * @typeParam E - An optional custom file validation error.\n * @param files - The list of files to check\n * @param options - The {@link FilesValidationOptions}\n * @returns the {@link ValidatedFilesResult}\n * @see {@link validateFiles} for the default implementation\n * @since 2.9.0\n */\nexport type FilesValidator<CustomError = never> = (\n files: readonly File[],\n options: FilesValidationOptions\n) => ValidatedFilesResult<CustomError>;\n\n/**\n * A pretty decent default implementation for validating files with the\n * {@link useFileUpload} that ensures the {@link FilesValidationOptions} are\n * enforced before allowing a file to be uploaded.\n *\n * @typeParam E - An optional custom file validation error.\n * @param files - The list of files to check\n * @param options - The {@link FilesValidationOptions}\n * @returns the {@link ValidatedFilesResult}\n * @since 2.9.0\n */\nexport function validateFiles<CustomError>(\n files: readonly File[],\n options: FilesValidationOptions\n): ValidatedFilesResult<CustomError> {\n const {\n maxFiles,\n extensions,\n minFileSize,\n maxFileSize,\n totalBytes,\n totalFiles,\n totalFileSize,\n isValidFileName,\n } = options;\n\n const errors: FileValidationError<CustomError>[] = [];\n const pending: File[] = [];\n const extraFiles: File[] = [];\n const extensionRegExp =\n extensions.length > 0\n ? new RegExp(`\\\\.(${extensions.join(\"|\")})$`, \"i\")\n : undefined;\n\n let maxFilesReached = maxFiles > 0 && totalFiles >= maxFiles;\n let remainingBytes = totalFileSize - totalBytes;\n const extensionErrors: File[] = [];\n const minErrors: File[] = [];\n const maxErrors: File[] = [];\n const totalSizeErrors: File[] = [];\n for (let i = 0; i < files.length; i += 1) {\n const file = files[i];\n\n let valid = true;\n const { size } = file;\n if (!isValidFileName(file, extensionRegExp, extensions)) {\n valid = false;\n extensionErrors.push(file);\n }\n\n if (minFileSize > 0 && size < minFileSize) {\n valid = false;\n minErrors.push(file);\n }\n\n if (maxFileSize > 0 && size > maxFileSize) {\n valid = false;\n maxErrors.push(file);\n } else if (totalFileSize > 0 && remainingBytes - file.size < 0) {\n // don't want both errors displaying\n valid = false;\n totalSizeErrors.push(file);\n }\n\n if (maxFilesReached && valid) {\n extraFiles.push(file);\n } else if (!maxFilesReached && valid) {\n pending.push(file);\n remainingBytes -= file.size;\n maxFilesReached =\n maxFilesReached ||\n (maxFiles > 0 && totalFiles + pending.length >= maxFiles);\n }\n }\n\n if (extensionErrors.length) {\n errors.push(new FileExtensionError(extensionErrors, extensions));\n }\n\n if (minErrors.length) {\n errors.push(new FileSizeError(minErrors, \"min\", minFileSize));\n }\n\n if (maxErrors.length) {\n errors.push(new FileSizeError(maxErrors, \"max\", maxFileSize));\n }\n\n if (totalSizeErrors.length) {\n errors.push(new FileSizeError(totalSizeErrors, \"total\", totalFileSize));\n }\n\n if (extraFiles.length) {\n errors.push(new TooManyFilesError(extraFiles, maxFiles));\n }\n\n return { pending, errors };\n}\n"],"names":["nanoid","FileAccessError","Error","constructor","message","key","name","GenericFileError","files","reason","TooManyFilesError","limit","FileSizeError","type","FileExtensionError","extensions","isGenericFileError","error","isFileAccessError","isTooManyFilesError","isFileSizeError","isFileExtensionError","isValidFileName","file","matcher","test","validateFiles","options","maxFiles","minFileSize","maxFileSize","totalBytes","totalFiles","totalFileSize","errors","pending","extraFiles","extensionRegExp","length","RegExp","join","undefined","maxFilesReached","remainingBytes","extensionErrors","minErrors","maxErrors","totalSizeErrors","i","valid","size","push"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/files/validation.ts"],"sourcesContent":["import { nanoid } from \"nanoid\";\n\n/**\n * An error that will be created if a user tries dragging and dropping files\n * from a shared directory that they do not have access to. This error will not\n * occur much.\n *\n * @since 2.9.0\n */\nexport class FileAccessError extends Error {\n /**\n * A unique key generated by `nanoid` that can be used as a `React` key\n */\n public key: string;\n\n /**\n *\n * @param message - An optional message for the error.\n */\n constructor(message?: string) {\n super(message);\n this.key = nanoid();\n this.name = \"FileAccessError\";\n }\n}\n\n/**\n * An error that just requires a `File` to be passed as the first argument.\n *\n * @since 2.9.0\n */\nexport class GenericFileError extends Error {\n /**\n * A unique key generated by `nanoid` that can be used as a `React` key\n */\n public key: string;\n\n /**\n *\n * @param files - A list of files that caused the error.\n * @param reason - An optional reason for the error\n */\n constructor(\n public files: readonly File[],\n public reason?: string\n ) {\n super(\"Invalid files\");\n this.key = nanoid();\n this.name = \"GenericFileError\";\n }\n}\n\n/**\n * An error that is created during the upload process if the number of files\n * exceeds the {@link FileUploadOptions.maxFiles} amount.\n *\n * @since 2.9.0\n */\nexport class TooManyFilesError extends GenericFileError {\n /**\n *\n * @param files - The list of files that could not be uploaded due to the file\n * limit defined.\n * @param limit - The max limit of files allowed.\n */\n constructor(\n files: readonly File[],\n public limit: number\n ) {\n super(files, \"file limit\");\n this.name = \"TooManyFilesError\";\n }\n}\n\n/**\n * An error that will be created if a user tries to upload a file that\n * is either:\n * - less than the {@link FileValidationOptions.minFileSize}\n * - greater than the {@link FileValidationOptions.maxFileSize}\n * - including the file would be greater than the {@link FileValidationOptions.totalFileSize}\n *\n * @since 2.9.0\n */\nexport class FileSizeError extends GenericFileError {\n /**\n *\n * @param files - The list of files that have the file size error\n * @param type - The file size error type\n * @param limit - The number of bytes allowed based on the type\n */\n constructor(\n files: readonly File[],\n public type: \"min\" | \"max\" | \"total\",\n public limit: number\n ) {\n super(files, \"file size\");\n this.name = \"FileSizeError\";\n }\n}\n\n/**\n * An error that will be created if a user tries to upload a file that does not\n * end with one of the {@link FileValidationOptions.extensions}.\n *\n * @since 2.9.0\n */\nexport class FileExtensionError extends GenericFileError {\n /**\n *\n * @param files - The file that caused the error\n * @param extensions - The allowed list of file extensions\n */\n constructor(\n files: readonly File[],\n public extensions: readonly string[]\n ) {\n super(files, \"extension\");\n this.name = \"FileExtensionError\";\n }\n}\n\n/**\n * Mostly an internal type that is used to allow custom validation errors\n *\n * @since 2.9.0\n */\nexport type FileValidationError<E = GenericFileError> =\n | FileAccessError\n | TooManyFilesError\n | FileSizeError\n | FileExtensionError\n | E;\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link GenericFileError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileAccessError}\n */\nexport function isGenericFileError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is GenericFileError {\n return \"name\" in error && error.name === \"GenericFileError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link FileAccessError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileAccessError}\n */\nexport function isFileAccessError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is FileAccessError {\n return \"name\" in error && error.name === \"FileAccessError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link TooManyFilesError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link TooManyFilesError}\n */\nexport function isTooManyFilesError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is TooManyFilesError {\n return \"name\" in error && error.name === \"TooManyFilesError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link FileSizeError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileSizeError}\n */\nexport function isFileSizeError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is FileSizeError {\n return \"name\" in error && error.name === \"FileSizeError\";\n}\n\n/**\n * A simple type-guard that can be used to check if the\n * {@link FileValidationError} is the {@link FileExtensionError} which can be\n * useful when displaying the errors to the user.\n *\n * @param error - The error to check\n * @returns true if the error is a {@link FileExtensionError}\n */\nexport function isFileExtensionError<CustomError extends object>(\n error: FileValidationError<CustomError>\n): error is FileExtensionError {\n return \"name\" in error && error.name === \"FileExtensionError\";\n}\n\n/**\n * This function is used to determine if a file should be added to the\n * {@link FileExtensionError}. The default implementation should work for most\n * use cases except when files that do not have extensions can be uploaded. i.e.\n * LICENSE files.\n *\n * @param file - The file being checked\n * @param extensionRegExp - A regex that will only be defined if the\n * `extensions` list had at least one value.\n * @param extensions - The list of extensions allowed\n * @returns true if the file has a valid name.\n * @since 3.1.0\n */\nexport type IsValidFileName = (\n file: File,\n extensionRegExp: RegExp | undefined,\n extensions: readonly string[]\n) => boolean;\n\n/**\n *\n * @defaultValue `matcher?.test(file.name) ?? true`\n * @since 3.1.0\n */\nexport const isValidFileName: IsValidFileName = (file, matcher) =>\n matcher?.test(file.name) ?? true;\n\n/** @since 2.9.0 */\nexport interface FileValidationOptions {\n /**\n * If the number of files should be limited, set this value to a number\n * greater than `0`.\n *\n * Note: This still allows \"infinite\" files when set to `0` since the\n * `<input>` element should normally be set to `disabled` if files should not\n * be able to be uploaded.\n *\n * @defaultValue `-1`\n */\n maxFiles?: number;\n\n /**\n * An optional minimum file size to enforce for each file. This will only be\n * used when it is greater than `0`.\n *\n * @defaultValue `-1`\n */\n minFileSize?: number;\n\n /**\n * An optional maximum file size to enforce for each file. This will only be\n * used when it is greater than `0`.\n *\n * @defaultValue `-1`\n */\n maxFileSize?: number;\n\n /**\n * An optional list of extensions to enforce when uploading files.\n *\n * Note: The extensions and file names will be compared ignoring case.\n *\n * @example Only Allow Images\n * ```ts\n * const extensions = [\"png\", \"jpeg\", \"jpg\", \"gif\"];\n * ```\n */\n extensions?: readonly string[];\n\n /** {@inheritDoc IsValidFileName} */\n isValidFileName?: IsValidFileName;\n\n /**\n * An optional total file size to enforce when the {@link maxFiles} option is\n * not set to `1`.\n *\n * @defaultValue `-1`\n */\n totalFileSize?: number;\n}\n\n/** @since 2.9.0 */\nexport interface FilesValidationOptions\n extends Required<FileValidationOptions> {\n /**\n * The total number of bytes in the {@link FileUploadHookReturnValue.stats}\n * list. This is really just:\n *\n * ```ts\n * const totalBytes = stats.reduce((total, stat) => total + stat.file.size, 0);\n * ```\n */\n totalBytes: number;\n\n /**\n * The total number of files in the {@link FileUploadHookReturnValue.stats}.\n */\n totalFiles: number;\n}\n\n/**\n * @since 2.9.0\n */\nexport interface ValidatedFilesResult<CustomError> {\n /**\n * A filtered list of files that have been validated and can be queued for the\n * upload process.\n */\n pending: readonly File[];\n\n /**\n * A list of {@link FileValidationError} that occurred during the validation\n * step.\n *\n * Note: If an error has occurred, the file **should not** be added to the\n * {@link pending} list of files.\n */\n errors: readonly FileValidationError<CustomError>[];\n}\n\n/**\n * This function will be called whenever a file has been uploaded by the user\n * either through an `<input type=\"file\">` or drag and drop behavior.\n *\n * @example Simple Example\n * ```ts\n * const validateFiles: FilesValidator = (files, options) => {\n * const invalid: File[] = [];\n * const pending: File[] = [];\n * for (const file of files) {\n * if (!/\\.(jpe?g|svg|png)$/i.test(name)) {\n * invalid.push(file);\n * } else {\n * pending.push(file);\n * }\n * }\n *\n * const errors: FileValidationError[] = [];\n * if (invalid.length) {\n * errors.push(new GenericFileError(invalid))\n * }\n *\n * return { pending, errors };\n * };\n * ```\n *\n * @typeParam E - An optional custom file validation error.\n * @param files - The list of files to check\n * @param options - The {@link FilesValidationOptions}\n * @returns the {@link ValidatedFilesResult}\n * @see {@link validateFiles} for the default implementation\n * @since 2.9.0\n */\nexport type FilesValidator<CustomError = never> = (\n files: readonly File[],\n options: FilesValidationOptions\n) => ValidatedFilesResult<CustomError>;\n\n/**\n * A pretty decent default implementation for validating files with the\n * {@link useFileUpload} that ensures the {@link FilesValidationOptions} are\n * enforced before allowing a file to be uploaded.\n *\n * @typeParam E - An optional custom file validation error.\n * @param files - The list of files to check\n * @param options - The {@link FilesValidationOptions}\n * @returns the {@link ValidatedFilesResult}\n * @since 2.9.0\n */\nexport function validateFiles<CustomError>(\n files: readonly File[],\n options: FilesValidationOptions\n): ValidatedFilesResult<CustomError> {\n const {\n maxFiles,\n extensions,\n minFileSize,\n maxFileSize,\n totalBytes,\n totalFiles,\n totalFileSize,\n isValidFileName,\n } = options;\n\n const errors: FileValidationError<CustomError>[] = [];\n const pending: File[] = [];\n const extraFiles: File[] = [];\n const extensionRegExp =\n extensions.length > 0\n ? new RegExp(`\\\\.(${extensions.join(\"|\")})$`, \"i\")\n : undefined;\n\n let maxFilesReached = maxFiles > 0 && totalFiles >= maxFiles;\n let remainingBytes = totalFileSize - totalBytes;\n const extensionErrors: File[] = [];\n const minErrors: File[] = [];\n const maxErrors: File[] = [];\n const totalSizeErrors: File[] = [];\n for (let i = 0; i < files.length; i += 1) {\n const file = files[i];\n\n let valid = true;\n const { size } = file;\n if (!isValidFileName(file, extensionRegExp, extensions)) {\n valid = false;\n extensionErrors.push(file);\n }\n\n if (minFileSize > 0 && size < minFileSize) {\n valid = false;\n minErrors.push(file);\n }\n\n if (maxFileSize > 0 && size > maxFileSize) {\n valid = false;\n maxErrors.push(file);\n } else if (totalFileSize > 0 && remainingBytes - file.size < 0) {\n // don't want both errors displaying\n valid = false;\n totalSizeErrors.push(file);\n }\n\n if (maxFilesReached && valid) {\n extraFiles.push(file);\n } else if (!maxFilesReached && valid) {\n pending.push(file);\n remainingBytes -= file.size;\n maxFilesReached =\n maxFilesReached ||\n (maxFiles > 0 && totalFiles + pending.length >= maxFiles);\n }\n }\n\n if (extensionErrors.length) {\n errors.push(new FileExtensionError(extensionErrors, extensions));\n }\n\n if (minErrors.length) {\n errors.push(new FileSizeError(minErrors, \"min\", minFileSize));\n }\n\n if (maxErrors.length) {\n errors.push(new FileSizeError(maxErrors, \"max\", maxFileSize));\n }\n\n if (totalSizeErrors.length) {\n errors.push(new FileSizeError(totalSizeErrors, \"total\", totalFileSize));\n }\n\n if (extraFiles.length) {\n errors.push(new TooManyFilesError(extraFiles, maxFiles));\n }\n\n return { pending, errors };\n}\n"],"names":["nanoid","FileAccessError","Error","message","key","name","GenericFileError","files","reason","TooManyFilesError","limit","FileSizeError","type","FileExtensionError","extensions","isGenericFileError","error","isFileAccessError","isTooManyFilesError","isFileSizeError","isFileExtensionError","isValidFileName","file","matcher","test","validateFiles","options","maxFiles","minFileSize","maxFileSize","totalBytes","totalFiles","totalFileSize","errors","pending","extraFiles","extensionRegExp","length","RegExp","join","undefined","maxFilesReached","remainingBytes","extensionErrors","minErrors","maxErrors","totalSizeErrors","i","valid","size","push"],"mappings":"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"}
@@ -17,10 +17,17 @@ import { type TransitionCallbacks } from "../transition/types.js";
17
17
  * @since 6.0.0
18
18
  */
19
19
  export type FocusType = "mount" | "unmount" | "keyboard";
20
- /** @since 6.0.0 */
21
- export type FocusContainerTransitionCallbacks = Pick<TransitionCallbacks, "onEntering" | "onEntered" | "onExiting" | "onExited">;
22
- /** @since 6.0.0 */
23
- export interface FocusContainerTransitionOptions<E extends HTMLElement> extends FocusContainerTransitionCallbacks {
20
+ /**
21
+ * @since 6.0.0
22
+ * @deprecated Use `TransitionCallbacks` instead.
23
+ */
24
+ export type FocusContainerTransitionCallbacks = TransitionCallbacks;
25
+ /**
26
+ * @since 6.0.0
27
+ * @since 6.3.2 Fixed by extending `TransitionCallbacks` after the
28
+ * `onEnteredOnce` and `onExitedOnce` support was added to CSS transitions.
29
+ */
30
+ export interface FocusContainerTransitionOptions<E extends HTMLElement> extends TransitionCallbacks {
24
31
  /**
25
32
  * An optional ref that will be merged with the
26
33
  * {@link FocusContainerImplementation.nodeRef}
@@ -50,7 +50,7 @@ const noop = ()=>{
50
50
  *
51
51
  * @since 6.0.0
52
52
  */ export function useFocusContainer(options) {
53
- const { nodeRef, activate, onEntering = noop, onEntered = noop, onExiting = noop, onExited = noop, onKeyDown = noop, programmatic = false, disableTransition = false, isFocusTypeDisabled = noop } = options;
53
+ const { nodeRef, activate, onEnter, onEntering, onEntered, onExit, onExiting, onExited, onKeyDown = noop, programmatic = false, disableTransition = false, isFocusTypeDisabled = noop } = options;
54
54
  const [ref, refCallback] = useEnsuredRef(nodeRef);
55
55
  const prevFocus = useRef(null);
56
56
  useEffect(()=>{
@@ -66,6 +66,7 @@ const noop = ()=>{
66
66
  transitionOptions: {
67
67
  nodeRef: refCallback,
68
68
  ...getTransitionCallbacks({
69
+ onEnter,
69
70
  onEnterOnce: ()=>{
70
71
  const instance = ref.current;
71
72
  if (instance && !isFocusTypeDisabled("mount") && (!document.activeElement || !instance.contains(document.activeElement))) {
@@ -84,6 +85,7 @@ const noop = ()=>{
84
85
  prevFocus.current?.focus();
85
86
  });
86
87
  },
88
+ onExit,
87
89
  onExiting,
88
90
  onExited,
89
91
  disableTransition
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/focus/useFocusContainer.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type KeyboardEventHandler,\n type Ref,\n type RefObject,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { getTransitionCallbacks } from \"../transition/getTransitionCallbacks.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport {\n type FocusElementWithinType,\n focusElementWithin,\n getFocusableElements,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * `\"mount\"` - this will attempt to focus the container element if:\n * - there is no `document.activeElement`\n * - the container element does not contain the `document.activeElement`\n *\n * `\"unmount\"` - attempts to re-focus the element that was focused before the\n * focus container became active. The previous focus element is captured\n * whenever the `activate` option on the `useFocusContainer` hook is set to\n * `true`. This is normally when an element becomes `visible`.\n *\n * `\"keyboard\"` - refocuses the first focusable element if pressing `Tab` would\n * move the focus outside of the container element. If `Shift + Tab` was used,\n * the last focusable element will be used instead.\n *\n * @since 6.0.0\n */\nexport type FocusType = \"mount\" | \"unmount\" | \"keyboard\";\n\n/** @since 6.0.0 */\nexport type FocusContainerTransitionCallbacks = Pick<\n TransitionCallbacks,\n \"onEntering\" | \"onEntered\" | \"onExiting\" | \"onExited\"\n>;\n\n/** @since 6.0.0 */\nexport interface FocusContainerTransitionOptions<E extends HTMLElement>\n extends FocusContainerTransitionCallbacks {\n /**\n * An optional ref that will be merged with the\n * {@link FocusContainerImplementation.nodeRef}\n */\n nodeRef?: Ref<E>;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerEventHandlers<E extends HTMLElement> {\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type IsFocusTypeDisabled = (type: FocusType) => boolean;\n\nexport interface FocusContainerComponentProps {\n /**\n * @defaultValue `() => false`\n */\n isFocusTypeDisabled?: IsFocusTypeDisabled;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerOptions<E extends HTMLElement>\n extends FocusContainerTransitionOptions<E>,\n FocusContainerComponentProps {\n onKeyDown?: KeyboardEventHandler<E>;\n /**\n * This to `true` will capture the current focused element as a focus target\n * once the `onExited` hook is fired. This should usually be set to the\n * `transitionIn` prop for `useTransition`.\n */\n activate: boolean;\n\n /**\n * Set this to true if elements that can be programmatically focused should be\n * included. These would be elements with a `tabIndex={-1}`.\n *\n * @defaultValue `false`\n */\n programmatic?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerImplementation<E extends HTMLElement> {\n nodeRef: RefObject<E>;\n eventHandlers: Required<FocusContainerEventHandlers<E>>;\n transitionOptions: Required<FocusContainerTransitionOptions<E>>;\n}\n\n/**\n * This hook is mostly for internal use only for dialog accessibility behavior\n * to prevent the focus from moving outside of the dialog while it is visible.\n * This API was developed to be used with the `useCSSTransition`/`useTransition`\n * hooks as well.\n *\n * @example Main Usage\n * ```tsx\n * import { Button } from \"@react-md/core/button/Button\"\n * import { useFocusContainer } from \"@react-md/core/focus/useFocusContainer\"\n * import { useScaleTransition } from \"@react-md/core/transition/useScaleTransition\"\n * import { useToggle } from \"@react-md/core/useToggle\"\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { toggled, enable, disable } = useToggle(false);\n *\n * const { eventHandlers, transitionOptions } = useFocusContainer({\n * activate: toggled,\n * });\n * const { elementProps, rendered } = useScaleTransition({\n * transitionIn: toggled,\n * temporary: true,\n * ...transitionOptions,\n * });\n *\n * return (\n * <>\n * <Button onClick={enable}>Toggle</Button>\n * {rendered && (\n * <div {...eventHandlers} {...elementProps}>\n * <Button onClick={disable}>Button 1</Button>\n * <Button onClick={disable}>Button 2</Button>\n * <Button onClick={disable}>Button 3</Button>\n * <Button onClick={disable}>Button 4</Button>\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useFocusContainer<E extends HTMLElement>(\n options: FocusContainerOptions<E>\n): FocusContainerImplementation<E> {\n const {\n nodeRef,\n activate,\n onEntering = noop,\n onEntered = noop,\n onExiting = noop,\n onExited = noop,\n onKeyDown = noop,\n programmatic = false,\n disableTransition = false,\n isFocusTypeDisabled = noop,\n } = options;\n\n const [ref, refCallback] = useEnsuredRef(nodeRef);\n const prevFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!activate || !(document.activeElement instanceof HTMLElement)) {\n return;\n }\n\n prevFocus.current = document.activeElement;\n }, [activate]);\n\n return {\n nodeRef: ref,\n transitionOptions: {\n nodeRef: refCallback,\n ...getTransitionCallbacks({\n onEnterOnce: () => {\n const instance = ref.current;\n if (\n instance &&\n !isFocusTypeDisabled(\"mount\") &&\n (!document.activeElement ||\n !instance.contains(document.activeElement))\n ) {\n instance.focus();\n }\n },\n onEntering,\n onEntered,\n onExitOnce: () => {\n if (isFocusTypeDisabled(\"unmount\")) {\n return;\n }\n\n // For some reason, the `\"Enter\"` keydown event fires at a different timing\n // than the Space keydown event.\n window.requestAnimationFrame(() => {\n prevFocus.current?.focus();\n });\n },\n onExiting,\n onExited,\n disableTransition,\n }),\n },\n eventHandlers: {\n onKeyDown(event) {\n onKeyDown(event);\n if (\n event.isPropagationStopped() ||\n event.key !== \"Tab\" ||\n isFocusTypeDisabled(\"keyboard\")\n ) {\n return;\n }\n\n const { target, shiftKey, currentTarget } = event;\n const elements = getFocusableElements(currentTarget, programmatic);\n const count = elements.length;\n if (count === 0) {\n event.preventDefault();\n return;\n }\n\n // if the container element is the current focus, need to either focus\n // the first or last element so focus doesn't escape\n let type: FocusElementWithinType | undefined;\n if (\n count === 1 ||\n (!shiftKey &&\n (target === currentTarget || target === elements[count - 1]))\n ) {\n type = \"first\";\n } else if (\n shiftKey &&\n (target === currentTarget || target === elements[0])\n ) {\n type = \"last\";\n }\n\n if (type) {\n event.preventDefault();\n focusElementWithin({\n type,\n elements,\n container: currentTarget,\n });\n }\n },\n },\n };\n}\n"],"names":["useEffect","useRef","getTransitionCallbacks","useEnsuredRef","focusElementWithin","getFocusableElements","noop","useFocusContainer","options","nodeRef","activate","onEntering","onEntered","onExiting","onExited","onKeyDown","programmatic","disableTransition","isFocusTypeDisabled","ref","refCallback","prevFocus","document","activeElement","HTMLElement","current","transitionOptions","onEnterOnce","instance","contains","focus","onExitOnce","window","requestAnimationFrame","eventHandlers","event","isPropagationStopped","key","target","shiftKey","currentTarget","elements","count","length","preventDefault","type","container"],"mappings":"AAAA;AAEA,SAIEA,SAAS,EACTC,MAAM,QACD,QAAQ;AAEf,SAASC,sBAAsB,QAAQ,0CAA0C;AAEjF,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAEEC,kBAAkB,EAClBC,oBAAoB,QACf,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AAsFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CC,GACD,OAAO,SAASC,kBACdC,OAAiC;IAEjC,MAAM,EACJC,OAAO,EACPC,QAAQ,EACRC,aAAaL,IAAI,EACjBM,YAAYN,IAAI,EAChBO,YAAYP,IAAI,EAChBQ,WAAWR,IAAI,EACfS,YAAYT,IAAI,EAChBU,eAAe,KAAK,EACpBC,oBAAoB,KAAK,EACzBC,sBAAsBZ,IAAI,EAC3B,GAAGE;IAEJ,MAAM,CAACW,KAAKC,YAAY,GAAGjB,cAAcM;IACzC,MAAMY,YAAYpB,OAA2B;IAE7CD,UAAU;QACR,IAAI,CAACU,YAAY,CAAEY,CAAAA,SAASC,aAAa,YAAYC,WAAU,GAAI;YACjE;QACF;QAEAH,UAAUI,OAAO,GAAGH,SAASC,aAAa;IAC5C,GAAG;QAACb;KAAS;IAEb,OAAO;QACLD,SAASU;QACTO,mBAAmB;YACjBjB,SAASW;YACT,GAAGlB,uBAAuB;gBACxByB,aAAa;oBACX,MAAMC,WAAWT,IAAIM,OAAO;oBAC5B,IACEG,YACA,CAACV,oBAAoB,YACpB,CAAA,CAACI,SAASC,aAAa,IACtB,CAACK,SAASC,QAAQ,CAACP,SAASC,aAAa,CAAA,GAC3C;wBACAK,SAASE,KAAK;oBAChB;gBACF;gBACAnB;gBACAC;gBACAmB,YAAY;oBACV,IAAIb,oBAAoB,YAAY;wBAClC;oBACF;oBAEA,2EAA2E;oBAC3E,iCAAiC;oBACjCc,OAAOC,qBAAqB,CAAC;wBAC3BZ,UAAUI,OAAO,EAAEK;oBACrB;gBACF;gBACAjB;gBACAC;gBACAG;YACF,EAAE;QACJ;QACAiB,eAAe;YACbnB,WAAUoB,KAAK;gBACbpB,UAAUoB;gBACV,IACEA,MAAMC,oBAAoB,MAC1BD,MAAME,GAAG,KAAK,SACdnB,oBAAoB,aACpB;oBACA;gBACF;gBAEA,MAAM,EAAEoB,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAGL;gBAC5C,MAAMM,WAAWpC,qBAAqBmC,eAAexB;gBACrD,MAAM0B,QAAQD,SAASE,MAAM;gBAC7B,IAAID,UAAU,GAAG;oBACfP,MAAMS,cAAc;oBACpB;gBACF;gBAEA,sEAAsE;gBACtE,oDAAoD;gBACpD,IAAIC;gBACJ,IACEH,UAAU,KACT,CAACH,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAACC,QAAQ,EAAE,AAAD,GAC5D;oBACAG,OAAO;gBACT,OAAO,IACLN,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAAC,EAAE,AAAD,GAClD;oBACAI,OAAO;gBACT;gBAEA,IAAIA,MAAM;oBACRV,MAAMS,cAAc;oBACpBxC,mBAAmB;wBACjByC;wBACAJ;wBACAK,WAAWN;oBACb;gBACF;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/focus/useFocusContainer.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type KeyboardEventHandler,\n type Ref,\n type RefObject,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { getTransitionCallbacks } from \"../transition/getTransitionCallbacks.js\";\nimport { type TransitionCallbacks } from \"../transition/types.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport {\n type FocusElementWithinType,\n focusElementWithin,\n getFocusableElements,\n} from \"./utils.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * `\"mount\"` - this will attempt to focus the container element if:\n * - there is no `document.activeElement`\n * - the container element does not contain the `document.activeElement`\n *\n * `\"unmount\"` - attempts to re-focus the element that was focused before the\n * focus container became active. The previous focus element is captured\n * whenever the `activate` option on the `useFocusContainer` hook is set to\n * `true`. This is normally when an element becomes `visible`.\n *\n * `\"keyboard\"` - refocuses the first focusable element if pressing `Tab` would\n * move the focus outside of the container element. If `Shift + Tab` was used,\n * the last focusable element will be used instead.\n *\n * @since 6.0.0\n */\nexport type FocusType = \"mount\" | \"unmount\" | \"keyboard\";\n\n/**\n * @since 6.0.0\n * @deprecated Use `TransitionCallbacks` instead.\n */\nexport type FocusContainerTransitionCallbacks = TransitionCallbacks;\n\n/**\n * @since 6.0.0\n * @since 6.3.2 Fixed by extending `TransitionCallbacks` after the\n * `onEnteredOnce` and `onExitedOnce` support was added to CSS transitions.\n */\nexport interface FocusContainerTransitionOptions<E extends HTMLElement>\n extends TransitionCallbacks {\n /**\n * An optional ref that will be merged with the\n * {@link FocusContainerImplementation.nodeRef}\n */\n nodeRef?: Ref<E>;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerEventHandlers<E extends HTMLElement> {\n onKeyDown?: KeyboardEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n */\nexport type IsFocusTypeDisabled = (type: FocusType) => boolean;\n\nexport interface FocusContainerComponentProps {\n /**\n * @defaultValue `() => false`\n */\n isFocusTypeDisabled?: IsFocusTypeDisabled;\n\n /**\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerOptions<E extends HTMLElement>\n extends FocusContainerTransitionOptions<E>,\n FocusContainerComponentProps {\n onKeyDown?: KeyboardEventHandler<E>;\n /**\n * This to `true` will capture the current focused element as a focus target\n * once the `onExited` hook is fired. This should usually be set to the\n * `transitionIn` prop for `useTransition`.\n */\n activate: boolean;\n\n /**\n * Set this to true if elements that can be programmatically focused should be\n * included. These would be elements with a `tabIndex={-1}`.\n *\n * @defaultValue `false`\n */\n programmatic?: boolean;\n}\n\n/** @since 6.0.0 */\nexport interface FocusContainerImplementation<E extends HTMLElement> {\n nodeRef: RefObject<E>;\n eventHandlers: Required<FocusContainerEventHandlers<E>>;\n transitionOptions: Required<FocusContainerTransitionOptions<E>>;\n}\n\n/**\n * This hook is mostly for internal use only for dialog accessibility behavior\n * to prevent the focus from moving outside of the dialog while it is visible.\n * This API was developed to be used with the `useCSSTransition`/`useTransition`\n * hooks as well.\n *\n * @example Main Usage\n * ```tsx\n * import { Button } from \"@react-md/core/button/Button\"\n * import { useFocusContainer } from \"@react-md/core/focus/useFocusContainer\"\n * import { useScaleTransition } from \"@react-md/core/transition/useScaleTransition\"\n * import { useToggle } from \"@react-md/core/useToggle\"\n * import { type ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { toggled, enable, disable } = useToggle(false);\n *\n * const { eventHandlers, transitionOptions } = useFocusContainer({\n * activate: toggled,\n * });\n * const { elementProps, rendered } = useScaleTransition({\n * transitionIn: toggled,\n * temporary: true,\n * ...transitionOptions,\n * });\n *\n * return (\n * <>\n * <Button onClick={enable}>Toggle</Button>\n * {rendered && (\n * <div {...eventHandlers} {...elementProps}>\n * <Button onClick={disable}>Button 1</Button>\n * <Button onClick={disable}>Button 2</Button>\n * <Button onClick={disable}>Button 3</Button>\n * <Button onClick={disable}>Button 4</Button>\n * </div>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @since 6.0.0\n */\nexport function useFocusContainer<E extends HTMLElement>(\n options: FocusContainerOptions<E>\n): FocusContainerImplementation<E> {\n const {\n nodeRef,\n activate,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n onKeyDown = noop,\n programmatic = false,\n disableTransition = false,\n isFocusTypeDisabled = noop,\n } = options;\n\n const [ref, refCallback] = useEnsuredRef(nodeRef);\n const prevFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!activate || !(document.activeElement instanceof HTMLElement)) {\n return;\n }\n\n prevFocus.current = document.activeElement;\n }, [activate]);\n\n return {\n nodeRef: ref,\n transitionOptions: {\n nodeRef: refCallback,\n ...getTransitionCallbacks({\n onEnter,\n onEnterOnce: () => {\n const instance = ref.current;\n if (\n instance &&\n !isFocusTypeDisabled(\"mount\") &&\n (!document.activeElement ||\n !instance.contains(document.activeElement))\n ) {\n instance.focus();\n }\n },\n onEntering,\n onEntered,\n onExitOnce: () => {\n if (isFocusTypeDisabled(\"unmount\")) {\n return;\n }\n\n // For some reason, the `\"Enter\"` keydown event fires at a different timing\n // than the Space keydown event.\n window.requestAnimationFrame(() => {\n prevFocus.current?.focus();\n });\n },\n onExit,\n onExiting,\n onExited,\n disableTransition,\n }),\n },\n eventHandlers: {\n onKeyDown(event) {\n onKeyDown(event);\n if (\n event.isPropagationStopped() ||\n event.key !== \"Tab\" ||\n isFocusTypeDisabled(\"keyboard\")\n ) {\n return;\n }\n\n const { target, shiftKey, currentTarget } = event;\n const elements = getFocusableElements(currentTarget, programmatic);\n const count = elements.length;\n if (count === 0) {\n event.preventDefault();\n return;\n }\n\n // if the container element is the current focus, need to either focus\n // the first or last element so focus doesn't escape\n let type: FocusElementWithinType | undefined;\n if (\n count === 1 ||\n (!shiftKey &&\n (target === currentTarget || target === elements[count - 1]))\n ) {\n type = \"first\";\n } else if (\n shiftKey &&\n (target === currentTarget || target === elements[0])\n ) {\n type = \"last\";\n }\n\n if (type) {\n event.preventDefault();\n focusElementWithin({\n type,\n elements,\n container: currentTarget,\n });\n }\n },\n },\n };\n}\n"],"names":["useEffect","useRef","getTransitionCallbacks","useEnsuredRef","focusElementWithin","getFocusableElements","noop","useFocusContainer","options","nodeRef","activate","onEnter","onEntering","onEntered","onExit","onExiting","onExited","onKeyDown","programmatic","disableTransition","isFocusTypeDisabled","ref","refCallback","prevFocus","document","activeElement","HTMLElement","current","transitionOptions","onEnterOnce","instance","contains","focus","onExitOnce","window","requestAnimationFrame","eventHandlers","event","isPropagationStopped","key","target","shiftKey","currentTarget","elements","count","length","preventDefault","type","container"],"mappings":"AAAA;AAEA,SAIEA,SAAS,EACTC,MAAM,QACD,QAAQ;AAEf,SAASC,sBAAsB,QAAQ,0CAA0C;AAEjF,SAASC,aAAa,QAAQ,sBAAsB;AACpD,SAEEC,kBAAkB,EAClBC,oBAAoB,QACf,aAAa;AAEpB,MAAMC,OAAO;AACX,aAAa;AACf;AA0FA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CC,GACD,OAAO,SAASC,kBACdC,OAAiC;IAEjC,MAAM,EACJC,OAAO,EACPC,QAAQ,EACRC,OAAO,EACPC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,SAAS,EACTC,QAAQ,EACRC,YAAYX,IAAI,EAChBY,eAAe,KAAK,EACpBC,oBAAoB,KAAK,EACzBC,sBAAsBd,IAAI,EAC3B,GAAGE;IAEJ,MAAM,CAACa,KAAKC,YAAY,GAAGnB,cAAcM;IACzC,MAAMc,YAAYtB,OAA2B;IAE7CD,UAAU;QACR,IAAI,CAACU,YAAY,CAAEc,CAAAA,SAASC,aAAa,YAAYC,WAAU,GAAI;YACjE;QACF;QAEAH,UAAUI,OAAO,GAAGH,SAASC,aAAa;IAC5C,GAAG;QAACf;KAAS;IAEb,OAAO;QACLD,SAASY;QACTO,mBAAmB;YACjBnB,SAASa;YACT,GAAGpB,uBAAuB;gBACxBS;gBACAkB,aAAa;oBACX,MAAMC,WAAWT,IAAIM,OAAO;oBAC5B,IACEG,YACA,CAACV,oBAAoB,YACpB,CAAA,CAACI,SAASC,aAAa,IACtB,CAACK,SAASC,QAAQ,CAACP,SAASC,aAAa,CAAA,GAC3C;wBACAK,SAASE,KAAK;oBAChB;gBACF;gBACApB;gBACAC;gBACAoB,YAAY;oBACV,IAAIb,oBAAoB,YAAY;wBAClC;oBACF;oBAEA,2EAA2E;oBAC3E,iCAAiC;oBACjCc,OAAOC,qBAAqB,CAAC;wBAC3BZ,UAAUI,OAAO,EAAEK;oBACrB;gBACF;gBACAlB;gBACAC;gBACAC;gBACAG;YACF,EAAE;QACJ;QACAiB,eAAe;YACbnB,WAAUoB,KAAK;gBACbpB,UAAUoB;gBACV,IACEA,MAAMC,oBAAoB,MAC1BD,MAAME,GAAG,KAAK,SACdnB,oBAAoB,aACpB;oBACA;gBACF;gBAEA,MAAM,EAAEoB,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAGL;gBAC5C,MAAMM,WAAWtC,qBAAqBqC,eAAexB;gBACrD,MAAM0B,QAAQD,SAASE,MAAM;gBAC7B,IAAID,UAAU,GAAG;oBACfP,MAAMS,cAAc;oBACpB;gBACF;gBAEA,sEAAsE;gBACtE,oDAAoD;gBACpD,IAAIC;gBACJ,IACEH,UAAU,KACT,CAACH,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAACC,QAAQ,EAAE,AAAD,GAC5D;oBACAG,OAAO;gBACT,OAAO,IACLN,YACCD,CAAAA,WAAWE,iBAAiBF,WAAWG,QAAQ,CAAC,EAAE,AAAD,GAClD;oBACAI,OAAO;gBACT;gBAEA,IAAIA,MAAM;oBACRV,MAAMS,cAAc;oBACpB1C,mBAAmB;wBACjB2C;wBACAJ;wBACAK,WAAWN;oBACb;gBACF;YACF;QACF;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/InputToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type LabelHTMLAttributes,\n type ReactNode,\n forwardRef,\n} from \"react\";\n\nimport { type ComponentWithRippleProps } from \"../interaction/types.js\";\nimport { useElementInteraction } from \"../interaction/useElementInteraction.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { InputToggleIcon } from \"./InputToggleIcon.js\";\nimport { Label } from \"./Label.js\";\nimport { type InputToggleSize } from \"./inputToggleStyles.js\";\nimport {\n type FormComponentStates,\n type FormMessageContainerExtension,\n} from \"./types.js\";\n\n/**\n * @since 6.0.0\n */\nexport interface ConfigurableInputToggleIconProps {\n /**\n * @see {@link InputToggleSize}\n * @defaultValue `\"normal\"`\n */\n size?: InputToggleSize;\n\n /**\n * The icon to use while unchecked. This defaults to the unchecked\n * checkbox/radio icon from the `ICON_CONFIG`.\n *\n * @defaultValue `getIcon(props.type)`\n */\n icon?: ReactNode;\n\n /**\n * The icon to use while unchecked. This defaults to the unchecked\n * checkbox/radio icon from the `ICON_CONFIG`.\n *\n * @defaultValue `getIcon(``${props.type}Checked``)`\n */\n checkedIcon?: ReactNode;\n\n /**\n * Any props that should be passed to the `<span>` that surrounds the current\n * icon element.\n */\n iconProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n\n /**\n * Optional style to set on the `<span>` that surrounds the current icon\n * element.\n */\n iconStyle?: CSSProperties;\n\n /**\n * Optional className to set on the `<span>` that surrounds the current icon\n * element.\n */\n iconClassName?: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface InputToggleLabelProps {\n /**\n * An optional label to display with the checkbox. If this is omitted, it is\n * recommended to provide an `aria-label` for accessibility.\n */\n label?: ReactNode;\n\n /**\n * Any props that should be passed to the `<Label>` component.\n *\n * Note: If `style` or `className` are provided in this object, they will be\n * ignored. Use the top-level `style` and `className` props instead.\n *\n * @example\n * ```\n * // bad\n * labelProps={{\n * \"aria-label\": \"checkbox\",\n * style: { color: \"red\" },\n * className: \"custom\"\n * }}\n *\n * // good\n * style={{ color: \"red\" }}\n * className=\"custom\"\n * labelProps={{\n * \"aria-label\": \"checkbox\",\n * }}\n * ```\n */\n labelProps?: PropsWithRef<LabelHTMLAttributes<HTMLLabelElement>>;\n\n /**\n * @see {@link LabelClassNameOptions.gap}\n * @defaultValue `false`\n */\n disableLabelGap?: boolean;\n\n /**\n * Set this to `true` to swap the position of the {@link label} and the current\n * icon. This prop can be used with the {@link stacked} prop to change the\n * position if the icon and label:\n *\n * ____________________________________\n * | stacked | iconAfter | position |\n * ____________________________________\n * | | | icon label |\n * ____________________________________\n * | | X | label icon |\n * ____________________________________\n * | X | | icon |\n * | | | label |\n * ____________________________________\n * | X | X | label |\n * | | | icon |\n * ____________________________________\n *\n *\n * @defaultValue `false`\n */\n iconAfter?: boolean;\n\n /**\n * Set this to `true` if the label should be stacked instead of inline with\n * the current icon.\n *\n * @see {@link iconAfter}\n * @defaultValue `false`\n */\n stacked?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface BaseInputToggleProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\">,\n FormMessageContainerExtension,\n FormComponentStates,\n ConfigurableInputToggleIconProps,\n InputToggleLabelProps,\n ComponentWithRippleProps {\n /**\n * @see https://stackoverflow.com/questions/5985839/bug-with-firefox-disabled-attribute-of-input-not-resetting-when-refreshing\n * @defaultValue `type === \"checkbox\" ? \"off\" : undefined`\n */\n autoComplete?: string;\n}\n\n/**\n * @since 2.8.5\n * @since 6.0.0 Removed the `aria-controls` prop and added the\n * `indeterminateIcon` prop.\n */\nexport interface IndeterminateCheckboxProps {\n /**\n * Set this value to `true` if the checkbox is in an \"indeterminate\" state:\n *\n * - this checkbox controls the select all/select none behavior of other\n * checkboxes in a group\n * - at least one of the checkboxes have been checked\n * - the `checked` prop for this Checkbox should also be `true`\n *\n * You should normally use the `useCheckboxGroup` hook to handle this\n * behavior.\n *\n * @defaultValue `false`\n */\n indeterminate?: boolean;\n\n /**\n * The icon to display when the checkbox is checked and the\n * {@link indeterminate} prop is `true`.\n *\n * @defaultValue `getIcon(\"checkboxIndeterminate\")`\n * @since 6.0.0\n */\n indeterminateIcon?: ReactNode;\n}\n\nexport interface CheckboxProps\n extends BaseInputToggleProps,\n IndeterminateCheckboxProps {}\n\n/** @since 6.0.0 */\nexport interface CheckboxInputToggleProps extends CheckboxProps {\n type: \"checkbox\";\n}\n\nexport interface RadioProps extends BaseInputToggleProps {\n /**\n * The value for the radio button.\n *\n * @since 6.0.0 This is now optional and no longer supports\n * `string[]` since there isn't much of a use case for array values.\n */\n value?: string | number;\n}\n\n/** @since 6.0.0 */\nexport interface RadioInputToggleProps extends RadioProps {\n type: \"radio\";\n}\n\n/**\n * @since 6.0.0 Updated to be a union between\n * `CheckboxInputToggleProps` and `RadioInputToggleProps`\n */\nexport type InputToggleProps = CheckboxInputToggleProps | RadioInputToggleProps;\n\n/**\n * **Client Component**\n *\n * @see {@link https://react-md.dev/components/checkbox | Checkbox Demos}\n * @see {@link https://react-md.dev/components/radio | Radio Demos}\n * @since 6.0.0 Now supports the `FormMessage` behavior and requires\n * different icons for each checked state.\n */\nexport const InputToggle = forwardRef<HTMLInputElement, InputToggleProps>(\n function InputToggle(props, ref) {\n const {\n id: propId,\n type,\n label,\n labelProps,\n style,\n className,\n autoComplete = type === \"checkbox\" ? \"off\" : undefined,\n disableLabelGap = false,\n stacked = false,\n iconAfter = false,\n size = \"normal\",\n error = false,\n active = false,\n indeterminate = false,\n messageProps,\n messageContainerProps,\n icon,\n checkedIcon,\n indeterminateIcon,\n iconProps,\n iconStyle,\n iconClassName,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseLeave,\n onDragStart,\n onMouseUp,\n onTouchEnd,\n onTouchMove,\n onTouchStart,\n disableRipple,\n ...remaining\n } = props as CheckboxInputToggleProps;\n const { disabled = false, checked } = props;\n\n const id = useEnsuredId(propId, type);\n const { pressedClassName, ripples, handlers } = useElementInteraction({\n mode: disableRipple ? \"none\" : undefined,\n disabled,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseLeave,\n onDragStart,\n onMouseUp,\n onTouchEnd,\n onTouchMove,\n onTouchStart,\n });\n\n // set on the `remaining` object to bypass the eslint rule about\n // aria-checked not being valid for textbox role\n remaining[\"aria-checked\"] =\n (remaining[\"aria-checked\"] ?? indeterminate) ? \"mixed\" : undefined;\n\n return (\n <FormMessageContainer\n {...messageContainerProps}\n messageProps={messageProps}\n >\n <Label\n {...labelProps}\n gap={!disableLabelGap}\n style={style}\n stacked={stacked}\n reversed={!iconAfter}\n active={active}\n error={error}\n disabled={disabled}\n className={className}\n >\n {label}\n <InputToggleIcon\n style={iconStyle}\n {...iconProps}\n className={cnb(\n pressedClassName,\n iconClassName,\n iconProps?.className\n )}\n error={error}\n checked={checked}\n disabled={disabled}\n size={size}\n type={type}\n icon={icon}\n checkedIcon={checkedIcon}\n indeterminate={indeterminate}\n indeterminateIcon={indeterminateIcon}\n >\n <input\n {...remaining}\n {...handlers}\n autoComplete={autoComplete}\n id={id}\n ref={ref}\n type={type}\n className=\"rmd-hidden-input\"\n />\n {ripples}\n </InputToggleIcon>\n </Label>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["cnb","forwardRef","useElementInteraction","useEnsuredId","FormMessageContainer","InputToggleIcon","Label","InputToggle","props","ref","id","propId","type","label","labelProps","style","className","autoComplete","undefined","disableLabelGap","stacked","iconAfter","size","error","active","indeterminate","messageProps","messageContainerProps","icon","checkedIcon","indeterminateIcon","iconProps","iconStyle","iconClassName","onBlur","onClick","onKeyDown","onKeyUp","onMouseDown","onMouseLeave","onDragStart","onMouseUp","onTouchEnd","onTouchMove","onTouchStart","disableRipple","remaining","disabled","checked","pressedClassName","ripples","handlers","mode","gap","reversed","input"],"mappings":"AAAA;;AAEA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAMEC,UAAU,QACL,QAAQ;AAGf,SAASC,qBAAqB,QAAQ,0CAA0C;AAEhF,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,oBAAoB,QAAQ,4BAA4B;AACjE,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,KAAK,QAAQ,aAAa;AA6MnC;;;;;;;CAOC,GACD,OAAO,MAAMC,4BAAcN,WACzB,SAASM,YAAYC,KAAK,EAAEC,GAAG;IAC7B,MAAM,EACJC,IAAIC,MAAM,EACVC,IAAI,EACJC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,SAAS,EACTC,eAAeL,SAAS,aAAa,QAAQM,SAAS,EACtDC,kBAAkB,KAAK,EACvBC,UAAU,KAAK,EACfC,YAAY,KAAK,EACjBC,OAAO,QAAQ,EACfC,QAAQ,KAAK,EACbC,SAAS,KAAK,EACdC,gBAAgB,KAAK,EACrBC,YAAY,EACZC,qBAAqB,EACrBC,IAAI,EACJC,WAAW,EACXC,iBAAiB,EACjBC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,MAAM,EACNC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,WAAW,EACXC,YAAY,EACZC,WAAW,EACXC,SAAS,EACTC,UAAU,EACVC,WAAW,EACXC,YAAY,EACZC,aAAa,EACb,GAAGC,WACJ,GAAGtC;IACJ,MAAM,EAAEuC,WAAW,KAAK,EAAEC,OAAO,EAAE,GAAGxC;IAEtC,MAAME,KAAKP,aAAaQ,QAAQC;IAChC,MAAM,EAAEqC,gBAAgB,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGjD,sBAAsB;QACpEkD,MAAMP,gBAAgB,SAAS3B;QAC/B6B;QACAb;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;IAEA,gEAAgE;IAChE,gDAAgD;IAChDE,SAAS,CAAC,eAAe,GACvB,AAACA,SAAS,CAAC,eAAe,IAAIrB,gBAAiB,UAAUP;IAE3D,qBACE,KAACd;QACE,GAAGuB,qBAAqB;QACzBD,cAAcA;kBAEd,cAAA,MAACpB;YACE,GAAGQ,UAAU;YACduC,KAAK,CAAClC;YACNJ,OAAOA;YACPK,SAASA;YACTkC,UAAU,CAACjC;YACXG,QAAQA;YACRD,OAAOA;YACPwB,UAAUA;YACV/B,WAAWA;;gBAEVH;8BACD,MAACR;oBACCU,OAAOiB;oBACN,GAAGD,SAAS;oBACbf,WAAWhB,IACTiD,kBACAhB,eACAF,WAAWf;oBAEbO,OAAOA;oBACPyB,SAASA;oBACTD,UAAUA;oBACVzB,MAAMA;oBACNV,MAAMA;oBACNgB,MAAMA;oBACNC,aAAaA;oBACbJ,eAAeA;oBACfK,mBAAmBA;;sCAEnB,KAACyB;4BACE,GAAGT,SAAS;4BACZ,GAAGK,QAAQ;4BACZlC,cAAcA;4BACdP,IAAIA;4BACJD,KAAKA;4BACLG,MAAMA;4BACNI,WAAU;;wBAEXkC;;;;;;AAKX,GACA"}
1
+ {"version":3,"sources":["../../src/form/InputToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type LabelHTMLAttributes,\n type ReactNode,\n forwardRef,\n} from \"react\";\n\nimport { type ComponentWithRippleProps } from \"../interaction/types.js\";\nimport { useElementInteraction } from \"../interaction/useElementInteraction.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { InputToggleIcon } from \"./InputToggleIcon.js\";\nimport { Label } from \"./Label.js\";\nimport { type InputToggleSize } from \"./inputToggleStyles.js\";\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { type LabelClassNameOptions } from \"./types.js\";\nimport {\n type FormComponentStates,\n type FormMessageContainerExtension,\n} from \"./types.js\";\n\n/**\n * @since 6.0.0\n */\nexport interface ConfigurableInputToggleIconProps {\n /**\n * @see {@link InputToggleSize}\n * @defaultValue `\"normal\"`\n */\n size?: InputToggleSize;\n\n /**\n * The icon to use while unchecked. This defaults to the unchecked\n * checkbox/radio icon from the `ICON_CONFIG`.\n *\n * @defaultValue `getIcon(props.type)`\n */\n icon?: ReactNode;\n\n /**\n * The icon to use while unchecked. This defaults to the unchecked\n * checkbox/radio icon from the `ICON_CONFIG`.\n *\n * @defaultValue `getIcon(``${props.type}Checked``)`\n */\n checkedIcon?: ReactNode;\n\n /**\n * Any props that should be passed to the `<span>` that surrounds the current\n * icon element.\n */\n iconProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n\n /**\n * Optional style to set on the `<span>` that surrounds the current icon\n * element.\n */\n iconStyle?: CSSProperties;\n\n /**\n * Optional className to set on the `<span>` that surrounds the current icon\n * element.\n */\n iconClassName?: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface InputToggleLabelProps {\n /**\n * An optional label to display with the checkbox. If this is omitted, it is\n * recommended to provide an `aria-label` for accessibility.\n */\n label?: ReactNode;\n\n /**\n * Any props that should be passed to the `<Label>` component.\n *\n * Note: If `style` or `className` are provided in this object, they will be\n * ignored. Use the top-level `style` and `className` props instead.\n *\n * @example\n * ```\n * // bad\n * labelProps={{\n * \"aria-label\": \"checkbox\",\n * style: { color: \"red\" },\n * className: \"custom\"\n * }}\n *\n * // good\n * style={{ color: \"red\" }}\n * className=\"custom\"\n * labelProps={{\n * \"aria-label\": \"checkbox\",\n * }}\n * ```\n */\n labelProps?: PropsWithRef<LabelHTMLAttributes<HTMLLabelElement>>;\n\n /**\n * @see {@link LabelClassNameOptions.gap}\n * @defaultValue `false`\n */\n disableLabelGap?: boolean;\n\n /**\n * Set this to `true` to swap the position of the {@link label} and the current\n * icon. This prop can be used with the {@link stacked} prop to change the\n * position if the icon and label:\n *\n * ____________________________________\n * | stacked | iconAfter | position |\n * ____________________________________\n * | | | icon label |\n * ____________________________________\n * | | X | label icon |\n * ____________________________________\n * | X | | icon |\n * | | | label |\n * ____________________________________\n * | X | X | label |\n * | | | icon |\n * ____________________________________\n *\n *\n * @defaultValue `false`\n */\n iconAfter?: boolean;\n\n /**\n * Set this to `true` if the label should be stacked instead of inline with\n * the current icon.\n *\n * @see {@link iconAfter}\n * @defaultValue `false`\n */\n stacked?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface BaseInputToggleProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\">,\n FormMessageContainerExtension,\n FormComponentStates,\n ConfigurableInputToggleIconProps,\n InputToggleLabelProps,\n ComponentWithRippleProps {\n /**\n * @see https://stackoverflow.com/questions/5985839/bug-with-firefox-disabled-attribute-of-input-not-resetting-when-refreshing\n * @defaultValue `type === \"checkbox\" ? \"off\" : undefined`\n */\n autoComplete?: string;\n}\n\n/**\n * @since 2.8.5\n * @since 6.0.0 Removed the `aria-controls` prop and added the\n * `indeterminateIcon` prop.\n */\nexport interface IndeterminateCheckboxProps {\n /**\n * Set this value to `true` if the checkbox is in an \"indeterminate\" state:\n *\n * - this checkbox controls the select all/select none behavior of other\n * checkboxes in a group\n * - at least one of the checkboxes have been checked\n * - the `checked` prop for this Checkbox should also be `true`\n *\n * You should normally use the `useCheckboxGroup` hook to handle this\n * behavior.\n *\n * @defaultValue `false`\n */\n indeterminate?: boolean;\n\n /**\n * The icon to display when the checkbox is checked and the\n * {@link indeterminate} prop is `true`.\n *\n * @defaultValue `getIcon(\"checkboxIndeterminate\")`\n * @since 6.0.0\n */\n indeterminateIcon?: ReactNode;\n}\n\nexport interface CheckboxProps\n extends BaseInputToggleProps,\n IndeterminateCheckboxProps {}\n\n/** @since 6.0.0 */\nexport interface CheckboxInputToggleProps extends CheckboxProps {\n type: \"checkbox\";\n}\n\nexport interface RadioProps extends BaseInputToggleProps {\n /**\n * The value for the radio button.\n *\n * @since 6.0.0 This is now optional and no longer supports\n * `string[]` since there isn't much of a use case for array values.\n */\n value?: string | number;\n}\n\n/** @since 6.0.0 */\nexport interface RadioInputToggleProps extends RadioProps {\n type: \"radio\";\n}\n\n/**\n * @since 6.0.0 Updated to be a union between\n * `CheckboxInputToggleProps` and `RadioInputToggleProps`\n */\nexport type InputToggleProps = CheckboxInputToggleProps | RadioInputToggleProps;\n\n/**\n * **Client Component**\n *\n * @see {@link https://react-md.dev/components/checkbox | Checkbox Demos}\n * @see {@link https://react-md.dev/components/radio | Radio Demos}\n * @since 6.0.0 Now supports the `FormMessage` behavior and requires\n * different icons for each checked state.\n */\nexport const InputToggle = forwardRef<HTMLInputElement, InputToggleProps>(\n function InputToggle(props, ref) {\n const {\n id: propId,\n type,\n label,\n labelProps,\n style,\n className,\n autoComplete = type === \"checkbox\" ? \"off\" : undefined,\n disableLabelGap = false,\n stacked = false,\n iconAfter = false,\n size = \"normal\",\n error = false,\n active = false,\n indeterminate = false,\n messageProps,\n messageContainerProps,\n icon,\n checkedIcon,\n indeterminateIcon,\n iconProps,\n iconStyle,\n iconClassName,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseLeave,\n onDragStart,\n onMouseUp,\n onTouchEnd,\n onTouchMove,\n onTouchStart,\n disableRipple,\n ...remaining\n } = props as CheckboxInputToggleProps;\n const { disabled = false, checked } = props;\n\n const id = useEnsuredId(propId, type);\n const { pressedClassName, ripples, handlers } = useElementInteraction({\n mode: disableRipple ? \"none\" : undefined,\n disabled,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseLeave,\n onDragStart,\n onMouseUp,\n onTouchEnd,\n onTouchMove,\n onTouchStart,\n });\n\n // set on the `remaining` object to bypass the eslint rule about\n // aria-checked not being valid for textbox role\n remaining[\"aria-checked\"] =\n (remaining[\"aria-checked\"] ?? indeterminate) ? \"mixed\" : undefined;\n\n return (\n <FormMessageContainer\n {...messageContainerProps}\n messageProps={messageProps}\n >\n <Label\n {...labelProps}\n gap={!disableLabelGap}\n style={style}\n stacked={stacked}\n reversed={!iconAfter}\n active={active}\n error={error}\n disabled={disabled}\n className={className}\n >\n {label}\n <InputToggleIcon\n style={iconStyle}\n {...iconProps}\n className={cnb(\n pressedClassName,\n iconClassName,\n iconProps?.className\n )}\n error={error}\n checked={checked}\n disabled={disabled}\n size={size}\n type={type}\n icon={icon}\n checkedIcon={checkedIcon}\n indeterminate={indeterminate}\n indeterminateIcon={indeterminateIcon}\n >\n <input\n {...remaining}\n {...handlers}\n autoComplete={autoComplete}\n id={id}\n ref={ref}\n type={type}\n className=\"rmd-hidden-input\"\n />\n {ripples}\n </InputToggleIcon>\n </Label>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["cnb","forwardRef","useElementInteraction","useEnsuredId","FormMessageContainer","InputToggleIcon","Label","InputToggle","props","ref","id","propId","type","label","labelProps","style","className","autoComplete","undefined","disableLabelGap","stacked","iconAfter","size","error","active","indeterminate","messageProps","messageContainerProps","icon","checkedIcon","indeterminateIcon","iconProps","iconStyle","iconClassName","onBlur","onClick","onKeyDown","onKeyUp","onMouseDown","onMouseLeave","onDragStart","onMouseUp","onTouchEnd","onTouchMove","onTouchStart","disableRipple","remaining","disabled","checked","pressedClassName","ripples","handlers","mode","gap","reversed","input"],"mappings":"AAAA;;AAEA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAMEC,UAAU,QACL,QAAQ;AAGf,SAASC,qBAAqB,QAAQ,0CAA0C;AAEhF,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,oBAAoB,QAAQ,4BAA4B;AACjE,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,KAAK,QAAQ,aAAa;AA+MnC;;;;;;;CAOC,GACD,OAAO,MAAMC,4BAAcN,WACzB,SAASM,YAAYC,KAAK,EAAEC,GAAG;IAC7B,MAAM,EACJC,IAAIC,MAAM,EACVC,IAAI,EACJC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,SAAS,EACTC,eAAeL,SAAS,aAAa,QAAQM,SAAS,EACtDC,kBAAkB,KAAK,EACvBC,UAAU,KAAK,EACfC,YAAY,KAAK,EACjBC,OAAO,QAAQ,EACfC,QAAQ,KAAK,EACbC,SAAS,KAAK,EACdC,gBAAgB,KAAK,EACrBC,YAAY,EACZC,qBAAqB,EACrBC,IAAI,EACJC,WAAW,EACXC,iBAAiB,EACjBC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,MAAM,EACNC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,WAAW,EACXC,YAAY,EACZC,WAAW,EACXC,SAAS,EACTC,UAAU,EACVC,WAAW,EACXC,YAAY,EACZC,aAAa,EACb,GAAGC,WACJ,GAAGtC;IACJ,MAAM,EAAEuC,WAAW,KAAK,EAAEC,OAAO,EAAE,GAAGxC;IAEtC,MAAME,KAAKP,aAAaQ,QAAQC;IAChC,MAAM,EAAEqC,gBAAgB,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGjD,sBAAsB;QACpEkD,MAAMP,gBAAgB,SAAS3B;QAC/B6B;QACAb;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;IAEA,gEAAgE;IAChE,gDAAgD;IAChDE,SAAS,CAAC,eAAe,GACvB,AAACA,SAAS,CAAC,eAAe,IAAIrB,gBAAiB,UAAUP;IAE3D,qBACE,KAACd;QACE,GAAGuB,qBAAqB;QACzBD,cAAcA;kBAEd,cAAA,MAACpB;YACE,GAAGQ,UAAU;YACduC,KAAK,CAAClC;YACNJ,OAAOA;YACPK,SAASA;YACTkC,UAAU,CAACjC;YACXG,QAAQA;YACRD,OAAOA;YACPwB,UAAUA;YACV/B,WAAWA;;gBAEVH;8BACD,MAACR;oBACCU,OAAOiB;oBACN,GAAGD,SAAS;oBACbf,WAAWhB,IACTiD,kBACAhB,eACAF,WAAWf;oBAEbO,OAAOA;oBACPyB,SAASA;oBACTD,UAAUA;oBACVzB,MAAMA;oBACNV,MAAMA;oBACNgB,MAAMA;oBACNC,aAAaA;oBACbJ,eAAeA;oBACfK,mBAAmBA;;sCAEnB,KAACyB;4BACE,GAAGT,SAAS;4BACZ,GAAGK,QAAQ;4BACZlC,cAAcA;4BACdP,IAAIA;4BACJD,KAAKA;4BACLG,MAAMA;4BACNI,WAAU;;wBAEXkC;;;;;;AAKX,GACA"}
@@ -1,14 +1,4 @@
1
1
  import { type LabelProps } from "./types.js";
2
- declare module "react" {
3
- interface CSSProperties {
4
- "--rmd-label-floating-x"?: string | number;
5
- "--rmd-label-floating-y"?: string | number;
6
- "--rmd-label-floating-active-x"?: string | number;
7
- "--rmd-label-floating-active-y"?: string | number;
8
- "--rmd-label-active-padding"?: string | number;
9
- "--rmd-label-active-background-color"?: string;
10
- }
11
- }
12
2
  /**
13
3
  * Most of the form components already use this `Label` internally when a
14
4
  * `label` prop has been provided. You should generally use this component if
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/Label.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { label } from \"./labelStyles.js\";\nimport { type LabelProps } from \"./types.js\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-label-floating-x\"?: string | number;\n \"--rmd-label-floating-y\"?: string | number;\n \"--rmd-label-floating-active-x\"?: string | number;\n \"--rmd-label-floating-active-y\"?: string | number;\n \"--rmd-label-active-padding\"?: string | number;\n \"--rmd-label-active-background-color\"?: string;\n }\n}\n\n/**\n * Most of the form components already use this `Label` internally when a\n * `label` prop has been provided. You should generally use this component if\n * you need to separate the label from an existing form component or you need to\n * create a custom implementation of a form component.\n *\n * @see {@link https://react-md.dev/components/select | Select Demos}\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/components/text-field#simple-textarea | TextArea Demos}\n * @since 6.0.0 Updated to be usable externally and combines the\n * floating label styles instead of having separate components.\n */\nexport const Label = forwardRef<HTMLLabelElement, LabelProps>(\n function Label(props, ref) {\n const {\n gap,\n error,\n dense,\n active,\n stacked,\n reversed,\n disabled,\n floating,\n inactive,\n floatingActive = active,\n className,\n children,\n ...remaining\n } = props;\n\n return (\n <label\n ref={ref}\n {...remaining}\n className={label({\n gap,\n error,\n dense,\n active,\n stacked,\n reversed,\n disabled,\n floating,\n floatingActive,\n inactive,\n className,\n })}\n >\n {children}\n </label>\n );\n }\n);\n"],"names":["forwardRef","label","Label","props","ref","gap","error","dense","active","stacked","reversed","disabled","floating","inactive","floatingActive","className","children","remaining"],"mappings":";AAAA,SAASA,UAAU,QAAQ,QAAQ;AAEnC,SAASC,KAAK,QAAQ,mBAAmB;AAczC;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,sBAAQF,WACnB,SAASE,MAAMC,KAAK,EAAEC,GAAG;IACvB,MAAM,EACJC,GAAG,EACHC,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EACRC,iBAAiBN,MAAM,EACvBO,SAAS,EACTC,QAAQ,EACR,GAAGC,WACJ,GAAGd;IAEJ,qBACE,KAACF;QACCG,KAAKA;QACJ,GAAGa,SAAS;QACbF,WAAWd,MAAM;YACfI;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAD;YACAE;QACF;kBAECC;;AAGP,GACA"}
1
+ {"version":3,"sources":["../../src/form/Label.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { label } from \"./labelStyles.js\";\nimport { type LabelProps } from \"./types.js\";\n\n/**\n * Most of the form components already use this `Label` internally when a\n * `label` prop has been provided. You should generally use this component if\n * you need to separate the label from an existing form component or you need to\n * create a custom implementation of a form component.\n *\n * @see {@link https://react-md.dev/components/select | Select Demos}\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/components/text-field#simple-textarea | TextArea Demos}\n * @since 6.0.0 Updated to be usable externally and combines the\n * floating label styles instead of having separate components.\n */\nexport const Label = forwardRef<HTMLLabelElement, LabelProps>(\n function Label(props, ref) {\n const {\n gap,\n error,\n dense,\n active,\n stacked,\n reversed,\n disabled,\n floating,\n inactive,\n floatingActive = active,\n className,\n children,\n ...remaining\n } = props;\n\n return (\n <label\n ref={ref}\n {...remaining}\n className={label({\n gap,\n error,\n dense,\n active,\n stacked,\n reversed,\n disabled,\n floating,\n floatingActive,\n inactive,\n className,\n })}\n >\n {children}\n </label>\n );\n }\n);\n"],"names":["forwardRef","label","Label","props","ref","gap","error","dense","active","stacked","reversed","disabled","floating","inactive","floatingActive","className","children","remaining"],"mappings":";AAAA,SAASA,UAAU,QAAQ,QAAQ;AAEnC,SAASC,KAAK,QAAQ,mBAAmB;AAGzC;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,sBAAQF,WACnB,SAASE,MAAMC,KAAK,EAAEC,GAAG;IACvB,MAAM,EACJC,GAAG,EACHC,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EACRC,iBAAiBN,MAAM,EACvBO,SAAS,EACTC,QAAQ,EACR,GAAGC,WACJ,GAAGd;IAEJ,qBACE,KAACF;QACCG,KAAKA;QACJ,GAAGa,SAAS;QACbF,WAAWd,MAAM;YACfI;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAE;YACAD;YACAE;QACF;kBAECC;;AAGP,GACA"}
@@ -20,6 +20,10 @@ declare module "react" {
20
20
  "--rmd-slider-tooltip-scale"?: string | number;
21
21
  "--rmd-slider-tooltip-translate"?: string | number;
22
22
  "--rmd-slider-mark-offset"?: string;
23
+ "--rmd-slider-mark-active-color"?: string;
24
+ "--rmd-slider-mark-active-opacity"?: string | number;
25
+ "--rmd-slider-mark-inactive-color"?: string;
26
+ "--rmd-slider-mark-inactive-opacity"?: string | number;
23
27
  }
24
28
  }
25
29
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/Slider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n useRef,\n} from \"react\";\n\nimport { type TooltipProps } from \"../tooltip/Tooltip.js\";\nimport {\n type LabelRequiredForA11y,\n type PropsWithRef,\n type UseStateSetter,\n} from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { identity } from \"../utils/identity.js\";\nimport { type SliderAddonProps, SliderContainer } from \"./SliderContainer.js\";\nimport {\n type ConfigurableSliderThumbProps,\n SliderThumb,\n type SliderThumbPresentation,\n type SliderThumbProps,\n} from \"./SliderThumb.js\";\nimport { SliderTrack } from \"./SliderTrack.js\";\nimport {\n type SliderMarksOptions,\n SliderValueMarks,\n} from \"./SliderValueMarks.js\";\nimport { getJumpValue, getSliderInputName } from \"./sliderUtils.js\";\nimport { type RangeSliderState } from \"./useRangeSlider.js\";\nimport { type SliderState, type SliderValueOptions } from \"./useSlider.js\";\nimport { useSliderDraggable } from \"./useSliderDraggable.js\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-slider-color\"?: string;\n \"--rmd-slider-active-color\"?: string;\n \"--rmd-slider-inactive-color\"?: string;\n \"--rmd-slider-size\"?: string | number;\n \"--rmd-slider-active-size\"?: string | number;\n \"--rmd-slider-inactive-size\"?: string | number;\n \"--rmd-slider-vertical-size\"?: string | number;\n \"--rmd-slider-offset-1\"?: string;\n \"--rmd-slider-offset-2\"?: string;\n \"--rmd-slider-tooltip-scale\"?: string | number;\n \"--rmd-slider-tooltip-translate\"?: string | number;\n \"--rmd-slider-mark-offset\"?: string;\n }\n}\n\nconst emptyString = (): string => \"\";\nconst noop = (): undefined => {\n // do nothing\n};\n\n/**\n * @since 2.5.0\n */\nexport interface BaseSliderProps\n extends HTMLAttributes<HTMLDivElement>,\n SliderThumbPresentation,\n SliderValueOptions,\n SliderAddonProps,\n SliderMarksOptions {\n /**\n * This can be used to apply a ref to the container element since this\n * component does not use `forwardRef`.\n */\n containerRef?: Ref<HTMLDivElement>;\n\n /**\n * The amount to jump the slider's value when the `PageUp` or `PageDown`\n * key is pressed.\n *\n * The default value is 1/10th of the range.\n *\n * @defaultValue `(numberOfSteps / 10) * step`\n */\n jump?: number;\n\n /** @defaultValue `false` */\n disabled?: boolean;\n\n /** @defaultValue `false` */\n vertical?: boolean;\n\n /**\n * This can be used to apply custom styles or a `ref` to the track element if\n * needed.\n */\n trackProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n\n /**\n * This can be used to configure any additional tooltip props like the\n * CSS transition `classNames`, styles, etc.\n *\n * This will only be used when {@link discrete} is `true`.\n *\n * Note: The `position` will always be `\"above\"` for horizontal sliders and\n * `\"left\"` for vertical sliders.\n */\n tooltipProps?: Omit<Partial<TooltipProps>, \"position\">;\n}\n\n/**\n * @since 2.5.0\n * @since 6.0.0 Only requires `value` and `setValue` props instead of all the\n * slider controls.\n * @since 6.0.0 The `thumbLabel` and `thumbLabelledBy` props were removed. Use\n * the `aria-label` or `aria-labelledby` props instead.\n * @since 6.0.0 The `baseId` prop was removed in favor of `id` or `*Props.id`\n */\nexport interface SliderProps extends BaseSliderProps, SliderState {\n /**\n * Convenience pass-through prop to {@link ConfigurableSliderThumbProps.name} which\n * will be applied to the hidden `<input type=\"range\" />`\n */\n name?: string;\n\n /**\n * Any additional props that should be provided to the thumb element. This can\n * be useful for applying additional styling.\n */\n thumbProps?: ConfigurableSliderThumbProps;\n\n /**\n * This can be used to update the discrete slider's tooltip props.\n *\n * @example Custom Styles\n * ```tsx\n * <Slider\n * {...slider}\n * discrete\n * getTooltipProps={(value) => ({\n * className: cssUtils({\n * backgroundColor: value < 30 ? \"warning\" : undefined,\n * }),\n * })}\n * />\n * ```\n */\n getTooltipProps?: (value: number) => Partial<TooltipProps> | undefined;\n\n /**\n * This can be used to update the discrete slider's value tooltip.\n *\n * @example More Value Information\n * ```tsx\n * <Slider\n * {...slider}\n * discrete\n * getTooltipChildren={(value) => (\n * <TextIconSpacing icon={<FavoriteIcon />}>\n * {value}\n * </TextIconSpacing>\n * )}\n * />\n * ```\n *\n * This will only be used when {@link discrete} is `true`.\n *\n * @defaultValue `(value) => value`\n */\n getTooltipChildren?: (value: number) => ReactNode;\n}\n\n/**\n * @since 2.5.0\n * @since 6.0.0 Only requires `rangeValue` and `setRangeValue` props instead of\n * all the slider controls.\n * @since 6.0.0 The `thumb1Label`, `thumb1LabelledBy`, `thumb1Props`,\n * `thumb2Label`, `thumb2LabelledBy` and `thumb2Props` were renamed to\n * `minThumbLabel`, `minThumbLabelledBy`, `minThumbProps`, `maxThumbLabel`,\n * `maxThumbLabelledBy`, and `maxThumbProps` respectively.\n */\nexport interface RangeSliderProps extends BaseSliderProps, RangeSliderState {\n /**\n * Convenience pass-through prop for {@link\n * ConfigurableSliderThumbProps.name} for both the {@link minThumbProps} and\n * {@link maxThumbProps}.\n */\n name?: string;\n\n /**\n * Any additional props that should be provided to the min value thumb\n * element. This can be useful for applying additional styling.\n */\n minThumbProps?: ConfigurableSliderThumbProps;\n\n /**\n * Any additional props that should be provided to the max value thumb\n * element. This can be useful for applying additional styling.\n */\n maxThumbProps?: ConfigurableSliderThumbProps;\n\n /**\n * The `aria-label` to apply to the min value.\n *\n * Note: Either this prop or the {@link minThumbLabelledBy} are required for\n * accessibility.\n *\n * @defaultValue `\"Min\"`\n */\n minThumbLabel?: string;\n\n /**\n * Set this to an element's id that labels the min value.\n *\n * Note: Either this prop or the {@link minThumbLabel} are required for\n * accessibility.\n */\n minThumbLabelledBy?: string;\n\n /**\n * The `aria-label` to apply to the max value.\n *\n * Note: Either this prop or the {@link maxThumbLabelledBy} are required for\n * accessibility.\n *\n * @defaultValue `\"Max\"`\n */\n maxThumbLabel?: string;\n\n /**\n * Set this to an element's id that labels the max value.\n *\n * Note: Either this prop or the {@link maxThumbLabel} are required for\n * accessibility.\n */\n maxThumbLabelledBy?: string;\n\n /**\n * This can be used to update the discrete slider's tooltip props.\n *\n * @example Custom Styles\n * ```tsx\n * <Slider\n * {...slider}\n * discrete\n * getTooltipProps={(value, isFirstThumb) => ({\n * className: cssUtils({\n * backgroundColor: value < 30 && isFirstThumb ? \"warning\" : undefined,\n * }),\n * })}\n * />\n * ```\n */\n getTooltipProps?: (\n value: number,\n isFirstThumb: boolean\n ) => Partial<TooltipProps>;\n\n /**\n * This can be used to update the discrete slider's value tooltip.\n *\n * @example More Value Information\n * ```tsx\n * <Slider\n * {...rangeSlider}\n * discrete\n * getTooltipChildren={(value, isFirstThumb) => (\n * <TextIconSpacing\n * icon={isFirstThumb ? <FavoriteIcon /> : <CloseIcon /}\n * iconAfter={!isFirstValue}\n * >\n * {value}\n * </TextIconSpacing>\n * )}\n * />\n * ```\n *\n * This will only be used when {@link discrete} is `true`.\n *\n * @defaultValue `(value) => value`\n */\n getTooltipChildren?: (value: number, isFirstThumb: boolean) => ReactNode;\n}\n\n/**\n * **Client Component**\n *\n * @example Simple Example\n * ```tsx\n * import { Form } from \"@react-md/core/form/Form\";\n * import { Slider } from \"@react-md/core/form/Slider\";\n * import { useSlider } from \"@react-md/core/form/useSlider\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const slider = useSlider({\n * // these are the defaults and can be changed\n * min: 0,\n * max: 100,\n * step: 1,\n * defaultValue: 50,\n * });\n *\n * // if you need access to the current value or manually change the value\n * // yourself.\n * const { value, setValue } = slider;\n *\n * return (\n * <Form>\n * <Slider {...slider} aria-label=\"Volume\" />\n * </Form>\n * );\n * }\n * ```\n *\n * @example Range Slider Example\n * ```tsx\n * import { Fieldset } from \"@react-md/core/form/Fieldset\";\n * import { Form } from \"@react-md/core/form/Form\";\n * import { Legend } from \"@react-md/core/form/Legend\";\n * import { Slider } from \"@react-md/core/form/Slider\";\n * import { useRangeSlider } from \"@react-md/core/form/useRangeSlider\";\n * import type { ReactElement } from \"react\";\n * import { useId } from \"react\";\n *\n * function Example(): ReactElement {\n * const slider = useRangeSlider({\n * // these are the defaults and can be changed\n * min: 0,\n * max: 100,\n * step: 1,\n * defaultValue: [0, 100],\n * });\n *\n * // if you need access to the current value or manually change the value\n * // yourself.\n * const { rangeValue, setRangeValue } = slider;\n * const [minPrice, maxPrice] = rangeValue;\n *\n * return (\n * <Form>\n * <Fieldset>\n * <Legend>Price Range</Legend>\n * <Slider {...slider} />\n * </Fieldset>\n * </Form>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/slider | Slider Demos}\n * @since 2.5.0\n * @since 6.0.0 The `Slider` and `RangeSlider` have been combined into the\n * single `Slider` component and removed the `label` support.\n * @since 6.0.0 Each thumb includes an invisible `<input type=\"range\">` instead\n * of an `<input type=\"hidden\">`.\n */\nexport function Slider(props: LabelRequiredForA11y<SliderProps>): ReactElement;\nexport function Slider(props: RangeSliderProps): ReactElement;\nexport function Slider(\n props: LabelRequiredForA11y<SliderProps> | RangeSliderProps\n): ReactElement {\n const {\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id: propId,\n name,\n min = 0,\n max = 100,\n step = 1,\n jump: propJump,\n vertical = false,\n discrete = false,\n disabled = false,\n getValueText = emptyString,\n children,\n marks = false,\n value,\n setValue,\n rangeValue,\n setRangeValue,\n trackProps,\n thumbProps,\n minThumbProps,\n minThumbLabel,\n minThumbLabelledBy,\n maxThumbProps,\n maxThumbLabel,\n maxThumbLabelledBy,\n tooltipProps,\n containerRef,\n getMarkProps = noop,\n getMarkLabelProps = noop,\n tooltipVisibility = \"auto\",\n getTooltipProps = noop,\n getTooltipChildren = identity,\n disableSmoothDragging = !!marks,\n ...remaining\n } = props as SliderProps & RangeSliderProps;\n\n const jump = getJumpValue({ min, max, step, jump: propJump });\n const isRangeSlider = typeof value !== \"number\";\n\n const thumb1Id = useEnsuredId(propId, \"slider\");\n const thumb2Id = `${thumb1Id}-2`;\n const thumb1Ref = useRef<HTMLSpanElement>(null);\n const thumb2Ref = useRef<HTMLSpanElement>(null);\n const { thumb1Name, thumb2Name } = getSliderInputName(name, isRangeSlider);\n\n let thumb1Max = max;\n let thumb2Min = min;\n let thumb1Label: string | undefined;\n let thumb1LabelledBy: string | undefined;\n let thumb2Label: string | undefined;\n let thumb2LabelledBy: string | undefined;\n let thumb1Value: number;\n let thumb2Value: number;\n let setThumb1Value: UseStateSetter<number>;\n let setThumb2Value: UseStateSetter<number>;\n if (!isRangeSlider) {\n thumb1Value = value;\n setThumb1Value = setValue;\n thumb2Value = max;\n setThumb2Value = noop;\n thumb1Label = ariaLabel;\n thumb1LabelledBy = ariaLabelledBy;\n } else {\n thumb1LabelledBy = minThumbLabelledBy;\n thumb1Label = minThumbLabel || (minThumbLabelledBy ? undefined : \"Min\");\n thumb2LabelledBy = maxThumbLabelledBy;\n thumb2Label = maxThumbLabel || (maxThumbLabelledBy ? undefined : \"Max\");\n\n [thumb1Value, thumb2Value] = rangeValue;\n\n thumb1Max = thumb2Value - step;\n thumb2Min = thumb1Value + step;\n\n setThumb1Value = (valueOrSetter) => {\n setRangeValue((prevRangeValue) => {\n const value =\n typeof valueOrSetter === \"number\"\n ? valueOrSetter\n : valueOrSetter(prevRangeValue[0]);\n\n return [value, prevRangeValue[1]];\n });\n };\n setThumb2Value = (valueOrSetter) => {\n setRangeValue((prevRangeValue) => {\n const value =\n typeof valueOrSetter === \"number\"\n ? valueOrSetter\n : valueOrSetter(prevRangeValue[1]);\n\n return [prevRangeValue[0], value];\n });\n };\n }\n\n const {\n onKeyDown: thumb1OnKeyDown,\n onMouseUp: thumb1OnMouseUp,\n onMouseDown: thumb1OnMouseDown,\n onMouseMove: thumb1OnMouseMove,\n onTouchStart: thumb1OnTouchStart,\n onTouchMove: thumb1OnTouchMove,\n dragPercentage: thumb1DragPercentage,\n draggableRef: thumb1DraggableRef,\n dragging: thumb1Dragging,\n } = useSliderDraggable({\n jump,\n ref: thumb1Ref,\n min,\n max: thumb1Max,\n rangeMax: max,\n step,\n value: thumb1Value,\n setValue: setThumb1Value,\n disabled,\n vertical,\n });\n\n const {\n onKeyDown: thumb2OnKeyDown,\n onMouseUp: thumb2OnMouseUp,\n onMouseDown: thumb2OnMouseDown,\n onMouseMove: thumb2OnMouseMove,\n onTouchStart: thumb2OnTouchStart,\n onTouchMove: thumb2OnTouchMove,\n dragPercentage: thumb2DragPercentage,\n draggableRef: thumb2DraggableRef,\n dragging: thumb2Dragging,\n } = useSliderDraggable({\n jump,\n ref: thumb2Ref,\n min: thumb2Min,\n max,\n rangeMin: min,\n step,\n value: thumb2Value,\n setValue: setThumb2Value,\n vertical,\n disabled,\n });\n\n const dragging = thumb1Dragging || thumb2Dragging;\n const sharedThumbProps = {\n step,\n animate: !dragging,\n discrete,\n disabled,\n vertical,\n getValueText,\n tooltipProps,\n getTooltipProps,\n getTooltipChildren,\n tooltipVisibility,\n disableSmoothDragging,\n } as const satisfies Partial<SliderThumbProps>;\n\n return (\n <SliderContainer {...remaining} ref={containerRef} vertical={vertical}>\n <SliderTrack\n {...trackProps}\n min={min}\n max={max}\n thumb1Ref={thumb1Ref}\n thumb1Value={thumb1Value}\n thumb1Dragging={!disableSmoothDragging && thumb1Dragging}\n thumb1DragPercentage={thumb1DragPercentage}\n thumb1OnMouseUp={thumb1OnMouseUp}\n thumb1OnMouseDown={thumb1OnMouseDown}\n thumb1OnMouseMove={thumb1OnMouseMove}\n thumb1OnTouchStart={thumb1OnTouchStart}\n thumb1OnTouchMove={thumb1OnTouchMove}\n thumb2Ref={thumb2Ref}\n thumb2Value={thumb2Value}\n thumb2Dragging={!disableSmoothDragging && thumb2Dragging}\n thumb2DragPercentage={thumb2DragPercentage}\n thumb2OnMouseUp={thumb2OnMouseUp}\n thumb2OnMouseDown={thumb2OnMouseDown}\n thumb2OnMouseMove={thumb2OnMouseMove}\n thumb2OnTouchStart={thumb2OnTouchStart}\n thumb2OnTouchMove={thumb2OnTouchMove}\n animate={!disableSmoothDragging && !dragging}\n disabled={disabled}\n vertical={vertical}\n isRangeSlider={isRangeSlider}\n >\n <SliderThumb\n aria-label={thumb1Label as string}\n aria-labelledby={thumb1LabelledBy}\n id={thumb1Id}\n name={thumb1Name}\n {...thumbProps}\n {...minThumbProps}\n {...sharedThumbProps}\n ref={thumb1DraggableRef}\n min={min}\n max={thumb1Max}\n value={thumb1Value}\n index={1}\n active={thumb1Dragging}\n onChange={(event) => {\n setThumb1Value(event.currentTarget.valueAsNumber);\n }}\n onKeyDown={thumb1OnKeyDown}\n />\n {isRangeSlider && (\n <SliderThumb\n aria-label={thumb2Label as string}\n aria-labelledby={thumb2LabelledBy}\n id={thumb2Id}\n name={thumb2Name}\n {...maxThumbProps}\n {...sharedThumbProps}\n ref={thumb2DraggableRef}\n min={thumb2Min}\n max={max}\n value={thumb2Value}\n index={2}\n active={thumb2Dragging}\n onChange={(event) => {\n setThumb2Value(event.currentTarget.valueAsNumber);\n }}\n onKeyDown={thumb2OnKeyDown}\n />\n )}\n {marks && (\n <SliderValueMarks\n min={min}\n max={max}\n step={step}\n marks={marks}\n vertical={vertical}\n thumb1Value={thumb1Value}\n thumb2Value={thumb2Value}\n isRangeSlider={isRangeSlider}\n getMarkProps={getMarkProps}\n getMarkLabelProps={getMarkLabelProps}\n />\n )}\n {children}\n </SliderTrack>\n </SliderContainer>\n );\n}\n"],"names":["useRef","useEnsuredId","identity","SliderContainer","SliderThumb","SliderTrack","SliderValueMarks","getJumpValue","getSliderInputName","useSliderDraggable","emptyString","noop","Slider","props","ariaLabel","ariaLabelledBy","id","propId","name","min","max","step","jump","propJump","vertical","discrete","disabled","getValueText","children","marks","value","setValue","rangeValue","setRangeValue","trackProps","thumbProps","minThumbProps","minThumbLabel","minThumbLabelledBy","maxThumbProps","maxThumbLabel","maxThumbLabelledBy","tooltipProps","containerRef","getMarkProps","getMarkLabelProps","tooltipVisibility","getTooltipProps","getTooltipChildren","disableSmoothDragging","remaining","isRangeSlider","thumb1Id","thumb2Id","thumb1Ref","thumb2Ref","thumb1Name","thumb2Name","thumb1Max","thumb2Min","thumb1Label","thumb1LabelledBy","thumb2Label","thumb2LabelledBy","thumb1Value","thumb2Value","setThumb1Value","setThumb2Value","undefined","valueOrSetter","prevRangeValue","onKeyDown","thumb1OnKeyDown","onMouseUp","thumb1OnMouseUp","onMouseDown","thumb1OnMouseDown","onMouseMove","thumb1OnMouseMove","onTouchStart","thumb1OnTouchStart","onTouchMove","thumb1OnTouchMove","dragPercentage","thumb1DragPercentage","draggableRef","thumb1DraggableRef","dragging","thumb1Dragging","ref","rangeMax","thumb2OnKeyDown","thumb2OnMouseUp","thumb2OnMouseDown","thumb2OnMouseMove","thumb2OnTouchStart","thumb2OnTouchMove","thumb2DragPercentage","thumb2DraggableRef","thumb2Dragging","rangeMin","sharedThumbProps","animate","aria-label","aria-labelledby","index","active","onChange","event","currentTarget","valueAsNumber"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/form/Slider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n useRef,\n} from \"react\";\n\nimport { type TooltipProps } from \"../tooltip/Tooltip.js\";\nimport {\n type LabelRequiredForA11y,\n type PropsWithRef,\n type UseStateSetter,\n} from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { identity } from \"../utils/identity.js\";\nimport { type SliderAddonProps, SliderContainer } from \"./SliderContainer.js\";\nimport {\n type ConfigurableSliderThumbProps,\n SliderThumb,\n type SliderThumbPresentation,\n type SliderThumbProps,\n} from \"./SliderThumb.js\";\nimport { SliderTrack } from \"./SliderTrack.js\";\nimport {\n type SliderMarksOptions,\n SliderValueMarks,\n} from \"./SliderValueMarks.js\";\nimport { getJumpValue, getSliderInputName } from \"./sliderUtils.js\";\nimport { type RangeSliderState } from \"./useRangeSlider.js\";\nimport { type SliderState, type SliderValueOptions } from \"./useSlider.js\";\nimport { useSliderDraggable } from \"./useSliderDraggable.js\";\n\n// NOTE: The augmentation appears in this file since no type definitions are\n// ever imported from the `sliderStyles` file.\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-slider-color\"?: string;\n \"--rmd-slider-active-color\"?: string;\n \"--rmd-slider-inactive-color\"?: string;\n \"--rmd-slider-size\"?: string | number;\n \"--rmd-slider-active-size\"?: string | number;\n \"--rmd-slider-inactive-size\"?: string | number;\n \"--rmd-slider-vertical-size\"?: string | number;\n \"--rmd-slider-offset-1\"?: string;\n \"--rmd-slider-offset-2\"?: string;\n \"--rmd-slider-tooltip-scale\"?: string | number;\n \"--rmd-slider-tooltip-translate\"?: string | number;\n \"--rmd-slider-mark-offset\"?: string;\n \"--rmd-slider-mark-active-color\"?: string;\n \"--rmd-slider-mark-active-opacity\"?: string | number;\n \"--rmd-slider-mark-inactive-color\"?: string;\n \"--rmd-slider-mark-inactive-opacity\"?: string | number;\n }\n}\n\nconst emptyString = (): string => \"\";\nconst noop = (): undefined => {\n // do nothing\n};\n\n/**\n * @since 2.5.0\n */\nexport interface BaseSliderProps\n extends HTMLAttributes<HTMLDivElement>,\n SliderThumbPresentation,\n SliderValueOptions,\n SliderAddonProps,\n SliderMarksOptions {\n /**\n * This can be used to apply a ref to the container element since this\n * component does not use `forwardRef`.\n */\n containerRef?: Ref<HTMLDivElement>;\n\n /**\n * The amount to jump the slider's value when the `PageUp` or `PageDown`\n * key is pressed.\n *\n * The default value is 1/10th of the range.\n *\n * @defaultValue `(numberOfSteps / 10) * step`\n */\n jump?: number;\n\n /** @defaultValue `false` */\n disabled?: boolean;\n\n /** @defaultValue `false` */\n vertical?: boolean;\n\n /**\n * This can be used to apply custom styles or a `ref` to the track element if\n * needed.\n */\n trackProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n\n /**\n * This can be used to configure any additional tooltip props like the\n * CSS transition `classNames`, styles, etc.\n *\n * This will only be used when {@link discrete} is `true`.\n *\n * Note: The `position` will always be `\"above\"` for horizontal sliders and\n * `\"left\"` for vertical sliders.\n */\n tooltipProps?: Omit<Partial<TooltipProps>, \"position\">;\n}\n\n/**\n * @since 2.5.0\n * @since 6.0.0 Only requires `value` and `setValue` props instead of all the\n * slider controls.\n * @since 6.0.0 The `thumbLabel` and `thumbLabelledBy` props were removed. Use\n * the `aria-label` or `aria-labelledby` props instead.\n * @since 6.0.0 The `baseId` prop was removed in favor of `id` or `*Props.id`\n */\nexport interface SliderProps extends BaseSliderProps, SliderState {\n /**\n * Convenience pass-through prop to {@link ConfigurableSliderThumbProps.name} which\n * will be applied to the hidden `<input type=\"range\" />`\n */\n name?: string;\n\n /**\n * Any additional props that should be provided to the thumb element. This can\n * be useful for applying additional styling.\n */\n thumbProps?: ConfigurableSliderThumbProps;\n\n /**\n * This can be used to update the discrete slider's tooltip props.\n *\n * @example Custom Styles\n * ```tsx\n * <Slider\n * {...slider}\n * discrete\n * getTooltipProps={(value) => ({\n * className: cssUtils({\n * backgroundColor: value < 30 ? \"warning\" : undefined,\n * }),\n * })}\n * />\n * ```\n */\n getTooltipProps?: (value: number) => Partial<TooltipProps> | undefined;\n\n /**\n * This can be used to update the discrete slider's value tooltip.\n *\n * @example More Value Information\n * ```tsx\n * <Slider\n * {...slider}\n * discrete\n * getTooltipChildren={(value) => (\n * <TextIconSpacing icon={<FavoriteIcon />}>\n * {value}\n * </TextIconSpacing>\n * )}\n * />\n * ```\n *\n * This will only be used when {@link discrete} is `true`.\n *\n * @defaultValue `(value) => value`\n */\n getTooltipChildren?: (value: number) => ReactNode;\n}\n\n/**\n * @since 2.5.0\n * @since 6.0.0 Only requires `rangeValue` and `setRangeValue` props instead of\n * all the slider controls.\n * @since 6.0.0 The `thumb1Label`, `thumb1LabelledBy`, `thumb1Props`,\n * `thumb2Label`, `thumb2LabelledBy` and `thumb2Props` were renamed to\n * `minThumbLabel`, `minThumbLabelledBy`, `minThumbProps`, `maxThumbLabel`,\n * `maxThumbLabelledBy`, and `maxThumbProps` respectively.\n */\nexport interface RangeSliderProps extends BaseSliderProps, RangeSliderState {\n /**\n * Convenience pass-through prop for {@link\n * ConfigurableSliderThumbProps.name} for both the {@link minThumbProps} and\n * {@link maxThumbProps}.\n */\n name?: string;\n\n /**\n * Any additional props that should be provided to the min value thumb\n * element. This can be useful for applying additional styling.\n */\n minThumbProps?: ConfigurableSliderThumbProps;\n\n /**\n * Any additional props that should be provided to the max value thumb\n * element. This can be useful for applying additional styling.\n */\n maxThumbProps?: ConfigurableSliderThumbProps;\n\n /**\n * The `aria-label` to apply to the min value.\n *\n * Note: Either this prop or the {@link minThumbLabelledBy} are required for\n * accessibility.\n *\n * @defaultValue `\"Min\"`\n */\n minThumbLabel?: string;\n\n /**\n * Set this to an element's id that labels the min value.\n *\n * Note: Either this prop or the {@link minThumbLabel} are required for\n * accessibility.\n */\n minThumbLabelledBy?: string;\n\n /**\n * The `aria-label` to apply to the max value.\n *\n * Note: Either this prop or the {@link maxThumbLabelledBy} are required for\n * accessibility.\n *\n * @defaultValue `\"Max\"`\n */\n maxThumbLabel?: string;\n\n /**\n * Set this to an element's id that labels the max value.\n *\n * Note: Either this prop or the {@link maxThumbLabel} are required for\n * accessibility.\n */\n maxThumbLabelledBy?: string;\n\n /**\n * This can be used to update the discrete slider's tooltip props.\n *\n * @example Custom Styles\n * ```tsx\n * <Slider\n * {...slider}\n * discrete\n * getTooltipProps={(value, isFirstThumb) => ({\n * className: cssUtils({\n * backgroundColor: value < 30 && isFirstThumb ? \"warning\" : undefined,\n * }),\n * })}\n * />\n * ```\n */\n getTooltipProps?: (\n value: number,\n isFirstThumb: boolean\n ) => Partial<TooltipProps>;\n\n /**\n * This can be used to update the discrete slider's value tooltip.\n *\n * @example More Value Information\n * ```tsx\n * <Slider\n * {...rangeSlider}\n * discrete\n * getTooltipChildren={(value, isFirstThumb) => (\n * <TextIconSpacing\n * icon={isFirstThumb ? <FavoriteIcon /> : <CloseIcon /}\n * iconAfter={!isFirstValue}\n * >\n * {value}\n * </TextIconSpacing>\n * )}\n * />\n * ```\n *\n * This will only be used when {@link discrete} is `true`.\n *\n * @defaultValue `(value) => value`\n */\n getTooltipChildren?: (value: number, isFirstThumb: boolean) => ReactNode;\n}\n\n/**\n * **Client Component**\n *\n * @example Simple Example\n * ```tsx\n * import { Form } from \"@react-md/core/form/Form\";\n * import { Slider } from \"@react-md/core/form/Slider\";\n * import { useSlider } from \"@react-md/core/form/useSlider\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const slider = useSlider({\n * // these are the defaults and can be changed\n * min: 0,\n * max: 100,\n * step: 1,\n * defaultValue: 50,\n * });\n *\n * // if you need access to the current value or manually change the value\n * // yourself.\n * const { value, setValue } = slider;\n *\n * return (\n * <Form>\n * <Slider {...slider} aria-label=\"Volume\" />\n * </Form>\n * );\n * }\n * ```\n *\n * @example Range Slider Example\n * ```tsx\n * import { Fieldset } from \"@react-md/core/form/Fieldset\";\n * import { Form } from \"@react-md/core/form/Form\";\n * import { Legend } from \"@react-md/core/form/Legend\";\n * import { Slider } from \"@react-md/core/form/Slider\";\n * import { useRangeSlider } from \"@react-md/core/form/useRangeSlider\";\n * import type { ReactElement } from \"react\";\n * import { useId } from \"react\";\n *\n * function Example(): ReactElement {\n * const slider = useRangeSlider({\n * // these are the defaults and can be changed\n * min: 0,\n * max: 100,\n * step: 1,\n * defaultValue: [0, 100],\n * });\n *\n * // if you need access to the current value or manually change the value\n * // yourself.\n * const { rangeValue, setRangeValue } = slider;\n * const [minPrice, maxPrice] = rangeValue;\n *\n * return (\n * <Form>\n * <Fieldset>\n * <Legend>Price Range</Legend>\n * <Slider {...slider} />\n * </Fieldset>\n * </Form>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/slider | Slider Demos}\n * @since 2.5.0\n * @since 6.0.0 The `Slider` and `RangeSlider` have been combined into the\n * single `Slider` component and removed the `label` support.\n * @since 6.0.0 Each thumb includes an invisible `<input type=\"range\">` instead\n * of an `<input type=\"hidden\">`.\n */\nexport function Slider(props: LabelRequiredForA11y<SliderProps>): ReactElement;\nexport function Slider(props: RangeSliderProps): ReactElement;\nexport function Slider(\n props: LabelRequiredForA11y<SliderProps> | RangeSliderProps\n): ReactElement {\n const {\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n id: propId,\n name,\n min = 0,\n max = 100,\n step = 1,\n jump: propJump,\n vertical = false,\n discrete = false,\n disabled = false,\n getValueText = emptyString,\n children,\n marks = false,\n value,\n setValue,\n rangeValue,\n setRangeValue,\n trackProps,\n thumbProps,\n minThumbProps,\n minThumbLabel,\n minThumbLabelledBy,\n maxThumbProps,\n maxThumbLabel,\n maxThumbLabelledBy,\n tooltipProps,\n containerRef,\n getMarkProps = noop,\n getMarkLabelProps = noop,\n tooltipVisibility = \"auto\",\n getTooltipProps = noop,\n getTooltipChildren = identity,\n disableSmoothDragging = !!marks,\n ...remaining\n } = props as SliderProps & RangeSliderProps;\n\n const jump = getJumpValue({ min, max, step, jump: propJump });\n const isRangeSlider = typeof value !== \"number\";\n\n const thumb1Id = useEnsuredId(propId, \"slider\");\n const thumb2Id = `${thumb1Id}-2`;\n const thumb1Ref = useRef<HTMLSpanElement>(null);\n const thumb2Ref = useRef<HTMLSpanElement>(null);\n const { thumb1Name, thumb2Name } = getSliderInputName(name, isRangeSlider);\n\n let thumb1Max = max;\n let thumb2Min = min;\n let thumb1Label: string | undefined;\n let thumb1LabelledBy: string | undefined;\n let thumb2Label: string | undefined;\n let thumb2LabelledBy: string | undefined;\n let thumb1Value: number;\n let thumb2Value: number;\n let setThumb1Value: UseStateSetter<number>;\n let setThumb2Value: UseStateSetter<number>;\n if (!isRangeSlider) {\n thumb1Value = value;\n setThumb1Value = setValue;\n thumb2Value = max;\n setThumb2Value = noop;\n thumb1Label = ariaLabel;\n thumb1LabelledBy = ariaLabelledBy;\n } else {\n thumb1LabelledBy = minThumbLabelledBy;\n thumb1Label = minThumbLabel || (minThumbLabelledBy ? undefined : \"Min\");\n thumb2LabelledBy = maxThumbLabelledBy;\n thumb2Label = maxThumbLabel || (maxThumbLabelledBy ? undefined : \"Max\");\n\n [thumb1Value, thumb2Value] = rangeValue;\n\n thumb1Max = thumb2Value - step;\n thumb2Min = thumb1Value + step;\n\n setThumb1Value = (valueOrSetter) => {\n setRangeValue((prevRangeValue) => {\n const value =\n typeof valueOrSetter === \"number\"\n ? valueOrSetter\n : valueOrSetter(prevRangeValue[0]);\n\n return [value, prevRangeValue[1]];\n });\n };\n setThumb2Value = (valueOrSetter) => {\n setRangeValue((prevRangeValue) => {\n const value =\n typeof valueOrSetter === \"number\"\n ? valueOrSetter\n : valueOrSetter(prevRangeValue[1]);\n\n return [prevRangeValue[0], value];\n });\n };\n }\n\n const {\n onKeyDown: thumb1OnKeyDown,\n onMouseUp: thumb1OnMouseUp,\n onMouseDown: thumb1OnMouseDown,\n onMouseMove: thumb1OnMouseMove,\n onTouchStart: thumb1OnTouchStart,\n onTouchMove: thumb1OnTouchMove,\n dragPercentage: thumb1DragPercentage,\n draggableRef: thumb1DraggableRef,\n dragging: thumb1Dragging,\n } = useSliderDraggable({\n jump,\n ref: thumb1Ref,\n min,\n max: thumb1Max,\n rangeMax: max,\n step,\n value: thumb1Value,\n setValue: setThumb1Value,\n disabled,\n vertical,\n });\n\n const {\n onKeyDown: thumb2OnKeyDown,\n onMouseUp: thumb2OnMouseUp,\n onMouseDown: thumb2OnMouseDown,\n onMouseMove: thumb2OnMouseMove,\n onTouchStart: thumb2OnTouchStart,\n onTouchMove: thumb2OnTouchMove,\n dragPercentage: thumb2DragPercentage,\n draggableRef: thumb2DraggableRef,\n dragging: thumb2Dragging,\n } = useSliderDraggable({\n jump,\n ref: thumb2Ref,\n min: thumb2Min,\n max,\n rangeMin: min,\n step,\n value: thumb2Value,\n setValue: setThumb2Value,\n vertical,\n disabled,\n });\n\n const dragging = thumb1Dragging || thumb2Dragging;\n const sharedThumbProps = {\n step,\n animate: !dragging,\n discrete,\n disabled,\n vertical,\n getValueText,\n tooltipProps,\n getTooltipProps,\n getTooltipChildren,\n tooltipVisibility,\n disableSmoothDragging,\n } as const satisfies Partial<SliderThumbProps>;\n\n return (\n <SliderContainer {...remaining} ref={containerRef} vertical={vertical}>\n <SliderTrack\n {...trackProps}\n min={min}\n max={max}\n thumb1Ref={thumb1Ref}\n thumb1Value={thumb1Value}\n thumb1Dragging={!disableSmoothDragging && thumb1Dragging}\n thumb1DragPercentage={thumb1DragPercentage}\n thumb1OnMouseUp={thumb1OnMouseUp}\n thumb1OnMouseDown={thumb1OnMouseDown}\n thumb1OnMouseMove={thumb1OnMouseMove}\n thumb1OnTouchStart={thumb1OnTouchStart}\n thumb1OnTouchMove={thumb1OnTouchMove}\n thumb2Ref={thumb2Ref}\n thumb2Value={thumb2Value}\n thumb2Dragging={!disableSmoothDragging && thumb2Dragging}\n thumb2DragPercentage={thumb2DragPercentage}\n thumb2OnMouseUp={thumb2OnMouseUp}\n thumb2OnMouseDown={thumb2OnMouseDown}\n thumb2OnMouseMove={thumb2OnMouseMove}\n thumb2OnTouchStart={thumb2OnTouchStart}\n thumb2OnTouchMove={thumb2OnTouchMove}\n animate={!disableSmoothDragging && !dragging}\n disabled={disabled}\n vertical={vertical}\n isRangeSlider={isRangeSlider}\n >\n <SliderThumb\n aria-label={thumb1Label as string}\n aria-labelledby={thumb1LabelledBy}\n id={thumb1Id}\n name={thumb1Name}\n {...thumbProps}\n {...minThumbProps}\n {...sharedThumbProps}\n ref={thumb1DraggableRef}\n min={min}\n max={thumb1Max}\n value={thumb1Value}\n index={1}\n active={thumb1Dragging}\n onChange={(event) => {\n setThumb1Value(event.currentTarget.valueAsNumber);\n }}\n onKeyDown={thumb1OnKeyDown}\n />\n {isRangeSlider && (\n <SliderThumb\n aria-label={thumb2Label as string}\n aria-labelledby={thumb2LabelledBy}\n id={thumb2Id}\n name={thumb2Name}\n {...maxThumbProps}\n {...sharedThumbProps}\n ref={thumb2DraggableRef}\n min={thumb2Min}\n max={max}\n value={thumb2Value}\n index={2}\n active={thumb2Dragging}\n onChange={(event) => {\n setThumb2Value(event.currentTarget.valueAsNumber);\n }}\n onKeyDown={thumb2OnKeyDown}\n />\n )}\n {marks && (\n <SliderValueMarks\n min={min}\n max={max}\n step={step}\n marks={marks}\n vertical={vertical}\n thumb1Value={thumb1Value}\n thumb2Value={thumb2Value}\n isRangeSlider={isRangeSlider}\n getMarkProps={getMarkProps}\n getMarkLabelProps={getMarkLabelProps}\n />\n )}\n {children}\n </SliderTrack>\n </SliderContainer>\n );\n}\n"],"names":["useRef","useEnsuredId","identity","SliderContainer","SliderThumb","SliderTrack","SliderValueMarks","getJumpValue","getSliderInputName","useSliderDraggable","emptyString","noop","Slider","props","ariaLabel","ariaLabelledBy","id","propId","name","min","max","step","jump","propJump","vertical","discrete","disabled","getValueText","children","marks","value","setValue","rangeValue","setRangeValue","trackProps","thumbProps","minThumbProps","minThumbLabel","minThumbLabelledBy","maxThumbProps","maxThumbLabel","maxThumbLabelledBy","tooltipProps","containerRef","getMarkProps","getMarkLabelProps","tooltipVisibility","getTooltipProps","getTooltipChildren","disableSmoothDragging","remaining","isRangeSlider","thumb1Id","thumb2Id","thumb1Ref","thumb2Ref","thumb1Name","thumb2Name","thumb1Max","thumb2Min","thumb1Label","thumb1LabelledBy","thumb2Label","thumb2LabelledBy","thumb1Value","thumb2Value","setThumb1Value","setThumb2Value","undefined","valueOrSetter","prevRangeValue","onKeyDown","thumb1OnKeyDown","onMouseUp","thumb1OnMouseUp","onMouseDown","thumb1OnMouseDown","onMouseMove","thumb1OnMouseMove","onTouchStart","thumb1OnTouchStart","onTouchMove","thumb1OnTouchMove","dragPercentage","thumb1DragPercentage","draggableRef","thumb1DraggableRef","dragging","thumb1Dragging","ref","rangeMax","thumb2OnKeyDown","thumb2OnMouseUp","thumb2OnMouseDown","thumb2OnMouseMove","thumb2OnTouchStart","thumb2OnTouchMove","thumb2DragPercentage","thumb2DraggableRef","thumb2Dragging","rangeMin","sharedThumbProps","animate","aria-label","aria-labelledby","index","active","onChange","event","currentTarget","valueAsNumber"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/Switch.tsx"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type ReactNode,\n forwardRef,\n} from \"react\";\n\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { type InputToggleLabelProps } from \"./InputToggle.js\";\nimport { Label } from \"./Label.js\";\nimport { SwitchTrack } from \"./SwitchTrack.js\";\nimport { switchStyles } from \"./switchStyles.js\";\nimport {\n type FormComponentStates,\n type FormMessageContainerExtension,\n} from \"./types.js\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-switch-track-background-color\"?: string;\n \"--rmd-switch-ball-background-color\"?: string;\n }\n}\n\n/**\n * @since 6.0.0 Added `containerProps` and support for the\n * `FormMessage` behavior.\n */\nexport interface SwitchProps\n extends InputHTMLAttributes<HTMLInputElement>,\n InputToggleLabelProps,\n FormMessageContainerExtension,\n FormComponentStates {\n containerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n trackProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n trackStyle?: CSSProperties;\n trackClassName?: string;\n ballAddon?: ReactNode;\n ballProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n ballStyle?: CSSProperties;\n ballClassName?: string;\n}\n\n/**\n * @example Simple Example\n * ```tsx\n * import { Form } from \"@react-md/core/form/Form\";\n * import { Switch } from \"@react-md/core/form/Switch\";\n * import type { ReactElement } from \"react\";\n * import { useState } from \"react\";\n *\n * function Example(): ReactElement {\n * const [checked, setChecked] = useState(false);\n *\n * return (\n * <Form>\n * <Switch\n * label=\"Label\"\n * name=\"enabled\"\n * checked={checked}\n * onChange={(event) => setChecked(event.currentTarget.checked)}\n * />\n * </Form>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/switch | Switch Demos}\n * @since 6.0.0 Added support for `FormMessage` behavior.\n */\nexport const Switch = forwardRef<HTMLInputElement, SwitchProps>(\n function Switch(props, ref) {\n const {\n id: propId,\n label,\n labelProps,\n style,\n className,\n containerProps,\n ballProps,\n ballStyle,\n ballClassName,\n ballAddon,\n trackProps,\n trackStyle,\n trackClassName,\n messageProps,\n messageContainerProps,\n disableLabelGap = false,\n error = false,\n active = false,\n stacked = false,\n iconAfter = false,\n disabled = false,\n readOnly = false,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"switch\");\n\n return (\n <FormMessageContainer\n {...messageContainerProps}\n messageProps={messageProps}\n >\n <Label\n style={style}\n {...labelProps}\n className={cnb(className, labelProps?.className)}\n gap={!disableLabelGap}\n stacked={stacked}\n reversed={!iconAfter}\n active={active}\n error={error}\n disabled={disabled}\n >\n {label}\n <div\n {...containerProps}\n className={switchStyles({\n clickable: !disabled && !readOnly,\n className: containerProps?.className,\n currentColor: active || error,\n })}\n >\n <SwitchTrack\n style={trackStyle}\n {...trackProps}\n className={cnb(trackClassName, trackProps?.className)}\n disabled={disabled}\n ballAddon={ballAddon}\n ballProps={ballProps}\n ballStyle={ballStyle}\n ballClassName={ballClassName}\n >\n <input\n {...remaining}\n id={id}\n ref={ref}\n role=\"switch\"\n type=\"checkbox\"\n className={cnb(\n \"rmd-switch__input rmd-hidden-input\",\n disabled && \"rmd-hidden-input--disabled\"\n )}\n disabled={disabled}\n />\n </SwitchTrack>\n </div>\n </Label>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["cnb","forwardRef","useEnsuredId","FormMessageContainer","Label","SwitchTrack","switchStyles","Switch","props","ref","id","propId","label","labelProps","style","className","containerProps","ballProps","ballStyle","ballClassName","ballAddon","trackProps","trackStyle","trackClassName","messageProps","messageContainerProps","disableLabelGap","error","active","stacked","iconAfter","disabled","readOnly","remaining","gap","reversed","div","clickable","currentColor","input","role","type"],"mappings":";AAAA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAKEC,UAAU,QACL,QAAQ;AAGf,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,oBAAoB,QAAQ,4BAA4B;AAEjE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,WAAW,QAAQ,mBAAmB;AAC/C,SAASC,YAAY,QAAQ,oBAAoB;AAgCjD;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GACD,OAAO,MAAMC,uBAASN,WACpB,SAASM,OAAOC,KAAK,EAAEC,GAAG;IACxB,MAAM,EACJC,IAAIC,MAAM,EACVC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,SAAS,EACTC,cAAc,EACdC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,SAAS,EACTC,UAAU,EACVC,UAAU,EACVC,cAAc,EACdC,YAAY,EACZC,qBAAqB,EACrBC,kBAAkB,KAAK,EACvBC,QAAQ,KAAK,EACbC,SAAS,KAAK,EACdC,UAAU,KAAK,EACfC,YAAY,KAAK,EACjBC,WAAW,KAAK,EAChBC,WAAW,KAAK,EAChB,GAAGC,WACJ,GAAGzB;IACJ,MAAME,KAAKR,aAAaS,QAAQ;IAEhC,qBACE,KAACR;QACE,GAAGsB,qBAAqB;QACzBD,cAAcA;kBAEd,cAAA,MAACpB;YACCU,OAAOA;YACN,GAAGD,UAAU;YACdE,WAAWf,IAAIe,WAAWF,YAAYE;YACtCmB,KAAK,CAACR;YACNG,SAASA;YACTM,UAAU,CAACL;YACXF,QAAQA;YACRD,OAAOA;YACPI,UAAUA;;gBAETnB;8BACD,KAACwB;oBACE,GAAGpB,cAAc;oBAClBD,WAAWT,aAAa;wBACtB+B,WAAW,CAACN,YAAY,CAACC;wBACzBjB,WAAWC,gBAAgBD;wBAC3BuB,cAAcV,UAAUD;oBAC1B;8BAEA,cAAA,KAACtB;wBACCS,OAAOQ;wBACN,GAAGD,UAAU;wBACdN,WAAWf,IAAIuB,gBAAgBF,YAAYN;wBAC3CgB,UAAUA;wBACVX,WAAWA;wBACXH,WAAWA;wBACXC,WAAWA;wBACXC,eAAeA;kCAEf,cAAA,KAACoB;4BACE,GAAGN,SAAS;4BACbvB,IAAIA;4BACJD,KAAKA;4BACL+B,MAAK;4BACLC,MAAK;4BACL1B,WAAWf,IACT,sCACA+B,YAAY;4BAEdA,UAAUA;;;;;;;AAOxB,GACA"}
1
+ {"version":3,"sources":["../../src/form/Switch.tsx"],"sourcesContent":["import { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type ReactNode,\n forwardRef,\n} from \"react\";\n\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { type InputToggleLabelProps } from \"./InputToggle.js\";\nimport { Label } from \"./Label.js\";\nimport { SwitchTrack } from \"./SwitchTrack.js\";\nimport { switchStyles } from \"./switchStyles.js\";\nimport {\n type FormComponentStates,\n type FormMessageContainerExtension,\n} from \"./types.js\";\n\n// NOTE: The augmentation appears in this file since no type definitions are\n// ever imported from the `switchStyles` file.\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-switch-track-background-color\"?: string;\n \"--rmd-switch-ball-background-color\"?: string;\n }\n}\n\n/**\n * @since 6.0.0 Added `containerProps` and support for the\n * `FormMessage` behavior.\n */\nexport interface SwitchProps\n extends InputHTMLAttributes<HTMLInputElement>,\n InputToggleLabelProps,\n FormMessageContainerExtension,\n FormComponentStates {\n containerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n trackProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n trackStyle?: CSSProperties;\n trackClassName?: string;\n ballAddon?: ReactNode;\n ballProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n ballStyle?: CSSProperties;\n ballClassName?: string;\n}\n\n/**\n * @example Simple Example\n * ```tsx\n * import { Form } from \"@react-md/core/form/Form\";\n * import { Switch } from \"@react-md/core/form/Switch\";\n * import type { ReactElement } from \"react\";\n * import { useState } from \"react\";\n *\n * function Example(): ReactElement {\n * const [checked, setChecked] = useState(false);\n *\n * return (\n * <Form>\n * <Switch\n * label=\"Label\"\n * name=\"enabled\"\n * checked={checked}\n * onChange={(event) => setChecked(event.currentTarget.checked)}\n * />\n * </Form>\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/switch | Switch Demos}\n * @since 6.0.0 Added support for `FormMessage` behavior.\n */\nexport const Switch = forwardRef<HTMLInputElement, SwitchProps>(\n function Switch(props, ref) {\n const {\n id: propId,\n label,\n labelProps,\n style,\n className,\n containerProps,\n ballProps,\n ballStyle,\n ballClassName,\n ballAddon,\n trackProps,\n trackStyle,\n trackClassName,\n messageProps,\n messageContainerProps,\n disableLabelGap = false,\n error = false,\n active = false,\n stacked = false,\n iconAfter = false,\n disabled = false,\n readOnly = false,\n ...remaining\n } = props;\n const id = useEnsuredId(propId, \"switch\");\n\n return (\n <FormMessageContainer\n {...messageContainerProps}\n messageProps={messageProps}\n >\n <Label\n style={style}\n {...labelProps}\n className={cnb(className, labelProps?.className)}\n gap={!disableLabelGap}\n stacked={stacked}\n reversed={!iconAfter}\n active={active}\n error={error}\n disabled={disabled}\n >\n {label}\n <div\n {...containerProps}\n className={switchStyles({\n clickable: !disabled && !readOnly,\n className: containerProps?.className,\n currentColor: active || error,\n })}\n >\n <SwitchTrack\n style={trackStyle}\n {...trackProps}\n className={cnb(trackClassName, trackProps?.className)}\n disabled={disabled}\n ballAddon={ballAddon}\n ballProps={ballProps}\n ballStyle={ballStyle}\n ballClassName={ballClassName}\n >\n <input\n {...remaining}\n id={id}\n ref={ref}\n role=\"switch\"\n type=\"checkbox\"\n className={cnb(\n \"rmd-switch__input rmd-hidden-input\",\n disabled && \"rmd-hidden-input--disabled\"\n )}\n disabled={disabled}\n />\n </SwitchTrack>\n </div>\n </Label>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["cnb","forwardRef","useEnsuredId","FormMessageContainer","Label","SwitchTrack","switchStyles","Switch","props","ref","id","propId","label","labelProps","style","className","containerProps","ballProps","ballStyle","ballClassName","ballAddon","trackProps","trackStyle","trackClassName","messageProps","messageContainerProps","disableLabelGap","error","active","stacked","iconAfter","disabled","readOnly","remaining","gap","reversed","div","clickable","currentColor","input","role","type"],"mappings":";AAAA,SAASA,GAAG,QAAQ,YAAY;AAChC,SAKEC,UAAU,QACL,QAAQ;AAGf,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,oBAAoB,QAAQ,4BAA4B;AAEjE,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,WAAW,QAAQ,mBAAmB;AAC/C,SAASC,YAAY,QAAQ,oBAAoB;AAkCjD;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GACD,OAAO,MAAMC,uBAASN,WACpB,SAASM,OAAOC,KAAK,EAAEC,GAAG;IACxB,MAAM,EACJC,IAAIC,MAAM,EACVC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,SAAS,EACTC,cAAc,EACdC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,SAAS,EACTC,UAAU,EACVC,UAAU,EACVC,cAAc,EACdC,YAAY,EACZC,qBAAqB,EACrBC,kBAAkB,KAAK,EACvBC,QAAQ,KAAK,EACbC,SAAS,KAAK,EACdC,UAAU,KAAK,EACfC,YAAY,KAAK,EACjBC,WAAW,KAAK,EAChBC,WAAW,KAAK,EAChB,GAAGC,WACJ,GAAGzB;IACJ,MAAME,KAAKR,aAAaS,QAAQ;IAEhC,qBACE,KAACR;QACE,GAAGsB,qBAAqB;QACzBD,cAAcA;kBAEd,cAAA,MAACpB;YACCU,OAAOA;YACN,GAAGD,UAAU;YACdE,WAAWf,IAAIe,WAAWF,YAAYE;YACtCmB,KAAK,CAACR;YACNG,SAASA;YACTM,UAAU,CAACL;YACXF,QAAQA;YACRD,OAAOA;YACPI,UAAUA;;gBAETnB;8BACD,KAACwB;oBACE,GAAGpB,cAAc;oBAClBD,WAAWT,aAAa;wBACtB+B,WAAW,CAACN,YAAY,CAACC;wBACzBjB,WAAWC,gBAAgBD;wBAC3BuB,cAAcV,UAAUD;oBAC1B;8BAEA,cAAA,KAACtB;wBACCS,OAAOQ;wBACN,GAAGD,UAAU;wBACdN,WAAWf,IAAIuB,gBAAgBF,YAAYN;wBAC3CgB,UAAUA;wBACVX,WAAWA;wBACXH,WAAWA;wBACXC,WAAWA;wBACXC,eAAeA;kCAEf,cAAA,KAACoB;4BACE,GAAGN,SAAS;4BACbvB,IAAIA;4BACJD,KAAKA;4BACL+B,MAAK;4BACLC,MAAK;4BACL1B,WAAWf,IACT,sCACA+B,YAAY;4BAEdA,UAAUA;;;;;;;AAOxB,GACA"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/TextArea.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type TextareaHTMLAttributes,\n forwardRef,\n} from \"react\";\n\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { Label } from \"./Label.js\";\nimport { ResizingTextAreaWrapper } from \"./ResizingTextAreaWrapper.js\";\nimport { TextFieldContainer } from \"./TextFieldContainer.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { textArea, textAreaContainer } from \"./textAreaStyles.js\";\nimport { type FormFieldOptions } from \"./types.js\";\nimport {\n type TextAreaResize,\n useResizingTextArea,\n} from \"./useResizingTextArea.js\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-text-area-height\"?: string | number;\n \"--rmd-text-area-padding\"?: string | number;\n }\n}\n\n/**\n * @since 6.0.0 Added `containerProps`.\n */\nexport interface TextAreaProps\n extends FormFieldOptions,\n TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** @defaultValue `\"text-area-\" + useId()` */\n id?: string;\n\n /**\n * Optional placeholder text to display in the text field.\n *\n * @defaultValue `label ? \" \" : \"\"`\n */\n placeholder?: string;\n\n /**\n * Set this to `true` if the auto resizing textarea should not animate for new\n * height changes.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * An optional style to apply to the textarea element. The base `style` prop\n * is applied to the surrounding `div` instead.\n */\n areaStyle?: CSSProperties;\n\n /**\n * An optional className to apply to the textarea element. The base `style`\n * prop is applied to the surrounding `div` instead.\n */\n areaClassName?: string;\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attr-rows\n * @defaultValue `2`\n */\n rows?: number;\n\n /**\n * The maximum number of rows a textarea can expand to before showing a\n * scrollbar. When this is set to `-1`, there will be no limit.\n *\n * @defaultValue `-1`\n */\n maxRows?: number;\n\n /**\n * @see {@link TextAreaResize}\n * @defaultValue `\"auto\"`\n */\n resize?: TextAreaResize;\n\n /**\n * When the {@link resize} prop is set to `\"auto\"`, an additional `<div>` is\n * added along with a hidden `<textarea>` mask. This prop can be used to add\n * any additional styling or props to that div.\n *\n * This will only be applied when {@link resize} is set to `\"auto\"`.\n */\n resizeContainerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n\n /**\n * Optional props to provide to the {@link TextFieldContainer} component.\n * There probably isn't any real use for this prop other than if you need to\n * add a `ref` for some DOM behavior.\n */\n containerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * **Client Component**\n *\n * @example Simple Example\n * ```tsx\n * import { TextArea } from \"@react-md/core/form/TextArea\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * return (\n * <TextArea\n * label=\"Label\"\n * placeholder=\"Placeholder\"\n * />\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/text-field#simple-textarea | TextArea Demos}\n */\nexport const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\n function TextArea(props, ref) {\n const {\n id: propId,\n style,\n className,\n label,\n labelProps,\n labelStyle,\n labelClassName,\n areaStyle,\n areaClassName,\n resizeContainerProps,\n resize = \"auto\",\n dense,\n error,\n active,\n inline: propInline,\n leftAddon,\n rightAddon,\n disableLeftAddonStyles,\n disableRightAddonStyles,\n theme: propTheme,\n underlineDirection: propUnderlineDirection,\n messageProps,\n messageContainerProps,\n containerProps,\n rows = 2,\n maxRows = -1,\n onChange: propOnChange,\n disableTransition: propDisableTransition,\n ...remaining\n } = props;\n const { disabled = false, readOnly = false, value, defaultValue } = props;\n const id = useEnsuredId(propId, \"text-area\");\n const theme = getFormConfig(\"theme\", propTheme);\n const underlineDirection = getFormConfig(\n \"underlineDirection\",\n propUnderlineDirection\n );\n const [areaRef, areaRefCallback] = useEnsuredRef(ref);\n\n const {\n maskRef,\n containerRef,\n height,\n onChange,\n scrollable,\n disableTransition,\n } = useResizingTextArea({\n maxRows,\n resize,\n onChange: propOnChange,\n containerRef: containerProps?.ref,\n disableTransition: propDisableTransition,\n });\n\n let { placeholder = \"\" } = props;\n if (label && !placeholder) {\n // See the placeholder type definition comments for information\n placeholder = \" \";\n }\n\n // have to force it inline or else you won't be able to resize\n // it horizontally.\n const inline = resize === \"horizontal\" || resize === \"both\" || propInline;\n\n const area = (\n <textarea\n {...remaining}\n id={id}\n ref={areaRefCallback}\n rows={rows}\n disabled={disabled}\n onChange={onChange}\n placeholder={placeholder}\n style={areaStyle}\n className={textArea({\n resize,\n scrollable,\n className: areaClassName,\n placeholderHidden: !!label && !active,\n })}\n />\n );\n\n const labelNode = label && (\n <Label\n {...labelProps}\n htmlFor={id}\n style={labelProps?.style ?? labelStyle}\n className={labelProps?.className ?? labelClassName}\n floating\n dense={dense}\n error={error}\n active={active}\n disabled={disabled}\n >\n {label}\n </Label>\n );\n\n let children = (\n <>\n {area}\n {labelNode}\n </>\n );\n\n if (resize === \"auto\") {\n children = (\n <ResizingTextAreaWrapper\n {...resizeContainerProps}\n maskId={`${id}-mask`}\n maskRef={maskRef}\n rows={rows}\n areaStyle={areaStyle}\n areaClassName={areaClassName}\n defaultValue={value ?? defaultValue}\n disableTransition={disableTransition}\n >\n {children}\n </ResizingTextAreaWrapper>\n );\n }\n\n return (\n <FormMessageContainer\n inline={inline}\n {...messageContainerProps}\n messageProps={messageProps}\n >\n <TextFieldContainer\n {...containerProps}\n ref={containerRef}\n style={{\n ...style,\n \"--rmd-text-area-height\": height,\n }}\n className={textAreaContainer({\n animate: !disableTransition && resize === \"auto\",\n disabled,\n height: !!height,\n underlineLabelled:\n !!label && (theme === \"underline\" || theme === \"filled\"),\n className,\n })}\n theme={theme}\n label={!!label}\n error={error}\n dense={dense}\n inline={inline}\n active={active}\n readOnly={readOnly}\n disabled={disabled}\n leftAddon={leftAddon}\n rightAddon={rightAddon}\n underlineDirection={underlineDirection}\n disableLeftAddonStyles={disableLeftAddonStyles}\n disableRightAddonStyles={disableRightAddonStyles}\n onClick={(event) => {\n // The textarea container adds padding-top when there is a label so\n // that the label does not cover the text so this makes it so you\n // can still click anywhere in the \"box\" to focus the textarea.\n if (!disabled && event.target === event.currentTarget) {\n areaRef.current?.focus();\n }\n }}\n >\n {children}\n </TextFieldContainer>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["forwardRef","useEnsuredId","useEnsuredRef","FormMessageContainer","Label","ResizingTextAreaWrapper","TextFieldContainer","getFormConfig","textArea","textAreaContainer","useResizingTextArea","TextArea","props","ref","id","propId","style","className","label","labelProps","labelStyle","labelClassName","areaStyle","areaClassName","resizeContainerProps","resize","dense","error","active","inline","propInline","leftAddon","rightAddon","disableLeftAddonStyles","disableRightAddonStyles","theme","propTheme","underlineDirection","propUnderlineDirection","messageProps","messageContainerProps","containerProps","rows","maxRows","onChange","propOnChange","disableTransition","propDisableTransition","remaining","disabled","readOnly","value","defaultValue","areaRef","areaRefCallback","maskRef","containerRef","height","scrollable","placeholder","area","textarea","placeholderHidden","labelNode","htmlFor","floating","children","maskId","animate","underlineLabelled","onClick","event","target","currentTarget","current","focus"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/form/TextArea.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type TextareaHTMLAttributes,\n forwardRef,\n} from \"react\";\n\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { FormMessageContainer } from \"./FormMessageContainer.js\";\nimport { Label } from \"./Label.js\";\nimport { ResizingTextAreaWrapper } from \"./ResizingTextAreaWrapper.js\";\nimport { TextFieldContainer } from \"./TextFieldContainer.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { textArea, textAreaContainer } from \"./textAreaStyles.js\";\nimport { type FormFieldOptions } from \"./types.js\";\nimport {\n type TextAreaResize,\n useResizingTextArea,\n} from \"./useResizingTextArea.js\";\n\n// NOTE: The augmentation appears in this file since no type definitions are\n// ever imported from the `textAreaStylesStyles` file.\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-text-area-height\"?: string | number;\n \"--rmd-text-area-padding\"?: string | number;\n }\n}\n\n/**\n * @since 6.0.0 Added `containerProps`.\n */\nexport interface TextAreaProps\n extends FormFieldOptions,\n TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** @defaultValue `\"text-area-\" + useId()` */\n id?: string;\n\n /**\n * Optional placeholder text to display in the text field.\n *\n * @defaultValue `label ? \" \" : \"\"`\n */\n placeholder?: string;\n\n /**\n * Set this to `true` if the auto resizing textarea should not animate for new\n * height changes.\n *\n * @defaultValue `false`\n */\n disableTransition?: boolean;\n\n /**\n * An optional style to apply to the textarea element. The base `style` prop\n * is applied to the surrounding `div` instead.\n */\n areaStyle?: CSSProperties;\n\n /**\n * An optional className to apply to the textarea element. The base `style`\n * prop is applied to the surrounding `div` instead.\n */\n areaClassName?: string;\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attr-rows\n * @defaultValue `2`\n */\n rows?: number;\n\n /**\n * The maximum number of rows a textarea can expand to before showing a\n * scrollbar. When this is set to `-1`, there will be no limit.\n *\n * @defaultValue `-1`\n */\n maxRows?: number;\n\n /**\n * @see {@link TextAreaResize}\n * @defaultValue `\"auto\"`\n */\n resize?: TextAreaResize;\n\n /**\n * When the {@link resize} prop is set to `\"auto\"`, an additional `<div>` is\n * added along with a hidden `<textarea>` mask. This prop can be used to add\n * any additional styling or props to that div.\n *\n * This will only be applied when {@link resize} is set to `\"auto\"`.\n */\n resizeContainerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n\n /**\n * Optional props to provide to the {@link TextFieldContainer} component.\n * There probably isn't any real use for this prop other than if you need to\n * add a `ref` for some DOM behavior.\n */\n containerProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * **Client Component**\n *\n * @example Simple Example\n * ```tsx\n * import { TextArea } from \"@react-md/core/form/TextArea\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * return (\n * <TextArea\n * label=\"Label\"\n * placeholder=\"Placeholder\"\n * />\n * );\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/text-field#simple-textarea | TextArea Demos}\n */\nexport const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\n function TextArea(props, ref) {\n const {\n id: propId,\n style,\n className,\n label,\n labelProps,\n labelStyle,\n labelClassName,\n areaStyle,\n areaClassName,\n resizeContainerProps,\n resize = \"auto\",\n dense,\n error,\n active,\n inline: propInline,\n leftAddon,\n rightAddon,\n disableLeftAddonStyles,\n disableRightAddonStyles,\n theme: propTheme,\n underlineDirection: propUnderlineDirection,\n messageProps,\n messageContainerProps,\n containerProps,\n rows = 2,\n maxRows = -1,\n onChange: propOnChange,\n disableTransition: propDisableTransition,\n ...remaining\n } = props;\n const { disabled = false, readOnly = false, value, defaultValue } = props;\n const id = useEnsuredId(propId, \"text-area\");\n const theme = getFormConfig(\"theme\", propTheme);\n const underlineDirection = getFormConfig(\n \"underlineDirection\",\n propUnderlineDirection\n );\n const [areaRef, areaRefCallback] = useEnsuredRef(ref);\n\n const {\n maskRef,\n containerRef,\n height,\n onChange,\n scrollable,\n disableTransition,\n } = useResizingTextArea({\n maxRows,\n resize,\n onChange: propOnChange,\n containerRef: containerProps?.ref,\n disableTransition: propDisableTransition,\n });\n\n let { placeholder = \"\" } = props;\n if (label && !placeholder) {\n // See the placeholder type definition comments for information\n placeholder = \" \";\n }\n\n // have to force it inline or else you won't be able to resize\n // it horizontally.\n const inline = resize === \"horizontal\" || resize === \"both\" || propInline;\n\n const area = (\n <textarea\n {...remaining}\n id={id}\n ref={areaRefCallback}\n rows={rows}\n disabled={disabled}\n onChange={onChange}\n placeholder={placeholder}\n style={areaStyle}\n className={textArea({\n resize,\n scrollable,\n className: areaClassName,\n placeholderHidden: !!label && !active,\n })}\n />\n );\n\n const labelNode = label && (\n <Label\n {...labelProps}\n htmlFor={id}\n style={labelProps?.style ?? labelStyle}\n className={labelProps?.className ?? labelClassName}\n floating\n dense={dense}\n error={error}\n active={active}\n disabled={disabled}\n >\n {label}\n </Label>\n );\n\n let children = (\n <>\n {area}\n {labelNode}\n </>\n );\n\n if (resize === \"auto\") {\n children = (\n <ResizingTextAreaWrapper\n {...resizeContainerProps}\n maskId={`${id}-mask`}\n maskRef={maskRef}\n rows={rows}\n areaStyle={areaStyle}\n areaClassName={areaClassName}\n defaultValue={value ?? defaultValue}\n disableTransition={disableTransition}\n >\n {children}\n </ResizingTextAreaWrapper>\n );\n }\n\n return (\n <FormMessageContainer\n inline={inline}\n {...messageContainerProps}\n messageProps={messageProps}\n >\n <TextFieldContainer\n {...containerProps}\n ref={containerRef}\n style={{\n ...style,\n \"--rmd-text-area-height\": height,\n }}\n className={textAreaContainer({\n animate: !disableTransition && resize === \"auto\",\n disabled,\n height: !!height,\n underlineLabelled:\n !!label && (theme === \"underline\" || theme === \"filled\"),\n className,\n })}\n theme={theme}\n label={!!label}\n error={error}\n dense={dense}\n inline={inline}\n active={active}\n readOnly={readOnly}\n disabled={disabled}\n leftAddon={leftAddon}\n rightAddon={rightAddon}\n underlineDirection={underlineDirection}\n disableLeftAddonStyles={disableLeftAddonStyles}\n disableRightAddonStyles={disableRightAddonStyles}\n onClick={(event) => {\n // The textarea container adds padding-top when there is a label so\n // that the label does not cover the text so this makes it so you\n // can still click anywhere in the \"box\" to focus the textarea.\n if (!disabled && event.target === event.currentTarget) {\n areaRef.current?.focus();\n }\n }}\n >\n {children}\n </TextFieldContainer>\n </FormMessageContainer>\n );\n }\n);\n"],"names":["forwardRef","useEnsuredId","useEnsuredRef","FormMessageContainer","Label","ResizingTextAreaWrapper","TextFieldContainer","getFormConfig","textArea","textAreaContainer","useResizingTextArea","TextArea","props","ref","id","propId","style","className","label","labelProps","labelStyle","labelClassName","areaStyle","areaClassName","resizeContainerProps","resize","dense","error","active","inline","propInline","leftAddon","rightAddon","disableLeftAddonStyles","disableRightAddonStyles","theme","propTheme","underlineDirection","propUnderlineDirection","messageProps","messageContainerProps","containerProps","rows","maxRows","onChange","propOnChange","disableTransition","propDisableTransition","remaining","disabled","readOnly","value","defaultValue","areaRef","areaRefCallback","maskRef","containerRef","height","scrollable","placeholder","area","textarea","placeholderHidden","labelNode","htmlFor","floating","children","maskId","animate","underlineLabelled","onClick","event","target","currentTarget","current","focus"],"mappings":"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"}
@@ -1,18 +1,5 @@
1
1
  import { type HTMLAttributes } from "react";
2
2
  import { type TextFieldContainerOptions } from "./types.js";
3
- declare module "react" {
4
- interface CSSProperties {
5
- "--rmd-text-field-height"?: string | number;
6
- "--rmd-text-field-padding-left"?: string | number;
7
- "--rmd-text-field-padding-right"?: string | number;
8
- "--rmd-text-field-padding-top"?: string | number;
9
- "--rmd-text-field-border-color"?: string;
10
- "--rmd-text-field-hover-border-color"?: string;
11
- "--rmd-text-field-filled-color"?: string;
12
- "--rmd-form-addon-top"?: string | number;
13
- "--rmd-form-addon-margin-top"?: string | number;
14
- }
15
- }
16
3
  export interface TextFieldContainerProps extends HTMLAttributes<HTMLDivElement>, TextFieldContainerOptions {
17
4
  /**
18
5
  * Set this to `true` if there is a floating label with the `TextField` or
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/form/TextFieldContainer.tsx"],"sourcesContent":["\"use client\";\n\nimport { type HTMLAttributes, forwardRef } from \"react\";\n\nimport { TextFieldAddon } from \"./TextFieldAddon.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { textFieldContainer } from \"./textFieldContainerStyles.js\";\nimport { type TextFieldContainerOptions } from \"./types.js\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-text-field-height\"?: string | number;\n \"--rmd-text-field-padding-left\"?: string | number;\n \"--rmd-text-field-padding-right\"?: string | number;\n \"--rmd-text-field-padding-top\"?: string | number;\n \"--rmd-text-field-border-color\"?: string;\n \"--rmd-text-field-hover-border-color\"?: string;\n \"--rmd-text-field-filled-color\"?: string;\n \"--rmd-form-addon-top\"?: string | number;\n \"--rmd-form-addon-margin-top\"?: string | number;\n }\n}\n\nexport interface TextFieldContainerProps\n extends HTMLAttributes<HTMLDivElement>,\n TextFieldContainerOptions {\n /**\n * Set this to `true` if there is a floating label with the `TextField` or\n * `TextArea`.\n *\n * @defaultValue `false`\n */\n label?: boolean;\n}\n\n/**\n * **Client Component**\n * This might be able to become a server component if I remove the useFormTheme hook\n *\n * This component is used to add the additional `TextField`, `TextArea`, and\n * `Select` theme styles.\n *\n * @internal\n */\nexport const TextFieldContainer = forwardRef<\n HTMLDivElement,\n TextFieldContainerProps\n>(function TextFieldContainer(props, ref) {\n const {\n children,\n className,\n dense,\n error,\n label,\n active,\n inline,\n readOnly,\n disabled,\n leftAddon,\n leftAddonProps,\n disableLeftAddonStyles,\n rightAddon,\n rightAddonProps,\n disableRightAddonStyles,\n theme: propTheme,\n underlineDirection: propUnderlineDirection,\n ...remaining\n } = props;\n const theme = getFormConfig(\"theme\", propTheme);\n const underlineDirection = getFormConfig(\n \"underlineDirection\",\n propUnderlineDirection\n );\n\n return (\n <div\n {...remaining}\n ref={ref}\n className={textFieldContainer({\n theme,\n dense,\n error,\n label,\n inline,\n active,\n readOnly,\n disabled,\n className,\n leftAddon: !!leftAddon && !disableLeftAddonStyles,\n rightAddon: !!rightAddon && !disableRightAddonStyles,\n underlineDirection,\n })}\n >\n <TextFieldAddon {...leftAddonProps} disabled={disableLeftAddonStyles}>\n {leftAddon}\n </TextFieldAddon>\n {children}\n <TextFieldAddon\n {...rightAddonProps}\n disabled={disableRightAddonStyles}\n after\n >\n {rightAddon}\n </TextFieldAddon>\n </div>\n );\n});\n"],"names":["forwardRef","TextFieldAddon","getFormConfig","textFieldContainer","TextFieldContainer","props","ref","children","className","dense","error","label","active","inline","readOnly","disabled","leftAddon","leftAddonProps","disableLeftAddonStyles","rightAddon","rightAddonProps","disableRightAddonStyles","theme","propTheme","underlineDirection","propUnderlineDirection","remaining","div","after"],"mappings":"AAAA;;AAEA,SAA8BA,UAAU,QAAQ,QAAQ;AAExD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,kBAAkB,QAAQ,gCAAgC;AA6BnE;;;;;;;;CAQC,GACD,OAAO,MAAMC,mCAAqBJ,WAGhC,SAASI,mBAAmBC,KAAK,EAAEC,GAAG;IACtC,MAAM,EACJC,QAAQ,EACRC,SAAS,EACTC,KAAK,EACLC,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,MAAM,EACNC,QAAQ,EACRC,QAAQ,EACRC,SAAS,EACTC,cAAc,EACdC,sBAAsB,EACtBC,UAAU,EACVC,eAAe,EACfC,uBAAuB,EACvBC,OAAOC,SAAS,EAChBC,oBAAoBC,sBAAsB,EAC1C,GAAGC,WACJ,GAAGrB;IACJ,MAAMiB,QAAQpB,cAAc,SAASqB;IACrC,MAAMC,qBAAqBtB,cACzB,sBACAuB;IAGF,qBACE,MAACE;QACE,GAAGD,SAAS;QACbpB,KAAKA;QACLE,WAAWL,mBAAmB;YAC5BmB;YACAb;YACAC;YACAC;YACAE;YACAD;YACAE;YACAC;YACAP;YACAQ,WAAW,CAAC,CAACA,aAAa,CAACE;YAC3BC,YAAY,CAAC,CAACA,cAAc,CAACE;YAC7BG;QACF;;0BAEA,KAACvB;gBAAgB,GAAGgB,cAAc;gBAAEF,UAAUG;0BAC3CF;;YAEFT;0BACD,KAACN;gBACE,GAAGmB,eAAe;gBACnBL,UAAUM;gBACVO,KAAK;0BAEJT;;;;AAIT,GAAG"}
1
+ {"version":3,"sources":["../../src/form/TextFieldContainer.tsx"],"sourcesContent":["\"use client\";\n\nimport { type HTMLAttributes, forwardRef } from \"react\";\n\nimport { TextFieldAddon } from \"./TextFieldAddon.js\";\nimport { getFormConfig } from \"./formConfig.js\";\nimport { textFieldContainer } from \"./textFieldContainerStyles.js\";\nimport { type TextFieldContainerOptions } from \"./types.js\";\n\nexport interface TextFieldContainerProps\n extends HTMLAttributes<HTMLDivElement>,\n TextFieldContainerOptions {\n /**\n * Set this to `true` if there is a floating label with the `TextField` or\n * `TextArea`.\n *\n * @defaultValue `false`\n */\n label?: boolean;\n}\n\n/**\n * **Client Component**\n * This might be able to become a server component if I remove the useFormTheme hook\n *\n * This component is used to add the additional `TextField`, `TextArea`, and\n * `Select` theme styles.\n *\n * @internal\n */\nexport const TextFieldContainer = forwardRef<\n HTMLDivElement,\n TextFieldContainerProps\n>(function TextFieldContainer(props, ref) {\n const {\n children,\n className,\n dense,\n error,\n label,\n active,\n inline,\n readOnly,\n disabled,\n leftAddon,\n leftAddonProps,\n disableLeftAddonStyles,\n rightAddon,\n rightAddonProps,\n disableRightAddonStyles,\n theme: propTheme,\n underlineDirection: propUnderlineDirection,\n ...remaining\n } = props;\n const theme = getFormConfig(\"theme\", propTheme);\n const underlineDirection = getFormConfig(\n \"underlineDirection\",\n propUnderlineDirection\n );\n\n return (\n <div\n {...remaining}\n ref={ref}\n className={textFieldContainer({\n theme,\n dense,\n error,\n label,\n inline,\n active,\n readOnly,\n disabled,\n className,\n leftAddon: !!leftAddon && !disableLeftAddonStyles,\n rightAddon: !!rightAddon && !disableRightAddonStyles,\n underlineDirection,\n })}\n >\n <TextFieldAddon {...leftAddonProps} disabled={disableLeftAddonStyles}>\n {leftAddon}\n </TextFieldAddon>\n {children}\n <TextFieldAddon\n {...rightAddonProps}\n disabled={disableRightAddonStyles}\n after\n >\n {rightAddon}\n </TextFieldAddon>\n </div>\n );\n});\n"],"names":["forwardRef","TextFieldAddon","getFormConfig","textFieldContainer","TextFieldContainer","props","ref","children","className","dense","error","label","active","inline","readOnly","disabled","leftAddon","leftAddonProps","disableLeftAddonStyles","rightAddon","rightAddonProps","disableRightAddonStyles","theme","propTheme","underlineDirection","propUnderlineDirection","remaining","div","after"],"mappings":"AAAA;;AAEA,SAA8BA,UAAU,QAAQ,QAAQ;AAExD,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,kBAAkB,QAAQ,gCAAgC;AAenE;;;;;;;;CAQC,GACD,OAAO,MAAMC,mCAAqBJ,WAGhC,SAASI,mBAAmBC,KAAK,EAAEC,GAAG;IACtC,MAAM,EACJC,QAAQ,EACRC,SAAS,EACTC,KAAK,EACLC,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,MAAM,EACNC,QAAQ,EACRC,QAAQ,EACRC,SAAS,EACTC,cAAc,EACdC,sBAAsB,EACtBC,UAAU,EACVC,eAAe,EACfC,uBAAuB,EACvBC,OAAOC,SAAS,EAChBC,oBAAoBC,sBAAsB,EAC1C,GAAGC,WACJ,GAAGrB;IACJ,MAAMiB,QAAQpB,cAAc,SAASqB;IACrC,MAAMC,qBAAqBtB,cACzB,sBACAuB;IAGF,qBACE,MAACE;QACE,GAAGD,SAAS;QACbpB,KAAKA;QACLE,WAAWL,mBAAmB;YAC5BmB;YACAb;YACAC;YACAC;YACAE;YACAD;YACAE;YACAC;YACAP;YACAQ,WAAW,CAAC,CAACA,aAAa,CAACE;YAC3BC,YAAY,CAAC,CAACA,cAAc,CAACE;YAC7BG;QACF;;0BAEA,KAACvB;gBAAgB,GAAGgB,cAAc;gBAAEF,UAAUG;0BAC3CF;;YAEFT;0BACD,KAACN;gBACE,GAAGmB,eAAe;gBACnBL,UAAUM;gBACVO,KAAK;0BAEJT;;;;AAIT,GAAG"}
@@ -107,7 +107,11 @@ $option-selected-icon-spacing: $option-padding-left !default;
107
107
  @if not $disable-native-select-multiple {
108
108
  .rmd-native-select-container {
109
109
  &--multi {
110
- @include text-field.set-var(addon-top, $native-select-addon-top);
110
+ @include text-field.set-var(addon-top, 0);
111
+ @include text-field.set-var(
112
+ addon-margin-top,
113
+ $native-select-addon-top
114
+ );
111
115
  @include text-field.use-var(min-height, height);
112
116
 
113
117
  height: auto;