@eeennsu/native 0.2.0 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../src/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,KAAK,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;AAkCjD;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAuClC,CAAC"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../src/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,KAAK,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;AAmDjD;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAyClC,CAAC"}
package/dist/button.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Pressable, Text as RNText } from "react-native-css/components";
3
3
  import { cn } from "./cn.js";
4
- import { Icon } from "./icon.js";
4
+ import { Glyph } from "./icon.js";
5
5
  /**
6
6
  * 웹은 배경과 글자색을 버튼 하나에 얹지만 RN 은 View → Text 로 색이 상속되지 않는다.
7
7
  * 그래서 variant 를 표면(컨테이너)과 전경(라벨 Text) 둘로 쪼갠다. 클래스 이름 자체는
@@ -13,6 +13,11 @@ const surfaces = {
13
13
  ghost: "hover:bg-surface-hover",
14
14
  danger: "bg-danger hover:bg-danger-hover",
15
15
  };
16
+ /**
17
+ * 누르는 동안의 표시(N-17). react-native-css 가 Pressable 의 누름 상태로 푼다.
18
+ * 색이 아니라 투명도라 소비자가 `bg-*` 로 배경을 바꿔도 따라간다(웹과 같은 클래스, AC-25).
19
+ */
20
+ const pressed = "active:opacity-80";
16
21
  const foregrounds = {
17
22
  primary: "text-fg-on-brand",
18
23
  secondary: "text-fg",
@@ -25,6 +30,16 @@ const boxes = {
25
30
  md: "px-4 py-2 rounded-md gap-2",
26
31
  lg: "px-6 py-3 rounded-lg gap-2",
27
32
  };
33
+ /**
34
+ * 누름 영역을 48dp 로 채운다(N-17). 높이 30 · 42 · 54 는 Input 과 맞춘 값이라(plan D-6) 세로는
35
+ * 모양을 두고 hitSlop 으로만 넓힌다. 가로는 짧은 라벨("예")에서 모자라므로 최소 폭 48(`min-w-12`)을 둔다.
36
+ * 세로로 쌓을 때 hitSlop 끼리 겹치지 않으려면 sm 은 18, md 는 6 이상 띄운다(알려진 동작 18).
37
+ */
38
+ const hitSlops = {
39
+ sm: { top: 9, bottom: 9 },
40
+ md: { top: 3, bottom: 3 },
41
+ lg: undefined,
42
+ };
28
43
  const labels = {
29
44
  sm: "text-sm",
30
45
  md: "text-md",
@@ -43,8 +58,8 @@ const labels = {
43
58
  export const Button = ({ label, variant = "primary", size = "md", icon, loading = false, disabled = false, onPress, className, ref, }) => {
44
59
  const inactive = disabled || loading;
45
60
  const foreground = foregrounds[variant];
46
- return (_jsxs(Pressable, { ref: ref, accessibilityRole: "button", accessibilityLabel: label, accessibilityState: { disabled: inactive }, disabled: inactive,
61
+ return (_jsxs(Pressable, { ref: ref, accessibilityRole: "button", accessibilityLabel: label, accessibilityState: { disabled: inactive }, disabled: inactive, hitSlop: hitSlops[size],
47
62
  // 계약은 `() => void` 다. 그대로 넘기면 누름 이벤트 객체가 새어 나간다.
48
- onPress: onPress && (() => onPress()), className: cn("flex-row items-center justify-center border border-transparent", surfaces[variant], boxes[size], inactive && "opacity-50", className), children: [loading ? (_jsx(Icon, { name: "loader", size: size, className: foreground })) : icon ? (_jsx(Icon, { name: icon, size: size, className: foreground })) : null, _jsx(RNText, { className: cn(foreground, labels[size]), children: label })] }));
63
+ onPress: onPress && (() => onPress()), className: cn("flex-row items-center justify-center border border-transparent min-w-12", surfaces[variant], pressed, boxes[size], inactive && "opacity-50", className), children: [loading ? (_jsx(Glyph, { name: "loader", size: size, className: foreground })) : icon ? (_jsx(Glyph, { name: icon, size: size, className: foreground })) : null, _jsx(RNText, { className: cn(foreground, labels[size]), children: label })] }));
49
64
  };
50
65
  //# sourceMappingURL=button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","sourceRoot":"","sources":["../src/button.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;;GAIG;AACH,MAAM,QAAQ,GAA4B;IACxC,OAAO,EAAE,+BAA+B;IACxC,SAAS,EAAE,yCAAyC;IACpD,KAAK,EAAE,wBAAwB;IAC/B,MAAM,EAAE,iCAAiC;CAC1C,CAAC;AAEF,MAAM,WAAW,GAA4B;IAC3C,OAAO,EAAE,kBAAkB;IAC3B,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,mBAAmB;CAC5B,CAAC;AAEF,4EAA4E;AAC5E,MAAM,KAAK,GAAgC;IACzC,EAAE,EAAE,4BAA4B;IAChC,EAAE,EAAE,4BAA4B;IAChC,EAAE,EAAE,4BAA4B;CACjC,CAAC;AAEF,MAAM,MAAM,GAAgC;IAC1C,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;CACd,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,MAAM,GAAoB,CAAC,EACtC,KAAK,EACL,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,IAAI,EACJ,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,OAAO,EACP,SAAS,EACT,GAAG,GACJ,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,QAAQ,IAAI,OAAO,CAAC;IACrC,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAExC,OAAO,CACL,MAAC,SAAS,IACR,GAAG,EAAE,GAAqC,EAC1C,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,KAAK,EACzB,kBAAkB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAC1C,QAAQ,EAAE,QAAQ;QAClB,iDAAiD;QACjD,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,EACrC,SAAS,EAAE,EAAE,CACX,gEAAgE,EAChE,QAAQ,CAAC,OAAO,CAAC,EACjB,KAAK,CAAC,IAAI,CAAC,EACX,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,aAEA,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,IAAI,IAAC,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,GAAI,CAC1D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACT,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,GAAI,CACxD,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,MAAM,IAAC,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,YAAG,KAAK,GAAU,IACvD,CACb,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../src/button.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAIlC;;;;GAIG;AACH,MAAM,QAAQ,GAA4B;IACxC,OAAO,EAAE,+BAA+B;IACxC,SAAS,EAAE,yCAAyC;IACpD,KAAK,EAAE,wBAAwB;IAC/B,MAAM,EAAE,iCAAiC;CAC1C,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,GAAG,mBAAmB,CAAC;AAEpC,MAAM,WAAW,GAA4B;IAC3C,OAAO,EAAE,kBAAkB;IAC3B,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,mBAAmB;CAC5B,CAAC;AAEF,4EAA4E;AAC5E,MAAM,KAAK,GAAgC;IACzC,EAAE,EAAE,4BAA4B;IAChC,EAAE,EAAE,4BAA4B;IAChC,EAAE,EAAE,4BAA4B;CACjC,CAAC;AAEF;;;;GAIG;AACH,MAAM,QAAQ,GAA4C;IACxD,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IACzB,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IACzB,EAAE,EAAE,SAAS;CACd,CAAC;AAEF,MAAM,MAAM,GAAgC;IAC1C,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;CACd,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,MAAM,GAAoB,CAAC,EACtC,KAAK,EACL,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,IAAI,EACJ,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,OAAO,EACP,SAAS,EACT,GAAG,GACJ,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,QAAQ,IAAI,OAAO,CAAC;IACrC,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAExC,OAAO,CACL,MAAC,SAAS,IACR,GAAG,EAAE,GAAqC,EAC1C,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,KAAK,EACzB,kBAAkB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAC1C,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC;QACvB,iDAAiD;QACjD,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,EACrC,SAAS,EAAE,EAAE,CACX,yEAAyE,EACzE,QAAQ,CAAC,OAAO,CAAC,EACjB,OAAO,EACP,KAAK,CAAC,IAAI,CAAC,EACX,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,aAEA,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,GAAI,CAC3D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACT,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,GAAI,CACzD,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,MAAM,IAAC,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,YAAG,KAAK,GAAU,IACvD,CACb,CAAC;AACJ,CAAC,CAAC"}
package/dist/chip.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { Contracts } from "@eeennsu/tokens";
2
+ import type { FC } from "react";
3
+ type ChipProps = Contracts<"native">["Chip"];
4
+ /**
5
+ * 고르는 칩(N-17). 웹 Chip 과 같은 클래스이고(AC-25), Button 처럼 표면(Pressable)과
6
+ * 전경(라벨 Text)으로 쪼갠다(N-12). 고른 상태는 `accessibilityState.selected` 로 알린다.
7
+ * 라벨은 글자 크기 설정을 끝까지 따른다 — 칩 묶음은 줄을 바꿔 늘어난 글자를 받는다(WCAG 1.4.4, Button 과 같다).
8
+ */
9
+ export declare const Chip: FC<ChipProps>;
10
+ export {};
11
+ //# sourceMappingURL=chip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chip.d.ts","sourceRoot":"","sources":["../src/chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,KAAK,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAS7C;;;;GAIG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAuB9B,CAAC"}
package/dist/chip.js ADDED
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Pressable, Text as RNText } from "react-native-css/components";
3
+ import { cn } from "./cn.js";
4
+ /**
5
+ * 칩 높이는 38(py-2 + text-sm 20 + 테두리 2)이다. 세로 hitSlop 5 를 더해 누름 영역 48 을 채우고,
6
+ * 가로는 최소 폭 48(`min-w-12`)을 둔다. 칩 줄 사이를 gap-3(12) 이상 띄우면 누름 영역이 서로
7
+ * 겹치지 않는다(구현 노트 N-17, 알려진 동작 18).
8
+ */
9
+ const hitSlop = { top: 5, bottom: 5 };
10
+ /**
11
+ * 고르는 칩(N-17). 웹 Chip 과 같은 클래스이고(AC-25), Button 처럼 표면(Pressable)과
12
+ * 전경(라벨 Text)으로 쪼갠다(N-12). 고른 상태는 `accessibilityState.selected` 로 알린다.
13
+ * 라벨은 글자 크기 설정을 끝까지 따른다 — 칩 묶음은 줄을 바꿔 늘어난 글자를 받는다(WCAG 1.4.4, Button 과 같다).
14
+ */
15
+ export const Chip = ({ label, selected = false, disabled = false, onPress, className, ref }) => (_jsx(Pressable, { ref: ref, accessibilityRole: "button", accessibilityLabel: label, accessibilityState: { selected, disabled }, disabled: disabled, hitSlop: hitSlop,
16
+ // 계약은 `() => void` 다. 누름 이벤트 객체를 넘기지 않는다.
17
+ onPress: onPress && (() => onPress()), className: cn("flex-row items-center justify-center border px-4 py-2 rounded-full min-w-12", selected ? "border-brand bg-brand hover:bg-brand-hover" : "border-border bg-surface hover:bg-surface-hover",
18
+ // 누르는 동안은 색이 아니라 투명도다 — 소비자가 배경을 바꿔도 따라간다(Button 과 같다)
19
+ "active:opacity-80", disabled && "opacity-50", className), children: _jsx(RNText, { className: cn("text-sm", selected ? "text-fg-on-brand" : "text-fg"), children: label }) }));
20
+ //# sourceMappingURL=chip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chip.js","sourceRoot":"","sources":["../src/chip.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAI7B;;;;GAIG;AACH,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAC7G,KAAC,SAAS,IACR,GAAG,EAAE,GAAmC,EACxC,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,KAAK,EACzB,kBAAkB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAC1C,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO;IAChB,0CAA0C;IAC1C,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,EACrC,SAAS,EAAE,EAAE,CACX,6EAA6E,EAC7E,QAAQ,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,iDAAiD;IAC3G,uDAAuD;IACvD,mBAAmB,EACnB,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,YAED,KAAC,MAAM,IAAC,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,YACxE,KAAK,GACC,GACC,CACb,CAAC"}
package/dist/icon.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { type ControlSize, type IconName } from "@eeennsu/tokens";
2
- import { type LucideIcon } from "lucide-react-native";
1
+ import { type Contracts, type ControlSize, type IconName } from "@eeennsu/tokens";
2
+ import type { LucideIcon } from "lucide-react-native";
3
+ import type { FC } from "react";
3
4
  /**
4
- * `IconName` → lucide 컴포넌트. 웹(`@eeennsu/web`)의 맵과 같은 24개이며
5
+ * `IconName` → lucide 컴포넌트. 웹(`@eeennsu/web`)의 맵과 같은 28개이며
5
6
  * `Record<IconName, LucideIcon>` 이라 tokens 목록에 이름을 추가하고 한쪽 맵을
6
7
  * 빠뜨리면 컴파일 에러가 난다(plan D-8).
7
8
  *
@@ -9,19 +10,28 @@ import { type LucideIcon } from "lucide-react-native";
9
10
  * major 에서 사라질 수 있다(plan v2 F-6).
10
11
  */
11
12
  declare const icons: Record<IconName, LucideIcon>;
12
- type IconProps = {
13
+ type GlyphProps = {
13
14
  name: IconName;
14
15
  size?: ControlSize;
15
16
  className?: string;
16
17
  };
17
18
  /**
18
- * DS 내부 전용이다 — 공개 컴포넌트가 아니고 `Contracts` 에도 없다.
19
+ * 컴포넌트 안에 붙는 아이콘(Button 의 `icon` · `loading`). 색은 호출부가 전경 클래스로 준다.
19
20
  * 크기는 클래스가 아니라 lucide `size` prop(JS 숫자)으로 준다 — 20px 는 spacing 열거
20
21
  * 밖이라 `size-5` 클래스가 생성되지 않기 때문이다(plan v2 F-8).
21
22
  *
22
- * 웹 Icon 의 `spin` 은 없다 — RN 에서 `animate-spin` 은 Reanimated 경로가 필요하고
23
+ * 웹의 `spin` 은 없다 — RN 에서 `animate-spin` 은 Reanimated 경로가 필요하고
23
24
  * v1 범위 밖이다. Button 의 `loading` 은 회전 없이 아이콘만 바꾼다(알려진 동작 참조).
24
25
  */
25
- export declare function Icon({ name, size, className }: IconProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
26
+ export declare function Glyph({ name, size, className }: GlyphProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
27
+ /**
28
+ * 단독 아이콘(구현 노트 N-17). RN 에는 글자색 상속이 없어 색을 `tone` 으로 아이콘 자신이 갖는다 —
29
+ * 웹도 같은 방식이라 같은 className 이 같은 결과를 낸다(AC-25).
30
+ * `label` 이 있으면 이름을 가진 그림(`image`)이고, 없거나 빈 문자열이면 꾸밈이라 보조 기술에서 숨긴다.
31
+ *
32
+ * 배치 · 변형 · 투명도 클래스는 루트 View(Frame)에 한 번 붙는다. 그림 크기는 `size` prop 이 정한다 —
33
+ * className 의 `size-*` 는 View 칸만 바꾼다(알려진 동작 20).
34
+ */
35
+ export declare const Icon: FC<Contracts<"native">["Icon"]>;
26
36
  export { icons };
27
37
  //# sourceMappingURL=icon.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../src/icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAeL,KAAK,UAAU,EAWhB,MAAM,qBAAqB,CAAC;AAG7B;;;;;;;GAOG;AACH,QAAA,MAAM,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAyBvC,CAAC;AAYF,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,SAAS,0FAG/D;AAED,OAAO,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../src/icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAa,MAAM,iBAAiB,CAAC;AA+BxG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC;;;;;;;GAOG;AACH,QAAA,MAAM,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CA6BvC,CAAC;AAaF,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,EAAE,IAAI,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,UAAU,0FAEjE;AAsDD;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAgBhD,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,CAAC"}
package/dist/icon.js CHANGED
@@ -1,8 +1,40 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import { component } from "@eeennsu/tokens";
2
- import { ArrowLeft, ArrowRight, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, CircleAlert, ExternalLink, Eye, EyeOff, Info, Loader, Lock, Mail, Menu, Minus, Pencil, Plus, Search, Settings, Trash, User, X, } from "lucide-react-native";
3
+ // 아이콘마다 파일 경로로 import 한다. Metro 는 tree shaking 을 하지 않아 목록 파일("lucide-react-native")에서
4
+ // import 하면 아이콘 3,600여 개가 모두 번들에 들어간다(약 1.7MB, 구현 노트 F-22).
5
+ import ArrowLeft from "lucide-react-native/icons/arrow-left";
6
+ import ArrowRight from "lucide-react-native/icons/arrow-right";
7
+ import Calendar from "lucide-react-native/icons/calendar";
8
+ import ChartPie from "lucide-react-native/icons/chart-pie";
9
+ import Check from "lucide-react-native/icons/check";
10
+ import ChevronDown from "lucide-react-native/icons/chevron-down";
11
+ import ChevronLeft from "lucide-react-native/icons/chevron-left";
12
+ import ChevronRight from "lucide-react-native/icons/chevron-right";
13
+ import ChevronUp from "lucide-react-native/icons/chevron-up";
14
+ import CircleAlert from "lucide-react-native/icons/circle-alert";
15
+ import ExternalLink from "lucide-react-native/icons/external-link";
16
+ import Eye from "lucide-react-native/icons/eye";
17
+ import EyeOff from "lucide-react-native/icons/eye-off";
18
+ import House from "lucide-react-native/icons/house";
19
+ import Info from "lucide-react-native/icons/info";
20
+ import List from "lucide-react-native/icons/list";
21
+ import Loader from "lucide-react-native/icons/loader";
22
+ import Lock from "lucide-react-native/icons/lock";
23
+ import Mail from "lucide-react-native/icons/mail";
24
+ import Menu from "lucide-react-native/icons/menu";
25
+ import Minus from "lucide-react-native/icons/minus";
26
+ import Pencil from "lucide-react-native/icons/pencil";
27
+ import Plus from "lucide-react-native/icons/plus";
28
+ import Search from "lucide-react-native/icons/search";
29
+ import Settings from "lucide-react-native/icons/settings";
30
+ import Trash from "lucide-react-native/icons/trash";
31
+ import User from "lucide-react-native/icons/user";
32
+ import X from "lucide-react-native/icons/x";
33
+ import { View } from "react-native";
34
+ import { cn } from "./cn.js";
3
35
  import { useCssElement } from "react-native-css";
4
36
  /**
5
- * `IconName` → lucide 컴포넌트. 웹(`@eeennsu/web`)의 맵과 같은 24개이며
37
+ * `IconName` → lucide 컴포넌트. 웹(`@eeennsu/web`)의 맵과 같은 28개이며
6
38
  * `Record<IconName, LucideIcon>` 이라 tokens 목록에 이름을 추가하고 한쪽 맵을
7
39
  * 빠뜨리면 컴파일 에러가 난다(plan D-8).
8
40
  *
@@ -34,27 +66,70 @@ const icons = {
34
66
  "alert-circle": CircleAlert,
35
67
  loader: Loader,
36
68
  "external-link": ExternalLink,
69
+ home: House,
70
+ list: List,
71
+ "chart-pie": ChartPie,
72
+ calendar: Calendar,
37
73
  };
38
74
  /**
39
75
  * 웹은 아이콘 색을 `currentColor` 로 상속하지만 RN 에는 `currentColor` 가 없다.
40
- * 그래서 `className` 의 색만 뽑아 lucide 의 `color` prop 으로 넘긴다 —
76
+ * 그래서 `className` 의 색만 뽑아 lucide 의 `color` prop 으로 옮긴다 —
41
77
  * 호출부는 `text-fg-on-brand` 처럼 웹과 같은 클래스를 쓴다(§9 S-17, AC-25).
42
- * `target: false` 라 `style` 은 만들지 않는다 — svg 는 style 을 안 받는다.
78
+ * Button 안의 아이콘(`Glyph`)만 이 매핑을 쓴다. 호출부가 색 클래스만 주므로 남는 style 이 없다 —
79
+ * lucide 는 남은 style 을 자식 도형마다 펼치므로 변형 · 투명도가 섞이면 겹쳐 걸린다(공개 Icon 은 Frame).
43
80
  */
44
81
  const mapping = {
45
82
  className: { target: false, nativeStyleMapping: { color: "color" } },
46
83
  };
47
84
  /**
48
- * DS 내부 전용이다 — 공개 컴포넌트가 아니고 `Contracts` 에도 없다.
85
+ * 컴포넌트 안에 붙는 아이콘(Button 의 `icon` · `loading`). 색은 호출부가 전경 클래스로 준다.
49
86
  * 크기는 클래스가 아니라 lucide `size` prop(JS 숫자)으로 준다 — 20px 는 spacing 열거
50
87
  * 밖이라 `size-5` 클래스가 생성되지 않기 때문이다(plan v2 F-8).
51
88
  *
52
- * 웹 Icon 의 `spin` 은 없다 — RN 에서 `animate-spin` 은 Reanimated 경로가 필요하고
89
+ * 웹의 `spin` 은 없다 — RN 에서 `animate-spin` 은 Reanimated 경로가 필요하고
53
90
  * v1 범위 밖이다. Button 의 `loading` 은 회전 없이 아이콘만 바꾼다(알려진 동작 참조).
54
91
  */
55
- export function Icon({ name, size = "md", className }) {
56
- const Glyph = icons[name];
57
- return useCssElement(Glyph, { className, size: component.icon.size[size] }, mapping);
92
+ export function Glyph({ name, size = "md", className }) {
93
+ return useCssElement(icons[name], { className, size: component.icon.size[size] }, mapping);
58
94
  }
95
+ /** `tone` 은 Text 와 같은 fg semantic 색이다(C-8). */
96
+ const tones = {
97
+ default: "text-fg",
98
+ muted: "text-fg-muted",
99
+ danger: "text-fg-danger",
100
+ };
101
+ /**
102
+ * 공개 Icon 의 뼈대. className 이 푼 style(여백 · 배치 · 변형 · 투명도)은 이 View 가 한 번만 받고,
103
+ * lucide 에는 크기와 색만 넘긴다. lucide 는 받은 style 을 svg 와 자식 도형마다 펼치므로, svg 에 직접 주면
104
+ * `rotate-180` 은 react-native-svg 의 transform 해석에서 던지고 `opacity-50` 은 세 번 곱해진다(N-17, DS-001 재검증).
105
+ */
106
+ function Frame({ svg: Svg, size, color, style, accessible, accessibilityRole, accessibilityLabel, accessibilityElementsHidden, importantForAccessibility, }) {
107
+ return (_jsx(View, { style: style, accessible: accessible, accessibilityRole: accessibilityRole, accessibilityLabel: accessibilityLabel, accessibilityElementsHidden: accessibilityElementsHidden, importantForAccessibility: importantForAccessibility, children: _jsx(Svg, { size: size, color: color }) }));
108
+ }
109
+ /** className 을 Frame 의 style 로 풀고, 색만 뽑아 `color` 로 옮긴다. */
110
+ const frameMapping = {
111
+ className: { target: "style", nativeStyleMapping: { color: "color" } },
112
+ };
113
+ /**
114
+ * 단독 아이콘(구현 노트 N-17). RN 에는 글자색 상속이 없어 색을 `tone` 으로 아이콘 자신이 갖는다 —
115
+ * 웹도 같은 방식이라 같은 className 이 같은 결과를 낸다(AC-25).
116
+ * `label` 이 있으면 이름을 가진 그림(`image`)이고, 없거나 빈 문자열이면 꾸밈이라 보조 기술에서 숨긴다.
117
+ *
118
+ * 배치 · 변형 · 투명도 클래스는 루트 View(Frame)에 한 번 붙는다. 그림 크기는 `size` prop 이 정한다 —
119
+ * className 의 `size-*` 는 View 칸만 바꾼다(알려진 동작 20).
120
+ */
121
+ export const Icon = ({ name, size = "md", tone = "default", label, className }) => {
122
+ const named = Boolean(label);
123
+ return useCssElement(Frame, {
124
+ className: cn(tones[tone], className),
125
+ svg: icons[name],
126
+ size: component.icon.size[size],
127
+ accessible: named,
128
+ accessibilityRole: named ? "image" : undefined,
129
+ accessibilityLabel: named ? label : undefined,
130
+ accessibilityElementsHidden: !named,
131
+ importantForAccessibility: named ? "yes" : "no-hide-descendants",
132
+ }, frameMapping);
133
+ };
59
134
  export { icons };
60
135
  //# sourceMappingURL=icon.js.map
package/dist/icon.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"icon.js","sourceRoot":"","sources":["../src/icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmC,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,SAAS,EACT,UAAU,EACV,KAAK,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,GAAG,EACH,MAAM,EACN,IAAI,EACJ,MAAM,EACN,IAAI,EAEJ,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAM,EACN,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,CAAC,GACF,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAA4B,MAAM,kBAAkB,CAAC;AAE3E;;;;;;;GAOG;AACH,MAAM,KAAK,GAAiC;IAC1C,KAAK,EAAE,KAAK;IACZ,CAAC,EAAE,CAAC;IACJ,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,MAAM;IACd,cAAc,EAAE,WAAW;IAC3B,YAAY,EAAE,SAAS;IACvB,cAAc,EAAE,WAAW;IAC3B,eAAe,EAAE,YAAY;IAC7B,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,UAAU;IACzB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,GAAG;IACR,SAAS,EAAE,MAAM;IACjB,IAAI,EAAE,IAAI;IACV,cAAc,EAAE,WAAW;IAC3B,MAAM,EAAE,MAAM;IACd,eAAe,EAAE,YAAY;CAC9B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,OAAO,GAAG;IACd,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;CAC3B,CAAC;AAQ5C;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,SAAS,EAAa;IAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACvF,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"icon.js","sourceRoot":"","sources":["../src/icon.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,12 +2,14 @@ import { Badge } from "./badge.js";
2
2
  import { Box } from "./box.js";
3
3
  import { Button } from "./button.js";
4
4
  import { Card } from "./card.js";
5
+ import { Chip } from "./chip.js";
6
+ import { Icon } from "./icon.js";
5
7
  import { Input } from "./input.js";
6
8
  import { Label } from "./label.js";
7
9
  import { Stack } from "./stack.js";
8
10
  import { Text } from "./text.js";
9
11
  import { Textarea } from "./textarea.js";
10
- export { Badge, Box, Button, Card, Input, Label, Stack, Text, Textarea };
12
+ export { Badge, Box, Button, Card, Chip, Icon, Input, Label, Stack, Text, Textarea };
11
13
  export { cn } from "./cn.js";
12
14
  /**
13
15
  * 계약 맵 테스트(C-17)가 보는 객체. 키 집합이 `nativeComponents` 와 같고
@@ -68,6 +70,22 @@ export declare const components: {
68
70
  size?: import("@eeennsu/tokens").BadgeSize;
69
71
  className?: string;
70
72
  }>;
73
+ Chip: import("react").FC<{
74
+ label: string;
75
+ selected?: boolean;
76
+ disabled?: boolean;
77
+ className?: string;
78
+ ref?: import("react").Ref<import("@eeennsu/tokens").FocusHandle>;
79
+ } & {
80
+ onPress?: () => void;
81
+ }>;
82
+ Icon: import("react").FC<{
83
+ name: import("@eeennsu/tokens").IconName;
84
+ size?: import("@eeennsu/tokens").ControlSize;
85
+ tone?: import("@eeennsu/tokens").Tone;
86
+ label?: string;
87
+ className?: string;
88
+ }>;
71
89
  Text: import("react").FC<{
72
90
  children: string | string[];
73
91
  tone?: import("@eeennsu/tokens").Tone;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACzE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAUtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACrF,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYtB,CAAC"}
package/dist/index.js CHANGED
@@ -2,12 +2,14 @@ import { Badge } from "./badge.js";
2
2
  import { Box } from "./box.js";
3
3
  import { Button } from "./button.js";
4
4
  import { Card } from "./card.js";
5
+ import { Chip } from "./chip.js";
6
+ import { Icon } from "./icon.js";
5
7
  import { Input } from "./input.js";
6
8
  import { Label } from "./label.js";
7
9
  import { Stack } from "./stack.js";
8
10
  import { Text } from "./text.js";
9
11
  import { Textarea } from "./textarea.js";
10
- export { Badge, Box, Button, Card, Input, Label, Stack, Text, Textarea };
12
+ export { Badge, Box, Button, Card, Chip, Icon, Input, Label, Stack, Text, Textarea };
11
13
  export { cn } from "./cn.js";
12
14
  /**
13
15
  * 계약 맵 테스트(C-17)가 보는 객체. 키 집합이 `nativeComponents` 와 같고
@@ -20,6 +22,8 @@ export const components = {
20
22
  Label,
21
23
  Card,
22
24
  Badge,
25
+ Chip,
26
+ Icon,
23
27
  Text,
24
28
  Stack,
25
29
  Box,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACzE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,GAAG;CACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACrF,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,GAAG;CACJ,CAAC"}
package/dist/input.d.ts CHANGED
@@ -5,10 +5,15 @@ type InputProps = Contracts<"native">["Input"];
5
5
  export declare const inputSizes: Record<ControlSize, string>;
6
6
  /**
7
7
  * 테두리 1px 이 Button 과 높이를 맞춘다 — 없으면 Input 이 2px 낮다(plan D-6).
8
- * 웹에는 있는 `placeholder:text-fg-muted` 가 빠져 있다 — react-native-css 는
9
- * `placeholder:` 변형을 `placeholderTextColor` 로 옮기지 않는다. v1 은 플랫폼 기본색을 쓴다.
8
+ * 포커스되면 테두리가 `border-focus` 색이 된다(plan D-9. 0.2.0 까지 빠져 있었다, N-17).
9
+ * 웹 Input 의 `placeholder:text-fg-muted` 는 react-native-css 가 옮기지 않아 0.2.0 까지 플랫폼
10
+ * 기본색이었다(N-13). 이제 `StyledTextInput` 이 `placeholderClassName` 으로 같은 토큰 색을 낸다(N-17).
10
11
  */
11
- export declare const controlBase = "w-full bg-surface text-fg border border-border";
12
+ export declare const controlBase = "w-full bg-surface text-fg border border-border focus:border-border-focus";
13
+ /** 오류 테두리는 포커스 중에도 danger 로 둔다 — 웹은 테두리가 아니라 outline 으로 포커스를 그린다. */
14
+ export declare const invalidBorder = "border-danger focus:border-danger";
15
+ /** placeholder 글자색. 웹 Input 의 `placeholder:text-fg-muted` 와 같은 토큰이다. */
16
+ export declare const placeholderColor = "text-fg-muted";
12
17
  /**
13
18
  * 한 줄 입력. `label` 은 `accessibilityLabel` 로만 간다 — 가시 라벨은 Label 조합이다(C-13).
14
19
  * `id` 를 주면 같은 `htmlFor` 의 Label 과 `accessibilityLabelledBy` 로 이어진다(Android 전용).
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAa,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,KAAK,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AA4B/C,iEAAiE;AACjE,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAIlD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,mDAAmD,CAAC;AAE5E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CA2ChC,CAAC"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAa,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,KAAK,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AA4B/C,iEAAiE;AACjE,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAIlD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,6EAA6E,CAAC;AAEtG,qEAAqE;AACrE,eAAO,MAAM,aAAa,sCAAsC,CAAC;AAEjE,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CA4ChC,CAAC"}
package/dist/input.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { TextInput } from "react-native-css/components";
3
2
  import { cn } from "./cn.js";
4
3
  import { labelNativeId } from "./label.js";
4
+ import { StyledTextInput } from "./text-input.js";
5
5
  /**
6
6
  * `kind` → RN `TextInput` 속성 매핑(C-11). 계약은 열거형 4값뿐이고 이 표는 어댑터 구현 세부다.
7
7
  * 자동완성은 `new-password` 를 구분하지 않는다(알려진 동작 8).
@@ -29,10 +29,15 @@ export const inputSizes = {
29
29
  };
30
30
  /**
31
31
  * 테두리 1px 이 Button 과 높이를 맞춘다 — 없으면 Input 이 2px 낮다(plan D-6).
32
- * 웹에는 있는 `placeholder:text-fg-muted` 가 빠져 있다 — react-native-css 는
33
- * `placeholder:` 변형을 `placeholderTextColor` 로 옮기지 않는다. v1 은 플랫폼 기본색을 쓴다.
32
+ * 포커스되면 테두리가 `border-focus` 색이 된다(plan D-9. 0.2.0 까지 빠져 있었다, N-17).
33
+ * 웹 Input 의 `placeholder:text-fg-muted` 는 react-native-css 가 옮기지 않아 0.2.0 까지 플랫폼
34
+ * 기본색이었다(N-13). 이제 `StyledTextInput` 이 `placeholderClassName` 으로 같은 토큰 색을 낸다(N-17).
34
35
  */
35
- export const controlBase = "w-full bg-surface text-fg border border-border";
36
+ export const controlBase = "w-full bg-surface text-fg border border-border focus:border-border-focus";
37
+ /** 오류 테두리는 포커스 중에도 danger 로 둔다 — 웹은 테두리가 아니라 outline 으로 포커스를 그린다. */
38
+ export const invalidBorder = "border-danger focus:border-danger";
39
+ /** placeholder 글자색. 웹 Input 의 `placeholder:text-fg-muted` 와 같은 토큰이다. */
40
+ export const placeholderColor = "text-fg-muted";
36
41
  /**
37
42
  * 한 줄 입력. `label` 은 `accessibilityLabel` 로만 간다 — 가시 라벨은 Label 조합이다(C-13).
38
43
  * `id` 를 주면 같은 `htmlFor` 의 Label 과 `accessibilityLabelledBy` 로 이어진다(Android 전용).
@@ -46,9 +51,9 @@ export const controlBase = "w-full bg-surface text-fg border border-border";
46
51
  */
47
52
  export const Input = ({ label, kind = "text", size = "md", id, placeholder, disabled = false, invalid = false, value, defaultValue, onValueChange, className, ref, }) => {
48
53
  const attributes = kinds[kind];
49
- return (_jsx(TextInput, { ref: ref, id: id, accessibilityLabel: label, accessibilityLabelledBy: id ? labelNativeId(id) : undefined, placeholder: placeholder, editable: !disabled, value: value, defaultValue: defaultValue, onChangeText: onValueChange,
54
+ return (_jsx(StyledTextInput, { ref: ref, id: id, accessibilityLabel: label, accessibilityLabelledBy: id ? labelNativeId(id) : undefined, placeholder: placeholder, placeholderClassName: placeholderColor, editable: !disabled, value: value, defaultValue: defaultValue, onChangeText: onValueChange,
50
55
  // kind 파생 속성은 하나씩 넘긴다. 스프레드로 넘기면 계약에 없는 prop 이 섞여도
51
56
  // 타입이 잡아주지 못하고, 웹 Input 과 읽는 방식도 갈린다(AC-11a 취지).
52
- secureTextEntry: attributes.secureTextEntry, keyboardType: attributes.keyboardType, autoCapitalize: attributes.autoCapitalize, autoComplete: attributes.autoComplete, textContentType: attributes.textContentType, className: cn(controlBase, inputSizes[size], invalid && "border-danger", disabled && "opacity-50", className) }));
57
+ secureTextEntry: attributes.secureTextEntry, keyboardType: attributes.keyboardType, autoCapitalize: attributes.autoCapitalize, autoComplete: attributes.autoComplete, textContentType: attributes.textContentType, className: cn(controlBase, inputSizes[size], invalid && invalidBorder, disabled && "opacity-50", className) }));
53
58
  };
54
59
  //# sourceMappingURL=input.js.map
package/dist/input.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI3C;;;GAGG;AACH,MAAM,KAAK,GAMP;IACF,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE;QACR,eAAe,EAAE,IAAI;QACrB,YAAY,EAAE,UAAU;QACxB,eAAe,EAAE,UAAU;KAC5B;IACD,KAAK,EAAE;QACL,YAAY,EAAE,eAAe;QAC7B,cAAc,EAAE,MAAM;QACtB,YAAY,EAAE,OAAO;QACrB,eAAe,EAAE,cAAc;KAChC;IACD,MAAM,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE;CACpC,CAAC;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAgC;IACrD,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,8BAA8B;CACnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,gDAAgD,CAAC;AAE5E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,KAAK,GAAmB,CAAC,EACpC,KAAK,EACL,IAAI,GAAG,MAAM,EACb,IAAI,GAAG,IAAI,EACX,EAAE,EACF,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,KAAK,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,GAAG,GACJ,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/B,OAAO,CACL,KAAC,SAAS,IACR,GAAG,EAAE,GAAoC,EACzC,EAAE,EAAE,EAAE,EACN,kBAAkB,EAAE,KAAK,EACzB,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC3D,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,QAAQ,EACnB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,aAAa;QAC3B,mDAAmD;QACnD,iDAAiD;QACjD,eAAe,EAAE,UAAU,CAAC,eAAe,EAC3C,YAAY,EAAE,UAAU,CAAC,YAAY,EACrC,cAAc,EAAE,UAAU,CAAC,cAAc,EACzC,YAAY,EAAE,UAAU,CAAC,YAAY,EACrC,eAAe,EAAE,UAAU,CAAC,eAAe,EAC3C,SAAS,EAAE,EAAE,CACX,WAAW,EACX,UAAU,CAAC,IAAI,CAAC,EAChB,OAAO,IAAI,eAAe,EAC1B,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlD;;;GAGG;AACH,MAAM,KAAK,GAMP;IACF,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE;QACR,eAAe,EAAE,IAAI;QACrB,YAAY,EAAE,UAAU;QACxB,eAAe,EAAE,UAAU;KAC5B;IACD,KAAK,EAAE;QACL,YAAY,EAAE,eAAe;QAC7B,cAAc,EAAE,MAAM;QACtB,YAAY,EAAE,OAAO;QACrB,eAAe,EAAE,cAAc;KAChC;IACD,MAAM,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE;CACpC,CAAC;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAgC;IACrD,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,8BAA8B;CACnC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,0EAA0E,CAAC;AAEtG,qEAAqE;AACrE,MAAM,CAAC,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAEjE,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,KAAK,GAAmB,CAAC,EACpC,KAAK,EACL,IAAI,GAAG,MAAM,EACb,IAAI,GAAG,IAAI,EACX,EAAE,EACF,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,KAAK,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,GAAG,GACJ,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/B,OAAO,CACL,KAAC,eAAe,IACd,GAAG,EAAE,GAAoC,EACzC,EAAE,EAAE,EAAE,EACN,kBAAkB,EAAE,KAAK,EACzB,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC3D,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,gBAAgB,EACtC,QAAQ,EAAE,CAAC,QAAQ,EACnB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,aAAa;QAC3B,mDAAmD;QACnD,iDAAiD;QACjD,eAAe,EAAE,UAAU,CAAC,eAAe,EAC3C,YAAY,EAAE,UAAU,CAAC,YAAY,EACrC,cAAc,EAAE,UAAU,CAAC,cAAc,EACzC,YAAY,EAAE,UAAU,CAAC,YAAY,EACrC,eAAe,EAAE,UAAU,CAAC,eAAe,EAC3C,SAAS,EAAE,EAAE,CACX,WAAW,EACX,UAAU,CAAC,IAAI,CAAC,EAChB,OAAO,IAAI,aAAa,EACxB,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Ref } from "react";
2
+ import { TextInput as RNTextInput, type TextInputProps } from "react-native";
3
+ type StyledTextInputProps = TextInputProps & {
4
+ className?: string;
5
+ placeholderClassName?: string;
6
+ ref?: Ref<RNTextInput>;
7
+ };
8
+ /** DS 내부 전용. Input · Textarea 가 쓴다. */
9
+ export declare function StyledTextInput(props: StyledTextInputProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
10
+ export {};
11
+ //# sourceMappingURL=text-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-input.d.ts","sourceRoot":"","sources":["../src/text-input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAc7E,KAAK,oBAAoB,GAAG,cAAc,GAAG;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;CACxB,CAAC;AAEF,uCAAuC;AACvC,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,0FAE1D"}
@@ -0,0 +1,17 @@
1
+ import { TextInput as RNTextInput } from "react-native";
2
+ import { useCssElement } from "react-native-css";
3
+ /**
4
+ * `react-native-css/components` 의 TextInput 과 같되 placeholder 색 매핑을 하나 더 둔다(N-17).
5
+ * react-native-css 는 `placeholder:` 변형을 `placeholderTextColor` 로 옮기지 않아(N-13) 플랫폼
6
+ * 기본 hint 색이 나오는데, Android AppCompat 라이트의 기본값은 흰 표면 위 약 2.7:1 이다.
7
+ * `placeholderClassName` 의 글자색을 `placeholderTextColor` 로 옮겨 토큰 색을 쓴다.
8
+ */
9
+ const mapping = {
10
+ className: { target: "style", nativeStyleMapping: { textAlign: true } },
11
+ placeholderClassName: { target: false, nativeStyleMapping: { color: "placeholderTextColor" } },
12
+ };
13
+ /** DS 내부 전용. Input · Textarea 가 쓴다. */
14
+ export function StyledTextInput(props) {
15
+ return useCssElement(RNTextInput, props, mapping);
16
+ }
17
+ //# sourceMappingURL=text-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-input.js","sourceRoot":"","sources":["../src/text-input.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,IAAI,WAAW,EAAuB,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,aAAa,EAA4B,MAAM,kBAAkB,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,OAAO,GAAG;IACd,SAAS,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;IACvE,oBAAoB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE;CAC7C,CAAC;AAQpD,uCAAuC;AACvC,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,OAAO,aAAa,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../src/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,KAAK,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAkCtC,CAAC"}
1
+ {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../src/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,KAAK,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAmCtC,CAAC"}
package/dist/textarea.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { component } from "@eeennsu/tokens";
3
- import { TextInput } from "react-native-css/components";
4
3
  import { cn } from "./cn.js";
5
- import { controlBase, inputSizes } from "./input.js";
4
+ import { controlBase, inputSizes, invalidBorder, placeholderColor } from "./input.js";
6
5
  import { labelNativeId } from "./label.js";
6
+ import { StyledTextInput } from "./text-input.js";
7
7
  /**
8
8
  * 여러 줄 입력. `size` 는 글자 크기가 아니라 **행수**로 해석한다 — 3 / 5 / 8 (plan D-14).
9
9
  * 패딩과 글자 크기는 Input `md` 로 고정한다. 웹 `rows` 는 RN `numberOfLines` 로 간다.
@@ -13,5 +13,5 @@ import { labelNativeId } from "./label.js";
13
13
  *
14
14
  * `invalid` 는 Input 과 같이 테두리 색까지만 간다 — RN 에 `aria-invalid` 가 없다(구현 노트 F-16).
15
15
  */
16
- export const Textarea = ({ label, size = "md", id, placeholder, disabled = false, invalid = false, value, defaultValue, onValueChange, className, ref, }) => (_jsx(TextInput, { ref: ref, id: id, multiline: true, numberOfLines: component.textarea.rows[size], textAlignVertical: "top", accessibilityLabel: label, accessibilityLabelledBy: id ? labelNativeId(id) : undefined, placeholder: placeholder, editable: !disabled, value: value, defaultValue: defaultValue, onChangeText: onValueChange, className: cn(controlBase, inputSizes.md, invalid && "border-danger", disabled && "opacity-50", className) }));
16
+ export const Textarea = ({ label, size = "md", id, placeholder, disabled = false, invalid = false, value, defaultValue, onValueChange, className, ref, }) => (_jsx(StyledTextInput, { ref: ref, id: id, multiline: true, numberOfLines: component.textarea.rows[size], textAlignVertical: "top", accessibilityLabel: label, accessibilityLabelledBy: id ? labelNativeId(id) : undefined, placeholder: placeholder, placeholderClassName: placeholderColor, editable: !disabled, value: value, defaultValue: defaultValue, onChangeText: onValueChange, className: cn(controlBase, inputSizes.md, invalid && invalidBorder, disabled && "opacity-50", className) }));
17
17
  //# sourceMappingURL=textarea.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","sourceRoot":"","sources":["../src/textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI3C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAsB,CAAC,EAC1C,KAAK,EACL,IAAI,GAAG,IAAI,EACX,EAAE,EACF,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,KAAK,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,GAAG,GACJ,EAAE,EAAE,CAAC,CACJ,KAAC,SAAS,IACR,GAAG,EAAE,GAAuC,EAC5C,EAAE,EAAE,EAAE,EACN,SAAS,QACT,aAAa,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAC5C,iBAAiB,EAAC,KAAK,EACvB,kBAAkB,EAAE,KAAK,EACzB,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC3D,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,QAAQ,EACnB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,aAAa,EAC3B,SAAS,EAAE,EAAE,CACX,WAAW,EACX,UAAU,CAAC,EAAE,EACb,OAAO,IAAI,eAAe,EAC1B,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,GACD,CACH,CAAC"}
1
+ {"version":3,"file":"textarea.js","sourceRoot":"","sources":["../src/textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAsB,CAAC,EAC1C,KAAK,EACL,IAAI,GAAG,IAAI,EACX,EAAE,EACF,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,KAAK,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,GAAG,GACJ,EAAE,EAAE,CAAC,CACJ,KAAC,eAAe,IACd,GAAG,EAAE,GAAuC,EAC5C,EAAE,EAAE,EAAE,EACN,SAAS,QACT,aAAa,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAC5C,iBAAiB,EAAC,KAAK,EACvB,kBAAkB,EAAE,KAAK,EACzB,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC3D,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,gBAAgB,EACtC,QAAQ,EAAE,CAAC,QAAQ,EACnB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,aAAa,EAC3B,SAAS,EAAE,EAAE,CACX,WAAW,EACX,UAAU,CAAC,EAAE,EACb,OAAO,IAAI,aAAa,EACxB,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,GACD,CACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeennsu/native",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "React Native(Expo + NativeWind v5) 디자인 시스템 컴포넌트",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "lucide-react-native": "1.41.0",
23
23
  "tailwind-merge": "^3.6.0",
24
- "@eeennsu/tokens": "0.2.0"
24
+ "@eeennsu/tokens": "0.3.0"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "nativewind": "5.0.0-preview.4",
package/themes/bakery.css CHANGED
@@ -21,7 +21,7 @@
21
21
  --fg-muted: oklch(70.7% 0.022 261.325);
22
22
  --fg-danger: var(--bg-danger);
23
23
  --fg-on-brand: oklch(13% 0.028 261.692);
24
- --fg-on-danger: oklch(100% 0 0);
24
+ --fg-on-danger: oklch(13% 0.028 261.692);
25
25
  --border-default: oklch(37.3% 0.034 259.733);
26
26
  --border-focus: var(--bg-brand);
27
27
  }
@@ -36,4 +36,9 @@
36
36
  --text-2xl--line-height: 1.3333333333333333;
37
37
  }
38
38
 
39
+ /* RN tabular-nums — font-variant-numeric 을 옮기지 않으므로 RN 선언을 더한다(구현 노트 F-21). */
40
+ .tabular-nums {
41
+ -rn-font-variant: tabular-nums;
42
+ }
43
+
39
44
  @source "../dist";
package/themes/base.css CHANGED
@@ -20,8 +20,8 @@
20
20
  --fg-default: oklch(98.5% 0.002 247.839);
21
21
  --fg-muted: oklch(70.7% 0.022 261.325);
22
22
  --fg-danger: var(--bg-danger);
23
- --fg-on-brand: oklch(100% 0 0);
24
- --fg-on-danger: oklch(100% 0 0);
23
+ --fg-on-brand: oklch(13% 0.028 261.692);
24
+ --fg-on-danger: oklch(13% 0.028 261.692);
25
25
  --border-default: oklch(37.3% 0.034 259.733);
26
26
  --border-focus: var(--bg-brand);
27
27
  }
@@ -36,4 +36,9 @@
36
36
  --text-2xl--line-height: 1.3333333333333333;
37
37
  }
38
38
 
39
+ /* RN tabular-nums — font-variant-numeric 을 옮기지 않으므로 RN 선언을 더한다(구현 노트 F-21). */
40
+ .tabular-nums {
41
+ -rn-font-variant: tabular-nums;
42
+ }
43
+
39
44
  @source "../dist";