@bearmenu/ui 0.6.1 → 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.
Files changed (69) hide show
  1. package/dist/chunk-A5ONAJCE.js +102 -0
  2. package/dist/chunk-AV777R4G.js +43 -0
  3. package/dist/{chunk-WKMLZDUT.js → chunk-FRPPIXMY.js} +1 -1
  4. package/dist/{chunk-PSR7N36A.js → chunk-HCM6LKM5.js} +1 -1
  5. package/dist/{chunk-YJ6OBKZJ.js → chunk-TL4YU2O5.js} +10 -3
  6. package/dist/chunk-UX6SWAKH.js +320 -0
  7. package/dist/{chunk-7PPCH42H.js → chunk-VQNDZVI7.js} +1 -1
  8. package/dist/chunk-WSRWFA6K.js +26 -0
  9. package/dist/chunk-YLNYXPIH.js +61 -0
  10. package/dist/components/accordion.js +1 -1
  11. package/dist/components/badge.d.ts +2 -1
  12. package/dist/components/badge.js +1 -1
  13. package/dist/components/card.js +127 -4
  14. package/dist/components/combobox.js +2 -2
  15. package/dist/components/command.js +2 -2
  16. package/dist/components/currency-input.js +1 -1
  17. package/dist/components/date-input.js +1 -1
  18. package/dist/components/dialog.js +1 -1
  19. package/dist/components/filter-category-row.d.ts +13 -0
  20. package/dist/components/filter-category-row.js +44 -0
  21. package/dist/components/input-group.d.ts +2 -0
  22. package/dist/components/input-group.js +10 -5
  23. package/dist/components/input.d.ts +1 -0
  24. package/dist/components/input.js +1 -1
  25. package/dist/components/multi-select-combobox.js +3 -3
  26. package/dist/components/phone-frame.js +1 -1
  27. package/dist/components/place-about-tab.d.ts +2 -2
  28. package/dist/components/place-about-tab.js +4 -3
  29. package/dist/components/place-details-mobile.js +5 -3
  30. package/dist/components/place-schedule-week.d.ts +19 -0
  31. package/dist/components/place-schedule-week.js +4 -0
  32. package/dist/components/place-types.d.ts +18 -9
  33. package/dist/components/scroll-fade.js +7 -2
  34. package/dist/components/searchable-select.js +2 -2
  35. package/dist/components/separator.js +3 -26
  36. package/dist/components/sheet.js +1 -1
  37. package/dist/components/sliding-panels.d.ts +1 -0
  38. package/dist/components/sliding-panels.js +22 -6
  39. package/dist/components/sort-option-list.d.ts +16 -0
  40. package/dist/components/sort-option-list.js +46 -0
  41. package/dist/components/tabs.js +98 -17
  42. package/dist/components/tag.js +3 -61
  43. package/dist/components/toast.js +1 -1
  44. package/dist/components/toaster.js +1 -1
  45. package/package.json +23 -113
  46. package/src/components/accordion.tsx +1 -1
  47. package/src/components/badge.tsx +9 -2
  48. package/src/components/card.tsx +22 -18
  49. package/src/components/dialog.tsx +1 -1
  50. package/src/components/filter-category-row.tsx +52 -0
  51. package/src/components/input-group.tsx +9 -4
  52. package/src/components/input.tsx +8 -3
  53. package/src/components/phone-frame.tsx +1 -1
  54. package/src/components/place-about-tab.stories.tsx +24 -13
  55. package/src/components/place-about-tab.test.tsx +92 -38
  56. package/src/components/place-about-tab.tsx +310 -344
  57. package/src/components/place-schedule-week.tsx +128 -0
  58. package/src/components/place-types.ts +27 -8
  59. package/src/components/scroll-fade.tsx +9 -4
  60. package/src/components/sheet.tsx +1 -1
  61. package/src/components/sliding-panels.tsx +33 -6
  62. package/src/components/sort-option-list.tsx +57 -0
  63. package/src/components/tabs.tsx +76 -11
  64. package/src/components/toast.tsx +1 -1
  65. package/src/globals.css +77 -19
  66. package/src/lib/motion.ts +137 -0
  67. package/dist/chunk-BAZFVSSG.js +0 -279
  68. package/dist/chunk-RIDXFY6M.js +0 -38
  69. package/dist/chunk-XK2ZDQVE.js +0 -122
