@ecohouse/ui 0.1.32 → 0.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/index.cjs +796 -509
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +74 -8
  4. package/dist/index.d.ts +74 -8
  5. package/dist/index.js +729 -448
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/components/DatePicker/DatePicker.tsx +115 -45
  9. package/src/components/Select/Select.tsx +5 -2
  10. package/src/components/Sidebar/Sidebar.tsx +25 -11
  11. package/src/components/StepPager/StepPager.tsx +150 -0
  12. package/src/components/StepPager/index.ts +2 -0
  13. package/src/components/index.ts +3 -0
  14. package/src/icons/Ban/BanIcon.tsx +15 -0
  15. package/src/icons/Ban/banPath.ts +2 -0
  16. package/src/icons/Ban/index.ts +1 -0
  17. package/src/icons/Fullscreen/FullscreenIcon.tsx +21 -0
  18. package/src/icons/Fullscreen/fullscreenPath.ts +2 -0
  19. package/src/icons/Fullscreen/index.ts +1 -0
  20. package/src/icons/Home/homePath.ts +1 -1
  21. package/src/icons/Sort/SortIcon.tsx +3 -3
  22. package/src/icons/Sort/SortIcon.web.tsx +2 -2
  23. package/src/icons/Sort/sortPath.ts +3 -2
  24. package/src/icons/VideoOff/VideoOffIcon.tsx +21 -0
  25. package/src/icons/VideoOff/VideoOffIcon.web.tsx +27 -0
  26. package/src/icons/VideoOff/index.ts +1 -0
  27. package/src/icons/VideoOff/videoOffPath.ts +2 -0
  28. package/src/icons/ZoomOut/ZoomOutIcon.tsx +21 -0
  29. package/src/icons/ZoomOut/index.ts +1 -0
  30. package/src/icons/ZoomOut/zoomOutPath.ts +2 -0
  31. package/src/icons/index.ts +4 -0
  32. package/src/icons/registry.ts +12 -0
  33. package/src/index.ts +8 -0
  34. package/src/theme/colors.test.ts +1 -1
  35. package/src/theme/typography.ts +4 -4
  36. package/src/utils/popoverAlign.ts +85 -0
@@ -0,0 +1,27 @@
1
+ import { VIDEO_OFF_PATH } from "./videoOffPath";
2
+ import { colors } from "../../theme";
3
+ import type { IconProps } from "../types";
4
+
5
+ /** Web / Storybook — plain SVG (no react-native-svg). */
6
+ export function VideoOffIcon({ size = 24, color = colors.primary, strokeWidth = 2 }: IconProps) {
7
+ return (
8
+ <svg
9
+ width={size}
10
+ height={size}
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ aria-hidden
15
+ >
16
+ <path
17
+ d={VIDEO_OFF_PATH}
18
+ stroke={color}
19
+ strokeWidth={strokeWidth}
20
+ strokeLinecap="round"
21
+ strokeLinejoin="round"
22
+ />
23
+ </svg>
24
+ );
25
+ }
26
+
27
+ export { VIDEO_OFF_PATH } from "./videoOffPath";
@@ -0,0 +1 @@
1
+ export { VideoOffIcon, VIDEO_OFF_PATH } from "./VideoOffIcon";
@@ -0,0 +1,2 @@
1
+ export const VIDEO_OFF_PATH =
2
+ "M5 5C3.34315 5 2 6.34315 2 8V16C2 17.6569 3.34315 19 5 19H14C15.3527 19 16.4962 18.1048 16.8705 16.8745M17 12L20.6343 8.36569C21.0627 7.93731 21.2769 7.72312 21.4608 7.70865C21.6203 7.69609 21.7763 7.76068 21.8802 7.88238C22 8.02265 22 8.32556 22 8.93137V15.0686C22 15.6744 22 15.9774 21.8802 16.1176C21.7763 16.2393 21.6203 16.3039 21.4608 16.2914C21.2769 16.2769 21.0627 16.0627 20.6343 15.6343L17 12ZM17 12V9.8C17 8.11984 17 7.27976 16.673 6.63803C16.3854 6.07354 15.9265 5.6146 15.362 5.32698C14.7202 5 13.8802 5 12.2 5H9.5M2 2L22 22";
@@ -0,0 +1,21 @@
1
+ import Svg, { Path } from "react-native-svg";
2
+ import { colors } from "../../theme";
3
+ import type { IconProps } from "../types";
4
+ import { ZOOM_OUT_PATH } from "./zoomOutPath";
5
+
6
+ export { ZOOM_OUT_PATH } from "./zoomOutPath";
7
+
8
+ /** Exit-fullscreen / zoom-out corners control (24×24 viewBox). */
9
+ export function ZoomOutIcon({ size = 24, color = colors.primary, strokeWidth = 2 }: IconProps) {
10
+ return (
11
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
12
+ <Path
13
+ d={ZOOM_OUT_PATH}
14
+ stroke={color}
15
+ strokeWidth={strokeWidth}
16
+ strokeLinecap="round"
17
+ strokeLinejoin="round"
18
+ />
19
+ </Svg>
20
+ );
21
+ }
@@ -0,0 +1 @@
1
+ export { ZoomOutIcon, ZOOM_OUT_PATH } from "./ZoomOutIcon";
@@ -0,0 +1,2 @@
1
+ export const ZOOM_OUT_PATH =
2
+ "M3 8H3.2C4.88016 8 5.72024 8 6.36197 7.67302C6.92646 7.3854 7.3854 6.92646 7.67302 6.36197C8 5.72024 8 4.88016 8 3.2V3M3 16H3.2C4.88016 16 5.72024 16 6.36197 16.327C6.92646 16.6146 7.3854 17.0735 7.67302 17.638C8 18.2798 8 19.1198 8 20.8V21M16 3V3.2C16 4.88016 16 5.72024 16.327 6.36197C16.6146 6.92646 17.0735 7.3854 17.638 7.67302C18.2798 8 19.1198 8 20.8 8H21M16 21V20.8C16 19.1198 16 18.2798 16.327 17.638C16.6146 17.0735 17.0735 16.6146 17.638 16.327C18.2798 16 19.1198 16 20.8 16H21";
@@ -11,6 +11,7 @@ export { AlertTriangleIcon } from "./AlertTriangle";
11
11
  export { AppleIcon } from "./Store";
