@proyecto-viviana/solidaria 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/src/button/createButton.ts +135 -0
- package/src/button/createToggleButton.ts +101 -0
- package/src/button/index.ts +4 -0
- package/src/button/types.ts +67 -0
- package/src/checkbox/createCheckbox.ts +135 -0
- package/src/checkbox/createCheckboxGroup.ts +137 -0
- package/src/checkbox/createCheckboxGroupItem.ts +117 -0
- package/src/checkbox/createCheckboxGroupState.ts +193 -0
- package/src/checkbox/index.ts +13 -0
- package/src/index.ts +128 -0
- package/src/interactions/FocusableProvider.tsx +44 -0
- package/src/interactions/PressEvent.ts +112 -0
- package/src/interactions/createFocus.ts +157 -0
- package/src/interactions/createFocusRing.ts +142 -0
- package/src/interactions/createFocusWithin.ts +141 -0
- package/src/interactions/createFocusable.ts +168 -0
- package/src/interactions/createHover.ts +214 -0
- package/src/interactions/createKeyboard.ts +82 -0
- package/src/interactions/createPress.ts +758 -0
- package/src/interactions/index.ts +45 -0
- package/src/label/createField.ts +145 -0
- package/src/label/createLabel.ts +116 -0
- package/src/label/createLabels.ts +50 -0
- package/src/label/index.ts +19 -0
- package/src/link/createLink.ts +176 -0
- package/src/link/index.ts +1 -0
- package/src/progress/createProgressBar.ts +128 -0
- package/src/progress/index.ts +5 -0
- package/src/radio/createRadio.ts +286 -0
- package/src/radio/createRadioGroup.ts +189 -0
- package/src/radio/createRadioGroupState.ts +201 -0
- package/src/radio/index.ts +23 -0
- package/src/separator/createSeparator.ts +82 -0
- package/src/separator/index.ts +6 -0
- package/src/ssr/index.ts +36 -0
- package/src/switch/createSwitch.ts +70 -0
- package/src/switch/index.ts +1 -0
- package/src/textfield/createTextField.ts +198 -0
- package/src/textfield/index.ts +5 -0
- package/src/toggle/createToggle.ts +222 -0
- package/src/toggle/createToggleState.ts +94 -0
- package/src/toggle/index.ts +7 -0
- package/src/utils/dom.ts +244 -0
- package/src/utils/events.ts +119 -0
- package/src/utils/filterDOMProps.ts +116 -0
- package/src/utils/focus.ts +151 -0
- package/src/utils/geometry.ts +115 -0
- package/src/utils/globalListeners.ts +142 -0
- package/src/utils/index.ts +66 -0
- package/src/utils/mergeProps.ts +49 -0
- package/src/utils/platform.ts +52 -0
- package/src/utils/reactivity.ts +36 -0
- package/src/utils/textSelection.ts +114 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text selection management utilities.
|
|
3
|
+
* Based on @react-aria/interactions textSelection utilities.
|
|
4
|
+
*
|
|
5
|
+
* On iOS, long press triggers text selection. The only way to prevent this
|
|
6
|
+
* is to set user-select: none on the entire page. On other platforms,
|
|
7
|
+
* we can just set it on the target element.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { isIOS } from './platform';
|
|
11
|
+
import { getOwnerDocument } from './dom';
|
|
12
|
+
|
|
13
|
+
type State = 'default' | 'disabled' | 'restoring';
|
|
14
|
+
|
|
15
|
+
// Global state to manage text selection across multiple press interactions
|
|
16
|
+
let state: State = 'default';
|
|
17
|
+
let savedUserSelect = '';
|
|
18
|
+
let modifiedElementMap = new WeakMap<HTMLElement, string>();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Disables text selection on the page or element during press.
|
|
22
|
+
* On iOS, applies to the entire document. On other platforms, just the target.
|
|
23
|
+
*/
|
|
24
|
+
export function disableTextSelection(target?: HTMLElement): void {
|
|
25
|
+
if (isIOS()) {
|
|
26
|
+
// iOS requires disabling selection on the entire page
|
|
27
|
+
if (state === 'default') {
|
|
28
|
+
const documentElement = getOwnerDocument(target).documentElement;
|
|
29
|
+
savedUserSelect = documentElement.style.webkitUserSelect;
|
|
30
|
+
documentElement.style.webkitUserSelect = 'none';
|
|
31
|
+
}
|
|
32
|
+
state = 'disabled';
|
|
33
|
+
} else if (target) {
|
|
34
|
+
// On other platforms, just disable on the target
|
|
35
|
+
const element = target as HTMLElement;
|
|
36
|
+
if (!modifiedElementMap.has(element)) {
|
|
37
|
+
modifiedElementMap.set(element, element.style.userSelect);
|
|
38
|
+
element.style.userSelect = 'none';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Restores text selection after press ends.
|
|
45
|
+
* On iOS, waits 300ms to avoid selection appearing during tap.
|
|
46
|
+
*/
|
|
47
|
+
export function restoreTextSelection(target?: HTMLElement): void {
|
|
48
|
+
if (isIOS()) {
|
|
49
|
+
// Don't restore if another press is active
|
|
50
|
+
if (state !== 'disabled') {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
state = 'restoring';
|
|
55
|
+
|
|
56
|
+
// Wait for iOS to finish any pending selection actions
|
|
57
|
+
// 300ms is the iOS long-press delay
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
// Use runAfterTransition to avoid CSS recomputation during animation
|
|
60
|
+
runAfterTransition(() => {
|
|
61
|
+
// Only restore if still in 'restoring' state (no new press started)
|
|
62
|
+
if (state === 'restoring') {
|
|
63
|
+
const documentElement = getOwnerDocument(target).documentElement;
|
|
64
|
+
if (savedUserSelect) {
|
|
65
|
+
documentElement.style.webkitUserSelect = savedUserSelect;
|
|
66
|
+
} else {
|
|
67
|
+
documentElement.style.removeProperty('-webkit-user-select');
|
|
68
|
+
}
|
|
69
|
+
savedUserSelect = '';
|
|
70
|
+
state = 'default';
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}, 300);
|
|
74
|
+
} else if (target) {
|
|
75
|
+
// On other platforms, restore immediately
|
|
76
|
+
const element = target as HTMLElement;
|
|
77
|
+
const savedValue = modifiedElementMap.get(element);
|
|
78
|
+
if (savedValue !== undefined) {
|
|
79
|
+
if (savedValue) {
|
|
80
|
+
element.style.userSelect = savedValue;
|
|
81
|
+
} else {
|
|
82
|
+
element.style.removeProperty('user-select');
|
|
83
|
+
}
|
|
84
|
+
modifiedElementMap.delete(element);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Tracks pending transitions for runAfterTransition
|
|
90
|
+
const pendingTransitions = new Set<() => void>();
|
|
91
|
+
let transitionTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Runs a callback after CSS transitions complete.
|
|
95
|
+
* Batches multiple callbacks to avoid unnecessary layout thrashing.
|
|
96
|
+
*/
|
|
97
|
+
function runAfterTransition(callback: () => void): void {
|
|
98
|
+
// If we haven't started tracking transitions, run immediately
|
|
99
|
+
pendingTransitions.add(callback);
|
|
100
|
+
|
|
101
|
+
// Debounce - wait for any transitions to settle
|
|
102
|
+
if (transitionTimeout != null) {
|
|
103
|
+
clearTimeout(transitionTimeout);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
transitionTimeout = setTimeout(() => {
|
|
107
|
+
// Run all pending callbacks
|
|
108
|
+
for (const cb of pendingTransitions) {
|
|
109
|
+
cb();
|
|
110
|
+
}
|
|
111
|
+
pendingTransitions.clear();
|
|
112
|
+
transitionTimeout = null;
|
|
113
|
+
}, 0);
|
|
114
|
+
}
|