@mantine/core 9.3.0 → 9.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/components/Collapse/Collapse.cjs +2 -1
- package/cjs/components/Collapse/Collapse.cjs.map +1 -1
- package/cjs/components/Dialog/Dialog.cjs.map +1 -1
- package/cjs/components/Input/Input.module.cjs.map +1 -1
- package/cjs/components/Menu/MenuContextMenu/MenuContextMenu.cjs +4 -3
- package/cjs/components/Menu/MenuContextMenu/MenuContextMenu.cjs.map +1 -1
- package/cjs/components/Menu/MenuSub/MenuSub.cjs +16 -13
- package/cjs/components/Menu/MenuSub/MenuSub.cjs.map +1 -1
- package/cjs/components/Popover/PopoverContextMenu/PopoverContextMenu.cjs +4 -3
- package/cjs/components/Popover/PopoverContextMenu/PopoverContextMenu.cjs.map +1 -1
- package/cjs/components/SegmentedControl/SegmentedControl.module.cjs.map +1 -1
- package/cjs/components/Tree/TreeNode.cjs +8 -1
- package/cjs/components/Tree/TreeNode.cjs.map +1 -1
- package/cjs/utils/Floating/use-context-menu-handlers.cjs +85 -0
- package/cjs/utils/Floating/use-context-menu-handlers.cjs.map +1 -0
- package/esm/components/Collapse/Collapse.mjs +2 -1
- package/esm/components/Collapse/Collapse.mjs.map +1 -1
- package/esm/components/Dialog/Dialog.mjs.map +1 -1
- package/esm/components/Input/Input.module.mjs.map +1 -1
- package/esm/components/Menu/MenuContextMenu/MenuContextMenu.mjs +4 -3
- package/esm/components/Menu/MenuContextMenu/MenuContextMenu.mjs.map +1 -1
- package/esm/components/Menu/MenuSub/MenuSub.mjs +18 -15
- package/esm/components/Menu/MenuSub/MenuSub.mjs.map +1 -1
- package/esm/components/Popover/PopoverContextMenu/PopoverContextMenu.mjs +4 -3
- package/esm/components/Popover/PopoverContextMenu/PopoverContextMenu.mjs.map +1 -1
- package/esm/components/SegmentedControl/SegmentedControl.module.mjs.map +1 -1
- package/esm/components/Tree/TreeNode.mjs +8 -1
- package/esm/components/Tree/TreeNode.mjs.map +1 -1
- package/esm/utils/Floating/use-context-menu-handlers.mjs +85 -0
- package/esm/utils/Floating/use-context-menu-handlers.mjs.map +1 -0
- package/lib/components/Collapse/Collapse.d.ts +1 -1
- package/lib/components/Dialog/Dialog.d.ts +1 -1
- package/lib/components/Menu/MenuContextMenu/MenuContextMenu.d.ts +2 -0
- package/lib/components/Menu/MenuSub/MenuSub.d.ts +2 -0
- package/lib/components/Popover/PopoverContextMenu/PopoverContextMenu.d.ts +2 -0
- package/lib/utils/Floating/{create-context-menu-handlers.d.ts → use-context-menu-handlers.d.ts} +9 -2
- package/package.json +2 -2
- package/styles/Input.css +1 -1
- package/styles/Input.layer.css +1 -1
- package/styles/SegmentedControl.css +4 -1
- package/styles/SegmentedControl.layer.css +4 -1
- package/styles.css +5 -2
- package/styles.layer.css +5 -2
- package/cjs/utils/Floating/create-context-menu-handlers.cjs +0 -38
- package/cjs/utils/Floating/create-context-menu-handlers.cjs.map +0 -1
- package/esm/utils/Floating/create-context-menu-handlers.mjs +0 -38
- package/esm/utils/Floating/create-context-menu-handlers.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.module.mjs","names":[],"sources":["../../../src/components/Input/Input.module.css"],"sourcesContent":[".wrapper {\n position: relative;\n margin-top: var(--input-margin-top, 0rem);\n margin-bottom: var(--input-margin-bottom, 0rem);\n\n --input-height-xs: 30px;\n --input-height-sm: 36px;\n --input-height-md: 42px;\n --input-height-lg: 50px;\n --input-height-xl: 60px;\n\n --input-padding-y-xs: 5px;\n --input-padding-y-sm: 6px;\n --input-padding-y-md: 8px;\n --input-padding-y-lg: 10px;\n --input-padding-y-xl: 13px;\n\n --input-height: var(--input-height-sm);\n --input-radius: var(--mantine-radius-default);\n\n --input-cursor: text;\n --input-line-height: calc(var(--input-height) - rem(2px));\n --input-padding: calc(var(--input-height) / 3);\n --input-padding-inline-start: var(--input-padding);\n --input-padding-inline-end: var(--input-padding);\n --input-placeholder-color: var(--mantine-color-placeholder);\n --input-color: var(--mantine-color-text);\n --input-disabled-bg: var(--mantine-color-disabled);\n --input-disabled-color: var(--mantine-color-disabled-color);\n\n --input-left-section-size: var(--input-left-section-width, calc(var(--input-height) - rem(2px)));\n\n --input-right-section-size: var(\n --input-right-section-width,\n calc(var(--input-height) - rem(2px))\n );\n\n --input-size: var(--input-height);\n\n --section-y: 1px;\n --left-section-start: 1px;\n --left-section-border-radius: var(--input-radius) 0 0 var(--input-radius);\n\n --right-section-end: 1px;\n --right-section-border-radius: 0 var(--input-radius) var(--input-radius) 0;\n\n &[data-variant='unstyled'] {\n --input-padding: 0;\n --input-padding-y: 0;\n --input-padding-inline-start: 0;\n --input-padding-inline-end: 0;\n }\n\n &[data-pointer] {\n --input-cursor: pointer;\n }\n\n &[data-with-bottom-section] {\n --input-bottom-section-height: 28px;\n }\n\n &[data-multiline] {\n --input-padding-y-xs: 4.5px;\n --input-padding-y-sm: 5.5px;\n --input-padding-y-md: 7px;\n --input-padding-y-lg: 9.5px;\n --input-padding-y-xl: 13px;\n\n --input-size: auto;\n --input-line-height: var(--mantine-line-height);\n }\n\n &[data-with-left-section] {\n --input-padding-inline-start: var(--input-left-section-size);\n }\n\n &[data-with-right-section] {\n --input-padding-inline-end: var(--input-right-section-size);\n\n &:has([data-combined-clear-section]) {\n .wrapper[data-size='xs'] & {\n --input-padding-inline-end: 41px;\n }\n\n .wrapper[data-size='sm'] & {\n --input-padding-inline-end: 50px;\n }\n\n .wrapper[data-size='md'] & {\n --input-padding-inline-end: 60px;\n }\n\n .wrapper[data-size='lg'] & {\n --input-padding-inline-end: 72px;\n }\n\n .wrapper[data-size='xl'] & {\n --input-padding-inline-end: 89px;\n }\n }\n }\n\n @mixin light {\n &[data-variant='default'] {\n --input-bd: var(--mantine-color-gray-4);\n --input-bg: var(--mantine-color-white);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='filled'] {\n --input-bd: transparent;\n --input-bg: var(--mantine-color-gray-1);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='unstyled'] {\n --input-bd: transparent;\n --input-bg: transparent;\n --input-bd-focus: transparent;\n }\n }\n\n @mixin dark {\n &[data-variant='default'] {\n --input-bd: var(--mantine-color-dark-4);\n --input-bg: var(--mantine-color-dark-6);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='filled'] {\n --input-bd: transparent;\n --input-bg: var(--mantine-color-dark-5);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='unstyled'] {\n --input-bd: transparent;\n --input-bg: transparent;\n --input-bd-focus: transparent;\n }\n }\n\n [data-mantine-color-scheme] &[data-error] {\n &:not([data-variant='unstyled']) {\n --input-bd: var(--mantine-color-error);\n }\n\n --input-color: var(--mantine-color-error);\n --input-placeholder-color: var(--mantine-color-error);\n --input-section-color: var(--mantine-color-error);\n }\n\n @mixin where-rtl {\n --left-section-border-radius: 0 var(--input-radius) var(--input-radius) 0;\n --right-section-border-radius: var(--input-radius) 0 0 var(--input-radius);\n }\n\n &[dir='ltr'] {\n --left-section-border-radius: var(--input-radius) 0 0 var(--input-radius);\n --right-section-border-radius: 0 var(--input-radius) var(--input-radius) 0;\n }\n}\n\n.input {\n -webkit-tap-highlight-color: transparent;\n appearance: none;\n resize: var(--input-resize, none);\n display: block;\n width: 100%;\n transition: border-color 100ms ease;\n\n text-align: start;\n color: var(--input-color);\n border: rem(1px) solid var(--input-bd);\n background-color: var(--input-bg);\n font-family: var(--input-font-family, var(--mantine-font-family));\n height: var(--input-size);\n min-height: var(--input-height);\n line-height: var(--input-line-height);\n font-size: var(--_input-fz, var(--input-fz, var(--mantine-font-size-md)));\n border-radius: var(--input-radius);\n padding-inline-start: var(--input-padding-inline-start);\n padding-inline-end: var(--input-padding-inline-end);\n padding-top: var(--input-padding-y, 0rem);\n padding-bottom: var(--input-padding-y, 0rem);\n cursor: var(--input-cursor);\n overflow: var(--input-overflow);\n\n /* Used as data attribute in Textarea component, does not have associated prop on the Input component */\n &[data-no-overflow] {\n --input-overflow: hidden;\n }\n\n /* Used as data attribute in JsonInput component, does not have associated prop on the Input component */\n &[data-monospace] {\n --input-font-family: var(--mantine-font-family-monospace);\n --_input-fz: calc(var(--input-fz) - rem(2px));\n }\n\n &:focus,\n &:focus-within {\n outline: none;\n --input-bd: var(--input-bd-focus);\n\n [data-error] & {\n --input-bd: var(--mantine-color-error);\n }\n }\n\n &::placeholder {\n color: var(--input-placeholder-color);\n opacity: 1;\n }\n\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button,\n &::-webkit-search-decoration,\n &::-webkit-search-cancel-button,\n &::-webkit-search-results-button,\n &::-webkit-search-results-decoration {\n appearance: none;\n }\n\n &[type='number'] {\n -moz-appearance: textfield;\n }\n\n &:disabled,\n &[data-disabled] {\n cursor: not-allowed;\n opacity: 0.6;\n background-color: var(--input-disabled-bg);\n color: var(--input-disabled-color);\n }\n\n /* Required to be a separate selector to work in Firefox, can be merged with &:disabled once :has is supported */\n &:has(input:disabled) {\n cursor: not-allowed;\n opacity: 0.6;\n background-color: var(--input-disabled-bg);\n color: var(--input-disabled-color);\n }\n\n &[readonly] {\n caret-color: transparent;\n }\n\n [data-with-bottom-section] & {\n padding-bottom: calc(var(--input-padding-y, 0rem) + var(--input-bottom-section-height));\n }\n}\n\n.bottomSection {\n position: absolute;\n bottom: 1px;\n left: 1px;\n right: 1px;\n height: var(--input-bottom-section-height);\n display: flex;\n align-items: center;\n justify-content: flex-start;\n padding-inline: var(--input-padding);\n border-radius: 0 0 var(--input-radius) var(--input-radius);\n pointer-events: all;\n color: var(--mantine-color-dimmed);\n font-size: var(--input-fz, var(--mantine-font-size-sm));\n}\n\n.section {\n pointer-events: var(--section-pointer-events);\n position: absolute;\n z-index: 1;\n inset-inline-start: var(--section-start);\n inset-inline-end: var(--section-end);\n bottom: var(--section-y);\n top: var(--section-y);\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--section-size);\n border-radius: var(--section-border-radius);\n color: var(--input-section-color, var(--mantine-color-dimmed));\n\n &[data-position='right'] {\n --section-pointer-events: var(--input-right-section-pointer-events);\n --section-end: var(--right-section-end);\n --section-size: var(--input-right-section-size);\n --section-border-radius: var(--right-section-border-radius);\n\n &:has([data-combined-clear-section]) {\n .wrapper[data-size='xs'] & {\n --section-size: 41px;\n }\n\n .wrapper[data-size='sm'] & {\n --section-size: 50px;\n }\n\n .wrapper[data-size='md'] & {\n --section-size: 60px;\n }\n\n .wrapper[data-size='lg'] & {\n --section-size: 72px;\n }\n\n .wrapper[data-size='xl'] & {\n --section-size: 89px;\n }\n }\n }\n\n &[data-position='left'] {\n --section-pointer-events: var(--input-left-section-pointer-events);\n --section-start: var(--left-section-start);\n --section-size: var(--input-left-section-size);\n --section-border-radius: var(--left-section-border-radius);\n }\n}\n\n/* ----- Input.Placeholder ----- */\n.placeholder {\n color: var(--input-placeholder-color, var(--mantine-color-placeholder));\n\n [data-error] & {\n --input-placeholder-color: var(--input-color, var(--mantine-color-placeholder));\n }\n}\n\n/* ----- Input.Wrapper ----- */\n.root {\n line-height: var(--mantine-line-height);\n}\n\n.label {\n display: inline-block;\n font-weight: var(--mantine-font-weight-medium);\n overflow-wrap: break-word;\n cursor: default;\n -webkit-tap-highlight-color: transparent;\n font-size: var(--input-label-size, var(--mantine-font-size-sm));\n}\n\n.required {\n color: var(--input-asterisk-color, var(--mantine-color-error));\n}\n\n.error,\n.description {\n word-wrap: break-word;\n line-height: 1.2;\n display: block;\n margin: 0;\n padding: 0;\n}\n\n.error {\n color: var(--mantine-color-error);\n font-size: var(--input-error-size, calc(var(--mantine-font-size-sm) - rem(2px)));\n}\n\n.description {\n color: var(--mantine-color-dimmed);\n font-size: var(--input-description-size, calc(var(--mantine-font-size-sm) - rem(2px)));\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Input.module.mjs","names":[],"sources":["../../../src/components/Input/Input.module.css"],"sourcesContent":[".wrapper {\n position: relative;\n margin-top: var(--input-margin-top, 0rem);\n margin-bottom: var(--input-margin-bottom, 0rem);\n\n --input-height-xs: 30px;\n --input-height-sm: 36px;\n --input-height-md: 42px;\n --input-height-lg: 50px;\n --input-height-xl: 60px;\n\n --input-padding-y-xs: 5px;\n --input-padding-y-sm: 6px;\n --input-padding-y-md: 8px;\n --input-padding-y-lg: 10px;\n --input-padding-y-xl: 13px;\n\n --input-height: var(--input-height-sm);\n --input-radius: var(--mantine-radius-default);\n\n --input-cursor: text;\n --input-line-height: calc(var(--input-height) - rem(2px));\n --input-padding: calc(var(--input-height) / 3);\n --input-padding-inline-start: var(--input-padding);\n --input-padding-inline-end: var(--input-padding);\n --input-placeholder-color: var(--mantine-color-placeholder);\n --input-color: var(--mantine-color-text);\n --input-disabled-bg: var(--mantine-color-disabled);\n --input-disabled-color: var(--mantine-color-disabled-color);\n\n --input-left-section-size: var(--input-left-section-width, calc(var(--input-height) - rem(2px)));\n\n --input-right-section-size: var(\n --input-right-section-width,\n calc(var(--input-height) - rem(2px))\n );\n\n --input-size: var(--input-height);\n\n --section-y: 1px;\n --left-section-start: 1px;\n --left-section-border-radius: var(--input-radius) 0 0 var(--input-radius);\n\n --right-section-end: 1px;\n --right-section-border-radius: 0 var(--input-radius) var(--input-radius) 0;\n\n &[data-variant='unstyled'] {\n --input-padding: 0;\n --input-padding-y: 0;\n --input-padding-inline-start: 0;\n --input-padding-inline-end: 0;\n }\n\n &[data-pointer] {\n --input-cursor: pointer;\n }\n\n &[data-with-bottom-section] {\n --input-bottom-section-height: 28px;\n }\n\n &[data-multiline] {\n --input-padding-y-xs: 4.5px;\n --input-padding-y-sm: 5.5px;\n --input-padding-y-md: 7px;\n --input-padding-y-lg: 9.5px;\n --input-padding-y-xl: 13px;\n\n --input-size: auto;\n --input-line-height: var(--mantine-line-height);\n }\n\n &[data-with-left-section] {\n --input-padding-inline-start: var(--input-left-section-size);\n }\n\n &[data-with-right-section] {\n --input-padding-inline-end: var(--input-right-section-size);\n\n &:has([data-combined-clear-section]) {\n .wrapper[data-size='xs'] & {\n --input-padding-inline-end: 41px;\n }\n\n .wrapper[data-size='sm'] & {\n --input-padding-inline-end: 50px;\n }\n\n .wrapper[data-size='md'] & {\n --input-padding-inline-end: 60px;\n }\n\n .wrapper[data-size='lg'] & {\n --input-padding-inline-end: 72px;\n }\n\n .wrapper[data-size='xl'] & {\n --input-padding-inline-end: 89px;\n }\n }\n }\n\n @mixin light {\n &[data-variant='default'] {\n --input-bd: var(--mantine-color-gray-4);\n --input-bg: var(--mantine-color-white);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='filled'] {\n --input-bd: transparent;\n --input-bg: var(--mantine-color-gray-1);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='unstyled'] {\n --input-bd: transparent;\n --input-bg: transparent;\n --input-bd-focus: transparent;\n }\n }\n\n @mixin dark {\n &[data-variant='default'] {\n --input-bd: var(--mantine-color-dark-4);\n --input-bg: var(--mantine-color-dark-6);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='filled'] {\n --input-bd: transparent;\n --input-bg: var(--mantine-color-dark-5);\n --input-bd-focus: var(--mantine-primary-color-filled);\n }\n\n &[data-variant='unstyled'] {\n --input-bd: transparent;\n --input-bg: transparent;\n --input-bd-focus: transparent;\n }\n }\n\n [data-mantine-color-scheme] &[data-error] {\n &:not([data-variant='unstyled']) {\n --input-bd: var(--mantine-color-error);\n }\n\n --input-color: var(--mantine-color-error);\n --input-placeholder-color: var(--mantine-color-error);\n --input-section-color: var(--mantine-color-error);\n }\n\n @mixin where-rtl {\n --left-section-border-radius: 0 var(--input-radius) var(--input-radius) 0;\n --right-section-border-radius: var(--input-radius) 0 0 var(--input-radius);\n }\n\n &[dir='ltr'] {\n --left-section-border-radius: var(--input-radius) 0 0 var(--input-radius);\n --right-section-border-radius: 0 var(--input-radius) var(--input-radius) 0;\n }\n}\n\n.input {\n -webkit-tap-highlight-color: transparent;\n appearance: none;\n resize: var(--input-resize, none);\n display: block;\n width: 100%;\n transition: border-color 100ms ease;\n\n text-align: var(--input-text-align, start);\n color: var(--input-color);\n border: rem(1px) solid var(--input-bd);\n background-color: var(--input-bg);\n font-family: var(--input-font-family, var(--mantine-font-family));\n height: var(--input-size);\n min-height: var(--input-height);\n line-height: var(--input-line-height);\n font-size: var(--_input-fz, var(--input-fz, var(--mantine-font-size-md)));\n border-radius: var(--input-radius);\n padding-inline-start: var(--input-padding-inline-start);\n padding-inline-end: var(--input-padding-inline-end);\n padding-top: var(--input-padding-y, 0rem);\n padding-bottom: var(--input-padding-y, 0rem);\n cursor: var(--input-cursor);\n overflow: var(--input-overflow);\n\n /* Used as data attribute in Textarea component, does not have associated prop on the Input component */\n &[data-no-overflow] {\n --input-overflow: hidden;\n }\n\n /* Used as data attribute in JsonInput component, does not have associated prop on the Input component */\n &[data-monospace] {\n --input-font-family: var(--mantine-font-family-monospace);\n --_input-fz: calc(var(--input-fz) - rem(2px));\n }\n\n &:focus,\n &:focus-within {\n outline: none;\n --input-bd: var(--input-bd-focus);\n\n [data-error] & {\n --input-bd: var(--mantine-color-error);\n }\n }\n\n &::placeholder {\n color: var(--input-placeholder-color);\n opacity: 1;\n }\n\n &::-webkit-inner-spin-button,\n &::-webkit-outer-spin-button,\n &::-webkit-search-decoration,\n &::-webkit-search-cancel-button,\n &::-webkit-search-results-button,\n &::-webkit-search-results-decoration {\n appearance: none;\n }\n\n &[type='number'] {\n -moz-appearance: textfield;\n }\n\n &:disabled,\n &[data-disabled] {\n cursor: not-allowed;\n opacity: 0.6;\n background-color: var(--input-disabled-bg);\n color: var(--input-disabled-color);\n }\n\n /* Required to be a separate selector to work in Firefox, can be merged with &:disabled once :has is supported */\n &:has(input:disabled) {\n cursor: not-allowed;\n opacity: 0.6;\n background-color: var(--input-disabled-bg);\n color: var(--input-disabled-color);\n }\n\n &[readonly] {\n caret-color: transparent;\n }\n\n [data-with-bottom-section] & {\n padding-bottom: calc(var(--input-padding-y, 0rem) + var(--input-bottom-section-height));\n }\n}\n\n.bottomSection {\n position: absolute;\n bottom: 1px;\n left: 1px;\n right: 1px;\n height: var(--input-bottom-section-height);\n display: flex;\n align-items: center;\n justify-content: flex-start;\n padding-inline: var(--input-padding);\n border-radius: 0 0 var(--input-radius) var(--input-radius);\n pointer-events: all;\n color: var(--mantine-color-dimmed);\n font-size: var(--input-fz, var(--mantine-font-size-sm));\n}\n\n.section {\n pointer-events: var(--section-pointer-events);\n position: absolute;\n z-index: 1;\n inset-inline-start: var(--section-start);\n inset-inline-end: var(--section-end);\n bottom: var(--section-y);\n top: var(--section-y);\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--section-size);\n border-radius: var(--section-border-radius);\n color: var(--input-section-color, var(--mantine-color-dimmed));\n\n &[data-position='right'] {\n --section-pointer-events: var(--input-right-section-pointer-events);\n --section-end: var(--right-section-end);\n --section-size: var(--input-right-section-size);\n --section-border-radius: var(--right-section-border-radius);\n\n &:has([data-combined-clear-section]) {\n .wrapper[data-size='xs'] & {\n --section-size: 41px;\n }\n\n .wrapper[data-size='sm'] & {\n --section-size: 50px;\n }\n\n .wrapper[data-size='md'] & {\n --section-size: 60px;\n }\n\n .wrapper[data-size='lg'] & {\n --section-size: 72px;\n }\n\n .wrapper[data-size='xl'] & {\n --section-size: 89px;\n }\n }\n }\n\n &[data-position='left'] {\n --section-pointer-events: var(--input-left-section-pointer-events);\n --section-start: var(--left-section-start);\n --section-size: var(--input-left-section-size);\n --section-border-radius: var(--left-section-border-radius);\n }\n}\n\n/* ----- Input.Placeholder ----- */\n.placeholder {\n color: var(--input-placeholder-color, var(--mantine-color-placeholder));\n\n [data-error] & {\n --input-placeholder-color: var(--input-color, var(--mantine-color-placeholder));\n }\n}\n\n/* ----- Input.Wrapper ----- */\n.root {\n line-height: var(--mantine-line-height);\n}\n\n.label {\n display: inline-block;\n font-weight: var(--mantine-font-weight-medium);\n overflow-wrap: break-word;\n cursor: default;\n -webkit-tap-highlight-color: transparent;\n font-size: var(--input-label-size, var(--mantine-font-size-sm));\n}\n\n.required {\n color: var(--input-asterisk-color, var(--mantine-color-error));\n}\n\n.error,\n.description {\n word-wrap: break-word;\n line-height: 1.2;\n display: block;\n margin: 0;\n padding: 0;\n}\n\n.error {\n color: var(--mantine-color-error);\n font-size: var(--input-error-size, calc(var(--mantine-font-size-sm) - rem(2px)));\n}\n\n.description {\n color: var(--mantine-color-dimmed);\n font-size: var(--input-description-size, calc(var(--mantine-font-size-sm) - rem(2px)));\n}\n"],"mappings":""}
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
import { getSingleElementChild } from "../../../core/utils/get-single-element-child/get-single-element-child.mjs";
|
|
3
3
|
import { useProps } from "../../../core/MantineProvider/use-props/use-props.mjs";
|
|
4
4
|
import { usePopoverContext } from "../../Popover/Popover.context.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { useContextMenuHandlers } from "../../../utils/Floating/use-context-menu-handlers.mjs";
|
|
6
6
|
import { useMenuContext } from "../Menu.context.mjs";
|
|
7
7
|
import { cloneElement } from "react";
|
|
8
8
|
//#region packages/@mantine/core/src/components/Menu/MenuContextMenu/MenuContextMenu.tsx
|
|
9
9
|
function MenuContextMenu(props) {
|
|
10
|
-
const { children, disabled } = useProps("MenuContextMenu", null, props);
|
|
10
|
+
const { children, disabled, longPressDelay } = useProps("MenuContextMenu", null, props);
|
|
11
11
|
const child = getSingleElementChild(children);
|
|
12
12
|
if (!child) throw new Error("Menu.ContextMenu component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported");
|
|
13
13
|
const ctx = useMenuContext();
|
|
14
14
|
const popoverCtx = usePopoverContext();
|
|
15
|
-
return cloneElement(child,
|
|
15
|
+
return cloneElement(child, useContextMenuHandlers({
|
|
16
16
|
childProps: child.props,
|
|
17
17
|
disabled: disabled || popoverCtx.disabled,
|
|
18
18
|
opened: ctx.opened,
|
|
19
|
+
longPressDelay,
|
|
19
20
|
setReference: popoverCtx.reference,
|
|
20
21
|
open: () => ctx.openDropdown()
|
|
21
22
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuContextMenu.mjs","names":[],"sources":["../../../../src/components/Menu/MenuContextMenu/MenuContextMenu.tsx"],"sourcesContent":["import { cloneElement } from 'react';\nimport { getSingleElementChild, useProps } from '../../../core';\nimport {
|
|
1
|
+
{"version":3,"file":"MenuContextMenu.mjs","names":[],"sources":["../../../../src/components/Menu/MenuContextMenu/MenuContextMenu.tsx"],"sourcesContent":["import { cloneElement } from 'react';\nimport { getSingleElementChild, useProps } from '../../../core';\nimport { useContextMenuHandlers } from '../../../utils/Floating/use-context-menu-handlers';\nimport { usePopoverContext } from '../../Popover';\nimport { useMenuContext } from '../Menu.context';\n\nexport interface MenuContextMenuProps {\n /** Element that opens the menu when right-clicked. Menu dropdown is positioned at the cursor. The trigger element must not call `event.preventDefault()` in its own `onContextMenu` handler, otherwise the native context menu is not suppressed. */\n children: React.ReactNode;\n\n /** If set, the right-click trigger is disabled and the browser's default context menu is shown */\n disabled?: boolean;\n\n /** Delay in ms before a touch long-press opens the dropdown on touch devices, `500` by default */\n longPressDelay?: number;\n}\n\nexport function MenuContextMenu(props: MenuContextMenuProps) {\n const { children, disabled, longPressDelay } = useProps('MenuContextMenu', null, props);\n\n const child = getSingleElementChild(children);\n if (!child) {\n throw new Error(\n 'Menu.ContextMenu component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported'\n );\n }\n\n const ctx = useMenuContext();\n const popoverCtx = usePopoverContext();\n\n const handlers = useContextMenuHandlers({\n childProps: child.props as any,\n disabled: disabled || popoverCtx.disabled,\n opened: ctx.opened,\n longPressDelay,\n setReference: popoverCtx.reference as unknown as (node: object) => void,\n open: () => ctx.openDropdown(),\n });\n\n return cloneElement(child, handlers as any);\n}\n\nMenuContextMenu.displayName = '@mantine/core/MenuContextMenu';\n"],"mappings":";;;;;;;;AAiBA,SAAgB,gBAAgB,OAA6B;CAC3D,MAAM,EAAE,UAAU,UAAU,mBAAmB,SAAS,mBAAmB,MAAM,KAAK;CAEtF,MAAM,QAAQ,sBAAsB,QAAQ;CAC5C,IAAI,CAAC,OACH,MAAM,IAAI,MACR,oKACF;CAGF,MAAM,MAAM,eAAe;CAC3B,MAAM,aAAa,kBAAkB;CAWrC,OAAO,aAAa,OATH,uBAAuB;EACtC,YAAY,MAAM;EAClB,UAAU,YAAY,WAAW;EACjC,QAAQ,IAAI;EACZ;EACA,cAAc,WAAW;EACzB,YAAY,IAAI,aAAa;CAC/B,CAEkC,CAAQ;AAC5C;AAEA,gBAAgB,cAAc"}
|
|
@@ -8,8 +8,8 @@ import { SubMenuContext } from "./MenuSub.context.mjs";
|
|
|
8
8
|
import { MenuSubDropdown } from "../MenuSubDropdown/MenuSubDropdown.mjs";
|
|
9
9
|
import { MenuSubItem } from "../MenuSubItem/MenuSubItem.mjs";
|
|
10
10
|
import { MenuSubTarget } from "../MenuSubTarget/MenuSubTarget.mjs";
|
|
11
|
-
import { use, useCallback, useRef } from "react";
|
|
12
|
-
import {
|
|
11
|
+
import { use, useCallback, useEffect, useRef } from "react";
|
|
12
|
+
import { useId as useId$1, useUncontrolled } from "@mantine/hooks";
|
|
13
13
|
import { jsx } from "react/jsx-runtime";
|
|
14
14
|
import { safePolygon, useFloating, useHover, useInteractions } from "@floating-ui/react";
|
|
15
15
|
//#region packages/@mantine/core/src/components/Menu/MenuSub/MenuSub.tsx
|
|
@@ -22,15 +22,18 @@ const defaultProps = {
|
|
|
22
22
|
middlewares: { shift: { crossAxis: true } }
|
|
23
23
|
};
|
|
24
24
|
function MenuSub(_props) {
|
|
25
|
-
const { children, closeDelay, openDelay, position, safeAreaPolygon, ...others } = useProps("MenuSub", defaultProps, _props);
|
|
25
|
+
const { children, closeDelay, openDelay, position, safeAreaPolygon, opened: openedProp, onChange, ...others } = useProps("MenuSub", defaultProps, _props);
|
|
26
26
|
const id = useId$1();
|
|
27
|
-
const [opened,
|
|
27
|
+
const [opened, setOpened] = useUncontrolled({
|
|
28
|
+
value: openedProp,
|
|
29
|
+
finalValue: false,
|
|
30
|
+
onChange
|
|
31
|
+
});
|
|
28
32
|
const parentSubCtx = use(SubMenuContext);
|
|
29
33
|
const menuCtx = useMenuContext();
|
|
30
34
|
const { dir } = useDirection();
|
|
31
35
|
const resolvedPosition = getFloatingPosition(dir, position);
|
|
32
36
|
const levelRegister = parentSubCtx?.registerOpenSub ?? menuCtx.registerOpenSub;
|
|
33
|
-
const unregisterRef = useRef(null);
|
|
34
37
|
const activeChildCloseRef = useRef(null);
|
|
35
38
|
const registerOpenSub = useCallback((closeFn) => {
|
|
36
39
|
const prev = activeChildCloseRef.current;
|
|
@@ -40,19 +43,18 @@ function MenuSub(_props) {
|
|
|
40
43
|
if (activeChildCloseRef.current === closeFn) activeChildCloseRef.current = null;
|
|
41
44
|
};
|
|
42
45
|
}, []);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
const setOpenedRef = useRef(setOpened);
|
|
47
|
+
setOpenedRef.current = setOpened;
|
|
48
|
+
const handleOpen = useCallback(() => setOpenedRef.current(true), []);
|
|
49
|
+
const handleClose = useCallback(() => setOpenedRef.current(false), []);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!opened) return;
|
|
52
|
+
return levelRegister(handleClose);
|
|
46
53
|
}, [
|
|
47
|
-
|
|
54
|
+
opened,
|
|
48
55
|
levelRegister,
|
|
49
|
-
|
|
56
|
+
handleClose
|
|
50
57
|
]);
|
|
51
|
-
const handleClose = useCallback(() => {
|
|
52
|
-
unregisterRef.current?.();
|
|
53
|
-
unregisterRef.current = null;
|
|
54
|
-
close();
|
|
55
|
-
}, [close]);
|
|
56
58
|
const { context, refs } = useFloating({
|
|
57
59
|
placement: resolvedPosition,
|
|
58
60
|
open: opened,
|
|
@@ -90,6 +92,7 @@ function MenuSub(_props) {
|
|
|
90
92
|
},
|
|
91
93
|
children: /* @__PURE__ */ jsx(Popover, {
|
|
92
94
|
opened,
|
|
95
|
+
onChange: (nextOpened) => nextOpened ? handleOpen() : handleClose(),
|
|
93
96
|
withinPortal: false,
|
|
94
97
|
withArrow: false,
|
|
95
98
|
id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuSub.mjs","names":["useId"],"sources":["../../../../src/components/Menu/MenuSub/MenuSub.tsx"],"sourcesContent":["import { use, useCallback, useRef } from 'react';\nimport {\n safePolygon,\n useFloating,\n useHover,\n useInteractions,\n type SafePolygonOptions,\n} from '@floating-ui/react';\nimport {
|
|
1
|
+
{"version":3,"file":"MenuSub.mjs","names":["useId"],"sources":["../../../../src/components/Menu/MenuSub/MenuSub.tsx"],"sourcesContent":["import { use, useCallback, useEffect, useRef } from 'react';\nimport {\n safePolygon,\n useFloating,\n useHover,\n useInteractions,\n type SafePolygonOptions,\n} from '@floating-ui/react';\nimport { useId, useUncontrolled } from '@mantine/hooks';\nimport { ExtendComponent, Factory, useDirection, useProps } from '../../../core';\nimport {\n FloatingAxesOffsets,\n FloatingPosition,\n getFloatingPosition,\n} from '../../../utils/Floating';\nimport { __PopoverProps, Popover } from '../../Popover';\nimport { TransitionOverride } from '../../Transition';\nimport { useMenuContext } from '../Menu.context';\nimport { MenuSubDropdown } from '../MenuSubDropdown/MenuSubDropdown';\nimport { MenuSubItem } from '../MenuSubItem/MenuSubItem';\nimport { MenuSubTarget } from '../MenuSubTarget/MenuSubTarget';\nimport { SubMenuContext } from './MenuSub.context';\n\nexport type MenuSubFactory = Factory<{\n props: MenuSubProps;\n}>;\n\nexport interface MenuSubProps extends __PopoverProps {\n children: React.ReactNode;\n\n /** Controlled opened state */\n opened?: boolean;\n\n /** Called with current state when dropdown opens or closes */\n onChange?: (opened: boolean) => void;\n\n /** Open delay in ms, applicable when hover trigger is used */\n openDelay?: number;\n\n /** Close delay in ms, applicable when hover trigger is used */\n closeDelay?: number;\n\n /** Dropdown position relative to the target element @default 'right-start' */\n position?: FloatingPosition;\n\n /** Offset of the dropdown element @default 0 */\n offset?: number | FloatingAxesOffsets;\n\n /** Props passed down to the `Transition` component that used to animate dropdown presence, use to configure duration and animation type @default { duration: 0 } */\n transitionProps?: TransitionOverride;\n\n /** Determines whether submenu stays open while the cursor moves toward its dropdown. Pass an object to configure safe polygon behavior. @default true */\n safeAreaPolygon?: boolean | SafePolygonOptions;\n}\n\nconst defaultProps = {\n offset: 0,\n position: 'right-start',\n safeAreaPolygon: true,\n transitionProps: { duration: 0 },\n openDelay: 0,\n middlewares: {\n shift: {\n // Enable crossAxis shift to keep submenu dropdown within viewport bounds when positioned horizontally\n crossAxis: true,\n },\n },\n} satisfies Partial<MenuSubProps>;\n\nexport function MenuSub(_props: MenuSubProps) {\n const {\n children,\n closeDelay,\n openDelay,\n position,\n safeAreaPolygon,\n opened: openedProp,\n onChange,\n ...others\n } = useProps('MenuSub', defaultProps, _props);\n const id = useId();\n const [opened, setOpened] = useUncontrolled({\n value: openedProp,\n finalValue: false,\n onChange,\n });\n const parentSubCtx = use(SubMenuContext);\n const menuCtx = useMenuContext();\n const { dir } = useDirection();\n const resolvedPosition = getFloatingPosition(dir, position);\n\n const levelRegister = parentSubCtx?.registerOpenSub ?? menuCtx.registerOpenSub;\n\n const activeChildCloseRef = useRef<(() => void) | null>(null);\n const registerOpenSub = useCallback((closeFn: () => void) => {\n const prev = activeChildCloseRef.current;\n if (prev && prev !== closeFn) {\n prev();\n }\n activeChildCloseRef.current = closeFn;\n return () => {\n if (activeChildCloseRef.current === closeFn) {\n activeChildCloseRef.current = null;\n }\n };\n }, []);\n\n const setOpenedRef = useRef(setOpened);\n setOpenedRef.current = setOpened;\n\n const handleOpen = useCallback(() => setOpenedRef.current(true), []);\n const handleClose = useCallback(() => setOpenedRef.current(false), []);\n\n useEffect(() => {\n if (!opened) {\n return undefined;\n }\n\n return levelRegister(handleClose);\n }, [opened, levelRegister, handleClose]);\n\n const { context, refs } = useFloating({\n placement: resolvedPosition,\n open: opened,\n onOpenChange: (nextOpen) => {\n if (nextOpen) {\n handleOpen();\n } else {\n handleClose();\n }\n },\n });\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useHover(context, {\n handleClose: safeAreaPolygon\n ? safePolygon(typeof safeAreaPolygon === 'object' ? safeAreaPolygon : undefined)\n : undefined,\n delay: { open: openDelay, close: closeDelay },\n }),\n ]);\n\n const focusFirstItem = () =>\n window.setTimeout(() => {\n document\n .getElementById(`${id}-dropdown`)\n ?.querySelectorAll<HTMLButtonElement>('[data-menu-item]:not([data-disabled])')[0]\n ?.focus();\n }, 16);\n\n const focusParentItem = () =>\n window.setTimeout(() => {\n document.getElementById(`${id}-target`)?.focus();\n }, 16);\n\n return (\n <SubMenuContext\n value={{\n opened,\n close: handleClose,\n open: handleOpen,\n focusFirstItem,\n focusParentItem,\n parentContext: parentSubCtx,\n setReference: refs.setReference,\n setFloating: refs.setFloating,\n getReferenceProps,\n getFloatingProps,\n registerOpenSub,\n }}\n >\n <Popover\n opened={opened}\n onChange={(nextOpened) => (nextOpened ? handleOpen() : handleClose())}\n withinPortal={false}\n withArrow={false}\n id={id}\n position={position}\n {...others}\n >\n {children}\n </Popover>\n </SubMenuContext>\n );\n}\n\nMenuSub.extend = (input: ExtendComponent<MenuSubFactory>) => input;\nMenuSub.displayName = '@mantine/core/MenuSub';\nMenuSub.Target = MenuSubTarget;\nMenuSub.Dropdown = MenuSubDropdown;\nMenuSub.Item = MenuSubItem;\n"],"mappings":";;;;;;;;;;;;;;;AAuDA,MAAM,eAAe;CACnB,QAAQ;CACR,UAAU;CACV,iBAAiB;CACjB,iBAAiB,EAAE,UAAU,EAAE;CAC/B,WAAW;CACX,aAAa,EACX,OAAO,EAEL,WAAW,KACb,EACF;AACF;AAEA,SAAgB,QAAQ,QAAsB;CAC5C,MAAM,EACJ,UACA,YACA,WACA,UACA,iBACA,QAAQ,YACR,UACA,GAAG,WACD,SAAS,WAAW,cAAc,MAAM;CAC5C,MAAM,KAAKA,QAAM;CACjB,MAAM,CAAC,QAAQ,aAAa,gBAAgB;EAC1C,OAAO;EACP,YAAY;EACZ;CACF,CAAC;CACD,MAAM,eAAe,IAAI,cAAc;CACvC,MAAM,UAAU,eAAe;CAC/B,MAAM,EAAE,QAAQ,aAAa;CAC7B,MAAM,mBAAmB,oBAAoB,KAAK,QAAQ;CAE1D,MAAM,gBAAgB,cAAc,mBAAmB,QAAQ;CAE/D,MAAM,sBAAsB,OAA4B,IAAI;CAC5D,MAAM,kBAAkB,aAAa,YAAwB;EAC3D,MAAM,OAAO,oBAAoB;EACjC,IAAI,QAAQ,SAAS,SACnB,KAAK;EAEP,oBAAoB,UAAU;EAC9B,aAAa;GACX,IAAI,oBAAoB,YAAY,SAClC,oBAAoB,UAAU;EAElC;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,eAAe,OAAO,SAAS;CACrC,aAAa,UAAU;CAEvB,MAAM,aAAa,kBAAkB,aAAa,QAAQ,IAAI,GAAG,CAAC,CAAC;CACnE,MAAM,cAAc,kBAAkB,aAAa,QAAQ,KAAK,GAAG,CAAC,CAAC;CAErE,gBAAgB;EACd,IAAI,CAAC,QACH;EAGF,OAAO,cAAc,WAAW;CAClC,GAAG;EAAC;EAAQ;EAAe;CAAW,CAAC;CAEvC,MAAM,EAAE,SAAS,SAAS,YAAY;EACpC,WAAW;EACX,MAAM;EACN,eAAe,aAAa;GAC1B,IAAI,UACF,WAAW;QAEX,YAAY;EAEhB;CACF,CAAC;CAED,MAAM,EAAE,mBAAmB,qBAAqB,gBAAgB,CAC9D,SAAS,SAAS;EAChB,aAAa,kBACT,YAAY,OAAO,oBAAoB,WAAW,kBAAkB,KAAA,CAAS,IAC7E,KAAA;EACJ,OAAO;GAAE,MAAM;GAAW,OAAO;EAAW;CAC9C,CAAC,CACH,CAAC;CAED,MAAM,uBACJ,OAAO,iBAAiB;EACtB,SACG,eAAe,GAAG,GAAG,UAAU,GAC9B,iBAAoC,uCAAuC,EAAE,IAC7E,MAAM;CACZ,GAAG,EAAE;CAEP,MAAM,wBACJ,OAAO,iBAAiB;EACtB,SAAS,eAAe,GAAG,GAAG,QAAQ,GAAG,MAAM;CACjD,GAAG,EAAE;CAEP,OACE,oBAAC,gBAAD;EACE,OAAO;GACL;GACA,OAAO;GACP,MAAM;GACN;GACA;GACA,eAAe;GACf,cAAc,KAAK;GACnB,aAAa,KAAK;GAClB;GACA;GACA;EACF;YAEA,oBAAC,SAAD;GACU;GACR,WAAW,eAAgB,aAAa,WAAW,IAAI,YAAY;GACnE,cAAc;GACd,WAAW;GACP;GACM;GACV,GAAI;GAEH;EACM,CAAA;CACK,CAAA;AAEpB;AAEA,QAAQ,UAAU,UAA2C;AAC7D,QAAQ,cAAc;AACtB,QAAQ,SAAS;AACjB,QAAQ,WAAW;AACnB,QAAQ,OAAO"}
|
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
import { getSingleElementChild } from "../../../core/utils/get-single-element-child/get-single-element-child.mjs";
|
|
3
3
|
import { useProps } from "../../../core/MantineProvider/use-props/use-props.mjs";
|
|
4
4
|
import { usePopoverContext } from "../Popover.context.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { useContextMenuHandlers } from "../../../utils/Floating/use-context-menu-handlers.mjs";
|
|
6
6
|
import { cloneElement } from "react";
|
|
7
7
|
//#region packages/@mantine/core/src/components/Popover/PopoverContextMenu/PopoverContextMenu.tsx
|
|
8
8
|
function PopoverContextMenu(props) {
|
|
9
|
-
const { children, disabled } = useProps("PopoverContextMenu", null, props);
|
|
9
|
+
const { children, disabled, longPressDelay } = useProps("PopoverContextMenu", null, props);
|
|
10
10
|
const child = getSingleElementChild(children);
|
|
11
11
|
if (!child) throw new Error("Popover.ContextMenu component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported");
|
|
12
12
|
const ctx = usePopoverContext();
|
|
13
|
-
return cloneElement(child,
|
|
13
|
+
return cloneElement(child, useContextMenuHandlers({
|
|
14
14
|
childProps: child.props,
|
|
15
15
|
disabled: disabled || ctx.disabled,
|
|
16
16
|
opened: ctx.opened,
|
|
17
|
+
longPressDelay,
|
|
17
18
|
setReference: ctx.reference,
|
|
18
19
|
open: () => {
|
|
19
20
|
if (!ctx.opened) ctx.onToggle();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PopoverContextMenu.mjs","names":[],"sources":["../../../../src/components/Popover/PopoverContextMenu/PopoverContextMenu.tsx"],"sourcesContent":["import { cloneElement } from 'react';\nimport { getSingleElementChild, useProps } from '../../../core';\nimport {
|
|
1
|
+
{"version":3,"file":"PopoverContextMenu.mjs","names":[],"sources":["../../../../src/components/Popover/PopoverContextMenu/PopoverContextMenu.tsx"],"sourcesContent":["import { cloneElement } from 'react';\nimport { getSingleElementChild, useProps } from '../../../core';\nimport { useContextMenuHandlers } from '../../../utils/Floating/use-context-menu-handlers';\nimport { usePopoverContext } from '../Popover.context';\n\nexport interface PopoverContextMenuProps {\n /** Element that opens the popover when right-clicked. Dropdown is positioned at the cursor. The trigger element must not call `event.preventDefault()` in its own `onContextMenu` handler, otherwise the native context menu is not suppressed. */\n children: React.ReactNode;\n\n /** If set, the right-click trigger is disabled and the browser's default context menu is shown */\n disabled?: boolean;\n\n /** Delay in ms before a touch long-press opens the dropdown on touch devices, `500` by default */\n longPressDelay?: number;\n}\n\nexport function PopoverContextMenu(props: PopoverContextMenuProps) {\n const { children, disabled, longPressDelay } = useProps('PopoverContextMenu', null, props);\n\n const child = getSingleElementChild(children);\n if (!child) {\n throw new Error(\n 'Popover.ContextMenu component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported'\n );\n }\n\n const ctx = usePopoverContext();\n\n const handlers = useContextMenuHandlers({\n childProps: child.props as any,\n disabled: disabled || ctx.disabled,\n opened: ctx.opened,\n longPressDelay,\n setReference: ctx.reference as unknown as (node: object) => void,\n open: () => {\n if (!ctx.opened) {\n ctx.onToggle();\n }\n },\n });\n\n return cloneElement(child, handlers as any);\n}\n\nPopoverContextMenu.displayName = '@mantine/core/PopoverContextMenu';\n"],"mappings":";;;;;;;AAgBA,SAAgB,mBAAmB,OAAgC;CACjE,MAAM,EAAE,UAAU,UAAU,mBAAmB,SAAS,sBAAsB,MAAM,KAAK;CAEzF,MAAM,QAAQ,sBAAsB,QAAQ;CAC5C,IAAI,CAAC,OACH,MAAM,IAAI,MACR,uKACF;CAGF,MAAM,MAAM,kBAAkB;CAe9B,OAAO,aAAa,OAbH,uBAAuB;EACtC,YAAY,MAAM;EAClB,UAAU,YAAY,IAAI;EAC1B,QAAQ,IAAI;EACZ;EACA,cAAc,IAAI;EAClB,YAAY;GACV,IAAI,CAAC,IAAI,QACP,IAAI,SAAS;EAEjB;CACF,CAEkC,CAAQ;AAC5C;AAEA,mBAAmB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl.module.mjs","names":[],"sources":["../../../src/components/SegmentedControl/SegmentedControl.module.css"],"sourcesContent":[".root {\n --sc-padding-xs: 2px 6px;\n --sc-padding-sm: 3px 10px;\n --sc-padding-md: 4px 14px;\n --sc-padding-lg: 7px 16px;\n --sc-padding-xl: 10px 20px;\n\n --sc-transition-duration: 200ms;\n --sc-padding: var(--sc-padding-sm);\n --sc-transition-timing-function: ease;\n --sc-font-size: var(--mantine-font-size-sm);\n\n position: relative;\n display: inline-flex;\n flex-direction: row;\n width: auto;\n border-radius: var(--sc-radius, var(--mantine-radius-default));\n overflow: hidden;\n padding: 4px;\n\n &:where([data-full-width]) {\n display: flex;\n }\n\n &:where([data-orientation='vertical']) {\n display: flex;\n flex-direction: column;\n width: max-content;\n\n &:where([data-full-width]) {\n width: auto;\n }\n }\n\n @mixin where-light {\n background-color: var(--mantine-color-gray-1);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-8);\n }\n}\n\n.indicator {\n position: absolute;\n display: block;\n z-index: 1;\n border-radius: calc(var(--sc-radius, var(--mantine-radius-default)) - 4px);\n\n @mixin where-light {\n box-shadow: var(--sc-shadow, none);\n background-color: var(--sc-color, var(--mantine-color-white));\n }\n\n @mixin where-dark {\n box-shadow: none;\n background-color: var(--sc-color, var(--mantine-color-dark-5));\n }\n}\n\n.label {\n -webkit-tap-highlight-color: transparent;\n font-weight: var(--mantine-font-weight-medium);\n display: block;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n user-select: none;\n border-radius: calc(var(--sc-radius, var(--mantine-radius-default)) - 4px);\n font-size: var(--sc-font-size);\n padding: var(--sc-padding);\n transition: color var(--sc-transition-duration) var(--sc-transition-timing-function);\n cursor: pointer;\n\n /* outline is controlled by .input */\n outline: var(--segmented-control-outline, none);\n\n @mixin where-light {\n color: var(--mantine-color-gray-7);\n }\n\n @mixin where-dark {\n color: var(--mantine-color-dark-1);\n }\n\n &:where([data-read-only]) {\n cursor: default;\n }\n\n fieldset:disabled &,\n &:where([data-disabled]) {\n cursor: not-allowed;\n color: var(--mantine-color-disabled-color);\n }\n\n &:where([data-active]) {\n @mixin where-light {\n color: var(--sc-label-color, var(--mantine-color-black));\n }\n\n @mixin where-dark {\n color: var(--sc-label-color, var(--mantine-color-white));\n }\n\n &::before {\n .root:where([data-initialized]) & {\n display: none;\n }\n content: '';\n inset: 0;\n z-index: 0;\n position: absolute;\n border-radius: calc(var(--sc-radius, var(--mantine-radius-default)) - 4px);\n\n @mixin where-light {\n box-shadow: var(--sc-shadow, none);\n background-color: var(--sc-color, var(--mantine-color-white));\n }\n\n @mixin where-dark {\n box-shadow: none;\n background-color: var(--sc-color, var(--mantine-color-dark-5));\n }\n }\n }\n\n &:where(:not([data-disabled], [data-active], [data-read-only])) {\n @mixin hover {\n @mixin where-light {\n color: var(--mantine-color-black);\n }\n\n @mixin where-dark {\n color: var(--mantine-color-white);\n }\n }\n }\n\n fieldset:disabled & {\n @mixin hover {\n color: var(--mantine-color-disabled-color) !important;\n }\n }\n}\n\n.input {\n height: 0;\n width: 0;\n position: absolute;\n overflow: hidden;\n white-space: nowrap;\n opacity: 0;\n\n &[data-focus-ring='auto'] {\n &:focus:focus-visible {\n & + .label {\n --segmented-control-outline: 2px solid var(--mantine-primary-color-filled);\n }\n }\n }\n\n &[data-focus-ring='always'] {\n &:focus {\n & + .label {\n --segmented-control-outline: 2px solid var(--mantine-primary-color-filled);\n }\n }\n }\n}\n\n.control {\n position: relative;\n flex: 1;\n z-index: 2;\n transition: border-color var(--sc-transition-duration) var(--sc-transition-timing-function);\n\n .root[data-with-items-borders] :where(&)::before {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n inset-inline-start: 0;\n background-color: var(--separator-color);\n width: 1px;\n transition: background-color var(--sc-transition-duration) var(--sc-transition-timing-function);\n }\n\n &[data-orientation='vertical'] {\n &::before {\n top: 0;\n inset-inline: 0;\n bottom: auto;\n height: 1px;\n width: auto;\n }\n }\n\n @mixin where-light {\n --separator-color: var(--mantine-color-gray-3);\n }\n\n @mixin where-dark {\n --separator-color: var(--mantine-color-dark-4);\n }\n\n &:first-of-type {\n &::before {\n --separator-color: transparent;\n }\n }\n\n &[data-active] {\n [data-mantine-color-scheme] & {\n &,\n & + .control {\n &::before {\n --separator-color: transparent;\n }\n }\n }\n }\n}\n\n.innerLabel {\n position: relative;\n z-index: 2;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"SegmentedControl.module.mjs","names":[],"sources":["../../../src/components/SegmentedControl/SegmentedControl.module.css"],"sourcesContent":[".root {\n --sc-padding-xs: 2px 6px;\n --sc-padding-sm: 3px 10px;\n --sc-padding-md: 4px 14px;\n --sc-padding-lg: 7px 16px;\n --sc-padding-xl: 10px 20px;\n\n --sc-transition-duration: 200ms;\n --sc-padding: var(--sc-padding-sm);\n --sc-transition-timing-function: ease;\n --sc-font-size: var(--mantine-font-size-sm);\n\n position: relative;\n display: inline-flex;\n flex-direction: row;\n width: auto;\n border-radius: var(--sc-radius, var(--mantine-radius-default));\n overflow: hidden;\n padding: 4px;\n\n &:where([data-full-width]) {\n display: flex;\n }\n\n &:where([data-orientation='vertical']) {\n display: flex;\n flex-direction: column;\n width: max-content;\n\n &:where([data-full-width]) {\n width: auto;\n }\n }\n\n @mixin where-light {\n background-color: var(--mantine-color-gray-1);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-8);\n }\n}\n\n.indicator {\n position: absolute;\n display: block;\n z-index: 1;\n border-radius: max(\n calc(var(--sc-radius, var(--mantine-radius-default)) - 4px),\n calc(var(--sc-radius, var(--mantine-radius-default)) / 4)\n );\n\n @mixin where-light {\n box-shadow: var(--sc-shadow, none);\n background-color: var(--sc-color, var(--mantine-color-white));\n }\n\n @mixin where-dark {\n box-shadow: none;\n background-color: var(--sc-color, var(--mantine-color-dark-5));\n }\n}\n\n.label {\n -webkit-tap-highlight-color: transparent;\n font-weight: var(--mantine-font-weight-medium);\n display: block;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n user-select: none;\n border-radius: calc(var(--sc-radius, var(--mantine-radius-default)) - 4px);\n font-size: var(--sc-font-size);\n padding: var(--sc-padding);\n transition: color var(--sc-transition-duration) var(--sc-transition-timing-function);\n cursor: pointer;\n\n /* outline is controlled by .input */\n outline: var(--segmented-control-outline, none);\n\n @mixin where-light {\n color: var(--mantine-color-gray-7);\n }\n\n @mixin where-dark {\n color: var(--mantine-color-dark-1);\n }\n\n &:where([data-read-only]) {\n cursor: default;\n }\n\n fieldset:disabled &,\n &:where([data-disabled]) {\n cursor: not-allowed;\n color: var(--mantine-color-disabled-color);\n }\n\n &:where([data-active]) {\n @mixin where-light {\n color: var(--sc-label-color, var(--mantine-color-black));\n }\n\n @mixin where-dark {\n color: var(--sc-label-color, var(--mantine-color-white));\n }\n\n &::before {\n .root:where([data-initialized]) & {\n display: none;\n }\n content: '';\n inset: 0;\n z-index: 0;\n position: absolute;\n border-radius: calc(var(--sc-radius, var(--mantine-radius-default)) - 4px);\n\n @mixin where-light {\n box-shadow: var(--sc-shadow, none);\n background-color: var(--sc-color, var(--mantine-color-white));\n }\n\n @mixin where-dark {\n box-shadow: none;\n background-color: var(--sc-color, var(--mantine-color-dark-5));\n }\n }\n }\n\n &:where(:not([data-disabled], [data-active], [data-read-only])) {\n @mixin hover {\n @mixin where-light {\n color: var(--mantine-color-black);\n }\n\n @mixin where-dark {\n color: var(--mantine-color-white);\n }\n }\n }\n\n fieldset:disabled & {\n @mixin hover {\n color: var(--mantine-color-disabled-color) !important;\n }\n }\n}\n\n.input {\n height: 0;\n width: 0;\n position: absolute;\n overflow: hidden;\n white-space: nowrap;\n opacity: 0;\n\n &[data-focus-ring='auto'] {\n &:focus:focus-visible {\n & + .label {\n --segmented-control-outline: 2px solid var(--mantine-primary-color-filled);\n }\n }\n }\n\n &[data-focus-ring='always'] {\n &:focus {\n & + .label {\n --segmented-control-outline: 2px solid var(--mantine-primary-color-filled);\n }\n }\n }\n}\n\n.control {\n position: relative;\n flex: 1;\n z-index: 2;\n transition: border-color var(--sc-transition-duration) var(--sc-transition-timing-function);\n\n .root[data-with-items-borders] :where(&)::before {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n inset-inline-start: 0;\n background-color: var(--separator-color);\n width: 1px;\n transition: background-color var(--sc-transition-duration) var(--sc-transition-timing-function);\n }\n\n &[data-orientation='vertical'] {\n &::before {\n top: 0;\n inset-inline: 0;\n bottom: auto;\n height: 1px;\n width: auto;\n }\n }\n\n @mixin where-light {\n --separator-color: var(--mantine-color-gray-3);\n }\n\n @mixin where-dark {\n --separator-color: var(--mantine-color-dark-4);\n }\n\n &:first-of-type {\n &::before {\n --separator-color: transparent;\n }\n }\n\n &[data-active] {\n [data-mantine-color-scheme] & {\n &,\n & + .control {\n &::before {\n --separator-color: transparent;\n }\n }\n }\n }\n}\n\n.innerLabel {\n position: relative;\n z-index: 2;\n}\n"],"mappings":""}
|
|
@@ -14,6 +14,13 @@ function getValuesRange(anchor, value, flatValues) {
|
|
|
14
14
|
const end = Math.max(anchorIndex, valueIndex);
|
|
15
15
|
return flatValues.slice(start, end + 1);
|
|
16
16
|
}
|
|
17
|
+
function isVisibleTreeNode(node, root) {
|
|
18
|
+
for (let current = node; current && current !== root;) {
|
|
19
|
+
if (current.style.display === "none") return false;
|
|
20
|
+
current = current.parentElement;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
17
24
|
function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selectOnClick, isSubtree, level = 1, renderNode, flatValues, allowRangeSelection, expandOnSpace, checkOnSpace, keepMounted, onDragDrop, allowDrop, withDragHandle, dragStateRef, data }) {
|
|
18
25
|
const ref = useRef(null);
|
|
19
26
|
const hasLoadedChildren = Array.isArray(node.children);
|
|
@@ -71,7 +78,7 @@ function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selec
|
|
|
71
78
|
if (!root) return;
|
|
72
79
|
event.stopPropagation();
|
|
73
80
|
event.preventDefault();
|
|
74
|
-
const nodes = Array.from(root.querySelectorAll("[role=treeitem]")).filter((treeNode) => treeNode
|
|
81
|
+
const nodes = Array.from(root.querySelectorAll("[role=treeitem]")).filter((treeNode) => isVisibleTreeNode(treeNode, root));
|
|
75
82
|
const index = nodes.indexOf(event.currentTarget);
|
|
76
83
|
if (index === -1) return;
|
|
77
84
|
const nextIndex = event.nativeEvent.code === "ArrowDown" ? index + 1 : index - 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeNode.mjs","names":[],"sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { Activity, useRef } from 'react';\nimport { Box, findElementAncestor, GetStylesApi } from '../../core';\nimport { Loader } from '../Loader';\nimport type { TreeDragDropPayload } from './move-tree-node/move-tree-node';\nimport type { RenderNode, TreeDragState, TreeFactory, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\nimport { TreeAllowDrop, useTreeNodeDragDrop } from './use-tree-node-drag-drop';\n\nfunction getValuesRange(anchor: string | null, value: string | undefined, flatValues: string[]) {\n if (!anchor || !value) {\n return [];\n }\n\n const anchorIndex = flatValues.indexOf(anchor);\n const valueIndex = flatValues.indexOf(value);\n const start = Math.min(anchorIndex, valueIndex);\n const end = Math.max(anchorIndex, valueIndex);\n\n return flatValues.slice(start, end + 1);\n}\n\ninterface TreeNodeProps {\n node: TreeNodeData;\n getStyles: GetStylesApi<TreeFactory>;\n rootIndex: number | undefined;\n controller: TreeController;\n expandOnClick: boolean | undefined;\n flatValues: string[];\n isSubtree?: boolean;\n level?: number;\n renderNode: RenderNode | undefined;\n selectOnClick: boolean | undefined;\n allowRangeSelection: boolean | undefined;\n expandOnSpace: boolean | undefined;\n checkOnSpace: boolean | undefined;\n keepMounted: boolean | undefined;\n onDragDrop: ((payload: TreeDragDropPayload) => void) | undefined;\n allowDrop: TreeAllowDrop | undefined;\n withDragHandle: boolean | undefined;\n dragStateRef: React.RefObject<TreeDragState>;\n data: TreeNodeData[];\n}\n\nexport function TreeNode({\n node,\n getStyles,\n rootIndex,\n controller,\n expandOnClick,\n selectOnClick,\n isSubtree,\n level = 1,\n renderNode,\n flatValues,\n allowRangeSelection,\n expandOnSpace,\n checkOnSpace,\n keepMounted,\n onDragDrop,\n allowDrop,\n withDragHandle,\n dragStateRef,\n data,\n}: TreeNodeProps) {\n const ref = useRef<HTMLLIElement>(null);\n const hasLoadedChildren = Array.isArray(node.children);\n const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;\n const hasChildren = hasLoadedChildren || hasAsyncChildren;\n const isLoading = controller.isNodeLoading(node.value);\n const loadError = controller.getNodeLoadError(node.value);\n const isExpanded = controller.expandedState[node.value] || false;\n\n const nested = (node.children || []).map((child) => (\n <TreeNode\n key={child.value}\n node={child}\n flatValues={flatValues}\n getStyles={getStyles}\n rootIndex={undefined}\n level={level + 1}\n controller={controller}\n expandOnClick={expandOnClick}\n isSubtree\n renderNode={renderNode}\n selectOnClick={selectOnClick}\n allowRangeSelection={allowRangeSelection}\n expandOnSpace={expandOnSpace}\n checkOnSpace={checkOnSpace}\n keepMounted={keepMounted}\n onDragDrop={onDragDrop}\n allowDrop={allowDrop}\n withDragHandle={withDragHandle}\n dragStateRef={dragStateRef}\n data={data}\n />\n ));\n\n const { elementProps: dragElementProps, dragHandleProps } = useTreeNodeDragDrop({\n nodeValue: node.value,\n hasChildren,\n isExpanded,\n data,\n onDragDrop,\n dragStateRef,\n allowDrop,\n withDragHandle,\n });\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.code === 'ArrowRight') {\n event.stopPropagation();\n event.preventDefault();\n\n if (isExpanded) {\n event.currentTarget.querySelector<HTMLLIElement>('[role=treeitem]')?.focus();\n } else {\n controller.expand(node.value);\n }\n }\n\n if (event.nativeEvent.code === 'ArrowLeft') {\n event.stopPropagation();\n event.preventDefault();\n if (isExpanded && hasChildren) {\n controller.collapse(node.value);\n } else if (isSubtree) {\n findElementAncestor(event.currentTarget as HTMLElement, '[role=treeitem]')?.focus();\n }\n }\n\n if (event.nativeEvent.code === 'ArrowDown' || event.nativeEvent.code === 'ArrowUp') {\n const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n\n if (!root) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const nodes = Array.from(root.querySelectorAll<HTMLLIElement>('[role=treeitem]')).filter(\n (treeNode) => treeNode.style.display !== 'none'\n );\n const index = nodes.indexOf(event.currentTarget as HTMLLIElement);\n\n if (index === -1) {\n return;\n }\n\n const nextIndex = event.nativeEvent.code === 'ArrowDown' ? index + 1 : index - 1;\n nodes[nextIndex]?.focus();\n\n if (event.shiftKey) {\n const selectNode = nodes[nextIndex];\n\n if (selectNode) {\n controller.setSelectedState(\n getValuesRange(controller.anchorNode, selectNode.dataset.value, flatValues)\n );\n }\n }\n }\n\n if (event.nativeEvent.code === 'Space') {\n if (expandOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.toggleExpanded(node.value);\n }\n\n if (checkOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.isNodeChecked(node.value)\n ? controller.uncheckNode(node.value)\n : controller.checkNode(node.value);\n }\n }\n };\n\n const handleNodeClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n\n if (allowRangeSelection && event.shiftKey && controller.anchorNode) {\n controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));\n ref.current?.focus();\n } else {\n if (expandOnClick) {\n controller.toggleExpanded(node.value);\n }\n\n selectOnClick && controller.select(node.value);\n ref.current?.focus();\n }\n };\n\n const selected = controller.selectedState.includes(node.value);\n const elementProps = {\n ...getStyles('label'),\n onClick: handleNodeClick,\n 'data-selected': selected || undefined,\n 'data-value': node.value,\n ...dragElementProps,\n };\n\n const withLoadingIndicator = isExpanded && isLoading && nested.length === 0;\n\n return (\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level - 1})` },\n })}\n role=\"treeitem\"\n aria-selected={selected}\n data-value={node.value}\n data-selected={selected || undefined}\n data-level={level}\n tabIndex={rootIndex === 0 ? 0 : -1}\n onKeyDown={handleKeyDown}\n ref={ref}\n >\n {typeof renderNode === 'function' ? (\n renderNode({\n node,\n level,\n selected,\n isRoot: level === 1,\n tree: controller,\n expanded: isExpanded,\n hasChildren,\n isLoading,\n loadError,\n elementProps,\n dragHandleProps,\n })\n ) : (\n <div {...elementProps}>{node.label}</div>\n )}\n\n {withLoadingIndicator && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level})` },\n })}\n >\n <div {...getStyles('label')}>\n <Loader size={16} style={{ marginInlineStart: 4 }} />\n </div>\n </li>\n </Box>\n )}\n\n {keepMounted && nested.length > 0 ? (\n <Activity mode={isExpanded ? 'visible' : 'hidden'}>\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n </Activity>\n ) : (\n isExpanded &&\n nested.length > 0 && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n )\n )}\n </li>\n );\n}\n\nTreeNode.displayName = '@mantine/core/TreeNode';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TreeNode.mjs","names":[],"sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { Activity, useRef } from 'react';\nimport { Box, findElementAncestor, GetStylesApi } from '../../core';\nimport { Loader } from '../Loader';\nimport type { TreeDragDropPayload } from './move-tree-node/move-tree-node';\nimport type { RenderNode, TreeDragState, TreeFactory, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\nimport { TreeAllowDrop, useTreeNodeDragDrop } from './use-tree-node-drag-drop';\n\nfunction getValuesRange(anchor: string | null, value: string | undefined, flatValues: string[]) {\n if (!anchor || !value) {\n return [];\n }\n\n const anchorIndex = flatValues.indexOf(anchor);\n const valueIndex = flatValues.indexOf(value);\n const start = Math.min(anchorIndex, valueIndex);\n const end = Math.max(anchorIndex, valueIndex);\n\n return flatValues.slice(start, end + 1);\n}\n\nfunction isVisibleTreeNode(node: HTMLElement, root: Element) {\n for (let current: HTMLElement | null = node; current && current !== root; ) {\n if (current.style.display === 'none') {\n return false;\n }\n current = current.parentElement;\n }\n\n return true;\n}\n\ninterface TreeNodeProps {\n node: TreeNodeData;\n getStyles: GetStylesApi<TreeFactory>;\n rootIndex: number | undefined;\n controller: TreeController;\n expandOnClick: boolean | undefined;\n flatValues: string[];\n isSubtree?: boolean;\n level?: number;\n renderNode: RenderNode | undefined;\n selectOnClick: boolean | undefined;\n allowRangeSelection: boolean | undefined;\n expandOnSpace: boolean | undefined;\n checkOnSpace: boolean | undefined;\n keepMounted: boolean | undefined;\n onDragDrop: ((payload: TreeDragDropPayload) => void) | undefined;\n allowDrop: TreeAllowDrop | undefined;\n withDragHandle: boolean | undefined;\n dragStateRef: React.RefObject<TreeDragState>;\n data: TreeNodeData[];\n}\n\nexport function TreeNode({\n node,\n getStyles,\n rootIndex,\n controller,\n expandOnClick,\n selectOnClick,\n isSubtree,\n level = 1,\n renderNode,\n flatValues,\n allowRangeSelection,\n expandOnSpace,\n checkOnSpace,\n keepMounted,\n onDragDrop,\n allowDrop,\n withDragHandle,\n dragStateRef,\n data,\n}: TreeNodeProps) {\n const ref = useRef<HTMLLIElement>(null);\n const hasLoadedChildren = Array.isArray(node.children);\n const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;\n const hasChildren = hasLoadedChildren || hasAsyncChildren;\n const isLoading = controller.isNodeLoading(node.value);\n const loadError = controller.getNodeLoadError(node.value);\n const isExpanded = controller.expandedState[node.value] || false;\n\n const nested = (node.children || []).map((child) => (\n <TreeNode\n key={child.value}\n node={child}\n flatValues={flatValues}\n getStyles={getStyles}\n rootIndex={undefined}\n level={level + 1}\n controller={controller}\n expandOnClick={expandOnClick}\n isSubtree\n renderNode={renderNode}\n selectOnClick={selectOnClick}\n allowRangeSelection={allowRangeSelection}\n expandOnSpace={expandOnSpace}\n checkOnSpace={checkOnSpace}\n keepMounted={keepMounted}\n onDragDrop={onDragDrop}\n allowDrop={allowDrop}\n withDragHandle={withDragHandle}\n dragStateRef={dragStateRef}\n data={data}\n />\n ));\n\n const { elementProps: dragElementProps, dragHandleProps } = useTreeNodeDragDrop({\n nodeValue: node.value,\n hasChildren,\n isExpanded,\n data,\n onDragDrop,\n dragStateRef,\n allowDrop,\n withDragHandle,\n });\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.code === 'ArrowRight') {\n event.stopPropagation();\n event.preventDefault();\n\n if (isExpanded) {\n event.currentTarget.querySelector<HTMLLIElement>('[role=treeitem]')?.focus();\n } else {\n controller.expand(node.value);\n }\n }\n\n if (event.nativeEvent.code === 'ArrowLeft') {\n event.stopPropagation();\n event.preventDefault();\n if (isExpanded && hasChildren) {\n controller.collapse(node.value);\n } else if (isSubtree) {\n findElementAncestor(event.currentTarget as HTMLElement, '[role=treeitem]')?.focus();\n }\n }\n\n if (event.nativeEvent.code === 'ArrowDown' || event.nativeEvent.code === 'ArrowUp') {\n const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n\n if (!root) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const nodes = Array.from(root.querySelectorAll<HTMLLIElement>('[role=treeitem]')).filter(\n (treeNode) => isVisibleTreeNode(treeNode, root)\n );\n const index = nodes.indexOf(event.currentTarget as HTMLLIElement);\n\n if (index === -1) {\n return;\n }\n\n const nextIndex = event.nativeEvent.code === 'ArrowDown' ? index + 1 : index - 1;\n nodes[nextIndex]?.focus();\n\n if (event.shiftKey) {\n const selectNode = nodes[nextIndex];\n\n if (selectNode) {\n controller.setSelectedState(\n getValuesRange(controller.anchorNode, selectNode.dataset.value, flatValues)\n );\n }\n }\n }\n\n if (event.nativeEvent.code === 'Space') {\n if (expandOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.toggleExpanded(node.value);\n }\n\n if (checkOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.isNodeChecked(node.value)\n ? controller.uncheckNode(node.value)\n : controller.checkNode(node.value);\n }\n }\n };\n\n const handleNodeClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n\n if (allowRangeSelection && event.shiftKey && controller.anchorNode) {\n controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));\n ref.current?.focus();\n } else {\n if (expandOnClick) {\n controller.toggleExpanded(node.value);\n }\n\n selectOnClick && controller.select(node.value);\n ref.current?.focus();\n }\n };\n\n const selected = controller.selectedState.includes(node.value);\n const elementProps = {\n ...getStyles('label'),\n onClick: handleNodeClick,\n 'data-selected': selected || undefined,\n 'data-value': node.value,\n ...dragElementProps,\n };\n\n const withLoadingIndicator = isExpanded && isLoading && nested.length === 0;\n\n return (\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level - 1})` },\n })}\n role=\"treeitem\"\n aria-selected={selected}\n data-value={node.value}\n data-selected={selected || undefined}\n data-level={level}\n tabIndex={rootIndex === 0 ? 0 : -1}\n onKeyDown={handleKeyDown}\n ref={ref}\n >\n {typeof renderNode === 'function' ? (\n renderNode({\n node,\n level,\n selected,\n isRoot: level === 1,\n tree: controller,\n expanded: isExpanded,\n hasChildren,\n isLoading,\n loadError,\n elementProps,\n dragHandleProps,\n })\n ) : (\n <div {...elementProps}>{node.label}</div>\n )}\n\n {withLoadingIndicator && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level})` },\n })}\n >\n <div {...getStyles('label')}>\n <Loader size={16} style={{ marginInlineStart: 4 }} />\n </div>\n </li>\n </Box>\n )}\n\n {keepMounted && nested.length > 0 ? (\n <Activity mode={isExpanded ? 'visible' : 'hidden'}>\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n </Activity>\n ) : (\n isExpanded &&\n nested.length > 0 && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n )\n )}\n </li>\n );\n}\n\nTreeNode.displayName = '@mantine/core/TreeNode';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createEventHandler } from "../../core/utils/create-event-handler/create-event-handler.mjs";
|
|
3
|
+
import { useRef } from "react";
|
|
4
|
+
import { useLongPress } from "@mantine/hooks";
|
|
5
|
+
//#region packages/@mantine/core/src/utils/Floating/use-context-menu-handlers.ts
|
|
6
|
+
function useContextMenuHandlers({ childProps, disabled, opened, longPressDelay = 500, setReference, open }) {
|
|
7
|
+
const touchActiveRef = useRef(false);
|
|
8
|
+
const gestureHandledRef = useRef(false);
|
|
9
|
+
const touchTargetRef = useRef(null);
|
|
10
|
+
const disabledRef = useRef(disabled);
|
|
11
|
+
disabledRef.current = disabled;
|
|
12
|
+
const openAtPoint = (clientX, clientY, contextElement) => {
|
|
13
|
+
setReference({
|
|
14
|
+
getBoundingClientRect: () => ({
|
|
15
|
+
x: clientX,
|
|
16
|
+
y: clientY,
|
|
17
|
+
width: 0,
|
|
18
|
+
height: 0,
|
|
19
|
+
top: clientY,
|
|
20
|
+
left: clientX,
|
|
21
|
+
right: clientX,
|
|
22
|
+
bottom: clientY,
|
|
23
|
+
toJSON: () => void 0
|
|
24
|
+
}),
|
|
25
|
+
contextElement
|
|
26
|
+
});
|
|
27
|
+
open();
|
|
28
|
+
};
|
|
29
|
+
const onMouseDown = createEventHandler(childProps.onMouseDown, (event) => {
|
|
30
|
+
if (disabled) return;
|
|
31
|
+
if (event.button === 2) event.stopPropagation();
|
|
32
|
+
});
|
|
33
|
+
const onContextMenu = createEventHandler(childProps.onContextMenu, (event) => {
|
|
34
|
+
if (disabled || event.defaultPrevented) return;
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
if (gestureHandledRef.current) return;
|
|
37
|
+
openAtPoint(event.clientX, event.clientY, event.currentTarget);
|
|
38
|
+
if (touchActiveRef.current) gestureHandledRef.current = true;
|
|
39
|
+
});
|
|
40
|
+
const longPressHandlers = useLongPress((event) => {
|
|
41
|
+
if (disabledRef.current || gestureHandledRef.current) return;
|
|
42
|
+
const touchEvent = event;
|
|
43
|
+
const touch = touchEvent.touches[0] ?? touchEvent.changedTouches[0];
|
|
44
|
+
if (!touch) return;
|
|
45
|
+
openAtPoint(touch.clientX, touch.clientY, touchTargetRef.current);
|
|
46
|
+
gestureHandledRef.current = true;
|
|
47
|
+
}, {
|
|
48
|
+
threshold: longPressDelay,
|
|
49
|
+
events: ["touch"],
|
|
50
|
+
cancelOnMove: true,
|
|
51
|
+
onStart: (event) => {
|
|
52
|
+
touchActiveRef.current = true;
|
|
53
|
+
gestureHandledRef.current = false;
|
|
54
|
+
touchTargetRef.current = event.currentTarget;
|
|
55
|
+
},
|
|
56
|
+
onFinish: (event) => {
|
|
57
|
+
touchActiveRef.current = false;
|
|
58
|
+
gestureHandledRef.current = false;
|
|
59
|
+
if (!disabledRef.current) event.preventDefault();
|
|
60
|
+
},
|
|
61
|
+
onCancel: () => {
|
|
62
|
+
touchActiveRef.current = false;
|
|
63
|
+
gestureHandledRef.current = false;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
onContextMenu,
|
|
68
|
+
onMouseDown,
|
|
69
|
+
onTouchStart: createEventHandler(childProps.onTouchStart, longPressHandlers.onTouchStart),
|
|
70
|
+
onTouchEnd: createEventHandler(childProps.onTouchEnd, longPressHandlers.onTouchEnd),
|
|
71
|
+
onTouchCancel: createEventHandler(childProps.onTouchCancel, longPressHandlers.onTouchCancel),
|
|
72
|
+
onTouchMove: createEventHandler(childProps.onTouchMove, longPressHandlers.onTouchMove),
|
|
73
|
+
style: disabled ? childProps.style : {
|
|
74
|
+
...childProps.style,
|
|
75
|
+
WebkitTouchCallout: "none",
|
|
76
|
+
WebkitUserSelect: "none",
|
|
77
|
+
userSelect: "none"
|
|
78
|
+
},
|
|
79
|
+
"data-expanded": opened ? true : void 0
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { useContextMenuHandlers };
|
|
84
|
+
|
|
85
|
+
//# sourceMappingURL=use-context-menu-handlers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-context-menu-handlers.mjs","names":[],"sources":["../../../src/utils/Floating/use-context-menu-handlers.ts"],"sourcesContent":["import React, { useRef } from 'react';\nimport { useLongPress } from '@mantine/hooks';\nimport { createEventHandler } from '../../core/utils/create-event-handler/create-event-handler';\n\ninterface UseContextMenuHandlersOptions {\n /** Props of the child element that opens the dropdown */\n childProps: Record<string, any>;\n\n /** If set, right-click trigger is disabled and the browser's default context menu is shown */\n disabled: boolean | undefined;\n\n /** Current opened state, used to set `data-expanded` on the child */\n opened: boolean;\n\n /** Delay in ms before a touch long-press opens the dropdown, `500` by default */\n longPressDelay?: number;\n\n /** Sets the floating reference to a virtual element positioned at the cursor */\n setReference: (node: object) => void;\n\n /** Called to open the dropdown after the reference has been set */\n open: () => void;\n}\n\nexport function useContextMenuHandlers({\n childProps,\n disabled,\n opened,\n longPressDelay = 500,\n setReference,\n open,\n}: UseContextMenuHandlersOptions) {\n const touchActiveRef = useRef(false);\n const gestureHandledRef = useRef(false);\n const touchTargetRef = useRef<object | null>(null);\n const disabledRef = useRef(disabled);\n disabledRef.current = disabled;\n\n const openAtPoint = (clientX: number, clientY: number, contextElement: object | null) => {\n setReference({\n getBoundingClientRect: () => ({\n x: clientX,\n y: clientY,\n width: 0,\n height: 0,\n top: clientY,\n left: clientX,\n right: clientX,\n bottom: clientY,\n toJSON: () => undefined,\n }),\n contextElement,\n });\n\n open();\n };\n\n const onMouseDown = createEventHandler<any>(\n childProps.onMouseDown,\n (event: React.MouseEvent<HTMLElement>) => {\n if (disabled) {\n return;\n }\n if (event.button === 2) {\n event.stopPropagation();\n }\n }\n );\n\n const onContextMenu = createEventHandler<any>(\n childProps.onContextMenu,\n (event: React.MouseEvent<HTMLElement>) => {\n if (disabled || event.defaultPrevented) {\n return;\n }\n\n event.preventDefault();\n\n if (gestureHandledRef.current) {\n return;\n }\n\n openAtPoint(event.clientX, event.clientY, event.currentTarget);\n\n if (touchActiveRef.current) {\n gestureHandledRef.current = true;\n }\n }\n );\n\n const longPressHandlers = useLongPress(\n (event) => {\n if (disabledRef.current || gestureHandledRef.current) {\n return;\n }\n\n const touchEvent = event as React.TouchEvent<HTMLElement>;\n const touch = touchEvent.touches[0] ?? touchEvent.changedTouches[0];\n if (!touch) {\n return;\n }\n\n openAtPoint(touch.clientX, touch.clientY, touchTargetRef.current);\n gestureHandledRef.current = true;\n },\n {\n threshold: longPressDelay,\n events: ['touch'],\n cancelOnMove: true,\n onStart: (event) => {\n touchActiveRef.current = true;\n gestureHandledRef.current = false;\n touchTargetRef.current = event.currentTarget;\n },\n onFinish: (event) => {\n touchActiveRef.current = false;\n gestureHandledRef.current = false;\n if (!disabledRef.current) {\n event.preventDefault();\n }\n },\n onCancel: () => {\n touchActiveRef.current = false;\n gestureHandledRef.current = false;\n },\n }\n );\n\n const onTouchStart = createEventHandler<any>(\n childProps.onTouchStart,\n longPressHandlers.onTouchStart\n );\n const onTouchEnd = createEventHandler<any>(childProps.onTouchEnd, longPressHandlers.onTouchEnd);\n const onTouchCancel = createEventHandler<any>(\n childProps.onTouchCancel,\n longPressHandlers.onTouchCancel\n );\n const onTouchMove = createEventHandler<any>(\n childProps.onTouchMove,\n longPressHandlers.onTouchMove\n );\n\n return {\n onContextMenu,\n onMouseDown,\n onTouchStart,\n onTouchEnd,\n onTouchCancel,\n onTouchMove,\n style: disabled\n ? childProps.style\n : {\n ...childProps.style,\n WebkitTouchCallout: 'none',\n WebkitUserSelect: 'none',\n userSelect: 'none',\n },\n 'data-expanded': opened ? true : undefined,\n };\n}\n"],"mappings":";;;;;AAwBA,SAAgB,uBAAuB,EACrC,YACA,UACA,QACA,iBAAiB,KACjB,cACA,QACgC;CAChC,MAAM,iBAAiB,OAAO,KAAK;CACnC,MAAM,oBAAoB,OAAO,KAAK;CACtC,MAAM,iBAAiB,OAAsB,IAAI;CACjD,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CAEtB,MAAM,eAAe,SAAiB,SAAiB,mBAAkC;EACvF,aAAa;GACX,8BAA8B;IAC5B,GAAG;IACH,GAAG;IACH,OAAO;IACP,QAAQ;IACR,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,cAAc,KAAA;GAChB;GACA;EACF,CAAC;EAED,KAAK;CACP;CAEA,MAAM,cAAc,mBAClB,WAAW,cACV,UAAyC;EACxC,IAAI,UACF;EAEF,IAAI,MAAM,WAAW,GACnB,MAAM,gBAAgB;CAE1B,CACF;CAEA,MAAM,gBAAgB,mBACpB,WAAW,gBACV,UAAyC;EACxC,IAAI,YAAY,MAAM,kBACpB;EAGF,MAAM,eAAe;EAErB,IAAI,kBAAkB,SACpB;EAGF,YAAY,MAAM,SAAS,MAAM,SAAS,MAAM,aAAa;EAE7D,IAAI,eAAe,SACjB,kBAAkB,UAAU;CAEhC,CACF;CAEA,MAAM,oBAAoB,cACvB,UAAU;EACT,IAAI,YAAY,WAAW,kBAAkB,SAC3C;EAGF,MAAM,aAAa;EACnB,MAAM,QAAQ,WAAW,QAAQ,MAAM,WAAW,eAAe;EACjE,IAAI,CAAC,OACH;EAGF,YAAY,MAAM,SAAS,MAAM,SAAS,eAAe,OAAO;EAChE,kBAAkB,UAAU;CAC9B,GACA;EACE,WAAW;EACX,QAAQ,CAAC,OAAO;EAChB,cAAc;EACd,UAAU,UAAU;GAClB,eAAe,UAAU;GACzB,kBAAkB,UAAU;GAC5B,eAAe,UAAU,MAAM;EACjC;EACA,WAAW,UAAU;GACnB,eAAe,UAAU;GACzB,kBAAkB,UAAU;GAC5B,IAAI,CAAC,YAAY,SACf,MAAM,eAAe;EAEzB;EACA,gBAAgB;GACd,eAAe,UAAU;GACzB,kBAAkB,UAAU;EAC9B;CACF,CACF;CAgBA,OAAO;EACL;EACA;EACA,cAjBmB,mBACnB,WAAW,cACX,kBAAkB,YAeP;EACX,YAdiB,mBAAwB,WAAW,YAAY,kBAAkB,UAczE;EACT,eAdoB,mBACpB,WAAW,eACX,kBAAkB,aAYN;EACZ,aAXkB,mBAClB,WAAW,aACX,kBAAkB,WASR;EACV,OAAO,WACH,WAAW,QACX;GACE,GAAG,WAAW;GACd,oBAAoB;GACpB,kBAAkB;GAClB,YAAY;EACd;EACJ,iBAAiB,SAAS,OAAO,KAAA;CACnC;AACF"}
|
|
@@ -14,7 +14,7 @@ export interface CollapseProps extends BoxProps, Omit<React.ComponentProps<'div'
|
|
|
14
14
|
transitionTimingFunction?: string;
|
|
15
15
|
/** Determines whether the opacity is animated @default true */
|
|
16
16
|
animateOpacity?: boolean;
|
|
17
|
-
/** If set, the element is kept in the DOM when collapsed. When `true`, React 19 `Activity` is used to preserve state while collapsed. When `false`, the element is unmounted after the exit animation. @default
|
|
17
|
+
/** If set, the element is kept in the DOM when collapsed. When `true`, React 19 `Activity` is used to preserve state while collapsed. When `false`, the element is unmounted after the exit animation. @default true */
|
|
18
18
|
keepMounted?: boolean;
|
|
19
19
|
}
|
|
20
20
|
export type CollapseFactory = Factory<{
|
|
@@ -9,7 +9,7 @@ export type DialogCssVariables = {
|
|
|
9
9
|
export interface DialogProps extends BoxProps, AffixBaseProps, PaperBaseProps, StylesApiProps<DialogFactory>, ElementProps<'div'> {
|
|
10
10
|
/** If set, the component uses `display: none` to hide the root element instead of removing the DOM node @default false */
|
|
11
11
|
keepMounted?: boolean;
|
|
12
|
-
/** If set, displays the close button @default
|
|
12
|
+
/** If set, displays the close button @default false */
|
|
13
13
|
withCloseButton?: boolean;
|
|
14
14
|
/** Called on close button click */
|
|
15
15
|
onClose?: () => void;
|
|
@@ -3,6 +3,8 @@ export interface MenuContextMenuProps {
|
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
/** If set, the right-click trigger is disabled and the browser's default context menu is shown */
|
|
5
5
|
disabled?: boolean;
|
|
6
|
+
/** Delay in ms before a touch long-press opens the dropdown on touch devices, `500` by default */
|
|
7
|
+
longPressDelay?: number;
|
|
6
8
|
}
|
|
7
9
|
export declare function MenuContextMenu(props: MenuContextMenuProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
8
10
|
export declare namespace MenuContextMenu {
|
|
@@ -9,6 +9,8 @@ export type MenuSubFactory = Factory<{
|
|
|
9
9
|
}>;
|
|
10
10
|
export interface MenuSubProps extends __PopoverProps {
|
|
11
11
|
children: React.ReactNode;
|
|
12
|
+
/** Controlled opened state */
|
|
13
|
+
opened?: boolean;
|
|
12
14
|
/** Called with current state when dropdown opens or closes */
|
|
13
15
|
onChange?: (opened: boolean) => void;
|
|
14
16
|
/** Open delay in ms, applicable when hover trigger is used */
|
|
@@ -3,6 +3,8 @@ export interface PopoverContextMenuProps {
|
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
/** If set, the right-click trigger is disabled and the browser's default context menu is shown */
|
|
5
5
|
disabled?: boolean;
|
|
6
|
+
/** Delay in ms before a touch long-press opens the dropdown on touch devices, `500` by default */
|
|
7
|
+
longPressDelay?: number;
|
|
6
8
|
}
|
|
7
9
|
export declare function PopoverContextMenu(props: PopoverContextMenuProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
8
10
|
export declare namespace PopoverContextMenu {
|
package/lib/utils/Floating/{create-context-menu-handlers.d.ts → use-context-menu-handlers.d.ts}
RENAMED
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
interface
|
|
1
|
+
interface UseContextMenuHandlersOptions {
|
|
2
2
|
/** Props of the child element that opens the dropdown */
|
|
3
3
|
childProps: Record<string, any>;
|
|
4
4
|
/** If set, right-click trigger is disabled and the browser's default context menu is shown */
|
|
5
5
|
disabled: boolean | undefined;
|
|
6
6
|
/** Current opened state, used to set `data-expanded` on the child */
|
|
7
7
|
opened: boolean;
|
|
8
|
+
/** Delay in ms before a touch long-press opens the dropdown, `500` by default */
|
|
9
|
+
longPressDelay?: number;
|
|
8
10
|
/** Sets the floating reference to a virtual element positioned at the cursor */
|
|
9
11
|
setReference: (node: object) => void;
|
|
10
12
|
/** Called to open the dropdown after the reference has been set */
|
|
11
13
|
open: () => void;
|
|
12
14
|
}
|
|
13
|
-
export declare function
|
|
15
|
+
export declare function useContextMenuHandlers({ childProps, disabled, opened, longPressDelay, setReference, open, }: UseContextMenuHandlersOptions): {
|
|
14
16
|
onContextMenu: (event?: any) => void;
|
|
15
17
|
onMouseDown: (event?: any) => void;
|
|
18
|
+
onTouchStart: (event?: any) => void;
|
|
19
|
+
onTouchEnd: (event?: any) => void;
|
|
20
|
+
onTouchCancel: (event?: any) => void;
|
|
21
|
+
onTouchMove: (event?: any) => void;
|
|
22
|
+
style: any;
|
|
16
23
|
'data-expanded': boolean | undefined;
|
|
17
24
|
};
|
|
18
25
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mantine/core",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"description": "React components library focused on usability, accessibility and developer experience",
|
|
5
5
|
"homepage": "https://mantine.dev/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"directory": "packages/@mantine/core"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@mantine/hooks": "9.3.
|
|
46
|
+
"@mantine/hooks": "9.3.1",
|
|
47
47
|
"react": "^19.2.0",
|
|
48
48
|
"react-dom": "^19.2.0"
|
|
49
49
|
},
|
package/styles/Input.css
CHANGED
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
width: 100%;
|
|
165
165
|
transition: border-color 100ms ease;
|
|
166
166
|
|
|
167
|
-
text-align: start;
|
|
167
|
+
text-align: var(--input-text-align, start);
|
|
168
168
|
color: var(--input-color);
|
|
169
169
|
border: calc(0.0625rem * var(--mantine-scale)) solid var(--input-bd);
|
|
170
170
|
background-color: var(--input-bg);
|
package/styles/Input.layer.css
CHANGED
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
width: 100%;
|
|
165
165
|
transition: border-color 100ms ease;
|
|
166
166
|
|
|
167
|
-
text-align: start;
|
|
167
|
+
text-align: var(--input-text-align, start);
|
|
168
168
|
color: var(--input-color);
|
|
169
169
|
border: calc(0.0625rem * var(--mantine-scale)) solid var(--input-bd);
|
|
170
170
|
background-color: var(--input-bg);
|
|
@@ -45,7 +45,10 @@
|
|
|
45
45
|
position: absolute;
|
|
46
46
|
display: block;
|
|
47
47
|
z-index: 1;
|
|
48
|
-
border-radius:
|
|
48
|
+
border-radius: max(
|
|
49
|
+
calc(var(--sc-radius, var(--mantine-radius-default)) - 4px),
|
|
50
|
+
calc(var(--sc-radius, var(--mantine-radius-default)) / 4)
|
|
51
|
+
);
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
:where([data-mantine-color-scheme='light']) .m_9e182ccd {
|
|
@@ -45,7 +45,10 @@
|
|
|
45
45
|
position: absolute;
|
|
46
46
|
display: block;
|
|
47
47
|
z-index: 1;
|
|
48
|
-
border-radius:
|
|
48
|
+
border-radius: max(
|
|
49
|
+
calc(var(--sc-radius, var(--mantine-radius-default)) - 4px),
|
|
50
|
+
calc(var(--sc-radius, var(--mantine-radius-default)) / 4)
|
|
51
|
+
);
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
:where([data-mantine-color-scheme='light']) .m_9e182ccd {
|