@musecat/functionkit 1.0.1 → 1.1.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.
Files changed (130) hide show
  1. package/.agents/references/components/ScrolltoTop.md +36 -0
  2. package/.agents/references/components/SwitchCase.md +47 -0
  3. package/.agents/references/components/ViewportPortal.md +34 -0
  4. package/.agents/references/cookie/cookie.md +47 -0
  5. package/.agents/references/datetime/dateTime.client.md +42 -0
  6. package/.agents/references/datetime/dateTime.server.md +42 -0
  7. package/.agents/references/datetime/dateTime.shared.md +86 -0
  8. package/.agents/references/hooks/useAvoidKeyboard.md +29 -0
  9. package/.agents/references/hooks/useCheckInvisible.md +36 -0
  10. package/.agents/references/hooks/useCheckScroll.md +36 -0
  11. package/.agents/references/hooks/useClientDateTime.md +39 -0
  12. package/.agents/references/hooks/useDebounce.md +46 -0
  13. package/.agents/references/hooks/useDebouncedCallback.md +34 -0
  14. package/.agents/references/hooks/useDoubleClick.md +40 -0
  15. package/.agents/references/hooks/useGeolocation.md +37 -0
  16. package/.agents/references/hooks/useHasMounted.md +27 -0
  17. package/.agents/references/hooks/useIntersectionObserver.md +41 -0
  18. package/.agents/references/hooks/useInterval.md +44 -0
  19. package/.agents/references/hooks/useKeyboardHeight.md +33 -0
  20. package/.agents/references/hooks/useKeyboardListNavigation.md +58 -0
  21. package/.agents/references/hooks/useLongPress.md +48 -0
  22. package/.agents/references/hooks/usePreservedCallback.md +37 -0
  23. package/.agents/references/hooks/usePreservedReference.md +34 -0
  24. package/.agents/references/hooks/useRefEffect.md +35 -0
  25. package/.agents/references/hooks/useRelativeDateTime.md +35 -0
  26. package/.agents/references/hooks/useTimeout.md +42 -0
  27. package/.agents/references/hooks/useToggleState.md +39 -0
  28. package/.agents/references/hooks/useViewportHeight.md +26 -0
  29. package/.agents/references/hooks/useViewportMatch.md +32 -0
  30. package/.agents/references/utils/browserStorage.md +41 -0
  31. package/.agents/references/utils/buildContext.md +47 -0
  32. package/.agents/references/utils/clipboardShare.md +59 -0
  33. package/.agents/references/utils/floatingMotion.md +67 -0
  34. package/.agents/references/utils/getDeviceInfo.md +43 -0
  35. package/.agents/references/utils/isEditableKeyboardTarget.md +35 -0
  36. package/.agents/references/utils/mergeRefs.md +29 -0
  37. package/.agents/references/utils/seen.md +37 -0
  38. package/.agents/references/utils/subscribeKeyboardHeight.md +35 -0
  39. package/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  40. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  41. package/.github/PULL_REQUEST_TEMPLATE.md +22 -0
  42. package/.github/workflows/ci.yml +20 -0
  43. package/.local/state/gh/device-id +1 -0
  44. package/.prettierrc +8 -0
  45. package/AGENTS.md +117 -396
  46. package/CODE_OF_CONDUCT.md +55 -0
  47. package/CONTRIBUTING.md +39 -0
  48. package/README.md +18 -5
  49. package/biome.json +25 -0
  50. package/index.ts +63 -68
  51. package/package.json +46 -13
  52. package/packages/components/ScrolltoTop.tsx +3 -3
  53. package/packages/components/SwitchCase.tsx +7 -7
  54. package/packages/components/ViewportPortal.tsx +22 -23
  55. package/packages/cookie/cookie.shared.ts +80 -110
  56. package/packages/cookie/cookieNames.shared.ts +9 -0
  57. package/packages/datetime/dateTime.client.ts +84 -86
  58. package/packages/datetime/dateTime.server.ts +84 -86
  59. package/packages/datetime/dateTime.shared.ts +249 -287
  60. package/packages/hooks/useAvoidKeyboard.ts +15 -15
  61. package/packages/hooks/useCheckInvisible.ts +16 -16
  62. package/packages/hooks/useCheckScroll.ts +10 -10
  63. package/packages/hooks/useClientDateTime.ts +24 -37
  64. package/packages/hooks/useDebounce.ts +90 -95
  65. package/packages/hooks/useDebouncedCallback.ts +45 -45
  66. package/packages/hooks/useDoubleClick.ts +43 -43
  67. package/packages/hooks/useGeolocation.ts +126 -130
  68. package/packages/hooks/useHasMounted.ts +5 -5
  69. package/packages/hooks/useIntersectionObserver.ts +20 -20
  70. package/packages/hooks/useInterval.ts +45 -45
  71. package/packages/hooks/useKeyboardHeight.ts +9 -9
  72. package/packages/hooks/useKeyboardListNavigation.ts +130 -158
  73. package/packages/hooks/useLongPress.ts +87 -98
  74. package/packages/hooks/usePreservedCallback.ts +12 -12
  75. package/packages/hooks/usePreservedReference.ts +10 -10
  76. package/packages/hooks/useRefEffect.ts +19 -19
  77. package/packages/hooks/useRelativeDateTime.ts +36 -39
  78. package/packages/hooks/useTimeout.ts +41 -41
  79. package/packages/hooks/useToggleState.ts +5 -5
  80. package/packages/hooks/useViewportHeight.ts +12 -13
  81. package/packages/hooks/useViewportMatch.ts +13 -23
  82. package/packages/utils/browserStorage.ts +26 -26
  83. package/packages/utils/buildContext.tsx +10 -11
  84. package/packages/utils/checkDevice.ts +64 -64
  85. package/packages/utils/clipboardShare.tsx +31 -31
  86. package/packages/utils/clipboardShare.types.ts +7 -7
  87. package/packages/utils/floatingMotion.ts +71 -77
  88. package/packages/utils/keyboardTarget.ts +9 -9
  89. package/packages/utils/mergeRefs.ts +9 -9
  90. package/packages/utils/seen.ts +15 -15
  91. package/packages/utils/subscribeKeyboardHeight.ts +49 -46
  92. package/tests/components/ScrolltoTop.test.tsx +15 -0
  93. package/tests/components/SwitchCase.test.tsx +33 -0
  94. package/tests/components/ViewportPortal.test.tsx +46 -0
  95. package/tests/cookie/cookie.test.ts +192 -0
  96. package/tests/datetime/datetime.test.ts +461 -0
  97. package/tests/hooks/useAvoidKeyboard.test.ts +43 -0
  98. package/tests/hooks/useCheckInvisible.test.ts +59 -0
  99. package/tests/hooks/useCheckScroll.test.ts +23 -0
  100. package/tests/hooks/useClientDateTime.test.ts +12 -0
  101. package/tests/hooks/useDebounce.test.ts +96 -0
  102. package/tests/hooks/useDebouncedCallback.test.ts +63 -0
  103. package/tests/hooks/useDoubleClick.test.ts +82 -0
  104. package/tests/hooks/useGeolocation.test.ts +201 -0
  105. package/tests/hooks/useHasMounted.test.ts +10 -0
  106. package/tests/hooks/useIntersectionObserver.test.ts +78 -0
  107. package/tests/hooks/useInterval.test.ts +56 -0
  108. package/tests/hooks/useKeyboardHeight.test.ts +10 -0
  109. package/tests/hooks/useKeyboardListNavigation.test.ts +404 -0
  110. package/tests/hooks/useLongPress.test.ts +214 -0
  111. package/tests/hooks/usePreservedCallback.test.ts +33 -0
  112. package/tests/hooks/usePreservedReference.test.ts +42 -0
  113. package/tests/hooks/useRefEffect.test.ts +67 -0
  114. package/tests/hooks/useRelativeDateTime.test.ts +21 -0
  115. package/tests/hooks/useTimeout.test.ts +72 -0
  116. package/tests/hooks/useToggleState.test.ts +43 -0
  117. package/tests/hooks/useViewportHeight.test.ts +32 -0
  118. package/tests/hooks/useViewportMatch.test.ts +35 -0
  119. package/tests/setup.ts +9 -0
  120. package/tests/utils/browserStorage.test.ts +114 -0
  121. package/tests/utils/buildContext.test.tsx +26 -0
  122. package/tests/utils/checkDevice.test.ts +140 -0
  123. package/tests/utils/clipboardShare.test.ts +152 -0
  124. package/tests/utils/floatingMotion.test.ts +135 -0
  125. package/tests/utils/keyboardTarget.test.ts +85 -0
  126. package/tests/utils/mergeRefs.test.ts +50 -0
  127. package/tests/utils/seen.test.ts +40 -0
  128. package/tests/utils/subscribeKeyboardHeight.test.ts +172 -0
  129. package/tsconfig.json +16 -16
  130. package/vitest.config.ts +22 -0
