@ecohouse/ui 0.1.31 → 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 (94) hide show
  1. package/README.md +5 -0
  2. package/dist/index.cjs +1594 -523
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +218 -10
  5. package/dist/index.d.ts +218 -10
  6. package/dist/index.js +1516 -471
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/components/AccountHeader/AccountHeader.stories.tsx +70 -0
  10. package/src/components/AccountHeader/AccountHeader.tsx +224 -0
  11. package/src/components/AccountHeader/index.ts +2 -0
  12. package/src/components/AvatarSimple/AvatarSimple.tsx +2 -2
  13. package/src/components/Button/Button.tsx +4 -1
  14. package/src/components/DatePicker/DatePicker.tsx +129 -54
  15. package/src/components/FloatingActionButton/FloatingActionButton.stories.tsx +42 -0
  16. package/src/components/FloatingActionButton/FloatingActionButton.tsx +77 -0
  17. package/src/components/FloatingActionButton/index.ts +2 -0
  18. package/src/components/InfoTile/InfoTile.stories.tsx +80 -0
  19. package/src/components/InfoTile/InfoTile.tsx +118 -0
  20. package/src/components/InfoTile/index.ts +2 -0
  21. package/src/components/PaginationDots/PaginationDots.stories.tsx +48 -0
  22. package/src/components/PaginationDots/PaginationDots.tsx +111 -0
  23. package/src/components/PaginationDots/index.ts +2 -0
  24. package/src/components/Select/Select.tsx +5 -2
  25. package/src/components/Sidebar/Sidebar.tsx +25 -11
  26. package/src/components/StatusBadge/StatusBadge.stories.tsx +54 -0
  27. package/src/components/StatusBadge/StatusBadge.tsx +108 -0
  28. package/src/components/StatusBadge/index.ts +2 -0
  29. package/src/components/StepList/StepList.stories.tsx +37 -0
  30. package/src/components/StepList/StepList.tsx +152 -0
  31. package/src/components/StepList/index.ts +2 -0
  32. package/src/components/StepPager/StepPager.tsx +150 -0
  33. package/src/components/StepPager/index.ts +2 -0
  34. package/src/components/index.ts +21 -0
  35. package/src/icons/AlertTriangle/AlertTriangleIcon.tsx +19 -0
  36. package/src/icons/AlertTriangle/AlertTriangleIcon.web.tsx +18 -0
  37. package/src/icons/AlertTriangle/alertTrianglePath.ts +3 -0
  38. package/src/icons/AlertTriangle/index.ts +1 -0
  39. package/src/icons/Ban/BanIcon.tsx +15 -0
  40. package/src/icons/Ban/banPath.ts +2 -0
  41. package/src/icons/Ban/index.ts +1 -0
  42. package/src/icons/Bell/BellIcon.tsx +2 -2
  43. package/src/icons/Bell/BellIcon.web.tsx +2 -2
  44. package/src/icons/Bell/bellPath.ts +1 -1
  45. package/src/icons/CottageDetail/CottageDetailIcons.tsx +15 -0
  46. package/src/icons/CottageDetail/CottageDetailIcons.web.tsx +15 -0
  47. package/src/icons/CottageDetail/cottageDetailPaths.ts +3 -0
  48. package/src/icons/CottageDetail/index.ts +1 -0
  49. package/src/icons/Edit/EditIcon.tsx +20 -0
  50. package/src/icons/Edit/EditIcon.web.tsx +19 -0
  51. package/src/icons/Edit/editPath.ts +3 -0
  52. package/src/icons/Edit/index.ts +1 -0
  53. package/src/icons/Fullscreen/FullscreenIcon.tsx +21 -0
  54. package/src/icons/Fullscreen/fullscreenPath.ts +2 -0
  55. package/src/icons/Fullscreen/index.ts +1 -0
  56. package/src/icons/Home/homePath.ts +1 -1
  57. package/src/icons/HouseRules/HouseRulesIcons.tsx +62 -0
  58. package/src/icons/HouseRules/HouseRulesIcons.web.tsx +61 -0
  59. package/src/icons/HouseRules/houseRulesPaths.ts +24 -0
  60. package/src/icons/HouseRules/index.ts +2 -0
  61. package/src/icons/LocationUser/LocationUserIcon.tsx +15 -0
  62. package/src/icons/LocationUser/LocationUserIcon.web.tsx +14 -0
  63. package/src/icons/LocationUser/index.ts +1 -0
  64. package/src/icons/LocationUser/locationUserPath.ts +2 -0
  65. package/src/icons/Lock/LockIcon.tsx +21 -0
  66. package/src/icons/Lock/LockIcon.web.tsx +26 -0
  67. package/src/icons/Lock/index.ts +1 -0
  68. package/src/icons/Lock/lockPath.ts +3 -0
  69. package/src/icons/Refresh/RefreshIcon.tsx +20 -0
  70. package/src/icons/Refresh/RefreshIcon.web.tsx +19 -0
  71. package/src/icons/Refresh/index.ts +1 -0
  72. package/src/icons/Refresh/refreshPath.ts +3 -0
  73. package/src/icons/RefundStatus/RefundStatusIcon.tsx +24 -0
  74. package/src/icons/RefundStatus/RefundStatusIcon.web.tsx +23 -0
  75. package/src/icons/RefundStatus/index.ts +1 -0
  76. package/src/icons/RefundStatus/refundStatusPath.ts +3 -0
  77. package/src/icons/Sort/SortIcon.tsx +3 -3
  78. package/src/icons/Sort/SortIcon.web.tsx +2 -2
  79. package/src/icons/Sort/sortPath.ts +3 -2
  80. package/src/icons/VideoOff/VideoOffIcon.tsx +21 -0
  81. package/src/icons/VideoOff/VideoOffIcon.web.tsx +27 -0
  82. package/src/icons/VideoOff/index.ts +1 -0
  83. package/src/icons/VideoOff/videoOffPath.ts +2 -0
  84. package/src/icons/ZoomOut/ZoomOutIcon.tsx +21 -0
  85. package/src/icons/ZoomOut/index.ts +1 -0
  86. package/src/icons/ZoomOut/zoomOutPath.ts +2 -0
  87. package/src/icons/index.ts +12 -0
  88. package/src/icons/registry.ts +42 -0
  89. package/src/index.ts +34 -0
  90. package/src/theme/colors.test.ts +1 -1
  91. package/src/theme/colors.ts +4 -0
  92. package/src/theme/typography.ts +5 -5
  93. package/src/utils/dateUtils.ts +25 -0
  94. package/src/utils/popoverAlign.ts +85 -0