@@ -0,0 +1,102 @@
1
+ import { Text } from './chunk-Y5D5LP4A.js';
2
+ import { cn } from './chunk-FEK5XGZW.js';
3
+ import { useRef, useEffect } from 'react';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ var WEEKDAY_KEYS = [
7
+ "monday",
8
+ "tuesday",
9
+ "wednesday",
10
+ "thursday",
11
+ "friday",
12
+ "saturday",
13
+ "sunday"
14
+ ];
15
+ function formatHour(h) {
16
+ return `${h.toString().padStart(2, "0")}:00`;
17
+ }
18
+ function todayWeekdayIndex() {
19
+ const d = (/* @__PURE__ */ new Date()).getDay();
20
+ return (d + 6) % 7;
21
+ }
22
+ function PlaceScheduleWeek({
23
+ schedule,
24
+ labels,
25
+ autoScrollToToday = false,
26
+ className
27
+ }) {
28
+ const todayIdx = todayWeekdayIndex();
29
+ const todayRowRef = useRef(null);
30
+ useEffect(() => {
31
+ var _a;
32
+ if (autoScrollToToday) {
33
+ (_a = todayRowRef.current) == null ? void 0 : _a.scrollIntoView({ block: "nearest" });
34
+ }
35
+ }, [autoScrollToToday]);
36
+ if (!schedule) {
37
+ return /* @__PURE__ */ jsx(Text, { as: "p", variant: "body-sm", color: "muted", children: labels.noHoursAvailable });
38
+ }
39
+ return /* @__PURE__ */ jsx("div", { className: cn(className), children: WEEKDAY_KEYS.map((dayKey, idx) => {
40
+ var _a;
41
+ const slots = (_a = schedule[dayKey]) != null ? _a : [];
42
+ const isToday = idx === todayIdx;
43
+ const isClosed = slots.length === 0;
44
+ return /* @__PURE__ */ jsxs(
45
+ "div",
46
+ {
47
+ ref: isToday ? todayRowRef : null,
48
+ className: cn(
49
+ "relative flex items-start justify-between gap-3 rounded-lg px-3 py-1.5 overflow-hidden",
50
+ isToday && "bg-primary/8"
51
+ ),
52
+ children: [
53
+ isToday && /* @__PURE__ */ jsx(
54
+ "span",
55
+ {
56
+ "aria-hidden": true,
57
+ className: "absolute left-0 top-0 bottom-0 w-1 bg-primary"
58
+ }
59
+ ),
60
+ /* @__PURE__ */ jsx(
61
+ Text,
62
+ {
63
+ as: "span",
64
+ variant: "body-sm",
65
+ weight: isToday ? "semibold" : "medium",
66
+ className: isToday ? "text-foreground" : "text-muted-foreground",
67
+ children: labels.days[dayKey]
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col items-end gap-0.5", children: isClosed ? /* @__PURE__ */ jsx(
71
+ Text,
72
+ {
73
+ as: "span",
74
+ variant: "body-sm",
75
+ className: "line-through text-muted-foreground/50",
76
+ children: labels.closed
77
+ }
78
+ ) : slots.map((slot, i) => /* @__PURE__ */ jsxs(
79
+ Text,
80
+ {
81
+ as: "span",
82
+ variant: "body-sm",
83
+ className: cn(
84
+ "tabular-nums",
85
+ isToday ? "text-foreground" : "text-muted-foreground"
86
+ ),
87
+ children: [
88
+ formatHour(slot.opens_at),
89
+ " \u2013 ",
90
+ formatHour(slot.closes_at)
91
+ ]
92
+ },
93
+ i
94
+ )) })
95
+ ]
96
+ },
97
+ dayKey
98
+ );
99
+ }) });
100
+ }
101
+
102
+ export { PlaceScheduleWeek };
@@ -0,0 +1,43 @@
1
+ import { cn } from './chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadValues } from './chunk-3GWWZKX7.js';
3
+ import * as React from 'react';
4
+ import { cva } from 'class-variance-authority';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ var inputVariants = cva(
8
+ "flex w-full border border-border bg-input/50 text-base transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:bg-input disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive/40",
9
+ {
10
+ variants: {
11
+ size: {
12
+ sm: "h-9 px-3 text-base md:text-sm",
13
+ default: "h-11 px-4 py-2",
14
+ lg: "h-12 px-5 text-base"
15
+ },
16
+ shape: {
17
+ rounded: "rounded-xl focus-visible:ring-ring",
18
+ pill: "rounded-full bg-background shadow-[var(--shadow-card)] focus-visible:ring-accent/30"
19
+ }
20
+ },
21
+ defaultVariants: {
22
+ size: "default",
23
+ shape: "rounded"
24
+ }
25
+ }
26
+ );
27
+ var Input = React.forwardRef(
28
+ (_a, ref) => {
29
+ var _b = _a, { className, type, size, shape } = _b, props = __objRest(_b, ["className", "type", "size", "shape"]);
30
+ return /* @__PURE__ */ jsx(
31
+ "input",
32
+ __spreadValues({
33
+ type,
34
+ "data-slot": "input",
35
+ className: cn(inputVariants({ size, shape }), className),
36
+ ref
37
+ }, props)
38
+ );
39
+ }
40
+ );
41
+ Input.displayName = "Input";
42
+
43
+ export { Input, inputVariants };
@@ -26,7 +26,7 @@ var DialogOverlay = React.forwardRef((_a, ref) => {
26
26
  });