@@ -1,108 +1,106 @@
1
1
  import {
2
- type DateInput,
3
- type DatePreset,
4
- format24HourTime,
5
- formatDotDate,
6
- formatKoreanTime,
7
- formatLongDate,
8
- formatRelativeText,
9
- formatTwelveHourTime,
10
- type TimePreset,
11
- toDate,
2
+ type DateInput,
3
+ type DatePreset,
4
+ format24HourTime,
5
+ formatDotDate,
6
+ formatKoreanTime,
7
+ formatLongDate,
8
+ formatRelativeText,
9
+ formatTwelveHourTime,
10
+ type TimePreset,
11
+ toDate,
12
12
  } from "./dateTime.shared";
13
13
 
14
14
  export function formatClientDate(
15
- value: DateInput,
16
- options: {
17
- locale?: string;
18
- timeZone?: string;
19
- preset: DatePreset;
20
- },
15
+ value: DateInput,
16
+ options: {
17
+ locale?: string;
18
+ timeZone?: string;
19
+ preset: DatePreset;
20
+ },
21
21
  ): string {
22
- const date = toDate(value);
23
- if (!date) return "";
22
+ const date = toDate(value);
23
+ if (!date) return "";
24
24
 
25
- return options.preset === "dot"
26
- ? formatDotDate(date, options.timeZone)
27
- : formatLongDate(date, options.locale, options.timeZone);
25
+ return options.preset === "dot"
26
+ ? formatDotDate(date, options.timeZone)
27
+ : formatLongDate(date, options.locale, options.timeZone);
28
28
  }
