@cdx-ui/primitives 0.1.6 → 0.2.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/lib/commonjs/color/Color.js +69 -0
- package/lib/commonjs/color/Color.js.map +1 -0
- package/lib/commonjs/color/index.js +13 -0
- package/lib/commonjs/color/index.js.map +1 -0
- package/lib/commonjs/color/types.js +2 -0
- package/lib/commonjs/color/types.js.map +1 -0
- package/lib/commonjs/color-area/ColorAreaAccessibility.js +100 -0
- package/lib/commonjs/color-area/ColorAreaAccessibility.js.map +1 -0
- package/lib/commonjs/color-area/ColorAreaAccessibility.web.js +58 -0
- package/lib/commonjs/color-area/ColorAreaAccessibility.web.js.map +1 -0
- package/lib/commonjs/color-area/ColorAreaRoot.js +240 -0
- package/lib/commonjs/color-area/ColorAreaRoot.js.map +1 -0
- package/lib/commonjs/color-area/ColorAreaThumb.js +71 -0
- package/lib/commonjs/color-area/ColorAreaThumb.js.map +1 -0
- package/lib/commonjs/color-area/context.js +11 -0
- package/lib/commonjs/color-area/context.js.map +1 -0
- package/lib/commonjs/color-area/index.js +27 -0
- package/lib/commonjs/color-area/index.js.map +1 -0
- package/lib/commonjs/color-area/types.js +6 -0
- package/lib/commonjs/color-area/types.js.map +1 -0
- package/lib/commonjs/color-area/utils.js +51 -0
- package/lib/commonjs/color-area/utils.js.map +1 -0
- package/lib/commonjs/color-field/ColorFieldInput.js +67 -0
- package/lib/commonjs/color-field/ColorFieldInput.js.map +1 -0
- package/lib/commonjs/color-field/ColorFieldRoot.js +104 -0
- package/lib/commonjs/color-field/ColorFieldRoot.js.map +1 -0
- package/lib/commonjs/color-field/context.js +11 -0
- package/lib/commonjs/color-field/context.js.map +1 -0
- package/lib/commonjs/color-field/index.js +27 -0
- package/lib/commonjs/color-field/index.js.map +1 -0
- package/lib/commonjs/color-field/types.js +6 -0
- package/lib/commonjs/color-field/types.js.map +1 -0
- package/lib/commonjs/color-field/utils.js +60 -0
- package/lib/commonjs/color-field/utils.js.map +1 -0
- package/lib/commonjs/color-picker/ColorPickerRoot.js +69 -0
- package/lib/commonjs/color-picker/ColorPickerRoot.js.map +1 -0
- package/lib/commonjs/color-picker/ColorPickerTrigger.js +98 -0
- package/lib/commonjs/color-picker/ColorPickerTrigger.js.map +1 -0
- package/lib/commonjs/color-picker/context.js +32 -0
- package/lib/commonjs/color-picker/context.js.map +1 -0
- package/lib/commonjs/color-picker/index.js +51 -0
- package/lib/commonjs/color-picker/index.js.map +1 -0
- package/lib/commonjs/color-picker/types.js +6 -0
- package/lib/commonjs/color-picker/types.js.map +1 -0
- package/lib/commonjs/color-slider/ColorSliderRail.js +119 -0
- package/lib/commonjs/color-slider/ColorSliderRail.js.map +1 -0
- package/lib/commonjs/color-slider/ColorSliderRoot.js +153 -0
- package/lib/commonjs/color-slider/ColorSliderRoot.js.map +1 -0
- package/lib/commonjs/color-slider/ColorSliderThumb.js +265 -0
- package/lib/commonjs/color-slider/ColorSliderThumb.js.map +1 -0
- package/lib/commonjs/color-slider/context.js +11 -0
- package/lib/commonjs/color-slider/context.js.map +1 -0
- package/lib/commonjs/color-slider/index.js +34 -0
- package/lib/commonjs/color-slider/index.js.map +1 -0
- package/lib/commonjs/color-slider/types.js +6 -0
- package/lib/commonjs/color-slider/types.js.map +1 -0
- package/lib/commonjs/color-slider/utils.js +75 -0
- package/lib/commonjs/color-slider/utils.js.map +1 -0
- package/lib/commonjs/color-swatch-picker/ColorSwatchPickerItem.js +46 -0
- package/lib/commonjs/color-swatch-picker/ColorSwatchPickerItem.js.map +1 -0
- package/lib/commonjs/color-swatch-picker/ColorSwatchPickerRoot.js +71 -0
- package/lib/commonjs/color-swatch-picker/ColorSwatchPickerRoot.js.map +1 -0
- package/lib/commonjs/color-swatch-picker/context.js +22 -0
- package/lib/commonjs/color-swatch-picker/context.js.map +1 -0
- package/lib/commonjs/color-swatch-picker/index.js +33 -0
- package/lib/commonjs/color-swatch-picker/index.js.map +1 -0
- package/lib/commonjs/color-swatch-picker/types.js +6 -0
- package/lib/commonjs/color-swatch-picker/types.js.map +1 -0
- package/lib/commonjs/dialog/DialogContent.js +13 -5
- package/lib/commonjs/dialog/DialogContent.js.map +1 -1
- package/lib/commonjs/dialog/DialogPopup.js +7 -1
- package/lib/commonjs/dialog/DialogPopup.js.map +1 -1
- package/lib/commonjs/dialog/DialogRoot.js +3 -1
- package/lib/commonjs/dialog/DialogRoot.js.map +1 -1
- package/lib/commonjs/index.js +80 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/portal/portal.js +4 -2
- package/lib/commonjs/portal/portal.js.map +1 -1
- package/lib/commonjs/react-native-web.d.js +2 -0
- package/lib/commonjs/react-native-web.d.js.map +1 -0
- package/lib/commonjs/select/SelectContent.js +1 -0
- package/lib/commonjs/select/SelectContent.js.map +1 -1
- package/lib/commonjs/slider/useSliderPointer.js +2 -0
- package/lib/commonjs/slider/useSliderPointer.js.map +1 -1
- package/lib/commonjs/utils/createPortal.web.js +10 -1
- package/lib/commonjs/utils/createPortal.web.js.map +1 -1
- package/lib/commonjs/utils/textAncestor.js +25 -0
- package/lib/commonjs/utils/textAncestor.js.map +1 -0
- package/lib/commonjs/utils/textAncestor.web.js +27 -0
- package/lib/commonjs/utils/textAncestor.web.js.map +1 -0
- package/lib/module/color/Color.js +65 -0
- package/lib/module/color/Color.js.map +1 -0
- package/lib/module/color/index.js +4 -0
- package/lib/module/color/index.js.map +1 -0
- package/lib/module/color/types.js +2 -0
- package/lib/module/color/types.js.map +1 -0
- package/lib/module/color-area/ColorAreaAccessibility.js +96 -0
- package/lib/module/color-area/ColorAreaAccessibility.js.map +1 -0
- package/lib/module/color-area/ColorAreaAccessibility.web.js +54 -0
- package/lib/module/color-area/ColorAreaAccessibility.web.js.map +1 -0
- package/lib/module/color-area/ColorAreaRoot.js +236 -0
- package/lib/module/color-area/ColorAreaRoot.js.map +1 -0
- package/lib/module/color-area/ColorAreaThumb.js +67 -0
- package/lib/module/color-area/ColorAreaThumb.js.map +1 -0
- package/lib/module/color-area/context.js +5 -0
- package/lib/module/color-area/context.js.map +1 -0
- package/lib/module/color-area/index.js +6 -0
- package/lib/module/color-area/index.js.map +1 -0
- package/lib/module/color-area/types.js +4 -0
- package/lib/module/color-area/types.js.map +1 -0
- package/lib/module/color-area/utils.js +45 -0
- package/lib/module/color-area/utils.js.map +1 -0
- package/lib/module/color-field/ColorFieldInput.js +63 -0
- package/lib/module/color-field/ColorFieldInput.js.map +1 -0
- package/lib/module/color-field/ColorFieldRoot.js +100 -0
- package/lib/module/color-field/ColorFieldRoot.js.map +1 -0
- package/lib/module/color-field/context.js +5 -0
- package/lib/module/color-field/context.js.map +1 -0
- package/lib/module/color-field/index.js +6 -0
- package/lib/module/color-field/index.js.map +1 -0
- package/lib/module/color-field/types.js +4 -0
- package/lib/module/color-field/types.js.map +1 -0
- package/lib/module/color-field/utils.js +55 -0
- package/lib/module/color-field/utils.js.map +1 -0
- package/lib/module/color-picker/ColorPickerRoot.js +65 -0
- package/lib/module/color-picker/ColorPickerRoot.js.map +1 -0
- package/lib/module/color-picker/ColorPickerTrigger.js +94 -0
- package/lib/module/color-picker/ColorPickerTrigger.js.map +1 -0
- package/lib/module/color-picker/context.js +25 -0
- package/lib/module/color-picker/context.js.map +1 -0
- package/lib/module/color-picker/index.js +6 -0
- package/lib/module/color-picker/index.js.map +1 -0
- package/lib/module/color-picker/types.js +4 -0
- package/lib/module/color-picker/types.js.map +1 -0
- package/lib/module/color-slider/ColorSliderRail.js +115 -0
- package/lib/module/color-slider/ColorSliderRail.js.map +1 -0
- package/lib/module/color-slider/ColorSliderRoot.js +149 -0
- package/lib/module/color-slider/ColorSliderRoot.js.map +1 -0
- package/lib/module/color-slider/ColorSliderThumb.js +261 -0
- package/lib/module/color-slider/ColorSliderThumb.js.map +1 -0
- package/lib/module/color-slider/context.js +5 -0
- package/lib/module/color-slider/context.js.map +1 -0
- package/lib/module/color-slider/index.js +7 -0
- package/lib/module/color-slider/index.js.map +1 -0
- package/lib/module/color-slider/types.js +4 -0
- package/lib/module/color-slider/types.js.map +1 -0
- package/lib/module/color-slider/utils.js +66 -0
- package/lib/module/color-slider/utils.js.map +1 -0
- package/lib/module/color-swatch-picker/ColorSwatchPickerItem.js +42 -0
- package/lib/module/color-swatch-picker/ColorSwatchPickerItem.js.map +1 -0
- package/lib/module/color-swatch-picker/ColorSwatchPickerRoot.js +67 -0
- package/lib/module/color-swatch-picker/ColorSwatchPickerRoot.js.map +1 -0
- package/lib/module/color-swatch-picker/context.js +15 -0
- package/lib/module/color-swatch-picker/context.js.map +1 -0
- package/lib/module/color-swatch-picker/index.js +6 -0
- package/lib/module/color-swatch-picker/index.js.map +1 -0
- package/lib/module/color-swatch-picker/types.js +4 -0
- package/lib/module/color-swatch-picker/types.js.map +1 -0
- package/lib/module/dialog/DialogContent.js +13 -5
- package/lib/module/dialog/DialogContent.js.map +1 -1
- package/lib/module/dialog/DialogPopup.js +7 -1
- package/lib/module/dialog/DialogPopup.js.map +1 -1
- package/lib/module/dialog/DialogRoot.js +4 -2
- package/lib/module/dialog/DialogRoot.js.map +1 -1
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/portal/portal.js +4 -2
- package/lib/module/portal/portal.js.map +1 -1
- package/lib/module/react-native-web.d.js +2 -0
- package/lib/module/react-native-web.d.js.map +1 -0
- package/lib/module/select/SelectContent.js +2 -1
- package/lib/module/select/SelectContent.js.map +1 -1
- package/lib/module/slider/useSliderPointer.js +2 -0
- package/lib/module/slider/useSliderPointer.js.map +1 -1
- package/lib/module/utils/createPortal.web.js +9 -1
- package/lib/module/utils/createPortal.web.js.map +1 -1
- package/lib/module/utils/textAncestor.js +20 -0
- package/lib/module/utils/textAncestor.js.map +1 -0
- package/lib/module/utils/textAncestor.web.js +22 -0
- package/lib/module/utils/textAncestor.web.js.map +1 -0
- package/lib/typescript/breadcrumbs/types.d.ts +13 -0
- package/lib/typescript/breadcrumbs/types.d.ts.map +1 -1
- package/lib/typescript/checkbox/types.d.ts +4 -0
- package/lib/typescript/checkbox/types.d.ts.map +1 -1
- package/lib/typescript/color/Color.d.ts +3 -0
- package/lib/typescript/color/Color.d.ts.map +1 -0
- package/lib/typescript/color/index.d.ts +3 -0
- package/lib/typescript/color/index.d.ts.map +1 -0
- package/lib/typescript/color/types.d.ts +13 -0
- package/lib/typescript/color/types.d.ts.map +1 -0
- package/lib/typescript/color-area/ColorAreaAccessibility.d.ts +8 -0
- package/lib/typescript/color-area/ColorAreaAccessibility.d.ts.map +1 -0
- package/lib/typescript/color-area/ColorAreaAccessibility.web.d.ts +8 -0
- package/lib/typescript/color-area/ColorAreaAccessibility.web.d.ts.map +1 -0
- package/lib/typescript/color-area/ColorAreaRoot.d.ts +7 -0
- package/lib/typescript/color-area/ColorAreaRoot.d.ts.map +1 -0
- package/lib/typescript/color-area/ColorAreaThumb.d.ts +6 -0
- package/lib/typescript/color-area/ColorAreaThumb.d.ts.map +1 -0
- package/lib/typescript/color-area/context.d.ts +6 -0
- package/lib/typescript/color-area/context.d.ts.map +1 -0
- package/lib/typescript/color-area/index.d.ts +5 -0
- package/lib/typescript/color-area/index.d.ts.map +1 -0
- package/lib/typescript/color-area/types.d.ts +65 -0
- package/lib/typescript/color-area/types.d.ts.map +1 -0
- package/lib/typescript/color-area/utils.d.ts +5 -0
- package/lib/typescript/color-area/utils.d.ts.map +1 -0
- package/lib/typescript/color-field/ColorFieldInput.d.ts +5 -0
- package/lib/typescript/color-field/ColorFieldInput.d.ts.map +1 -0
- package/lib/typescript/color-field/ColorFieldRoot.d.ts +7 -0
- package/lib/typescript/color-field/ColorFieldRoot.d.ts.map +1 -0
- package/lib/typescript/color-field/context.d.ts +6 -0
- package/lib/typescript/color-field/context.d.ts.map +1 -0
- package/lib/typescript/color-field/index.d.ts +7 -0
- package/lib/typescript/color-field/index.d.ts.map +1 -0
- package/lib/typescript/color-field/types.d.ts +39 -0
- package/lib/typescript/color-field/types.d.ts.map +1 -0
- package/lib/typescript/color-field/utils.d.ts +5 -0
- package/lib/typescript/color-field/utils.d.ts.map +1 -0
- package/lib/typescript/color-picker/ColorPickerRoot.d.ts +7 -0
- package/lib/typescript/color-picker/ColorPickerRoot.d.ts.map +1 -0
- package/lib/typescript/color-picker/ColorPickerTrigger.d.ts +4 -0
- package/lib/typescript/color-picker/ColorPickerTrigger.d.ts.map +1 -0
- package/lib/typescript/color-picker/context.d.ts +19 -0
- package/lib/typescript/color-picker/context.d.ts.map +1 -0
- package/lib/typescript/color-picker/index.d.ts +5 -0
- package/lib/typescript/color-picker/index.d.ts.map +1 -0
- package/lib/typescript/color-picker/types.d.ts +24 -0
- package/lib/typescript/color-picker/types.d.ts.map +1 -0
- package/lib/typescript/color-slider/ColorSliderRail.d.ts +6 -0
- package/lib/typescript/color-slider/ColorSliderRail.d.ts.map +1 -0
- package/lib/typescript/color-slider/ColorSliderRoot.d.ts +7 -0
- package/lib/typescript/color-slider/ColorSliderRoot.d.ts.map +1 -0
- package/lib/typescript/color-slider/ColorSliderThumb.d.ts +6 -0
- package/lib/typescript/color-slider/ColorSliderThumb.d.ts.map +1 -0
- package/lib/typescript/color-slider/context.d.ts +6 -0
- package/lib/typescript/color-slider/context.d.ts.map +1 -0
- package/lib/typescript/color-slider/index.d.ts +6 -0
- package/lib/typescript/color-slider/index.d.ts.map +1 -0
- package/lib/typescript/color-slider/types.d.ts +82 -0
- package/lib/typescript/color-slider/types.d.ts.map +1 -0
- package/lib/typescript/color-slider/utils.d.ts +12 -0
- package/lib/typescript/color-slider/utils.d.ts.map +1 -0
- package/lib/typescript/color-swatch-picker/ColorSwatchPickerItem.d.ts +6 -0
- package/lib/typescript/color-swatch-picker/ColorSwatchPickerItem.d.ts.map +1 -0
- package/lib/typescript/color-swatch-picker/ColorSwatchPickerRoot.d.ts +7 -0
- package/lib/typescript/color-swatch-picker/ColorSwatchPickerRoot.d.ts.map +1 -0
- package/lib/typescript/color-swatch-picker/context.d.ts +8 -0
- package/lib/typescript/color-swatch-picker/context.d.ts.map +1 -0
- package/lib/typescript/color-swatch-picker/index.d.ts +5 -0
- package/lib/typescript/color-swatch-picker/index.d.ts.map +1 -0
- package/lib/typescript/color-swatch-picker/types.d.ts +26 -0
- package/lib/typescript/color-swatch-picker/types.d.ts.map +1 -0
- package/lib/typescript/dialog/DialogContent.d.ts +1 -1
- package/lib/typescript/dialog/DialogContent.d.ts.map +1 -1
- package/lib/typescript/dialog/DialogPopup.d.ts.map +1 -1
- package/lib/typescript/dialog/DialogRoot.d.ts.map +1 -1
- package/lib/typescript/dialog/types.d.ts +12 -0
- package/lib/typescript/dialog/types.d.ts.map +1 -1
- package/lib/typescript/field/types.d.ts +1 -1
- package/lib/typescript/field/types.d.ts.map +1 -1
- package/lib/typescript/form/types.d.ts +6 -0
- package/lib/typescript/form/types.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +7 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/input/types.d.ts +1 -0
- package/lib/typescript/input/types.d.ts.map +1 -1
- package/lib/typescript/link/types.d.ts +2 -2
- package/lib/typescript/list-item/types.d.ts +3 -2
- package/lib/typescript/list-item/types.d.ts.map +1 -1
- package/lib/typescript/portal/portal.d.ts +13 -2
- package/lib/typescript/portal/portal.d.ts.map +1 -1
- package/lib/typescript/progress-bar/types.d.ts +9 -4
- package/lib/typescript/progress-bar/types.d.ts.map +1 -1
- package/lib/typescript/radio/types.d.ts +2 -0
- package/lib/typescript/radio/types.d.ts.map +1 -1
- package/lib/typescript/select/SelectContent.d.ts.map +1 -1
- package/lib/typescript/slider/useSliderPointer.d.ts.map +1 -1
- package/lib/typescript/switch/types.d.ts +4 -4
- package/lib/typescript/tabs/types.d.ts +7 -2
- package/lib/typescript/tabs/types.d.ts.map +1 -1
- package/lib/typescript/utils/createPortal.web.d.ts +6 -2
- package/lib/typescript/utils/createPortal.web.d.ts.map +1 -1
- package/lib/typescript/utils/textAncestor.d.ts +13 -0
- package/lib/typescript/utils/textAncestor.d.ts.map +1 -0
- package/lib/typescript/utils/textAncestor.web.d.ts +15 -0
- package/lib/typescript/utils/textAncestor.web.d.ts.map +1 -0
- package/package.json +4 -3
- package/src/breadcrumbs/types.ts +13 -0
- package/src/checkbox/types.ts +4 -0
- package/src/color/Color.ts +95 -0
- package/src/color/index.ts +2 -0
- package/src/color/types.ts +19 -0
- package/src/color-area/ColorAreaAccessibility.tsx +94 -0
- package/src/color-area/ColorAreaAccessibility.web.tsx +52 -0
- package/src/color-area/ColorAreaRoot.tsx +326 -0
- package/src/color-area/ColorAreaThumb.tsx +56 -0
- package/src/color-area/context.tsx +5 -0
- package/src/color-area/index.ts +10 -0
- package/src/color-area/types.ts +69 -0
- package/src/color-area/utils.ts +51 -0
- package/src/color-field/ColorFieldInput.tsx +66 -0
- package/src/color-field/ColorFieldRoot.tsx +132 -0
- package/src/color-field/context.tsx +5 -0
- package/src/color-field/index.ts +11 -0
- package/src/color-field/types.ts +46 -0
- package/src/color-field/utils.ts +75 -0
- package/src/color-picker/ColorPickerRoot.tsx +91 -0
- package/src/color-picker/ColorPickerTrigger.tsx +96 -0
- package/src/color-picker/context.tsx +47 -0
- package/src/color-picker/index.ts +12 -0
- package/src/color-picker/types.ts +25 -0
- package/src/color-slider/ColorSliderRail.tsx +130 -0
- package/src/color-slider/ColorSliderRoot.tsx +222 -0
- package/src/color-slider/ColorSliderThumb.tsx +294 -0
- package/src/color-slider/context.tsx +5 -0
- package/src/color-slider/index.ts +16 -0
- package/src/color-slider/types.ts +94 -0
- package/src/color-slider/utils.ts +79 -0
- package/src/color-swatch-picker/ColorSwatchPickerItem.tsx +54 -0
- package/src/color-swatch-picker/ColorSwatchPickerRoot.tsx +94 -0
- package/src/color-swatch-picker/context.tsx +22 -0
- package/src/color-swatch-picker/index.ts +4 -0
- package/src/color-swatch-picker/types.ts +29 -0
- package/src/dialog/DialogContent.tsx +13 -5
- package/src/dialog/DialogPopup.tsx +7 -1
- package/src/dialog/DialogRoot.tsx +3 -1
- package/src/dialog/types.ts +12 -0
- package/src/field/types.tsx +1 -1
- package/src/form/types.tsx +6 -0
- package/src/index.ts +7 -0
- package/src/input/types.ts +1 -0
- package/src/link/types.ts +2 -2
- package/src/list-item/types.ts +3 -2
- package/src/portal/portal.tsx +17 -2
- package/src/progress-bar/types.ts +9 -4
- package/src/radio/types.ts +2 -0
- package/src/react-native-web.d.ts +6 -0
- package/src/select/SelectContent.tsx +2 -1
- package/src/slider/useSliderPointer.ts +3 -0
- package/src/switch/types.ts +4 -4
- package/src/tabs/types.ts +7 -2
- package/src/utils/createPortal.web.ts +9 -3
- package/src/utils/textAncestor.ts +19 -0
- package/src/utils/textAncestor.web.ts +19 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Color } from '../color';
|
|
2
|
+
import type { ColorSliderConfiguration } from './types';
|
|
3
|
+
|
|
4
|
+
const HUE_STOPS = [0, 60, 120, 180, 240, 300, 360] as const;
|
|
5
|
+
|
|
6
|
+
export function clampColorSliderValue(value: number, min: number, max: number): number {
|
|
7
|
+
return Math.min(max, Math.max(min, value));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getColorSliderRange({ colorSpace, channel }: ColorSliderConfiguration): {
|
|
11
|
+
min: number;
|
|
12
|
+
max: number;
|
|
13
|
+
} {
|
|
14
|
+
if (colorSpace === 'rgb') {
|
|
15
|
+
return { min: 0, max: 255 };
|
|
16
|
+
}
|
|
17
|
+
if (channel === 'hue') {
|
|
18
|
+
return { min: 0, max: 360 };
|
|
19
|
+
}
|
|
20
|
+
return { min: 0, max: 100 };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getColorSliderChannelValue(
|
|
24
|
+
color: Color,
|
|
25
|
+
configuration: ColorSliderConfiguration,
|
|
26
|
+
): number {
|
|
27
|
+
if (configuration.colorSpace === 'rgb') {
|
|
28
|
+
return color.getChannel('rgb', configuration.channel);
|
|
29
|
+
}
|
|
30
|
+
if (configuration.colorSpace === 'hsl') {
|
|
31
|
+
return color.getChannel('hsl', configuration.channel);
|
|
32
|
+
}
|
|
33
|
+
return color.getChannel('hsb', configuration.channel);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function withColorSliderChannel(
|
|
37
|
+
color: Color,
|
|
38
|
+
configuration: ColorSliderConfiguration,
|
|
39
|
+
value: number,
|
|
40
|
+
): Color {
|
|
41
|
+
if (configuration.colorSpace === 'rgb') {
|
|
42
|
+
return color.withChannel('rgb', configuration.channel, value);
|
|
43
|
+
}
|
|
44
|
+
if (configuration.colorSpace === 'hsl') {
|
|
45
|
+
return color.withChannel('hsl', configuration.channel, value);
|
|
46
|
+
}
|
|
47
|
+
return color.withChannel('hsb', configuration.channel, value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function formatColorSliderValue(
|
|
51
|
+
value: number,
|
|
52
|
+
configuration: ColorSliderConfiguration,
|
|
53
|
+
): string {
|
|
54
|
+
const formatted = Number.isInteger(value) ? String(value) : value.toFixed(1);
|
|
55
|
+
if (configuration.channel === 'hue') {
|
|
56
|
+
return `${formatted}°`;
|
|
57
|
+
}
|
|
58
|
+
if (configuration.colorSpace !== 'rgb') {
|
|
59
|
+
return `${formatted}%`;
|
|
60
|
+
}
|
|
61
|
+
return formatted;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getColorSliderGradientColors(
|
|
65
|
+
color: Color,
|
|
66
|
+
configuration: ColorSliderConfiguration,
|
|
67
|
+
): readonly string[] {
|
|
68
|
+
if (configuration.channel === 'hue') {
|
|
69
|
+
return HUE_STOPS.map((value) =>
|
|
70
|
+
withColorSliderChannel(color, configuration, value).toString('hex'),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const { min, max } = getColorSliderRange(configuration);
|
|
75
|
+
return [
|
|
76
|
+
withColorSliderChannel(color, configuration, min).toString('hex'),
|
|
77
|
+
withColorSliderChannel(color, configuration, max).toString('hex'),
|
|
78
|
+
];
|
|
79
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { forwardRef, useEffect, useMemo, type ComponentRef } from 'react';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
3
|
+
import { RadioRoot } from '../radio';
|
|
4
|
+
import { ColorSwatchPickerItemProvider, useColorSwatchPickerContext } from './context';
|
|
5
|
+
import type { IColorSwatchPickerItemProps } from './types';
|
|
6
|
+
|
|
7
|
+
export interface ColorSwatchPickerItemProps extends IColorSwatchPickerItemProps {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ColorSwatchPickerItem = forwardRef<
|
|
12
|
+
ComponentRef<typeof Pressable>,
|
|
13
|
+
ColorSwatchPickerItemProps
|
|
14
|
+
>(
|
|
15
|
+
(
|
|
16
|
+
{
|
|
17
|
+
asChild,
|
|
18
|
+
color,
|
|
19
|
+
isDisabled,
|
|
20
|
+
disabled,
|
|
21
|
+
accessibilityLabel,
|
|
22
|
+
'aria-label': ariaLabelProp,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
},
|
|
26
|
+
ref,
|
|
27
|
+
) => {
|
|
28
|
+
const { registerColor } = useColorSwatchPickerContext();
|
|
29
|
+
const colorValue = color.toString('hex');
|
|
30
|
+
const label = ariaLabelProp ?? accessibilityLabel ?? colorValue;
|
|
31
|
+
const contextValue = useMemo(() => ({ color }), [color]);
|
|
32
|
+
|
|
33
|
+
useEffect(() => registerColor(color), [color, registerColor]);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<ColorSwatchPickerItemProvider value={contextValue}>
|
|
37
|
+
<RadioRoot
|
|
38
|
+
ref={ref}
|
|
39
|
+
asChild={asChild}
|
|
40
|
+
value={colorValue}
|
|
41
|
+
isDisabled={!!(isDisabled || disabled)}
|
|
42
|
+
disabled={disabled}
|
|
43
|
+
aria-label={label}
|
|
44
|
+
accessibilityLabel={label}
|
|
45
|
+
{...props}
|
|
46
|
+
>
|
|
47
|
+
{children}
|
|
48
|
+
</RadioRoot>
|
|
49
|
+
</ColorSwatchPickerItemProvider>
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
ColorSwatchPickerItem.displayName = 'ColorSwatchPickerItem';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { forwardRef, useCallback, useMemo, useRef, type ComponentRef } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { useControllableState } from '@cdx-ui/utils';
|
|
4
|
+
import { RadioGroup } from '../radio';
|
|
5
|
+
import { useOptionalColorPickerContext } from '../color-picker';
|
|
6
|
+
import type { Color } from '../color';
|
|
7
|
+
import { ColorSwatchPickerProvider } from './context';
|
|
8
|
+
import type { IColorSwatchPickerProps } from './types';
|
|
9
|
+
|
|
10
|
+
export interface ColorSwatchPickerRootProps extends IColorSwatchPickerProps {
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const ColorSwatchPickerRoot = forwardRef<
|
|
15
|
+
ComponentRef<typeof View>,
|
|
16
|
+
ColorSwatchPickerRootProps
|
|
17
|
+
>(
|
|
18
|
+
(
|
|
19
|
+
{
|
|
20
|
+
asChild,
|
|
21
|
+
value: valueProp,
|
|
22
|
+
defaultValue,
|
|
23
|
+
onValueChange,
|
|
24
|
+
isDisabled,
|
|
25
|
+
accessibilityLabel,
|
|
26
|
+
children,
|
|
27
|
+
...props
|
|
28
|
+
},
|
|
29
|
+
ref,
|
|
30
|
+
) => {
|
|
31
|
+
const picker = useOptionalColorPickerContext();
|
|
32
|
+
const usesPickerContext =
|
|
33
|
+
picker !== null && valueProp === undefined && defaultValue === undefined;
|
|
34
|
+
|
|
35
|
+
const [localValue, setLocalValue] = useControllableState<Color>({
|
|
36
|
+
prop: valueProp,
|
|
37
|
+
defaultProp: defaultValue,
|
|
38
|
+
onChange: onValueChange,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const value = usesPickerContext ? picker.value : localValue;
|
|
42
|
+
const colorsRef = useRef(new Map<string, Color>());
|
|
43
|
+
|
|
44
|
+
const registerColor = useCallback((color: Color) => {
|
|
45
|
+
const key = color.toString('hex');
|
|
46
|
+
colorsRef.current.set(key, color);
|
|
47
|
+
|
|
48
|
+
return () => {
|
|
49
|
+
if (colorsRef.current.get(key) === color) {
|
|
50
|
+
colorsRef.current.delete(key);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
const handleValueChange = useCallback(
|
|
56
|
+
(key: string) => {
|
|
57
|
+
const color = colorsRef.current.get(key);
|
|
58
|
+
|
|
59
|
+
if (!color) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (usesPickerContext) {
|
|
64
|
+
onValueChange?.(color);
|
|
65
|
+
picker.onValueChange(color);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setLocalValue(color);
|
|
70
|
+
},
|
|
71
|
+
[onValueChange, picker, setLocalValue, usesPickerContext],
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const contextValue = useMemo(() => ({ registerColor }), [registerColor]);
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<ColorSwatchPickerProvider value={contextValue}>
|
|
78
|
+
<RadioGroup
|
|
79
|
+
ref={ref}
|
|
80
|
+
asChild={asChild}
|
|
81
|
+
value={value?.toString('hex')}
|
|
82
|
+
onChange={handleValueChange}
|
|
83
|
+
isDisabled={isDisabled}
|
|
84
|
+
aria-label={props['aria-label'] ?? accessibilityLabel}
|
|
85
|
+
{...props}
|
|
86
|
+
>
|
|
87
|
+
{children}
|
|
88
|
+
</RadioGroup>
|
|
89
|
+
</ColorSwatchPickerProvider>
|
|
90
|
+
);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
ColorSwatchPickerRoot.displayName = 'ColorSwatchPickerRoot';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createContext as createReactContext, useContext } from 'react';
|
|
2
|
+
import { createContext } from '@cdx-ui/utils';
|
|
3
|
+
import type { ColorSwatchPickerContextValue, ColorSwatchPickerItemContextValue } from './types';
|
|
4
|
+
|
|
5
|
+
export const [ColorSwatchPickerProvider, useColorSwatchPickerContext] =
|
|
6
|
+
createContext<ColorSwatchPickerContextValue>('ColorSwatchPickerContext');
|
|
7
|
+
|
|
8
|
+
const ColorSwatchPickerItemContext = createReactContext<ColorSwatchPickerItemContextValue | null>(
|
|
9
|
+
null,
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const ColorSwatchPickerItemProvider = ColorSwatchPickerItemContext.Provider;
|
|
13
|
+
|
|
14
|
+
export function useColorSwatchPickerItemContext(): ColorSwatchPickerItemContextValue {
|
|
15
|
+
const context = useContext(ColorSwatchPickerItemContext);
|
|
16
|
+
|
|
17
|
+
if (!context) {
|
|
18
|
+
throw new Error('ColorSwatchPicker item slots must be used within ColorSwatchPicker.Item');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return context;
|
|
22
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ColorSwatchPickerRoot, type ColorSwatchPickerRootProps } from './ColorSwatchPickerRoot';
|
|
2
|
+
export { ColorSwatchPickerItem, type ColorSwatchPickerItemProps } from './ColorSwatchPickerItem';
|
|
3
|
+
export { useColorSwatchPickerContext, useColorSwatchPickerItemContext } from './context';
|
|
4
|
+
export type { IColorSwatchPickerItemProps, IColorSwatchPickerProps } from './types';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { PressableProps, ViewProps } from 'react-native';
|
|
3
|
+
import type { Color } from '../color';
|
|
4
|
+
|
|
5
|
+
export interface IColorSwatchPickerProps extends Omit<ViewProps, 'children'> {
|
|
6
|
+
value?: Color;
|
|
7
|
+
defaultValue?: Color;
|
|
8
|
+
onValueChange?: (value: Color) => void;
|
|
9
|
+
isDisabled?: boolean;
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IColorSwatchPickerItemProps extends Omit<PressableProps, 'children'> {
|
|
14
|
+
color: Color;
|
|
15
|
+
isDisabled?: boolean;
|
|
16
|
+
isHovered?: boolean;
|
|
17
|
+
isActive?: boolean;
|
|
18
|
+
isFocused?: boolean;
|
|
19
|
+
isFocusVisible?: boolean;
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ColorSwatchPickerContextValue {
|
|
24
|
+
registerColor: (color: Color) => () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ColorSwatchPickerItemContextValue {
|
|
28
|
+
color: Color;
|
|
29
|
+
}
|
|
@@ -14,20 +14,26 @@ export interface DialogContentProps extends IDialogContentProps {}
|
|
|
14
14
|
* - ARIA role, aria-modal, aria-labelledby/describedby
|
|
15
15
|
* - FocusScope (focus trap + restore + auto-focus)
|
|
16
16
|
* - Escape key dismissal (web)
|
|
17
|
-
* - Android hardware back button
|
|
17
|
+
* - Android hardware back button: calls the context `backHandlerRef` when set, otherwise dismisses (native)
|
|
18
18
|
* - data-state attribute for CSS transition targeting
|
|
19
19
|
*
|
|
20
20
|
* Unstyled — the styled layer applies centering, background, border-radius, etc.
|
|
21
21
|
*/
|
|
22
22
|
export const DialogContent = forwardRef<ComponentRef<typeof View>, DialogContentProps>(
|
|
23
23
|
({ asChild = false, forceMount = false, children, ...props }, ref) => {
|
|
24
|
-
const { open, onOpenChange, closeOnEscKey, nativeID, role } = useDialog();
|
|
24
|
+
const { open, onOpenChange, closeOnEscKey, nativeID, role, backHandlerRef } = useDialog();
|
|
25
25
|
|
|
26
26
|
const handleClose = useCallback(() => {
|
|
27
27
|
onOpenChange(false);
|
|
28
28
|
}, [onOpenChange]);
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
const handleEscape = useCallback(() => {
|
|
31
|
+
if (closeOnEscKey) onOpenChange(false);
|
|
32
|
+
}, [closeOnEscKey, onOpenChange]);
|
|
33
|
+
|
|
34
|
+
// Registered regardless of `closeOnEscKey` so a non-dismissible dialog still
|
|
35
|
+
// owns Escape while topmost instead of letting it reach the overlay beneath.
|
|
36
|
+
useEscapeKey(open, handleEscape, {
|
|
31
37
|
id: nativeID,
|
|
32
38
|
groupId: nativeID,
|
|
33
39
|
layer: 'modal',
|
|
@@ -46,14 +52,16 @@ export const DialogContent = forwardRef<ComponentRef<typeof View>, DialogContent
|
|
|
46
52
|
|
|
47
53
|
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
48
54
|
if (!isTopmost('back')) return false;
|
|
49
|
-
|
|
55
|
+
const onBack = backHandlerRef.current;
|
|
56
|
+
if (onBack) onBack();
|
|
57
|
+
else handleClose();
|
|
50
58
|
return true;
|
|
51
59
|
});
|
|
52
60
|
|
|
53
61
|
return () => {
|
|
54
62
|
backHandler.remove();
|
|
55
63
|
};
|
|
56
|
-
}, [handleClose, isTopmost, open]);
|
|
64
|
+
}, [backHandlerRef, handleClose, isTopmost, open]);
|
|
57
65
|
|
|
58
66
|
if (!forceMount && !open) {
|
|
59
67
|
return null;
|
|
@@ -47,7 +47,13 @@ export const DialogPopup = forwardRef<ComponentRef<typeof View>, DialogPopupProp
|
|
|
47
47
|
onOpenChange(false);
|
|
48
48
|
}, [onOpenChange]);
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
const handleEscape = useCallback(() => {
|
|
51
|
+
if (closeOnEscKey) onOpenChange(false);
|
|
52
|
+
}, [closeOnEscKey, onOpenChange]);
|
|
53
|
+
|
|
54
|
+
// Registered regardless of `closeOnEscKey` so a non-dismissible dialog still
|
|
55
|
+
// owns Escape while topmost instead of letting it reach the overlay beneath.
|
|
56
|
+
useEscapeKey(open, handleEscape, {
|
|
51
57
|
id: nativeID,
|
|
52
58
|
groupId: nativeID,
|
|
53
59
|
layer: 'modal',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useCallback, useId, useMemo, type ComponentRef } from 'react';
|
|
1
|
+
import { forwardRef, useCallback, useId, useMemo, useRef, type ComponentRef } from 'react';
|
|
2
2
|
import { View, type ViewProps } from 'react-native';
|
|
3
3
|
import { useControllableState } from '@cdx-ui/utils';
|
|
4
4
|
import { Slot } from '../slot';
|
|
@@ -40,6 +40,7 @@ export const DialogRoot = forwardRef<ComponentRef<typeof View>, DialogRootProps>
|
|
|
40
40
|
|
|
41
41
|
const id = useId();
|
|
42
42
|
const nativeID = `dialog-${id}`;
|
|
43
|
+
const backHandlerRef = useRef<(() => void) | undefined>(undefined);
|
|
43
44
|
|
|
44
45
|
const contextValue = useMemo(
|
|
45
46
|
() => ({
|
|
@@ -49,6 +50,7 @@ export const DialogRoot = forwardRef<ComponentRef<typeof View>, DialogRootProps>
|
|
|
49
50
|
closeOnEscKey,
|
|
50
51
|
nativeID,
|
|
51
52
|
role,
|
|
53
|
+
backHandlerRef,
|
|
52
54
|
}),
|
|
53
55
|
[open, setOpen, closeOnBackdropPress, closeOnEscKey, nativeID, role],
|
|
54
56
|
);
|
package/src/dialog/types.ts
CHANGED
|
@@ -8,6 +8,11 @@ export interface IDialogContextType {
|
|
|
8
8
|
readonly closeOnEscKey: boolean;
|
|
9
9
|
readonly nativeID: string;
|
|
10
10
|
readonly role: 'dialog' | 'alertdialog';
|
|
11
|
+
/**
|
|
12
|
+
* @internal Set by a header that owns step navigation. When set, Android back
|
|
13
|
+
* calls it instead of closing the dialog. Escape always closes.
|
|
14
|
+
*/
|
|
15
|
+
readonly backHandlerRef: React.RefObject<(() => void) | undefined>;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
export interface IDialogRootProps {
|
|
@@ -16,6 +21,12 @@ export interface IDialogRootProps {
|
|
|
16
21
|
readonly onOpenChange?: (open: boolean) => void;
|
|
17
22
|
readonly defaultOpen?: boolean;
|
|
18
23
|
readonly closeOnBackdropPress?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Close when Escape is pressed. Web only. When `false`, an open dialog still
|
|
26
|
+
* consumes Escape while topmost, so overlays beneath it stay open. Android's
|
|
27
|
+
* hardware back button dismisses independently of this prop.
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
19
30
|
readonly closeOnEscKey?: boolean;
|
|
20
31
|
readonly role?: 'dialog' | 'alertdialog';
|
|
21
32
|
readonly children: React.ReactNode;
|
|
@@ -38,6 +49,7 @@ export interface IDialogOverlayProps extends PressableProps {
|
|
|
38
49
|
|
|
39
50
|
export interface IDialogContentProps extends ViewProps {
|
|
40
51
|
readonly asChild?: boolean;
|
|
52
|
+
/** Keep the popup mounted while the dialog is closed. @default false */
|
|
41
53
|
readonly forceMount?: boolean;
|
|
42
54
|
/**
|
|
43
55
|
* Whether the content shifts up to clear the on-screen keyboard (native only).
|
package/src/field/types.tsx
CHANGED
|
@@ -23,7 +23,7 @@ export interface IFieldRootProps extends ViewProps {
|
|
|
23
23
|
readonly isInvalid?: boolean;
|
|
24
24
|
/** If true, the field is marked as required. Shows asterisk on label. */
|
|
25
25
|
readonly isRequired?: boolean;
|
|
26
|
-
/** If true, the field is disabled. */
|
|
26
|
+
/** If true, the field is disabled. Nested controls that read field context are disabled as well. */
|
|
27
27
|
readonly isDisabled?: boolean;
|
|
28
28
|
/** If true, the field is read-only. */
|
|
29
29
|
readonly isReadOnly?: boolean;
|
package/src/form/types.tsx
CHANGED
|
@@ -6,8 +6,14 @@ import type React from 'react';
|
|
|
6
6
|
* for API compatibility but silently ignored.
|
|
7
7
|
*/
|
|
8
8
|
export interface InterfaceFormRootProps {
|
|
9
|
+
/** Called when the form is submitted. Web only; ignored on native. */
|
|
9
10
|
onSubmit?: (e: React.SyntheticEvent) => void;
|
|
11
|
+
/**
|
|
12
|
+
* HTML `action` URL, or a function that receives the submitted `FormData`.
|
|
13
|
+
* Web only; ignored on native.
|
|
14
|
+
*/
|
|
10
15
|
action?: string | ((formData: FormData) => void | Promise<void>);
|
|
16
|
+
/** HTTP method. Web only; ignored on native. */
|
|
11
17
|
method?: string;
|
|
12
18
|
}
|
|
13
19
|
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,12 @@ export * from './breadcrumbs';
|
|
|
3
3
|
export * from './button';
|
|
4
4
|
export * from './chip';
|
|
5
5
|
export * from './checkbox';
|
|
6
|
+
export * from './color';
|
|
7
|
+
export * from './color-area';
|
|
8
|
+
export * from './color-field';
|
|
9
|
+
export * from './color-picker';
|
|
10
|
+
export * from './color-slider';
|
|
11
|
+
export * from './color-swatch-picker';
|
|
6
12
|
export * from './dialog';
|
|
7
13
|
export * from './drawer';
|
|
8
14
|
export * from './field';
|
|
@@ -80,4 +86,5 @@ export {
|
|
|
80
86
|
export { mapViewPropsToDom, type MapViewPropsToDomOptions } from './utils/mapViewPropsToDom';
|
|
81
87
|
export { assignRef } from './utils/assignRef';
|
|
82
88
|
export { createPortalFn } from './utils/createPortal';
|
|
89
|
+
export { useHasTextAncestor } from './utils/textAncestor';
|
|
83
90
|
export { Slot } from './slot';
|
package/src/input/types.ts
CHANGED
package/src/link/types.ts
CHANGED
|
@@ -16,11 +16,11 @@ export type LinkAction = 'navigate' | 'push' | 'replace';
|
|
|
16
16
|
|
|
17
17
|
export interface ILinkProps extends PressableProps {
|
|
18
18
|
/**
|
|
19
|
-
* URL
|
|
19
|
+
* URL or route path opened on press. Omit when the link only runs `onPress`.
|
|
20
20
|
*/
|
|
21
21
|
href?: string | undefined;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Invoked on press before navigation. Does not replace navigation.
|
|
24
24
|
*/
|
|
25
25
|
onPress?: ((event?: GestureResponderEvent) => void) | null | undefined;
|
|
26
26
|
/**
|
package/src/list-item/types.ts
CHANGED
|
@@ -29,8 +29,9 @@ export interface InterfaceListItemProps extends ViewProps, IListItemPressablePas
|
|
|
29
29
|
*/
|
|
30
30
|
crossAlign?: ListItemCrossAlign;
|
|
31
31
|
/**
|
|
32
|
-
* Merge
|
|
33
|
-
*
|
|
32
|
+
* Merge props onto a single child (for example `Link`) instead of rendering `View` or `Pressable`.
|
|
33
|
+
* The child's `onPress` is kept unless this component also passes `onPress`.
|
|
34
|
+
* `isDisabled` suppresses press on the child.
|
|
34
35
|
*/
|
|
35
36
|
asChild?: boolean;
|
|
36
37
|
}
|
package/src/portal/portal.tsx
CHANGED
|
@@ -130,7 +130,21 @@ export function PortalProvider({ children }: Readonly<{ children: React.ReactNod
|
|
|
130
130
|
|
|
131
131
|
// --------------------------------------------------
|
|
132
132
|
|
|
133
|
-
export
|
|
133
|
+
export interface PortalHostProps {
|
|
134
|
+
/** Host name that `Portal` targets through `hostName`. @default the shared default host */
|
|
135
|
+
name?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Web only. Element that receives the portal content instead of `document.body`.
|
|
138
|
+
*
|
|
139
|
+
* Use it to keep overlays inside an embedded surface, such as a device preview. Fixed
|
|
140
|
+
* overlays stay inside the container only when an ancestor of it creates a containing
|
|
141
|
+
* block for fixed descendants, for example through a `transform`. While `null`, such as
|
|
142
|
+
* before a callback ref attaches, the host renders nothing. Ignored on native.
|
|
143
|
+
*/
|
|
144
|
+
container?: Element | null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function PortalHost({ name = DEFAULT_PORTAL_HOST, container }: PortalHostProps) {
|
|
134
148
|
const registry = React.useContext(PortalRegistryContext) ?? fallbackPortalRegistry;
|
|
135
149
|
const hostId = React.useRef(Symbol()).current;
|
|
136
150
|
|
|
@@ -167,7 +181,8 @@ export function PortalHost({ name = DEFAULT_PORTAL_HOST }: { name?: string }) {
|
|
|
167
181
|
);
|
|
168
182
|
|
|
169
183
|
if (Platform.OS === 'web' && createPortalFn && typeof document !== 'undefined') {
|
|
170
|
-
|
|
184
|
+
if (container === null) return null;
|
|
185
|
+
return createPortalFn(content, container ?? document.body);
|
|
171
186
|
}
|
|
172
187
|
|
|
173
188
|
return content;
|
|
@@ -5,17 +5,22 @@ export type ProgressDataState = 'complete' | 'indeterminate' | 'loading';
|
|
|
5
5
|
|
|
6
6
|
export interface InterfaceProgressProps extends Omit<ViewProps, 'children'> {
|
|
7
7
|
/**
|
|
8
|
-
* Current value in the range [0, max]
|
|
9
|
-
*
|
|
8
|
+
* Current value in the range `[0, max]`, or `null` for indeterminate progress.
|
|
9
|
+
* Values below `0` clamp to `0`; values above `max` clamp to `max`.
|
|
10
|
+
* Non-finite values (such as `NaN`) are treated as `0`.
|
|
11
|
+
* @default 0
|
|
10
12
|
*/
|
|
11
13
|
readonly value?: number | null;
|
|
12
14
|
/**
|
|
13
|
-
* Maximum value
|
|
15
|
+
* Maximum value. The minimum is always `0`.
|
|
16
|
+
* A `max` of `0` or less is treated as complete.
|
|
14
17
|
* @default 100
|
|
15
18
|
*/
|
|
16
19
|
readonly max?: number;
|
|
17
20
|
/**
|
|
18
|
-
*
|
|
21
|
+
* Screen-reader text for determinate progress (`accessibilityValue.text`).
|
|
22
|
+
* Defaults to a rounded percentage of `max`, such as `"45%"`.
|
|
23
|
+
* No effect when `value` is `null`, or when `accessibilityValue` is set.
|
|
19
24
|
*/
|
|
20
25
|
readonly getValueLabel?: (value: number, max: number) => string;
|
|
21
26
|
readonly children?: ReactNode;
|
package/src/radio/types.ts
CHANGED
|
@@ -3,8 +3,10 @@ import type { PressableProps } from 'react-native';
|
|
|
3
3
|
export interface IRadioProps extends PressableProps {
|
|
4
4
|
/** Required — identifies this item's value within a Radio.Group. */
|
|
5
5
|
value: string;
|
|
6
|
+
/** Disables this item without disabling the rest of the group. */
|
|
6
7
|
isDisabled?: boolean;
|
|
7
8
|
isInvalid?: boolean;
|
|
9
|
+
/** Focusable, but the selection cannot be changed. */
|
|
8
10
|
isReadOnly?: boolean;
|
|
9
11
|
isHovered?: boolean;
|
|
10
12
|
isFocused?: boolean;
|
|
@@ -2,7 +2,7 @@ import React, { forwardRef, useCallback, useRef, type ComponentRef } from 'react
|
|
|
2
2
|
import { Platform, View } from 'react-native';
|
|
3
3
|
import { FadeIn, FadeOut } from 'react-native-reanimated';
|
|
4
4
|
import { composeEventHandlers, mergeRefs } from '@cdx-ui/utils';
|
|
5
|
-
import { OverlayContainer, useAnchoredOverlay, useDismissOverlay } from '../overlay';
|
|
5
|
+
import { OverlayContainer, useAnchoredOverlay, useDismissOverlay, useEscapeKey } from '../overlay';
|
|
6
6
|
import { Slot } from '../slot';
|
|
7
7
|
import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
|
|
8
8
|
import { useSelectContext } from './context';
|
|
@@ -76,6 +76,7 @@ export const SelectContent = forwardRef<ComponentRef<typeof View>, SelectContent
|
|
|
76
76
|
const mergedRef = mergeRefs(ref, focusOnMount as unknown as React.Ref<View>, floatingRef);
|
|
77
77
|
|
|
78
78
|
useDismissOverlay(overlayOpen, contentRef, [triggerRef], dismiss);
|
|
79
|
+
useEscapeKey(overlayOpen, dismiss);
|
|
79
80
|
|
|
80
81
|
const { handleKeyDown } = useListboxNavigation({
|
|
81
82
|
items,
|
|
@@ -97,6 +97,9 @@ export function useWebSliderDrag({
|
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
cleanupRef.current?.();
|
|
101
|
+
cleanupRef.current = null;
|
|
102
|
+
|
|
100
103
|
const trackSize = orientation === 'horizontal' ? layout.width : layout.height;
|
|
101
104
|
const travel = getThumbTravel(trackSize, thumbSize);
|
|
102
105
|
if (travel <= 0) {
|
package/src/switch/types.ts
CHANGED
|
@@ -7,11 +7,11 @@ export interface IInterfaceSwitchProps {
|
|
|
7
7
|
*/
|
|
8
8
|
onValueChange?: (value: boolean) => void;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Alias for `value`. `value` takes precedence when both are set.
|
|
11
11
|
*/
|
|
12
12
|
isChecked?: boolean;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Controlled on/off state. Takes precedence over `isChecked`.
|
|
15
15
|
*/
|
|
16
16
|
value?: boolean;
|
|
17
17
|
/**
|
|
@@ -19,11 +19,11 @@ export interface IInterfaceSwitchProps {
|
|
|
19
19
|
*/
|
|
20
20
|
isDisabled?: boolean;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Alias for `isDisabled`. Either prop disables the switch.
|
|
23
23
|
*/
|
|
24
24
|
disabled?: boolean;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Initial state when uncontrolled. No effect when `value` or `isChecked` is set.
|
|
27
27
|
*/
|
|
28
28
|
defaultValue?: boolean;
|
|
29
29
|
/**
|
package/src/tabs/types.ts
CHANGED
|
@@ -13,7 +13,8 @@ export interface ITabsProps {
|
|
|
13
13
|
onValueChange?: (value: string) => void;
|
|
14
14
|
/**
|
|
15
15
|
* `automatic` (default) selects a tab as soon as it receives focus via arrow keys.
|
|
16
|
-
* `manual` only moves focus
|
|
16
|
+
* `manual` only moves focus — press Enter or Space to select. Web only; native
|
|
17
|
+
* selection follows press. Use `manual` when rendering the next panel is expensive.
|
|
17
18
|
*/
|
|
18
19
|
activationMode?: TabsActivationMode;
|
|
19
20
|
/**
|
|
@@ -21,6 +22,7 @@ export interface ITabsProps {
|
|
|
21
22
|
* `vertical` uses ArrowUp/ArrowDown, per the ARIA APG tabs pattern.
|
|
22
23
|
*/
|
|
23
24
|
orientation?: TabsOrientation;
|
|
25
|
+
/** Disables every tab. Disable a single tab with `disabled` on that `Tabs.Tab`. */
|
|
24
26
|
disabled?: boolean;
|
|
25
27
|
children?: ReactNode;
|
|
26
28
|
}
|
|
@@ -63,7 +65,10 @@ export interface ITabProps extends PressableProps {
|
|
|
63
65
|
export interface ITabPanelProps extends ViewProps {
|
|
64
66
|
/** Required — correlates this panel with its `Tabs.Tab` counterpart. */
|
|
65
67
|
value: string;
|
|
66
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Unmount when inactive instead of keeping the panel mounted and hidden.
|
|
70
|
+
* The default keeps it mounted so the tab's `aria-controls` target stays in the tree.
|
|
71
|
+
*/
|
|
67
72
|
unmountWhenInactive?: boolean;
|
|
68
73
|
children?: ReactNode;
|
|
69
74
|
}
|