@@ -7,9 +7,11 @@ export { Icon } from "./Icon";
7
7
 
8
8
  export { AmenityIcon } from "./Amenity";
9
9
  export type { AmenityIconProps, AmenityName } from "./Amenity";
10
+ export { AlertTriangleIcon } from "./AlertTriangle";
10
11
  export { AppleIcon } from "./Store";
11
12
  export { ArrowRightIcon } from "./ArrowRight";
12
13
  export { BagIcon } from "./Bag";
14
+ export { BanIcon } from "./Ban";
13
15
  export { BellIcon } from "./Bell";
14
16
  export { BuildingIcon } from "./Building";
15
17
  export { CalendarIcon } from "./Calendar";
@@ -21,6 +23,7 @@ export { ChevronDownIcon } from "./ChevronDown";
21
23
  export { ChevronLeftIcon } from "./ChevronLeft";
22
24
  export { ClockIcon } from "./Clock";
23
25
  export { CloseIcon } from "./Close";
26
+ export { EditIcon } from "./Edit";
24
27
  export {
25
28
  BathroomsIcon,
26
29
  BedroomsIcon,
@@ -34,13 +37,16 @@ export {
34
37
  CheckSuccessIcon,
35
38
  ClockFilledIcon,
36
39
  CopyIcon,
40
+ DownloadIcon,
37
41
  QrCodeIcon,
38
42
  ShareIcon,
39
43
  TooltipArrowIcon,
40
44
  WhatsAppIcon,
41
45
  } from "./CottageDetail";
46
+ export { QuietHoursIcon, NoSmokingIcon, PawIcon, TrashIcon } from "./HouseRules";
42
47
  export { FacebookIcon } from "./Facebook";
43
48
  export { FiltersIcon } from "./Filters";
49
+ export { FullscreenIcon } from "./Fullscreen";
44
50
  export { HeartIcon } from "./Heart";
45
51
  export { GlobeIcon } from "./Globe";
46
52
  export { GooglePlayIcon } from "./Store";
@@ -52,6 +58,8 @@ export { LayoutGridIcon } from "./LayoutGrid";
52
58
  export { LinkedInIcon } from "./LinkedIn";
53
59
  export { ListViewIcon } from "./ListView";
54
60
  export { LocationPinIcon } from "./LocationPin";
61
+ export { LocationUserIcon } from "./LocationUser";
62
+ export { LockIcon } from "./Lock";
55
63
  export { LogOutIcon } from "./LogOut";
56
64
  export { MailIcon } from "./Mail";
57
65
  export { MapViewIcon } from "./MapView";
@@ -62,6 +70,8 @@ export { NavigateIcon } from "./Navigate";
62
70
  export { PhoneIcon } from "./Phone";
63
71
  export { PlusIcon } from "./Plus";
64
72
  export { MinusIcon } from "./Minus";
73
+ export { RefreshIcon } from "./Refresh";
74
+ export { RefundStatusIcon } from "./RefundStatus";
65
75
  export { SearchIcon } from "./Search";
66
76
  export { SettingsIcon } from "./Settings";
67
77
  export { ShowIcon } from "./Show";
@@ -72,4 +82,6 @@ export { StarFilledIcon } from "./StarFilled";
72
82
  export { UserIcon } from "./User";
73
83
  export { UsersAltIcon } from "./UsersAlt";
74
84
  export { VideoIcon } from "./Video";
85
+ export { VideoOffIcon } from "./VideoOff";
86
+ export { ZoomOutIcon } from "./ZoomOut";
75
87
  export type { StarIconProps } from "./Star";
@@ -1,6 +1,8 @@
1
1
  import { ArrowRightIcon } from "./ArrowRight";
2
+ import { AlertTriangleIcon } from "./AlertTriangle";
2
3
  import { AppleIcon, GooglePlayIcon } from "./Store";
3
4
  import { BagIcon } from "./Bag";
5
+ import { BanIcon } from "./Ban";
4
6
  import { BellIcon } from "./Bell";
5
7
  import { BuildingIcon } from "./Building";
6
8
  import { CalendarIcon } from "./Calendar";
@@ -12,6 +14,7 @@ import { ChevronDownIcon } from "./ChevronDown";
12
14
  import { ChevronLeftIcon } from "./ChevronLeft";
13
15
  import { ClockIcon } from "./Clock";
14
16
  import { CloseIcon } from "./Close";
17
+ import { EditIcon } from "./Edit";
15
18
  import {
16
19
  BathroomsIcon,
17
20
  BedroomsIcon,
@@ -25,13 +28,16 @@ import {
25
28
  CheckSuccessIcon,
26
29
  ClockFilledIcon,
27
30
  CopyIcon,
31
+ DownloadIcon,
28
32
  QrCodeIcon,
29
33
  ShareIcon,
30
34
  TooltipArrowIcon,
31
35
  WhatsAppIcon,
32
36
  } from "./CottageDetail";
37
+ import { NoSmokingIcon, PawIcon, QuietHoursIcon, TrashIcon } from "./HouseRules";
33
38
  import { FacebookIcon } from "./Facebook";
34
39
  import { FiltersIcon } from "./Filters";
40
+ import { FullscreenIcon } from "./Fullscreen";
35
41
  import { HeartIcon } from "./Heart";
36
42
  import { GlobeIcon } from "./Globe";
37
43
  import { HelpCircleIcon } from "./HelpCircle";
@@ -42,6 +48,8 @@ import { LayoutGridIcon } from "./LayoutGrid";
42
48
  import { LinkedInIcon } from "./LinkedIn";
43
49
  import { ListViewIcon } from "./ListView";
44
50
  import { LocationPinIcon } from "./LocationPin";
51
+ import { LocationUserIcon } from "./LocationUser";
52
+ import { LockIcon } from "./Lock";
45
53
  import { LogOutIcon } from "./LogOut";
46
54
  import { MailIcon } from "./Mail";
47
55
  import { MapViewIcon } from "./MapView";
@@ -51,6 +59,8 @@ import { MinusIcon } from "./Minus";
51
59
  import { NavigateIcon } from "./Navigate";
52
60
  import { PhoneIcon } from "./Phone";
53
61
  import { PlusIcon } from "./Plus";
62
+ import { RefreshIcon } from "./Refresh";
63
+ import { RefundStatusIcon } from "./RefundStatus";
54
64
  import { SearchIcon } from "./Search";
55
65
  import { SettingsIcon } from "./Settings";
56
66
  import { ShowIcon } from "./Show";
@@ -61,13 +71,17 @@ import { StarFilledIcon } from "./StarFilled";
61
71
  import { UserIcon } from "./User";
62
72
  import { UsersAltIcon } from "./UsersAlt";
63
73
  import { VideoIcon } from "./Video";
74
+ import { VideoOffIcon } from "./VideoOff";
75
+ import { ZoomOutIcon } from "./ZoomOut";
64
76
  import type { IconComponent } from "./types";
65
77
 
66
78
  export const icons = {
79
+ alertTriangle: AlertTriangleIcon,
67
80
  areaExpand: AreaExpandIcon,
68
81
  apple: AppleIcon,
69
82
  arrowRight: ArrowRightIcon,
70
83
  bag: BagIcon,
84
+ ban: BanIcon,
71
85
  bell: BellIcon,
72
86
  building: BuildingIcon,
73
87
  calendar: CalendarIcon,
@@ -80,13 +94,16 @@ export const icons = {
80
94
  chevronLeft: ChevronLeftIcon,
81
95
  clock: ClockIcon,
82
96
  close: CloseIcon,
97
+ edit: EditIcon,
83
98
  clockFilled: ClockFilledIcon,
84
99
  copy: CopyIcon,
100
+ download: DownloadIcon,
85
101
  bathrooms: BathroomsIcon,
86
102
  bedrooms: BedroomsIcon,
87
103
  cardLocation: CardLocationIcon,
88
104
  facebook: FacebookIcon,
89
105
  filters: FiltersIcon,
106
+ fullscreen: FullscreenIcon,
90
107
  guests: GuestsIcon,
91
108
  heart: HeartIcon,
92
109
  globe: GlobeIcon,
@@ -99,6 +116,8 @@ export const icons = {
99
116
  linkedin: LinkedInIcon,
100
117
  listView: ListViewIcon,
101
118
  locationPin: LocationPinIcon,
119
+ locationUser: LocationUserIcon,
120
+ lock: LockIcon,
102
121
  logOut: LogOutIcon,
103
122
  mail: MailIcon,
104
123
  mapView: MapViewIcon,
@@ -107,10 +126,15 @@ export const icons = {
107
126
  menu: MenuIcon,
108
127
  minus: MinusIcon,
109
128
  navigate: NavigateIcon,
129
+ noSmoking: NoSmokingIcon,
130
+ paw: PawIcon,
110
131
  phone: PhoneIcon,
111
132
  qrCode: QrCodeIcon,
133
+ quietHours: QuietHoursIcon,
112
134
  ratingStar: RatingStarIcon,
113
135
  plus: PlusIcon,
136
+ refresh: RefreshIcon,
137
+ refundStatus: RefundStatusIcon,
114
138
  search: SearchIcon,
115
139
  saveHeart: SaveHeartIcon,
116
140
  share: ShareIcon,
@@ -121,10 +145,13 @@ export const icons = {
121
145
  star: StarIcon,
122
146
  starFilled: StarFilledIcon,
123
147
  tooltipArrow: TooltipArrowIcon,
148
+ trash: TrashIcon,
124
149
  user: UserIcon,
125
150
  usersAlt: UsersAltIcon,
126
151
  video: VideoIcon,
152
+ videoOff: VideoOffIcon,
127
153
  whatsApp: WhatsAppIcon,
154
+ zoomOut: ZoomOutIcon,
128
155
  } as const satisfies Record<string, IconComponent>;
129
156
 
130
157
  export type IconName = keyof typeof icons;
@@ -139,6 +166,7 @@ export const iconGroups = {
139
166
  "home",
140
167
  "listView",
141
168
  "locationPin",
169
+ "locationUser",
142
170
  "mapCollapse",
143
171
  "mapExpand",
144
172
  "mapView",
@@ -147,6 +175,8 @@ export const iconGroups = {
147
175
  ],
148
176
  actions: [
149
177
  "show",
178
+ "alertTriangle",
179
+ "ban",
150
180
  "bell",
151
181
  "camera",
152
182
  "key",
@@ -154,19 +184,25 @@ export const iconGroups = {
154
184
  "checkBadge",
155
185
  "checkSuccess",
156
186
  "copy",
187
+ "download",
157
188
  "search",
158
189
  "calendar",
159
190
  "calendarOutline",
160
191
  "close",
192
+ "edit",
161
193
  "ratingStar",
162
194
  "saveHeart",
163
195
  "share",
164
196
  "filters",
197
+ "fullscreen",
165
198
  "heart",
199
+ "zoomOut",
166
200
  "star",
167
201
  "starFilled",
168
202
  "minus",
169
203
  "plus",
204
+ "refresh",
205
+ "refundStatus",
170
206
  "sort",
171
207
  ],
172
208
  objects: [
@@ -178,10 +214,16 @@ export const iconGroups = {
178
214
  "clock",
179
215
  "clockFilled",
180
216
  "guests",
217
+ "lock",
218
+ "noSmoking",
219
+ "paw",
181
220
  "qrCode",
221
+ "quietHours",
222
+ "trash",
182
223
  "user",
183
224
  "usersAlt",
184
225
  "video",
226
+ "videoOff",
185
227
  "whatsApp",
186
228
  ],
187
229
  communication: ["mail", "phone"],
package/src/index.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  export {
2
2
  Avatar,
3
3
  AvatarSimple,
4
+ AccountHeader,
4
5
  Badge,
6
+ StatusBadge,
7
+ PaginationDots,
8
+ StepPager,
9
+ InfoTile,
10
+ StepList,
5
11
  Counter,
6
12
  SegmentedToggle,
7
13
  Sidebar,
@@ -11,6 +17,7 @@ export {
11
17
  Button,
12
18
  Checkbox,
13
19
  DatePicker,
20
+ FloatingActionButton,
14
21
  Input,
15
22
  VerificationCodeInput,
16
23
  Select,
@@ -24,8 +31,15 @@ export type {
24
31
  AvatarProps,
25
32
  AvatarMenuItem,
26
33
  AvatarSimpleProps,
34
+ AccountHeaderProps,
27
35
  BadgeProps,
28
36
  BadgeVariant,
37
+ StatusBadgeProps,
38
+ StatusBadgeTone,
39
+ PaginationDotsProps,
40
+ StepPagerProps,
41
+ InfoTileProps,
42
+ StepListProps,
29
43
  CounterProps,
30
44
  SegmentedToggleOption,
31
45
  SegmentedToggleProps,
@@ -45,6 +59,7 @@ export type {
45
59
  DatePickerRangeProps,
46
60
  DatePickerVariant,
47
61
  DateRange,
62
+ FloatingActionButtonProps,
48
63
  InputIcon,
49
64
  InputProps,
50
65
  InputSize,
@@ -84,6 +99,7 @@ export type {
84
99
  export {
85
100
  Icon,
86
101
  AmenityIcon,
102
+ AlertTriangleIcon,
87
103
  AppleIcon,
88
104
  icons,
89
105
  iconNames,
@@ -92,6 +108,7 @@ export {
92
108
  getIconsByGroup,
93
109
  ArrowRightIcon,
94
110
  BagIcon,
111
+ BanIcon,
95
112
  BellIcon,
96
113
  BuildingIcon,
97
114
  CalendarIcon,
@@ -103,6 +120,7 @@ export {
103
120
  ChevronLeftIcon,
104
121
  ClockIcon,
105
122
  CloseIcon,
123
+ EditIcon,
106
124
  BathroomsIcon,
107
125
  BedroomsIcon,
108
126
  CardLocationIcon,
@@ -113,12 +131,18 @@ export {
113
131
  CheckSuccessIcon,
114
132
  ClockFilledIcon,
115
133
  CopyIcon,
134
+ DownloadIcon,
116
135
  QrCodeIcon,
117
136
  ShareIcon,
118
137
  TooltipArrowIcon,
119
138
  WhatsAppIcon,
139
+ QuietHoursIcon,
140
+ NoSmokingIcon,
141
+ PawIcon,
142
+ TrashIcon,
120
143
  FacebookIcon,
121
144
  FiltersIcon,
145
+ FullscreenIcon,
122
146
  HeartIcon,
123
147
  GlobeIcon,
124
148
  GooglePlayIcon,
@@ -130,6 +154,8 @@ export {
130
154
  LinkedInIcon,
131
155
  ListViewIcon,
132
156
  LocationPinIcon,
157
+ LocationUserIcon,
158
+ LockIcon,
133
159
  LogOutIcon,
134
160
  MailIcon,
135
161
  MapViewIcon,
@@ -140,6 +166,8 @@ export {
140
166
  NavigateIcon,
141
167
  PhoneIcon,
142
168
  PlusIcon,
169
+ RefreshIcon,
170
+ RefundStatusIcon,
143
171
  SearchIcon,
144
172
  SettingsIcon,
145
173
  ShowIcon,
@@ -150,6 +178,8 @@ export {
150
178
  UserIcon,
151
179
  UsersAltIcon,
152
180
  VideoIcon,
181
+ VideoOffIcon,
182
+ ZoomOutIcon,
153
183
  } from "./icons";
154
184
  export type {
155
185
  IconProps,
@@ -182,3 +212,7 @@ export {
182
212
  fonts,
183
213
  } from "./theme";
184
214
  export type { GreyStep } from "./theme";
215
+
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);
@@ -33,10 +33,13 @@ export const colors = {
33
33
  red: "#A63E3E",
34
34
  lightGrey: "#B7B7B7",
35
35
  green: "#34A853",
36
+ greenMuted: "#34A85329",
36
37
  primaryMuted: "#B464360F",
37
38
  primaryHover: "#B4643633",
38
39
  redMuted: "#A63E3E0F",
39
40
  redHover: "#A63E3E33",
41
+ greyMuted: "#76767629",
42
+ cancelledMuted: "#A63E3E29",
40
43
 
41
44
  grey0: grey["0"],
42
45
  grey50: grey["0.5"],
@@ -47,6 +50,7 @@ export const colors = {
47
50
  grey400: grey["4"],
48
51
  grey500: grey["5"],
49
52
  grey600: grey["6"],
53
+ grey650: "#1B1B1B",
50
54
  grey700: grey["7"],
51
55
  grey750: grey["7.5"],
52
56
  grey800: grey["8"],
@@ -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: {
@@ -193,7 +193,7 @@ export const datePickerTypography = {
193
193
  fontFamily: fonts.sans,
194
194
  fontSize: 12,
195
195
  fontWeight: "400" as const,
196
- lineHeight: 12,
196
+ lineHeight: 14,
197
197
  letterSpacing: 0.36,
198
198
  },
199
199
  rangeLabel: {
@@ -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: {
@@ -57,6 +57,31 @@ export function formatDate(date: Date): string {
57
57
  return `${day}.${month}.${date.getFullYear()}`;
58
58
  }
59
59
 
60
+ /**
61
+ * Shortens a month name to `letterCount` letters.
62
+ * Armenian digraph «ու» counts as one letter so «Հուլիս» → «Հուլ», not «Հու».
63
+ */
64
+ export function abbreviateMonthName(monthName: string, letterCount = 3): string {
65
+ const chars = Array.from(monthName);
66
+ let visual = 0;
67
+ let end = 0;
68
+ while (end < chars.length && visual < letterCount) {
69
+ if (chars[end] === "ո" && chars[end + 1] === "ւ") {
70
+ end += 2;
71
+ } else {
72
+ end += 1;
73
+ }
74
+ visual += 1;
75
+ }
76
+ return chars.slice(0, end).join("");
77
+ }
78
+
79
+ /** "15 Հուլ 2026" — day + abbreviated month + year for range triggers. */
80
+ export function formatDateDayShortMonth(date: Date, monthNames: string[], letterCount = 3): string {
81
+ const month = abbreviateMonthName(monthNames[date.getMonth()] ?? "", letterCount);
82
+ return `${date.getDate()} ${month} ${date.getFullYear()}`;
83
+ }
84
+
60
85
  /**
61
86
  * Builds a 6×7 grid of calendar days for the month containing `monthDate`,
62
87
  * including the leading/trailing days from adjacent months needed to fill
@@ -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
+ }