29
29
 
30
30
  export function formatClientTime(
31
- value: DateInput,
32
- options: {
33
- locale?: string;
34
- timeZone?: string;
35
- preset: TimePreset;
36
- },
31
+ value: DateInput,
32
+ options: {
33
+ locale?: string;
34
+ timeZone?: string;
35
+ preset: TimePreset;
36
+ },
37
37
  ): string {
38
- const date = toDate(value);
39
- if (!date) return "";
38
+ const date = toDate(value);
39
+ if (!date) return "";
40
40
 
41
- switch (options.preset) {
42
- case "ko":
43
- return formatKoreanTime(date, options.timeZone);
44
- case "12h":
45
- return formatTwelveHourTime(date, options.locale, options.timeZone);
46
- case "24h-second":
47
- return format24HourTime(date, {
48
- includeSeconds: true,
49
- timeZone: options.timeZone,
50
- });
51
- default:
52
- return format24HourTime(date, { timeZone: options.timeZone });
53
- }
41
+ switch (options.preset) {
42
+ case "ko":
43
+ return formatKoreanTime(date, options.timeZone);
44
+ case "12h":
45
+ return formatTwelveHourTime(date, options.locale, options.timeZone);
46
+ case "24h-second":
47
+ return format24HourTime(date, {
48
+ includeSeconds: true,
49
+ timeZone: options.timeZone,
50
+ });
51
+ default:
52
+ return format24HourTime(date, { timeZone: options.timeZone });
53
+ }
54
54
  }
55
55
 
56
56
  export function formatClientDateTime(
57
- value: DateInput,
58
- options: {
59
- locale?: string;
60
- timeZone?: string;
61
- datePreset?: DatePreset;
62
- timePreset?: TimePreset;
63
- },
57
+ value: DateInput,
58
+ options: {
59
+ locale?: string;
60
+ timeZone?: string;
61
+ datePreset?: DatePreset;
62
+ timePreset?: TimePreset;
63
+ },
64
64
  ): string {
65
- const dateText = formatClientDate(value, {
66
- locale: options.locale,
67
- timeZone: options.timeZone,
68
- preset: options.datePreset ?? "long",
69
- });
70
- const timeText = formatClientTime(value, {
71
- locale: options.locale,
72
- timeZone: options.timeZone,
73
- preset: options.timePreset ?? "24h-minute",
74
- });
75
- return dateText && timeText
76
- ? `${dateText} ${timeText}`
77
- : dateText || timeText;
65
+ const dateText = formatClientDate(value, {
66
+ locale: options.locale,
67
+ timeZone: options.timeZone,
68
+ preset: options.datePreset ?? "long",
69
+ });
70
+ const timeText = formatClientTime(value, {
71
+ locale: options.locale,
72
+ timeZone: options.timeZone,
73
+ preset: options.timePreset ?? "24h-minute",
74
+ });
75
+ return dateText && timeText ? `${dateText} ${timeText}` : dateText || timeText;
78
76
  }
