@eeennsu/native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/button.d.ts +16 -0
- package/dist/button.d.ts.map +1 -0
- package/dist/button.js +50 -0
- package/dist/button.js.map +1 -0
- package/dist/card.d.ts +8 -0
- package/dist/card.d.ts.map +1 -0
- package/dist/card.js +9 -0
- package/dist/card.js.map +1 -0
- package/dist/cn.d.ts +9 -0
- package/dist/cn.d.ts.map +1 -0
- package/dist/cn.js +11 -0
- package/dist/cn.js.map +1 -0
- package/dist/icon.d.ts +27 -0
- package/dist/icon.d.ts.map +1 -0
- package/dist/icon.js +60 -0
- package/dist/icon.js.map +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/input.d.ts +16 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +52 -0
- package/dist/input.js.map +1 -0
- package/dist/stack.d.ts +10 -0
- package/dist/stack.d.ts.map +1 -0
- package/dist/stack.js +26 -0
- package/dist/stack.js.map +1 -0
- package/dist/text.d.ts +18 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +27 -0
- package/dist/text.js.map +1 -0
- package/package.json +46 -0
- package/themes/bakery.css +39 -0
- package/themes/base.css +39 -0
package/dist/button.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Contracts } from "@eeennsu/tokens";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
type ButtonProps = Contracts<"native">["Button"];
|
|
4
|
+
/**
|
|
5
|
+
* 누름 버튼. `label` 이 가시 텍스트 겸 접근성 이름이다(C-13) — `children` 이 없다.
|
|
6
|
+
* `label` 은 아이콘이 있어도 항상 렌더된다(알려진 동작 9).
|
|
7
|
+
*
|
|
8
|
+
* `ref` 는 호스트 인스턴스를 그대로 넘긴다. RN 의 `NativeMethods` 가 `focus()` · `blur()`
|
|
9
|
+
* 를 가지므로 `FocusHandle` 을 구조적으로 만족한다(웹 N-4 와 같은 처리).
|
|
10
|
+
*
|
|
11
|
+
* 비활성은 `disabled` prop 으로 처리한다 — 웹의 `pointer-events-none` 에 해당하는
|
|
12
|
+
* 클래스가 RN 에 없다. 흐려 보이는 것만 `opacity-50` 으로 맞춘다.
|
|
13
|
+
*/
|
|
14
|
+
export declare const Button: FC<ButtonProps>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/button.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Pressable, Text as RNText } from "react-native-css/components";
|
|
3
|
+
import { cn } from "./cn.js";
|
|
4
|
+
import { Icon } from "./icon.js";
|
|
5
|
+
/**
|
|
6
|
+
* 웹은 배경과 글자색을 버튼 하나에 얹지만 RN 은 View → Text 로 색이 상속되지 않는다.
|
|
7
|
+
* 그래서 variant 를 표면(컨테이너)과 전경(라벨 Text) 둘로 쪼갠다. 클래스 이름 자체는
|
|
8
|
+
* 웹과 같은 어휘다(AC-25). `hover:` 는 RN 에서 무동작이지만 어휘를 맞추려고 남긴다.
|
|
9
|
+
*/
|
|
10
|
+
const surfaces = {
|
|
11
|
+
primary: "bg-brand hover:bg-brand-hover",
|
|
12
|
+
secondary: "bg-surface-muted hover:bg-surface-hover",
|
|
13
|
+
ghost: "hover:bg-surface-hover",
|
|
14
|
+
danger: "bg-danger hover:bg-danger-hover",
|
|
15
|
+
};
|
|
16
|
+
const foregrounds = {
|
|
17
|
+
primary: "text-fg-on-brand",
|
|
18
|
+
secondary: "text-fg",
|
|
19
|
+
ghost: "text-fg",
|
|
20
|
+
danger: "text-fg-on-danger",
|
|
21
|
+
};
|
|
22
|
+
/** 높이는 고정 `h-*` 없이 `py + text + 투명 테두리` 로 만든다 — 30 / 42 / 54 (plan D-6). */
|
|
23
|
+
const boxes = {
|
|
24
|
+
sm: "px-3 py-1 rounded-md gap-1",
|
|
25
|
+
md: "px-4 py-2 rounded-md gap-2",
|
|
26
|
+
lg: "px-6 py-3 rounded-lg gap-2",
|
|
27
|
+
};
|
|
28
|
+
const labels = {
|
|
29
|
+
sm: "text-sm",
|
|
30
|
+
md: "text-md",
|
|
31
|
+
lg: "text-lg",
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* 누름 버튼. `label` 이 가시 텍스트 겸 접근성 이름이다(C-13) — `children` 이 없다.
|
|
35
|
+
* `label` 은 아이콘이 있어도 항상 렌더된다(알려진 동작 9).
|
|
36
|
+
*
|
|
37
|
+
* `ref` 는 호스트 인스턴스를 그대로 넘긴다. RN 의 `NativeMethods` 가 `focus()` · `blur()`
|
|
38
|
+
* 를 가지므로 `FocusHandle` 을 구조적으로 만족한다(웹 N-4 와 같은 처리).
|
|
39
|
+
*
|
|
40
|
+
* 비활성은 `disabled` prop 으로 처리한다 — 웹의 `pointer-events-none` 에 해당하는
|
|
41
|
+
* 클래스가 RN 에 없다. 흐려 보이는 것만 `opacity-50` 으로 맞춘다.
|
|
42
|
+
*/
|
|
43
|
+
export const Button = ({ label, variant = "primary", size = "md", icon, loading = false, disabled = false, onPress, className, ref, }) => {
|
|
44
|
+
const inactive = disabled || loading;
|
|
45
|
+
const foreground = foregrounds[variant];
|
|
46
|
+
return (_jsxs(Pressable, { ref: ref, accessibilityRole: "button", accessibilityLabel: label, accessibilityState: { disabled: inactive }, disabled: inactive,
|
|
47
|
+
// 계약은 `() => 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 })] }));
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=button.js.map
|
|
@@ -0,0 +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"}
|
package/dist/card.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Contracts } from "@eeennsu/tokens";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* 표면 컨테이너. 웹 Card 와 같은 클래스 문자열이다(AC-25).
|
|
5
|
+
* `variant` 를 두지 않는다 — 표면은 하나뿐이고 색을 바꾸려면 `className` 이다(§4.2).
|
|
6
|
+
*/
|
|
7
|
+
export declare const Card: FC<Contracts<"native">["Card"]>;
|
|
8
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../src/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAIhD,CAAC"}
|
package/dist/card.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { View } from "react-native-css/components";
|
|
3
|
+
import { cn } from "./cn.js";
|
|
4
|
+
/**
|
|
5
|
+
* 표면 컨테이너. 웹 Card 와 같은 클래스 문자열이다(AC-25).
|
|
6
|
+
* `variant` 를 두지 않는다 — 표면은 하나뿐이고 색을 바꾸려면 `className` 이다(§4.2).
|
|
7
|
+
*/
|
|
8
|
+
export const Card = ({ children, className }) => (_jsx(View, { className: cn("bg-surface border border-border rounded-lg shadow-sm p-4", className), children: children }));
|
|
9
|
+
//# sourceMappingURL=card.js.map
|
package/dist/card.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../src/card.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAoC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAChF,KAAC,IAAI,IAAC,SAAS,EAAE,EAAE,CAAC,0DAA0D,EAAE,SAAS,CAAC,YACvF,QAAQ,GACJ,CACR,CAAC"}
|
package/dist/cn.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DS 기본 클래스와 소비자 `className` 을 병합한다. 충돌하면 소비자가 이긴다(C-15).
|
|
3
|
+
* 웹(`@eeennsu/web`)과 **같은 설정 객체**를 쓴다 — 어휘가 갈리면 AC-25 가 깨진다.
|
|
4
|
+
*
|
|
5
|
+
* `override` 여야 한다 — `extend` 는 기본 검증자에 concat 이라 spacing 의 기본 `isNumber`
|
|
6
|
+
* 가 남고, 존재하지 않는 `mt-5` 가 DS 의 `mt-4` 를 밀어낸다(plan v2 F-4, T-T5 테스트).
|
|
7
|
+
*/
|
|
8
|
+
export declare const cn: (...classLists: import("tailwind-merge").ClassNameValue[]) => string;
|
|
9
|
+
//# sourceMappingURL=cn.d.ts.map
|
package/dist/cn.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../src/cn.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,eAAO,MAAM,EAAE,sEAA8D,CAAC"}
|
package/dist/cn.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { twMergeConfig } from "@eeennsu/tokens";
|
|
2
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
3
|
+
/**
|
|
4
|
+
* DS 기본 클래스와 소비자 `className` 을 병합한다. 충돌하면 소비자가 이긴다(C-15).
|
|
5
|
+
* 웹(`@eeennsu/web`)과 **같은 설정 객체**를 쓴다 — 어휘가 갈리면 AC-25 가 깨진다.
|
|
6
|
+
*
|
|
7
|
+
* `override` 여야 한다 — `extend` 는 기본 검증자에 concat 이라 spacing 의 기본 `isNumber`
|
|
8
|
+
* 가 남고, 존재하지 않는 `mt-5` 가 DS 의 `mt-4` 를 밀어낸다(plan v2 F-4, T-T5 테스트).
|
|
9
|
+
*/
|
|
10
|
+
export const cn = extendTailwindMerge({ override: { theme: twMergeConfig } });
|
|
11
|
+
//# sourceMappingURL=cn.js.map
|
package/dist/cn.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.js","sourceRoot":"","sources":["../src/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC"}
|
package/dist/icon.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ControlSize, type IconName } from "@eeennsu/tokens";
|
|
2
|
+
import { type LucideIcon } from "lucide-react-native";
|
|
3
|
+
/**
|
|
4
|
+
* `IconName` → lucide 컴포넌트. 웹(`@eeennsu/web`)의 맵과 같은 24개이며
|
|
5
|
+
* `Record<IconName, LucideIcon>` 이라 tokens 목록에 이름을 추가하고 한쪽 맵을
|
|
6
|
+
* 빠뜨리면 컴파일 에러가 난다(plan D-8).
|
|
7
|
+
*
|
|
8
|
+
* lucide 의 **정식 export 이름**만 쓴다 — 별칭(`AlertCircle` → `CircleAlert`)은
|
|
9
|
+
* major 에서 사라질 수 있다(plan v2 F-6).
|
|
10
|
+
*/
|
|
11
|
+
declare const icons: Record<IconName, LucideIcon>;
|
|
12
|
+
type IconProps = {
|
|
13
|
+
name: IconName;
|
|
14
|
+
size?: ControlSize;
|
|
15
|
+
className?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* DS 내부 전용이다 — 공개 컴포넌트가 아니고 `Contracts` 에도 없다.
|
|
19
|
+
* 크기는 클래스가 아니라 lucide `size` prop(JS 숫자)으로 준다 — 20px 는 spacing 열거
|
|
20
|
+
* 밖이라 `size-5` 클래스가 생성되지 않기 때문이다(plan v2 F-8).
|
|
21
|
+
*
|
|
22
|
+
* 웹 Icon 의 `spin` 은 없다 — RN 에서 `animate-spin` 은 Reanimated 경로가 필요하고
|
|
23
|
+
* v1 범위 밖이다. Button 의 `loading` 은 회전 없이 아이콘만 바꾼다(알려진 동작 참조).
|
|
24
|
+
*/
|
|
25
|
+
export declare function Icon({ name, size, className }: IconProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
26
|
+
export { icons };
|
|
27
|
+
//# sourceMappingURL=icon.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/icon.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
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 { useCssElement } from "react-native-css";
|
|
4
|
+
/**
|
|
5
|
+
* `IconName` → lucide 컴포넌트. 웹(`@eeennsu/web`)의 맵과 같은 24개이며
|
|
6
|
+
* `Record<IconName, LucideIcon>` 이라 tokens 목록에 이름을 추가하고 한쪽 맵을
|
|
7
|
+
* 빠뜨리면 컴파일 에러가 난다(plan D-8).
|
|
8
|
+
*
|
|
9
|
+
* lucide 의 **정식 export 이름**만 쓴다 — 별칭(`AlertCircle` → `CircleAlert`)은
|
|
10
|
+
* major 에서 사라질 수 있다(plan v2 F-6).
|
|
11
|
+
*/
|
|
12
|
+
const icons = {
|
|
13
|
+
check: Check,
|
|
14
|
+
x: X,
|
|
15
|
+
plus: Plus,
|
|
16
|
+
minus: Minus,
|
|
17
|
+
trash: Trash,
|
|
18
|
+
pencil: Pencil,
|
|
19
|
+
search: Search,
|
|
20
|
+
"chevron-down": ChevronDown,
|
|
21
|
+
"chevron-up": ChevronUp,
|
|
22
|
+
"chevron-left": ChevronLeft,
|
|
23
|
+
"chevron-right": ChevronRight,
|
|
24
|
+
"arrow-left": ArrowLeft,
|
|
25
|
+
"arrow-right": ArrowRight,
|
|
26
|
+
menu: Menu,
|
|
27
|
+
settings: Settings,
|
|
28
|
+
user: User,
|
|
29
|
+
mail: Mail,
|
|
30
|
+
lock: Lock,
|
|
31
|
+
eye: Eye,
|
|
32
|
+
"eye-off": EyeOff,
|
|
33
|
+
info: Info,
|
|
34
|
+
"alert-circle": CircleAlert,
|
|
35
|
+
loader: Loader,
|
|
36
|
+
"external-link": ExternalLink,
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* 웹은 아이콘 색을 `currentColor` 로 상속하지만 RN 에는 `currentColor` 가 없다.
|
|
40
|
+
* 그래서 `className` 의 색만 뽑아 lucide 의 `color` prop 으로 넘긴다 —
|
|
41
|
+
* 호출부는 `text-fg-on-brand` 처럼 웹과 같은 클래스를 쓴다(§9 S-17, AC-25).
|
|
42
|
+
* `target: false` 라 `style` 은 만들지 않는다 — svg 는 style 을 안 받는다.
|
|
43
|
+
*/
|
|
44
|
+
const mapping = {
|
|
45
|
+
className: { target: false, nativeStyleMapping: { color: "color" } },
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* DS 내부 전용이다 — 공개 컴포넌트가 아니고 `Contracts` 에도 없다.
|
|
49
|
+
* 크기는 클래스가 아니라 lucide `size` prop(JS 숫자)으로 준다 — 20px 는 spacing 열거
|
|
50
|
+
* 밖이라 `size-5` 클래스가 생성되지 않기 때문이다(plan v2 F-8).
|
|
51
|
+
*
|
|
52
|
+
* 웹 Icon 의 `spin` 은 없다 — RN 에서 `animate-spin` 은 Reanimated 경로가 필요하고
|
|
53
|
+
* v1 범위 밖이다. Button 의 `loading` 은 회전 없이 아이콘만 바꾼다(알려진 동작 참조).
|
|
54
|
+
*/
|
|
55
|
+
export function Icon({ name, size = "md", className }) {
|
|
56
|
+
const Glyph = icons[name];
|
|
57
|
+
return useCssElement(Glyph, { className, size: component.icon.size[size] }, mapping);
|
|
58
|
+
}
|
|
59
|
+
export { icons };
|
|
60
|
+
//# sourceMappingURL=icon.js.map
|
package/dist/icon.js.map
ADDED
|
@@ -0,0 +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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
import { Card } from "./card.js";
|
|
3
|
+
import { Input } from "./input.js";
|
|
4
|
+
import { Stack } from "./stack.js";
|
|
5
|
+
import { Text } from "./text.js";
|
|
6
|
+
export { Button, Card, Input, Stack, Text };
|
|
7
|
+
export { cn } from "./cn.js";
|
|
8
|
+
/**
|
|
9
|
+
* 계약 맵 테스트(C-17)가 보는 객체. 키 집합이 `nativeComponents` 와 같고
|
|
10
|
+
* 값 타입이 `FC<Contracts<"native">[K]>` 와 같아야 한다(AC-21).
|
|
11
|
+
*/
|
|
12
|
+
export declare const components: {
|
|
13
|
+
Button: import("react").FC<{
|
|
14
|
+
label: string;
|
|
15
|
+
variant?: import("@eeennsu/tokens").Variant;
|
|
16
|
+
size?: import("@eeennsu/tokens").ControlSize;
|
|
17
|
+
icon?: import("@eeennsu/tokens").IconName;
|
|
18
|
+
loading?: boolean;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
className?: string;
|
|
21
|
+
ref?: import("react").Ref<import("@eeennsu/tokens").FocusHandle>;
|
|
22
|
+
} & {
|
|
23
|
+
onPress?: () => void;
|
|
24
|
+
}>;
|
|
25
|
+
Input: import("react").FC<{
|
|
26
|
+
label: string;
|
|
27
|
+
kind?: import("@eeennsu/tokens").InputKind;
|
|
28
|
+
size?: import("@eeennsu/tokens").ControlSize;
|
|
29
|
+
id?: string;
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
invalid?: boolean;
|
|
33
|
+
value?: string;
|
|
34
|
+
defaultValue?: string;
|
|
35
|
+
onValueChange?: (value: string) => void;
|
|
36
|
+
className?: string;
|
|
37
|
+
ref?: import("react").Ref<import("@eeennsu/tokens").FocusHandle>;
|
|
38
|
+
}>;
|
|
39
|
+
Card: import("react").FC<{
|
|
40
|
+
children: import("@eeennsu/tokens").ElementChildren;
|
|
41
|
+
className?: string;
|
|
42
|
+
}>;
|
|
43
|
+
Stack: import("react").FC<{
|
|
44
|
+
children: import("@eeennsu/tokens").ElementChildren;
|
|
45
|
+
direction?: "row" | "column";
|
|
46
|
+
align?: "start" | "center" | "end" | "stretch";
|
|
47
|
+
justify?: "start" | "center" | "end" | "between";
|
|
48
|
+
wrap?: boolean;
|
|
49
|
+
className?: string;
|
|
50
|
+
}>;
|
|
51
|
+
Text: import("react").FC<{
|
|
52
|
+
children: string | string[];
|
|
53
|
+
tone?: import("@eeennsu/tokens").Tone;
|
|
54
|
+
size?: import("@eeennsu/tokens").TypographyStep;
|
|
55
|
+
heading?: "1" | "2" | "3";
|
|
56
|
+
className?: string;
|
|
57
|
+
}>;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMtB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
import { Card } from "./card.js";
|
|
3
|
+
import { Input } from "./input.js";
|
|
4
|
+
import { Stack } from "./stack.js";
|
|
5
|
+
import { Text } from "./text.js";
|
|
6
|
+
export { Button, Card, Input, Stack, Text };
|
|
7
|
+
export { cn } from "./cn.js";
|
|
8
|
+
/**
|
|
9
|
+
* 계약 맵 테스트(C-17)가 보는 객체. 키 집합이 `nativeComponents` 와 같고
|
|
10
|
+
* 값 타입이 `FC<Contracts<"native">[K]>` 와 같아야 한다(AC-21).
|
|
11
|
+
*/
|
|
12
|
+
export const components = {
|
|
13
|
+
Button,
|
|
14
|
+
Input,
|
|
15
|
+
Card,
|
|
16
|
+
Stack,
|
|
17
|
+
Text,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM;IACN,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;CACL,CAAC"}
|
package/dist/input.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Contracts } from "@eeennsu/tokens";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
type InputProps = Contracts<"native">["Input"];
|
|
4
|
+
/**
|
|
5
|
+
* 한 줄 입력. `label` 은 `accessibilityLabel` 로만 간다 — 가시 라벨은 v2 의 Label 조합이다(C-13).
|
|
6
|
+
* 값 제어는 `value` / `defaultValue` / `onValueChange` 3종뿐이다(C-12).
|
|
7
|
+
* RN 의 `onChangeText` 가 이미 값을 주므로 어댑터가 이벤트를 벗길 일이 없다.
|
|
8
|
+
*
|
|
9
|
+
* `invalid` 는 **테두리 색까지만** 간다. 웹의 `aria-invalid` 에 해당하는 것이 RN 에 없다 —
|
|
10
|
+
* `accessibilityState` 는 disabled · selected · checked · busy · expanded 뿐이고
|
|
11
|
+
* `aria-invalid` 는 react-native 에 존재하지 않는 prop 이라 넘겨도 무동작이다.
|
|
12
|
+
* 오류를 읽히려면 소비자가 `Text tone="danger"` 로 메시지를 놓는다(C-21 과 같은 방식).
|
|
13
|
+
*/
|
|
14
|
+
export declare const Input: FC<InputProps>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAA0B,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,KAAK,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AA0C/C;;;;;;;;;GASG;AACH,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CA0ChC,CAAC"}
|
package/dist/input.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { TextInput } from "react-native-css/components";
|
|
3
|
+
import { cn } from "./cn.js";
|
|
4
|
+
/**
|
|
5
|
+
* `kind` → RN `TextInput` 속성 매핑(C-11). 계약은 열거형 4값뿐이고 이 표는 어댑터 구현 세부다.
|
|
6
|
+
* 자동완성은 `new-password` 를 구분하지 않는다(알려진 동작 8).
|
|
7
|
+
*/
|
|
8
|
+
const kinds = {
|
|
9
|
+
text: {},
|
|
10
|
+
password: {
|
|
11
|
+
secureTextEntry: true,
|
|
12
|
+
autoComplete: "password",
|
|
13
|
+
textContentType: "password",
|
|
14
|
+
},
|
|
15
|
+
email: {
|
|
16
|
+
keyboardType: "email-address",
|
|
17
|
+
autoCapitalize: "none",
|
|
18
|
+
autoComplete: "email",
|
|
19
|
+
textContentType: "emailAddress",
|
|
20
|
+
},
|
|
21
|
+
number: { keyboardType: "numeric" },
|
|
22
|
+
};
|
|
23
|
+
/** 웹 Input 과 같은 크기 클래스다(AC-25). 웹의 `text-*` 는 여기서도 같은 스텝을 쓴다. */
|
|
24
|
+
const sizes = {
|
|
25
|
+
sm: "px-3 py-1 text-sm rounded-md",
|
|
26
|
+
md: "px-3 py-2 text-md rounded-md",
|
|
27
|
+
lg: "px-4 py-3 text-lg rounded-md",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 테두리 1px 이 Button 과 높이를 맞춘다 — 없으면 Input 이 2px 낮다(plan D-6).
|
|
31
|
+
* 웹에는 있는 `placeholder:text-fg-muted` 가 빠져 있다 — react-native-css 는
|
|
32
|
+
* `placeholder:` 변형을 `placeholderTextColor` 로 옮기지 않는다. v1 은 플랫폼 기본색을 쓴다.
|
|
33
|
+
*/
|
|
34
|
+
const base = "w-full bg-surface text-fg border border-border";
|
|
35
|
+
/**
|
|
36
|
+
* 한 줄 입력. `label` 은 `accessibilityLabel` 로만 간다 — 가시 라벨은 v2 의 Label 조합이다(C-13).
|
|
37
|
+
* 값 제어는 `value` / `defaultValue` / `onValueChange` 3종뿐이다(C-12).
|
|
38
|
+
* RN 의 `onChangeText` 가 이미 값을 주므로 어댑터가 이벤트를 벗길 일이 없다.
|
|
39
|
+
*
|
|
40
|
+
* `invalid` 는 **테두리 색까지만** 간다. 웹의 `aria-invalid` 에 해당하는 것이 RN 에 없다 —
|
|
41
|
+
* `accessibilityState` 는 disabled · selected · checked · busy · expanded 뿐이고
|
|
42
|
+
* `aria-invalid` 는 react-native 에 존재하지 않는 prop 이라 넘겨도 무동작이다.
|
|
43
|
+
* 오류를 읽히려면 소비자가 `Text tone="danger"` 로 메시지를 놓는다(C-21 과 같은 방식).
|
|
44
|
+
*/
|
|
45
|
+
export const Input = ({ label, kind = "text", size = "md", id, placeholder, disabled = false, invalid = false, value, defaultValue, onValueChange, className, ref, }) => {
|
|
46
|
+
const attributes = kinds[kind];
|
|
47
|
+
return (_jsx(TextInput, { ref: ref, id: id, accessibilityLabel: label, placeholder: placeholder, editable: !disabled, value: value, defaultValue: defaultValue, onChangeText: onValueChange,
|
|
48
|
+
// kind 파생 속성은 하나씩 넘긴다. 스프레드로 넘기면 계약에 없는 prop 이 섞여도
|
|
49
|
+
// 타입이 잡아주지 못하고, 웹 Input 과 읽는 방식도 갈린다(AC-11a 취지).
|
|
50
|
+
secureTextEntry: attributes.secureTextEntry, keyboardType: attributes.keyboardType, autoCapitalize: attributes.autoCapitalize, autoComplete: attributes.autoComplete, textContentType: attributes.textContentType, className: cn(base, sizes[size], invalid && "border-danger", disabled && "opacity-50", className) }));
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -0,0 +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;AAI7B;;;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,KAAK,GAAgC;IACzC,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,8BAA8B;CACnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,IAAI,GAAG,gDAAgD,CAAC;AAE9D;;;;;;;;;GASG;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,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,IAAI,EACJ,KAAK,CAAC,IAAI,CAAC,EACX,OAAO,IAAI,eAAe,EAC1B,QAAQ,IAAI,YAAY,EACxB,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/stack.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Contracts } from "@eeennsu/tokens";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
type StackProps = Contracts<"native">["Stack"];
|
|
4
|
+
/**
|
|
5
|
+
* flex 컨테이너. 웹 Stack 과 **같은 클래스 문자열**을 낸다(AC-25).
|
|
6
|
+
* 간격 prop 은 없다 — 소비자가 `className="gap-4"` 로 준다(C-14).
|
|
7
|
+
*/
|
|
8
|
+
export declare const Stack: FC<StackProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=stack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../src/stack.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,KAAK,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AAsB/C;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAoBhC,CAAC"}
|
package/dist/stack.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { View } from "react-native-css/components";
|
|
3
|
+
import { cn } from "./cn.js";
|
|
4
|
+
/** 클래스는 전부 정적 리터럴이어야 `@source` 스캔이 잡는다(C-4 (2)). */
|
|
5
|
+
const directions = {
|
|
6
|
+
row: "flex-row",
|
|
7
|
+
column: "flex-col",
|
|
8
|
+
};
|
|
9
|
+
const aligns = {
|
|
10
|
+
start: "items-start",
|
|
11
|
+
center: "items-center",
|
|
12
|
+
end: "items-end",
|
|
13
|
+
stretch: "items-stretch",
|
|
14
|
+
};
|
|
15
|
+
const justifies = {
|
|
16
|
+
start: "justify-start",
|
|
17
|
+
center: "justify-center",
|
|
18
|
+
end: "justify-end",
|
|
19
|
+
between: "justify-between",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* flex 컨테이너. 웹 Stack 과 **같은 클래스 문자열**을 낸다(AC-25).
|
|
23
|
+
* 간격 prop 은 없다 — 소비자가 `className="gap-4"` 로 준다(C-14).
|
|
24
|
+
*/
|
|
25
|
+
export const Stack = ({ children, direction = "column", align = "stretch", justify = "start", wrap = false, className, }) => (_jsx(View, { className: cn("flex", directions[direction], aligns[align], justifies[justify], wrap && "flex-wrap", className), children: children }));
|
|
26
|
+
//# sourceMappingURL=stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.js","sourceRoot":"","sources":["../src/stack.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAI7B,oDAAoD;AACpD,MAAM,UAAU,GAAyD;IACvE,GAAG,EAAE,UAAU;IACf,MAAM,EAAE,UAAU;CACnB,CAAC;AAEF,MAAM,MAAM,GAAqD;IAC/D,KAAK,EAAE,aAAa;IACpB,MAAM,EAAE,cAAc;IACtB,GAAG,EAAE,WAAW;IAChB,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF,MAAM,SAAS,GAAuD;IACpE,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,gBAAgB;IACxB,GAAG,EAAE,aAAa;IAClB,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAmB,CAAC,EACpC,QAAQ,EACR,SAAS,GAAG,QAAQ,EACpB,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,OAAO,EACjB,IAAI,GAAG,KAAK,EACZ,SAAS,GACV,EAAE,EAAE,CAAC,CACJ,KAAC,IAAI,IACH,SAAS,EAAE,EAAE,CACX,MAAM,EACN,UAAU,CAAC,SAAS,CAAC,EACrB,MAAM,CAAC,KAAK,CAAC,EACb,SAAS,CAAC,OAAO,CAAC,EAClB,IAAI,IAAI,WAAW,EACnB,SAAS,CACV,YAEA,QAAQ,GACJ,CACR,CAAC"}
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Contracts, Tone, TypographyStep } from "@eeennsu/tokens";
|
|
2
|
+
import type { FC } from "react";
|
|
3
|
+
type TextProps = Contracts<"native">["Text"];
|
|
4
|
+
/** `tone` 은 fg semantic 색과 1:1 이다(C-8). `danger` 는 `bg.danger` 별칭이다(plan D-3). */
|
|
5
|
+
export declare const tones: Record<Tone, string>;
|
|
6
|
+
/**
|
|
7
|
+
* 스텝 하나가 크기·행간·무게를 함께 바꾼다(C-6 복합 폰트 변수).
|
|
8
|
+
* RN 에서 세 값이 다 맞는 것은 native 래퍼가 line-height 를 배수로 다시 내기 때문이다(T-N0).
|
|
9
|
+
*/
|
|
10
|
+
export declare const steps: Record<TypographyStep, string>;
|
|
11
|
+
/**
|
|
12
|
+
* 텍스트. 웹은 `heading` 을 `h1~h3` 엘리먼트로 내지만 RN 에는 제목 엘리먼트가 없어
|
|
13
|
+
* `accessibilityRole="header"` 로 간다 — 레벨 개념이 없으므로 1·2·3 이 같은 역할이 된다.
|
|
14
|
+
* 시각적 크기는 어느 쪽이든 `size` 가 정한다.
|
|
15
|
+
*/
|
|
16
|
+
export declare const Text: FC<TextProps>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,KAAK,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7C,kFAAkF;AAClF,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAItC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAMhD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAa9B,CAAC"}
|
package/dist/text.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text as RNText } from "react-native-css/components";
|
|
3
|
+
import { cn } from "./cn.js";
|
|
4
|
+
/** `tone` 은 fg semantic 색과 1:1 이다(C-8). `danger` 는 `bg.danger` 별칭이다(plan D-3). */
|
|
5
|
+
export const tones = {
|
|
6
|
+
default: "text-fg",
|
|
7
|
+
muted: "text-fg-muted",
|
|
8
|
+
danger: "text-fg-danger",
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* 스텝 하나가 크기·행간·무게를 함께 바꾼다(C-6 복합 폰트 변수).
|
|
12
|
+
* RN 에서 세 값이 다 맞는 것은 native 래퍼가 line-height 를 배수로 다시 내기 때문이다(T-N0).
|
|
13
|
+
*/
|
|
14
|
+
export const steps = {
|
|
15
|
+
sm: "text-sm",
|
|
16
|
+
md: "text-md",
|
|
17
|
+
lg: "text-lg",
|
|
18
|
+
xl: "text-xl",
|
|
19
|
+
"2xl": "text-2xl",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 텍스트. 웹은 `heading` 을 `h1~h3` 엘리먼트로 내지만 RN 에는 제목 엘리먼트가 없어
|
|
23
|
+
* `accessibilityRole="header"` 로 간다 — 레벨 개념이 없으므로 1·2·3 이 같은 역할이 된다.
|
|
24
|
+
* 시각적 크기는 어느 쪽이든 `size` 가 정한다.
|
|
25
|
+
*/
|
|
26
|
+
export const Text = ({ children, tone = "default", size = "md", heading, className, }) => (_jsx(RNText, { accessibilityRole: heading ? "header" : undefined, className: cn(tones[tone], steps[size], className), children: children }));
|
|
27
|
+
//# sourceMappingURL=text.js.map
|
package/dist/text.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAI7B,kFAAkF;AAClF,MAAM,CAAC,MAAM,KAAK,GAAyB;IACzC,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,gBAAgB;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAmC;IACnD,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,KAAK,EAAE,UAAU;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAkB,CAAC,EAClC,QAAQ,EACR,IAAI,GAAG,SAAS,EAChB,IAAI,GAAG,IAAI,EACX,OAAO,EACP,SAAS,GACV,EAAE,EAAE,CAAC,CACJ,KAAC,MAAM,IACL,iBAAiB,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EACjD,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,YAEjD,QAAQ,GACF,CACV,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eeennsu/native",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React Native(Expo + NativeWind v5) 디자인 시스템 컴포넌트",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"*.css"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"themes"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./themes/*.css": "./themes/*.css"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"lucide-react-native": "1.41.0",
|
|
23
|
+
"tailwind-merge": "^3.6.0",
|
|
24
|
+
"@eeennsu/tokens": "0.1.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"nativewind": "5.0.0-preview.4",
|
|
28
|
+
"react": ">=19",
|
|
29
|
+
"react-native": ">=0.81",
|
|
30
|
+
"react-native-css": "3.0.7",
|
|
31
|
+
"react-native-svg": "*",
|
|
32
|
+
"tailwindcss": ">=4.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "~19.2.18",
|
|
36
|
+
"lightningcss": "1.30.1",
|
|
37
|
+
"react": "19.2.3",
|
|
38
|
+
"react-native": "0.86.3",
|
|
39
|
+
"react-native-css": "3.0.7",
|
|
40
|
+
"react-native-svg": "15.15.4"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"test": "vitest run --typecheck --passWithNoTests"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* 생성 파일. packages/tokens/scripts/build.ts 가 만든다. 직접 수정하지 않는다. */
|
|
2
|
+
/* @eeennsu/native — brand: bakery. 소비자 공개 경로다(C-3). */
|
|
3
|
+
/* @custom-variant dark 를 넣지 않는다 — RN 은 NativeWind 의 dark: 기본 동작을 쓴다(C-20, plan v2 F-21). */
|
|
4
|
+
|
|
5
|
+
@import "tailwindcss";
|
|
6
|
+
@import "@eeennsu/tokens/themes/bakery.css";
|
|
7
|
+
|
|
8
|
+
/* RN 다크 — 토큰 파일의 .dark 와 :root:not(.light) 는 NativeWind v5 에서 죽는다(게이트 (2)·(4)). */
|
|
9
|
+
@media (prefers-color-scheme: dark) {
|
|
10
|
+
:root {
|
|
11
|
+
--bg-canvas: oklch(13% 0.028 261.692);
|
|
12
|
+
--bg-surface: oklch(21% 0.034 264.665);
|
|
13
|
+
--bg-surface-muted: oklch(27.8% 0.033 256.848);
|
|
14
|
+
--bg-surface-hover: oklch(37.3% 0.034 259.733);
|
|
15
|
+
--bg-brand: oklch(76.9% 0.188 70.08);
|
|
16
|
+
--bg-brand-hover: oklch(82.8% 0.189 84.429);
|
|
17
|
+
--bg-danger: oklch(63.7% 0.237 25.331);
|
|
18
|
+
--bg-danger-hover: oklch(70.4% 0.191 22.216);
|
|
19
|
+
--bg-overlay: oklch(0% 0 0 / 0.6);
|
|
20
|
+
--fg-default: oklch(98.5% 0.002 247.839);
|
|
21
|
+
--fg-muted: oklch(70.7% 0.022 261.325);
|
|
22
|
+
--fg-danger: var(--bg-danger);
|
|
23
|
+
--fg-on-brand: oklch(13% 0.028 261.692);
|
|
24
|
+
--fg-on-danger: oklch(100% 0 0);
|
|
25
|
+
--border-default: oklch(37.3% 0.034 259.733);
|
|
26
|
+
--border-focus: var(--bg-brand);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* RN line-height — px 를 배수로 읽으므로 배수로 다시 낸다(게이트 (5), plan D-31). */
|
|
31
|
+
@theme {
|
|
32
|
+
--text-sm--line-height: 1.4285714285714286;
|
|
33
|
+
--text-md--line-height: 1.5;
|
|
34
|
+
--text-lg--line-height: 1.5555555555555556;
|
|
35
|
+
--text-xl--line-height: 1.4;
|
|
36
|
+
--text-2xl--line-height: 1.3333333333333333;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@source "../dist";
|
package/themes/base.css
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* 생성 파일. packages/tokens/scripts/build.ts 가 만든다. 직접 수정하지 않는다. */
|
|
2
|
+
/* @eeennsu/native — brand: base. 소비자 공개 경로다(C-3). */
|
|
3
|
+
/* @custom-variant dark 를 넣지 않는다 — RN 은 NativeWind 의 dark: 기본 동작을 쓴다(C-20, plan v2 F-21). */
|
|
4
|
+
|
|
5
|
+
@import "tailwindcss";
|
|
6
|
+
@import "@eeennsu/tokens/themes/base.css";
|
|
7
|
+
|
|
8
|
+
/* RN 다크 — 토큰 파일의 .dark 와 :root:not(.light) 는 NativeWind v5 에서 죽는다(게이트 (2)·(4)). */
|
|
9
|
+
@media (prefers-color-scheme: dark) {
|
|
10
|
+
:root {
|
|
11
|
+
--bg-canvas: oklch(13% 0.028 261.692);
|
|
12
|
+
--bg-surface: oklch(21% 0.034 264.665);
|
|
13
|
+
--bg-surface-muted: oklch(27.8% 0.033 256.848);
|
|
14
|
+
--bg-surface-hover: oklch(37.3% 0.034 259.733);
|
|
15
|
+
--bg-brand: oklch(62.3% 0.214 259.815);
|
|
16
|
+
--bg-brand-hover: oklch(70.7% 0.165 254.624);
|
|
17
|
+
--bg-danger: oklch(63.7% 0.237 25.331);
|
|
18
|
+
--bg-danger-hover: oklch(70.4% 0.191 22.216);
|
|
19
|
+
--bg-overlay: oklch(0% 0 0 / 0.6);
|
|
20
|
+
--fg-default: oklch(98.5% 0.002 247.839);
|
|
21
|
+
--fg-muted: oklch(70.7% 0.022 261.325);
|
|
22
|
+
--fg-danger: var(--bg-danger);
|
|
23
|
+
--fg-on-brand: oklch(100% 0 0);
|
|
24
|
+
--fg-on-danger: oklch(100% 0 0);
|
|
25
|
+
--border-default: oklch(37.3% 0.034 259.733);
|
|
26
|
+
--border-focus: var(--bg-brand);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* RN line-height — px 를 배수로 읽으므로 배수로 다시 낸다(게이트 (5), plan D-31). */
|
|
31
|
+
@theme {
|
|
32
|
+
--text-sm--line-height: 1.4285714285714286;
|
|
33
|
+
--text-md--line-height: 1.5;
|
|
34
|
+
--text-lg--line-height: 1.5555555555555556;
|
|
35
|
+
--text-xl--line-height: 1.4;
|
|
36
|
+
--text-2xl--line-height: 1.3333333333333333;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@source "../dist";
|