@fluentui/react-switch 9.0.0-rc.3 → 9.0.0-rc.4
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/CHANGELOG.json +40 -1
- package/CHANGELOG.md +15 -2
- package/dist/react-switch.d.ts +57 -40
- package/lib/components/Switch/Switch.d.ts +1 -1
- package/lib/components/Switch/Switch.js +1 -1
- package/lib/components/Switch/Switch.js.map +1 -1
- package/lib/components/Switch/Switch.types.d.ts +41 -35
- package/lib/components/Switch/Switch.types.js.map +1 -1
- package/lib/components/Switch/renderSwitch.d.ts +1 -1
- package/lib/components/Switch/renderSwitch.js +8 -6
- package/lib/components/Switch/renderSwitch.js.map +1 -1
- package/lib/components/Switch/useSwitch.d.ts +8 -2
- package/lib/components/Switch/useSwitch.js +63 -43
- package/lib/components/Switch/useSwitch.js.map +1 -1
- package/lib/components/Switch/useSwitchStyles.d.ts +5 -2
- package/lib/components/Switch/useSwitchStyles.js +144 -262
- package/lib/components/Switch/useSwitchStyles.js.map +1 -1
- package/lib-commonjs/components/Switch/Switch.d.ts +1 -1
- package/lib-commonjs/components/Switch/Switch.js +1 -1
- package/lib-commonjs/components/Switch/Switch.js.map +1 -1
- package/lib-commonjs/components/Switch/Switch.types.d.ts +41 -35
- package/lib-commonjs/components/Switch/renderSwitch.d.ts +1 -1
- package/lib-commonjs/components/Switch/renderSwitch.js +8 -6
- package/lib-commonjs/components/Switch/renderSwitch.js.map +1 -1
- package/lib-commonjs/components/Switch/useSwitch.d.ts +8 -2
- package/lib-commonjs/components/Switch/useSwitch.js +65 -43
- package/lib-commonjs/components/Switch/useSwitch.js.map +1 -1
- package/lib-commonjs/components/Switch/useSwitchStyles.d.ts +5 -2
- package/lib-commonjs/components/Switch/useSwitchStyles.js +146 -264
- package/lib-commonjs/components/Switch/useSwitchStyles.js.map +1 -1
- package/package.json +6 -4
- package/lib/components/Switch/useSwitchState.d.ts +0 -2
- package/lib/components/Switch/useSwitchState.js +0 -144
- package/lib/components/Switch/useSwitchState.js.map +0 -1
- package/lib-commonjs/components/Switch/useSwitchState.d.ts +0 -2
- package/lib-commonjs/components/Switch/useSwitchState.js +0 -156
- package/lib-commonjs/components/Switch/useSwitchState.js.map +0 -1
@@ -1,144 +0,0 @@
|
|
1
|
-
import * as React from 'react';
|
2
|
-
import { clamp, useBoolean, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';
|
3
|
-
import { useFluent } from '@fluentui/react-shared-contexts'; // TODO: This should be replaced with a useEvent hook
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
5
|
-
|
6
|
-
const on = (element, eventName, callback) => {
|
7
|
-
element.addEventListener(eventName, callback);
|
8
|
-
return () => element.removeEventListener(eventName, callback);
|
9
|
-
};
|
10
|
-
|
11
|
-
export const useSwitchState = state => {
|
12
|
-
const {
|
13
|
-
defaultChecked = false,
|
14
|
-
checked,
|
15
|
-
disabled = false,
|
16
|
-
onChange
|
17
|
-
} = state;
|
18
|
-
const {
|
19
|
-
onPointerDown: onPointerDownCallback,
|
20
|
-
onKeyUp: onKeyUpCallback
|
21
|
-
} = state.root;
|
22
|
-
const {
|
23
|
-
dir
|
24
|
-
} = useFluent();
|
25
|
-
const inputRef = useMergedRefs(state.input.ref);
|
26
|
-
const railRef = React.useRef(null);
|
27
|
-
const internalState = React.useRef({
|
28
|
-
internalValue: checked ? checked : defaultChecked,
|
29
|
-
thumbIsDragging: false,
|
30
|
-
disposables: []
|
31
|
-
});
|
32
|
-
const [currentValue, setCurrentValue] = useControllableState({
|
33
|
-
defaultState: defaultChecked,
|
34
|
-
state: checked,
|
35
|
-
initialState: false
|
36
|
-
});
|
37
|
-
const [thumbAnimation, {
|
38
|
-
setTrue: showThumbAnimation,
|
39
|
-
setFalse: hideThumbAnimation
|
40
|
-
}] = useBoolean(true);
|
41
|
-
const [renderedPosition, setRenderedPosition] = React.useState(undefined);
|
42
|
-
const setChecked = useEventCallback((ev, incomingValue) => {
|
43
|
-
ev.stopPropagation();
|
44
|
-
ev.preventDefault();
|
45
|
-
internalState.current.internalValue = incomingValue;
|
46
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(ev, {
|
47
|
-
checked: incomingValue
|
48
|
-
});
|
49
|
-
setCurrentValue(incomingValue);
|
50
|
-
setRenderedPosition(undefined);
|
51
|
-
});
|
52
|
-
const calculatePosition = React.useCallback(ev => {
|
53
|
-
var _a;
|
54
|
-
|
55
|
-
const currentBounds = (_a = railRef === null || railRef === void 0 ? void 0 : railRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
56
|
-
const railWidth = currentBounds.width;
|
57
|
-
const railPosition = dir === 'rtl' ? currentBounds.right : currentBounds.left;
|
58
|
-
const distance = dir === 'rtl' ? railPosition - ev.clientX : ev.clientX - railPosition;
|
59
|
-
return clamp(distance / railWidth * 100, 0, 100);
|
60
|
-
}, [dir]);
|
61
|
-
const onPointerMove = React.useCallback(ev => {
|
62
|
-
const incomingPosition = calculatePosition(ev);
|
63
|
-
internalState.current.thumbIsDragging = true;
|
64
|
-
hideThumbAnimation();
|
65
|
-
setRenderedPosition(incomingPosition); // If the Switch reaches a new position of 0% or 100%, update the state and fire change.
|
66
|
-
|
67
|
-
if (incomingPosition === 100 && internalState.current.internalValue !== true) {
|
68
|
-
setChecked(ev, true);
|
69
|
-
} else if (incomingPosition === 0 && internalState.current.internalValue !== false) {
|
70
|
-
setChecked(ev, false);
|
71
|
-
}
|
72
|
-
}, [calculatePosition, hideThumbAnimation, setChecked]);
|
73
|
-
const onPointerUp = React.useCallback(ev => {
|
74
|
-
internalState.current.disposables.forEach(dispose => dispose());
|
75
|
-
internalState.current.disposables = [];
|
76
|
-
inputRef.current.focus();
|
77
|
-
|
78
|
-
if (internalState.current.thumbIsDragging) {
|
79
|
-
const roundedPosition = Math.round(calculatePosition(ev) / 100) * 100;
|
80
|
-
showThumbAnimation();
|
81
|
-
|
82
|
-
if (roundedPosition === 100) {
|
83
|
-
setChecked(ev, true);
|
84
|
-
} else if (roundedPosition === 0) {
|
85
|
-
setChecked(ev, false);
|
86
|
-
}
|
87
|
-
} else {
|
88
|
-
setChecked(ev, !internalState.current.internalValue);
|
89
|
-
}
|
90
|
-
}, [calculatePosition, inputRef, setChecked, showThumbAnimation]);
|
91
|
-
const onPointerDown = React.useCallback(ev => {
|
92
|
-
var _a;
|
93
|
-
|
94
|
-
const {
|
95
|
-
pointerId
|
96
|
-
} = ev;
|
97
|
-
const target = ev.target;
|
98
|
-
onPointerDownCallback === null || onPointerDownCallback === void 0 ? void 0 : onPointerDownCallback(ev);
|
99
|
-
showThumbAnimation();
|
100
|
-
(_a = target.setPointerCapture) === null || _a === void 0 ? void 0 : _a.call(target, pointerId);
|
101
|
-
internalState.current.thumbIsDragging = false;
|
102
|
-
internalState.current.disposables.push(on(target, 'pointermove', onPointerMove), on(target, 'pointerup', onPointerUp), () => {
|
103
|
-
var _a;
|
104
|
-
|
105
|
-
(_a = target.releasePointerCapture) === null || _a === void 0 ? void 0 : _a.call(target, pointerId);
|
106
|
-
});
|
107
|
-
}, [onPointerDownCallback, onPointerMove, onPointerUp, showThumbAnimation]);
|
108
|
-
const onKeyUp = React.useCallback(ev => {
|
109
|
-
onKeyUpCallback === null || onKeyUpCallback === void 0 ? void 0 : onKeyUpCallback(ev);
|
110
|
-
|
111
|
-
if (ev.key === ' ') {
|
112
|
-
setChecked(ev, !internalState.current.internalValue);
|
113
|
-
}
|
114
|
-
}, [onKeyUpCallback, setChecked]);
|
115
|
-
const currentPosition = renderedPosition !== undefined ? renderedPosition : currentValue ? 100 : 0;
|
116
|
-
const rootStyles = {
|
117
|
-
'--switch-checked-opacity': currentPosition / 100,
|
118
|
-
'--switch-unchecked-opacity': (100 - currentPosition) / 100
|
119
|
-
};
|
120
|
-
const thumbWrapperStyles = {
|
121
|
-
transform: `translate(${dir === 'rtl' ? -currentPosition : currentPosition}%)`,
|
122
|
-
transition: thumbAnimation ? 'transform .1s cubic-bezier(0.33, 0.0, 0.67, 1), opacity .1s cubic-bezier(0.33, 0.0, 0.67, 1)' : 'none'
|
123
|
-
}; // Root Props
|
124
|
-
|
125
|
-
state.root.style = rootStyles;
|
126
|
-
|
127
|
-
if (!disabled) {
|
128
|
-
state.root.onPointerDown = onPointerDown;
|
129
|
-
state.root.onKeyUp = onKeyUp;
|
130
|
-
} // Input Props
|
131
|
-
|
132
|
-
|
133
|
-
state.input.checked = currentValue;
|
134
|
-
state.input.disabled = disabled;
|
135
|
-
state.input.ref = inputRef;
|
136
|
-
state.input.readOnly = true;
|
137
|
-
state.input.role = 'switch'; // Thumb Container Props
|
138
|
-
|
139
|
-
state.thumbWrapper.style = thumbWrapperStyles; // Active Rail Props
|
140
|
-
|
141
|
-
state.activeRail.ref = railRef;
|
142
|
-
return state;
|
143
|
-
};
|
144
|
-
//# sourceMappingURL=useSwitchState.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["components/Switch/useSwitchState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAZ,MAAuB,OAAvB;AACA,SAAS,KAAT,EAAgB,UAAhB,EAA4B,oBAA5B,EAAkD,gBAAlD,EAAoE,aAApE,QAAyF,2BAAzF;AACA,SAAS,SAAT,QAA0B,iCAA1B,C,CAoBA;AACA;;AACA,MAAM,EAAE,GAAG,CAAC,OAAD,EAAmB,SAAnB,EAAsC,QAAtC,KAAqE;AAC9E,EAAA,OAAO,CAAC,gBAAR,CAAyB,SAAzB,EAAoC,QAApC;AACA,SAAO,MAAM,OAAO,CAAC,mBAAR,CAA4B,SAA5B,EAAuC,QAAvC,CAAb;AACD,CAHD;;AAKA,OAAO,MAAM,cAAc,GAAI,KAAD,IAAuB;AACnD,QAAM;AAAE,IAAA,cAAc,GAAG,KAAnB;AAA0B,IAAA,OAA1B;AAAmC,IAAA,QAAQ,GAAG,KAA9C;AAAqD,IAAA;AAArD,MAAkE,KAAxE;AACA,QAAM;AAAE,IAAA,aAAa,EAAE,qBAAjB;AAAwC,IAAA,OAAO,EAAE;AAAjD,MAAqE,KAAK,CAAC,IAAjF;AAEA,QAAM;AAAE,IAAA;AAAF,MAAU,SAAS,EAAzB;AACA,QAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,KAAN,CAAY,GAAb,CAA9B;AACA,QAAM,OAAO,GAAG,KAAK,CAAC,MAAN,CAA6B,IAA7B,CAAhB;AACA,QAAM,aAAa,GAAG,KAAK,CAAC,MAAN,CAAkC;AACtD,IAAA,aAAa,EAAE,OAAO,GAAG,OAAH,GAAa,cADmB;AAEtD,IAAA,eAAe,EAAE,KAFqC;AAGtD,IAAA,WAAW,EAAE;AAHyC,GAAlC,CAAtB;AAMA,QAAM,CAAC,YAAD,EAAe,eAAf,IAAkC,oBAAoB,CAAC;AAC3D,IAAA,YAAY,EAAE,cAD6C;AAE3D,IAAA,KAAK,EAAE,OAFoD;AAG3D,IAAA,YAAY,EAAE;AAH6C,GAAD,CAA5D;AAKA,QAAM,CAAC,cAAD,EAAiB;AAAE,IAAA,OAAO,EAAE,kBAAX;AAA+B,IAAA,QAAQ,EAAE;AAAzC,GAAjB,IAAkF,UAAU,CAAC,IAAD,CAAlG;AACA,QAAM,CAAC,gBAAD,EAAmB,mBAAnB,IAA0C,KAAK,CAAC,QAAN,CAAmC,SAAnC,CAAhD;AAEA,QAAM,UAAU,GAAG,gBAAgB,CACjC,CAAC,EAAD,EAA+E,aAA/E,KAAyG;AACvG,IAAA,EAAE,CAAC,eAAH;AACA,IAAA,EAAE,CAAC,cAAH;AACA,IAAA,aAAa,CAAC,OAAd,CAAsB,aAAtB,GAAsC,aAAtC;AACA,IAAA,QAAQ,KAAA,IAAR,IAAA,QAAQ,KAAA,KAAA,CAAR,GAAQ,KAAA,CAAR,GAAA,QAAQ,CAAG,EAAH,EAAO;AAAE,MAAA,OAAO,EAAE;AAAX,KAAP,CAAR;AACA,IAAA,eAAe,CAAC,aAAD,CAAf;AACA,IAAA,mBAAmB,CAAC,SAAD,CAAnB;AACD,GARgC,CAAnC;AAWA,QAAM,iBAAiB,GAAG,KAAK,CAAC,WAAN,CACvB,EAAD,IAAmD;;;AACjD,UAAM,aAAa,GAAG,CAAA,EAAA,GAAA,OAAO,KAAA,IAAP,IAAA,OAAO,KAAA,KAAA,CAAP,GAAO,KAAA,CAAP,GAAA,OAAO,CAAE,OAAT,MAAgB,IAAhB,IAAgB,EAAA,KAAA,KAAA,CAAhB,GAAgB,KAAA,CAAhB,GAAgB,EAAA,CAAE,qBAAF,EAAtC;AACA,UAAM,SAAS,GAAG,aAAc,CAAC,KAAjC;AACA,UAAM,YAAY,GAAG,GAAG,KAAK,KAAR,GAAgB,aAAc,CAAC,KAA/B,GAAuC,aAAc,CAAC,IAA3E;AACA,UAAM,QAAQ,GAAG,GAAG,KAAK,KAAR,GAAgB,YAAY,GAAG,EAAE,CAAC,OAAlC,GAA4C,EAAE,CAAC,OAAH,GAAa,YAA1E;AACA,WAAO,KAAK,CAAE,QAAQ,GAAG,SAAZ,GAAyB,GAA1B,EAA+B,CAA/B,EAAkC,GAAlC,CAAZ;AACD,GAPuB,EAQxB,CAAC,GAAD,CARwB,CAA1B;AAWA,QAAM,aAAa,GAAG,KAAK,CAAC,WAAN,CACnB,EAAD,IAAiD;AAC/C,UAAM,gBAAgB,GAAG,iBAAiB,CAAC,EAAD,CAA1C;AAEA,IAAA,aAAa,CAAC,OAAd,CAAsB,eAAtB,GAAwC,IAAxC;AACA,IAAA,kBAAkB;AAClB,IAAA,mBAAmB,CAAC,gBAAD,CAAnB,CAL+C,CAO/C;;AACA,QAAI,gBAAgB,KAAK,GAArB,IAA4B,aAAa,CAAC,OAAd,CAAsB,aAAtB,KAAwC,IAAxE,EAA8E;AAC5E,MAAA,UAAU,CAAC,EAAD,EAAK,IAAL,CAAV;AACD,KAFD,MAEO,IAAI,gBAAgB,KAAK,CAArB,IAA0B,aAAa,CAAC,OAAd,CAAsB,aAAtB,KAAwC,KAAtE,EAA6E;AAClF,MAAA,UAAU,CAAC,EAAD,EAAK,KAAL,CAAV;AACD;AACF,GAdmB,EAepB,CAAC,iBAAD,EAAoB,kBAApB,EAAwC,UAAxC,CAfoB,CAAtB;AAkBA,QAAM,WAAW,GAAG,KAAK,CAAC,WAAN,CACjB,EAAD,IAAiD;AAC/C,IAAA,aAAa,CAAC,OAAd,CAAsB,WAAtB,CAAkC,OAAlC,CAA0C,OAAO,IAAI,OAAO,EAA5D;AACA,IAAA,aAAa,CAAC,OAAd,CAAsB,WAAtB,GAAoC,EAApC;AACA,IAAA,QAAQ,CAAC,OAAT,CAAkB,KAAlB;;AAEA,QAAI,aAAa,CAAC,OAAd,CAAsB,eAA1B,EAA2C;AACzC,YAAM,eAAe,GAAG,IAAI,CAAC,KAAL,CAAW,iBAAiB,CAAC,EAAD,CAAjB,GAAyB,GAApC,IAA2C,GAAnE;AAEA,MAAA,kBAAkB;;AAClB,UAAI,eAAe,KAAK,GAAxB,EAA6B;AAC3B,QAAA,UAAU,CAAC,EAAD,EAAK,IAAL,CAAV;AACD,OAFD,MAEO,IAAI,eAAe,KAAK,CAAxB,EAA2B;AAChC,QAAA,UAAU,CAAC,EAAD,EAAK,KAAL,CAAV;AACD;AACF,KATD,MASO;AACL,MAAA,UAAU,CAAC,EAAD,EAAK,CAAC,aAAa,CAAC,OAAd,CAAsB,aAA5B,CAAV;AACD;AACF,GAlBiB,EAmBlB,CAAC,iBAAD,EAAoB,QAApB,EAA8B,UAA9B,EAA0C,kBAA1C,CAnBkB,CAApB;AAsBA,QAAM,aAAa,GAAG,KAAK,CAAC,WAAN,CACnB,EAAD,IAAiD;;;AAC/C,UAAM;AAAE,MAAA;AAAF,QAAgB,EAAtB;AACA,UAAM,MAAM,GAAG,EAAE,CAAC,MAAlB;AAEA,IAAA,qBAAqB,KAAA,IAArB,IAAA,qBAAqB,KAAA,KAAA,CAArB,GAAqB,KAAA,CAArB,GAAA,qBAAqB,CAAG,EAAH,CAArB;AACA,IAAA,kBAAkB;AAClB,KAAA,EAAA,GAAA,MAAM,CAAC,iBAAP,MAAwB,IAAxB,IAAwB,EAAA,KAAA,KAAA,CAAxB,GAAwB,KAAA,CAAxB,GAAwB,EAAA,CAAA,IAAA,CAAxB,MAAwB,EAAG,SAAH,CAAxB;AACA,IAAA,aAAa,CAAC,OAAd,CAAsB,eAAtB,GAAwC,KAAxC;AAEA,IAAA,aAAa,CAAC,OAAd,CAAsB,WAAtB,CAAkC,IAAlC,CACE,EAAE,CAAC,MAAD,EAAS,aAAT,EAAwB,aAAxB,CADJ,EAEE,EAAE,CAAC,MAAD,EAAS,WAAT,EAAsB,WAAtB,CAFJ,EAGE,MAAK;;;AACH,OAAA,EAAA,GAAA,MAAM,CAAC,qBAAP,MAA4B,IAA5B,IAA4B,EAAA,KAAA,KAAA,CAA5B,GAA4B,KAAA,CAA5B,GAA4B,EAAA,CAAA,IAAA,CAA5B,MAA4B,EAAG,SAAH,CAA5B;AACD,KALH;AAOD,GAjBmB,EAkBpB,CAAC,qBAAD,EAAwB,aAAxB,EAAuC,WAAvC,EAAoD,kBAApD,CAlBoB,CAAtB;AAqBA,QAAM,OAAO,GAAG,KAAK,CAAC,WAAN,CACb,EAAD,IAAkD;AAChD,IAAA,eAAe,KAAA,IAAf,IAAA,eAAe,KAAA,KAAA,CAAf,GAAe,KAAA,CAAf,GAAA,eAAe,CAAG,EAAH,CAAf;;AACA,QAAI,EAAE,CAAC,GAAH,KAAW,GAAf,EAAoB;AAClB,MAAA,UAAU,CAAC,EAAD,EAAK,CAAC,aAAa,CAAC,OAAd,CAAsB,aAA5B,CAAV;AACD;AACF,GANa,EAOd,CAAC,eAAD,EAAkB,UAAlB,CAPc,CAAhB;AAUA,QAAM,eAAe,GAAG,gBAAgB,KAAK,SAArB,GAAiC,gBAAjC,GAAoD,YAAY,GAAG,GAAH,GAAS,CAAjG;AAEA,QAAM,UAAU,GAAG;AACjB,gCAA4B,eAAe,GAAG,GAD7B;AAEjB,kCAA8B,CAAC,MAAM,eAAP,IAA0B;AAFvC,GAAnB;AAKA,QAAM,kBAAkB,GAAG;AACzB,IAAA,SAAS,EAAE,aAAa,GAAG,KAAK,KAAR,GAAgB,CAAC,eAAjB,GAAmC,eAAe,IADjD;AAEzB,IAAA,UAAU,EAAE,cAAc,GACtB,8FADsB,GAEtB;AAJqB,GAA3B,CAzHmD,CAgInD;;AACA,EAAA,KAAK,CAAC,IAAN,CAAW,KAAX,GAAmB,UAAnB;;AACA,MAAI,CAAC,QAAL,EAAe;AACb,IAAA,KAAK,CAAC,IAAN,CAAW,aAAX,GAA2B,aAA3B;AACA,IAAA,KAAK,CAAC,IAAN,CAAW,OAAX,GAAqB,OAArB;AACD,GArIkD,CAuInD;;;AACA,EAAA,KAAK,CAAC,KAAN,CAAY,OAAZ,GAAsB,YAAtB;AACA,EAAA,KAAK,CAAC,KAAN,CAAY,QAAZ,GAAuB,QAAvB;AACA,EAAA,KAAK,CAAC,KAAN,CAAY,GAAZ,GAAkB,QAAlB;AACA,EAAA,KAAK,CAAC,KAAN,CAAY,QAAZ,GAAuB,IAAvB;AACA,EAAA,KAAK,CAAC,KAAN,CAAY,IAAZ,GAAmB,QAAnB,CA5ImD,CA8InD;;AACA,EAAA,KAAK,CAAC,YAAN,CAAmB,KAAnB,GAA2B,kBAA3B,CA/ImD,CAiJnD;;AACA,EAAA,KAAK,CAAC,UAAN,CAAiB,GAAjB,GAAuB,OAAvB;AAEA,SAAO,KAAP;AACD,CArJM","sourcesContent":["import * as React from 'react';\nimport { clamp, useBoolean, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useFluent } from '@fluentui/react-shared-contexts';\nimport type { SwitchState } from './Switch.types';\n\ntype SwitchInternalState = {\n /**\n * The internal rendered value of the Switch.\n */\n internalValue: boolean;\n\n /**\n * Whether the thumb is currently being dragged.\n */\n thumbIsDragging: boolean;\n\n /**\n * Disposable events for the Switch.\n */\n disposables: (() => void)[];\n};\n\n// TODO: This should be replaced with a useEvent hook\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst on = (element: Element, eventName: string, callback: (ev: any) => void) => {\n element.addEventListener(eventName, callback);\n return () => element.removeEventListener(eventName, callback);\n};\n\nexport const useSwitchState = (state: SwitchState) => {\n const { defaultChecked = false, checked, disabled = false, onChange } = state;\n const { onPointerDown: onPointerDownCallback, onKeyUp: onKeyUpCallback } = state.root;\n\n const { dir } = useFluent();\n const inputRef = useMergedRefs(state.input.ref);\n const railRef = React.useRef<HTMLDivElement>(null);\n const internalState = React.useRef<SwitchInternalState>({\n internalValue: checked ? checked : defaultChecked,\n thumbIsDragging: false,\n disposables: [],\n });\n\n const [currentValue, setCurrentValue] = useControllableState({\n defaultState: defaultChecked,\n state: checked,\n initialState: false,\n });\n const [thumbAnimation, { setTrue: showThumbAnimation, setFalse: hideThumbAnimation }] = useBoolean(true);\n const [renderedPosition, setRenderedPosition] = React.useState<number | undefined>(undefined);\n\n const setChecked = useEventCallback(\n (ev: React.PointerEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>, incomingValue: boolean) => {\n ev.stopPropagation();\n ev.preventDefault();\n internalState.current.internalValue = incomingValue;\n onChange?.(ev, { checked: incomingValue });\n setCurrentValue(incomingValue);\n setRenderedPosition(undefined);\n },\n );\n\n const calculatePosition = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): number => {\n const currentBounds = railRef?.current?.getBoundingClientRect();\n const railWidth = currentBounds!.width;\n const railPosition = dir === 'rtl' ? currentBounds!.right : currentBounds!.left;\n const distance = dir === 'rtl' ? railPosition - ev.clientX : ev.clientX - railPosition;\n return clamp((distance / railWidth) * 100, 0, 100);\n },\n [dir],\n );\n\n const onPointerMove = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): void => {\n const incomingPosition = calculatePosition(ev);\n\n internalState.current.thumbIsDragging = true;\n hideThumbAnimation();\n setRenderedPosition(incomingPosition);\n\n // If the Switch reaches a new position of 0% or 100%, update the state and fire change.\n if (incomingPosition === 100 && internalState.current.internalValue !== true) {\n setChecked(ev, true);\n } else if (incomingPosition === 0 && internalState.current.internalValue !== false) {\n setChecked(ev, false);\n }\n },\n [calculatePosition, hideThumbAnimation, setChecked],\n );\n\n const onPointerUp = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): void => {\n internalState.current.disposables.forEach(dispose => dispose());\n internalState.current.disposables = [];\n inputRef.current!.focus();\n\n if (internalState.current.thumbIsDragging) {\n const roundedPosition = Math.round(calculatePosition(ev)! / 100) * 100;\n\n showThumbAnimation();\n if (roundedPosition === 100) {\n setChecked(ev, true);\n } else if (roundedPosition === 0) {\n setChecked(ev, false);\n }\n } else {\n setChecked(ev, !internalState.current.internalValue);\n }\n },\n [calculatePosition, inputRef, setChecked, showThumbAnimation],\n );\n\n const onPointerDown = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): void => {\n const { pointerId } = ev;\n const target = ev.target as HTMLElement;\n\n onPointerDownCallback?.(ev);\n showThumbAnimation();\n target.setPointerCapture?.(pointerId);\n internalState.current.thumbIsDragging = false;\n\n internalState.current.disposables.push(\n on(target, 'pointermove', onPointerMove),\n on(target, 'pointerup', onPointerUp),\n () => {\n target.releasePointerCapture?.(pointerId);\n },\n );\n },\n [onPointerDownCallback, onPointerMove, onPointerUp, showThumbAnimation],\n );\n\n const onKeyUp = React.useCallback(\n (ev: React.KeyboardEvent<HTMLDivElement>): void => {\n onKeyUpCallback?.(ev);\n if (ev.key === ' ') {\n setChecked(ev, !internalState.current.internalValue);\n }\n },\n [onKeyUpCallback, setChecked],\n );\n\n const currentPosition = renderedPosition !== undefined ? renderedPosition : currentValue ? 100 : 0;\n\n const rootStyles = {\n '--switch-checked-opacity': currentPosition / 100,\n '--switch-unchecked-opacity': (100 - currentPosition) / 100,\n } as React.CSSProperties;\n\n const thumbWrapperStyles = {\n transform: `translate(${dir === 'rtl' ? -currentPosition : currentPosition}%)`,\n transition: thumbAnimation\n ? 'transform .1s cubic-bezier(0.33, 0.0, 0.67, 1), opacity .1s cubic-bezier(0.33, 0.0, 0.67, 1)'\n : 'none',\n };\n\n // Root Props\n state.root.style = rootStyles;\n if (!disabled) {\n state.root.onPointerDown = onPointerDown;\n state.root.onKeyUp = onKeyUp;\n }\n\n // Input Props\n state.input.checked = currentValue;\n state.input.disabled = disabled;\n state.input.ref = inputRef;\n state.input.readOnly = true;\n state.input.role = 'switch';\n\n // Thumb Container Props\n state.thumbWrapper.style = thumbWrapperStyles;\n\n // Active Rail Props\n state.activeRail.ref = railRef;\n\n return state;\n};\n"],"sourceRoot":"../src/"}
|
@@ -1,156 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
4
|
-
value: true
|
5
|
-
});
|
6
|
-
exports.useSwitchState = void 0;
|
7
|
-
|
8
|
-
const React = /*#__PURE__*/require("react");
|
9
|
-
|
10
|
-
const react_utilities_1 = /*#__PURE__*/require("@fluentui/react-utilities");
|
11
|
-
|
12
|
-
const react_shared_contexts_1 = /*#__PURE__*/require("@fluentui/react-shared-contexts"); // TODO: This should be replaced with a useEvent hook
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
14
|
-
|
15
|
-
|
16
|
-
const on = (element, eventName, callback) => {
|
17
|
-
element.addEventListener(eventName, callback);
|
18
|
-
return () => element.removeEventListener(eventName, callback);
|
19
|
-
};
|
20
|
-
|
21
|
-
const useSwitchState = state => {
|
22
|
-
const {
|
23
|
-
defaultChecked = false,
|
24
|
-
checked,
|
25
|
-
disabled = false,
|
26
|
-
onChange
|
27
|
-
} = state;
|
28
|
-
const {
|
29
|
-
onPointerDown: onPointerDownCallback,
|
30
|
-
onKeyUp: onKeyUpCallback
|
31
|
-
} = state.root;
|
32
|
-
const {
|
33
|
-
dir
|
34
|
-
} = react_shared_contexts_1.useFluent();
|
35
|
-
const inputRef = react_utilities_1.useMergedRefs(state.input.ref);
|
36
|
-
const railRef = React.useRef(null);
|
37
|
-
const internalState = React.useRef({
|
38
|
-
internalValue: checked ? checked : defaultChecked,
|
39
|
-
thumbIsDragging: false,
|
40
|
-
disposables: []
|
41
|
-
});
|
42
|
-
const [currentValue, setCurrentValue] = react_utilities_1.useControllableState({
|
43
|
-
defaultState: defaultChecked,
|
44
|
-
state: checked,
|
45
|
-
initialState: false
|
46
|
-
});
|
47
|
-
const [thumbAnimation, {
|
48
|
-
setTrue: showThumbAnimation,
|
49
|
-
setFalse: hideThumbAnimation
|
50
|
-
}] = react_utilities_1.useBoolean(true);
|
51
|
-
const [renderedPosition, setRenderedPosition] = React.useState(undefined);
|
52
|
-
const setChecked = react_utilities_1.useEventCallback((ev, incomingValue) => {
|
53
|
-
ev.stopPropagation();
|
54
|
-
ev.preventDefault();
|
55
|
-
internalState.current.internalValue = incomingValue;
|
56
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(ev, {
|
57
|
-
checked: incomingValue
|
58
|
-
});
|
59
|
-
setCurrentValue(incomingValue);
|
60
|
-
setRenderedPosition(undefined);
|
61
|
-
});
|
62
|
-
const calculatePosition = React.useCallback(ev => {
|
63
|
-
var _a;
|
64
|
-
|
65
|
-
const currentBounds = (_a = railRef === null || railRef === void 0 ? void 0 : railRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
66
|
-
const railWidth = currentBounds.width;
|
67
|
-
const railPosition = dir === 'rtl' ? currentBounds.right : currentBounds.left;
|
68
|
-
const distance = dir === 'rtl' ? railPosition - ev.clientX : ev.clientX - railPosition;
|
69
|
-
return react_utilities_1.clamp(distance / railWidth * 100, 0, 100);
|
70
|
-
}, [dir]);
|
71
|
-
const onPointerMove = React.useCallback(ev => {
|
72
|
-
const incomingPosition = calculatePosition(ev);
|
73
|
-
internalState.current.thumbIsDragging = true;
|
74
|
-
hideThumbAnimation();
|
75
|
-
setRenderedPosition(incomingPosition); // If the Switch reaches a new position of 0% or 100%, update the state and fire change.
|
76
|
-
|
77
|
-
if (incomingPosition === 100 && internalState.current.internalValue !== true) {
|
78
|
-
setChecked(ev, true);
|
79
|
-
} else if (incomingPosition === 0 && internalState.current.internalValue !== false) {
|
80
|
-
setChecked(ev, false);
|
81
|
-
}
|
82
|
-
}, [calculatePosition, hideThumbAnimation, setChecked]);
|
83
|
-
const onPointerUp = React.useCallback(ev => {
|
84
|
-
internalState.current.disposables.forEach(dispose => dispose());
|
85
|
-
internalState.current.disposables = [];
|
86
|
-
inputRef.current.focus();
|
87
|
-
|
88
|
-
if (internalState.current.thumbIsDragging) {
|
89
|
-
const roundedPosition = Math.round(calculatePosition(ev) / 100) * 100;
|
90
|
-
showThumbAnimation();
|
91
|
-
|
92
|
-
if (roundedPosition === 100) {
|
93
|
-
setChecked(ev, true);
|
94
|
-
} else if (roundedPosition === 0) {
|
95
|
-
setChecked(ev, false);
|
96
|
-
}
|
97
|
-
} else {
|
98
|
-
setChecked(ev, !internalState.current.internalValue);
|
99
|
-
}
|
100
|
-
}, [calculatePosition, inputRef, setChecked, showThumbAnimation]);
|
101
|
-
const onPointerDown = React.useCallback(ev => {
|
102
|
-
var _a;
|
103
|
-
|
104
|
-
const {
|
105
|
-
pointerId
|
106
|
-
} = ev;
|
107
|
-
const target = ev.target;
|
108
|
-
onPointerDownCallback === null || onPointerDownCallback === void 0 ? void 0 : onPointerDownCallback(ev);
|
109
|
-
showThumbAnimation();
|
110
|
-
(_a = target.setPointerCapture) === null || _a === void 0 ? void 0 : _a.call(target, pointerId);
|
111
|
-
internalState.current.thumbIsDragging = false;
|
112
|
-
internalState.current.disposables.push(on(target, 'pointermove', onPointerMove), on(target, 'pointerup', onPointerUp), () => {
|
113
|
-
var _a;
|
114
|
-
|
115
|
-
(_a = target.releasePointerCapture) === null || _a === void 0 ? void 0 : _a.call(target, pointerId);
|
116
|
-
});
|
117
|
-
}, [onPointerDownCallback, onPointerMove, onPointerUp, showThumbAnimation]);
|
118
|
-
const onKeyUp = React.useCallback(ev => {
|
119
|
-
onKeyUpCallback === null || onKeyUpCallback === void 0 ? void 0 : onKeyUpCallback(ev);
|
120
|
-
|
121
|
-
if (ev.key === ' ') {
|
122
|
-
setChecked(ev, !internalState.current.internalValue);
|
123
|
-
}
|
124
|
-
}, [onKeyUpCallback, setChecked]);
|
125
|
-
const currentPosition = renderedPosition !== undefined ? renderedPosition : currentValue ? 100 : 0;
|
126
|
-
const rootStyles = {
|
127
|
-
'--switch-checked-opacity': currentPosition / 100,
|
128
|
-
'--switch-unchecked-opacity': (100 - currentPosition) / 100
|
129
|
-
};
|
130
|
-
const thumbWrapperStyles = {
|
131
|
-
transform: `translate(${dir === 'rtl' ? -currentPosition : currentPosition}%)`,
|
132
|
-
transition: thumbAnimation ? 'transform .1s cubic-bezier(0.33, 0.0, 0.67, 1), opacity .1s cubic-bezier(0.33, 0.0, 0.67, 1)' : 'none'
|
133
|
-
}; // Root Props
|
134
|
-
|
135
|
-
state.root.style = rootStyles;
|
136
|
-
|
137
|
-
if (!disabled) {
|
138
|
-
state.root.onPointerDown = onPointerDown;
|
139
|
-
state.root.onKeyUp = onKeyUp;
|
140
|
-
} // Input Props
|
141
|
-
|
142
|
-
|
143
|
-
state.input.checked = currentValue;
|
144
|
-
state.input.disabled = disabled;
|
145
|
-
state.input.ref = inputRef;
|
146
|
-
state.input.readOnly = true;
|
147
|
-
state.input.role = 'switch'; // Thumb Container Props
|
148
|
-
|
149
|
-
state.thumbWrapper.style = thumbWrapperStyles; // Active Rail Props
|
150
|
-
|
151
|
-
state.activeRail.ref = railRef;
|
152
|
-
return state;
|
153
|
-
};
|
154
|
-
|
155
|
-
exports.useSwitchState = useSwitchState;
|
156
|
-
//# sourceMappingURL=useSwitchState.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["components/Switch/useSwitchState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { clamp, useBoolean, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useFluent } from '@fluentui/react-shared-contexts';\nimport type { SwitchState } from './Switch.types';\n\ntype SwitchInternalState = {\n /**\n * The internal rendered value of the Switch.\n */\n internalValue: boolean;\n\n /**\n * Whether the thumb is currently being dragged.\n */\n thumbIsDragging: boolean;\n\n /**\n * Disposable events for the Switch.\n */\n disposables: (() => void)[];\n};\n\n// TODO: This should be replaced with a useEvent hook\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst on = (element: Element, eventName: string, callback: (ev: any) => void) => {\n element.addEventListener(eventName, callback);\n return () => element.removeEventListener(eventName, callback);\n};\n\nexport const useSwitchState = (state: SwitchState) => {\n const { defaultChecked = false, checked, disabled = false, onChange } = state;\n const { onPointerDown: onPointerDownCallback, onKeyUp: onKeyUpCallback } = state.root;\n\n const { dir } = useFluent();\n const inputRef = useMergedRefs(state.input.ref);\n const railRef = React.useRef<HTMLDivElement>(null);\n const internalState = React.useRef<SwitchInternalState>({\n internalValue: checked ? checked : defaultChecked,\n thumbIsDragging: false,\n disposables: [],\n });\n\n const [currentValue, setCurrentValue] = useControllableState({\n defaultState: defaultChecked,\n state: checked,\n initialState: false,\n });\n const [thumbAnimation, { setTrue: showThumbAnimation, setFalse: hideThumbAnimation }] = useBoolean(true);\n const [renderedPosition, setRenderedPosition] = React.useState<number | undefined>(undefined);\n\n const setChecked = useEventCallback(\n (ev: React.PointerEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>, incomingValue: boolean) => {\n ev.stopPropagation();\n ev.preventDefault();\n internalState.current.internalValue = incomingValue;\n onChange?.(ev, { checked: incomingValue });\n setCurrentValue(incomingValue);\n setRenderedPosition(undefined);\n },\n );\n\n const calculatePosition = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): number => {\n const currentBounds = railRef?.current?.getBoundingClientRect();\n const railWidth = currentBounds!.width;\n const railPosition = dir === 'rtl' ? currentBounds!.right : currentBounds!.left;\n const distance = dir === 'rtl' ? railPosition - ev.clientX : ev.clientX - railPosition;\n return clamp((distance / railWidth) * 100, 0, 100);\n },\n [dir],\n );\n\n const onPointerMove = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): void => {\n const incomingPosition = calculatePosition(ev);\n\n internalState.current.thumbIsDragging = true;\n hideThumbAnimation();\n setRenderedPosition(incomingPosition);\n\n // If the Switch reaches a new position of 0% or 100%, update the state and fire change.\n if (incomingPosition === 100 && internalState.current.internalValue !== true) {\n setChecked(ev, true);\n } else if (incomingPosition === 0 && internalState.current.internalValue !== false) {\n setChecked(ev, false);\n }\n },\n [calculatePosition, hideThumbAnimation, setChecked],\n );\n\n const onPointerUp = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): void => {\n internalState.current.disposables.forEach(dispose => dispose());\n internalState.current.disposables = [];\n inputRef.current!.focus();\n\n if (internalState.current.thumbIsDragging) {\n const roundedPosition = Math.round(calculatePosition(ev)! / 100) * 100;\n\n showThumbAnimation();\n if (roundedPosition === 100) {\n setChecked(ev, true);\n } else if (roundedPosition === 0) {\n setChecked(ev, false);\n }\n } else {\n setChecked(ev, !internalState.current.internalValue);\n }\n },\n [calculatePosition, inputRef, setChecked, showThumbAnimation],\n );\n\n const onPointerDown = React.useCallback(\n (ev: React.PointerEvent<HTMLDivElement>): void => {\n const { pointerId } = ev;\n const target = ev.target as HTMLElement;\n\n onPointerDownCallback?.(ev);\n showThumbAnimation();\n target.setPointerCapture?.(pointerId);\n internalState.current.thumbIsDragging = false;\n\n internalState.current.disposables.push(\n on(target, 'pointermove', onPointerMove),\n on(target, 'pointerup', onPointerUp),\n () => {\n target.releasePointerCapture?.(pointerId);\n },\n );\n },\n [onPointerDownCallback, onPointerMove, onPointerUp, showThumbAnimation],\n );\n\n const onKeyUp = React.useCallback(\n (ev: React.KeyboardEvent<HTMLDivElement>): void => {\n onKeyUpCallback?.(ev);\n if (ev.key === ' ') {\n setChecked(ev, !internalState.current.internalValue);\n }\n },\n [onKeyUpCallback, setChecked],\n );\n\n const currentPosition = renderedPosition !== undefined ? renderedPosition : currentValue ? 100 : 0;\n\n const rootStyles = {\n '--switch-checked-opacity': currentPosition / 100,\n '--switch-unchecked-opacity': (100 - currentPosition) / 100,\n } as React.CSSProperties;\n\n const thumbWrapperStyles = {\n transform: `translate(${dir === 'rtl' ? -currentPosition : currentPosition}%)`,\n transition: thumbAnimation\n ? 'transform .1s cubic-bezier(0.33, 0.0, 0.67, 1), opacity .1s cubic-bezier(0.33, 0.0, 0.67, 1)'\n : 'none',\n };\n\n // Root Props\n state.root.style = rootStyles;\n if (!disabled) {\n state.root.onPointerDown = onPointerDown;\n state.root.onKeyUp = onKeyUp;\n }\n\n // Input Props\n state.input.checked = currentValue;\n state.input.disabled = disabled;\n state.input.ref = inputRef;\n state.input.readOnly = true;\n state.input.role = 'switch';\n\n // Thumb Container Props\n state.thumbWrapper.style = thumbWrapperStyles;\n\n // Active Rail Props\n state.activeRail.ref = railRef;\n\n return state;\n};\n"],"sourceRoot":"../src/"}
|