@basiln/utils 0.1.9 → 0.1.10

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/README.md CHANGED
@@ -24,6 +24,8 @@ yarn add @basiln/utils
24
24
  - [getVar](#getvar)
25
25
  - [Format](#format)
26
26
  - [DomainFormat](#domainformat)
27
+ - [useCombinedRefs](#usecombinedrefs)
28
+ - [useControllableState](#usecontrollablestate)
27
29
 
28
30
  ### `If`
29
31
 
@@ -345,5 +347,41 @@ DomainFormat.userLevel({level: '1', language: 'en'}) // MASTER
345
347
  // Mode 추가가 필요한 경우
346
348
  DomainFormat.modeName('R', {R: '실외기 잠금'}); // 실외기 잠금
347
349
  DomainFormat.modeColor('R', {N: 'gray'}); // 'gray'
350
+ ```
351
+ ---
352
+ ### `useCombinedRefs`
353
+ 컴포넌트 내부에 선언된 ref와, 사용하는 부분에서 forwarded된 ref를 합칠 수 있도록 하는 hook 입니다.
354
+ #### 사용법
355
+ ```tsx
356
+ const TextField = forwardRef((props, forwardedRef) => {
357
+ const ref = useRef<HTMLInputElement | null>(null);
358
+ const combinedRefs = useCombinedRefs(ref, forwardedRef);
359
+ return <input ref={ref} />
360
+ })
361
+ ```
362
+ ---
363
+ ### `useControllableState`
364
+ 사용자의 입력을 통해 상태를 관리할 때와 사용자의 입력을 상태로 관리하지 않고 싶을 때 두 경우 모두를 지원하는 hook 입니다.
365
+ #### 사용법 ([참고](https://github.com/seedn-corp/leaf-airmate-web-fe/blob/20bec52b87814e7c0a9f174b08bdaa0bff2e8680/src/components/historyInfo/Select/index.tsx#L14-L33))
366
+ ```tsx
367
+ const [value, setValue] = useControllableState({
368
+ prop: valueFromProps,
369
+ defaultProp: defaultValue,
370
+ onChange: onValueChange,
371
+ });
372
+ return (
373
+ <SelectProvider
374
+ value={value}
375
+ onValueChange={setValue}
376
+ triggerWidth={triggerWidth}
377
+ onTriggerWidthChange={setTriggerWidth}
378
+ >
379
+ <SelectPrimitive.Root value={value} onValueChange={setValue} {...restProps}>
380
+ <div ref={ref}>{children}</div>
381
+ </SelectPrimitive.Root>
382
+ </SelectProvider>
383
+ );
384
+ });
385
+
386
+ ```
348
387
 
349
- ```
@@ -0,0 +1,19 @@
1
+ // src/useCombinedRefs.ts
2
+ import { useCallback } from "react";
3
+ var useCombinedRefs = (...refs) => useCallback(
4
+ (element) => refs.forEach((ref) => {
5
+ if (!ref) {
6
+ return;
7
+ }
8
+ if (typeof ref === "function") {
9
+ return ref(element);
10
+ }
11
+ ref.current = element;
12
+ }),
13
+ [refs]
14
+ );
15
+
16
+ export {
17
+ useCombinedRefs
18
+ };
19
+ //# sourceMappingURL=chunk-D2YRH4XY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useCombinedRefs.ts"],"sourcesContent":["import { type Ref, useCallback } from 'react';\n// Reference: https://github.com/facebook/react/issues/13029#issuecomment-497641073\nexport const useCombinedRefs = <T>(...refs: Array<Ref<T>>): Ref<T> =>\n useCallback(\n (element: T) =>\n refs.forEach((ref) => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n return ref(element);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (ref as any).current = element;\n }),\n [refs]\n );\n"],"mappings":";AAAA,SAAmB,mBAAmB;AAE/B,IAAM,kBAAkB,IAAO,SACpC;AAAA,EACE,CAAC,YACC,KAAK,QAAQ,CAAC,QAAQ;AACpB,QAAI,CAAC,KAAK;AACR;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,YAAY;AAC7B,aAAO,IAAI,OAAO;AAAA,IACpB;AAEA,IAAC,IAAY,UAAU;AAAA,EACzB,CAAC;AAAA,EACH,CAAC,IAAI;AACP;","names":[]}
@@ -0,0 +1,57 @@
1
+ import {
2
+ usePreservedCallback_default
3
+ } from "./chunk-QGQNMD22.mjs";
4
+
5
+ // src/useControllableState.ts
6
+ import * as React from "react";
7
+ function noop() {
8
+ }
9
+ var useControllableState = ({
10
+ prop,
11
+ defaultProp,
12
+ onChange = noop
13
+ }) => {
14
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({
15
+ defaultProp,
16
+ onChange
17
+ });
18
+ const isControlled = prop !== void 0;
19
+ const value = isControlled ? prop : uncontrolledProp;
20
+ const handleChange = usePreservedCallback_default(onChange);
21
+ const setValue = React.useCallback(
22
+ (nextValue) => {
23
+ if (isControlled) {
24
+ const setter = nextValue;
25
+ const value2 = typeof nextValue === "function" ? setter(prop) : nextValue;
26
+ if (value2 !== prop) handleChange(value2);
27
+ } else {
28
+ setUncontrolledProp(nextValue);
29
+ }
30
+ },
31
+ [isControlled, prop, setUncontrolledProp, handleChange]
32
+ );
33
+ return [value, setValue];
34
+ };
35
+ var useUncontrolledState = ({
36
+ defaultProp,
37
+ onChange = noop
38
+ }) => {
39
+ const uncontrolledState = React.useState(defaultProp);
40
+ const [value] = uncontrolledState;
41
+ const prevValueRef = React.useRef(value);
42
+ const handleChange = usePreservedCallback_default(onChange);
43
+ React.useEffect(() => {
44
+ if (prevValueRef.current !== value) {
45
+ handleChange(value);
46
+ prevValueRef.current = value;
47
+ }
48
+ }, [value, prevValueRef, handleChange]);
49
+ return uncontrolledState;
50
+ };
51
+ var useControllableState_default = useControllableState;
52
+
53
+ export {
54
+ useControllableState,
55
+ useControllableState_default
56
+ };
57
+ //# sourceMappingURL=chunk-HOC4D4DT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useControllableState.ts"],"sourcesContent":["import * as React from 'react';\n\nimport usePreservedCallback from './usePreservedCallback';\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop() {}\nexport type UseControllableStateParams<T> = {\n prop?: T | undefined;\n defaultProp?: T | undefined;\n onChange?: (state: T) => void;\n};\ntype SetStateFn<T> = (prevState?: T) => T;\n/**\n * @description\n * Radix UI's useControllableState\n */\nexport const useControllableState = <T>({\n prop,\n defaultProp,\n onChange = noop,\n}: UseControllableStateParams<T>) => {\n const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({\n defaultProp,\n onChange,\n });\n const isControlled = prop !== undefined;\n const value = isControlled ? prop : uncontrolledProp;\n const handleChange = usePreservedCallback(onChange);\n const setValue: React.Dispatch<React.SetStateAction<T | undefined>> = React.useCallback(\n (nextValue) => {\n if (isControlled) {\n const setter = nextValue as SetStateFn<T>;\n const value = typeof nextValue === 'function' ? setter(prop) : nextValue;\n if (value !== prop) handleChange(value as T);\n } else {\n setUncontrolledProp(nextValue);\n }\n },\n [isControlled, prop, setUncontrolledProp, handleChange]\n );\n return [value, setValue] as const;\n};\nconst useUncontrolledState = <T>({\n defaultProp,\n onChange = noop,\n}: Omit<UseControllableStateParams<T>, 'prop'>) => {\n const uncontrolledState = React.useState<T | undefined>(defaultProp);\n const [value] = uncontrolledState;\n const prevValueRef = React.useRef(value);\n const handleChange = usePreservedCallback(onChange);\n React.useEffect(() => {\n if (prevValueRef.current !== value) {\n handleChange(value as T);\n prevValueRef.current = value;\n }\n }, [value, prevValueRef, handleChange]);\n return uncontrolledState;\n};\nexport default useControllableState;\n"],"mappings":";;;;;AAAA,YAAY,WAAW;AAIvB,SAAS,OAAO;AAAC;AAWV,IAAM,uBAAuB,CAAI;AAAA,EACtC;AAAA,EACA;AAAA,EACA,WAAW;AACb,MAAqC;AACnC,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,qBAAqB;AAAA,IACnE;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,eAAe,SAAS;AAC9B,QAAM,QAAQ,eAAe,OAAO;AACpC,QAAM,eAAe,6BAAqB,QAAQ;AAClD,QAAM,WAAsE;AAAA,IAC1E,CAAC,cAAc;AACb,UAAI,cAAc;AAChB,cAAM,SAAS;AACf,cAAMA,SAAQ,OAAO,cAAc,aAAa,OAAO,IAAI,IAAI;AAC/D,YAAIA,WAAU,KAAM,cAAaA,MAAU;AAAA,MAC7C,OAAO;AACL,4BAAoB,SAAS;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,CAAC,cAAc,MAAM,qBAAqB,YAAY;AAAA,EACxD;AACA,SAAO,CAAC,OAAO,QAAQ;AACzB;AACA,IAAM,uBAAuB,CAAI;AAAA,EAC/B;AAAA,EACA,WAAW;AACb,MAAmD;AACjD,QAAM,oBAA0B,eAAwB,WAAW;AACnE,QAAM,CAAC,KAAK,IAAI;AAChB,QAAM,eAAqB,aAAO,KAAK;AACvC,QAAM,eAAe,6BAAqB,QAAQ;AAClD,EAAM,gBAAU,MAAM;AACpB,QAAI,aAAa,YAAY,OAAO;AAClC,mBAAa,KAAU;AACvB,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,OAAO,cAAc,YAAY,CAAC;AACtC,SAAO;AACT;AACA,IAAO,+BAAQ;","names":["value"]}
@@ -0,0 +1,15 @@
1
+ // src/usePreservedCallback.ts
2
+ import { useEffect, useMemo, useRef } from "react";
3
+ var usePreservedCallback = (callback) => {
4
+ const callbackRef = useRef(callback);
5
+ useEffect(() => {
6
+ callbackRef.current = callback;
7
+ }, [callback]);
8
+ return useMemo(() => (...args) => callbackRef.current?.(...args), []);
9
+ };
10
+ var usePreservedCallback_default = usePreservedCallback;
11
+
12
+ export {
13
+ usePreservedCallback_default
14
+ };
15
+ //# sourceMappingURL=chunk-QGQNMD22.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usePreservedCallback.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst usePreservedCallback = <T extends (...args: any[]) => any>(callback: T): T => {\n const callbackRef = useRef(callback);\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n return useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n};\nexport default usePreservedCallback;\n"],"mappings":";AAAA,SAAS,WAAW,SAAS,cAAc;AAE3C,IAAM,uBAAuB,CAAoC,aAAmB;AAClF,QAAM,cAAc,OAAO,QAAQ;AACnC,YAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AACb,SAAO,QAAQ,MAAO,IAAI,SAAS,YAAY,UAAU,GAAG,IAAI,GAAS,CAAC,CAAC;AAC7E;AACA,IAAO,+BAAQ;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { ReactNode, FC, PropsWithChildren, HTMLAttributes, CSSProperties, ComponentPropsWithoutRef } from 'react';
3
+ import React__default, { ReactNode, FC, PropsWithChildren, HTMLAttributes, CSSProperties, ComponentPropsWithoutRef, Ref } from 'react';
4
4
  import * as styled_components from 'styled-components';
5
5
 
6
6
  type ChooseWhenProps = {
@@ -247,4 +247,17 @@ declare const DomainFormat: {
247
247
  }) => string;
248
248
  };
249
249
 
250
- export { type AirLevel, Choose, type ChooseOtherwiseProps, type ChooseProps, type ChooseWhenProps, type DebouncedFunction, DomainFormat, Flex, type FlexProps, Format, type HexToRgbaProps, If, type IfProps, type JosaProps, type Mode, type MultiLineEllipsisProps, SafeArea, type SafeAreaCssValueProps, type SafeAreaProps, Spacing, type SpacingProps, type UserLevel, Validate, type VariableType, type Wind, composeEventHandlers, createContext, debounce, ellipsis, getVar, hexToRgba, josa, multiLineEllipsis, queryString, useSafeArea };
250
+ declare const useCombinedRefs: <T>(...refs: Array<Ref<T>>) => Ref<T>;
251
+
252
+ type UseControllableStateParams<T> = {
253
+ prop?: T | undefined;
254
+ defaultProp?: T | undefined;
255
+ onChange?: (state: T) => void;
256
+ };
257
+ /**
258
+ * @description
259
+ * Radix UI's useControllableState
260
+ */
261
+ declare const useControllableState: <T>({ prop, defaultProp, onChange, }: UseControllableStateParams<T>) => readonly [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>];
262
+
263
+ export { type AirLevel, Choose, type ChooseOtherwiseProps, type ChooseProps, type ChooseWhenProps, type DebouncedFunction, DomainFormat, Flex, type FlexProps, Format, type HexToRgbaProps, If, type IfProps, type JosaProps, type Mode, type MultiLineEllipsisProps, SafeArea, type SafeAreaCssValueProps, type SafeAreaProps, Spacing, type SpacingProps, type UseControllableStateParams, type UserLevel, Validate, type VariableType, type Wind, composeEventHandlers, createContext, debounce, ellipsis, getVar, hexToRgba, josa, multiLineEllipsis, queryString, useCombinedRefs, useControllableState, useSafeArea };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { ReactNode, FC, PropsWithChildren, HTMLAttributes, CSSProperties, ComponentPropsWithoutRef } from 'react';
3
+ import React__default, { ReactNode, FC, PropsWithChildren, HTMLAttributes, CSSProperties, ComponentPropsWithoutRef, Ref } from 'react';
4
4
  import * as styled_components from 'styled-components';
5
5
 
6
6
  type ChooseWhenProps = {
@@ -247,4 +247,17 @@ declare const DomainFormat: {
247
247
  }) => string;
248
248
  };
249
249
 
250
- export { type AirLevel, Choose, type ChooseOtherwiseProps, type ChooseProps, type ChooseWhenProps, type DebouncedFunction, DomainFormat, Flex, type FlexProps, Format, type HexToRgbaProps, If, type IfProps, type JosaProps, type Mode, type MultiLineEllipsisProps, SafeArea, type SafeAreaCssValueProps, type SafeAreaProps, Spacing, type SpacingProps, type UserLevel, Validate, type VariableType, type Wind, composeEventHandlers, createContext, debounce, ellipsis, getVar, hexToRgba, josa, multiLineEllipsis, queryString, useSafeArea };
250
+ declare const useCombinedRefs: <T>(...refs: Array<Ref<T>>) => Ref<T>;
251
+
252
+ type UseControllableStateParams<T> = {
253
+ prop?: T | undefined;
254
+ defaultProp?: T | undefined;
255
+ onChange?: (state: T) => void;
256
+ };
257
+ /**
258
+ * @description
259
+ * Radix UI's useControllableState
260
+ */
261
+ declare const useControllableState: <T>({ prop, defaultProp, onChange, }: UseControllableStateParams<T>) => readonly [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>];
262
+
263
+ export { type AirLevel, Choose, type ChooseOtherwiseProps, type ChooseProps, type ChooseWhenProps, type DebouncedFunction, DomainFormat, Flex, type FlexProps, Format, type HexToRgbaProps, If, type IfProps, type JosaProps, type Mode, type MultiLineEllipsisProps, SafeArea, type SafeAreaCssValueProps, type SafeAreaProps, Spacing, type SpacingProps, type UseControllableStateParams, type UserLevel, Validate, type VariableType, type Wind, composeEventHandlers, createContext, debounce, ellipsis, getVar, hexToRgba, josa, multiLineEllipsis, queryString, useCombinedRefs, useControllableState, useSafeArea };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -37,6 +47,8 @@ __export(src_exports, {
37
47
  josa: () => josa,
38
48
  multiLineEllipsis: () => multiLineEllipsis,
39
49
  queryString: () => queryString,
50
+ useCombinedRefs: () => useCombinedRefs,
51
+ useControllableState: () => useControllableState,
40
52
  useSafeArea: () => useSafeArea
41
53
  });
42
54
  module.exports = __toCommonJS(src_exports);
@@ -602,6 +614,81 @@ var DomainFormat = {
602
614
  airLevelColor: formatAirLevelColor,
603
615
  userLevel: formatUserLevel
604
616
  };
617
+
618
+ // src/useCombinedRefs.ts
619
+ var import_react6 = require("react");
620
+ var useCombinedRefs = (...refs) => (0, import_react6.useCallback)(
621
+ (element) => refs.forEach((ref) => {
622
+ if (!ref) {
623
+ return;
624
+ }
625
+ if (typeof ref === "function") {
626
+ return ref(element);
627
+ }
628
+ ref.current = element;
629
+ }),
630
+ [refs]
631
+ );
632
+
633
+ // src/useControllableState.ts
634
+ var React2 = __toESM(require("react"));
635
+
636
+ // src/usePreservedCallback.ts
637
+ var import_react7 = require("react");
638
+ var usePreservedCallback = (callback) => {
639
+ const callbackRef = (0, import_react7.useRef)(callback);
640
+ (0, import_react7.useEffect)(() => {
641
+ callbackRef.current = callback;
642
+ }, [callback]);
643
+ return (0, import_react7.useMemo)(() => (...args) => callbackRef.current?.(...args), []);
644
+ };
645
+ var usePreservedCallback_default = usePreservedCallback;
646
+
647
+ // src/useControllableState.ts
648
+ function noop() {
649
+ }
650
+ var useControllableState = ({
651
+ prop,
652
+ defaultProp,
653
+ onChange = noop
654
+ }) => {
655
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({
656
+ defaultProp,
657
+ onChange
658
+ });
659
+ const isControlled = prop !== void 0;
660
+ const value = isControlled ? prop : uncontrolledProp;
661
+ const handleChange = usePreservedCallback_default(onChange);
662
+ const setValue = React2.useCallback(
663
+ (nextValue) => {
664
+ if (isControlled) {
665
+ const setter = nextValue;
666
+ const value2 = typeof nextValue === "function" ? setter(prop) : nextValue;
667
+ if (value2 !== prop) handleChange(value2);
668
+ } else {
669
+ setUncontrolledProp(nextValue);
670
+ }
671
+ },
672
+ [isControlled, prop, setUncontrolledProp, handleChange]
673
+ );
674
+ return [value, setValue];
675
+ };
676
+ var useUncontrolledState = ({
677
+ defaultProp,
678
+ onChange = noop
679
+ }) => {
680
+ const uncontrolledState = React2.useState(defaultProp);
681
+ const [value] = uncontrolledState;
682
+ const prevValueRef = React2.useRef(value);
683
+ const handleChange = usePreservedCallback_default(onChange);
684
+ React2.useEffect(() => {
685
+ if (prevValueRef.current !== value) {
686
+ handleChange(value);
687
+ prevValueRef.current = value;
688
+ }
689
+ }, [value, prevValueRef, handleChange]);
690
+ return uncontrolledState;
691
+ };
605
692
  // Annotate the CommonJS export names for ESM import in node:
606
693
  0 && (module.exports = {
607
694
  Choose,
@@ -621,6 +708,8 @@ var DomainFormat = {
621
708
  josa,
622
709
  multiLineEllipsis,
623
710
  queryString,
711
+ useCombinedRefs,
712
+ useControllableState,
624
713
  useSafeArea
625
714
  });
626
715
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Choose.tsx","../src/composeEventHandlers.ts","../src/createContext.tsx","../src/getVar.ts","../src/If.tsx","../src/Flex.tsx","../src/coerceCssPixelValue.ts","../src/ellipsis.ts","../src/hexToRgba.ts","../src/constants/josa.ts","../src/hasBatchim.ts","../src/josa.ts","../src/Validate.ts","../src/Spacing.tsx","../src/useSafeArea.ts","../src/SafeArea.tsx","../src/queryString.ts","../src/debounce.ts","../src/Format.ts","../src/DomainFormat.ts"],"sourcesContent":["export {\n Choose,\n type ChooseWhenProps,\n type ChooseProps,\n type ChooseOtherwiseProps,\n} from './Choose';\n\nexport { composeEventHandlers } from './composeEventHandlers';\n\nexport { createContext } from './createContext';\n\nexport { getVar, type VariableType } from './getVar';\n\nexport { If, type IfProps } from './If';\n\nexport { Flex, type FlexProps } from './Flex';\n\nexport { ellipsis, multiLineEllipsis, type MultiLineEllipsisProps } from './ellipsis';\n\nexport { hexToRgba, type HexToRgbaProps } from './hexToRgba';\n\nexport { josa, type JosaProps } from './josa';\n\nexport { Validate } from './Validate';\n\nexport { Spacing, type SpacingProps } from './Spacing';\n\nexport { useSafeArea, type SafeAreaCssValueProps } from './useSafeArea';\n\nexport { SafeArea, type SafeAreaProps } from './SafeArea';\n\nexport { queryString } from './queryString';\n\nexport { debounce, type DebouncedFunction } from './debounce';\n\nexport { Format } from './Format';\n\nexport { DomainFormat, type Mode, type Wind, type AirLevel, type UserLevel } from './DomainFormat';\n","import { isValidElement, type ReactNode, type FC, Children } from 'react';\n\nexport type ChooseWhenProps = {\n condition: boolean;\n children: ReactNode;\n};\n\nexport type ChooseProps = {\n children: ReactNode;\n};\n\nexport type ChooseOtherwiseProps = {\n children: ReactNode;\n};\n\nexport function Choose({ children }: ChooseProps) {\n const validChildren = Children.toArray(children);\n\n const matchingChild = validChildren.find(\n (child) =>\n isValidElement<ChooseWhenProps>(child) &&\n child.type === Choose.When &&\n child.props.condition\n );\n\n if (matchingChild) {\n return matchingChild;\n }\n\n const otherwiseChild = validChildren.find(\n (child) => isValidElement(child) && child.type === Choose.Otherwise\n );\n\n return otherwiseChild || <></>;\n}\n\nconst ChooseWhen: FC<ChooseWhenProps> = ({ children }) => <>{children}</>;\nChooseWhen.displayName = 'Choose.When';\n\nconst ChooseOtherwise: FC<ChooseOtherwiseProps> = ({ children }) => (\n <>{children}</>\n);\n\nChoose.When = ChooseWhen;\nChoose.Otherwise = ChooseOtherwise;\n","// @see https://github.com/radix-ui/primitives/blob/main/packages/core/primitive/src/primitive.tsx\n\nexport function composeEventHandlers<E>(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n { checkForDefaultPrevented = true } = {}\n) {\n return function handleEvent(event: E) {\n originalEventHandler?.(event);\n\n if (\n checkForDefaultPrevented === false ||\n !(event as unknown as Event).defaultPrevented\n ) {\n return ourEventHandler?.(event);\n }\n };\n}\n","import {\n useMemo,\n createContext as createContextRaw,\n useContext as useContextRaw,\n type PropsWithChildren,\n} from 'react';\n\nexport function createContext<ContextValueType extends object | null>(\n rootComponentName: string,\n defaultContext?: ContextValueType\n) {\n const Context = createContextRaw<ContextValueType | undefined>(\n defaultContext\n );\n\n function Provider(props: PropsWithChildren<ContextValueType>) {\n const { children, ...contextValues } = props;\n\n const value = useMemo(\n () => contextValues,\n [contextValues]\n ) as ContextValueType;\n\n return <Context.Provider value={value}>{children}</Context.Provider>;\n }\n\n function useContext(consumerName: string) {\n const context = useContextRaw(Context);\n if (context == null) {\n throw new Error(\n `${consumerName}은 ${rootComponentName}하위에서 사용해야 합니다.`\n );\n }\n\n return context;\n }\n\n Provider.displayName = `${rootComponentName}Provider`;\n return [Provider, useContext] as const;\n}\n","export type VariableType = `--${string}`;\n\nexport function getVar(variable: VariableType, defaultValue?: string) {\n if (defaultValue) {\n return `var(${variable}, ${defaultValue})`;\n }\n\n return `var(${variable})`;\n}\n","import { type ReactNode } from 'react';\n\nexport type IfProps = {\n condition: boolean;\n children: ReactNode;\n};\n\nexport function If(props: IfProps) {\n const { condition, children } = props;\n\n return condition ? <>{children}</> : null;\n}\n","import { memo, type CSSProperties, type HTMLAttributes } from 'react';\nimport { styled } from 'styled-components';\n\nimport { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\ntype Justify = CSSProperties['justifyContent'];\ntype Align = CSSProperties['alignItems'];\ntype Direction = CSSProperties['flexDirection'];\n\nexport type FlexProps = HTMLAttributes<HTMLDivElement> & {\n gap?: CSSPixelValue;\n justify?: Justify;\n align?: Align;\n direction?: Direction;\n};\n\nexport const Flex = memo(function Flex(props: FlexProps) {\n const {\n gap = 0,\n justify = 'center',\n align = 'center',\n direction = 'row',\n children,\n ...restProps\n } = props;\n\n return (\n <Container\n $gap={gap}\n $justify={justify}\n $align={align}\n $direction={direction}\n {...restProps}\n >\n {children}\n </Container>\n );\n});\n\nexport const Container = styled.div<{\n $gap: CSSPixelValue;\n $justify: Justify;\n $align: Align;\n $direction: Direction;\n}>`\n display: flex;\n flex-direction: ${({ $direction }) => $direction};\n gap: ${({ $gap }) => coerceCssPixelValue($gap)};\n align-items: ${({ $align }) => $align};\n justify-content: ${({ $justify }) => $justify};\n`;\n","export type CSSPixelValue = string | number;\n\nexport function coerceCssPixelValue(value: CSSPixelValue): string {\n return typeof value === 'string' ? value : `${value}px`;\n}\n","import { css } from 'styled-components';\n\nexport type MultiLineEllipsisProps = {\n line: number;\n};\n\nexport const ellipsis = css`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nexport const multiLineEllipsis = ({ line }: MultiLineEllipsisProps) => css`\n display: -webkit-box;\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-line-clamp: ${line};\n -webkit-box-orient: vertical;\n`;\n","export type HexToRgbaProps = { hex: string; alpha?: number };\n\nfunction parseHexToDecimal(hex: string): number {\n return parseInt(hex, 16);\n}\n\nfunction validateHex(hex: string): string {\n const match = /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.exec(hex);\n if (!match) {\n throw new Error(\n `Invalid hex value: \"${hex}\". Expected formats: \"#RGB\", \"RGB\", \"#RRGGBB\", or \"RRGGBB\".`\n );\n }\n return match[1];\n}\n\nfunction expandHex(hex: string): string {\n return hex.length === 3\n ? hex\n .split('')\n .map((char) => char + char)\n .join('')\n : hex;\n}\n\nfunction isValidAlpha(alpha: number): boolean {\n return alpha >= 0 && alpha <= 1;\n}\n\nexport function hexToRgba({ hex, alpha = 1 }: HexToRgbaProps): string {\n if (!isValidAlpha(alpha)) {\n throw new Error(\n `Invalid alpha value. Must be between 0 and 1, received: ${alpha}`\n );\n }\n\n const validatedHex = validateHex(hex);\n const expandedHex = expandHex(validatedHex);\n\n const r = parseHexToDecimal(expandedHex.slice(0, 2));\n const g = parseHexToDecimal(expandedHex.slice(2, 4));\n const b = parseHexToDecimal(expandedHex.slice(4, 6));\n\n return `rgba(${r},${g},${b},${alpha})`;\n}\n","export const COMPLETE_HANGUL_START_CHARCODE = '가'.charCodeAt(0);\nexport const COMPLETE_HANGUL_END_CHARCODE = '힣'.charCodeAt(0);\n\nexport const NUMBER_OF_JONGSEONG = 28;\nexport const NUMBER_OF_JUNGSEONG = 21;\n\nconst DISASSEMBLED_CONSONANTS_BY_CONSONANT = {\n '': '',\n ㄱ: 'ㄱ',\n ㄲ: 'ㄲ',\n ㄳ: 'ㄱㅅ',\n ㄴ: 'ㄴ',\n ㄵ: 'ㄴㅈ',\n ㄶ: 'ㄴㅎ',\n ㄷ: 'ㄷ',\n ㄸ: 'ㄸ',\n ㄹ: 'ㄹ',\n ㄺ: 'ㄹㄱ',\n ㄻ: 'ㄹㅁ',\n ㄼ: 'ㄹㅂ',\n ㄽ: 'ㄹㅅ',\n ㄾ: 'ㄹㅌ',\n ㄿ: 'ㄹㅍ',\n ㅀ: 'ㄹㅎ',\n ㅁ: 'ㅁ',\n ㅂ: 'ㅂ',\n ㅃ: 'ㅃ',\n ㅄ: 'ㅂㅅ',\n ㅅ: 'ㅅ',\n ㅆ: 'ㅆ',\n ㅇ: 'ㅇ',\n ㅈ: 'ㅈ',\n ㅉ: 'ㅉ',\n ㅊ: 'ㅊ',\n ㅋ: 'ㅋ',\n ㅌ: 'ㅌ',\n ㅍ: 'ㅍ',\n ㅎ: 'ㅎ',\n} as const;\n\nexport const JONGSEONGS = (\n [\n '',\n 'ㄱ',\n 'ㄲ',\n 'ㄳ',\n 'ㄴ',\n 'ㄵ',\n 'ㄶ',\n 'ㄷ',\n 'ㄹ',\n 'ㄺ',\n 'ㄻ',\n 'ㄼ',\n 'ㄽ',\n 'ㄾ',\n 'ㄿ',\n 'ㅀ',\n 'ㅁ',\n 'ㅂ',\n 'ㅄ',\n 'ㅅ',\n 'ㅆ',\n 'ㅇ',\n 'ㅈ',\n 'ㅊ',\n 'ㅋ',\n 'ㅌ',\n 'ㅍ',\n 'ㅎ',\n ] as const\n).map((consonant) => DISASSEMBLED_CONSONANTS_BY_CONSONANT[consonant]);\n","import {\n COMPLETE_HANGUL_END_CHARCODE,\n COMPLETE_HANGUL_START_CHARCODE,\n NUMBER_OF_JONGSEONG,\n} from './constants/josa';\n\n/**\n * 한글 음절의 받침 유무를 확인합니다.\n * @param str - 검사할 문자열\n * @returns 받침이 있으면 true, 없으면 false\n */\nexport function hasBatchim(str: string): boolean {\n const lastChar = str[str.length - 1];\n if (!lastChar) return false;\n\n const charCode = lastChar.charCodeAt(0);\n\n // 한글 완성형 문자인지 확인\n if (\n charCode < COMPLETE_HANGUL_START_CHARCODE ||\n charCode > COMPLETE_HANGUL_END_CHARCODE\n ) {\n return false;\n }\n\n // 받침 코드 계산\n const batchimCode =\n (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG;\n\n return batchimCode > 0; // 받침이 있으면 true\n}\n","import { hasBatchim } from './hasBatchim';\n\ntype JosaOption = '이/가' | '을/를' | '은/는';\n\ntype ExtractJosaOption<T> = T extends `${infer A}/${infer B}` ? A | B : never;\n\nexport type JosaProps<U extends JosaOption> = {\n word: string;\n josa: U;\n};\n\n/**\n * 주어진 단어와 조사 옵션을 기반으로 올바른 조사를 반환합니다.\n * @returns 단어와 올바른 조사가 결합된 문자열\n */\nexport function josa<U extends JosaOption>(\n props: JosaProps<U>\n): `${JosaProps<U>['word']}${ExtractJosaOption<U>}` {\n const { word, josa } = props;\n\n if (!word) {\n return word as `${JosaProps<U>['word']}${ExtractJosaOption<U>}`;\n }\n\n return `${word}${josaPicker({\n word,\n josa,\n })}` as `${JosaProps<U>['word']}${ExtractJosaOption<U>}`;\n}\n\n/**\n * 주어진 단어와 조사 옵션을 기반으로 올바른 조사를 선택합니다.\n * @returns 올바른 조사\n */\nfunction josaPicker<U extends JosaOption>(\n props: JosaProps<U>\n): ExtractJosaOption<U> {\n const { word, josa } = props;\n\n if (!word) {\n return josa.split('/')[0] as ExtractJosaOption<U>;\n }\n\n const has받침 = hasBatchim(word);\n const index = has받침 ? 0 : 1;\n\n return josa.split('/')[index] as ExtractJosaOption<U>;\n}\n\njosa.pick = josaPicker;\n","/**\n *\n * @see 이메일 주소가 RFC 5322 표준을 따르는지 검사합니다. {@link https://emailregex.com/}\n */\nfunction isEmail(email: string) {\n const regExp =\n /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n return regExp.test(email);\n}\n\nfunction isPhoneNumber(phoneNumber: string) {\n // 하이픈 있는 형식\n const regExpWithHyphen = /^01([0|1|6|7|8|9])-([0-9]{3,4})-([0-9]{4})$/;\n // 하이픈 없는 형식\n const regExpWithoutHyphen = /^01([0|1|6|7|8|9])([0-9]{3,4})([0-9]{4})$/;\n\n return (\n regExpWithHyphen.test(phoneNumber) || regExpWithoutHyphen.test(phoneNumber)\n );\n}\n\nexport const Validate = {\n email: isEmail,\n phoneNumber: isPhoneNumber,\n};\n","import { memo, type HTMLAttributes } from 'react';\nimport { styled } from 'styled-components';\n\nimport { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\ntype AxisDirection = 'vertical' | 'horizontal';\n\nexport type SpacingProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {\n direction?: AxisDirection;\n size: CSSPixelValue;\n};\n\nexport const Spacing = memo(function Spacing(props: SpacingProps) {\n const { direction = 'vertical', size, ...restProps } = props;\n\n return (\n <SpacingContainer $direction={direction} $size={size} {...restProps} />\n );\n});\n\nconst SpacingContainer = styled.div<{\n $direction: SpacingProps['direction'];\n $size: SpacingProps['size'];\n}>`\n flex: none;\n width: ${({ $direction, $size }) =>\n $direction === 'horizontal' ? coerceCssPixelValue($size) : undefined};\n height: ${({ $direction, $size }) =>\n $direction === 'vertical' ? coerceCssPixelValue($size) : undefined};\n`;\n","import { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\nexport type SafeAreaCssValueProps = {\n top?: CSSPixelValue;\n bottom?: CSSPixelValue;\n left?: CSSPixelValue;\n right?: CSSPixelValue;\n};\n\nconst useSafeArea = ({\n top: T = 0,\n bottom: B = 0,\n left: L = 0,\n right: R = 0,\n}: SafeAreaCssValueProps = {}) => {\n const top = `max(${coerceCssPixelValue(T)}, env(safe-area-inset-top))`;\n const bottom = `max(${coerceCssPixelValue(B)}, env(safe-area-inset-bottom))`;\n const left = `max(${coerceCssPixelValue(L)}, env(safe-area-inset-left))`;\n const right = `max(${coerceCssPixelValue(R)}, env(safe-area-inset-right))`;\n\n return { top, bottom, left, right };\n};\n\nexport { useSafeArea };\n","import React, {\n memo,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\n\nimport { Spacing } from './Spacing';\nimport { useSafeArea } from './useSafeArea';\n\nexport type SafeAreaProps<T extends React.ElementType = 'div'> = {\n as?: T;\n children: ReactNode;\n} & ComponentPropsWithoutRef<T>;\n\nexport const SafeArea = <T extends React.ElementType = 'div'>({\n as,\n children,\n ...props\n}: SafeAreaProps<T>) => {\n const Component = as || 'div';\n\n return (\n <Component {...props}>\n <SafeAreaTop />\n {children}\n <SafeAreaBottom />\n </Component>\n );\n};\n\nconst SafeAreaTop = memo(function SafeAreaTop(\n props: Omit<ComponentPropsWithoutRef<typeof Spacing>, 'size'>\n) {\n const { top } = useSafeArea();\n return <Spacing {...props} size={top} />;\n});\n\nconst SafeAreaBottom = memo(function SafeAreaBottom(\n props: Omit<ComponentPropsWithoutRef<typeof Spacing>, 'size'>\n) {\n const { bottom } = useSafeArea();\n return <Spacing {...props} size={bottom} />;\n});\n\nSafeArea.Top = SafeAreaTop;\nSafeArea.Bottom = SafeAreaBottom;\n","/**\n * @description 쿼리 스트링을 생성합니다.\n * @example createSearchParamString({ a: 1, b: 2, c: 3 }) // 'a=1&b=2&c=3'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createSearchParamString(params: Record<string, any>) {\n return (\n new URLSearchParams(\n Object.entries(params)\n .filter(([, value]) => value != null)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n return value.map((x) => [key, x]);\n }\n return [[key, value]];\n })\n .flat()\n )\n .toString()\n // Convert space characters to '%20' according to RFC3986 spec, from RFC1738.\n .replace(/\\+/g, '%20')\n );\n}\n\n/**\n * @description 물음표를 포함한 쿼리 스트링을 생성합니다.\n * @example createQueryString({ a: 1, b: 2, c: 3 }) // '?a=1&b=2&c=3'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createQueryString(params: Record<string, any>) {\n const queryString = createSearchParamString(params);\n\n if (queryString === '') {\n return '';\n }\n\n return `?${queryString}`;\n}\n\n/**\n * @description 이터러블에서 키와 값을 가진 객체로 변환합니다.\n * @example fromEntries([['a', 1], ['b', 2], ['c', 3]]) // { a: 1, b: 2, c: 3 }\n */\nfunction fromEntries<T extends readonly [string | number, unknown]>(\n iterable: Iterable<T>\n) {\n const result: Record<string | number | symbol, T[1]> = {};\n\n for (const [key, value] of Array.from(iterable)) {\n if (result[key]) {\n if (Array.isArray(result[key])) {\n (result[key] as Array<string | number>).push(value as string | number);\n } else {\n result[key] = [result[key], value];\n }\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * @description 쿼리 스트링을 객체로 변환합니다.\n * @example parseQueryString('?a=1&b=2&c=3') // { a: '1', b: '2', c: '3' }\n */\nfunction parseQueryString<Result = Record<string, string>>(\n queryString: string = typeof location !== 'undefined' ? location.search : ''\n): Result {\n const query = queryString.trim().replace(/^[?#&]/, '');\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fromEntries(new URLSearchParams(query)) as any;\n}\n\n/**\n * @description 쿼리 스트링에서 특정 키의 값을 가져옵니다.\n *\n * @param name 가져올 쿼리 스트링의 키\n * @param parser 가져온 값을 파싱할 함수\n * @returns 파싱된 값\n *\n * @example\n * url: 'http://example.com/?a=1'\n * getQueryString('a') // '1'\n * getQueryString('a', parseInt) // 1\n * getQueryString('b') // undefined\n * getQueryString('b', parseInt) // undefined\n */\nfunction getQueryString(name: string): string | undefined;\nfunction getQueryString<T>(\n name: string,\n parser: (val: string) => T\n): T | undefined;\nfunction getQueryString<T = string>(name: string, parser?: (val: string) => T) {\n const value = queryString.parse<{ [name: string]: string | undefined }>()[\n name\n ];\n\n if (parser == null || value == null) {\n return value;\n } else {\n return parser(value);\n }\n}\n\n/**\n * @description 기존 쿼리 스트링에 새로운 쿼리 스트링을 추가합니다.\n * @example setQueryString({ qs: '?a=1', key: 'b', value: '2' }) // '?a=1&b=2'\n */\nfunction setQueryString({\n qs,\n key,\n value,\n}: {\n qs: string;\n key: string;\n value: string;\n}) {\n const parsed = parseQueryString(qs);\n\n return createQueryString({\n ...parsed,\n [key]: value,\n });\n}\n\nexport const queryString = {\n create: createQueryString,\n parse: parseQueryString,\n get: getQueryString,\n set: setQueryString,\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport type DebouncedFunction<F extends (...args: any[]) => void> = {\n (...args: Parameters<F>): void;\n\n /**\n * 디바운스된 함수의 모든 예약된 실행을 취소합니다.\n * 이 메서드는 활성 타이머를 제거하고 저장된 컨텍스트나 인수를 재설정합니다.\n */\n cancel: () => void;\n\n /**\n * 예약된 실행이 있는 경우 디바운스된 함수를 즉시 호출합니다.\n * 이 메서드는 현재 타이머를 취소하여 함수가 즉시 실행되도록 합니다.\n */\n flush: () => void;\n};\n\n/**\n * @example\n * const debouncedFunction = debounce(() => {\n * console.log('Function executed');\n * }, 1000);\n *\n */\nexport function debounce<F extends (...args: any[]) => void>(\n func: F,\n debounceMs: number\n): DebouncedFunction<F> {\n let pendingCall: { thisArg: any; args: Parameters<F> } | null = null;\n\n const invoke = () => {\n if (pendingCall !== null) {\n const { thisArg, args } = pendingCall;\n func.apply(thisArg, args);\n pendingCall = null;\n }\n };\n\n const onTimerEnd = () => {\n invoke();\n cancel();\n };\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const schedule = () => {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n timeoutId = null;\n onTimerEnd();\n }, debounceMs);\n };\n\n const cancelTimer = () => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n const cancel = () => {\n cancelTimer();\n pendingCall = null;\n };\n\n const flush = () => {\n cancelTimer();\n invoke();\n };\n\n const debounced = function (this: any, ...args: Parameters<F>) {\n pendingCall = { thisArg: this, args };\n schedule();\n };\n\n debounced.cancel = cancel;\n debounced.flush = flush;\n\n return debounced;\n}\n","type Value = number | string;\n\nexport const Format = {\n phone: formatPhoneNumber,\n removeHyphen,\n commaize: formatCommaizeNumber,\n padTime,\n};\n\n/**\n * 숫자를 전화번호 형식으로 변환합니다.\n * @example Format.phone('01012345678') // '010-1234-5678'\n */\nfunction formatPhoneNumber(phoneNumber: string) {\n return phoneNumber\n .replace(/[^0-9]/g, '')\n .replace(/^(\\d{0,3})(\\d{0,4})(\\d{0,4})$/g, '$1-$2-$3')\n .replace(/(-{1,2})$/g, '');\n}\n\n/**\n * 하이픈을 제거합니다.\n * @example Format.removeHyphen('01012345678') // '01012345678'\n */\nfunction removeHyphen(value: string) {\n return value.replaceAll('-', '');\n}\n\n/**\n * 숫자를 콤마로 구분합니다.\n * https://www.slash.page/ko/libraries/common/utils/src/Numbers_commaizeNumber.i18n\n *\n * @example\n * Format.commaize('123456') // '123,456'\n * Format.commaize(123456) // '123,456'\n */\nfunction formatCommaizeNumber(value: Value) {\n const numStr = String(value);\n const decimalPointIndex = numStr.indexOf('.');\n const commaizeRegExp = /(\\d)(?=(\\d\\d\\d)+(?!\\d))/g;\n\n return decimalPointIndex > -1\n ? numStr.slice(0, decimalPointIndex).replace(commaizeRegExp, '$1,') +\n numStr.slice(decimalPointIndex)\n : numStr.replace(commaizeRegExp, '$1,');\n}\n\n/**\n * 숫자를 2자리 수 형태로 변환합니다.\n * @example Format.padTime(9) // '09'\n */\nfunction padTime(value: Value) {\n return String(value).padStart(2, '0');\n}\n","export type Mode = 'H' | 'C' | 'W';\nexport type Wind = 1 | 2 | 3;\nexport type AirLevel = 1 | 2 | 3 | 4 | 5;\nexport type UserLevel = '1' | '2' | '3' | '4';\nexport type Language = 'en' | 'ko';\n\nfunction formatModeName(mode: Mode, customMapping: Record<string, string> = {}): string {\n const defaultModeMapping: Record<Mode, string> = {\n H: '난방',\n C: '냉방',\n W: '송풍',\n };\n\n const combinedMapping = { ...defaultModeMapping, ...customMapping };\n\n if (!(mode in combinedMapping)) {\n throw new Error(`지원하지 않는 모드입니다. mode: ${mode}`);\n }\n\n return combinedMapping[mode];\n}\n\nfunction formatModeColor(mode: Mode, customMapping: Record<string, string> = {}) {\n const defaultColorMapping: Record<Mode, string> = {\n H: '#e77676',\n C: '#9fc6ff',\n W: '#a8e379',\n };\n\n const combinedMapping = { ...defaultColorMapping, ...customMapping };\n\n if (!(mode in combinedMapping)) {\n throw new Error(`지원하지 않는 모드입니다. mode: ${mode}`);\n }\n\n return combinedMapping[mode];\n}\n\nfunction formatWind(wind: Wind, customMapping: Record<string, string> = {}) {\n const defaultWindMapping: Record<Wind, string> = {\n 1: '미풍',\n 2: '약풍',\n 3: '강풍',\n };\n\n const combinedMapping = { ...defaultWindMapping, ...customMapping };\n\n if (!(wind in combinedMapping)) {\n throw new Error(`지원하지 않는 풍량입니다. wind: ${wind}`);\n }\n\n return combinedMapping[wind];\n}\n\nfunction formatAirLevelName(level: AirLevel) {\n const airLevelMapping: Record<AirLevel, string> = {\n 1: '매우 나쁨',\n 2: '나쁨',\n 3: '보통',\n 4: '좋음',\n 5: '매우 좋음',\n };\n\n if (!(level in airLevelMapping)) {\n throw new Error(`지원하지 않는 레벨입니다. level: ${level}`);\n }\n\n return airLevelMapping[level];\n}\n\nfunction formatAirLevelColor(level: AirLevel) {\n const colorMapping: Record<AirLevel, string> = {\n 1: '#ff5d47',\n 2: '#ff961c',\n 3: '#ffca42',\n 4: '#63ff60',\n 5: '#49ffe9',\n };\n\n if (!(level in colorMapping)) {\n throw new Error(`지원하지 않는 레벨입니다. level: ${level}`);\n }\n\n return colorMapping[level];\n}\n\nconst formatUserLevel = ({ level, language = 'ko' }: { level: UserLevel; language?: Language }) => {\n const userLevelMapping: Record<Language, Record<UserLevel, string>> = {\n en: {\n '1': 'MASTER',\n '2': 'MASTER KID',\n '3': 'SENIOR',\n '4': 'JUNIOR',\n },\n ko: {\n '1': '마스터',\n '2': '마스터키즈',\n '3': '시니어',\n '4': '주니어',\n },\n };\n\n if (!(language in userLevelMapping)) {\n throw new Error(`지원하지 않는 언어입니다. language: ${language}`);\n }\n\n if (!(level in userLevelMapping[language])) {\n throw new Error(`지원하지 않는 레벨입니다. level: ${level}`);\n }\n\n return userLevelMapping[language][level];\n};\n\nexport const DomainFormat = {\n modeName: formatModeName,\n modeColor: formatModeColor,\n wind: formatWind,\n airLevelName: formatAirLevelName,\n airLevelColor: formatAirLevelColor,\n userLevel: formatUserLevel,\n};\n"],"mappings":"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","names":["import_react","import_jsx_runtime","createContextRaw","useContextRaw","import_jsx_runtime","import_react","import_jsx_runtime","Flex","import_styled_components","josa","import_react","import_styled_components","import_jsx_runtime","Spacing","import_react","import_jsx_runtime","SafeAreaTop","SafeAreaBottom","queryString"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Choose.tsx","../src/composeEventHandlers.ts","../src/createContext.tsx","../src/getVar.ts","../src/If.tsx","../src/Flex.tsx","../src/coerceCssPixelValue.ts","../src/ellipsis.ts","../src/hexToRgba.ts","../src/constants/josa.ts","../src/hasBatchim.ts","../src/josa.ts","../src/Validate.ts","../src/Spacing.tsx","../src/useSafeArea.ts","../src/SafeArea.tsx","../src/queryString.ts","../src/debounce.ts","../src/Format.ts","../src/DomainFormat.ts","../src/useCombinedRefs.ts","../src/useControllableState.ts","../src/usePreservedCallback.ts"],"sourcesContent":["export {\n Choose,\n type ChooseWhenProps,\n type ChooseProps,\n type ChooseOtherwiseProps,\n} from './Choose';\n\nexport { composeEventHandlers } from './composeEventHandlers';\n\nexport { createContext } from './createContext';\n\nexport { getVar, type VariableType } from './getVar';\n\nexport { If, type IfProps } from './If';\n\nexport { Flex, type FlexProps } from './Flex';\n\nexport { ellipsis, multiLineEllipsis, type MultiLineEllipsisProps } from './ellipsis';\n\nexport { hexToRgba, type HexToRgbaProps } from './hexToRgba';\n\nexport { josa, type JosaProps } from './josa';\n\nexport { Validate } from './Validate';\n\nexport { Spacing, type SpacingProps } from './Spacing';\n\nexport { useSafeArea, type SafeAreaCssValueProps } from './useSafeArea';\n\nexport { SafeArea, type SafeAreaProps } from './SafeArea';\n\nexport { queryString } from './queryString';\n\nexport { debounce, type DebouncedFunction } from './debounce';\n\nexport { Format } from './Format';\n\nexport { DomainFormat, type Mode, type Wind, type AirLevel, type UserLevel } from './DomainFormat';\n\nexport { useCombinedRefs } from './useCombinedRefs';\n\nexport { useControllableState, type UseControllableStateParams } from './useControllableState';\n","import { isValidElement, type ReactNode, type FC, Children } from 'react';\n\nexport type ChooseWhenProps = {\n condition: boolean;\n children: ReactNode;\n};\n\nexport type ChooseProps = {\n children: ReactNode;\n};\n\nexport type ChooseOtherwiseProps = {\n children: ReactNode;\n};\n\nexport function Choose({ children }: ChooseProps) {\n const validChildren = Children.toArray(children);\n\n const matchingChild = validChildren.find(\n (child) =>\n isValidElement<ChooseWhenProps>(child) &&\n child.type === Choose.When &&\n child.props.condition\n );\n\n if (matchingChild) {\n return matchingChild;\n }\n\n const otherwiseChild = validChildren.find(\n (child) => isValidElement(child) && child.type === Choose.Otherwise\n );\n\n return otherwiseChild || <></>;\n}\n\nconst ChooseWhen: FC<ChooseWhenProps> = ({ children }) => <>{children}</>;\nChooseWhen.displayName = 'Choose.When';\n\nconst ChooseOtherwise: FC<ChooseOtherwiseProps> = ({ children }) => (\n <>{children}</>\n);\n\nChoose.When = ChooseWhen;\nChoose.Otherwise = ChooseOtherwise;\n","// @see https://github.com/radix-ui/primitives/blob/main/packages/core/primitive/src/primitive.tsx\n\nexport function composeEventHandlers<E>(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n { checkForDefaultPrevented = true } = {}\n) {\n return function handleEvent(event: E) {\n originalEventHandler?.(event);\n\n if (\n checkForDefaultPrevented === false ||\n !(event as unknown as Event).defaultPrevented\n ) {\n return ourEventHandler?.(event);\n }\n };\n}\n","import {\n useMemo,\n createContext as createContextRaw,\n useContext as useContextRaw,\n type PropsWithChildren,\n} from 'react';\n\nexport function createContext<ContextValueType extends object | null>(\n rootComponentName: string,\n defaultContext?: ContextValueType\n) {\n const Context = createContextRaw<ContextValueType | undefined>(\n defaultContext\n );\n\n function Provider(props: PropsWithChildren<ContextValueType>) {\n const { children, ...contextValues } = props;\n\n const value = useMemo(\n () => contextValues,\n [contextValues]\n ) as ContextValueType;\n\n return <Context.Provider value={value}>{children}</Context.Provider>;\n }\n\n function useContext(consumerName: string) {\n const context = useContextRaw(Context);\n if (context == null) {\n throw new Error(\n `${consumerName}은 ${rootComponentName}하위에서 사용해야 합니다.`\n );\n }\n\n return context;\n }\n\n Provider.displayName = `${rootComponentName}Provider`;\n return [Provider, useContext] as const;\n}\n","export type VariableType = `--${string}`;\n\nexport function getVar(variable: VariableType, defaultValue?: string) {\n if (defaultValue) {\n return `var(${variable}, ${defaultValue})`;\n }\n\n return `var(${variable})`;\n}\n","import { type ReactNode } from 'react';\n\nexport type IfProps = {\n condition: boolean;\n children: ReactNode;\n};\n\nexport function If(props: IfProps) {\n const { condition, children } = props;\n\n return condition ? <>{children}</> : null;\n}\n","import { memo, type CSSProperties, type HTMLAttributes } from 'react';\nimport { styled } from 'styled-components';\n\nimport { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\ntype Justify = CSSProperties['justifyContent'];\ntype Align = CSSProperties['alignItems'];\ntype Direction = CSSProperties['flexDirection'];\n\nexport type FlexProps = HTMLAttributes<HTMLDivElement> & {\n gap?: CSSPixelValue;\n justify?: Justify;\n align?: Align;\n direction?: Direction;\n};\n\nexport const Flex = memo(function Flex(props: FlexProps) {\n const {\n gap = 0,\n justify = 'center',\n align = 'center',\n direction = 'row',\n children,\n ...restProps\n } = props;\n\n return (\n <Container\n $gap={gap}\n $justify={justify}\n $align={align}\n $direction={direction}\n {...restProps}\n >\n {children}\n </Container>\n );\n});\n\nexport const Container = styled.div<{\n $gap: CSSPixelValue;\n $justify: Justify;\n $align: Align;\n $direction: Direction;\n}>`\n display: flex;\n flex-direction: ${({ $direction }) => $direction};\n gap: ${({ $gap }) => coerceCssPixelValue($gap)};\n align-items: ${({ $align }) => $align};\n justify-content: ${({ $justify }) => $justify};\n`;\n","export type CSSPixelValue = string | number;\n\nexport function coerceCssPixelValue(value: CSSPixelValue): string {\n return typeof value === 'string' ? value : `${value}px`;\n}\n","import { css } from 'styled-components';\n\nexport type MultiLineEllipsisProps = {\n line: number;\n};\n\nexport const ellipsis = css`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nexport const multiLineEllipsis = ({ line }: MultiLineEllipsisProps) => css`\n display: -webkit-box;\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-line-clamp: ${line};\n -webkit-box-orient: vertical;\n`;\n","export type HexToRgbaProps = { hex: string; alpha?: number };\n\nfunction parseHexToDecimal(hex: string): number {\n return parseInt(hex, 16);\n}\n\nfunction validateHex(hex: string): string {\n const match = /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.exec(hex);\n if (!match) {\n throw new Error(\n `Invalid hex value: \"${hex}\". Expected formats: \"#RGB\", \"RGB\", \"#RRGGBB\", or \"RRGGBB\".`\n );\n }\n return match[1];\n}\n\nfunction expandHex(hex: string): string {\n return hex.length === 3\n ? hex\n .split('')\n .map((char) => char + char)\n .join('')\n : hex;\n}\n\nfunction isValidAlpha(alpha: number): boolean {\n return alpha >= 0 && alpha <= 1;\n}\n\nexport function hexToRgba({ hex, alpha = 1 }: HexToRgbaProps): string {\n if (!isValidAlpha(alpha)) {\n throw new Error(\n `Invalid alpha value. Must be between 0 and 1, received: ${alpha}`\n );\n }\n\n const validatedHex = validateHex(hex);\n const expandedHex = expandHex(validatedHex);\n\n const r = parseHexToDecimal(expandedHex.slice(0, 2));\n const g = parseHexToDecimal(expandedHex.slice(2, 4));\n const b = parseHexToDecimal(expandedHex.slice(4, 6));\n\n return `rgba(${r},${g},${b},${alpha})`;\n}\n","export const COMPLETE_HANGUL_START_CHARCODE = '가'.charCodeAt(0);\nexport const COMPLETE_HANGUL_END_CHARCODE = '힣'.charCodeAt(0);\n\nexport const NUMBER_OF_JONGSEONG = 28;\nexport const NUMBER_OF_JUNGSEONG = 21;\n\nconst DISASSEMBLED_CONSONANTS_BY_CONSONANT = {\n '': '',\n ㄱ: 'ㄱ',\n ㄲ: 'ㄲ',\n ㄳ: 'ㄱㅅ',\n ㄴ: 'ㄴ',\n ㄵ: 'ㄴㅈ',\n ㄶ: 'ㄴㅎ',\n ㄷ: 'ㄷ',\n ㄸ: 'ㄸ',\n ㄹ: 'ㄹ',\n ㄺ: 'ㄹㄱ',\n ㄻ: 'ㄹㅁ',\n ㄼ: 'ㄹㅂ',\n ㄽ: 'ㄹㅅ',\n ㄾ: 'ㄹㅌ',\n ㄿ: 'ㄹㅍ',\n ㅀ: 'ㄹㅎ',\n ㅁ: 'ㅁ',\n ㅂ: 'ㅂ',\n ㅃ: 'ㅃ',\n ㅄ: 'ㅂㅅ',\n ㅅ: 'ㅅ',\n ㅆ: 'ㅆ',\n ㅇ: 'ㅇ',\n ㅈ: 'ㅈ',\n ㅉ: 'ㅉ',\n ㅊ: 'ㅊ',\n ㅋ: 'ㅋ',\n ㅌ: 'ㅌ',\n ㅍ: 'ㅍ',\n ㅎ: 'ㅎ',\n} as const;\n\nexport const JONGSEONGS = (\n [\n '',\n 'ㄱ',\n 'ㄲ',\n 'ㄳ',\n 'ㄴ',\n 'ㄵ',\n 'ㄶ',\n 'ㄷ',\n 'ㄹ',\n 'ㄺ',\n 'ㄻ',\n 'ㄼ',\n 'ㄽ',\n 'ㄾ',\n 'ㄿ',\n 'ㅀ',\n 'ㅁ',\n 'ㅂ',\n 'ㅄ',\n 'ㅅ',\n 'ㅆ',\n 'ㅇ',\n 'ㅈ',\n 'ㅊ',\n 'ㅋ',\n 'ㅌ',\n 'ㅍ',\n 'ㅎ',\n ] as const\n).map((consonant) => DISASSEMBLED_CONSONANTS_BY_CONSONANT[consonant]);\n","import {\n COMPLETE_HANGUL_END_CHARCODE,\n COMPLETE_HANGUL_START_CHARCODE,\n NUMBER_OF_JONGSEONG,\n} from './constants/josa';\n\n/**\n * 한글 음절의 받침 유무를 확인합니다.\n * @param str - 검사할 문자열\n * @returns 받침이 있으면 true, 없으면 false\n */\nexport function hasBatchim(str: string): boolean {\n const lastChar = str[str.length - 1];\n if (!lastChar) return false;\n\n const charCode = lastChar.charCodeAt(0);\n\n // 한글 완성형 문자인지 확인\n if (\n charCode < COMPLETE_HANGUL_START_CHARCODE ||\n charCode > COMPLETE_HANGUL_END_CHARCODE\n ) {\n return false;\n }\n\n // 받침 코드 계산\n const batchimCode =\n (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG;\n\n return batchimCode > 0; // 받침이 있으면 true\n}\n","import { hasBatchim } from './hasBatchim';\n\ntype JosaOption = '이/가' | '을/를' | '은/는';\n\ntype ExtractJosaOption<T> = T extends `${infer A}/${infer B}` ? A | B : never;\n\nexport type JosaProps<U extends JosaOption> = {\n word: string;\n josa: U;\n};\n\n/**\n * 주어진 단어와 조사 옵션을 기반으로 올바른 조사를 반환합니다.\n * @returns 단어와 올바른 조사가 결합된 문자열\n */\nexport function josa<U extends JosaOption>(\n props: JosaProps<U>\n): `${JosaProps<U>['word']}${ExtractJosaOption<U>}` {\n const { word, josa } = props;\n\n if (!word) {\n return word as `${JosaProps<U>['word']}${ExtractJosaOption<U>}`;\n }\n\n return `${word}${josaPicker({\n word,\n josa,\n })}` as `${JosaProps<U>['word']}${ExtractJosaOption<U>}`;\n}\n\n/**\n * 주어진 단어와 조사 옵션을 기반으로 올바른 조사를 선택합니다.\n * @returns 올바른 조사\n */\nfunction josaPicker<U extends JosaOption>(\n props: JosaProps<U>\n): ExtractJosaOption<U> {\n const { word, josa } = props;\n\n if (!word) {\n return josa.split('/')[0] as ExtractJosaOption<U>;\n }\n\n const has받침 = hasBatchim(word);\n const index = has받침 ? 0 : 1;\n\n return josa.split('/')[index] as ExtractJosaOption<U>;\n}\n\njosa.pick = josaPicker;\n","/**\n *\n * @see 이메일 주소가 RFC 5322 표준을 따르는지 검사합니다. {@link https://emailregex.com/}\n */\nfunction isEmail(email: string) {\n const regExp =\n /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n return regExp.test(email);\n}\n\nfunction isPhoneNumber(phoneNumber: string) {\n // 하이픈 있는 형식\n const regExpWithHyphen = /^01([0|1|6|7|8|9])-([0-9]{3,4})-([0-9]{4})$/;\n // 하이픈 없는 형식\n const regExpWithoutHyphen = /^01([0|1|6|7|8|9])([0-9]{3,4})([0-9]{4})$/;\n\n return (\n regExpWithHyphen.test(phoneNumber) || regExpWithoutHyphen.test(phoneNumber)\n );\n}\n\nexport const Validate = {\n email: isEmail,\n phoneNumber: isPhoneNumber,\n};\n","import { memo, type HTMLAttributes } from 'react';\nimport { styled } from 'styled-components';\n\nimport { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\ntype AxisDirection = 'vertical' | 'horizontal';\n\nexport type SpacingProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {\n direction?: AxisDirection;\n size: CSSPixelValue;\n};\n\nexport const Spacing = memo(function Spacing(props: SpacingProps) {\n const { direction = 'vertical', size, ...restProps } = props;\n\n return (\n <SpacingContainer $direction={direction} $size={size} {...restProps} />\n );\n});\n\nconst SpacingContainer = styled.div<{\n $direction: SpacingProps['direction'];\n $size: SpacingProps['size'];\n}>`\n flex: none;\n width: ${({ $direction, $size }) =>\n $direction === 'horizontal' ? coerceCssPixelValue($size) : undefined};\n height: ${({ $direction, $size }) =>\n $direction === 'vertical' ? coerceCssPixelValue($size) : undefined};\n`;\n","import { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\nexport type SafeAreaCssValueProps = {\n top?: CSSPixelValue;\n bottom?: CSSPixelValue;\n left?: CSSPixelValue;\n right?: CSSPixelValue;\n};\n\nconst useSafeArea = ({\n top: T = 0,\n bottom: B = 0,\n left: L = 0,\n right: R = 0,\n}: SafeAreaCssValueProps = {}) => {\n const top = `max(${coerceCssPixelValue(T)}, env(safe-area-inset-top))`;\n const bottom = `max(${coerceCssPixelValue(B)}, env(safe-area-inset-bottom))`;\n const left = `max(${coerceCssPixelValue(L)}, env(safe-area-inset-left))`;\n const right = `max(${coerceCssPixelValue(R)}, env(safe-area-inset-right))`;\n\n return { top, bottom, left, right };\n};\n\nexport { useSafeArea };\n","import React, {\n memo,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\n\nimport { Spacing } from './Spacing';\nimport { useSafeArea } from './useSafeArea';\n\nexport type SafeAreaProps<T extends React.ElementType = 'div'> = {\n as?: T;\n children: ReactNode;\n} & ComponentPropsWithoutRef<T>;\n\nexport const SafeArea = <T extends React.ElementType = 'div'>({\n as,\n children,\n ...props\n}: SafeAreaProps<T>) => {\n const Component = as || 'div';\n\n return (\n <Component {...props}>\n <SafeAreaTop />\n {children}\n <SafeAreaBottom />\n </Component>\n );\n};\n\nconst SafeAreaTop = memo(function SafeAreaTop(\n props: Omit<ComponentPropsWithoutRef<typeof Spacing>, 'size'>\n) {\n const { top } = useSafeArea();\n return <Spacing {...props} size={top} />;\n});\n\nconst SafeAreaBottom = memo(function SafeAreaBottom(\n props: Omit<ComponentPropsWithoutRef<typeof Spacing>, 'size'>\n) {\n const { bottom } = useSafeArea();\n return <Spacing {...props} size={bottom} />;\n});\n\nSafeArea.Top = SafeAreaTop;\nSafeArea.Bottom = SafeAreaBottom;\n","/**\n * @description 쿼리 스트링을 생성합니다.\n * @example createSearchParamString({ a: 1, b: 2, c: 3 }) // 'a=1&b=2&c=3'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createSearchParamString(params: Record<string, any>) {\n return (\n new URLSearchParams(\n Object.entries(params)\n .filter(([, value]) => value != null)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n return value.map((x) => [key, x]);\n }\n return [[key, value]];\n })\n .flat()\n )\n .toString()\n // Convert space characters to '%20' according to RFC3986 spec, from RFC1738.\n .replace(/\\+/g, '%20')\n );\n}\n\n/**\n * @description 물음표를 포함한 쿼리 스트링을 생성합니다.\n * @example createQueryString({ a: 1, b: 2, c: 3 }) // '?a=1&b=2&c=3'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createQueryString(params: Record<string, any>) {\n const queryString = createSearchParamString(params);\n\n if (queryString === '') {\n return '';\n }\n\n return `?${queryString}`;\n}\n\n/**\n * @description 이터러블에서 키와 값을 가진 객체로 변환합니다.\n * @example fromEntries([['a', 1], ['b', 2], ['c', 3]]) // { a: 1, b: 2, c: 3 }\n */\nfunction fromEntries<T extends readonly [string | number, unknown]>(\n iterable: Iterable<T>\n) {\n const result: Record<string | number | symbol, T[1]> = {};\n\n for (const [key, value] of Array.from(iterable)) {\n if (result[key]) {\n if (Array.isArray(result[key])) {\n (result[key] as Array<string | number>).push(value as string | number);\n } else {\n result[key] = [result[key], value];\n }\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * @description 쿼리 스트링을 객체로 변환합니다.\n * @example parseQueryString('?a=1&b=2&c=3') // { a: '1', b: '2', c: '3' }\n */\nfunction parseQueryString<Result = Record<string, string>>(\n queryString: string = typeof location !== 'undefined' ? location.search : ''\n): Result {\n const query = queryString.trim().replace(/^[?#&]/, '');\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fromEntries(new URLSearchParams(query)) as any;\n}\n\n/**\n * @description 쿼리 스트링에서 특정 키의 값을 가져옵니다.\n *\n * @param name 가져올 쿼리 스트링의 키\n * @param parser 가져온 값을 파싱할 함수\n * @returns 파싱된 값\n *\n * @example\n * url: 'http://example.com/?a=1'\n * getQueryString('a') // '1'\n * getQueryString('a', parseInt) // 1\n * getQueryString('b') // undefined\n * getQueryString('b', parseInt) // undefined\n */\nfunction getQueryString(name: string): string | undefined;\nfunction getQueryString<T>(\n name: string,\n parser: (val: string) => T\n): T | undefined;\nfunction getQueryString<T = string>(name: string, parser?: (val: string) => T) {\n const value = queryString.parse<{ [name: string]: string | undefined }>()[\n name\n ];\n\n if (parser == null || value == null) {\n return value;\n } else {\n return parser(value);\n }\n}\n\n/**\n * @description 기존 쿼리 스트링에 새로운 쿼리 스트링을 추가합니다.\n * @example setQueryString({ qs: '?a=1', key: 'b', value: '2' }) // '?a=1&b=2'\n */\nfunction setQueryString({\n qs,\n key,\n value,\n}: {\n qs: string;\n key: string;\n value: string;\n}) {\n const parsed = parseQueryString(qs);\n\n return createQueryString({\n ...parsed,\n [key]: value,\n });\n}\n\nexport const queryString = {\n create: createQueryString,\n parse: parseQueryString,\n get: getQueryString,\n set: setQueryString,\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport type DebouncedFunction<F extends (...args: any[]) => void> = {\n (...args: Parameters<F>): void;\n\n /**\n * 디바운스된 함수의 모든 예약된 실행을 취소합니다.\n * 이 메서드는 활성 타이머를 제거하고 저장된 컨텍스트나 인수를 재설정합니다.\n */\n cancel: () => void;\n\n /**\n * 예약된 실행이 있는 경우 디바운스된 함수를 즉시 호출합니다.\n * 이 메서드는 현재 타이머를 취소하여 함수가 즉시 실행되도록 합니다.\n */\n flush: () => void;\n};\n\n/**\n * @example\n * const debouncedFunction = debounce(() => {\n * console.log('Function executed');\n * }, 1000);\n *\n */\nexport function debounce<F extends (...args: any[]) => void>(\n func: F,\n debounceMs: number\n): DebouncedFunction<F> {\n let pendingCall: { thisArg: any; args: Parameters<F> } | null = null;\n\n const invoke = () => {\n if (pendingCall !== null) {\n const { thisArg, args } = pendingCall;\n func.apply(thisArg, args);\n pendingCall = null;\n }\n };\n\n const onTimerEnd = () => {\n invoke();\n cancel();\n };\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const schedule = () => {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n timeoutId = null;\n onTimerEnd();\n }, debounceMs);\n };\n\n const cancelTimer = () => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n const cancel = () => {\n cancelTimer();\n pendingCall = null;\n };\n\n const flush = () => {\n cancelTimer();\n invoke();\n };\n\n const debounced = function (this: any, ...args: Parameters<F>) {\n pendingCall = { thisArg: this, args };\n schedule();\n };\n\n debounced.cancel = cancel;\n debounced.flush = flush;\n\n return debounced;\n}\n","type Value = number | string;\n\nexport const Format = {\n phone: formatPhoneNumber,\n removeHyphen,\n commaize: formatCommaizeNumber,\n padTime,\n};\n\n/**\n * 숫자를 전화번호 형식으로 변환합니다.\n * @example Format.phone('01012345678') // '010-1234-5678'\n */\nfunction formatPhoneNumber(phoneNumber: string) {\n return phoneNumber\n .replace(/[^0-9]/g, '')\n .replace(/^(\\d{0,3})(\\d{0,4})(\\d{0,4})$/g, '$1-$2-$3')\n .replace(/(-{1,2})$/g, '');\n}\n\n/**\n * 하이픈을 제거합니다.\n * @example Format.removeHyphen('01012345678') // '01012345678'\n */\nfunction removeHyphen(value: string) {\n return value.replaceAll('-', '');\n}\n\n/**\n * 숫자를 콤마로 구분합니다.\n * https://www.slash.page/ko/libraries/common/utils/src/Numbers_commaizeNumber.i18n\n *\n * @example\n * Format.commaize('123456') // '123,456'\n * Format.commaize(123456) // '123,456'\n */\nfunction formatCommaizeNumber(value: Value) {\n const numStr = String(value);\n const decimalPointIndex = numStr.indexOf('.');\n const commaizeRegExp = /(\\d)(?=(\\d\\d\\d)+(?!\\d))/g;\n\n return decimalPointIndex > -1\n ? numStr.slice(0, decimalPointIndex).replace(commaizeRegExp, '$1,') +\n numStr.slice(decimalPointIndex)\n : numStr.replace(commaizeRegExp, '$1,');\n}\n\n/**\n * 숫자를 2자리 수 형태로 변환합니다.\n * @example Format.padTime(9) // '09'\n */\nfunction padTime(value: Value) {\n return String(value).padStart(2, '0');\n}\n","export type Mode = 'H' | 'C' | 'W';\nexport type Wind = 1 | 2 | 3;\nexport type AirLevel = 1 | 2 | 3 | 4 | 5;\nexport type UserLevel = '1' | '2' | '3' | '4';\nexport type Language = 'en' | 'ko';\n\nfunction formatModeName(mode: Mode, customMapping: Record<string, string> = {}): string {\n const defaultModeMapping: Record<Mode, string> = {\n H: '난방',\n C: '냉방',\n W: '송풍',\n };\n\n const combinedMapping = { ...defaultModeMapping, ...customMapping };\n\n if (!(mode in combinedMapping)) {\n throw new Error(`지원하지 않는 모드입니다. mode: ${mode}`);\n }\n\n return combinedMapping[mode];\n}\n\nfunction formatModeColor(mode: Mode, customMapping: Record<string, string> = {}) {\n const defaultColorMapping: Record<Mode, string> = {\n H: '#e77676',\n C: '#9fc6ff',\n W: '#a8e379',\n };\n\n const combinedMapping = { ...defaultColorMapping, ...customMapping };\n\n if (!(mode in combinedMapping)) {\n throw new Error(`지원하지 않는 모드입니다. mode: ${mode}`);\n }\n\n return combinedMapping[mode];\n}\n\nfunction formatWind(wind: Wind, customMapping: Record<string, string> = {}) {\n const defaultWindMapping: Record<Wind, string> = {\n 1: '미풍',\n 2: '약풍',\n 3: '강풍',\n };\n\n const combinedMapping = { ...defaultWindMapping, ...customMapping };\n\n if (!(wind in combinedMapping)) {\n throw new Error(`지원하지 않는 풍량입니다. wind: ${wind}`);\n }\n\n return combinedMapping[wind];\n}\n\nfunction formatAirLevelName(level: AirLevel) {\n const airLevelMapping: Record<AirLevel, string> = {\n 1: '매우 나쁨',\n 2: '나쁨',\n 3: '보통',\n 4: '좋음',\n 5: '매우 좋음',\n };\n\n if (!(level in airLevelMapping)) {\n throw new Error(`지원하지 않는 레벨입니다. level: ${level}`);\n }\n\n return airLevelMapping[level];\n}\n\nfunction formatAirLevelColor(level: AirLevel) {\n const colorMapping: Record<AirLevel, string> = {\n 1: '#ff5d47',\n 2: '#ff961c',\n 3: '#ffca42',\n 4: '#63ff60',\n 5: '#49ffe9',\n };\n\n if (!(level in colorMapping)) {\n throw new Error(`지원하지 않는 레벨입니다. level: ${level}`);\n }\n\n return colorMapping[level];\n}\n\nconst formatUserLevel = ({ level, language = 'ko' }: { level: UserLevel; language?: Language }) => {\n const userLevelMapping: Record<Language, Record<UserLevel, string>> = {\n en: {\n '1': 'MASTER',\n '2': 'MASTER KID',\n '3': 'SENIOR',\n '4': 'JUNIOR',\n },\n ko: {\n '1': '마스터',\n '2': '마스터키즈',\n '3': '시니어',\n '4': '주니어',\n },\n };\n\n if (!(language in userLevelMapping)) {\n throw new Error(`지원하지 않는 언어입니다. language: ${language}`);\n }\n\n if (!(level in userLevelMapping[language])) {\n throw new Error(`지원하지 않는 레벨입니다. level: ${level}`);\n }\n\n return userLevelMapping[language][level];\n};\n\nexport const DomainFormat = {\n modeName: formatModeName,\n modeColor: formatModeColor,\n wind: formatWind,\n airLevelName: formatAirLevelName,\n airLevelColor: formatAirLevelColor,\n userLevel: formatUserLevel,\n};\n","import { type Ref, useCallback } from 'react';\n// Reference: https://github.com/facebook/react/issues/13029#issuecomment-497641073\nexport const useCombinedRefs = <T>(...refs: Array<Ref<T>>): Ref<T> =>\n useCallback(\n (element: T) =>\n refs.forEach((ref) => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n return ref(element);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (ref as any).current = element;\n }),\n [refs]\n );\n","import * as React from 'react';\n\nimport usePreservedCallback from './usePreservedCallback';\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop() {}\nexport type UseControllableStateParams<T> = {\n prop?: T | undefined;\n defaultProp?: T | undefined;\n onChange?: (state: T) => void;\n};\ntype SetStateFn<T> = (prevState?: T) => T;\n/**\n * @description\n * Radix UI's useControllableState\n */\nexport const useControllableState = <T>({\n prop,\n defaultProp,\n onChange = noop,\n}: UseControllableStateParams<T>) => {\n const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({\n defaultProp,\n onChange,\n });\n const isControlled = prop !== undefined;\n const value = isControlled ? prop : uncontrolledProp;\n const handleChange = usePreservedCallback(onChange);\n const setValue: React.Dispatch<React.SetStateAction<T | undefined>> = React.useCallback(\n (nextValue) => {\n if (isControlled) {\n const setter = nextValue as SetStateFn<T>;\n const value = typeof nextValue === 'function' ? setter(prop) : nextValue;\n if (value !== prop) handleChange(value as T);\n } else {\n setUncontrolledProp(nextValue);\n }\n },\n [isControlled, prop, setUncontrolledProp, handleChange]\n );\n return [value, setValue] as const;\n};\nconst useUncontrolledState = <T>({\n defaultProp,\n onChange = noop,\n}: Omit<UseControllableStateParams<T>, 'prop'>) => {\n const uncontrolledState = React.useState<T | undefined>(defaultProp);\n const [value] = uncontrolledState;\n const prevValueRef = React.useRef(value);\n const handleChange = usePreservedCallback(onChange);\n React.useEffect(() => {\n if (prevValueRef.current !== value) {\n handleChange(value as T);\n prevValueRef.current = value;\n }\n }, [value, prevValueRef, handleChange]);\n return uncontrolledState;\n};\nexport default useControllableState;\n","import { useEffect, useMemo, useRef } from 'react';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst usePreservedCallback = <T extends (...args: any[]) => any>(callback: T): T => {\n const callbackRef = useRef(callback);\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n return useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n};\nexport default usePreservedCallback;\n"],"mappings":"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","names":["import_react","import_jsx_runtime","createContextRaw","useContextRaw","import_jsx_runtime","import_react","import_jsx_runtime","Flex","import_styled_components","josa","import_react","import_styled_components","import_jsx_runtime","Spacing","import_react","import_jsx_runtime","SafeAreaTop","SafeAreaBottom","queryString","import_react","React","import_react","value"]}
package/dist/index.mjs CHANGED
@@ -4,6 +4,13 @@ import {
4
4
  import {
5
5
  queryString
6
6
  } from "./chunk-Z7YV6A56.mjs";
7
+ import {
8
+ useCombinedRefs
9
+ } from "./chunk-D2YRH4XY.mjs";
10
+ import {
11
+ useControllableState
12
+ } from "./chunk-HOC4D4DT.mjs";
13
+ import "./chunk-QGQNMD22.mjs";
7
14
  import {
8
15
  composeEventHandlers
9
16
  } from "./chunk-QD5QDTUG.mjs";
@@ -71,6 +78,8 @@ export {
71
78
  josa,
72
79
  multiLineEllipsis,
73
80
  queryString,
81
+ useCombinedRefs,
82
+ useControllableState,
74
83
  useSafeArea
75
84
  };
76
85
  //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/useCombinedRefs.ts
21
+ var useCombinedRefs_exports = {};
22
+ __export(useCombinedRefs_exports, {
23
+ useCombinedRefs: () => useCombinedRefs
24
+ });
25
+ module.exports = __toCommonJS(useCombinedRefs_exports);
26
+ var import_react = require("react");
27
+ var useCombinedRefs = (...refs) => (0, import_react.useCallback)(
28
+ (element) => refs.forEach((ref) => {
29
+ if (!ref) {
30
+ return;
31
+ }
32
+ if (typeof ref === "function") {
33
+ return ref(element);
34
+ }
35
+ ref.current = element;
36
+ }),
37
+ [refs]
38
+ );
39
+ // Annotate the CommonJS export names for ESM import in node:
40
+ 0 && (module.exports = {
41
+ useCombinedRefs
42
+ });
43
+ //# sourceMappingURL=useCombinedRefs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useCombinedRefs.ts"],"sourcesContent":["import { type Ref, useCallback } from 'react';\n// Reference: https://github.com/facebook/react/issues/13029#issuecomment-497641073\nexport const useCombinedRefs = <T>(...refs: Array<Ref<T>>): Ref<T> =>\n useCallback(\n (element: T) =>\n refs.forEach((ref) => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n return ref(element);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (ref as any).current = element;\n }),\n [refs]\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAsC;AAE/B,IAAM,kBAAkB,IAAO,aACpC;AAAA,EACE,CAAC,YACC,KAAK,QAAQ,CAAC,QAAQ;AACpB,QAAI,CAAC,KAAK;AACR;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,YAAY;AAC7B,aAAO,IAAI,OAAO;AAAA,IACpB;AAEA,IAAC,IAAY,UAAU;AAAA,EACzB,CAAC;AAAA,EACH,CAAC,IAAI;AACP;","names":[]}
@@ -0,0 +1,7 @@
1
+ import {
2
+ useCombinedRefs
3
+ } from "./chunk-D2YRH4XY.mjs";
4
+ export {
5
+ useCombinedRefs
6
+ };
7
+ //# sourceMappingURL=useCombinedRefs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/useControllableState.ts
31
+ var useControllableState_exports = {};
32
+ __export(useControllableState_exports, {
33
+ default: () => useControllableState_default,
34
+ useControllableState: () => useControllableState
35
+ });
36
+ module.exports = __toCommonJS(useControllableState_exports);
37
+ var React = __toESM(require("react"));
38
+
39
+ // src/usePreservedCallback.ts
40
+ var import_react = require("react");
41
+ var usePreservedCallback = (callback) => {
42
+ const callbackRef = (0, import_react.useRef)(callback);
43
+ (0, import_react.useEffect)(() => {
44
+ callbackRef.current = callback;
45
+ }, [callback]);
46
+ return (0, import_react.useMemo)(() => (...args) => callbackRef.current?.(...args), []);
47
+ };
48
+ var usePreservedCallback_default = usePreservedCallback;
49
+
50
+ // src/useControllableState.ts
51
+ function noop() {
52
+ }
53
+ var useControllableState = ({
54
+ prop,
55
+ defaultProp,
56
+ onChange = noop
57
+ }) => {
58
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({
59
+ defaultProp,
60
+ onChange
61
+ });
62
+ const isControlled = prop !== void 0;
63
+ const value = isControlled ? prop : uncontrolledProp;
64
+ const handleChange = usePreservedCallback_default(onChange);
65
+ const setValue = React.useCallback(
66
+ (nextValue) => {
67
+ if (isControlled) {
68
+ const setter = nextValue;
69
+ const value2 = typeof nextValue === "function" ? setter(prop) : nextValue;
70
+ if (value2 !== prop) handleChange(value2);
71
+ } else {
72
+ setUncontrolledProp(nextValue);
73
+ }
74
+ },
75
+ [isControlled, prop, setUncontrolledProp, handleChange]
76
+ );
77
+ return [value, setValue];
78
+ };
79
+ var useUncontrolledState = ({
80
+ defaultProp,
81
+ onChange = noop
82
+ }) => {
83
+ const uncontrolledState = React.useState(defaultProp);
84
+ const [value] = uncontrolledState;
85
+ const prevValueRef = React.useRef(value);
86
+ const handleChange = usePreservedCallback_default(onChange);
87
+ React.useEffect(() => {
88
+ if (prevValueRef.current !== value) {
89
+ handleChange(value);
90
+ prevValueRef.current = value;
91
+ }
92
+ }, [value, prevValueRef, handleChange]);
93
+ return uncontrolledState;
94
+ };
95
+ var useControllableState_default = useControllableState;
96
+ // Annotate the CommonJS export names for ESM import in node:
97
+ 0 && (module.exports = {
98
+ useControllableState
99
+ });
100
+ //# sourceMappingURL=useControllableState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useControllableState.ts","../src/usePreservedCallback.ts"],"sourcesContent":["import * as React from 'react';\n\nimport usePreservedCallback from './usePreservedCallback';\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop() {}\nexport type UseControllableStateParams<T> = {\n prop?: T | undefined;\n defaultProp?: T | undefined;\n onChange?: (state: T) => void;\n};\ntype SetStateFn<T> = (prevState?: T) => T;\n/**\n * @description\n * Radix UI's useControllableState\n */\nexport const useControllableState = <T>({\n prop,\n defaultProp,\n onChange = noop,\n}: UseControllableStateParams<T>) => {\n const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({\n defaultProp,\n onChange,\n });\n const isControlled = prop !== undefined;\n const value = isControlled ? prop : uncontrolledProp;\n const handleChange = usePreservedCallback(onChange);\n const setValue: React.Dispatch<React.SetStateAction<T | undefined>> = React.useCallback(\n (nextValue) => {\n if (isControlled) {\n const setter = nextValue as SetStateFn<T>;\n const value = typeof nextValue === 'function' ? setter(prop) : nextValue;\n if (value !== prop) handleChange(value as T);\n } else {\n setUncontrolledProp(nextValue);\n }\n },\n [isControlled, prop, setUncontrolledProp, handleChange]\n );\n return [value, setValue] as const;\n};\nconst useUncontrolledState = <T>({\n defaultProp,\n onChange = noop,\n}: Omit<UseControllableStateParams<T>, 'prop'>) => {\n const uncontrolledState = React.useState<T | undefined>(defaultProp);\n const [value] = uncontrolledState;\n const prevValueRef = React.useRef(value);\n const handleChange = usePreservedCallback(onChange);\n React.useEffect(() => {\n if (prevValueRef.current !== value) {\n handleChange(value as T);\n prevValueRef.current = value;\n }\n }, [value, prevValueRef, handleChange]);\n return uncontrolledState;\n};\nexport default useControllableState;\n","import { useEffect, useMemo, useRef } from 'react';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst usePreservedCallback = <T extends (...args: any[]) => any>(callback: T): T => {\n const callbackRef = useRef(callback);\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n return useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n};\nexport default usePreservedCallback;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAAuB;;;ACAvB,mBAA2C;AAE3C,IAAM,uBAAuB,CAAoC,aAAmB;AAClF,QAAM,kBAAc,qBAAO,QAAQ;AACnC,8BAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AACb,aAAO,sBAAQ,MAAO,IAAI,SAAS,YAAY,UAAU,GAAG,IAAI,GAAS,CAAC,CAAC;AAC7E;AACA,IAAO,+BAAQ;;;ADLf,SAAS,OAAO;AAAC;AAWV,IAAM,uBAAuB,CAAI;AAAA,EACtC;AAAA,EACA;AAAA,EACA,WAAW;AACb,MAAqC;AACnC,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,qBAAqB;AAAA,IACnE;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,eAAe,SAAS;AAC9B,QAAM,QAAQ,eAAe,OAAO;AACpC,QAAM,eAAe,6BAAqB,QAAQ;AAClD,QAAM,WAAsE;AAAA,IAC1E,CAAC,cAAc;AACb,UAAI,cAAc;AAChB,cAAM,SAAS;AACf,cAAMA,SAAQ,OAAO,cAAc,aAAa,OAAO,IAAI,IAAI;AAC/D,YAAIA,WAAU,KAAM,cAAaA,MAAU;AAAA,MAC7C,OAAO;AACL,4BAAoB,SAAS;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,CAAC,cAAc,MAAM,qBAAqB,YAAY;AAAA,EACxD;AACA,SAAO,CAAC,OAAO,QAAQ;AACzB;AACA,IAAM,uBAAuB,CAAI;AAAA,EAC/B;AAAA,EACA,WAAW;AACb,MAAmD;AACjD,QAAM,oBAA0B,eAAwB,WAAW;AACnE,QAAM,CAAC,KAAK,IAAI;AAChB,QAAM,eAAqB,aAAO,KAAK;AACvC,QAAM,eAAe,6BAAqB,QAAQ;AAClD,EAAM,gBAAU,MAAM;AACpB,QAAI,aAAa,YAAY,OAAO;AAClC,mBAAa,KAAU;AACvB,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,OAAO,cAAc,YAAY,CAAC;AACtC,SAAO;AACT;AACA,IAAO,+BAAQ;","names":["value"]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ useControllableState,
3
+ useControllableState_default
4
+ } from "./chunk-HOC4D4DT.mjs";
5
+ import "./chunk-QGQNMD22.mjs";
6
+ export {
7
+ useControllableState_default as default,
8
+ useControllableState
9
+ };
10
+ //# sourceMappingURL=useControllableState.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/usePreservedCallback.ts
21
+ var usePreservedCallback_exports = {};
22
+ __export(usePreservedCallback_exports, {
23
+ default: () => usePreservedCallback_default
24
+ });
25
+ module.exports = __toCommonJS(usePreservedCallback_exports);
26
+ var import_react = require("react");
27
+ var usePreservedCallback = (callback) => {
28
+ const callbackRef = (0, import_react.useRef)(callback);
29
+ (0, import_react.useEffect)(() => {
30
+ callbackRef.current = callback;
31
+ }, [callback]);
32
+ return (0, import_react.useMemo)(() => (...args) => callbackRef.current?.(...args), []);
33
+ };
34
+ var usePreservedCallback_default = usePreservedCallback;
35
+ //# sourceMappingURL=usePreservedCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usePreservedCallback.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst usePreservedCallback = <T extends (...args: any[]) => any>(callback: T): T => {\n const callbackRef = useRef(callback);\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n return useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);\n};\nexport default usePreservedCallback;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2C;AAE3C,IAAM,uBAAuB,CAAoC,aAAmB;AAClF,QAAM,kBAAc,qBAAO,QAAQ;AACnC,8BAAU,MAAM;AACd,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,QAAQ,CAAC;AACb,aAAO,sBAAQ,MAAO,IAAI,SAAS,YAAY,UAAU,GAAG,IAAI,GAAS,CAAC,CAAC;AAC7E;AACA,IAAO,+BAAQ;","names":[]}
@@ -0,0 +1,7 @@
1
+ import {
2
+ usePreservedCallback_default
3
+ } from "./chunk-QGQNMD22.mjs";
4
+ export {
5
+ usePreservedCallback_default as default
6
+ };
7
+ //# sourceMappingURL=usePreservedCallback.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basiln/utils",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",