79
77
 
80
78
  export function formatClientRelative(
81
- value: DateInput,
82
- options: {
83
- locale?: string;
84
- now?: DateInput;
85
- maxRelativeDays?: number;
86
- fallbackDatePreset?: DatePreset;
87
- },
79
+ value: DateInput,
80
+ options: {
81
+ locale?: string;
82
+ now?: DateInput;
83
+ maxRelativeDays?: number;
84
+ fallbackDatePreset?: DatePreset;
85
+ },
88
86
  ): { text: string; isRelative: boolean } {
89
- const date = toDate(value);
90
- const now = toDate(options.now ?? Date.now());
91
- if (!date || !now) {
92
- return { text: "", isRelative: false };
93
- }
87
+ const date = toDate(value);
88
+ const now = toDate(options.now ?? Date.now());
89
+ if (!date || !now) {
90
+ return { text: "", isRelative: false };
91
+ }
94
92
 
95
- const diffMs = Math.max(0, now.getTime() - date.getTime());
96
- const maxRelativeMs = (options.maxRelativeDays ?? 7) * 24 * 60 * 60 * 1000;
97
- if (diffMs > maxRelativeMs) {
98
- return {
99
- text: formatClientDate(date, {
100
- locale: options.locale,
101
- preset: options.fallbackDatePreset ?? "dot",
102
- }),
103
- isRelative: false,
104
- };
105
- }
93
+ const diffMs = Math.max(0, now.getTime() - date.getTime());
94
+ const maxRelativeMs = (options.maxRelativeDays ?? 7) * 24 * 60 * 60 * 1000;
95
+ if (diffMs > maxRelativeMs) {
96
+ return {
97
+ text: formatClientDate(date, {
98
+ locale: options.locale,
99
+ preset: options.fallbackDatePreset ?? "dot",
100
+ }),
101
+ isRelative: false,
102
+ };
103
+ }
106
104
 
107
- return formatRelativeText(diffMs, options.locale);
105
+ return formatRelativeText(diffMs, options.locale);
108
106
  }
@@ -1,108 +1,106 @@
1
1
  import {
2
- type DateInput,
3
- type DatePreset,
4
- format24HourTime,
5
- formatDotDate,
6
- formatKoreanTime,
7
- formatLongDate,
8
- formatRelativeText,
9
- formatTwelveHourTime,
10
- type TimePreset,
11
- toDate,
2
+ type DateInput,
3
+ type DatePreset,
4
+ format24HourTime,
5
+ formatDotDate,
6
+ formatKoreanTime,
7
+ formatLongDate,
8
+ formatRelativeText,
9
+ formatTwelveHourTime,
10
+ type TimePreset,
11
+ toDate,
12
12
  } from "./dateTime.shared";
13
13
 
14
14
  export function formatServerDate(
15
- value: DateInput,
16
- options: {
17
- locale?: string;
18
- timeZone?: string;
19
- preset: DatePreset;
20
- },
15
+ value: DateInput,
16
+ options: {
17
+ locale?: string;
18
+ timeZone?: string;
19
+ preset: DatePreset;
20
+ },
21
21
  ): string {
22
- const date = toDate(value);
23
- if (!date) return "";
22
+ const date = toDate(value);
23
+ if (!date) return "";
24
24
 
25
- return options.preset === "dot"
26
- ? formatDotDate(date, options.timeZone)
27
- : formatLongDate(date, options.locale, options.timeZone);
25
+ return options.preset === "dot"
26
+ ? formatDotDate(date, options.timeZone)
27
+ : formatLongDate(date, options.locale, options.timeZone);
28
28
  }
29
29
 
