@ecohouse/ui 0.1.1 → 0.1.3
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 +2 -1
- package/dist/index.cjs +1266 -109
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +188 -12
- package/dist/index.d.ts +188 -12
- package/dist/index.js +1260 -112
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/components/Button/Button.tsx +106 -88
- package/src/components/Checkbox/Checkbox.stories.tsx +112 -0
- package/src/components/Checkbox/Checkbox.tsx +150 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/Input/Input.stories.tsx +11 -40
- package/src/components/Input/Input.tsx +58 -54
- package/src/components/Input/index.ts +1 -1
- package/src/components/Select/Select.stories.tsx +196 -0
- package/src/components/Select/Select.tsx +851 -0
- package/src/components/Select/index.ts +2 -0
- package/src/components/Textarea/Textarea.stories.tsx +71 -0
- package/src/components/Textarea/Textarea.tsx +241 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Toggle/Toggle.stories.tsx +100 -0
- package/src/components/Toggle/Toggle.tsx +176 -0
- package/src/components/Toggle/index.ts +2 -0
- package/src/components/index.ts +13 -1
- package/src/icons/Check/CheckIcon.tsx +26 -0
- package/src/icons/Check/CheckIcon.web.tsx +32 -0
- package/src/icons/Check/checkPath.ts +2 -0
- package/src/icons/Check/index.ts +1 -0
- package/src/icons/ChevronDown/ChevronDownIcon.tsx +30 -0
- package/src/icons/ChevronDown/ChevronDownIcon.web.tsx +36 -0
- package/src/icons/ChevronDown/chevronDownPath.ts +2 -0
- package/src/icons/ChevronDown/index.ts +1 -0
- package/src/icons/Search/SearchIcon.tsx +37 -0
- package/src/icons/Search/SearchIcon.web.tsx +43 -0
- package/src/icons/Search/index.ts +1 -0
- package/src/icons/Search/searchPath.ts +5 -0
- package/src/icons/index.ts +3 -0
- package/src/icons/registry.ts +8 -2
- package/src/index.ts +21 -3
- package/src/theme/index.ts +7 -1
- package/src/theme/typography.ts +52 -2
- package/src/utils/mergeRefs.ts +20 -0
- package/src/web/styles/fonts.css +1 -0
- package/src/web/styles/typography.css +6 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Svg, { Path } from "react-native-svg";
|
|
2
|
+
import { CHEVRON_DOWN_PATH } from "./chevronDownPath";
|
|
3
|
+
import { colors } from "../../theme";
|
|
4
|
+
|
|
5
|
+
export { CHEVRON_DOWN_PATH } from "./chevronDownPath";
|
|
6
|
+
|
|
7
|
+
interface ChevronDownIconProps {
|
|
8
|
+
size?: number;
|
|
9
|
+
color?: string;
|
|
10
|
+
strokeWidth?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Native — react-native-svg (peer dependency). */
|
|
14
|
+
export function ChevronDownIcon({
|
|
15
|
+
size = 20,
|
|
16
|
+
color = colors.primary,
|
|
17
|
+
strokeWidth = 2,
|
|
18
|
+
}: ChevronDownIconProps) {
|
|
19
|
+
return (
|
|
20
|
+
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none">
|
|
21
|
+
<Path
|
|
22
|
+
d={CHEVRON_DOWN_PATH}
|
|
23
|
+
stroke={color}
|
|
24
|
+
strokeWidth={strokeWidth}
|
|
25
|
+
strokeLinecap="round"
|
|
26
|
+
strokeLinejoin="round"
|
|
27
|
+
/>
|
|
28
|
+
</Svg>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CHEVRON_DOWN_PATH } from "./chevronDownPath";
|
|
2
|
+
import { colors } from "../../theme";
|
|
3
|
+
|
|
4
|
+
interface ChevronDownIconProps {
|
|
5
|
+
size?: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
strokeWidth?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Web / Storybook — plain SVG (no react-native-svg). */
|
|
11
|
+
export function ChevronDownIcon({
|
|
12
|
+
size = 20,
|
|
13
|
+
color = colors.primary,
|
|
14
|
+
strokeWidth = 2,
|
|
15
|
+
}: ChevronDownIconProps) {
|
|
16
|
+
return (
|
|
17
|
+
<svg
|
|
18
|
+
width={size}
|
|
19
|
+
height={size}
|
|
20
|
+
viewBox="0 0 20 20"
|
|
21
|
+
fill="none"
|
|
22
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
23
|
+
aria-hidden
|
|
24
|
+
>
|
|
25
|
+
<path
|
|
26
|
+
d={CHEVRON_DOWN_PATH}
|
|
27
|
+
stroke={color}
|
|
28
|
+
strokeWidth={strokeWidth}
|
|
29
|
+
strokeLinecap="round"
|
|
30
|
+
strokeLinejoin="round"
|
|
31
|
+
/>
|
|
32
|
+
</svg>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { CHEVRON_DOWN_PATH } from "./chevronDownPath";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ChevronDownIcon, CHEVRON_DOWN_PATH } from "./ChevronDownIcon";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Svg, { Path } from "react-native-svg";
|
|
2
|
+
import { SEARCH_CIRCLE_PATH, SEARCH_HANDLE_PATH } from "./searchPath";
|
|
3
|
+
import { colors } from "../../theme";
|
|
4
|
+
|
|
5
|
+
export { SEARCH_CIRCLE_PATH, SEARCH_HANDLE_PATH } from "./searchPath";
|
|
6
|
+
|
|
7
|
+
interface SearchIconProps {
|
|
8
|
+
size?: number;
|
|
9
|
+
color?: string;
|
|
10
|
+
strokeWidth?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Native — react-native-svg (peer dependency). */
|
|
14
|
+
export function SearchIcon({
|
|
15
|
+
size = 20,
|
|
16
|
+
color = colors.primary,
|
|
17
|
+
strokeWidth = 2,
|
|
18
|
+
}: SearchIconProps) {
|
|
19
|
+
return (
|
|
20
|
+
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none">
|
|
21
|
+
<Path
|
|
22
|
+
d={SEARCH_CIRCLE_PATH}
|
|
23
|
+
stroke={color}
|
|
24
|
+
strokeWidth={strokeWidth}
|
|
25
|
+
strokeLinecap="round"
|
|
26
|
+
strokeLinejoin="round"
|
|
27
|
+
/>
|
|
28
|
+
<Path
|
|
29
|
+
d={SEARCH_HANDLE_PATH}
|
|
30
|
+
stroke={color}
|
|
31
|
+
strokeWidth={strokeWidth}
|
|
32
|
+
strokeLinecap="round"
|
|
33
|
+
strokeLinejoin="round"
|
|
34
|
+
/>
|
|
35
|
+
</Svg>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SEARCH_CIRCLE_PATH, SEARCH_HANDLE_PATH } from "./searchPath";
|
|
2
|
+
import { colors } from "../../theme";
|
|
3
|
+
|
|
4
|
+
interface SearchIconProps {
|
|
5
|
+
size?: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
strokeWidth?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Web / Storybook — plain SVG (no react-native-svg). */
|
|
11
|
+
export function SearchIcon({
|
|
12
|
+
size = 20,
|
|
13
|
+
color = colors.primary,
|
|
14
|
+
strokeWidth = 2,
|
|
15
|
+
}: SearchIconProps) {
|
|
16
|
+
return (
|
|
17
|
+
<svg
|
|
18
|
+
width={size}
|
|
19
|
+
height={size}
|
|
20
|
+
viewBox="0 0 20 20"
|
|
21
|
+
fill="none"
|
|
22
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
23
|
+
aria-hidden
|
|
24
|
+
>
|
|
25
|
+
<path
|
|
26
|
+
d={SEARCH_CIRCLE_PATH}
|
|
27
|
+
stroke={color}
|
|
28
|
+
strokeWidth={strokeWidth}
|
|
29
|
+
strokeLinecap="round"
|
|
30
|
+
strokeLinejoin="round"
|
|
31
|
+
/>
|
|
32
|
+
<path
|
|
33
|
+
d={SEARCH_HANDLE_PATH}
|
|
34
|
+
stroke={color}
|
|
35
|
+
strokeWidth={strokeWidth}
|
|
36
|
+
strokeLinecap="round"
|
|
37
|
+
strokeLinejoin="round"
|
|
38
|
+
/>
|
|
39
|
+
</svg>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { SEARCH_CIRCLE_PATH, SEARCH_HANDLE_PATH } from "./searchPath";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SearchIcon, SEARCH_CIRCLE_PATH, SEARCH_HANDLE_PATH } from "./SearchIcon";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Search (magnifying glass) paths — 20×20 viewBox. */
|
|
2
|
+
export const SEARCH_CIRCLE_PATH =
|
|
3
|
+
"M9.16667 15.8333C12.8486 15.8333 15.8333 12.8486 15.8333 9.16667C15.8333 5.48477 12.8486 2.5 9.16667 2.5C5.48477 2.5 2.5 5.48477 2.5 9.16667C2.5 12.8486 5.48477 15.8333 9.16667 15.8333Z";
|
|
4
|
+
|
|
5
|
+
export const SEARCH_HANDLE_PATH = "M17.5 17.5L13.875 13.875";
|
package/src/icons/index.ts
CHANGED
|
@@ -10,7 +10,9 @@ export { BagIcon } from "./Bag";
|
|
|
10
10
|
export { BellIcon } from "./Bell";
|
|
11
11
|
export { BuildingIcon } from "./Building";
|
|
12
12
|
export { CameraIcon } from "./Camera";
|
|
13
|
+
export { CheckIcon } from "./Check";
|
|
13
14
|
export { CheckBadgeIcon } from "./CheckBadge";
|
|
15
|
+
export { ChevronDownIcon } from "./ChevronDown";
|
|
14
16
|
export { ClockIcon } from "./Clock";
|
|
15
17
|
export { FacebookIcon } from "./Facebook";
|
|
16
18
|
export { HomeIcon } from "./Home";
|
|
@@ -20,5 +22,6 @@ export { LinkedInIcon } from "./LinkedIn";
|
|
|
20
22
|
export { MailIcon } from "./Mail";
|
|
21
23
|
export { NavigateIcon } from "./Navigate";
|
|
22
24
|
export { PhoneIcon } from "./Phone";
|
|
25
|
+
export { SearchIcon } from "./Search";
|
|
23
26
|
export { ShowIcon } from "./Show";
|
|
24
27
|
export { UserIcon } from "./User";
|
package/src/icons/registry.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { BagIcon } from "./Bag";
|
|
|
3
3
|
import { BellIcon } from "./Bell";
|
|
4
4
|
import { BuildingIcon } from "./Building";
|
|
5
5
|
import { CameraIcon } from "./Camera";
|
|
6
|
+
import { CheckIcon } from "./Check";
|
|
6
7
|
import { CheckBadgeIcon } from "./CheckBadge";
|
|
8
|
+
import { ChevronDownIcon } from "./ChevronDown";
|
|
7
9
|
import { ClockIcon } from "./Clock";
|
|
8
10
|
import { FacebookIcon } from "./Facebook";
|
|
9
11
|
import { HomeIcon } from "./Home";
|
|
@@ -13,6 +15,7 @@ import { LinkedInIcon } from "./LinkedIn";
|
|
|
13
15
|
import { MailIcon } from "./Mail";
|
|
14
16
|
import { NavigateIcon } from "./Navigate";
|
|
15
17
|
import { PhoneIcon } from "./Phone";
|
|
18
|
+
import { SearchIcon } from "./Search";
|
|
16
19
|
import { ShowIcon } from "./Show";
|
|
17
20
|
import { UserIcon } from "./User";
|
|
18
21
|
import type { IconComponent } from "./types";
|
|
@@ -23,7 +26,9 @@ export const icons = {
|
|
|
23
26
|
bell: BellIcon,
|
|
24
27
|
building: BuildingIcon,
|
|
25
28
|
camera: CameraIcon,
|
|
29
|
+
check: CheckIcon,
|
|
26
30
|
checkBadge: CheckBadgeIcon,
|
|
31
|
+
chevronDown: ChevronDownIcon,
|
|
27
32
|
clock: ClockIcon,
|
|
28
33
|
facebook: FacebookIcon,
|
|
29
34
|
home: HomeIcon,
|
|
@@ -33,6 +38,7 @@ export const icons = {
|
|
|
33
38
|
mail: MailIcon,
|
|
34
39
|
navigate: NavigateIcon,
|
|
35
40
|
phone: PhoneIcon,
|
|
41
|
+
search: SearchIcon,
|
|
36
42
|
show: ShowIcon,
|
|
37
43
|
user: UserIcon,
|
|
38
44
|
} as const satisfies Record<string, IconComponent>;
|
|
@@ -42,8 +48,8 @@ export type IconName = keyof typeof icons;
|
|
|
42
48
|
export const iconNames = Object.keys(icons) as IconName[];
|
|
43
49
|
|
|
44
50
|
export const iconGroups = {
|
|
45
|
-
navigation: ["arrowRight", "home", "navigate"],
|
|
46
|
-
actions: ["show", "bell", "camera", "key", "checkBadge"],
|
|
51
|
+
navigation: ["arrowRight", "chevronDown", "home", "navigate"],
|
|
52
|
+
actions: ["show", "bell", "camera", "key", "check", "checkBadge", "search"],
|
|
47
53
|
objects: ["bag", "building", "clock", "user"],
|
|
48
54
|
communication: ["mail", "phone"],
|
|
49
55
|
social: ["facebook", "instagram", "linkedin"],
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
export { Button, Input } from "./components";
|
|
1
|
+
export { Button, Checkbox, Input, Select, Textarea, Toggle } from "./components";
|
|
2
2
|
export type {
|
|
3
3
|
ButtonProps,
|
|
4
4
|
ButtonSize,
|
|
5
5
|
ButtonVariant,
|
|
6
|
+
CheckboxProps,
|
|
7
|
+
CheckboxVariant,
|
|
6
8
|
InputProps,
|
|
7
9
|
InputSize,
|
|
8
|
-
|
|
10
|
+
SelectOption,
|
|
11
|
+
SelectProps,
|
|
12
|
+
SelectSingleProps,
|
|
13
|
+
SelectMultipleProps,
|
|
14
|
+
TextareaProps,
|
|
15
|
+
ToggleProps,
|
|
9
16
|
} from "./components";
|
|
10
17
|
|
|
11
18
|
export {
|
|
@@ -20,7 +27,9 @@ export {
|
|
|
20
27
|
BellIcon,
|
|
21
28
|
BuildingIcon,
|
|
22
29
|
CameraIcon,
|
|
30
|
+
CheckIcon,
|
|
23
31
|
CheckBadgeIcon,
|
|
32
|
+
ChevronDownIcon,
|
|
24
33
|
ClockIcon,
|
|
25
34
|
FacebookIcon,
|
|
26
35
|
HomeIcon,
|
|
@@ -30,10 +39,19 @@ export {
|
|
|
30
39
|
MailIcon,
|
|
31
40
|
NavigateIcon,
|
|
32
41
|
PhoneIcon,
|
|
42
|
+
SearchIcon,
|
|
33
43
|
ShowIcon,
|
|
34
44
|
UserIcon,
|
|
35
45
|
} from "./icons";
|
|
36
46
|
export type { IconProps, IconName, IconGroup, IconComponent, IconByNameProps } from "./icons";
|
|
37
47
|
|
|
38
|
-
export {
|
|
48
|
+
export {
|
|
49
|
+
colors,
|
|
50
|
+
grey,
|
|
51
|
+
buttonTypography,
|
|
52
|
+
inputTypography,
|
|
53
|
+
selectTypography,
|
|
54
|
+
textareaTypography,
|
|
55
|
+
fonts,
|
|
56
|
+
} from "./theme";
|
|
39
57
|
export type { GreyStep } from "./theme";
|
package/src/theme/index.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export { colors, grey } from "./colors";
|
|
2
2
|
export type { GreyStep } from "./colors";
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export {
|
|
5
|
+
fonts,
|
|
6
|
+
buttonTypography,
|
|
7
|
+
inputTypography,
|
|
8
|
+
selectTypography,
|
|
9
|
+
textareaTypography,
|
|
10
|
+
} from "./typography";
|
package/src/theme/typography.ts
CHANGED
|
@@ -26,9 +26,34 @@ export const inputTypography = {
|
|
|
26
26
|
fontFamily: fonts.sans,
|
|
27
27
|
fontSize: 12,
|
|
28
28
|
fontWeight: "500" as const,
|
|
29
|
-
lineHeight:
|
|
29
|
+
lineHeight: 12,
|
|
30
|
+
letterSpacing: 0.36,
|
|
31
|
+
},
|
|
32
|
+
field: {
|
|
33
|
+
fontFamily: fonts.sans,
|
|
34
|
+
fontSize: 14,
|
|
35
|
+
fontWeight: "400" as const,
|
|
36
|
+
lineHeight: 19,
|
|
30
37
|
letterSpacing: 0,
|
|
31
38
|
},
|
|
39
|
+
hint: {
|
|
40
|
+
fontFamily: fonts.sans,
|
|
41
|
+
fontSize: 12,
|
|
42
|
+
fontWeight: "400" as const,
|
|
43
|
+
lineHeight: 12,
|
|
44
|
+
letterSpacing: 0.36,
|
|
45
|
+
},
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
/** Select label / field / hint typography — Medium/Regular 12–14, letter-spacing 3%. */
|
|
49
|
+
export const selectTypography = {
|
|
50
|
+
label: {
|
|
51
|
+
fontFamily: fonts.sans,
|
|
52
|
+
fontSize: 12,
|
|
53
|
+
fontWeight: "500" as const,
|
|
54
|
+
lineHeight: 12,
|
|
55
|
+
letterSpacing: 0.36,
|
|
56
|
+
},
|
|
32
57
|
field: {
|
|
33
58
|
fontFamily: fonts.sans,
|
|
34
59
|
fontSize: 14,
|
|
@@ -40,7 +65,32 @@ export const inputTypography = {
|
|
|
40
65
|
fontFamily: fonts.sans,
|
|
41
66
|
fontSize: 12,
|
|
42
67
|
fontWeight: "400" as const,
|
|
43
|
-
lineHeight:
|
|
68
|
+
lineHeight: 12,
|
|
69
|
+
letterSpacing: 0.36,
|
|
70
|
+
},
|
|
71
|
+
} as const;
|
|
72
|
+
|
|
73
|
+
/** Textarea label / field / hint typography — Medium/Regular 12–14, letter-spacing 3%. */
|
|
74
|
+
export const textareaTypography = {
|
|
75
|
+
label: {
|
|
76
|
+
fontFamily: fonts.sans,
|
|
77
|
+
fontSize: 12,
|
|
78
|
+
fontWeight: "500" as const,
|
|
79
|
+
lineHeight: 12,
|
|
80
|
+
letterSpacing: 0.36,
|
|
81
|
+
},
|
|
82
|
+
field: {
|
|
83
|
+
fontFamily: fonts.sans,
|
|
84
|
+
fontSize: 14,
|
|
85
|
+
fontWeight: "400" as const,
|
|
86
|
+
lineHeight: 19,
|
|
44
87
|
letterSpacing: 0,
|
|
45
88
|
},
|
|
89
|
+
hint: {
|
|
90
|
+
fontFamily: fonts.sans,
|
|
91
|
+
fontSize: 12,
|
|
92
|
+
fontWeight: "400" as const,
|
|
93
|
+
lineHeight: 12,
|
|
94
|
+
letterSpacing: 0.36,
|
|
95
|
+
},
|
|
46
96
|
} as const;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ForwardedRef, MutableRefObject, RefCallback } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Combines a component's internal ref (used e.g. by `useApplyWebClassName`)
|
|
5
|
+
* with an optional externally-forwarded ref, so consumers can still call
|
|
6
|
+
* `.focus()`/`.measure()` on the underlying native node via `ref`.
|
|
7
|
+
*/
|
|
8
|
+
export function mergeRefs<T>(
|
|
9
|
+
internalRef: MutableRefObject<T | null>,
|
|
10
|
+
forwardedRef: ForwardedRef<T>,
|
|
11
|
+
): RefCallback<T> {
|
|
12
|
+
return (node) => {
|
|
13
|
+
internalRef.current = node;
|
|
14
|
+
if (typeof forwardedRef === "function") {
|
|
15
|
+
forwardedRef(node);
|
|
16
|
+
} else if (forwardedRef) {
|
|
17
|
+
forwardedRef.current = node;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+Armenian:wght@400;500;600;700&display=swap");
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--font-sans: "Noto Sans Armenian", ui-sans-serif, system-ui, sans-serif;
|
|
3
|
+
}
|
|
4
|
+
|
|
1
5
|
@layer components {
|
|
2
6
|
.typography-button-lg {
|
|
3
|
-
font-family: var(--font-sans
|
|
7
|
+
font-family: var(--font-sans);
|
|
4
8
|
font-size: 14px;
|
|
5
9
|
font-weight: 600;
|
|
6
10
|
line-height: 100%;
|
|
@@ -8,7 +12,7 @@
|
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
.typography-button-sm {
|
|
11
|
-
font-family: var(--font-sans
|
|
15
|
+
font-family: var(--font-sans);
|
|
12
16
|
font-size: 12px;
|
|
13
17
|
font-weight: 600;
|
|
14
18
|
line-height: 100%;
|