@recursica/adapter-mantine-v8 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/commonArgTypes.ts +148 -0
- package/ARCHITECTURE.md +18 -0
- package/CHANGELOG.md +688 -0
- package/LICENSE +21 -0
- package/OVERSTYLING.md +56 -0
- package/README.md +70 -0
- package/SETUP.md +93 -0
- package/USAGE.md +57 -0
- package/dist/adapter-mantine-v8.cjs +12 -0
- package/dist/adapter-mantine-v8.cjs.map +1 -0
- package/dist/adapter-mantine-v8.css +1 -0
- package/dist/adapter-mantine-v8.js +5759 -0
- package/dist/adapter-mantine-v8.js.map +1 -0
- package/dist/index.d.ts +2095 -0
- package/dist/test.html +1 -0
- package/dist/vite.svg +1 -0
- package/docs/PHILOSOPHY.md +39 -0
- package/llms.txt +74 -0
- package/package.json +131 -0
- package/recursica_brand.json +2677 -0
- package/recursica_tokens.json +799 -0
- package/recursica_ui-kit.json +14981 -0
- package/recursica_variables_scoped.css +30489 -0
- package/src/GlobalExemptions.modules.css +7 -0
- package/src/Introduction.stories.tsx +154 -0
- package/src/OverStyling.tsx +79 -0
- package/src/Version.tsx +44 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +72 -0
- package/src/components/Accordion/Accordion.module.css +367 -0
- package/src/components/Accordion/Accordion.stories.tsx +189 -0
- package/src/components/Accordion/Accordion.test.tsx +1 -0
- package/src/components/Accordion/Accordion.tsx +220 -0
- package/src/components/Accordion/USAGE.md +51 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/ASSISTIVEELEMENT_IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +68 -0
- package/src/components/AssistiveElement/AssistiveElement.test.tsx +1 -0
- package/src/components/AssistiveElement/AssistiveElement.tsx +93 -0
- package/src/components/AssistiveElement/USAGE.md +36 -0
- package/src/components/AutoComplete/AUTOCOMPLETE_IMPLEMENTATION_NOTES.md +42 -0
- package/src/components/AutoComplete/AutoComplete.module.css +430 -0
- package/src/components/AutoComplete/AutoComplete.stories.tsx +336 -0
- package/src/components/AutoComplete/AutoComplete.test.tsx +1 -0
- package/src/components/AutoComplete/AutoComplete.tsx +179 -0
- package/src/components/AutoComplete/USAGE.md +80 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +34 -0
- package/src/components/Avatar/Avatar.module.css +336 -0
- package/src/components/Avatar/Avatar.stories.tsx +92 -0
- package/src/components/Avatar/Avatar.test.tsx +1 -0
- package/src/components/Avatar/Avatar.tsx +108 -0
- package/src/components/Avatar/USAGE.md +38 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Badge/Badge.module.css +127 -0
- package/src/components/Badge/Badge.stories.tsx +78 -0
- package/src/components/Badge/Badge.test.tsx +1 -0
- package/src/components/Badge/Badge.tsx +64 -0
- package/src/components/Badge/USAGE.md +56 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +47 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +48 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +114 -0
- package/src/components/Breadcrumb/Breadcrumb.test.tsx +1 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +85 -0
- package/src/components/Breadcrumb/USAGE.md +55 -0
- package/src/components/Breadcrumb/markCurrentPageItem.test.ts +49 -0
- package/src/components/Button/Button.module.css +446 -0
- package/src/components/Button/Button.stories.tsx +196 -0
- package/src/components/Button/Button.styleIsolation.dom.test.tsx +98 -0
- package/src/components/Button/Button.tsx +184 -0
- package/src/components/Button/IMPLEMENTATION_NOTES.md +109 -0
- package/src/components/Button/USAGE.md +80 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +17 -0
- package/src/components/Card/Card.module.css +119 -0
- package/src/components/Card/Card.stories.tsx +131 -0
- package/src/components/Card/Card.test.tsx +1 -0
- package/src/components/Card/Card.tsx +248 -0
- package/src/components/Card/USAGE.md +63 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Checkbox/Checkbox.module.css +267 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +97 -0
- package/src/components/Checkbox/Checkbox.test.tsx +1 -0
- package/src/components/Checkbox/Checkbox.tsx +151 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +147 -0
- package/src/components/Checkbox/USAGE.md +48 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +110 -0
- package/src/components/Chip/Chip.module.css +288 -0
- package/src/components/Chip/Chip.stories.tsx +128 -0
- package/src/components/Chip/Chip.test.tsx +1 -0
- package/src/components/Chip/Chip.tsx +157 -0
- package/src/components/Chip/USAGE.md +55 -0
- package/src/components/Container/CONTAINER_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Container/Container.module.css +7 -0
- package/src/components/Container/Container.stories.tsx +118 -0
- package/src/components/Container/Container.test.tsx +1 -0
- package/src/components/Container/Container.tsx +69 -0
- package/src/components/Container/USAGE.md +47 -0
- package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +31 -0
- package/src/components/DatePicker/DatePicker.icons.tsx +27 -0
- package/src/components/DatePicker/DatePicker.module.css +566 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +158 -0
- package/src/components/DatePicker/DatePicker.test.tsx +1 -0
- package/src/components/DatePicker/DatePicker.tsx +218 -0
- package/src/components/DatePicker/USAGE.md +49 -0
- package/src/components/Dropdown/BareDropdown.tsx +97 -0
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Dropdown/Dropdown.module.css +477 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +252 -0
- package/src/components/Dropdown/Dropdown.test.tsx +1 -0
- package/src/components/Dropdown/Dropdown.tsx +213 -0
- package/src/components/Dropdown/USAGE.md +69 -0
- package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +153 -0
- package/src/components/FileInput/FileInput.module.css +280 -0
- package/src/components/FileInput/FileInput.stories.tsx +313 -0
- package/src/components/FileInput/FileInput.test.tsx +1 -0
- package/src/components/FileInput/FileInput.tsx +417 -0
- package/src/components/FileInput/USAGE.md +145 -0
- package/src/components/FileUpload/FILEUPLOAD_IMPLEMENTATION_NOTES.md +244 -0
- package/src/components/FileUpload/FileUpload.module.css +205 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +362 -0
- package/src/components/FileUpload/FileUpload.test.tsx +1 -0
- package/src/components/FileUpload/FileUpload.tsx +354 -0
- package/src/components/FileUpload/USAGE.md +199 -0
- package/src/components/Flex/FLEX_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Flex/Flex.module.css +7 -0
- package/src/components/Flex/Flex.stories.tsx +128 -0
- package/src/components/Flex/Flex.test.tsx +1 -0
- package/src/components/Flex/Flex.tsx +75 -0
- package/src/components/Flex/USAGE.md +48 -0
- package/src/components/FormControlLayout/FormControlLayout.module.css +90 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +118 -0
- package/src/components/FormControlLayout/FormControlLayout.test.tsx +1 -0
- package/src/components/FormControlLayout/FormControlLayout.tsx +74 -0
- package/src/components/FormControlLayout/USAGE.md +40 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +75 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +129 -0
- package/src/components/FormControlWrapper/FormControlWrapper.test.tsx +1 -0
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +151 -0
- package/src/components/FormControlWrapper/USAGE.md +47 -0
- package/src/components/Grid/GRID_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Grid/Grid.module.css +11 -0
- package/src/components/Grid/Grid.stories.tsx +206 -0
- package/src/components/Grid/Grid.test.tsx +1 -0
- package/src/components/Grid/Grid.tsx +140 -0
- package/src/components/Grid/USAGE.md +47 -0
- package/src/components/Group/GROUP_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Group/Group.module.css +7 -0
- package/src/components/Group/Group.stories.tsx +120 -0
- package/src/components/Group/Group.test.tsx +1 -0
- package/src/components/Group/Group.tsx +60 -0
- package/src/components/Group/USAGE.md +48 -0
- package/src/components/Heading/HEADING_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Heading/Heading.module.css +13 -0
- package/src/components/Heading/Heading.stories.tsx +50 -0
- package/src/components/Heading/Heading.test.tsx +1 -0
- package/src/components/Heading/Heading.tsx +52 -0
- package/src/components/Heading/USAGE.md +36 -0
- package/src/components/HoverCard/HOVERCARD_IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/HoverCard/HoverCard.module.css +90 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +172 -0
- package/src/components/HoverCard/HoverCard.test.tsx +1 -0
- package/src/components/HoverCard/HoverCard.tsx +133 -0
- package/src/components/HoverCard/USAGE.md +52 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Label/Label.module.css +141 -0
- package/src/components/Label/Label.stories.tsx +131 -0
- package/src/components/Label/Label.test.tsx +1 -0
- package/src/components/Label/Label.tsx +113 -0
- package/src/components/Label/USAGE.md +47 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Layer/USAGE.md +54 -0
- package/src/components/Link/IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/Link/Link.module.css +110 -0
- package/src/components/Link/Link.stories.tsx +58 -0
- package/src/components/Link/Link.test.tsx +1 -0
- package/src/components/Link/Link.tsx +67 -0
- package/src/components/Link/USAGE.md +56 -0
- package/src/components/Link/index.ts +1 -0
- package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Loader/Loader.animate.dom.test.tsx +82 -0
- package/src/components/Loader/Loader.module.css +63 -0
- package/src/components/Loader/Loader.stories.tsx +123 -0
- package/src/components/Loader/Loader.test.tsx +1 -0
- package/src/components/Loader/Loader.tsx +69 -0
- package/src/components/Loader/USAGE.md +44 -0
- package/src/components/Menu/MENU_IMPLEMENTATION_NOTES.md +88 -0
- package/src/components/Menu/Menu.module.css +280 -0
- package/src/components/Menu/Menu.stories.tsx +371 -0
- package/src/components/Menu/Menu.test.tsx +1 -0
- package/src/components/Menu/Menu.tsx +373 -0
- package/src/components/Menu/USAGE.md +55 -0
- package/src/components/Modal/MODAL_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/Modal/Modal.module.css +302 -0
- package/src/components/Modal/Modal.stories.tsx +105 -0
- package/src/components/Modal/Modal.test.tsx +1 -0
- package/src/components/Modal/Modal.tsx +368 -0
- package/src/components/Modal/USAGE.md +58 -0
- package/src/components/Modal/index.ts +1 -0
- package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/NumberInput/NumberInput.module.css +302 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +96 -0
- package/src/components/NumberInput/NumberInput.test.tsx +1 -0
- package/src/components/NumberInput/NumberInput.tsx +157 -0
- package/src/components/NumberInput/USAGE.md +52 -0
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +16 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +188 -0
- package/src/components/Pagination/Pagination.stories.tsx +48 -0
- package/src/components/Pagination/Pagination.test.tsx +1 -0
- package/src/components/Pagination/Pagination.tsx +265 -0
- package/src/components/Pagination/USAGE.md +36 -0
- package/src/components/Pagination/index.ts +5 -0
- package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +116 -0
- package/src/components/Panel/Panel.module.css +209 -0
- package/src/components/Panel/Panel.stories.tsx +227 -0
- package/src/components/Panel/Panel.test.tsx +1 -0
- package/src/components/Panel/Panel.tsx +269 -0
- package/src/components/Panel/USAGE.md +56 -0
- package/src/components/Popover/IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/Popover/Popover.module.css +86 -0
- package/src/components/Popover/Popover.stories.tsx +133 -0
- package/src/components/Popover/Popover.test.tsx +1 -0
- package/src/components/Popover/Popover.tsx +142 -0
- package/src/components/Popover/USAGE.md +61 -0
- package/src/components/Popover/index.ts +1 -0
- package/src/components/Radio/Radio.module.css +231 -0
- package/src/components/Radio/Radio.stories.tsx +93 -0
- package/src/components/Radio/Radio.test.tsx +1 -0
- package/src/components/Radio/Radio.tsx +168 -0
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +124 -0
- package/src/components/Radio/USAGE.md +36 -0
- package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +54 -0
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +163 -0
- package/src/components/ReadOnlyField/ReadOnlyField.test.tsx +1 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +114 -0
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/USAGE.md +44 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +5 -0
- package/src/components/RecursicaThemeProvider/USAGE.md +60 -0
- package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +185 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +106 -0
- package/src/components/SegmentedControl/SegmentedControl.test.tsx +1 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +110 -0
- package/src/components/SegmentedControl/USAGE.md +55 -0
- package/src/components/Slider/IMPLEMENTATION_NOTES.md +92 -0
- package/src/components/Slider/Slider.module.css +588 -0
- package/src/components/Slider/Slider.stories.tsx +282 -0
- package/src/components/Slider/Slider.test.tsx +1 -0
- package/src/components/Slider/Slider.tsx +391 -0
- package/src/components/Slider/USAGE.md +56 -0
- package/src/components/Stack/STACK_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stack/Stack.module.css +7 -0
- package/src/components/Stack/Stack.stories.tsx +108 -0
- package/src/components/Stack/Stack.test.tsx +1 -0
- package/src/components/Stack/Stack.tsx +62 -0
- package/src/components/Stack/USAGE.md +48 -0
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +28 -0
- package/src/components/Stepper/Stepper.module.css +404 -0
- package/src/components/Stepper/Stepper.stories.tsx +148 -0
- package/src/components/Stepper/Stepper.test.tsx +1 -0
- package/src/components/Stepper/Stepper.tsx +93 -0
- package/src/components/Stepper/USAGE.md +41 -0
- package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +64 -0
- package/src/components/Switch/Switch.module.css +279 -0
- package/src/components/Switch/Switch.stories.tsx +114 -0
- package/src/components/Switch/Switch.test.tsx +1 -0
- package/src/components/Switch/Switch.tsx +177 -0
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +127 -0
- package/src/components/Switch/USAGE.md +42 -0
- package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +78 -0
- package/src/components/Table/Table.icons.tsx +40 -0
- package/src/components/Table/Table.module.css +444 -0
- package/src/components/Table/Table.stories.tsx +140 -0
- package/src/components/Table/Table.test.tsx +1 -0
- package/src/components/Table/Table.tsx +243 -0
- package/src/components/Table/USAGE.md +78 -0
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +27 -0
- package/src/components/Tabs/Tabs.module.css +591 -0
- package/src/components/Tabs/Tabs.stories.tsx +154 -0
- package/src/components/Tabs/Tabs.test.tsx +1 -0
- package/src/components/Tabs/Tabs.tsx +114 -0
- package/src/components/Tabs/USAGE.md +45 -0
- package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Text/Text.module.css +13 -0
- package/src/components/Text/Text.stories.tsx +75 -0
- package/src/components/Text/Text.test.tsx +1 -0
- package/src/components/Text/Text.tsx +53 -0
- package/src/components/Text/USAGE.md +40 -0
- package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/TextArea/TextArea.module.css +183 -0
- package/src/components/TextArea/TextArea.stories.tsx +94 -0
- package/src/components/TextArea/TextArea.test.tsx +1 -0
- package/src/components/TextArea/TextArea.tsx +137 -0
- package/src/components/TextArea/USAGE.md +48 -0
- package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/TextField/TextField.module.css +264 -0
- package/src/components/TextField/TextField.stories.tsx +162 -0
- package/src/components/TextField/TextField.test.tsx +1 -0
- package/src/components/TextField/TextField.tsx +139 -0
- package/src/components/TextField/USAGE.md +44 -0
- package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +119 -0
- package/src/components/TimePicker/TimePicker.module.css +291 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +141 -0
- package/src/components/TimePicker/TimePicker.test.tsx +1 -0
- package/src/components/TimePicker/TimePicker.tsx +304 -0
- package/src/components/TimePicker/USAGE.md +57 -0
- package/src/components/Timeline/TIMELINE_IMPLEMENTATION_NOTES.md +13 -0
- package/src/components/Timeline/Timeline.module.css +373 -0
- package/src/components/Timeline/Timeline.stories.tsx +128 -0
- package/src/components/Timeline/Timeline.test.tsx +1 -0
- package/src/components/Timeline/Timeline.tsx +73 -0
- package/src/components/Timeline/TimelineItem.tsx +79 -0
- package/src/components/Timeline/USAGE.md +49 -0
- package/src/components/Toast/TOAST_IMPLEMENTATION_NOTES.md +39 -0
- package/src/components/Toast/Toast.module.css +184 -0
- package/src/components/Toast/Toast.stories.tsx +67 -0
- package/src/components/Toast/Toast.test.tsx +1 -0
- package/src/components/Toast/Toast.tsx +82 -0
- package/src/components/Toast/USAGE.md +50 -0
- package/src/components/Toast/index.ts +1 -0
- package/src/components/Tooltip/TOOLTIP_IMPLEMENTATION_NOTES.md +85 -0
- package/src/components/Tooltip/Tooltip.module.css +91 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +165 -0
- package/src/components/Tooltip/Tooltip.test.tsx +1 -0
- package/src/components/Tooltip/Tooltip.tsx +117 -0
- package/src/components/Tooltip/USAGE.md +80 -0
- package/src/components/TransferList/TRANSFERLIST_IMPLEMENTATION_NOTES.md +111 -0
- package/src/components/TransferList/TransferList.module.css +182 -0
- package/src/components/TransferList/TransferList.stories.tsx +121 -0
- package/src/components/TransferList/TransferList.test.tsx +1 -0
- package/src/components/TransferList/TransferList.tsx +419 -0
- package/src/components/TransferList/USAGE.md +77 -0
- package/src/components/Tree/IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Tree/Tree.module.css +232 -0
- package/src/components/Tree/Tree.stories.tsx +104 -0
- package/src/components/Tree/Tree.test.tsx +1 -0
- package/src/components/Tree/Tree.tsx +220 -0
- package/src/components/Tree/USAGE.md +96 -0
- package/src/components/Tree/index.ts +1 -0
- package/src/components/index.ts +52 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +179 -0
- package/src/types/index.ts +9 -0
- package/src/types/mantine.d.ts +7 -0
- package/src/types/scss-modules.d.ts +9 -0
- package/src/utils/ColorSchemeWrapper.tsx +27 -0
- package/src/utils/RequireAccessibleLabel.ts +1 -0
- package/src/utils/copyToClipboard.ts +36 -0
- package/src/utils/filterStylingProps.test.ts +85 -0
- package/src/utils/filterStylingProps.ts +150 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/renderRichOption.tsx +65 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect, useRef, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
TimePicker as MantineTimePicker,
|
|
4
|
+
type TimePickerProps as MantineTimePickerProps,
|
|
5
|
+
} from "@mantine/dates";
|
|
6
|
+
import { type InputWrapperProps } from "@mantine/core";
|
|
7
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
omitUnsupportedProps,
|
|
11
|
+
mergeClassNames,
|
|
12
|
+
type RecursicaOverStyled,
|
|
13
|
+
} from "../../utils/filterStylingProps";
|
|
14
|
+
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
15
|
+
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
16
|
+
import { BareDropdown } from "../Dropdown/BareDropdown";
|
|
17
|
+
import styles from "./TimePicker.module.css";
|
|
18
|
+
|
|
19
|
+
import { type RecursicaTimePickerProps as BaseRecursicaTimePickerProps } from "@recursica/adapter-common";
|
|
20
|
+
|
|
21
|
+
const AM_PM_DATA = [
|
|
22
|
+
{ value: "AM", label: "AM" },
|
|
23
|
+
{ value: "PM", label: "PM" },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
/** Parses an "HH:mm"/"HH:mm:ss" string's hour, or undefined if not set/parseable. */
|
|
27
|
+
function getHour(value: string | undefined): number | undefined {
|
|
28
|
+
if (!value) return undefined;
|
|
29
|
+
const hour = parseInt(value.slice(0, 2), 10);
|
|
30
|
+
return Number.isNaN(hour) ? undefined : hour;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Replaces the hour segment of an "HH:mm"/"HH:mm:ss" string, preserving minutes/seconds. */
|
|
34
|
+
function withHour(value: string, hour: number): string {
|
|
35
|
+
return `${String(hour).padStart(2, "0")}${value.slice(2)}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Formats an "HH:mm"/"HH:mm:ss" 24-hour value as a 12-hour + AM/PM string for read-only display
|
|
40
|
+
* (e.g. "14:30" -> "2:30 PM") — the raw 24-hour string was being shown as-is in read-only mode,
|
|
41
|
+
* with no AM/PM, unlike the interactive composite. Returns undefined if not parseable.
|
|
42
|
+
*/
|
|
43
|
+
function formatReadOnlyTime(value: string | undefined): string | undefined {
|
|
44
|
+
if (!value) return undefined;
|
|
45
|
+
const [hourStr, minute, second] = value.split(":");
|
|
46
|
+
const hour24 = parseInt(hourStr, 10);
|
|
47
|
+
if (Number.isNaN(hour24) || minute === undefined) return value;
|
|
48
|
+
const isPM = hour24 >= 12;
|
|
49
|
+
const hour12 = hour24 % 12 === 0 ? 12 : hour24 % 12;
|
|
50
|
+
const rest = second !== undefined ? `${minute}:${second}` : minute;
|
|
51
|
+
return `${hour12}:${rest} ${isPM ? "PM" : "AM"}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Simulates a real user interaction on Mantine's own (CSS-hidden) native AM/PM <select>, since it's
|
|
56
|
+
* a React-controlled element — setting `.value` directly and dispatching a plain DOM event doesn't
|
|
57
|
+
* trigger React's change handling; using the native property setter first does. See "Why AM/PM is
|
|
58
|
+
* seeded on mount" in TIMEPICKER_IMPLEMENTATION_NOTES.md.
|
|
59
|
+
*/
|
|
60
|
+
function setNativeSelectValue(el: HTMLSelectElement, value: string): void {
|
|
61
|
+
const nativeSetter = Object.getOwnPropertyDescriptor(
|
|
62
|
+
window.HTMLSelectElement.prototype,
|
|
63
|
+
"value",
|
|
64
|
+
)?.set;
|
|
65
|
+
nativeSetter?.call(el, value);
|
|
66
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface RecursicaTimePickerProps
|
|
70
|
+
extends Omit<
|
|
71
|
+
MantineTimePickerProps,
|
|
72
|
+
| "size"
|
|
73
|
+
| "variant"
|
|
74
|
+
| "radius"
|
|
75
|
+
| "wrapperProps"
|
|
76
|
+
| "format"
|
|
77
|
+
| "min"
|
|
78
|
+
| "max"
|
|
79
|
+
// AM/PM is always shown via our own BareDropdown, driving a fixed 12h format — these all
|
|
80
|
+
// control Mantine's own native (now CSS-hidden) AM/PM select and would be misleading to
|
|
81
|
+
// expose, since they'd have no visible effect. See TIMEPICKER_IMPLEMENTATION_NOTES.md.
|
|
82
|
+
| "amPmInputLabel"
|
|
83
|
+
| "amPmLabels"
|
|
84
|
+
| "amPmSelectProps"
|
|
85
|
+
| "amPmRef"
|
|
86
|
+
// The optional time-presets dropdown isn't wired up; keep the public API to what's supported.
|
|
87
|
+
| "withDropdown"
|
|
88
|
+
| "presets"
|
|
89
|
+
| "maxDropdownContentHeight"
|
|
90
|
+
| "scrollAreaProps"
|
|
91
|
+
| "reverseTimeControlsList"
|
|
92
|
+
| "popoverProps"
|
|
93
|
+
>,
|
|
94
|
+
Pick<
|
|
95
|
+
InputWrapperProps,
|
|
96
|
+
"label" | "error" | "required" | "withAsterisk" | "id"
|
|
97
|
+
>,
|
|
98
|
+
Omit<
|
|
99
|
+
RecursicaFormControlWrapperProps,
|
|
100
|
+
"controlMaxWidth" | "controlMinWidth"
|
|
101
|
+
>,
|
|
102
|
+
ReadOnlyControlProps,
|
|
103
|
+
BaseRecursicaTimePickerProps {}
|
|
104
|
+
|
|
105
|
+
export type TimePickerProps = RecursicaOverStyled<RecursicaTimePickerProps>;
|
|
106
|
+
|
|
107
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
108
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
109
|
+
const UNSUPPORTED_PROPS = [
|
|
110
|
+
"size", // Recursica controls sizing via the `size` variant + design tokens, not raw dimensions.
|
|
111
|
+
"variant", // Colors/variants are token-driven; the library's native palette isn't exposed.
|
|
112
|
+
"radius", // Recursica does not expose the library's native corner-radius system.
|
|
113
|
+
] as const satisfies readonly (keyof MantineTimePickerProps)[];
|
|
114
|
+
|
|
115
|
+
export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(
|
|
116
|
+
function TimePicker(props, ref) {
|
|
117
|
+
const {
|
|
118
|
+
overStyled = false,
|
|
119
|
+
formLayout = "stacked",
|
|
120
|
+
|
|
121
|
+
// Label & Wrapper Maps
|
|
122
|
+
labelSize,
|
|
123
|
+
labelAlignment,
|
|
124
|
+
labelOptionalText,
|
|
125
|
+
labelWithEditIcon,
|
|
126
|
+
onLabelEditClick,
|
|
127
|
+
|
|
128
|
+
label,
|
|
129
|
+
assistiveText,
|
|
130
|
+
assistiveWithIcon,
|
|
131
|
+
error,
|
|
132
|
+
required,
|
|
133
|
+
withAsterisk,
|
|
134
|
+
id,
|
|
135
|
+
className,
|
|
136
|
+
style,
|
|
137
|
+
disabled,
|
|
138
|
+
readOnly,
|
|
139
|
+
readOnlyComponent,
|
|
140
|
+
emptyValueComponent,
|
|
141
|
+
value,
|
|
142
|
+
defaultValue,
|
|
143
|
+
onChange,
|
|
144
|
+
withSeconds,
|
|
145
|
+
minTime,
|
|
146
|
+
maxTime,
|
|
147
|
+
...rest
|
|
148
|
+
} = props;
|
|
149
|
+
|
|
150
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
151
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
152
|
+
UNSUPPORTED_PROPS,
|
|
153
|
+
);
|
|
154
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
155
|
+
|
|
156
|
+
// Internal full 24-hour value. Needed because Mantine's TimePicker (hour/minute/second entry)
|
|
157
|
+
// and our own BareDropdown (AM/PM) both mutate the same conceptual value — see
|
|
158
|
+
// TIMEPICKER_IMPLEMENTATION_NOTES.md.
|
|
159
|
+
const [internalValue, setInternalValue] = useState<string | undefined>(
|
|
160
|
+
() => value ?? defaultValue,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
if (value !== undefined) {
|
|
165
|
+
setInternalValue(value);
|
|
166
|
+
}
|
|
167
|
+
}, [value]);
|
|
168
|
+
|
|
169
|
+
// Mantine's own internal amPm state starts `null` whenever there's no initial hour to derive it
|
|
170
|
+
// from (see convertTimeTo12HourFormat in @mantine/dates), and it stays null — meaning Mantine
|
|
171
|
+
// never reports a valid onChange, no matter what's typed — until something interacts with the
|
|
172
|
+
// (CSS-hidden) native AM/PM <select>. Simulating that interaction once on mount, defaulting to
|
|
173
|
+
// AM, breaks the deadlock: a freshly-typed time now resolves and reports immediately, and our
|
|
174
|
+
// own BareDropdown (which drives the same native select the same way, see handleMeridiemChange)
|
|
175
|
+
// correctly displays and changes it from there. Skipped whenever a real initial value/defaultValue
|
|
176
|
+
// is already present — Mantine already derives the correct AM/PM from that on its own. See
|
|
177
|
+
// TIMEPICKER_IMPLEMENTATION_NOTES.md.
|
|
178
|
+
const amPmRef = useRef<HTMLSelectElement>(null);
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (getHour(value ?? defaultValue) === undefined && amPmRef.current) {
|
|
181
|
+
setNativeSelectValue(amPmRef.current, "AM");
|
|
182
|
+
}
|
|
183
|
+
// Intentionally mount-only — this seeds Mantine's internal state once; after that it's driven
|
|
184
|
+
// by real interaction (typing, or our own BareDropdown).
|
|
185
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
186
|
+
}, []);
|
|
187
|
+
|
|
188
|
+
const emitChange = (next: string) => {
|
|
189
|
+
setInternalValue(next);
|
|
190
|
+
onChange?.(next);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const hour = getHour(internalValue);
|
|
194
|
+
const isPM = hour !== undefined && hour >= 12;
|
|
195
|
+
|
|
196
|
+
const handleFieldChange = (next: string) => {
|
|
197
|
+
emitChange(next);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const handleMeridiemChange = (next: string | null) => {
|
|
201
|
+
if (hour === undefined || !internalValue || !next) return;
|
|
202
|
+
const wantsPM = next === "PM";
|
|
203
|
+
if (wantsPM === isPM) return;
|
|
204
|
+
const nextHour = wantsPM ? hour + 12 : hour - 12;
|
|
205
|
+
emitChange(withHour(internalValue, nextHour));
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const wrapperClass = className
|
|
209
|
+
? `${styles.layoutOverride} ${className}`
|
|
210
|
+
: styles.layoutOverride;
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<WithReadOnlyWrapper
|
|
214
|
+
className={wrapperClass}
|
|
215
|
+
style={style as React.CSSProperties}
|
|
216
|
+
controlMaxWidth={undefined}
|
|
217
|
+
controlMinWidth={undefined}
|
|
218
|
+
overStyled={overStyled as true}
|
|
219
|
+
formLayout={formLayout}
|
|
220
|
+
labelSize={labelSize}
|
|
221
|
+
labelAlignment={labelAlignment}
|
|
222
|
+
labelOptionalText={labelOptionalText}
|
|
223
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
224
|
+
onLabelEditClick={onLabelEditClick}
|
|
225
|
+
label={label}
|
|
226
|
+
assistiveText={assistiveText}
|
|
227
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
228
|
+
error={error}
|
|
229
|
+
required={required}
|
|
230
|
+
withAsterisk={withAsterisk}
|
|
231
|
+
id={id}
|
|
232
|
+
readOnly={readOnly}
|
|
233
|
+
readOnlyComponent={readOnlyComponent}
|
|
234
|
+
emptyValueComponent={emptyValueComponent}
|
|
235
|
+
readOnlyType="text"
|
|
236
|
+
readOnlyValue={formatReadOnlyTime(
|
|
237
|
+
value !== undefined ? value : defaultValue,
|
|
238
|
+
)}
|
|
239
|
+
readOnlyNativeProps={props}
|
|
240
|
+
activeComponent={
|
|
241
|
+
/* Naked field execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks.
|
|
242
|
+
format="12h" is always on — this is the only way this component operates, not a user
|
|
243
|
+
choice (see TIMEPICKER_IMPLEMENTATION_NOTES.md). Mantine's own native AM/PM <select>
|
|
244
|
+
(bundled unconditionally with format="12h") is CSS-hidden; our own BareDropdown next to
|
|
245
|
+
it is the only AM/PM control the user interacts with. */
|
|
246
|
+
<div
|
|
247
|
+
className={styles.root}
|
|
248
|
+
data-disabled={disabled ? "true" : undefined}
|
|
249
|
+
data-error={error ? "true" : undefined}
|
|
250
|
+
>
|
|
251
|
+
<MantineTimePicker
|
|
252
|
+
ref={ref}
|
|
253
|
+
{...(sanitizedProps as unknown as MantineTimePickerProps)}
|
|
254
|
+
classNames={mergeClassNames(
|
|
255
|
+
{
|
|
256
|
+
wrapper: styles.timeWrapper,
|
|
257
|
+
input: styles.timeInput,
|
|
258
|
+
section: styles.section,
|
|
259
|
+
fieldsGroup: styles.fieldsGroup,
|
|
260
|
+
field: styles.timeField,
|
|
261
|
+
},
|
|
262
|
+
restRecord.classNames as
|
|
263
|
+
| Partial<Record<string, string>>
|
|
264
|
+
| undefined,
|
|
265
|
+
)}
|
|
266
|
+
disabled={disabled}
|
|
267
|
+
value={internalValue}
|
|
268
|
+
onChange={handleFieldChange}
|
|
269
|
+
format="12h"
|
|
270
|
+
withSeconds={withSeconds}
|
|
271
|
+
min={minTime}
|
|
272
|
+
max={maxTime}
|
|
273
|
+
withDropdown={false}
|
|
274
|
+
// Internal-only — not part of the public API (see the Omit list above) — used solely
|
|
275
|
+
// to seed the mount-time AM default onto Mantine's own hidden native select. See
|
|
276
|
+
// TIMEPICKER_IMPLEMENTATION_NOTES.md.
|
|
277
|
+
amPmRef={amPmRef}
|
|
278
|
+
/>
|
|
279
|
+
<BareDropdown
|
|
280
|
+
overStyled
|
|
281
|
+
className={styles.amPmSelect}
|
|
282
|
+
// Dropdown.module.css's own .root sets width: 100% (correct for a standalone
|
|
283
|
+
// Dropdown filling its form-control column) — overStyled lets us override just the
|
|
284
|
+
// width, keeping every other Recursica style (border, colors, padding) intact.
|
|
285
|
+
// A plain `style` prop won't do this: Mantine's Select/InputBase internals
|
|
286
|
+
// (useInputProps) route a top-level `style` prop to the *label* InputWrapper, not
|
|
287
|
+
// the bordered input box itself — `styles={{ wrapper: ... }}` is the styles-api hook
|
|
288
|
+
// that actually targets that box. See TIMEPICKER_IMPLEMENTATION_NOTES.md.
|
|
289
|
+
styles={{ wrapper: { width: "fit-content" } }}
|
|
290
|
+
data={AM_PM_DATA}
|
|
291
|
+
value={isPM ? "PM" : "AM"}
|
|
292
|
+
onChange={handleMeridiemChange}
|
|
293
|
+
disabled={disabled}
|
|
294
|
+
error={!!error}
|
|
295
|
+
aria-label="AM or PM"
|
|
296
|
+
/>
|
|
297
|
+
</div>
|
|
298
|
+
}
|
|
299
|
+
/>
|
|
300
|
+
);
|
|
301
|
+
},
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
TimePicker.displayName = "TimePicker";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# TimePicker - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `TimePicker` component in your projects using `@recursica/adapter-mantine-v8`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { TimePicker } from "@recursica/adapter-mantine-v8";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { TimePicker } from "@recursica/adapter-mantine-v8";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return <TimePicker label="Select Time" />;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> [!IMPORTANT] > **Recursica-specific behavior:** `TimePicker` always renders in **12-hour format with a dedicated AM/PM `Dropdown`-style selector** next to the hour/minute input — this deviates from the underlying Mantine library's own default (24-hour, no AM/PM control) and is **not configurable**. There is no prop to switch to a plain 24-hour input; this is the only way the component operates.
|
|
27
|
+
|
|
28
|
+
Pass `withSeconds` to add a seconds segment, and `minTime`/`maxTime` (`"HH:mm"` or `"HH:mm:ss"` with `withSeconds`) to bound the allowed range — these always describe 24-hour boundaries.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<TimePicker
|
|
32
|
+
label="Precise Time"
|
|
33
|
+
withSeconds
|
|
34
|
+
minTime="09:00:00"
|
|
35
|
+
maxTime="17:00:00"
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The AM/PM control visually matches Recursica's `Dropdown` component exactly, rather than a native `<select>`.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 3. Design System Integration
|
|
44
|
+
|
|
45
|
+
All Recursica components in the `@recursica/adapter-mantine-v8` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
46
|
+
|
|
47
|
+
> [!IMPORTANT]
|
|
48
|
+
>
|
|
49
|
+
> - **Anti-override protection**: Rogue style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
|
|
50
|
+
> - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
|
|
51
|
+
> - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 4. Read-Only Mode
|
|
56
|
+
|
|
57
|
+
Pass `readOnly` to render the current value as static text, matching every other Recursica form control. The value is formatted as 12-hour + AM/PM (e.g. `"14:30"` displays as `"2:30 PM"`).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Timeline Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
The `Timeline` component is a strict structural wrapper around Mantine's `<Timeline>` and `<Timeline.Item>` components.
|
|
6
|
+
|
|
7
|
+
- `Timeline.tsx` intercepts overarching properties like `lineWidth` and `bulletSize` to strip them out via `overStyled`, strictly adhering to the CSS token mapping in `.item` rules instead.
|
|
8
|
+
- `TimelineItem.tsx` implements a custom `timestamp` React node rendering slot to match the design system, positioning the text directly below the item's `children`.
|
|
9
|
+
- `TimelineItem.tsx` supports a custom `bulletVariant` prop (`"default" | "avatar" | "icon" | "icon-alternative"`) mapped onto `data-variant` to handle CSS variations dynamically.
|
|
10
|
+
|
|
11
|
+
## Limitations & Missing Tokens
|
|
12
|
+
|
|
13
|
+
- **Avatar Bullet Size**: There is no specific pixel variable provided for the Avatar bullet size in the UI kit tokens (`avatar-size` evaluates to `"default"`). To maintain exact mathematical centering with Mantine's connector line `calc()` equations, the CSS falls back to inheriting the `default` bullet size (`20px`) for avatar nodes natively. If users supply a custom sized `img` tag, it must adhere to inline structural constraints or flex mappings.
|