@bearmenu/ui 0.6.0 → 0.7.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/chunk-A5ONAJCE.js +102 -0
- package/dist/chunk-AV777R4G.js +43 -0
- package/dist/{chunk-WKMLZDUT.js → chunk-FRPPIXMY.js} +1 -1
- package/dist/{chunk-PSR7N36A.js → chunk-HCM6LKM5.js} +1 -1
- package/dist/{chunk-YJ6OBKZJ.js → chunk-TL4YU2O5.js} +10 -3
- package/dist/chunk-UX6SWAKH.js +320 -0
- package/dist/{chunk-7PPCH42H.js → chunk-VQNDZVI7.js} +1 -1
- package/dist/chunk-WSRWFA6K.js +26 -0
- package/dist/chunk-YLNYXPIH.js +61 -0
- package/dist/components/accordion.js +1 -1
- package/dist/components/alert.d.ts +2 -2
- package/dist/components/badge.d.ts +3 -2
- package/dist/components/badge.js +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/card.d.ts +2 -2
- package/dist/components/card.js +127 -4
- package/dist/components/combobox.js +2 -2
- package/dist/components/command.d.ts +15 -15
- package/dist/components/command.js +2 -2
- package/dist/components/currency-input.js +1 -1
- package/dist/components/date-input.d.ts +1 -1
- package/dist/components/date-input.js +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/filter-category-row.d.ts +13 -0
- package/dist/components/filter-category-row.js +44 -0
- package/dist/components/input-group.d.ts +2 -0
- package/dist/components/input-group.js +10 -5
- package/dist/components/input.d.ts +1 -0
- package/dist/components/input.js +1 -1
- package/dist/components/item.d.ts +2 -2
- package/dist/components/multi-select-combobox.js +3 -3
- package/dist/components/phone-frame.js +1 -1
- package/dist/components/place-about-tab.d.ts +2 -2
- package/dist/components/place-about-tab.js +4 -3
- package/dist/components/place-details-mobile.js +5 -3
- package/dist/components/place-schedule-week.d.ts +19 -0
- package/dist/components/place-schedule-week.js +4 -0
- package/dist/components/place-types.d.ts +18 -9
- package/dist/components/scroll-fade.d.ts +15 -0
- package/dist/components/scroll-fade.js +121 -0
- package/dist/components/searchable-select.js +2 -2
- package/dist/components/separator.js +3 -26
- package/dist/components/sheet.js +1 -1
- package/dist/components/sliding-panels.d.ts +1 -0
- package/dist/components/sliding-panels.js +22 -6
- package/dist/components/sort-option-list.d.ts +16 -0
- package/dist/components/sort-option-list.js +46 -0
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/tabs.js +98 -17
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/tag.js +3 -61
- package/dist/components/text.d.ts +3 -3
- package/dist/components/toast.js +1 -1
- package/dist/components/toaster.js +1 -1
- package/package.json +23 -112
- package/src/components/accordion.tsx +1 -1
- package/src/components/badge.tsx +9 -2
- package/src/components/card.tsx +22 -18
- package/src/components/dialog.tsx +1 -1
- package/src/components/filter-category-row.tsx +52 -0
- package/src/components/input-group.tsx +9 -4
- package/src/components/input.tsx +8 -3
- package/src/components/phone-frame.tsx +1 -1
- package/src/components/place-about-tab.stories.tsx +24 -13
- package/src/components/place-about-tab.test.tsx +92 -38
- package/src/components/place-about-tab.tsx +310 -344
- package/src/components/place-schedule-week.tsx +128 -0
- package/src/components/place-types.ts +27 -8
- package/src/components/scroll-fade.stories.tsx +98 -0
- package/src/components/scroll-fade.tsx +132 -0
- package/src/components/sheet.tsx +1 -1
- package/src/components/sliding-panels.tsx +33 -6
- package/src/components/sort-option-list.tsx +57 -0
- package/src/components/tabs.tsx +76 -11
- package/src/components/toast.tsx +1 -1
- package/src/globals.css +77 -19
- package/src/lib/motion.ts +137 -0
- package/dist/chunk-BAZFVSSG.js +0 -279
- package/dist/chunk-RIDXFY6M.js +0 -38
- package/dist/chunk-XK2ZDQVE.js +0 -122
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from "vitest";
|
|
2
2
|
import { render, screen, fireEvent } from "@testing-library/react";
|
|
3
3
|
import { PlaceAboutTab } from "./place-about-tab";
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
PlaceAboutTabLabels,
|
|
6
|
+
PlacePreview,
|
|
7
|
+
PlaceSchedule,
|
|
8
|
+
} from "./place-types";
|
|
5
9
|
|
|
6
10
|
// ─── Fixtures ─────────────────────────────────────────────────────────────────
|
|
7
11
|
|
|
8
12
|
const LABELS: PlaceAboutTabLabels = {
|
|
9
|
-
overview: "Overview",
|
|
10
13
|
description: "Description",
|
|
11
|
-
whatPeopleSay: "What people say",
|
|
12
14
|
contactAndLocation: "Contact & Location",
|
|
13
|
-
address: "Address",
|
|
14
15
|
instagram: "Instagram",
|
|
15
16
|
facebook: "Facebook",
|
|
16
|
-
todayHours: "
|
|
17
|
-
statusOpen: "Open now",
|
|
17
|
+
todayHours: "Hours",
|
|
18
18
|
statusClosed: "Closed",
|
|
19
19
|
typicalBusyness: "Typical busyness",
|
|
20
20
|
cuisines: "Cuisines",
|
|
@@ -23,10 +23,16 @@ const LABELS: PlaceAboutTabLabels = {
|
|
|
23
23
|
accessibility: "Accessibility",
|
|
24
24
|
parking: "Parking",
|
|
25
25
|
nearbyLandmarks: "Nearby landmarks",
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
scheduleDays: {
|
|
27
|
+
monday: "Monday",
|
|
28
|
+
tuesday: "Tuesday",
|
|
29
|
+
wednesday: "Wednesday",
|
|
30
|
+
thursday: "Thursday",
|
|
31
|
+
friday: "Friday",
|
|
32
|
+
saturday: "Saturday",
|
|
33
|
+
sunday: "Sunday",
|
|
34
|
+
},
|
|
35
|
+
noHoursAvailable: "Hours not available",
|
|
30
36
|
amenityLabels: { wifi: "Free Wi-Fi" },
|
|
31
37
|
paymentLabels: {},
|
|
32
38
|
accessibilityLabels: {},
|
|
@@ -35,6 +41,19 @@ const LABELS: PlaceAboutTabLabels = {
|
|
|
35
41
|
statusLabels: {},
|
|
36
42
|
};
|
|
37
43
|
|
|
44
|
+
function makeSchedule(overrides: Partial<PlaceSchedule> = {}): PlaceSchedule {
|
|
45
|
+
return {
|
|
46
|
+
monday: [],
|
|
47
|
+
tuesday: [],
|
|
48
|
+
wednesday: [],
|
|
49
|
+
thursday: [],
|
|
50
|
+
friday: [],
|
|
51
|
+
saturday: [],
|
|
52
|
+
sunday: [],
|
|
53
|
+
...overrides,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
38
57
|
function makePlace(overrides: Partial<PlacePreview> = {}): PlacePreview {
|
|
39
58
|
return {
|
|
40
59
|
id: "1",
|
|
@@ -104,6 +123,33 @@ describe("PlaceAboutTab", () => {
|
|
|
104
123
|
expect(screen.queryByText("Facebook")).not.toBeInTheDocument();
|
|
105
124
|
});
|
|
106
125
|
|
|
126
|
+
// ─── Address + neighborhood subline ─────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
it("renders address as primary text and neighborhood as muted subline", () => {
|
|
129
|
+
render(
|
|
130
|
+
<PlaceAboutTab
|
|
131
|
+
place={makePlace({
|
|
132
|
+
location: { address: "Strada Napoca 12" },
|
|
133
|
+
areas: [{ name: "Centru" }, { name: "Piata Unirii" }],
|
|
134
|
+
})}
|
|
135
|
+
labels={LABELS}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
expect(screen.getByText("Strada Napoca 12")).toBeInTheDocument();
|
|
139
|
+
expect(screen.getByText("Centru · Piata Unirii")).toBeInTheDocument();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("does not render neighborhood subline when areas is empty", () => {
|
|
143
|
+
render(
|
|
144
|
+
<PlaceAboutTab
|
|
145
|
+
place={makePlace({ location: { address: "Strada Napoca 12" } })}
|
|
146
|
+
labels={LABELS}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
expect(screen.getByText("Strada Napoca 12")).toBeInTheDocument();
|
|
150
|
+
expect(screen.queryByText(/·/)).not.toBeInTheDocument();
|
|
151
|
+
});
|
|
152
|
+
|
|
107
153
|
// ─── mapSlot ────────────────────────────────────────────────────────────────
|
|
108
154
|
|
|
109
155
|
it("renders mapSlot when prop is passed (regardless of busyness data)", () => {
|
|
@@ -227,29 +273,49 @@ describe("PlaceAboutTab", () => {
|
|
|
227
273
|
);
|
|
228
274
|
});
|
|
229
275
|
|
|
230
|
-
// ───
|
|
276
|
+
// ─── Hours section (full week, schedule-driven) ─────────────────────────────
|
|
231
277
|
|
|
232
|
-
it("renders
|
|
278
|
+
it("renders the hours section heading and a slot row when place.schedule is provided", () => {
|
|
233
279
|
render(
|
|
234
280
|
<PlaceAboutTab
|
|
235
|
-
place={makePlace({
|
|
281
|
+
place={makePlace({
|
|
282
|
+
schedule: makeSchedule({ monday: [{ opens_at: 9, closes_at: 22 }] }),
|
|
283
|
+
})}
|
|
236
284
|
labels={LABELS}
|
|
237
285
|
/>
|
|
238
286
|
);
|
|
239
|
-
expect(screen.getByText("
|
|
240
|
-
expect(screen.getByText("09:00
|
|
287
|
+
expect(screen.getByText("Hours")).toBeInTheDocument();
|
|
288
|
+
expect(screen.getByText("09:00 – 22:00")).toBeInTheDocument();
|
|
289
|
+
expect(screen.getByText("Monday")).toBeInTheDocument();
|
|
241
290
|
});
|
|
242
291
|
|
|
243
|
-
it("
|
|
292
|
+
it("renders all 7 weekday labels when schedule is present", () => {
|
|
244
293
|
render(
|
|
245
|
-
<PlaceAboutTab
|
|
294
|
+
<PlaceAboutTab
|
|
295
|
+
place={makePlace({ schedule: makeSchedule() })}
|
|
296
|
+
labels={LABELS}
|
|
297
|
+
/>
|
|
298
|
+
);
|
|
299
|
+
expect(screen.getByText("Monday")).toBeInTheDocument();
|
|
300
|
+
expect(screen.getByText("Sunday")).toBeInTheDocument();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("renders 'Closed' (line-through) for days with no slots", () => {
|
|
304
|
+
render(
|
|
305
|
+
<PlaceAboutTab
|
|
306
|
+
place={makePlace({
|
|
307
|
+
schedule: makeSchedule({ monday: [{ opens_at: 9, closes_at: 22 }] }),
|
|
308
|
+
})}
|
|
309
|
+
labels={LABELS}
|
|
310
|
+
/>
|
|
246
311
|
);
|
|
247
|
-
|
|
312
|
+
// Six remaining days are closed → six "Closed" line-through entries.
|
|
313
|
+
expect(screen.getAllByText("Closed")).toHaveLength(6);
|
|
248
314
|
});
|
|
249
315
|
|
|
250
|
-
it("does NOT render
|
|
316
|
+
it("does NOT render the hours section when place.schedule is absent", () => {
|
|
251
317
|
render(<PlaceAboutTab place={makePlace()} labels={LABELS} />);
|
|
252
|
-
expect(screen.queryByText("
|
|
318
|
+
expect(screen.queryByText("Hours")).not.toBeInTheDocument();
|
|
253
319
|
});
|
|
254
320
|
|
|
255
321
|
// ─── amenityLabels fallback to humanizeEnum ──────────────────────────────────
|
|
@@ -261,7 +327,6 @@ describe("PlaceAboutTab", () => {
|
|
|
261
327
|
labels={LABELS}
|
|
262
328
|
/>
|
|
263
329
|
);
|
|
264
|
-
// LABELS.amenityLabels.wifi = "Free Wi-Fi"
|
|
265
330
|
expect(screen.getByText("Free Wi-Fi")).toBeInTheDocument();
|
|
266
331
|
});
|
|
267
332
|
|
|
@@ -272,13 +337,12 @@ describe("PlaceAboutTab", () => {
|
|
|
272
337
|
labels={LABELS}
|
|
273
338
|
/>
|
|
274
339
|
);
|
|
275
|
-
// humanizeEnum("outdoor_seating") → "outdoor seating"
|
|
276
340
|
expect(screen.getByText("outdoor seating")).toBeInTheDocument();
|
|
277
341
|
});
|
|
278
342
|
|
|
279
|
-
// ─── Description
|
|
343
|
+
// ─── Description visibility ────────────────────────────────────────────────
|
|
280
344
|
|
|
281
|
-
it("renders description
|
|
345
|
+
it("renders description prose when description is set", () => {
|
|
282
346
|
render(
|
|
283
347
|
<PlaceAboutTab
|
|
284
348
|
place={makePlace({ description: "A great place to eat." })}
|
|
@@ -288,7 +352,7 @@ describe("PlaceAboutTab", () => {
|
|
|
288
352
|
expect(screen.getByText("A great place to eat.")).toBeInTheDocument();
|
|
289
353
|
});
|
|
290
354
|
|
|
291
|
-
it("renders description
|
|
355
|
+
it("renders description prose when generative_summary is set", () => {
|
|
292
356
|
render(
|
|
293
357
|
<PlaceAboutTab
|
|
294
358
|
place={makePlace({ generative_summary: "AI summary here." })}
|
|
@@ -298,7 +362,7 @@ describe("PlaceAboutTab", () => {
|
|
|
298
362
|
expect(screen.getByText("AI summary here.")).toBeInTheDocument();
|
|
299
363
|
});
|
|
300
364
|
|
|
301
|
-
it("renders description
|
|
365
|
+
it("renders description prose when review_summary is set", () => {
|
|
302
366
|
render(
|
|
303
367
|
<PlaceAboutTab
|
|
304
368
|
place={makePlace({ review_summary: "People love it." })}
|
|
@@ -308,18 +372,8 @@ describe("PlaceAboutTab", () => {
|
|
|
308
372
|
expect(screen.getByText("People love it.")).toBeInTheDocument();
|
|
309
373
|
});
|
|
310
374
|
|
|
311
|
-
it("hides description
|
|
375
|
+
it("hides the description section heading when no prose and no business chips are present", () => {
|
|
312
376
|
render(<PlaceAboutTab place={makePlace()} labels={LABELS} />);
|
|
313
|
-
|
|
314
|
-
// The description card renders labels.description as its CardTitle.
|
|
315
|
-
// Use a more specific query: look for the card header content.
|
|
316
|
-
// Since labels.contactAndLocation is always rendered, we need to count occurrences.
|
|
317
|
-
// "Description" appears in labels.description; if no card exists it should not appear at all.
|
|
318
|
-
expect(screen.queryByText("A great place to eat.")).not.toBeInTheDocument();
|
|
319
|
-
// Verify no card title "Description" is rendered (description card uses labels.description as title)
|
|
320
|
-
// Note: "Description" also equals labels.description label inside the card — use getAllByText and check count
|
|
321
|
-
const descTexts = screen.queryAllByText("Description");
|
|
322
|
-
// When description card is hidden, "Description" label should not appear
|
|
323
|
-
expect(descTexts).toHaveLength(0);
|
|
377
|
+
expect(screen.queryByText("Description")).not.toBeInTheDocument();
|
|
324
378
|
});
|
|
325
379
|
});
|