@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.
Files changed (56) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/package.json +4 -3
  4. package/src/button/createButton.ts +135 -0
  5. package/src/button/createToggleButton.ts +101 -0
  6. package/src/button/index.ts +4 -0
  7. package/src/button/types.ts +67 -0
  8. package/src/checkbox/createCheckbox.ts +135 -0
  9. package/src/checkbox/createCheckboxGroup.ts +137 -0
  10. package/src/checkbox/createCheckboxGroupItem.ts +117 -0
  11. package/src/checkbox/createCheckboxGroupState.ts +193 -0
  12. package/src/checkbox/index.ts +13 -0
  13. package/src/index.ts +128 -0
  14. package/src/interactions/FocusableProvider.tsx +44 -0
  15. package/src/interactions/PressEvent.ts +112 -0
  16. package/src/interactions/createFocus.ts +157 -0
  17. package/src/interactions/createFocusRing.ts +142 -0
  18. package/src/interactions/createFocusWithin.ts +141 -0
  19. package/src/interactions/createFocusable.ts +168 -0
  20. package/src/interactions/createHover.ts +214 -0
  21. package/src/interactions/createKeyboard.ts +82 -0
  22. package/src/interactions/createPress.ts +758 -0
  23. package/src/interactions/index.ts +45 -0
  24. package/src/label/createField.ts +145 -0
  25. package/src/label/createLabel.ts +116 -0
  26. package/src/label/createLabels.ts +50 -0
  27. package/src/label/index.ts +19 -0
  28. package/src/link/createLink.ts +176 -0
  29. package/src/link/index.ts +1 -0
  30. package/src/progress/createProgressBar.ts +128 -0
  31. package/src/progress/index.ts +5 -0
  32. package/src/radio/createRadio.ts +286 -0
  33. package/src/radio/createRadioGroup.ts +189 -0
  34. package/src/radio/createRadioGroupState.ts +201 -0
  35. package/src/radio/index.ts +23 -0
  36. package/src/separator/createSeparator.ts +82 -0
  37. package/src/separator/index.ts +6 -0
  38. package/src/ssr/index.ts +36 -0
  39. package/src/switch/createSwitch.ts +70 -0
  40. package/src/switch/index.ts +1 -0
  41. package/src/textfield/createTextField.ts +198 -0
  42. package/src/textfield/index.ts +5 -0
  43. package/src/toggle/createToggle.ts +222 -0
  44. package/src/toggle/createToggleState.ts +94 -0
  45. package/src/toggle/index.ts +7 -0
  46. package/src/utils/dom.ts +244 -0
  47. package/src/utils/events.ts +119 -0
  48. package/src/utils/filterDOMProps.ts +116 -0
  49. package/src/utils/focus.ts +151 -0
  50. package/src/utils/geometry.ts +115 -0
  51. package/src/utils/globalListeners.ts +142 -0
  52. package/src/utils/index.ts +66 -0
  53. package/src/utils/mergeProps.ts +49 -0
  54. package/src/utils/platform.ts +52 -0
  55. package/src/utils/reactivity.ts +36 -0
  56. 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
+ }