30
30
  export function formatServerTime(
31
- value: DateInput,
32
- options: {
33
- locale?: string;
34
- timeZone?: string;
35
- preset: TimePreset;
36
- },
31
+ value: DateInput,
32
+ options: {
33
+ locale?: string;
34
+ timeZone?: string;
35
+ preset: TimePreset;
36
+ },
37
37
  ): string {
38
- const date = toDate(value);
39
- if (!date) return "";
38
+ const date = toDate(value);
39
+ if (!date) return "";
40
40
 
41
- switch (options.preset) {
42
- case "ko":
43
- return formatKoreanTime(date, options.timeZone);
44
- case "12h":
45
- return formatTwelveHourTime(date, options.locale, options.timeZone);
46
- case "24h-second":
47
- return format24HourTime(date, {
48
- includeSeconds: true,
49
- timeZone: options.timeZone,
50
- });
51
- default:
52
- return format24HourTime(date, { timeZone: options.timeZone });
53
- }
41
+ switch (options.preset) {
42
+ case "ko":
43
+ return formatKoreanTime(date, options.timeZone);
44
+ case "12h":
45
+ return formatTwelveHourTime(date, options.locale, options.timeZone);
46
+ case "24h-second":
47
+ return format24HourTime(date, {
48
+ includeSeconds: true,
49
+ timeZone: options.timeZone,
50
+ });
51
+ default:
52
+ return format24HourTime(date, { timeZone: options.timeZone });
53
+ }
54
54
  }
55
55
 
56
56
  export function formatServerDateTime(
57
- value: DateInput,
58
- options: {
59
- locale?: string;
60
- timeZone?: string;
61
- datePreset?: DatePreset;
62
- timePreset?: TimePreset;
63
- },
57
+ value: DateInput,
58
+ options: {
59
+ locale?: string;
60
+ timeZone?: string;
61
+ datePreset?: DatePreset;
62
+ timePreset?: TimePreset;
63
+ },
64
64
  ): string {
65
- const dateText = formatServerDate(value, {
66
- locale: options.locale,
67
- timeZone: options.timeZone,
68
- preset: options.datePreset ?? "long",
69
- });
70
- const timeText = formatServerTime(value, {
71
- locale: options.locale,
72
- timeZone: options.timeZone,
73
- preset: options.timePreset ?? "24h-minute",
74
- });
75
- return dateText && timeText
76
- ? `${dateText} ${timeText}`
77
- : dateText || timeText;
65
+ const dateText = formatServerDate(value, {
66
+ locale: options.locale,
67
+ timeZone: options.timeZone,
68
+ preset: options.datePreset ?? "long",
69
+ });
70
+ const timeText = formatServerTime(value, {
71
+ locale: options.locale,
72
+ timeZone: options.timeZone,
73
+ preset: options.timePreset ?? "24h-minute",
74
+ });
75
+ return dateText && timeText ? `${dateText} ${timeText}` : dateText || timeText;
78
76
  }
79
77
 
80
78
  export function formatServerRelative(
81
- value: DateInput,
82
- options: {
83
- locale?: string;
84
- now?: DateInput;
85
- maxRelativeDays?: number;
86
- fallbackDatePreset?: DatePreset;
87
- },
79
+ value: DateInput,
80
+ options: {
81
+ locale?: string;
82
+ now?: DateInput;
83
+ maxRelativeDays?: number;
84
+ fallbackDatePreset?: DatePreset;
85
+ },
88
86
  ): { text: string; isRelative: boolean } {
89
- const date = toDate(value);
90
- const now = toDate(options.now ?? new Date());
91
- if (!date || !now) {
92
- return { text: "", isRelative: false };
93
- }
87
+ const date = toDate(value);
88
+ const now = toDate(options.now ?? new Date());
89
+ if (!date || !now) {
90
+ return { text: "", isRelative: false };
91
+ }
94
92
 
95
- const diffMs = Math.max(0, now.getTime() - date.getTime());
96
- const maxRelativeMs = (options.maxRelativeDays ?? 7) * 24 * 60 * 60 * 1000;
97
- if (diffMs > maxRelativeMs) {
98
- return {
99
- text: formatServerDate(date, {
100
- locale: options.locale,
101
- preset: options.fallbackDatePreset ?? "dot",
102
- }),
103
- isRelative: false,
104
- };
105
- }
93
+ const diffMs = Math.max(0, now.getTime() - date.getTime());
94
+ const maxRelativeMs = (options.maxRelativeDays ?? 7) * 24 * 60 * 60 * 1000;
95
+ if (diffMs > maxRelativeMs) {
96
+ return {
97
+ text: formatServerDate(date, {
98
+ locale: options.locale,
99
+ preset: options.fallbackDatePreset ?? "dot",
100
+ }),
101
+ isRelative: false,
102
+ };
103
+ }
106
104
 
107
- return formatRelativeText(diffMs, options.locale);
105
+ return formatRelativeText(diffMs, options.locale);
108
106
  }