27
27
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
28
28
  var dialogContentVariants = cva(
29
- "fixed left-[50%] top-[50%] z-[1000] grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 bg-card p-6 shadow-2xl duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 rounded-2xl border border-border",
29
+ "fixed left-[50%] top-[50%] z-[1000] grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 bg-card p-6 shadow-2xl data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:duration-[var(--duration-deliberate)] data-[state=closed]:duration-[var(--duration-exit-standard)] data-[state=open]:ease-[var(--ease-enter)] data-[state=closed]:ease-[var(--ease-exit)] data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 rounded-2xl border border-border",
30
30
  {
31
31
  variants: {
32
32
  size: {
@@ -1,4 +1,4 @@
1
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from './chunk-WKMLZDUT.js';
1
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from './chunk-FRPPIXMY.js';
2
2
  import { cn } from './chunk-FEK5XGZW.js';
3
3
  import { __objRest, __spreadValues, __spreadProps } from './chunk-3GWWZKX7.js';
4
4
  import * as React from 'react';
@@ -17,16 +17,23 @@ var badgeVariants = cva(
17
17
  success: "border-transparent bg-success text-success-foreground",
18
18
  warning: "border-transparent bg-warning text-warning-foreground",
19
19
  brown: "border-transparent bg-brown text-brown-foreground"
20
+ },
21
+ // v1.0 motion: "live" surface signal — applies `live-pulse` archetype.
22
+ // Pair with a colored variant (e.g. variant="destructive" live).
23
+ live: {
24
+ true: "motion-live-pulse motion-reduce:animate-none",
25
+ false: ""
20
26
  }
21
27
  },
22
28
  defaultVariants: {
23
- variant: "default"
29
+ variant: "default",
30
+ live: false
24
31
  }
25
32
  }
26
33
  );
27
34
  function Badge(_a) {
28
- var _b = _a, { className, variant } = _b, props = __objRest(_b, ["className", "variant"]);
29
- return /* @__PURE__ */ jsx("div", __spreadValues({ "data-slot": "badge", className: cn(badgeVariants({ variant }), className) }, props));
35
+ var _b = _a, { className, variant, live } = _b, props = __objRest(_b, ["className", "variant", "live"]);
36
+ return /* @__PURE__ */ jsx("div", __spreadValues({ "data-slot": "badge", className: cn(badgeVariants({ variant, live }), className) }, props));
30
37
  }
31
38
 
32
39
  export { Badge, badgeVariants };
@@ -0,0 +1,320 @@
1
+ import { Tag } from './chunk-YLNYXPIH.js';
2
+ import { Separator } from './chunk-WSRWFA6K.js';
3
+ import { PlaceScheduleWeek } from './chunk-A5ONAJCE.js';
4
+ import { Text } from './chunk-Y5D5LP4A.js';
5
+ import { cn } from './chunk-FEK5XGZW.js';
6
+ import { __spreadProps, __spreadValues } from './chunk-3GWWZKX7.js';
7
+ import { Fragment } from 'react';
8
+ import { Phone, Globe, Check } from 'lucide-react';
9
+ import { jsxs, jsx } from 'react/jsx-runtime';
10
+
11
+ function Instagram(props) {
12
+ return /* @__PURE__ */ jsxs(
13
+ "svg",
14
+ __spreadProps(__spreadValues({
15
+ viewBox: "0 0 24 24",
16
+ fill: "none",
17
+ stroke: "currentColor",
18
+ strokeWidth: "2",
19
+ strokeLinecap: "round",
20
+ strokeLinejoin: "round"
21
+ }, props), {
22
+ children: [
23
+ /* @__PURE__ */ jsx("rect", { width: "20", height: "20", x: "2", y: "2", rx: "5", ry: "5" }),
24
+ /* @__PURE__ */ jsx("path", { d: "M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z" }),
25
+ /* @__PURE__ */ jsx("line", { x1: "17.5", x2: "17.51", y1: "6.5", y2: "6.5" })
26
+ ]
27
+ })
28
+ );
29
+ }
30
+ function Facebook(props) {
31
+ return /* @__PURE__ */ jsx(
32
+ "svg",
33
+ __spreadProps(__spreadValues({
34
+ viewBox: "0 0 24 24",
35
+ fill: "none",
36
+ stroke: "currentColor",
37
+ strokeWidth: "2",
38
+ strokeLinecap: "round",
39
+ strokeLinejoin: "round"
40
+ }, props), {
41
+ children: /* @__PURE__ */ jsx("path", { d: "M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" })
42
+ })
43
+ );
44
+ }
45
+ function humanizeEnum(value) {
46
+ return value.replace(/_/g, " ");
47
+ }
48
+ function SectionHeading({ children }) {
49
+ return /* @__PURE__ */ jsx(Text, { as: "h3", variant: "body-sm", weight: "semibold", className: "text-foreground", children });
50
+ }
51
+ function Divider() {
52
+ return /* @__PURE__ */ jsx(Separator, { className: "mx-4 w-auto" });
53
+ }
54
+ function ChecklistGrid({ items }) {
55
+ return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-x-3 gap-y-1.5", children: items.map((item, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
56
+ /* @__PURE__ */ jsx(
57
+ Check,
58
+ {
59
+ className: "w-3.5 h-3.5 mt-0.5 shrink-0 text-muted-foreground",
60
+ "aria-hidden": true
61
+ }
62
+ ),
63
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-sm", color: "muted", children: item })
64
+ ] }, i)) });
65
+ }
66
+ function ChipRow({ items }) {
67
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: items.map((item, i) => /* @__PURE__ */ jsx(Tag, { variant: "default", children: item }, i)) });
68
+ }
69
+ function StatusTag({
70
+ status,
71
+ label
72
+ }) {
73
+ const variant = status === "operational" ? "success" : status === "closed_temporarily" ? "warning" : "destructive";
74
+ return /* @__PURE__ */ jsx(Tag, { variant, className: "capitalize", children: label });
75
+ }
76
+ function PlaceAboutTab({
77
+ place,
78
+ labels,
79
+ mapSlot,
80
+ busynessSlot,
81
+ onLinkClick,
82
+ className
83
+ }) {
84
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
85
+ const handleLinkClick = (kind, url) => {
86
+ if (onLinkClick && url) onLinkClick(kind, url);
87
+ };
88
+ const getAmenityLabel = (key) => labels.amenityLabels[key] || humanizeEnum(key);
89
+ const getPaymentLabel = (key) => labels.paymentLabels[key] || humanizeEnum(key);
90
+ const getAccessibilityLabel = (key) => labels.accessibilityLabels[key] || humanizeEnum(key);
91
+ const getParkingLabel = (key) => labels.parkingLabels[key] || humanizeEnum(key);
92
+ const getTypeLabel = (key) => labels.typeLabels[key] || humanizeEnum(key);
93
+ const getStatusLabel = (key) => labels.statusLabels[key] || humanizeEnum(key);
94
+ const hasDescription = Boolean(
95
+ place.generative_summary || place.review_summary || place.description
96
+ );
97
+ const hasDescriptionChips = Boolean(place.type || place.business_status);
98
+ const hasContact = Boolean(
99
+ ((_a = place.location) == null ? void 0 : _a.address) || place.phone || place.website_url || ((_b = place.socials) == null ? void 0 : _b.instagram_url) || ((_c = place.socials) == null ? void 0 : _c.facebook_url)
100
+ );
101
+ const hasSchedule = Boolean(place.schedule);
102
+ const hasBusyness = Boolean(busynessSlot && place.busyness && place.busyness.length > 0);
103
+ const hasCuisines = ((_e = (_d = place.cuisines) == null ? void 0 : _d.length) != null ? _e : 0) > 0;
104
+ const hasAmenities = ((_g = (_f = place.amenities) == null ? void 0 : _f.length) != null ? _g : 0) > 0;
105
+ const hasPayment = ((_i = (_h = place.payment_options) == null ? void 0 : _h.length) != null ? _i : 0) > 0;
106
+ const hasAccessibility = ((_k = (_j = place.accessibility_features) == null ? void 0 : _j.length) != null ? _k : 0) > 0;
107
+ const hasParking = ((_m = (_l = place.parking_options) == null ? void 0 : _l.length) != null ? _m : 0) > 0;
108
+ const hasLandmarks = ((_o = (_n = place.landmarks) == null ? void 0 : _n.length) != null ? _o : 0) > 0;
109
+ const neighborhood = place.areas && place.areas.length > 0 ? place.areas.map((a) => a.name).join(" \xB7 ") : null;
110
+ const sections = [];
111
+ if (hasDescription || hasDescriptionChips) {
112
+ sections.push({
113
+ key: "description",
114
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
115
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.description }),
116
+ hasDescription && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
117
+ place.generative_summary && /* @__PURE__ */ jsx(Text, { as: "p", variant: "body-sm", leading: "snug", color: "muted", children: place.generative_summary }),
118
+ place.review_summary && /* @__PURE__ */ jsx(Text, { as: "p", variant: "body-sm", leading: "snug", color: "muted", children: place.review_summary }),
119
+ place.description && /* @__PURE__ */ jsx(Text, { as: "p", variant: "body-sm", leading: "snug", color: "muted", children: place.description })
120
+ ] }),
121
+ hasDescriptionChips && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
122
+ place.type && /* @__PURE__ */ jsx(Tag, { variant: "default", className: "capitalize", children: getTypeLabel(place.type) }),
123
+ place.business_status && /* @__PURE__ */ jsx(
124
+ StatusTag,
125
+ {
126
+ status: place.business_status,
127
+ label: getStatusLabel(place.business_status)
128
+ }
129
+ )
130
+ ] })
131
+ ] })
132
+ });
133
+ }
134
+ if (hasContact) {
135
+ sections.push({
136
+ key: "contact",
137
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
138
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.contactAndLocation }),
139
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2.5", children: [
140
+ ((_p = place.location) == null ? void 0 : _p.address) && /* @__PURE__ */ jsxs("div", { children: [
141
+ /* @__PURE__ */ jsx(Text, { as: "p", variant: "body-sm", color: "muted", children: place.location.address }),
142
+ neighborhood && /* @__PURE__ */ jsx(Text, { as: "p", variant: "body-sm", color: "muted", className: "mt-0.5", children: neighborhood })
143
+ ] }),
144
+ place.phone && /* @__PURE__ */ jsxs(
145
+ "a",
146
+ {
147
+ href: `tel:${place.phone}`,
148
+ onClick: () => handleLinkClick("phone", place.phone),
149
+ className: "flex items-center gap-2 text-foreground hover:text-primary transition-colors",
150
+ children: [
151
+ /* @__PURE__ */ jsx(Phone, { className: "w-4 h-4 text-muted-foreground shrink-0", "aria-hidden": true }),
152
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-sm", children: place.phone })
153
+ ]
154
+ }
155
+ ),
156
+ place.website_url && /* @__PURE__ */ jsxs(
157
+ "a",
158
+ {
159
+ href: place.website_url,
160
+ target: "_blank",
161
+ rel: "noopener noreferrer",
162
+ onClick: () => handleLinkClick("website", place.website_url),
163
+ className: "flex items-center gap-2 text-foreground hover:text-primary transition-colors break-all",
164
+ children: [
165
+ /* @__PURE__ */ jsx(Globe, { className: "w-4 h-4 text-muted-foreground shrink-0", "aria-hidden": true }),
166
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-sm", className: "break-all", children: place.website_url })
167
+ ]
168
+ }
169
+ ),
170
+ ((_q = place.socials) == null ? void 0 : _q.instagram_url) && /* @__PURE__ */ jsxs(
171
+ "a",
172
+ {
173
+ href: place.socials.instagram_url,
174
+ target: "_blank",
175
+ rel: "noopener noreferrer",
176
+ onClick: () => {
177
+ var _a2;
178
+ return handleLinkClick("instagram", (_a2 = place.socials) == null ? void 0 : _a2.instagram_url);
179
+ },
180
+ className: "flex items-center gap-2 text-foreground hover:text-primary transition-colors",
181
+ children: [
182
+ /* @__PURE__ */ jsx(Instagram, { className: "w-4 h-4 text-muted-foreground shrink-0", "aria-hidden": true }),
183
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-sm", children: labels.instagram })
184
+ ]
185
+ }
186
+ ),
187
+ ((_r = place.socials) == null ? void 0 : _r.facebook_url) && /* @__PURE__ */ jsxs(
188
+ "a",
189
+ {
190
+ href: place.socials.facebook_url,
191
+ target: "_blank",
192
+ rel: "noopener noreferrer",
193
+ onClick: () => {
194
+ var _a2;
195
+ return handleLinkClick("facebook", (_a2 = place.socials) == null ? void 0 : _a2.facebook_url);
196
+ },
197
+ className: "flex items-center gap-2 text-foreground hover:text-primary transition-colors",
198
+ children: [
199
+ /* @__PURE__ */ jsx(Facebook, { className: "w-4 h-4 text-muted-foreground shrink-0", "aria-hidden": true }),
200
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-sm", children: labels.facebook })
201
+ ]
202
+ }
203
+ )
204
+ ] })
205
+ ] })
206
+ });
207
+ }
208
+ if (hasSchedule) {
209
+ sections.push({
210
+ key: "hours",
211
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
212
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.todayHours }),
213
+ /* @__PURE__ */ jsx(
214
+ PlaceScheduleWeek,
215
+ {
216
+ schedule: place.schedule,
217
+ labels: {
218
+ days: labels.scheduleDays,
219
+ closed: labels.statusClosed,
220
+ noHoursAvailable: labels.noHoursAvailable
221
+ },
222
+ autoScrollToToday: false
223
+ }
224
+ )
225
+ ] })
226
+ });
227
+ }
228
+ if (hasBusyness) {
229
+ sections.push({
230
+ key: "busyness",
231
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
232
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.typicalBusyness }),
233
+ busynessSlot
234
+ ] })
235
+ });
236
+ }
237
+ if (hasCuisines) {
238
+ sections.push({
239
+ key: "cuisines",
240
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
241
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.cuisines }),
242
+ /* @__PURE__ */ jsx(
243
+ ChipRow,
244
+ {
245
+ items: place.cuisines.map((c) => c.charAt(0).toUpperCase() + c.slice(1))
246
+ }
247
+ )
248
+ ] })
249
+ });
250
+ }
251
+ if (hasAmenities) {
252
+ sections.push({
253
+ key: "amenities",
254
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
255
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.amenities }),
256
+ /* @__PURE__ */ jsx(ChecklistGrid, { items: place.amenities.map(getAmenityLabel) })
257
+ ] })
258
+ });
259
+ }
260
+ if (hasPayment) {
261
+ sections.push({
262
+ key: "payment",
263
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
264
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.paymentOptions }),
265
+ /* @__PURE__ */ jsx(ChipRow, { items: place.payment_options.map(getPaymentLabel) })
266
+ ] })
267
+ });
268
+ }
269
+ if (hasAccessibility) {
270
+ sections.push({
271
+ key: "accessibility",
272
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
273
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.accessibility }),
274
+ /* @__PURE__ */ jsx(ChecklistGrid, { items: place.accessibility_features.map(getAccessibilityLabel) })
275
+ ] })
276
+ });
277
+ }
278
+ if (hasParking) {
279
+ sections.push({
280
+ key: "parking",
281
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
282
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.parking }),
283
+ /* @__PURE__ */ jsx(ChipRow, { items: place.parking_options.map(getParkingLabel) })
284
+ ] })
285
+ });
286
+ }
287
+ if (hasLandmarks) {
288
+ sections.push({
289
+ key: "landmarks",
290
+ node: /* @__PURE__ */ jsxs("section", { className: "px-4 space-y-2", children: [
291
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.nearbyLandmarks }),
292
+ /* @__PURE__ */ jsx("div", { className: "space-y-2", children: place.landmarks.map((landmark, i) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-baseline gap-3", children: [
293
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-sm", children: landmark.name }),
294
+ landmark.distance_meters != null && /* @__PURE__ */ jsxs(
295
+ Text,
296
+ {
297
+ as: "span",
298
+ variant: "body-sm",
299
+ color: "muted",
300
+ className: "tabular-nums shrink-0",
301
+ children: [
302
+ (landmark.distance_meters / 1e3).toFixed(1),
303
+ " km"
304
+ ]
305
+ }
306
+ )
307
+ ] }, i)) })
308
+ ] })
309
+ });
310
+ }
311
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6 pt-4", className), children: [
312
+ mapSlot,
313
+ sections.map((s, i) => /* @__PURE__ */ jsxs(Fragment, { children: [
314
+ (i > 0 || mapSlot) && /* @__PURE__ */ jsx(Divider, {}),
315
+ s.node
316
+ ] }, s.key))
317
+ ] });
318
+ }
319
+
320
+ export { PlaceAboutTab };
@@ -22,7 +22,7 @@ var ToastViewport = React.forwardRef((_a, ref) => {
22
22
  });