12
12
  export { ArrowRightIcon } from "./ArrowRight";
13
13
  export { BagIcon } from "./Bag";
14
+ export { BanIcon } from "./Ban";
14
15
  export { BellIcon } from "./Bell";
15
16
  export { BuildingIcon } from "./Building";
16
17
  export { CalendarIcon } from "./Calendar";
@@ -45,6 +46,7 @@ export {
45
46
  export { QuietHoursIcon, NoSmokingIcon, PawIcon, TrashIcon } from "./HouseRules";
46
47
  export { FacebookIcon } from "./Facebook";
47
48
  export { FiltersIcon } from "./Filters";
49
+ export { FullscreenIcon } from "./Fullscreen";
48
50
  export { HeartIcon } from "./Heart";
49
51
  export { GlobeIcon } from "./Globe";
50
52
  export { GooglePlayIcon } from "./Store";
@@ -80,4 +82,6 @@ export { StarFilledIcon } from "./StarFilled";
80
82
  export { UserIcon } from "./User";
81
83
  export { UsersAltIcon } from "./UsersAlt";
82
84
  export { VideoIcon } from "./Video";
85
+ export { VideoOffIcon } from "./VideoOff";
86
+ export { ZoomOutIcon } from "./ZoomOut";
83
87
  export type { StarIconProps } from "./Star";
@@ -2,6 +2,7 @@ import { ArrowRightIcon } from "./ArrowRight";
2
2
  import { AlertTriangleIcon } from "./AlertTriangle";
3
3
  import { AppleIcon, GooglePlayIcon } from "./Store";
4
4
  import { BagIcon } from "./Bag";
5
+ import { BanIcon } from "./Ban";
5
6
  import { BellIcon } from "./Bell";
6
7
  import { BuildingIcon } from "./Building";
7
8
  import { CalendarIcon } from "./Calendar";
@@ -36,6 +37,7 @@ import {
36
37
  import { NoSmokingIcon, PawIcon, QuietHoursIcon, TrashIcon } from "./HouseRules";
37
38
  import { FacebookIcon } from "./Facebook";
38
39
  import { FiltersIcon } from "./Filters";
40
+ import { FullscreenIcon } from "./Fullscreen";
39
41
  import { HeartIcon } from "./Heart";
40
42
  import { GlobeIcon } from "./Globe";
41
43
  import { HelpCircleIcon } from "./HelpCircle";
@@ -69,6 +71,8 @@ import { StarFilledIcon } from "./StarFilled";
69
71
  import { UserIcon } from "./User";
70
72
  import { UsersAltIcon } from "./UsersAlt";
71
73
  import { VideoIcon } from "./Video";
74
+ import { VideoOffIcon } from "./VideoOff";
75
+ import { ZoomOutIcon } from "./ZoomOut";
72
76
  import type { IconComponent } from "./types";
73
77
 
74
78
  export const icons = {
@@ -77,6 +81,7 @@ export const icons = {
77
81
  apple: AppleIcon,
78
82
  arrowRight: ArrowRightIcon,
79
83
  bag: BagIcon,
84
+ ban: BanIcon,
80
85
  bell: BellIcon,
81
86
  building: BuildingIcon,
82
87
  calendar: CalendarIcon,
@@ -98,6 +103,7 @@ export const icons = {
98
103
  cardLocation: CardLocationIcon,
99
104
  facebook: FacebookIcon,
100
105
  filters: FiltersIcon,
106
+ fullscreen: FullscreenIcon,
101
107
  guests: GuestsIcon,
102
108
  heart: HeartIcon,
103
109
  globe: GlobeIcon,
@@ -143,7 +149,9 @@ export const icons = {
143
149
  user: UserIcon,
144
150
  usersAlt: UsersAltIcon,
145
151
  video: VideoIcon,
152
+ videoOff: VideoOffIcon,
146
153
  whatsApp: WhatsAppIcon,
154
+ zoomOut: ZoomOutIcon,
147
155
  } as const satisfies Record<string, IconComponent>;
148
156
 
149
157
  export type IconName = keyof typeof icons;
@@ -168,6 +176,7 @@ export const iconGroups = {
168
176
  actions: [
169
177
  "show",
170
178
  "alertTriangle",
179
+ "ban",
171
180
  "bell",
172
181
  "camera",
173
182
  "key",
@@ -185,7 +194,9 @@ export const iconGroups = {
185
194
  "saveHeart",
186
195
  "share",
187
196
  "filters",
197
+ "fullscreen",
188
198
  "heart",
199
+ "zoomOut",
189
200
  "star",
190
201
  "starFilled",
191
202
  "minus",
@@ -212,6 +223,7 @@ export const iconGroups = {
212
223
  "user",
213
224
  "usersAlt",
214
225
  "video",
226
+ "videoOff",
215
227
  "whatsApp",
216
228
  ],
217
229
  communication: ["mail", "phone"],
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ export {
5
5
  Badge,
6
6
  StatusBadge,
7
7
  PaginationDots,
8
+ StepPager,
8
9
  InfoTile,
9
10
  StepList,
10
11
  Counter,
@@ -36,6 +37,7 @@ export type {
36
37
  StatusBadgeProps,
37
38
  StatusBadgeTone,
38
39
  PaginationDotsProps,
40
+ StepPagerProps,
39
41
  InfoTileProps,
40
42
  StepListProps,
41
43
  CounterProps,
@@ -106,6 +108,7 @@ export {
106
108
  getIconsByGroup,
107
109
  ArrowRightIcon,
108
110
  BagIcon,
111
+ BanIcon,
109
112
  BellIcon,
110
113
  BuildingIcon,
111
114
  CalendarIcon,
@@ -139,6 +142,7 @@ export {
139
142
  TrashIcon,
140
143
  FacebookIcon,
141
144
  FiltersIcon,
145
+ FullscreenIcon,
142
146
  HeartIcon,
143
147
  GlobeIcon,
144
148
  GooglePlayIcon,
@@ -174,6 +178,8 @@ export {
174
178
  UserIcon,
175
179
  UsersAltIcon,
176
180
  VideoIcon,
181
+ VideoOffIcon,
182
+ ZoomOutIcon,
177
183
  } from "./icons";
178
184
  export type {
179
185
  IconProps,
@@ -208,3 +214,5 @@ export {
208
214
  export type { GreyStep } from "./theme";
209
215
 
210
216
  export { abbreviateMonthName, formatDate, formatDateDayShortMonth } from "./utils/dateUtils";
217
+ export { resolvePopoverAlign } from "./utils/popoverAlign";
218
+ export type { PopoverAlign, ResolvePopoverAlignOptions } from "./utils/popoverAlign";
@@ -30,7 +30,7 @@ describe("design tokens", () => {
30
30
  fontSize: 12,
31
31
  fontWeight: "400",
32
32
  letterSpacing: 0.36,
33
- lineHeight: 12,
33
+ lineHeight: 16,
34
34
  };
35
35
 
36
36
  expect(inputTypography.field).toMatchObject(fieldTypography);
@@ -119,7 +119,7 @@ export const inputTypography = {
119
119
  fontFamily: fonts.sans,
120
120
  fontSize: 12,
121
121
  fontWeight: "400" as const,
122
- lineHeight: 12,
122
+ lineHeight: 16,
123
123
  letterSpacing: 0.36,
124
124
  },
125
125
  hint: {
@@ -144,7 +144,7 @@ export const selectTypography = {
144
144
  fontFamily: fonts.sans,
145
145
  fontSize: 12,
146
146
  fontWeight: "400" as const,
147
- lineHeight: 12,
147
+ lineHeight: 16,
148
148
  letterSpacing: 0.36,
149
149
  },
150
150
  hint: {
@@ -169,7 +169,7 @@ export const avatarTypography = {
169
169
  fontFamily: fonts.sans,
170
170
  fontSize: 12,
171
171
  fontWeight: "400" as const,
172
- lineHeight: 12,
172
+ lineHeight: 14,
173
173
  letterSpacing: 0,
174
174
  },
175
175
  menuItem: {
@@ -255,7 +255,7 @@ export const textareaTypography = {
255
255
  fontFamily: fonts.sans,
256
256
  fontSize: 12,
257
257
  fontWeight: "400" as const,
258
- lineHeight: 12,
258
+ lineHeight: 16,
259
259
  letterSpacing: 0.36,
260
260
  },
261
261
  hint: {
@@ -0,0 +1,85 @@
1
+ export type PopoverAlign = "center" | "start" | "end";
2
+
3
+ export type ResolvePopoverAlignOptions = {
4
+ /** Trigger element bounds in viewport coordinates. */
5
+ triggerRect: Pick<DOMRect, "left" | "right" | "width">;
6
+ /** Popover panel width in px. */
7
+ panelWidth: number;
8
+ /** Viewport width in px. */
9
+ viewportWidth: number;
10
+ /** Minimum gap from the viewport edges. Defaults to 8. */
11
+ padding?: number;
12
+ /**
13
+ * `auto` (default): prefer center, then end (opens left), then start (opens right).
14
+ * Fixed values force that alignment.
15
+ */
16
+ preferred?: PopoverAlign | "auto";
17
+ };
18
+
19
+ function fitsCenter(
20
+ triggerRect: Pick<DOMRect, "left" | "width">,
21
+ panelWidth: number,
22
+ viewportWidth: number,
23
+ padding: number,
24
+ ) {
25
+ const centerX = triggerRect.left + triggerRect.width / 2;
26
+ const left = centerX - panelWidth / 2;
27
+ const right = centerX + panelWidth / 2;
28
+ return left >= padding && right <= viewportWidth - padding;
29
+ }
30
+
31
+ function fitsEnd(triggerRect: Pick<DOMRect, "right">, panelWidth: number, padding: number) {
32
+ return triggerRect.right - panelWidth >= padding;
33
+ }
34
+
35
+ function fitsStart(
36
+ triggerRect: Pick<DOMRect, "left">,
37
+ panelWidth: number,
38
+ viewportWidth: number,
39
+ padding: number,
40
+ ) {
41
+ return triggerRect.left + panelWidth <= viewportWidth - padding;
42
+ }
43
+
44
+ /**
45
+ * Picks horizontal popover alignment so the panel stays in view.
46
+ * Preference for `auto`: center → start (rightward) → end (leftward)
47
+ * when the trigger sits near the left edge (common for card actions).
48
+ */
49
+ export function resolvePopoverAlign({
50
+ triggerRect,
51
+ panelWidth,
52
+ viewportWidth,
53
+ padding = 8,
54
+ preferred = "auto",
55
+ }: ResolvePopoverAlignOptions): PopoverAlign {
56
+ if (preferred !== "auto") {
57
+ return preferred;
58
+ }
59
+
60
+ if (fitsCenter(triggerRect, panelWidth, viewportWidth, padding)) {
61
+ return "center";
62
+ }
63
+
64
+ const spaceLeft = triggerRect.right - padding;
65
+ const spaceRight = viewportWidth - padding - triggerRect.left;
66
+
67
+ // Prefer opening toward the side with more room.
68
+ if (spaceRight >= spaceLeft) {
69
+ if (fitsStart(triggerRect, panelWidth, viewportWidth, padding)) {
70
+ return "start";
71
+ }
72
+ if (fitsEnd(triggerRect, panelWidth, padding)) {
73
+ return "end";
74
+ }
75
+ } else {
76
+ if (fitsEnd(triggerRect, panelWidth, padding)) {
77
+ return "end";
78
+ }
79
+ if (fitsStart(triggerRect, panelWidth, viewportWidth, padding)) {
80
+ return "start";
81
+ }
82
+ }
83
+
84
+ return spaceRight >= spaceLeft ? "start" : "end";
85
+ }