23
23
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
24
24
  var toastVariants = cva(
25
- "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-xl p-6 pr-8 shadow-2xl transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
25
+ "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-xl p-6 pr-8 shadow-2xl transition-[transform,opacity] duration-[var(--duration-standard)] ease-[var(--ease-standard)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=open]:duration-[var(--duration-standard)] data-[state=closed]:duration-[var(--duration-exit-standard)] data-[state=open]:ease-[var(--ease-enter)] data-[state=closed]:ease-[var(--ease-exit)] data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
26
26
  {
27
27
  variants: {
28
28
  variant: {
@@ -0,0 +1,26 @@
1
+ import { cn } from './chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadValues } from './chunk-3GWWZKX7.js';
3
+ import * as React from 'react';
4
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ var Separator = React.forwardRef((_a, ref) => {
8
+ var _b = _a, { className, orientation = "horizontal", decorative = true } = _b, props = __objRest(_b, ["className", "orientation", "decorative"]);
9
+ return /* @__PURE__ */ jsx(
10
+ SeparatorPrimitive.Root,
11
+ __spreadValues({
12
+ ref,
13
+ "data-slot": "separator",
14
+ decorative,
15
+ orientation,
16
+ className: cn(
17
+ "shrink-0",
18
+ orientation === "horizontal" ? "h-px w-full bg-gradient-to-r from-transparent via-border to-transparent" : "h-full w-px bg-gradient-to-b from-transparent via-border to-transparent",
19
+ className
20
+ )
21
+ }, props)
22
+ );
23
+ });
24
+ Separator.displayName = SeparatorPrimitive.Root.displayName;
25
+
26
+ export { Separator };
@@ -0,0 +1,61 @@
1
+ import { cn } from './chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadProps, __spreadValues } from './chunk-3GWWZKX7.js';
3
+ import * as React from 'react';
4
+ import { X } from 'lucide-react';
5
+ import { cva } from 'class-variance-authority';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var tagVariants = cva(
9
+ "inline-flex items-center gap-1 rounded-full border text-xs font-medium transition-colors",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "border-border bg-muted text-foreground",
14
+ primary: "border-primary/30 bg-primary/10 text-primary",
15
+ success: "border-success/30 bg-success/10 text-success",
16
+ warning: "border-warning/30 bg-warning/10 text-warning",
17
+ destructive: "border-destructive/30 bg-destructive/10 text-destructive",
18
+ outline: "border-border bg-transparent text-foreground"
19
+ },
20
+ size: {
21
+ sm: "h-5 px-2 text-[10px]",
22
+ default: "h-6 px-2.5",
23
+ lg: "h-7 px-3 text-sm"
24
+ }
25
+ },
26
+ defaultVariants: {
27
+ variant: "default",
28
+ size: "default"
29
+ }
30
+ }
31
+ );
32
+ var Tag = React.forwardRef(
33
+ (_a, ref) => {
34
+ var _b = _a, { className, variant, size, onRemove, removeLabel = "Remove", children } = _b, props = __objRest(_b, ["className", "variant", "size", "onRemove", "removeLabel", "children"]);
35
+ return /* @__PURE__ */ jsxs(
36
+ "span",
37
+ __spreadProps(__spreadValues({
38
+ ref,
39
+ "data-slot": "tag",
40
+ className: cn(tagVariants({ variant, size }), className)
41
+ }, props), {
42
+ children: [
43
+ children,
44
+ onRemove && /* @__PURE__ */ jsx(
45
+ "button",
46
+ {
47
+ type: "button",
48
+ "aria-label": removeLabel,
49
+ onClick: onRemove,
50
+ className: "-mr-0.5 inline-flex size-3.5 items-center justify-center rounded-full transition-colors hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
51
+ children: /* @__PURE__ */ jsx(X, { className: "size-3" })
52
+ }
53
+ )
54
+ ]
55
+ })
56
+ );
57
+ }
58
+ );
59
+ Tag.displayName = "Tag";
60
+
61
+ export { Tag, tagVariants };
@@ -35,7 +35,7 @@ var AccordionTrigger = React.forwardRef((_a, ref) => {
35
35
  }, props), {
36
36
  children: [
37
37
  children,
38
- /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground transition-transform duration-200" })
38
+ /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground transition-transform duration-[var(--duration-quick)] ease-[var(--ease-standard)]" })
39
39
  ]
40
40
  })
41
41
  ) });
@@ -5,9 +5,10 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const badgeVariants: (props?: ({
7
7
  variant?: "default" | "destructive" | "outline" | "secondary" | "glass" | "brown" | "success" | "warning" | "overlay" | null | undefined;
8
+ live?: boolean | null | undefined;
8
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
10
  interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
10
11
  }
11
- declare function Badge({ className, variant, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
12
+ declare function Badge({ className, variant, live, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
12
13
 
13
14
  export { Badge, type BadgeProps, badgeVariants };
@@ -1,3 +1,3 @@
1
- export { Badge, badgeVariants } from '../chunk-YJ6OBKZJ.js';
1
+ export { Badge, badgeVariants } from '../chunk-TL4YU2O5.js';
2
2
  import '../chunk-FEK5XGZW.js';
3
3
  import '../chunk-3GWWZKX7.js';