@clubmed/trident-ui 2.0.0-beta.62 → 2.0.0-beta.64
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/examples/journey-card-compact-demo.d.ts +1 -0
- package/examples/journey-card-compact-demo.js +71 -0
- package/examples/journey-card-compact-demo.js.map +1 -0
- package/examples/journey-card-demo.d.ts +1 -0
- package/examples/journey-card-demo.js +123 -0
- package/examples/journey-card-demo.js.map +1 -0
- package/examples/tabs-notification-demo.d.ts +1 -0
- package/examples/tabs-notification-demo.js +64 -0
- package/examples/tabs-notification-demo.js.map +1 -0
- package/package.json +1 -1
- package/ui/PageNavigation.js +1 -1
- package/ui/PageNavigation.js.map +1 -1
- package/ui/journey-card/FlightSegmentCard.d.ts +15 -0
- package/ui/journey-card/FlightSegmentCard.js +73 -0
- package/ui/journey-card/FlightSegmentCard.js.map +1 -0
- package/ui/journey-card/FlightTimeline.d.ts +5 -0
- package/ui/journey-card/FlightTimeline.js +27 -0
- package/ui/journey-card/FlightTimeline.js.map +1 -0
- package/ui/journey-card/ItineraryDetails.d.ts +9 -0
- package/ui/journey-card/ItineraryDetails.js +40 -0
- package/ui/journey-card/ItineraryDetails.js.map +1 -0
- package/ui/journey-card/JourneyCard.d.ts +17 -0
- package/ui/journey-card/JourneyCard.js +34 -0
- package/ui/journey-card/JourneyCard.js.map +1 -0
- package/ui/journey-card/JourneyDetails.d.ts +47 -0
- package/ui/journey-card/JourneyDetails.js +183 -0
- package/ui/journey-card/JourneyDetails.js.map +1 -0
- package/ui/tabs/Tabs.d.ts +5 -1
- package/ui/tabs/Tabs.js +49 -43
- package/ui/tabs/Tabs.js.map +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function JourneyCardCompactDemo(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { JourneyCard as e } from "../ui/journey-card/JourneyCard.js";
|
|
3
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
4
|
+
//#region lib/examples/journey-card-compact-demo.tsx
|
|
5
|
+
var n = {
|
|
6
|
+
direction: "Outbound",
|
|
7
|
+
directionType: "Outbound",
|
|
8
|
+
departureDate: "10 Apr. 2026",
|
|
9
|
+
departureTime: "11:55",
|
|
10
|
+
arrivalDate: "11 Apr. 2026",
|
|
11
|
+
arrivalTime: "15:25",
|
|
12
|
+
duration: "9h30mn",
|
|
13
|
+
departureAirport: {
|
|
14
|
+
name: "Paris-Orly",
|
|
15
|
+
terminal: "Terminal 2"
|
|
16
|
+
},
|
|
17
|
+
arrivalAirport: {
|
|
18
|
+
name: "Punta Cana",
|
|
19
|
+
terminal: "Terminal 2E"
|
|
20
|
+
},
|
|
21
|
+
stopLabel: "Direct",
|
|
22
|
+
airlineLogoSrc: "https://dummyimage.com/100x28/ccc/555.png&text=Airline",
|
|
23
|
+
airlineLogoAlt: "Transavia logo",
|
|
24
|
+
operatedBy: "Transavia",
|
|
25
|
+
characteristics: "Economy class, (x1) checked luggage per person — Boeing 777-300e",
|
|
26
|
+
carbonEmission: "A total of 750 kg CO₂ emitted.",
|
|
27
|
+
carbonEmissionLearnMoreLabel: "Learn more",
|
|
28
|
+
plusDaysLabel: "day",
|
|
29
|
+
localTimeLabel: "(local time)"
|
|
30
|
+
}, r = {
|
|
31
|
+
direction: "Inbound",
|
|
32
|
+
directionType: "Inbound",
|
|
33
|
+
departureDate: "16 Apr. 2026",
|
|
34
|
+
departureTime: "17:50",
|
|
35
|
+
arrivalDate: "17 Apr. 2026",
|
|
36
|
+
arrivalTime: "08:20",
|
|
37
|
+
duration: "8h40mn",
|
|
38
|
+
departureAirport: {
|
|
39
|
+
name: "Punta Cana",
|
|
40
|
+
terminal: "Terminal 2E"
|
|
41
|
+
},
|
|
42
|
+
arrivalAirport: {
|
|
43
|
+
name: "Paris-Orly",
|
|
44
|
+
terminal: "Terminal 2"
|
|
45
|
+
},
|
|
46
|
+
stopLabel: "1 Stop over",
|
|
47
|
+
nbStopovers: 1,
|
|
48
|
+
airlineLogoSrc: "https://dummyimage.com/100x28/ccc/555.png&text=Airline",
|
|
49
|
+
airlineLogoAlt: "Transavia logo",
|
|
50
|
+
operatedBy: "Transavia",
|
|
51
|
+
characteristics: "Economy class, (x1) checked luggage per person — Boeing 777-300e",
|
|
52
|
+
carbonEmission: "A total of 750 kg CO₂ emitted.",
|
|
53
|
+
carbonEmissionLearnMoreLabel: "Learn more",
|
|
54
|
+
plusDays: 1,
|
|
55
|
+
plusDaysLabel: "day",
|
|
56
|
+
localTimeLabel: "(local time)"
|
|
57
|
+
};
|
|
58
|
+
function i() {
|
|
59
|
+
return /* @__PURE__ */ t("div", {
|
|
60
|
+
className: "w-full",
|
|
61
|
+
children: /* @__PURE__ */ t(e, {
|
|
62
|
+
compact: !0,
|
|
63
|
+
flight1Journey: n,
|
|
64
|
+
flight2Journey: r
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { i as default };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=journey-card-compact-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journey-card-compact-demo.js","names":[],"sources":["../../lib/examples/journey-card-compact-demo.tsx"],"sourcesContent":["'use client';\n\nimport { JourneyCard } from '@/ui/journey-card/JourneyCard';\nimport type { JourneyDetailsProps } from '@/ui/journey-card/JourneyDetails';\n\nconst outbound: JourneyDetailsProps = {\n direction: 'Outbound',\n directionType: 'Outbound',\n departureDate: '10 Apr. 2026',\n departureTime: '11:55',\n arrivalDate: '11 Apr. 2026',\n arrivalTime: '15:25',\n duration: '9h30mn',\n departureAirport: { name: 'Paris-Orly', terminal: 'Terminal 2' },\n arrivalAirport: { name: 'Punta Cana', terminal: 'Terminal 2E' },\n stopLabel: 'Direct',\n airlineLogoSrc: 'https://dummyimage.com/100x28/ccc/555.png&text=Airline',\n airlineLogoAlt: 'Transavia logo',\n operatedBy: 'Transavia',\n characteristics: 'Economy class, (x1) checked luggage per person — Boeing 777-300e',\n carbonEmission: 'A total of 750 kg CO₂ emitted.',\n carbonEmissionLearnMoreLabel: 'Learn more',\n plusDaysLabel: 'day',\n localTimeLabel: '(local time)',\n};\n\nconst inbound: JourneyDetailsProps = {\n direction: 'Inbound',\n directionType: 'Inbound',\n departureDate: '16 Apr. 2026',\n departureTime: '17:50',\n arrivalDate: '17 Apr. 2026',\n arrivalTime: '08:20',\n duration: '8h40mn',\n departureAirport: { name: 'Punta Cana', terminal: 'Terminal 2E' },\n arrivalAirport: { name: 'Paris-Orly', terminal: 'Terminal 2' },\n stopLabel: '1 Stop over',\n nbStopovers: 1,\n airlineLogoSrc: 'https://dummyimage.com/100x28/ccc/555.png&text=Airline',\n airlineLogoAlt: 'Transavia logo',\n operatedBy: 'Transavia',\n characteristics: 'Economy class, (x1) checked luggage per person — Boeing 777-300e',\n carbonEmission: 'A total of 750 kg CO₂ emitted.',\n carbonEmissionLearnMoreLabel: 'Learn more',\n plusDays: 1,\n plusDaysLabel: 'day',\n localTimeLabel: '(local time)',\n};\n\nexport default function JourneyCardCompactDemo() {\n return (\n <div className=\"w-full\">\n <JourneyCard compact flight1Journey={outbound} flight2Journey={inbound} />\n </div>\n );\n}\n"],"mappings":";;;;AAKA,IAAM,IAAgC;CACpC,WAAW;CACX,eAAe;CACf,eAAe;CACf,eAAe;CACf,aAAa;CACb,aAAa;CACb,UAAU;CACV,kBAAkB;EAAE,MAAM;EAAc,UAAU;EAAc;CAChE,gBAAgB;EAAE,MAAM;EAAc,UAAU;EAAe;CAC/D,WAAW;CACX,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;CACZ,iBAAiB;CACjB,gBAAgB;CAChB,8BAA8B;CAC9B,eAAe;CACf,gBAAgB;CACjB,EAEK,IAA+B;CACnC,WAAW;CACX,eAAe;CACf,eAAe;CACf,eAAe;CACf,aAAa;CACb,aAAa;CACb,UAAU;CACV,kBAAkB;EAAE,MAAM;EAAc,UAAU;EAAe;CACjE,gBAAgB;EAAE,MAAM;EAAc,UAAU;EAAc;CAC9D,WAAW;CACX,aAAa;CACb,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;CACZ,iBAAiB;CACjB,gBAAgB;CAChB,8BAA8B;CAC9B,UAAU;CACV,eAAe;CACf,gBAAgB;CACjB;AAED,SAAwB,IAAyB;AAC/C,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GAAa,SAAA;GAAQ,gBAAgB;GAAU,gBAAgB;GAAW,CAAA;EACtE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function JourneyCardDemo(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { JourneyCard as e } from "../ui/journey-card/JourneyCard.js";
|
|
3
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
4
|
+
//#region lib/examples/journey-card-demo.tsx
|
|
5
|
+
var n = {
|
|
6
|
+
direction: "Outbound",
|
|
7
|
+
directionType: "Outbound",
|
|
8
|
+
departureDate: "10 Apr. 2026",
|
|
9
|
+
departureTime: "11:55",
|
|
10
|
+
arrivalDate: "11 Apr. 2026",
|
|
11
|
+
arrivalTime: "15:25",
|
|
12
|
+
duration: "9h30mn",
|
|
13
|
+
departureAirport: {
|
|
14
|
+
name: "Paris-Orly",
|
|
15
|
+
terminal: "Terminal 2"
|
|
16
|
+
},
|
|
17
|
+
arrivalAirport: {
|
|
18
|
+
name: "Punta Cana",
|
|
19
|
+
terminal: "Terminal 2E"
|
|
20
|
+
},
|
|
21
|
+
stopLabel: "Direct",
|
|
22
|
+
airlineLogoSrc: "https://dummyimage.com/100x28/ccc/555.png&text=Airline",
|
|
23
|
+
airlineLogoAlt: "Transavia logo",
|
|
24
|
+
operatedBy: "Transavia",
|
|
25
|
+
companyName: "Operated by Hop",
|
|
26
|
+
characteristics: "Economy class, (x1) checked luggage per person — Boeing 777-300e",
|
|
27
|
+
carbonEmission: "A total of 750 kg CO₂ emitted.",
|
|
28
|
+
carbonEmissionLearnMoreUrl: "#",
|
|
29
|
+
carbonEmissionLearnMoreLabel: "Learn more",
|
|
30
|
+
plusDays: 1,
|
|
31
|
+
plusDaysLabel: "day",
|
|
32
|
+
localTimeLabel: "(local time)",
|
|
33
|
+
itinerary: {
|
|
34
|
+
segments: [{
|
|
35
|
+
flightNumber: "LX 633 Transavia",
|
|
36
|
+
departureTime: "09:45",
|
|
37
|
+
arrivalTime: "11:05",
|
|
38
|
+
departureAirport: {
|
|
39
|
+
name: "Paris-Roissy CDG",
|
|
40
|
+
terminal: "Terminal 2"
|
|
41
|
+
},
|
|
42
|
+
arrivalAirport: {
|
|
43
|
+
name: "Zurich",
|
|
44
|
+
terminal: "Terminal 2E"
|
|
45
|
+
},
|
|
46
|
+
arrivalDate: "Arrival: 11 Apr. 2026"
|
|
47
|
+
}],
|
|
48
|
+
flexibleOption: "Flexible flight option\n• Cancellation fees limited to €300\n• Baggage included"
|
|
49
|
+
}
|
|
50
|
+
}, r = {
|
|
51
|
+
direction: "Inbound",
|
|
52
|
+
directionType: "Inbound",
|
|
53
|
+
departureDate: "16 Apr. 2026",
|
|
54
|
+
departureTime: "17:50",
|
|
55
|
+
arrivalDate: "17 Apr. 2026",
|
|
56
|
+
arrivalTime: "08:20",
|
|
57
|
+
duration: "8h40mn",
|
|
58
|
+
departureAirport: {
|
|
59
|
+
name: "Punta Cana",
|
|
60
|
+
terminal: "Terminal 2E"
|
|
61
|
+
},
|
|
62
|
+
arrivalAirport: {
|
|
63
|
+
name: "Paris-Orly",
|
|
64
|
+
terminal: "Terminal 2"
|
|
65
|
+
},
|
|
66
|
+
stopLabel: "1 Stop over",
|
|
67
|
+
nbStopovers: 1,
|
|
68
|
+
airlineLogoSrc: "https://dummyimage.com/100x28/ccc/555.png&text=Airline",
|
|
69
|
+
airlineLogoAlt: "Transavia logo",
|
|
70
|
+
operatedBy: "Transavia",
|
|
71
|
+
companyName: "Operated by Hop",
|
|
72
|
+
characteristics: "Economy class, (x1) checked luggage per person — Boeing 777-300e",
|
|
73
|
+
carbonEmission: "A total of 750 kg CO₂ emitted.",
|
|
74
|
+
carbonEmissionLearnMoreUrl: "#",
|
|
75
|
+
carbonEmissionLearnMoreLabel: "Learn more",
|
|
76
|
+
plusDays: 1,
|
|
77
|
+
plusDaysLabel: "day",
|
|
78
|
+
localTimeLabel: "(local time)",
|
|
79
|
+
itinerary: {
|
|
80
|
+
segments: [{
|
|
81
|
+
flightNumber: "LX 630 Transavia",
|
|
82
|
+
departureTime: "09:45",
|
|
83
|
+
arrivalTime: "11:05",
|
|
84
|
+
departureAirport: {
|
|
85
|
+
name: "Punta Cana",
|
|
86
|
+
terminal: "Terminal 2E"
|
|
87
|
+
},
|
|
88
|
+
arrivalAirport: {
|
|
89
|
+
name: "Zurich",
|
|
90
|
+
terminal: "Terminal 2E"
|
|
91
|
+
},
|
|
92
|
+
arrivalDate: "Arrival: 16 Apr. 2026"
|
|
93
|
+
}, {
|
|
94
|
+
flightNumber: "LX 654 Transavia",
|
|
95
|
+
departureTime: "12:30",
|
|
96
|
+
arrivalTime: "08:20",
|
|
97
|
+
departureAirport: {
|
|
98
|
+
name: "Zurich",
|
|
99
|
+
terminal: "Terminal 2E"
|
|
100
|
+
},
|
|
101
|
+
arrivalAirport: {
|
|
102
|
+
name: "Paris-Orly",
|
|
103
|
+
terminal: "Terminal 2"
|
|
104
|
+
},
|
|
105
|
+
arrivalDate: "Arrival: 17 Apr. 2026"
|
|
106
|
+
}],
|
|
107
|
+
connectionTime: "1h10min : Airport connection",
|
|
108
|
+
flexibleOption: "Flexible flight option\n• Cancellation fees limited to €300\n• Baggage included"
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
function i() {
|
|
112
|
+
return /* @__PURE__ */ t("div", {
|
|
113
|
+
className: "w-full",
|
|
114
|
+
children: /* @__PURE__ */ t(e, {
|
|
115
|
+
flight1Journey: n,
|
|
116
|
+
flight2Journey: r
|
|
117
|
+
})
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
export { i as default };
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=journey-card-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journey-card-demo.js","names":[],"sources":["../../lib/examples/journey-card-demo.tsx"],"sourcesContent":["'use client';\n\nimport { JourneyCard } from '@/ui/journey-card/JourneyCard';\nimport type { JourneyDetailsProps } from '@/ui/journey-card/JourneyDetails';\n\nconst outbound: JourneyDetailsProps = {\n direction: 'Outbound',\n directionType: 'Outbound',\n departureDate: '10 Apr. 2026',\n departureTime: '11:55',\n arrivalDate: '11 Apr. 2026',\n arrivalTime: '15:25',\n duration: '9h30mn',\n departureAirport: { name: 'Paris-Orly', terminal: 'Terminal 2' },\n arrivalAirport: { name: 'Punta Cana', terminal: 'Terminal 2E' },\n stopLabel: 'Direct',\n airlineLogoSrc: 'https://dummyimage.com/100x28/ccc/555.png&text=Airline',\n airlineLogoAlt: 'Transavia logo',\n operatedBy: 'Transavia',\n companyName: 'Operated by Hop',\n characteristics: 'Economy class, (x1) checked luggage per person — Boeing 777-300e',\n carbonEmission: 'A total of 750 kg CO₂ emitted.',\n carbonEmissionLearnMoreUrl: '#',\n carbonEmissionLearnMoreLabel: 'Learn more',\n plusDays: 1,\n plusDaysLabel: 'day',\n localTimeLabel: '(local time)',\n itinerary: {\n segments: [\n {\n flightNumber: 'LX 633 Transavia',\n departureTime: '09:45',\n arrivalTime: '11:05',\n departureAirport: { name: 'Paris-Roissy CDG', terminal: 'Terminal 2' },\n arrivalAirport: { name: 'Zurich', terminal: 'Terminal 2E' },\n arrivalDate: 'Arrival: 11 Apr. 2026',\n },\n ],\n flexibleOption:\n 'Flexible flight option\\n• Cancellation fees limited to €300\\n• Baggage included',\n },\n};\n\nconst inbound: JourneyDetailsProps = {\n direction: 'Inbound',\n directionType: 'Inbound',\n departureDate: '16 Apr. 2026',\n departureTime: '17:50',\n arrivalDate: '17 Apr. 2026',\n arrivalTime: '08:20',\n duration: '8h40mn',\n departureAirport: { name: 'Punta Cana', terminal: 'Terminal 2E' },\n arrivalAirport: { name: 'Paris-Orly', terminal: 'Terminal 2' },\n stopLabel: '1 Stop over',\n nbStopovers: 1,\n airlineLogoSrc: 'https://dummyimage.com/100x28/ccc/555.png&text=Airline',\n airlineLogoAlt: 'Transavia logo',\n operatedBy: 'Transavia',\n companyName: 'Operated by Hop',\n characteristics: 'Economy class, (x1) checked luggage per person — Boeing 777-300e',\n carbonEmission: 'A total of 750 kg CO₂ emitted.',\n carbonEmissionLearnMoreUrl: '#',\n carbonEmissionLearnMoreLabel: 'Learn more',\n plusDays: 1,\n plusDaysLabel: 'day',\n localTimeLabel: '(local time)',\n itinerary: {\n segments: [\n {\n flightNumber: 'LX 630 Transavia',\n departureTime: '09:45',\n arrivalTime: '11:05',\n departureAirport: { name: 'Punta Cana', terminal: 'Terminal 2E' },\n arrivalAirport: { name: 'Zurich', terminal: 'Terminal 2E' },\n arrivalDate: 'Arrival: 16 Apr. 2026',\n },\n {\n flightNumber: 'LX 654 Transavia',\n departureTime: '12:30',\n arrivalTime: '08:20',\n departureAirport: { name: 'Zurich', terminal: 'Terminal 2E' },\n arrivalAirport: { name: 'Paris-Orly', terminal: 'Terminal 2' },\n arrivalDate: 'Arrival: 17 Apr. 2026',\n },\n ],\n connectionTime: '1h10min : Airport connection',\n flexibleOption:\n 'Flexible flight option\\n• Cancellation fees limited to €300\\n• Baggage included',\n },\n};\n\nexport default function JourneyCardDemo() {\n return (\n <div className=\"w-full\">\n <JourneyCard flight1Journey={outbound} flight2Journey={inbound} />\n </div>\n );\n}\n"],"mappings":";;;;AAKA,IAAM,IAAgC;CACpC,WAAW;CACX,eAAe;CACf,eAAe;CACf,eAAe;CACf,aAAa;CACb,aAAa;CACb,UAAU;CACV,kBAAkB;EAAE,MAAM;EAAc,UAAU;EAAc;CAChE,gBAAgB;EAAE,MAAM;EAAc,UAAU;EAAe;CAC/D,WAAW;CACX,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,iBAAiB;CACjB,gBAAgB;CAChB,4BAA4B;CAC5B,8BAA8B;CAC9B,UAAU;CACV,eAAe;CACf,gBAAgB;CAChB,WAAW;EACT,UAAU,CACR;GACE,cAAc;GACd,eAAe;GACf,aAAa;GACb,kBAAkB;IAAE,MAAM;IAAoB,UAAU;IAAc;GACtE,gBAAgB;IAAE,MAAM;IAAU,UAAU;IAAe;GAC3D,aAAa;GACd,CACF;EACD,gBACE;;CAEL,EAEK,IAA+B;CACnC,WAAW;CACX,eAAe;CACf,eAAe;CACf,eAAe;CACf,aAAa;CACb,aAAa;CACb,UAAU;CACV,kBAAkB;EAAE,MAAM;EAAc,UAAU;EAAe;CACjE,gBAAgB;EAAE,MAAM;EAAc,UAAU;EAAc;CAC9D,WAAW;CACX,aAAa;CACb,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,iBAAiB;CACjB,gBAAgB;CAChB,4BAA4B;CAC5B,8BAA8B;CAC9B,UAAU;CACV,eAAe;CACf,gBAAgB;CAChB,WAAW;EACT,UAAU,CACR;GACE,cAAc;GACd,eAAe;GACf,aAAa;GACb,kBAAkB;IAAE,MAAM;IAAc,UAAU;IAAe;GACjE,gBAAgB;IAAE,MAAM;IAAU,UAAU;IAAe;GAC3D,aAAa;GACd,EACD;GACE,cAAc;GACd,eAAe;GACf,aAAa;GACb,kBAAkB;IAAE,MAAM;IAAU,UAAU;IAAe;GAC7D,gBAAgB;IAAE,MAAM;IAAc,UAAU;IAAc;GAC9D,aAAa;GACd,CACF;EACD,gBAAgB;EAChB,gBACE;;CAEL;AAED,SAAwB,IAAkB;AACxC,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GAAa,gBAAgB;GAAU,gBAAgB;GAAW,CAAA;EAC9D,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function TabsNotificationDemo(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Tab as e, TabList as t, TabPanel as n, Tabs as r, TabsBody as i } from "../ui/tabs/Tabs.js";
|
|
2
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
3
|
+
//#region lib/examples/tabs-notification-demo.tsx
|
|
4
|
+
function s() {
|
|
5
|
+
return /* @__PURE__ */ o(r, {
|
|
6
|
+
selected: 1,
|
|
7
|
+
children: [/* @__PURE__ */ o(t, {
|
|
8
|
+
constrained: !0,
|
|
9
|
+
children: [
|
|
10
|
+
/* @__PURE__ */ a(e, {
|
|
11
|
+
label: "Overview",
|
|
12
|
+
value: 1
|
|
13
|
+
}),
|
|
14
|
+
/* @__PURE__ */ a(e, {
|
|
15
|
+
label: "Messages",
|
|
16
|
+
value: 2,
|
|
17
|
+
notification: 3
|
|
18
|
+
}),
|
|
19
|
+
/* @__PURE__ */ a(e, {
|
|
20
|
+
label: "Alerts",
|
|
21
|
+
value: 3,
|
|
22
|
+
notification: "!"
|
|
23
|
+
}),
|
|
24
|
+
/* @__PURE__ */ a(e, {
|
|
25
|
+
label: "Settings",
|
|
26
|
+
value: 4
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
}), /* @__PURE__ */ o(i, { children: [
|
|
30
|
+
/* @__PURE__ */ a(n, {
|
|
31
|
+
value: 1,
|
|
32
|
+
children: /* @__PURE__ */ a("div", {
|
|
33
|
+
className: "p-16 bg-lightSand",
|
|
34
|
+
children: "Overview panel"
|
|
35
|
+
})
|
|
36
|
+
}),
|
|
37
|
+
/* @__PURE__ */ a(n, {
|
|
38
|
+
value: 2,
|
|
39
|
+
children: /* @__PURE__ */ a("div", {
|
|
40
|
+
className: "p-16 bg-saffron",
|
|
41
|
+
children: "3 unread messages"
|
|
42
|
+
})
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ a(n, {
|
|
45
|
+
value: 3,
|
|
46
|
+
children: /* @__PURE__ */ a("div", {
|
|
47
|
+
className: "p-16 bg-lavender",
|
|
48
|
+
children: "Alerts panel"
|
|
49
|
+
})
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ a(n, {
|
|
52
|
+
value: 4,
|
|
53
|
+
children: /* @__PURE__ */ a("div", {
|
|
54
|
+
className: "p-16 bg-lightSand",
|
|
55
|
+
children: "Settings panel"
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
] })]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { s as default };
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=tabs-notification-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs-notification-demo.js","names":[],"sources":["../../lib/examples/tabs-notification-demo.tsx"],"sourcesContent":["import { Tab, TabList, TabPanel, Tabs, TabsBody } from '../ui/tabs/Tabs';\n\nexport default function TabsNotificationDemo() {\n return (\n <Tabs selected={1}>\n <TabList constrained>\n <Tab label=\"Overview\" value={1} />\n <Tab label=\"Messages\" value={2} notification={3} />\n <Tab label=\"Alerts\" value={3} notification=\"!\" />\n <Tab label=\"Settings\" value={4} />\n </TabList>\n <TabsBody>\n <TabPanel value={1}>\n <div className=\"p-16 bg-lightSand\">Overview panel</div>\n </TabPanel>\n <TabPanel value={2}>\n <div className=\"p-16 bg-saffron\">3 unread messages</div>\n </TabPanel>\n <TabPanel value={3}>\n <div className=\"p-16 bg-lavender\">Alerts panel</div>\n </TabPanel>\n <TabPanel value={4}>\n <div className=\"p-16 bg-lightSand\">Settings panel</div>\n </TabPanel>\n </TabsBody>\n </Tabs>\n );\n}\n"],"mappings":";;;AAEA,SAAwB,IAAuB;AAC7C,QACE,kBAAC,GAAD;EAAM,UAAU;YAAhB,CACE,kBAAC,GAAD;GAAS,aAAA;aAAT;IACE,kBAAC,GAAD;KAAK,OAAM;KAAW,OAAO;KAAK,CAAA;IAClC,kBAAC,GAAD;KAAK,OAAM;KAAW,OAAO;KAAG,cAAc;KAAK,CAAA;IACnD,kBAAC,GAAD;KAAK,OAAM;KAAS,OAAO;KAAG,cAAa;KAAM,CAAA;IACjD,kBAAC,GAAD;KAAK,OAAM;KAAW,OAAO;KAAK,CAAA;IAC1B;MACV,kBAAC,GAAD,EAAA,UAAA;GACE,kBAAC,GAAD;IAAU,OAAO;cACf,kBAAC,OAAD;KAAK,WAAU;eAAoB;KAAoB,CAAA;IAC9C,CAAA;GACX,kBAAC,GAAD;IAAU,OAAO;cACf,kBAAC,OAAD;KAAK,WAAU;eAAkB;KAAuB,CAAA;IAC/C,CAAA;GACX,kBAAC,GAAD;IAAU,OAAO;cACf,kBAAC,OAAD;KAAK,WAAU;eAAmB;KAAkB,CAAA;IAC3C,CAAA;GACX,kBAAC,GAAD;IAAU,OAAO;cACf,kBAAC,OAAD;KAAK,WAAU;eAAoB;KAAoB,CAAA;IAC9C,CAAA;GACF,EAAA,CAAA,CACN"}
|
package/package.json
CHANGED
package/ui/PageNavigation.js
CHANGED
|
@@ -44,7 +44,7 @@ var o = {
|
|
|
44
44
|
href: t.href,
|
|
45
45
|
"aria-current": n ? "page" : void 0,
|
|
46
46
|
style: n ? s : void 0,
|
|
47
|
-
className: e("relative z-10 grid items-center justify-center gap-2 rounded-pill", "font-sans text-b3 font-
|
|
47
|
+
className: e("relative z-10 grid items-center justify-center gap-2 rounded-pill", "font-sans text-b3 font-semibold focus-visible:ring-8 focus-visible:ring-lavender/20 outline-none", n ? "[@supports(not(anchor-name:--x))]:bg-black" : "focus:bg-pearl", n ? "px-20 py-12" : "md:px-20 md:py-12", n ? "text-white" : "text-black"),
|
|
48
48
|
children: [t.icon && /* @__PURE__ */ i("div", {
|
|
49
49
|
className: e("row-start-1 row-end-1 col-start-1 col-end-1 flex items-center justify-center transition-opacity duration-300 md:hidden", "md:opacity-0 transition-opacity mx-auto", n && "opacity-0"),
|
|
50
50
|
"aria-hidden": "true",
|
package/ui/PageNavigation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageNavigation.js","names":[],"sources":["../../lib/ui/PageNavigation.tsx"],"sourcesContent":["'use client';\n\nimport type {\n ComponentPropsWithoutRef,\n CSSProperties,\n FunctionComponent,\n KeyboardEvent,\n} from 'react';\nimport { useCallback, useRef } from 'react';\nimport clsx from 'clsx';\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\n\nexport interface PageNavigationItem {\n id: string;\n label: string;\n href: string;\n icon?: IconicNames;\n}\n\nexport interface PageNavigationProps extends ComponentPropsWithoutRef<'nav'> {\n items: PageNavigationItem[];\n activeItem: string;\n}\n\n// Static — hoisted outside component so it's not recreated on every render\nconst PILL_STYLE: CSSProperties = {\n positionAnchor: '--page-nav-active',\n top: 'anchor(top)',\n bottom: 'anchor(bottom)',\n left: 'anchor(left)',\n right: 'anchor(right)',\n position: 'absolute',\n};\n\nconst ACTIVE_ANCHOR_STYLE: CSSProperties = { anchorName: '--page-nav-active' };\n\nconst PILL = (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute rounded-pill bg-black transition-all duration-300 [position-anchor:--page-nav-active]\"\n style={PILL_STYLE}\n />\n);\n\nexport const PageNavigation: FunctionComponent<PageNavigationProps> = ({\n items,\n activeItem,\n className,\n ...attrs\n}) => {\n const listRef = useRef<HTMLUListElement>(null);\n\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLUListElement>) => {\n const links = Array.from(listRef.current?.querySelectorAll<HTMLAnchorElement>('a') ?? []);\n const focused = links.indexOf(document.activeElement as HTMLAnchorElement);\n if (focused === -1) return;\n\n let next = focused;\n if (e.key === 'ArrowRight') next = (focused + 1) % links.length;\n else if (e.key === 'ArrowLeft') next = (focused - 1 + links.length) % links.length;\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = links.length - 1;\n else return;\n\n e.preventDefault();\n links[next].focus();\n }, []);\n\n return (\n <nav aria-label=\"Page navigation\" {...attrs} className={clsx('flex items-center', className)}>\n <ul\n ref={listRef}\n onKeyDown={handleKeyDown}\n className=\"relative flex items-center gap-4 md:gap-16\"\n role=\"list\"\n >\n {PILL}\n\n {items.map((item) => {\n const isActive = item.id === activeItem;\n\n return (\n <li key={item.id} className=\"relative\">\n <a\n href={item.href}\n aria-current={isActive ? 'page' : undefined}\n style={isActive ? ACTIVE_ANCHOR_STYLE : undefined}\n className={clsx(\n 'relative z-10 grid items-center justify-center gap-2 rounded-pill',\n 'font-sans text-b3 font-
|
|
1
|
+
{"version":3,"file":"PageNavigation.js","names":[],"sources":["../../lib/ui/PageNavigation.tsx"],"sourcesContent":["'use client';\n\nimport type {\n ComponentPropsWithoutRef,\n CSSProperties,\n FunctionComponent,\n KeyboardEvent,\n} from 'react';\nimport { useCallback, useRef } from 'react';\nimport clsx from 'clsx';\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\n\nexport interface PageNavigationItem {\n id: string;\n label: string;\n href: string;\n icon?: IconicNames;\n}\n\nexport interface PageNavigationProps extends ComponentPropsWithoutRef<'nav'> {\n items: PageNavigationItem[];\n activeItem: string;\n}\n\n// Static — hoisted outside component so it's not recreated on every render\nconst PILL_STYLE: CSSProperties = {\n positionAnchor: '--page-nav-active',\n top: 'anchor(top)',\n bottom: 'anchor(bottom)',\n left: 'anchor(left)',\n right: 'anchor(right)',\n position: 'absolute',\n};\n\nconst ACTIVE_ANCHOR_STYLE: CSSProperties = { anchorName: '--page-nav-active' };\n\nconst PILL = (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute rounded-pill bg-black transition-all duration-300 [position-anchor:--page-nav-active]\"\n style={PILL_STYLE}\n />\n);\n\nexport const PageNavigation: FunctionComponent<PageNavigationProps> = ({\n items,\n activeItem,\n className,\n ...attrs\n}) => {\n const listRef = useRef<HTMLUListElement>(null);\n\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLUListElement>) => {\n const links = Array.from(listRef.current?.querySelectorAll<HTMLAnchorElement>('a') ?? []);\n const focused = links.indexOf(document.activeElement as HTMLAnchorElement);\n if (focused === -1) return;\n\n let next = focused;\n if (e.key === 'ArrowRight') next = (focused + 1) % links.length;\n else if (e.key === 'ArrowLeft') next = (focused - 1 + links.length) % links.length;\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = links.length - 1;\n else return;\n\n e.preventDefault();\n links[next].focus();\n }, []);\n\n return (\n <nav aria-label=\"Page navigation\" {...attrs} className={clsx('flex items-center', className)}>\n <ul\n ref={listRef}\n onKeyDown={handleKeyDown}\n className=\"relative flex items-center gap-4 md:gap-16\"\n role=\"list\"\n >\n {PILL}\n\n {items.map((item) => {\n const isActive = item.id === activeItem;\n\n return (\n <li key={item.id} className=\"relative\">\n <a\n href={item.href}\n aria-current={isActive ? 'page' : undefined}\n style={isActive ? ACTIVE_ANCHOR_STYLE : undefined}\n className={clsx(\n 'relative z-10 grid items-center justify-center gap-2 rounded-pill',\n 'font-sans text-b3 font-semibold focus-visible:ring-8 focus-visible:ring-lavender/20 outline-none',\n isActive ? '[@supports(not(anchor-name:--x))]:bg-black' : 'focus:bg-pearl',\n isActive ? 'px-20 py-12' : 'md:px-20 md:py-12',\n isActive ? 'text-white' : 'text-black',\n )}\n >\n {item.icon && (\n <div\n className={clsx(\n 'row-start-1 row-end-1 col-start-1 col-end-1 flex items-center justify-center transition-opacity duration-300 md:hidden',\n 'md:opacity-0 transition-opacity mx-auto',\n isActive && 'opacity-0',\n )}\n aria-hidden=\"true\"\n >\n <Icon name={item.icon} width=\"30px\" />\n </div>\n )}\n\n <span\n className={clsx(\n 'row-start-1 row-end-1 col-start-1 col-end-1 grid grid-cols-[0fr] md:grid-cols-[1fr] overflow-hidden transition-all opacity-0 duration-300 md:opacity-100 text-center',\n isActive && 'grid-cols-[1fr] opacity-100',\n )}\n >\n <span className=\"overflow-hidden mx-auto\">{item.label}</span>\n </span>\n </a>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n};\n"],"mappings":";;;;;;AAyBA,IAAM,IAA4B;CAChC,gBAAgB;CAChB,KAAK;CACL,QAAQ;CACR,MAAM;CACN,OAAO;CACP,UAAU;CACX,EAEK,IAAqC,EAAE,YAAY,qBAAqB,EAExE,IACJ,kBAAC,QAAD;CACE,eAAY;CACZ,WAAU;CACV,OAAO;CACP,CAAA,EAGS,KAA0D,EACrE,UACA,eACA,cACA,GAAG,QACC;CACJ,IAAM,IAAU,EAAyB,KAAK,EAExC,IAAgB,GAAa,MAAuC;EACxE,IAAM,IAAQ,MAAM,KAAK,EAAQ,SAAS,iBAAoC,IAAI,IAAI,EAAE,CAAC,EACnF,IAAU,EAAM,QAAQ,SAAS,cAAmC;AAC1E,MAAI,MAAY,GAAI;EAEpB,IAAI,IAAO;AACX,MAAI,EAAE,QAAQ,aAAc,MAAQ,IAAU,KAAK,EAAM;WAChD,EAAE,QAAQ,YAAa,MAAQ,IAAU,IAAI,EAAM,UAAU,EAAM;WACnE,EAAE,QAAQ,OAAQ,KAAO;WACzB,EAAE,QAAQ,MAAO,KAAO,EAAM,SAAS;MAC3C;AAGL,EADA,EAAE,gBAAgB,EAClB,EAAM,GAAM,OAAO;IAClB,EAAE,CAAC;AAEN,QACE,kBAAC,OAAD;EAAK,cAAW;EAAkB,GAAI;EAAO,WAAW,EAAK,qBAAqB,EAAU;YAC1F,kBAAC,MAAD;GACE,KAAK;GACL,WAAW;GACX,WAAU;GACV,MAAK;aAJP,CAMG,GAEA,EAAM,KAAK,MAAS;IACnB,IAAM,IAAW,EAAK,OAAO;AAE7B,WACE,kBAAC,MAAD;KAAkB,WAAU;eAC1B,kBAAC,KAAD;MACE,MAAM,EAAK;MACX,gBAAc,IAAW,SAAS,KAAA;MAClC,OAAO,IAAW,IAAsB,KAAA;MACxC,WAAW,EACT,qEACA,oGACA,IAAW,+CAA+C,kBAC1D,IAAW,gBAAgB,qBAC3B,IAAW,eAAe,aAC3B;gBAVH,CAYG,EAAK,QACJ,kBAAC,OAAD;OACE,WAAW,EACT,0HACA,2CACA,KAAY,YACb;OACD,eAAY;iBAEZ,kBAAC,GAAD;QAAM,MAAM,EAAK;QAAM,OAAM;QAAS,CAAA;OAClC,CAAA,EAGR,kBAAC,QAAD;OACE,WAAW,EACT,wKACA,KAAY,8BACb;iBAED,kBAAC,QAAD;QAAM,WAAU;kBAA2B,EAAK;QAAa,CAAA;OACxD,CAAA,CAAA;;KAEN,EAnCI,EAAK,GAmCT;KAEP,CAAA;;EAEA,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
export interface AirportInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
terminal?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FlightSegmentCardProps extends ComponentPropsWithoutRef<'div'> {
|
|
7
|
+
flightNumber: string;
|
|
8
|
+
departureTime: string;
|
|
9
|
+
arrivalTime: string;
|
|
10
|
+
departureAirport: AirportInfo;
|
|
11
|
+
arrivalAirport: AirportInfo;
|
|
12
|
+
arrivalDate?: string;
|
|
13
|
+
plusDays?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function FlightSegmentCard({ flightNumber, departureTime, arrivalTime, departureAirport, arrivalAirport, arrivalDate, className, ...props }: FlightSegmentCardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
2
|
+
import { FlightTimeline as t } from "./FlightTimeline.js";
|
|
3
|
+
import { Icon as n } from "@clubmed/trident-icons";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region lib/ui/journey-card/FlightSegmentCard.tsx
|
|
6
|
+
function a({ flightNumber: a, departureTime: o, arrivalTime: s, departureAirport: c, arrivalAirport: l, arrivalDate: u, className: d, ...f }) {
|
|
7
|
+
return /* @__PURE__ */ i("div", {
|
|
8
|
+
"data-name": "FlightSegmentCard",
|
|
9
|
+
...f,
|
|
10
|
+
className: e("flex h-fit w-full flex-col gap-12 rounded-32 bg-white p-20", d),
|
|
11
|
+
children: [/* @__PURE__ */ i("div", {
|
|
12
|
+
className: "flex h-24 w-full flex-row items-center gap-8",
|
|
13
|
+
children: [/* @__PURE__ */ r(n, {
|
|
14
|
+
name: "PlaneOutbound",
|
|
15
|
+
width: "24px",
|
|
16
|
+
className: "shrink-0 text-black"
|
|
17
|
+
}), /* @__PURE__ */ r("span", {
|
|
18
|
+
className: "font-sans text-b4",
|
|
19
|
+
children: a
|
|
20
|
+
})]
|
|
21
|
+
}), /* @__PURE__ */ i("div", {
|
|
22
|
+
className: "flex w-full flex-col gap-4",
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ i("div", {
|
|
25
|
+
className: "flex w-full flex-row items-end justify-between",
|
|
26
|
+
children: [/* @__PURE__ */ r("div", {
|
|
27
|
+
className: "flex flex-1 flex-col justify-center",
|
|
28
|
+
children: /* @__PURE__ */ r("span", {
|
|
29
|
+
className: "font-sans text-b3 font-semibold",
|
|
30
|
+
children: o
|
|
31
|
+
})
|
|
32
|
+
}), /* @__PURE__ */ i("div", {
|
|
33
|
+
className: "flex flex-col items-end justify-center",
|
|
34
|
+
children: [u && /* @__PURE__ */ r("span", {
|
|
35
|
+
className: "font-sans text-b4",
|
|
36
|
+
children: u
|
|
37
|
+
}), /* @__PURE__ */ r("span", {
|
|
38
|
+
className: "font-sans text-b3 font-semibold",
|
|
39
|
+
children: s
|
|
40
|
+
})]
|
|
41
|
+
})]
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ r(t, {}),
|
|
44
|
+
/* @__PURE__ */ i("div", {
|
|
45
|
+
className: "flex w-full flex-row items-start justify-between",
|
|
46
|
+
children: [/* @__PURE__ */ i("div", {
|
|
47
|
+
className: "flex w-120 min-w-120 flex-col",
|
|
48
|
+
children: [/* @__PURE__ */ r("span", {
|
|
49
|
+
className: "font-sans text-b4 font-semibold",
|
|
50
|
+
children: c.name
|
|
51
|
+
}), c.terminal && /* @__PURE__ */ r("span", {
|
|
52
|
+
className: "font-sans text-b4",
|
|
53
|
+
children: c.terminal
|
|
54
|
+
})]
|
|
55
|
+
}), /* @__PURE__ */ i("div", {
|
|
56
|
+
className: "flex w-120 min-w-120 flex-col items-end",
|
|
57
|
+
children: [/* @__PURE__ */ r("span", {
|
|
58
|
+
className: "font-sans text-b4 font-semibold",
|
|
59
|
+
children: l.name
|
|
60
|
+
}), l.terminal && /* @__PURE__ */ r("span", {
|
|
61
|
+
className: "font-sans text-b4 text-right",
|
|
62
|
+
children: l.terminal
|
|
63
|
+
})]
|
|
64
|
+
})]
|
|
65
|
+
})
|
|
66
|
+
]
|
|
67
|
+
})]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { a as FlightSegmentCard };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=FlightSegmentCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlightSegmentCard.js","names":[],"sources":["../../../lib/ui/journey-card/FlightSegmentCard.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport type { ComponentPropsWithoutRef } from 'react';\nimport { Icon } from '@clubmed/trident-icons';\nimport { FlightTimeline } from './FlightTimeline';\n\nexport interface AirportInfo {\n name: string;\n terminal?: string;\n}\n\nexport interface FlightSegmentCardProps extends ComponentPropsWithoutRef<'div'> {\n flightNumber: string;\n departureTime: string;\n arrivalTime: string;\n departureAirport: AirportInfo;\n arrivalAirport: AirportInfo;\n arrivalDate?: string;\n plusDays?: number;\n}\n\nexport function FlightSegmentCard({\n flightNumber,\n departureTime,\n arrivalTime,\n departureAirport,\n arrivalAirport,\n arrivalDate,\n className,\n ...props\n}: FlightSegmentCardProps) {\n return (\n <div\n data-name=\"FlightSegmentCard\"\n {...props}\n className={clsx('flex h-fit w-full flex-col gap-12 rounded-32 bg-white p-20', className)}\n >\n <div className=\"flex h-24 w-full flex-row items-center gap-8\">\n <Icon name=\"PlaneOutbound\" width=\"24px\" className=\"shrink-0 text-black\" />\n <span className=\"font-sans text-b4\">{flightNumber}</span>\n </div>\n\n <div className=\"flex w-full flex-col gap-4\">\n <div className=\"flex w-full flex-row items-end justify-between\">\n <div className=\"flex flex-1 flex-col justify-center\">\n <span className=\"font-sans text-b3 font-semibold\">{departureTime}</span>\n </div>\n <div className=\"flex flex-col items-end justify-center\">\n {arrivalDate && <span className=\"font-sans text-b4\">{arrivalDate}</span>}\n <span className=\"font-sans text-b3 font-semibold\">{arrivalTime}</span>\n </div>\n </div>\n\n <FlightTimeline />\n\n <div className=\"flex w-full flex-row items-start justify-between\">\n <div className=\"flex w-120 min-w-120 flex-col\">\n <span className=\"font-sans text-b4 font-semibold\">{departureAirport.name}</span>\n {departureAirport.terminal && (\n <span className=\"font-sans text-b4\">{departureAirport.terminal}</span>\n )}\n </div>\n <div className=\"flex w-120 min-w-120 flex-col items-end\">\n <span className=\"font-sans text-b4 font-semibold\">{arrivalAirport.name}</span>\n {arrivalAirport.terminal && (\n <span className=\"font-sans text-b4 text-right\">{arrivalAirport.terminal}</span>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAoBA,SAAgB,EAAkB,EAChC,iBACA,kBACA,gBACA,qBACA,mBACA,gBACA,cACA,GAAG,KACsB;AACzB,QACE,kBAAC,OAAD;EACE,aAAU;EACV,GAAI;EACJ,WAAW,EAAK,8DAA8D,EAAU;YAH1F,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAM,MAAK;IAAgB,OAAM;IAAO,WAAU;IAAwB,CAAA,EAC1E,kBAAC,QAAD;IAAM,WAAU;cAAqB;IAAoB,CAAA,CACrD;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,QAAD;OAAM,WAAU;iBAAmC;OAAqB,CAAA;MACpE,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,KAAe,kBAAC,QAAD;OAAM,WAAU;iBAAqB;OAAmB,CAAA,EACxE,kBAAC,QAAD;OAAM,WAAU;iBAAmC;OAAmB,CAAA,CAClE;QACF;;IAEN,kBAAC,GAAD,EAAkB,CAAA;IAElB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAmC,EAAiB;OAAY,CAAA,EAC/E,EAAiB,YAChB,kBAAC,QAAD;OAAM,WAAU;iBAAqB,EAAiB;OAAgB,CAAA,CAEpE;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAmC,EAAe;OAAY,CAAA,EAC7E,EAAe,YACd,kBAAC,QAAD;OAAM,WAAU;iBAAgC,EAAe;OAAgB,CAAA,CAE7E;QACF;;IACF;KACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
export interface FlightTimelineProps extends ComponentPropsWithoutRef<'div'> {
|
|
3
|
+
nbStopovers?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function FlightTimeline({ nbStopovers, className, ...props }: FlightTimelineProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
2
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
+
//#region lib/ui/journey-card/FlightTimeline.tsx
|
|
4
|
+
function r({ nbStopovers: r = 0, className: i, ...a }) {
|
|
5
|
+
return /* @__PURE__ */ n("div", {
|
|
6
|
+
"data-name": "FlightTimeline",
|
|
7
|
+
...a,
|
|
8
|
+
className: e("relative flex w-full items-center h-12", i),
|
|
9
|
+
children: [
|
|
10
|
+
/* @__PURE__ */ t("span", { className: "absolute left-0 h-12 w-12 rounded-full border-2 border-black bg-white" }),
|
|
11
|
+
/* @__PURE__ */ t("span", { className: "h-2 flex-1 rounded-pill bg-black" }),
|
|
12
|
+
r > 0 && /* @__PURE__ */ t("div", {
|
|
13
|
+
className: "flex shrink-0 flex-row items-center gap-2",
|
|
14
|
+
children: Array.from({ length: r }).map((e, r) => /* @__PURE__ */ n("span", {
|
|
15
|
+
className: "flex flex-row items-center gap-2",
|
|
16
|
+
children: [r !== 0 && /* @__PURE__ */ t("span", { className: "h-2 w-8 rounded-pill bg-black" }), /* @__PURE__ */ t("span", { className: "h-12 w-12 rounded-full border-2 border-white bg-black" })]
|
|
17
|
+
}, r))
|
|
18
|
+
}),
|
|
19
|
+
/* @__PURE__ */ t("span", { className: "h-2 flex-1 rounded-pill bg-black" }),
|
|
20
|
+
/* @__PURE__ */ t("span", { className: "absolute right-0 h-12 w-12 rounded-full border-2 border-black bg-white" })
|
|
21
|
+
]
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { r as FlightTimeline };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=FlightTimeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlightTimeline.js","names":[],"sources":["../../../lib/ui/journey-card/FlightTimeline.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport type { ComponentPropsWithoutRef } from 'react';\n\nexport interface FlightTimelineProps extends ComponentPropsWithoutRef<'div'> {\n nbStopovers?: number;\n}\n\nexport function FlightTimeline({ nbStopovers = 0, className, ...props }: FlightTimelineProps) {\n return (\n <div\n data-name=\"FlightTimeline\"\n {...props}\n className={clsx('relative flex w-full items-center h-12', className)}\n >\n <span className=\"absolute left-0 h-12 w-12 rounded-full border-2 border-black bg-white\" />\n <span className=\"h-2 flex-1 rounded-pill bg-black\" />\n {nbStopovers > 0 && (\n <div className=\"flex shrink-0 flex-row items-center gap-2\">\n {Array.from({ length: nbStopovers }).map((_, i) => (\n <span key={i} className=\"flex flex-row items-center gap-2\">\n {i !== 0 && <span className=\"h-2 w-8 rounded-pill bg-black\" />}\n <span className=\"h-12 w-12 rounded-full border-2 border-white bg-black\" />\n </span>\n ))}\n </div>\n )}\n <span className=\"h-2 flex-1 rounded-pill bg-black\" />\n <span className=\"absolute right-0 h-12 w-12 rounded-full border-2 border-black bg-white\" />\n </div>\n );\n}\n"],"mappings":";;;AAOA,SAAgB,EAAe,EAAE,iBAAc,GAAG,cAAW,GAAG,KAA8B;AAC5F,QACE,kBAAC,OAAD;EACE,aAAU;EACV,GAAI;EACJ,WAAW,EAAK,0CAA0C,EAAU;YAHtE;GAKE,kBAAC,QAAD,EAAM,WAAU,yEAA0E,CAAA;GAC1F,kBAAC,QAAD,EAAM,WAAU,oCAAqC,CAAA;GACpD,IAAc,KACb,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAM,KAAK,EAAE,QAAQ,GAAa,CAAC,CAAC,KAAK,GAAG,MAC3C,kBAAC,QAAD;KAAc,WAAU;eAAxB,CACG,MAAM,KAAK,kBAAC,QAAD,EAAM,WAAU,iCAAkC,CAAA,EAC9D,kBAAC,QAAD,EAAM,WAAU,yDAA0D,CAAA,CACrE;OAHI,EAGJ,CACP;IACE,CAAA;GAER,kBAAC,QAAD,EAAM,WAAU,oCAAqC,CAAA;GACrD,kBAAC,QAAD,EAAM,WAAU,0EAA2E,CAAA;GACvF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { AirportInfo, FlightSegmentCardProps } from './FlightSegmentCard';
|
|
3
|
+
export type { AirportInfo };
|
|
4
|
+
export interface ItineraryDetailsProps extends ComponentPropsWithoutRef<'div'> {
|
|
5
|
+
segments: FlightSegmentCardProps[];
|
|
6
|
+
connectionTime?: string;
|
|
7
|
+
flexibleOption?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function ItineraryDetails({ segments, connectionTime, flexibleOption, className, ...props }: ItineraryDetailsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
2
|
+
import { FlightSegmentCard as t } from "./FlightSegmentCard.js";
|
|
3
|
+
import { Icon as n } from "@clubmed/trident-icons";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region lib/ui/journey-card/ItineraryDetails.tsx
|
|
6
|
+
function a({ segments: a, connectionTime: o, flexibleOption: s, className: c, ...l }) {
|
|
7
|
+
return /* @__PURE__ */ i("div", {
|
|
8
|
+
"data-name": "ItineraryDetails",
|
|
9
|
+
...l,
|
|
10
|
+
className: e("flex h-fit w-full flex-col gap-8 rounded-44 bg-lightSand p-16", c),
|
|
11
|
+
children: [a.map((e, s) => /* @__PURE__ */ i("div", {
|
|
12
|
+
className: "flex flex-col gap-8",
|
|
13
|
+
children: [/* @__PURE__ */ r(t, { ...e }), o && s < a.length - 1 && /* @__PURE__ */ i("div", {
|
|
14
|
+
className: "flex h-fit w-full flex-row items-center gap-2 pl-20",
|
|
15
|
+
children: [/* @__PURE__ */ r(n, {
|
|
16
|
+
name: "ClockDefault",
|
|
17
|
+
width: "24px",
|
|
18
|
+
className: "shrink-0 text-black"
|
|
19
|
+
}), /* @__PURE__ */ r("span", {
|
|
20
|
+
className: "font-sans text-b4",
|
|
21
|
+
children: o
|
|
22
|
+
})]
|
|
23
|
+
})]
|
|
24
|
+
}, s)), s && /* @__PURE__ */ i("div", {
|
|
25
|
+
className: "flex w-full flex-row items-start gap-2",
|
|
26
|
+
children: [/* @__PURE__ */ r(n, {
|
|
27
|
+
name: "LightBulb",
|
|
28
|
+
width: "24px",
|
|
29
|
+
className: "mt-2 shrink-0 text-black"
|
|
30
|
+
}), /* @__PURE__ */ r("div", {
|
|
31
|
+
className: "whitespace-pre-wrap font-sans text-b4",
|
|
32
|
+
children: s
|
|
33
|
+
})]
|
|
34
|
+
})]
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { a as ItineraryDetails };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=ItineraryDetails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ItineraryDetails.js","names":[],"sources":["../../../lib/ui/journey-card/ItineraryDetails.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport type { ComponentPropsWithoutRef } from 'react';\nimport { Icon } from '@clubmed/trident-icons';\nimport { FlightSegmentCard } from './FlightSegmentCard';\nimport type { AirportInfo, FlightSegmentCardProps } from './FlightSegmentCard';\n\nexport type { AirportInfo };\n\nexport interface ItineraryDetailsProps extends ComponentPropsWithoutRef<'div'> {\n segments: FlightSegmentCardProps[];\n connectionTime?: string;\n flexibleOption?: string;\n}\n\nexport function ItineraryDetails({\n segments,\n connectionTime,\n flexibleOption,\n className,\n ...props\n}: ItineraryDetailsProps) {\n return (\n <div\n data-name=\"ItineraryDetails\"\n {...props}\n className={clsx('flex h-fit w-full flex-col gap-8 rounded-44 bg-lightSand p-16', className)}\n >\n {segments.map((segment, index) => (\n <div key={index} className=\"flex flex-col gap-8\">\n <FlightSegmentCard {...segment} />\n\n {connectionTime && index < segments.length - 1 && (\n <div className=\"flex h-fit w-full flex-row items-center gap-2 pl-20\">\n <Icon name=\"ClockDefault\" width=\"24px\" className=\"shrink-0 text-black\" />\n <span className=\"font-sans text-b4\">{connectionTime}</span>\n </div>\n )}\n </div>\n ))}\n\n {flexibleOption && (\n <div className=\"flex w-full flex-row items-start gap-2\">\n <Icon name=\"LightBulb\" width=\"24px\" className=\"mt-2 shrink-0 text-black\" />\n <div className=\"whitespace-pre-wrap font-sans text-b4\">{flexibleOption}</div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;AAcA,SAAgB,EAAiB,EAC/B,aACA,mBACA,mBACA,cACA,GAAG,KACqB;AACxB,QACE,kBAAC,OAAD;EACE,aAAU;EACV,GAAI;EACJ,WAAW,EAAK,iEAAiE,EAAU;YAH7F,CAKG,EAAS,KAAK,GAAS,MACtB,kBAAC,OAAD;GAAiB,WAAU;aAA3B,CACE,kBAAC,GAAD,EAAmB,GAAI,GAAW,CAAA,EAEjC,KAAkB,IAAQ,EAAS,SAAS,KAC3C,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAM,MAAK;KAAe,OAAM;KAAO,WAAU;KAAwB,CAAA,EACzE,kBAAC,QAAD;KAAM,WAAU;eAAqB;KAAsB,CAAA,CACvD;MAEJ;KATI,EASJ,CACN,EAED,KACC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAM,MAAK;IAAY,OAAM;IAAO,WAAU;IAA6B,CAAA,EAC3E,kBAAC,OAAD;IAAK,WAAU;cAAyC;IAAqB,CAAA,CACzE;KAEJ"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { JourneyDetailsProps } from './JourneyDetails';
|
|
3
|
+
export type { JourneyDetailsProps };
|
|
4
|
+
export type { AirportInfo, ItineraryDetailsProps } from './ItineraryDetails';
|
|
5
|
+
export type { FlightSegmentCardProps } from './FlightSegmentCard';
|
|
6
|
+
export interface JourneyCardProps extends ComponentPropsWithoutRef<'div'> {
|
|
7
|
+
/** Outbound or inbound flight leg */
|
|
8
|
+
flight1Journey: JourneyDetailsProps;
|
|
9
|
+
/** Return flight leg */
|
|
10
|
+
flight2Journey: JourneyDetailsProps;
|
|
11
|
+
/**
|
|
12
|
+
* When true, both legs are displayed side-by-side with a vertical divider
|
|
13
|
+
* instead of stacked with a horizontal divider.
|
|
14
|
+
*/
|
|
15
|
+
compact?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function JourneyCard({ flight1Journey, flight2Journey, compact, className, ...props }: JourneyCardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
2
|
+
import { JourneyDetails as t } from "./JourneyDetails.js";
|
|
3
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
|
+
//#region lib/ui/journey-card/JourneyCard.tsx
|
|
5
|
+
function i({ flight1Journey: i, flight2Journey: a, compact: o = !1, className: s, ...c }) {
|
|
6
|
+
return /* @__PURE__ */ n("div", {
|
|
7
|
+
"data-name": "JourneyCard",
|
|
8
|
+
...c,
|
|
9
|
+
className: e("flex h-fit w-full flex-col", s),
|
|
10
|
+
children: /* @__PURE__ */ r("div", {
|
|
11
|
+
className: e("flex w-full rounded-32 border border-lightGrey bg-white p-20", o ? "flex-row gap-0" : "flex-col gap-12"),
|
|
12
|
+
children: [
|
|
13
|
+
/* @__PURE__ */ n(t, {
|
|
14
|
+
...i,
|
|
15
|
+
className: e(o && "flex-1 pe-12"),
|
|
16
|
+
vertical: o
|
|
17
|
+
}),
|
|
18
|
+
!o && /* @__PURE__ */ n("div", {
|
|
19
|
+
role: "separator",
|
|
20
|
+
className: e("shrink-0 bg-lightGrey h-px w-full")
|
|
21
|
+
}),
|
|
22
|
+
/* @__PURE__ */ n(t, {
|
|
23
|
+
...a,
|
|
24
|
+
className: e(o && "flex-1 ps-12"),
|
|
25
|
+
vertical: o
|
|
26
|
+
})
|
|
27
|
+
]
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { i as JourneyCard };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=JourneyCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JourneyCard.js","names":[],"sources":["../../../lib/ui/journey-card/JourneyCard.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport type { ComponentPropsWithoutRef } from 'react';\nimport { JourneyDetails } from './JourneyDetails';\nimport type { JourneyDetailsProps } from './JourneyDetails';\n\nexport type { JourneyDetailsProps };\nexport type { AirportInfo, ItineraryDetailsProps } from './ItineraryDetails';\nexport type { FlightSegmentCardProps } from './FlightSegmentCard';\n\nexport interface JourneyCardProps extends ComponentPropsWithoutRef<'div'> {\n /** Outbound or inbound flight leg */\n flight1Journey: JourneyDetailsProps;\n /** Return flight leg */\n flight2Journey: JourneyDetailsProps;\n /**\n * When true, both legs are displayed side-by-side with a vertical divider\n * instead of stacked with a horizontal divider.\n */\n compact?: boolean;\n}\n\nexport function JourneyCard({\n flight1Journey,\n flight2Journey,\n compact = false,\n className,\n ...props\n}: JourneyCardProps) {\n return (\n <div\n data-name=\"JourneyCard\"\n {...props}\n className={clsx('flex h-fit w-full flex-col', className)}\n >\n <div\n className={clsx(\n 'flex w-full rounded-32 border border-lightGrey bg-white p-20',\n compact ? 'flex-row gap-0' : 'flex-col gap-12',\n )}\n >\n <JourneyDetails\n {...flight1Journey}\n className={clsx(compact && 'flex-1 pe-12')}\n vertical={compact}\n />\n {!compact && <div role=\"separator\" className={clsx('shrink-0 bg-lightGrey h-px w-full')} />}\n <JourneyDetails\n {...flight2Journey}\n className={clsx(compact && 'flex-1 ps-12')}\n vertical={compact}\n />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;AAqBA,SAAgB,EAAY,EAC1B,mBACA,mBACA,aAAU,IACV,cACA,GAAG,KACgB;AACnB,QACE,kBAAC,OAAD;EACE,aAAU;EACV,GAAI;EACJ,WAAW,EAAK,8BAA8B,EAAU;YAExD,kBAAC,OAAD;GACE,WAAW,EACT,gEACA,IAAU,mBAAmB,kBAC9B;aAJH;IAME,kBAAC,GAAD;KACE,GAAI;KACJ,WAAW,EAAK,KAAW,eAAe;KAC1C,UAAU;KACV,CAAA;IACD,CAAC,KAAW,kBAAC,OAAD;KAAK,MAAK;KAAY,WAAW,EAAK,oCAAoC;KAAI,CAAA;IAC3F,kBAAC,GAAD;KACE,GAAI;KACJ,WAAW,EAAK,KAAW,eAAe;KAC1C,UAAU;KACV,CAAA;IACE;;EACF,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { ItineraryDetailsProps } from './ItineraryDetails';
|
|
3
|
+
export interface AirportInfo {
|
|
4
|
+
name: string;
|
|
5
|
+
terminal?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface JourneyDetailsProps extends ComponentPropsWithoutRef<'div'> {
|
|
8
|
+
/** Human-readable leg label, e.g. "Outbound" or "Inbound" */
|
|
9
|
+
direction: string;
|
|
10
|
+
/** Controls which plane icon is rendered; falls back to `direction` when omitted */
|
|
11
|
+
directionType?: 'Inbound' | 'Outbound';
|
|
12
|
+
departureDate: string;
|
|
13
|
+
departureTime: string;
|
|
14
|
+
arrivalDate: string;
|
|
15
|
+
arrivalTime: string;
|
|
16
|
+
/** Total flight duration, e.g. "9h30mn" */
|
|
17
|
+
duration: string;
|
|
18
|
+
departureAirport: AirportInfo;
|
|
19
|
+
arrivalAirport: AirportInfo;
|
|
20
|
+
/** Connection label shown on the timeline, e.g. "Direct" or "1 Stop over" */
|
|
21
|
+
stopLabel: string;
|
|
22
|
+
/** Number of stopover dots on the timeline */
|
|
23
|
+
nbStopovers?: number;
|
|
24
|
+
airlineLogoSrc: string;
|
|
25
|
+
airlineLogoAlt: string;
|
|
26
|
+
/** Primary operator name */
|
|
27
|
+
operatedBy: string;
|
|
28
|
+
/** Secondary operator line, e.g. "Operated by Hop" */
|
|
29
|
+
companyName?: string;
|
|
30
|
+
/** Cabin / luggage summary text */
|
|
31
|
+
characteristics: string;
|
|
32
|
+
/** Carbon footprint text */
|
|
33
|
+
carbonEmission: string;
|
|
34
|
+
carbonEmissionLearnMoreUrl?: string;
|
|
35
|
+
carbonEmissionLearnMoreLabel: string;
|
|
36
|
+
/** How many calendar days after departure the arrival falls */
|
|
37
|
+
plusDays?: number;
|
|
38
|
+
/** Label appended to plusDays value, e.g. "day" */
|
|
39
|
+
plusDaysLabel: string;
|
|
40
|
+
/** Local time qualifier shown near arrival time, e.g. "(local time)" */
|
|
41
|
+
localTimeLabel: string;
|
|
42
|
+
/** Optional expanded itinerary with per-segment flight cards */
|
|
43
|
+
itinerary?: ItineraryDetailsProps;
|
|
44
|
+
/** When true, the component is displayed in a vertical layout for side-by-side JourneyCards */
|
|
45
|
+
vertical?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function JourneyDetails({ itinerary, direction, directionType, departureDate, departureTime, arrivalDate, arrivalTime, duration, departureAirport, arrivalAirport, stopLabel, nbStopovers, airlineLogoSrc, airlineLogoAlt, operatedBy, companyName, characteristics, carbonEmission, carbonEmissionLearnMoreUrl, carbonEmissionLearnMoreLabel, plusDays, plusDaysLabel, localTimeLabel, className, vertical, ...props }: JourneyDetailsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as e } from "../../chunks/clsx.js";
|
|
3
|
+
import { ElasticHeight as t } from "../ElasticHeight.js";
|
|
4
|
+
import { Tag as n } from "../Tag.js";
|
|
5
|
+
import { FlightTimeline as r } from "./FlightTimeline.js";
|
|
6
|
+
import { ItineraryDetails as i } from "./ItineraryDetails.js";
|
|
7
|
+
import { useState as a } from "react";
|
|
8
|
+
import { Icon as o } from "@clubmed/trident-icons";
|
|
9
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
10
|
+
//#region lib/ui/journey-card/JourneyDetails.tsx
|
|
11
|
+
function l({ itinerary: l, direction: u, directionType: d, departureDate: f, departureTime: p, arrivalDate: m, arrivalTime: h, duration: g, departureAirport: _, arrivalAirport: v, stopLabel: y, nbStopovers: b, airlineLogoSrc: x, airlineLogoAlt: S, operatedBy: C, companyName: w, characteristics: T, carbonEmission: E, carbonEmissionLearnMoreUrl: D, carbonEmissionLearnMoreLabel: O, plusDays: k, plusDaysLabel: A, localTimeLabel: j, className: M, vertical: N = !1, ...P }) {
|
|
12
|
+
let [F, I] = a(!1), L = (d ?? u) === "Outbound";
|
|
13
|
+
return /* @__PURE__ */ c("div", {
|
|
14
|
+
"data-name": "JourneyDetails",
|
|
15
|
+
...P,
|
|
16
|
+
className: e("flex h-fit w-full flex-col gap-8", M),
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ c("div", {
|
|
19
|
+
className: "flex h-48 w-full flex-row items-center justify-between",
|
|
20
|
+
children: [/* @__PURE__ */ c("div", {
|
|
21
|
+
className: "flex h-fit flex-row items-center gap-12",
|
|
22
|
+
children: [/* @__PURE__ */ s(o, {
|
|
23
|
+
name: L ? "PlaneOutbound" : "PlaneInBound",
|
|
24
|
+
width: "24px",
|
|
25
|
+
className: "text-black"
|
|
26
|
+
}), /* @__PURE__ */ s("span", {
|
|
27
|
+
className: "font-sans text-b3 font-semibold",
|
|
28
|
+
children: u
|
|
29
|
+
})]
|
|
30
|
+
}), /* @__PURE__ */ s("img", {
|
|
31
|
+
src: x,
|
|
32
|
+
alt: S,
|
|
33
|
+
width: 100,
|
|
34
|
+
height: 28,
|
|
35
|
+
className: "object-contain"
|
|
36
|
+
})]
|
|
37
|
+
}),
|
|
38
|
+
/* @__PURE__ */ c("div", {
|
|
39
|
+
className: "flex h-fit w-full flex-col gap-4",
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ c("div", {
|
|
42
|
+
className: "flex w-full flex-row items-end justify-between",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ c("div", {
|
|
45
|
+
className: "flex flex-1 flex-col",
|
|
46
|
+
children: [/* @__PURE__ */ s("span", {
|
|
47
|
+
className: "font-sans text-b4",
|
|
48
|
+
children: f
|
|
49
|
+
}), /* @__PURE__ */ s("span", {
|
|
50
|
+
className: "font-sans text-b1 font-semibold",
|
|
51
|
+
children: p
|
|
52
|
+
})]
|
|
53
|
+
}),
|
|
54
|
+
/* @__PURE__ */ s("div", {
|
|
55
|
+
className: "flex flex-1 justify-center",
|
|
56
|
+
children: /* @__PURE__ */ s("span", {
|
|
57
|
+
className: "text-center font-sans text-b4",
|
|
58
|
+
children: g
|
|
59
|
+
})
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ c("div", {
|
|
62
|
+
className: "flex flex-1 flex-col items-end",
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ c("div", {
|
|
65
|
+
className: e("flex", !N && "flex-row items-center justify-end gap-4", N && "flex-col items-end justify-start gap-0"),
|
|
66
|
+
children: [/* @__PURE__ */ s("span", {
|
|
67
|
+
className: "font-sans text-b4",
|
|
68
|
+
children: m
|
|
69
|
+
}), k && k > 0 && /* @__PURE__ */ s(n, {
|
|
70
|
+
label: `+${k} ${A}`,
|
|
71
|
+
theme: "label",
|
|
72
|
+
backgroundColor: "black",
|
|
73
|
+
color: "white",
|
|
74
|
+
className: "rounded-full"
|
|
75
|
+
})]
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ s("span", {
|
|
78
|
+
className: "text-right font-sans text-b4",
|
|
79
|
+
children: j
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ s("span", {
|
|
82
|
+
className: "text-right font-sans text-b1 font-semibold",
|
|
83
|
+
children: h
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}),
|
|
89
|
+
/* @__PURE__ */ s(r, { nbStopovers: b }),
|
|
90
|
+
/* @__PURE__ */ c("div", {
|
|
91
|
+
className: "flex w-full flex-row items-start justify-between",
|
|
92
|
+
children: [
|
|
93
|
+
/* @__PURE__ */ c("div", {
|
|
94
|
+
className: "flex flex-1 flex-col",
|
|
95
|
+
children: [/* @__PURE__ */ s("span", {
|
|
96
|
+
className: "font-sans text-b4 font-semibold",
|
|
97
|
+
children: _.name
|
|
98
|
+
}), _.terminal && /* @__PURE__ */ s("span", {
|
|
99
|
+
className: "font-sans text-b4",
|
|
100
|
+
children: _.terminal
|
|
101
|
+
})]
|
|
102
|
+
}),
|
|
103
|
+
/* @__PURE__ */ s("span", {
|
|
104
|
+
className: "flex-1 text-center font-sans text-b4",
|
|
105
|
+
children: y
|
|
106
|
+
}),
|
|
107
|
+
/* @__PURE__ */ c("div", {
|
|
108
|
+
className: "flex flex-1 flex-col items-end",
|
|
109
|
+
children: [/* @__PURE__ */ s("span", {
|
|
110
|
+
className: "font-sans text-b4 font-semibold",
|
|
111
|
+
children: v.name
|
|
112
|
+
}), v.terminal && /* @__PURE__ */ s("span", {
|
|
113
|
+
className: "text-right font-sans text-b4",
|
|
114
|
+
children: v.terminal
|
|
115
|
+
})]
|
|
116
|
+
})
|
|
117
|
+
]
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
}),
|
|
121
|
+
/* @__PURE__ */ c("button", {
|
|
122
|
+
type: "button",
|
|
123
|
+
onClick: () => I((e) => !e),
|
|
124
|
+
"aria-expanded": F,
|
|
125
|
+
className: "flex w-full cursor-pointer flex-row items-end justify-between border-none bg-transparent p-0",
|
|
126
|
+
children: [/* @__PURE__ */ c("div", {
|
|
127
|
+
className: "flex flex-col text-left",
|
|
128
|
+
children: [/* @__PURE__ */ s("span", {
|
|
129
|
+
className: "font-sans text-b4 font-semibold",
|
|
130
|
+
children: C
|
|
131
|
+
}), w && /* @__PURE__ */ s("span", {
|
|
132
|
+
className: "font-sans text-b4",
|
|
133
|
+
children: w
|
|
134
|
+
})]
|
|
135
|
+
}), /* @__PURE__ */ s(o, {
|
|
136
|
+
name: "ArrowOutlinedUp",
|
|
137
|
+
width: "24px",
|
|
138
|
+
className: e("text-black transition-transform duration-200", { "rotate-180": !F })
|
|
139
|
+
})]
|
|
140
|
+
}),
|
|
141
|
+
/* @__PURE__ */ c(t, {
|
|
142
|
+
isExpanded: F,
|
|
143
|
+
innerClassName: "flex flex-col gap-8",
|
|
144
|
+
children: [
|
|
145
|
+
/* @__PURE__ */ c("div", {
|
|
146
|
+
className: "flex h-fit w-full flex-row items-start gap-8",
|
|
147
|
+
children: [/* @__PURE__ */ s(o, {
|
|
148
|
+
name: "Luggage",
|
|
149
|
+
width: "24px",
|
|
150
|
+
className: "shrink-0 text-black"
|
|
151
|
+
}), /* @__PURE__ */ s("span", {
|
|
152
|
+
className: "font-sans text-b4",
|
|
153
|
+
children: T
|
|
154
|
+
})]
|
|
155
|
+
}),
|
|
156
|
+
/* @__PURE__ */ c("div", {
|
|
157
|
+
className: "flex h-fit w-full flex-row items-start gap-8",
|
|
158
|
+
children: [/* @__PURE__ */ s(o, {
|
|
159
|
+
name: "HappyToCare",
|
|
160
|
+
width: "24px",
|
|
161
|
+
className: "shrink-0 text-black"
|
|
162
|
+
}), /* @__PURE__ */ c("div", {
|
|
163
|
+
className: "flex flex-col",
|
|
164
|
+
children: [/* @__PURE__ */ s("span", {
|
|
165
|
+
className: "font-sans text-b4",
|
|
166
|
+
children: E
|
|
167
|
+
}), D && /* @__PURE__ */ s("a", {
|
|
168
|
+
href: D,
|
|
169
|
+
className: "font-sans text-b4 underline",
|
|
170
|
+
children: O
|
|
171
|
+
})]
|
|
172
|
+
})]
|
|
173
|
+
}),
|
|
174
|
+
l && /* @__PURE__ */ s(i, { ...l })
|
|
175
|
+
]
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
//#endregion
|
|
181
|
+
export { l as JourneyDetails };
|
|
182
|
+
|
|
183
|
+
//# sourceMappingURL=JourneyDetails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JourneyDetails.js","names":[],"sources":["../../../lib/ui/journey-card/JourneyDetails.tsx"],"sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport type { ComponentPropsWithoutRef } from 'react';\nimport { useState } from 'react';\nimport { Icon } from '@clubmed/trident-icons';\nimport { Tag } from '../Tag';\nimport { ElasticHeight } from '../ElasticHeight';\nimport { FlightTimeline } from './FlightTimeline';\nimport { ItineraryDetails } from './ItineraryDetails';\nimport type { ItineraryDetailsProps } from './ItineraryDetails';\n\nexport interface AirportInfo {\n name: string;\n terminal?: string;\n}\n\nexport interface JourneyDetailsProps extends ComponentPropsWithoutRef<'div'> {\n /** Human-readable leg label, e.g. \"Outbound\" or \"Inbound\" */\n direction: string;\n /** Controls which plane icon is rendered; falls back to `direction` when omitted */\n directionType?: 'Inbound' | 'Outbound';\n departureDate: string;\n departureTime: string;\n arrivalDate: string;\n arrivalTime: string;\n /** Total flight duration, e.g. \"9h30mn\" */\n duration: string;\n departureAirport: AirportInfo;\n arrivalAirport: AirportInfo;\n /** Connection label shown on the timeline, e.g. \"Direct\" or \"1 Stop over\" */\n stopLabel: string;\n /** Number of stopover dots on the timeline */\n nbStopovers?: number;\n airlineLogoSrc: string;\n airlineLogoAlt: string;\n /** Primary operator name */\n operatedBy: string;\n /** Secondary operator line, e.g. \"Operated by Hop\" */\n companyName?: string;\n /** Cabin / luggage summary text */\n characteristics: string;\n /** Carbon footprint text */\n carbonEmission: string;\n carbonEmissionLearnMoreUrl?: string;\n carbonEmissionLearnMoreLabel: string;\n /** How many calendar days after departure the arrival falls */\n plusDays?: number;\n /** Label appended to plusDays value, e.g. \"day\" */\n plusDaysLabel: string;\n /** Local time qualifier shown near arrival time, e.g. \"(local time)\" */\n localTimeLabel: string;\n /** Optional expanded itinerary with per-segment flight cards */\n itinerary?: ItineraryDetailsProps;\n /** When true, the component is displayed in a vertical layout for side-by-side JourneyCards */\n vertical?: boolean;\n}\n\nexport function JourneyDetails({\n itinerary,\n direction,\n directionType,\n departureDate,\n departureTime,\n arrivalDate,\n arrivalTime,\n duration,\n departureAirport,\n arrivalAirport,\n stopLabel,\n nbStopovers,\n airlineLogoSrc,\n airlineLogoAlt,\n operatedBy,\n companyName,\n characteristics,\n carbonEmission,\n carbonEmissionLearnMoreUrl,\n carbonEmissionLearnMoreLabel,\n plusDays,\n plusDaysLabel,\n localTimeLabel,\n className,\n vertical = false,\n ...props\n}: JourneyDetailsProps) {\n const [isOpen, setIsOpen] = useState(false);\n const isOutbound = (directionType ?? direction) === 'Outbound';\n\n return (\n <div\n data-name=\"JourneyDetails\"\n {...props}\n className={clsx('flex h-fit w-full flex-col gap-8', className)}\n >\n {/* Row 1 — direction label + airline logo */}\n <div className=\"flex h-48 w-full flex-row items-center justify-between\">\n <div className=\"flex h-fit flex-row items-center gap-12\">\n <Icon\n name={isOutbound ? 'PlaneOutbound' : 'PlaneInBound'}\n width=\"24px\"\n className=\"text-black\"\n />\n <span className=\"font-sans text-b3 font-semibold\">{direction}</span>\n </div>\n <img\n src={airlineLogoSrc}\n alt={airlineLogoAlt}\n width={100}\n height={28}\n className=\"object-contain\"\n />\n </div>\n\n {/* Row 2 — schedule */}\n <div className=\"flex h-fit w-full flex-col gap-4\">\n <div className=\"flex w-full flex-row items-end justify-between\">\n <div className=\"flex flex-1 flex-col\">\n <span className=\"font-sans text-b4\">{departureDate}</span>\n <span className=\"font-sans text-b1 font-semibold\">{departureTime}</span>\n </div>\n\n <div className=\"flex flex-1 justify-center\">\n <span className=\"text-center font-sans text-b4\">{duration}</span>\n </div>\n\n <div className=\"flex flex-1 flex-col items-end\">\n <div\n className={clsx(\n 'flex',\n !vertical && 'flex-row items-center justify-end gap-4',\n vertical && 'flex-col items-end justify-start gap-0',\n )}\n >\n <span className=\"font-sans text-b4\">{arrivalDate}</span>\n {plusDays && plusDays > 0 && (\n <Tag\n label={`+${plusDays} ${plusDaysLabel}`}\n theme=\"label\"\n backgroundColor=\"black\"\n color=\"white\"\n className=\"rounded-full\"\n />\n )}\n </div>\n <span className=\"text-right font-sans text-b4\">{localTimeLabel}</span>\n <span className=\"text-right font-sans text-b1 font-semibold\">{arrivalTime}</span>\n </div>\n </div>\n\n <FlightTimeline nbStopovers={nbStopovers} />\n\n <div className=\"flex w-full flex-row items-start justify-between\">\n <div className=\"flex flex-1 flex-col\">\n <span className=\"font-sans text-b4 font-semibold\">{departureAirport.name}</span>\n {departureAirport.terminal && (\n <span className=\"font-sans text-b4\">{departureAirport.terminal}</span>\n )}\n </div>\n <span className=\"flex-1 text-center font-sans text-b4\">{stopLabel}</span>\n <div className=\"flex flex-1 flex-col items-end\">\n <span className=\"font-sans text-b4 font-semibold\">{arrivalAirport.name}</span>\n {arrivalAirport.terminal && (\n <span className=\"text-right font-sans text-b4\">{arrivalAirport.terminal}</span>\n )}\n </div>\n </div>\n </div>\n\n {/* Row 3 — operator toggle */}\n <button\n type=\"button\"\n onClick={() => setIsOpen((v) => !v)}\n aria-expanded={isOpen}\n className=\"flex w-full cursor-pointer flex-row items-end justify-between border-none bg-transparent p-0\"\n >\n <div className=\"flex flex-col text-left\">\n <span className=\"font-sans text-b4 font-semibold\">{operatedBy}</span>\n {companyName && <span className=\"font-sans text-b4\">{companyName}</span>}\n </div>\n <Icon\n name=\"ArrowOutlinedUp\"\n width=\"24px\"\n className={clsx('text-black transition-transform duration-200', {\n 'rotate-180': !isOpen,\n })}\n />\n </button>\n\n {/* Rows 4 & 5 — accordion */}\n <ElasticHeight isExpanded={isOpen} innerClassName=\"flex flex-col gap-8\">\n <div className=\"flex h-fit w-full flex-row items-start gap-8\">\n <Icon name=\"Luggage\" width=\"24px\" className=\"shrink-0 text-black\" />\n <span className=\"font-sans text-b4\">{characteristics}</span>\n </div>\n <div className=\"flex h-fit w-full flex-row items-start gap-8\">\n <Icon name=\"HappyToCare\" width=\"24px\" className=\"shrink-0 text-black\" />\n <div className=\"flex flex-col\">\n <span className=\"font-sans text-b4\">{carbonEmission}</span>\n {carbonEmissionLearnMoreUrl && (\n <a href={carbonEmissionLearnMoreUrl} className=\"font-sans text-b4 underline\">\n {carbonEmissionLearnMoreLabel}\n </a>\n )}\n </div>\n </div>\n {itinerary && <ItineraryDetails {...itinerary} />}\n </ElasticHeight>\n </div>\n );\n}\n"],"mappings":"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"}
|
package/ui/tabs/Tabs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentProps, ComponentPropsWithoutRef, FunctionComponent, PropsWithChildren } from 'react';
|
|
1
|
+
import { ComponentProps, ComponentPropsWithoutRef, FunctionComponent, PropsWithChildren, ReactNode } from 'react';
|
|
2
2
|
import { TabsProvider } from '../contexts/TabControl';
|
|
3
3
|
type ProviderProps = ComponentProps<typeof TabsProvider>;
|
|
4
4
|
interface Props extends ProviderProps {
|
|
@@ -46,6 +46,10 @@ export interface TabSelectProps {
|
|
|
46
46
|
}
|
|
47
47
|
export declare const TabSelect: FunctionComponent<TabSelectProps>;
|
|
48
48
|
interface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {
|
|
49
|
+
/**
|
|
50
|
+
* Notification content
|
|
51
|
+
*/
|
|
52
|
+
notification?: ReactNode;
|
|
49
53
|
/**
|
|
50
54
|
* Tab Heading text
|
|
51
55
|
*/
|
package/ui/tabs/Tabs.js
CHANGED
|
@@ -156,79 +156,85 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
156
156
|
children: e.label
|
|
157
157
|
}, e.value))
|
|
158
158
|
});
|
|
159
|
-
}, x = ({ as: e = "h2", label: t, children: n, value: i, onSelect: o, className: p,
|
|
160
|
-
let
|
|
159
|
+
}, x = ({ as: e = "h2", label: t, children: n, value: i, onSelect: o, className: p, notification: g, ..._ }) => {
|
|
160
|
+
let v = f(null), y = r(), b = s(), x = a({
|
|
161
161
|
value: i,
|
|
162
|
-
ref:
|
|
163
|
-
}),
|
|
164
|
-
|
|
165
|
-
let
|
|
162
|
+
ref: v
|
|
163
|
+
}), S = f(y), C = f(y === i);
|
|
164
|
+
C.current = y === i;
|
|
165
|
+
let w = { "--tab-index": i };
|
|
166
166
|
d(() => {
|
|
167
|
-
|
|
167
|
+
S.current !== y && i === y && (v.current?.focus(), o?.({
|
|
168
168
|
value: i,
|
|
169
169
|
label: t
|
|
170
|
-
})),
|
|
170
|
+
})), S.current !== y && (S.current = y);
|
|
171
171
|
}, [
|
|
172
172
|
t,
|
|
173
173
|
i,
|
|
174
174
|
o,
|
|
175
|
-
|
|
175
|
+
y
|
|
176
176
|
]);
|
|
177
|
-
let
|
|
177
|
+
let T = c({
|
|
178
178
|
start: u(() => {
|
|
179
|
-
|
|
180
|
-
}, [
|
|
179
|
+
x({ type: "start" });
|
|
180
|
+
}, [x]),
|
|
181
181
|
end: u(() => {
|
|
182
|
-
|
|
183
|
-
}, [
|
|
182
|
+
x({ type: "end" });
|
|
183
|
+
}, [x]),
|
|
184
184
|
up: u(() => {
|
|
185
|
-
|
|
186
|
-
}, [
|
|
185
|
+
x({ type: "previous" });
|
|
186
|
+
}, [x]),
|
|
187
187
|
down: u(() => {
|
|
188
|
-
|
|
189
|
-
}, [
|
|
188
|
+
x({ type: "next" });
|
|
189
|
+
}, [x]),
|
|
190
190
|
left: u(() => {
|
|
191
|
-
|
|
192
|
-
}, [
|
|
191
|
+
x({ type: document.documentElement.dir === "rtl" ? "next" : "previous" });
|
|
192
|
+
}, [x]),
|
|
193
193
|
right: u(() => {
|
|
194
|
-
|
|
195
|
-
}, [
|
|
196
|
-
}),
|
|
194
|
+
x({ type: document.documentElement.dir === "rtl" ? "previous" : "next" });
|
|
195
|
+
}, [x])
|
|
196
|
+
}), E = u((e) => {
|
|
197
197
|
let t = e.key === " " || e.key === "Spacebar" || e.code === "Space", n = e.key === "Enter" || e.code === "Enter";
|
|
198
|
-
if (
|
|
198
|
+
if (C.current && (t || n)) {
|
|
199
199
|
e.preventDefault();
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
202
|
-
|
|
203
|
-
}, [
|
|
204
|
-
|
|
202
|
+
T(e);
|
|
203
|
+
}, [T]), D = () => {
|
|
204
|
+
C.current || x({
|
|
205
205
|
type: "update",
|
|
206
206
|
payload: i
|
|
207
207
|
});
|
|
208
208
|
};
|
|
209
209
|
return /* @__PURE__ */ m("div", {
|
|
210
|
-
...
|
|
211
|
-
id:
|
|
210
|
+
..._,
|
|
211
|
+
id: _.id || `Tab_${i}_${b}`,
|
|
212
212
|
"data-name": "Tab",
|
|
213
|
-
ref:
|
|
213
|
+
ref: v,
|
|
214
214
|
role: "tab",
|
|
215
|
-
"aria-selected":
|
|
216
|
-
"aria-controls": `TabPanel_${i}_${
|
|
217
|
-
tabIndex:
|
|
218
|
-
className: l("group text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none", {
|
|
219
|
-
"text-white":
|
|
220
|
-
"text-black": !
|
|
221
|
-
"transition-transform active:scale-[1.03]":
|
|
215
|
+
"aria-selected": C.current,
|
|
216
|
+
"aria-controls": `TabPanel_${i}_${b}`,
|
|
217
|
+
tabIndex: C.current ? 0 : -1,
|
|
218
|
+
className: l("group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none", {
|
|
219
|
+
"text-white": C.current,
|
|
220
|
+
"text-black": !C.current,
|
|
221
|
+
"transition-transform active:scale-[1.03]": C.current
|
|
222
222
|
}),
|
|
223
|
-
onKeyDown:
|
|
224
|
-
onClick:
|
|
223
|
+
onKeyDown: E,
|
|
224
|
+
onClick: D,
|
|
225
225
|
children: /* @__PURE__ */ h(e, {
|
|
226
|
-
className: l("relative inline-block px-20 py-12", "before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within:before:bg-(--color-pearl) group-hover:before:bg-(--color-pearl) group-focus:before:bg-(--color-pearl)", p),
|
|
227
|
-
...
|
|
226
|
+
className: l("relative inline-block px-20 py-12", "before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)", p),
|
|
227
|
+
...C ? {} : { role: "presentation" },
|
|
228
228
|
children: [/* @__PURE__ */ m("span", {
|
|
229
229
|
className: l("tab-focus-pill ease transition-transform/colors", "rounded-pill absolute inset-0 -z-1 duration-300", "bg-black"),
|
|
230
|
-
style:
|
|
231
|
-
}),
|
|
230
|
+
style: w
|
|
231
|
+
}), /* @__PURE__ */ h("span", {
|
|
232
|
+
className: "flex items-center gap-8",
|
|
233
|
+
children: [n ?? t, g && /* @__PURE__ */ m("div", {
|
|
234
|
+
className: l("size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300", { "group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl": !C.current }),
|
|
235
|
+
children: g
|
|
236
|
+
})]
|
|
237
|
+
})]
|
|
232
238
|
})
|
|
233
239
|
});
|
|
234
240
|
};
|
package/ui/tabs/Tabs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","names":[],"sources":["../../../lib/ui/tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type FunctionComponent,\n type PropsWithChildren,\n type RefObject,\n type KeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { TabsProvider } from '../contexts/TabControl';\nimport {\n useActiveTab,\n useActiveTabControl,\n useRegisterTabControl,\n useTabDispatch,\n useTabsUid,\n} from '../hooks/tabControl';\nimport { useKeyboardControls } from '../hooks/useKeyboardControls';\nimport { Select } from '../forms/Select';\nimport { cn } from '../helpers/cn';\nimport { ArrowButton } from '../buttons/ArrowButton';\n\ntype ProviderProps = ComponentProps<typeof TabsProvider>;\n\ninterface Props extends ProviderProps {\n className?: string;\n /**\n * Shrink the spacing between tabs and panels\n */\n compacted?: boolean;\n}\n\nexport const Tabs: FunctionComponent<PropsWithChildren<Props>> = ({\n className,\n compacted = false,\n selected,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'flex flex-col',\n {\n 'sm:gap-y-20': !compacted,\n },\n className,\n )}\n data-name=\"Tabs\"\n >\n <TabsProvider selected={selected}>{children}</TabsProvider>\n </div>\n );\n};\n\ninterface TabsBodyProps {\n className?: string;\n}\n\nexport const TabsBody: FunctionComponent<PropsWithChildren<TabsBodyProps>> = ({\n className,\n children,\n}) => {\n return (\n <div data-name=\"TabsBody\" className={cn('grid grid-rows-1 overflow-hidden', className)}>\n {children}\n </div>\n );\n};\n\ninterface TabPanelProps {\n className?: string;\n /**\n * Tab panel index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on panel select handler\n */\n onSelect?: (context: { value: TabPanelProps['value'] }) => void;\n}\n\nexport const TabPanel: FunctionComponent<PropsWithChildren<TabPanelProps>> = ({\n value,\n className,\n onSelect,\n children,\n ...attrs\n}) => {\n const uid = useTabsUid();\n const mounted = useRef(false);\n const tabSelected = useActiveTab();\n const isActive = tabSelected === value;\n\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n\n if (isActive) {\n onSelect?.({ value });\n }\n }, [isActive, value, onSelect]);\n\n return (\n <div\n {...attrs}\n aria-hidden={!isActive}\n className={cn(\n 'relative col-start-1 row-start-1 transition-opacity duration-500',\n {\n 'pointer-events-none z-0 h-0 opacity-0': !isActive,\n 'pointer-events-auto z-1 h-auto opacity-100': isActive,\n },\n className,\n )}\n inert={isActive ? undefined : true}\n tabIndex={isActive ? 0 : -1}\n id={`TabPanel_${value}_${uid}`}\n data-name={`TabPanel_${value}`}\n role=\"tabpanel\"\n aria-labelledby={`Tab_${value}_${uid}`}\n >\n {children}\n </div>\n );\n};\n\ninterface TabListProps {\n className?: string;\n /**\n * Remove filler placeholders\n */\n constrained?: boolean;\n}\n\nexport const TabList: FunctionComponent<PropsWithChildren<TabListProps>> = ({\n className,\n constrained = false,\n children,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [currentTab, currentControl] = useActiveTabControl();\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const updateScrollState = useCallback(() => {\n const el = ref.current;\n if (!el) return;\n setCanScrollLeft(el.scrollLeft > 0);\n setCanScrollRight(Math.ceil(el.scrollLeft) < el.scrollWidth - el.clientWidth);\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n updateScrollState();\n\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(el);\n el.addEventListener('scroll', updateScrollState, { passive: true });\n\n return () => {\n observer.disconnect();\n el.removeEventListener('scroll', updateScrollState);\n };\n }, [updateScrollState]);\n\n useEffect(() => {\n if (!currentControl?.current || !ref.current) {\n return;\n }\n\n const spacerWidth = spacerRef.current!.offsetWidth ?? 0;\n const currentRect = currentControl.current.getBoundingClientRect();\n const containerRect = ref.current!.getBoundingClientRect();\n\n ref.current.scrollBy({\n left: currentRect.left - containerRect.left - spacerWidth,\n behavior: 'smooth',\n });\n }, [currentControl]);\n\n const scrollRafRef = useRef<number | null>(null);\n\n const stopScroll = useCallback(() => {\n if (scrollRafRef.current !== null) {\n cancelAnimationFrame(scrollRafRef.current);\n scrollRafRef.current = null;\n }\n }, []);\n\n const startScroll = useCallback((direction: -1 | 1) => {\n if (scrollRafRef.current !== null) return;\n const step = () => {\n ref.current?.scrollBy({ left: direction * 6 });\n scrollRafRef.current = requestAnimationFrame(step);\n };\n scrollRafRef.current = requestAnimationFrame(step);\n }, []);\n\n const handleScrollKeyUp = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') stopScroll();\n },\n [stopScroll],\n );\n\n const handleScrollLeftKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(-1);\n }\n },\n [startScroll],\n );\n\n const handleScrollRightKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(1);\n }\n },\n [startScroll],\n );\n\n useEffect(() => stopScroll, [stopScroll]);\n\n const style = { '--active-tab': currentTab } as CSSProperties;\n const isScrollable = canScrollLeft || canScrollRight;\n\n return (\n <div className=\"relative\" data-name=\"TabsHeader\">\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultLeft\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollLeft ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(-1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollLeftKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollLeft}\n tabIndex={canScrollLeft ? 0 : -1}\n >\n Scroll tabs left\n </ArrowButton>\n </div>\n )}\n <div\n className={cn(\n 'scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20',\n className,\n )}\n ref={ref}\n >\n <div role=\"tablist\" className=\"flex flex-row\" style={style}>\n <div\n ref={spacerRef}\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n {children}\n <div\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n </div>\n </div>\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultRight\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollRight ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollRightKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollRight}\n tabIndex={canScrollRight ? 0 : -1}\n >\n Scroll tabs right\n </ArrowButton>\n </div>\n )}\n </div>\n );\n};\n\nexport interface TabSelectProps {\n items: { label: string; value: number }[];\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const TabSelect: FunctionComponent<TabSelectProps> = ({\n items,\n className,\n 'aria-label': ariaLabel = 'Select tab',\n}) => {\n const activeTab = useActiveTab();\n const dispatch = useTabDispatch();\n\n const handleChange = (_event: Event, value: string) => {\n dispatch({ type: 'update', payload: Number(value) });\n };\n\n const selectValue = activeTab === -1 ? undefined : activeTab;\n\n return (\n <Select\n value={selectValue?.toString()}\n onChange={handleChange}\n name={ariaLabel}\n className={cn(className)}\n >\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </Select>\n );\n};\n\ninterface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /**\n * Tab Heading text\n */\n label?: string;\n /**\n * Tab heading index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on tab select handler\n */\n onSelect?: (context: { value: TabProps['value']; label: TabProps['label'] }) => void;\n /**\n * Heading type\n * _default: **h2**_\n */\n as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';\n}\n\nexport const Tab: FunctionComponent<PropsWithChildren<TabProps>> = ({\n as: TagName = 'h2',\n label,\n children,\n value,\n onSelect,\n className,\n ...attr\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const activeTab = useActiveTab();\n const uid = useTabsUid();\n const dispatch = useRegisterTabControl({ value, ref: ref as RefObject<HTMLDivElement> });\n const previousActiveTab = useRef(activeTab);\n\n const isActive = useRef(activeTab === value);\n isActive.current = activeTab === value;\n\n const pillStyle = { '--tab-index': value } as CSSProperties;\n\n useEffect(() => {\n if (previousActiveTab.current !== activeTab && value === activeTab) {\n ref.current?.focus();\n onSelect?.({ value, label });\n }\n if (previousActiveTab.current !== activeTab) {\n previousActiveTab.current = activeTab;\n }\n }, [label, value, onSelect, activeTab]);\n\n const start = useCallback(() => {\n dispatch({ type: 'start' });\n }, [dispatch]);\n\n const end = useCallback(() => {\n dispatch({ type: 'end' });\n }, [dispatch]);\n\n const up = useCallback(() => {\n dispatch({ type: 'previous' });\n }, [dispatch]);\n\n const down = useCallback(() => {\n dispatch({ type: 'next' });\n }, [dispatch]);\n\n const left = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'next' : 'previous' });\n }, [dispatch]);\n\n const right = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'previous' : 'next' });\n }, [dispatch]);\n\n const keyboardHandler = useKeyboardControls({\n start,\n end,\n up,\n down,\n left,\n right,\n });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';\n const isEnter = e.key === 'Enter' || e.code === 'Enter';\n\n if (isActive.current && (isSpace || isEnter)) {\n e.preventDefault();\n return;\n }\n\n keyboardHandler(e);\n },\n [keyboardHandler],\n );\n\n const handleClick = () => {\n if (isActive.current) {\n return;\n }\n\n dispatch({ type: 'update', payload: value });\n };\n\n return (\n <div\n {...attr}\n id={attr.id || `Tab_${value}_${uid}`}\n data-name=\"Tab\"\n ref={ref}\n role=\"tab\"\n aria-selected={isActive.current}\n aria-controls={`TabPanel_${value}_${uid}`}\n tabIndex={isActive.current ? 0 : -1}\n className={cn(\n 'group text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none',\n {\n 'text-white': isActive.current,\n 'text-black': !isActive.current,\n 'transition-transform active:scale-[1.03]': isActive.current,\n },\n )}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n >\n <TagName\n className={cn(\n 'relative inline-block px-20 py-12',\n 'before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within:before:bg-(--color-pearl) group-hover:before:bg-(--color-pearl) group-focus:before:bg-(--color-pearl)',\n className,\n )}\n {...(!isActive ? { role: 'presentation' } : {})}\n >\n <span\n className={cn(\n 'tab-focus-pill ease transition-transform/colors',\n 'rounded-pill absolute inset-0 -z-1 duration-300',\n 'bg-black',\n )}\n style={pillStyle}\n />\n {children ?? label}\n </TagName>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tabs.js","names":[],"sources":["../../../lib/ui/tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type FunctionComponent,\n type PropsWithChildren,\n type RefObject,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { TabsProvider } from '../contexts/TabControl';\nimport {\n useActiveTab,\n useActiveTabControl,\n useRegisterTabControl,\n useTabDispatch,\n useTabsUid,\n} from '../hooks/tabControl';\nimport { useKeyboardControls } from '../hooks/useKeyboardControls';\nimport { Select } from '../forms/Select';\nimport { cn } from '../helpers/cn';\nimport { ArrowButton } from '../buttons/ArrowButton';\n\ntype ProviderProps = ComponentProps<typeof TabsProvider>;\n\ninterface Props extends ProviderProps {\n className?: string;\n /**\n * Shrink the spacing between tabs and panels\n */\n compacted?: boolean;\n}\n\nexport const Tabs: FunctionComponent<PropsWithChildren<Props>> = ({\n className,\n compacted = false,\n selected,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'flex flex-col',\n {\n 'sm:gap-y-20': !compacted,\n },\n className,\n )}\n data-name=\"Tabs\"\n >\n <TabsProvider selected={selected}>{children}</TabsProvider>\n </div>\n );\n};\n\ninterface TabsBodyProps {\n className?: string;\n}\n\nexport const TabsBody: FunctionComponent<PropsWithChildren<TabsBodyProps>> = ({\n className,\n children,\n}) => {\n return (\n <div data-name=\"TabsBody\" className={cn('grid grid-rows-1 overflow-hidden', className)}>\n {children}\n </div>\n );\n};\n\ninterface TabPanelProps {\n className?: string;\n /**\n * Tab panel index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on panel select handler\n */\n onSelect?: (context: { value: TabPanelProps['value'] }) => void;\n}\n\nexport const TabPanel: FunctionComponent<PropsWithChildren<TabPanelProps>> = ({\n value,\n className,\n onSelect,\n children,\n ...attrs\n}) => {\n const uid = useTabsUid();\n const mounted = useRef(false);\n const tabSelected = useActiveTab();\n const isActive = tabSelected === value;\n\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n\n if (isActive) {\n onSelect?.({ value });\n }\n }, [isActive, value, onSelect]);\n\n return (\n <div\n {...attrs}\n aria-hidden={!isActive}\n className={cn(\n 'relative col-start-1 row-start-1 transition-opacity duration-500',\n {\n 'pointer-events-none z-0 h-0 opacity-0': !isActive,\n 'pointer-events-auto z-1 h-auto opacity-100': isActive,\n },\n className,\n )}\n inert={isActive ? undefined : true}\n tabIndex={isActive ? 0 : -1}\n id={`TabPanel_${value}_${uid}`}\n data-name={`TabPanel_${value}`}\n role=\"tabpanel\"\n aria-labelledby={`Tab_${value}_${uid}`}\n >\n {children}\n </div>\n );\n};\n\ninterface TabListProps {\n className?: string;\n /**\n * Remove filler placeholders\n */\n constrained?: boolean;\n}\n\nexport const TabList: FunctionComponent<PropsWithChildren<TabListProps>> = ({\n className,\n constrained = false,\n children,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [currentTab, currentControl] = useActiveTabControl();\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const updateScrollState = useCallback(() => {\n const el = ref.current;\n if (!el) return;\n setCanScrollLeft(el.scrollLeft > 0);\n setCanScrollRight(Math.ceil(el.scrollLeft) < el.scrollWidth - el.clientWidth);\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n updateScrollState();\n\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(el);\n el.addEventListener('scroll', updateScrollState, { passive: true });\n\n return () => {\n observer.disconnect();\n el.removeEventListener('scroll', updateScrollState);\n };\n }, [updateScrollState]);\n\n useEffect(() => {\n if (!currentControl?.current || !ref.current) {\n return;\n }\n\n const spacerWidth = spacerRef.current!.offsetWidth ?? 0;\n const currentRect = currentControl.current.getBoundingClientRect();\n const containerRect = ref.current!.getBoundingClientRect();\n\n ref.current.scrollBy({\n left: currentRect.left - containerRect.left - spacerWidth,\n behavior: 'smooth',\n });\n }, [currentControl]);\n\n const scrollRafRef = useRef<number | null>(null);\n\n const stopScroll = useCallback(() => {\n if (scrollRafRef.current !== null) {\n cancelAnimationFrame(scrollRafRef.current);\n scrollRafRef.current = null;\n }\n }, []);\n\n const startScroll = useCallback((direction: -1 | 1) => {\n if (scrollRafRef.current !== null) return;\n const step = () => {\n ref.current?.scrollBy({ left: direction * 6 });\n scrollRafRef.current = requestAnimationFrame(step);\n };\n scrollRafRef.current = requestAnimationFrame(step);\n }, []);\n\n const handleScrollKeyUp = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') stopScroll();\n },\n [stopScroll],\n );\n\n const handleScrollLeftKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(-1);\n }\n },\n [startScroll],\n );\n\n const handleScrollRightKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(1);\n }\n },\n [startScroll],\n );\n\n useEffect(() => stopScroll, [stopScroll]);\n\n const style = { '--active-tab': currentTab } as CSSProperties;\n const isScrollable = canScrollLeft || canScrollRight;\n\n return (\n <div className=\"relative\" data-name=\"TabsHeader\">\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultLeft\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollLeft ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(-1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollLeftKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollLeft}\n tabIndex={canScrollLeft ? 0 : -1}\n >\n Scroll tabs left\n </ArrowButton>\n </div>\n )}\n <div\n className={cn(\n 'scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20',\n className,\n )}\n ref={ref}\n >\n <div role=\"tablist\" className=\"flex flex-row\" style={style}>\n <div\n ref={spacerRef}\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n {children}\n <div\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n </div>\n </div>\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultRight\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollRight ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollRightKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollRight}\n tabIndex={canScrollRight ? 0 : -1}\n >\n Scroll tabs right\n </ArrowButton>\n </div>\n )}\n </div>\n );\n};\n\nexport interface TabSelectProps {\n items: { label: string; value: number }[];\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const TabSelect: FunctionComponent<TabSelectProps> = ({\n items,\n className,\n 'aria-label': ariaLabel = 'Select tab',\n}) => {\n const activeTab = useActiveTab();\n const dispatch = useTabDispatch();\n\n const handleChange = (_event: Event, value: string) => {\n dispatch({ type: 'update', payload: Number(value) });\n };\n\n const selectValue = activeTab === -1 ? undefined : activeTab;\n\n return (\n <Select\n value={selectValue?.toString()}\n onChange={handleChange}\n name={ariaLabel}\n className={cn(className)}\n >\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </Select>\n );\n};\n\ninterface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /**\n * Notification content\n */\n notification?: ReactNode;\n /**\n * Tab Heading text\n */\n label?: string;\n /**\n * Tab heading index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on tab select handler\n */\n onSelect?: (context: { value: TabProps['value']; label: TabProps['label'] }) => void;\n /**\n * Heading type\n * _default: **h2**_\n */\n as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';\n}\n\nexport const Tab: FunctionComponent<PropsWithChildren<TabProps>> = ({\n as: TagName = 'h2',\n label,\n children,\n value,\n onSelect,\n className,\n notification,\n ...attr\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const activeTab = useActiveTab();\n const uid = useTabsUid();\n const dispatch = useRegisterTabControl({ value, ref: ref as RefObject<HTMLDivElement> });\n const previousActiveTab = useRef(activeTab);\n\n const isActive = useRef(activeTab === value);\n isActive.current = activeTab === value;\n\n const pillStyle = { '--tab-index': value } as CSSProperties;\n\n useEffect(() => {\n if (previousActiveTab.current !== activeTab && value === activeTab) {\n ref.current?.focus();\n onSelect?.({ value, label });\n }\n if (previousActiveTab.current !== activeTab) {\n previousActiveTab.current = activeTab;\n }\n }, [label, value, onSelect, activeTab]);\n\n const start = useCallback(() => {\n dispatch({ type: 'start' });\n }, [dispatch]);\n\n const end = useCallback(() => {\n dispatch({ type: 'end' });\n }, [dispatch]);\n\n const up = useCallback(() => {\n dispatch({ type: 'previous' });\n }, [dispatch]);\n\n const down = useCallback(() => {\n dispatch({ type: 'next' });\n }, [dispatch]);\n\n const left = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'next' : 'previous' });\n }, [dispatch]);\n\n const right = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'previous' : 'next' });\n }, [dispatch]);\n\n const keyboardHandler = useKeyboardControls({\n start,\n end,\n up,\n down,\n left,\n right,\n });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';\n const isEnter = e.key === 'Enter' || e.code === 'Enter';\n\n if (isActive.current && (isSpace || isEnter)) {\n e.preventDefault();\n return;\n }\n\n keyboardHandler(e);\n },\n [keyboardHandler],\n );\n\n const handleClick = () => {\n if (isActive.current) {\n return;\n }\n\n dispatch({ type: 'update', payload: value });\n };\n\n return (\n <div\n {...attr}\n id={attr.id || `Tab_${value}_${uid}`}\n data-name=\"Tab\"\n ref={ref}\n role=\"tab\"\n aria-selected={isActive.current}\n aria-controls={`TabPanel_${value}_${uid}`}\n tabIndex={isActive.current ? 0 : -1}\n className={cn(\n 'group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none',\n {\n 'text-white': isActive.current,\n 'text-black': !isActive.current,\n 'transition-transform active:scale-[1.03]': isActive.current,\n },\n )}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n >\n <TagName\n className={cn(\n 'relative inline-block px-20 py-12',\n 'before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)',\n className,\n )}\n {...(!isActive ? { role: 'presentation' } : {})}\n >\n <span\n className={cn(\n 'tab-focus-pill ease transition-transform/colors',\n 'rounded-pill absolute inset-0 -z-1 duration-300',\n 'bg-black',\n )}\n style={pillStyle}\n />\n <span className=\"flex items-center gap-8\">\n {children ?? label}\n {notification && (\n <div\n className={cn(\n 'size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300',\n {\n 'group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl':\n !isActive.current,\n },\n )}\n >\n {notification}\n </div>\n )}\n </span>\n </TagName>\n </div>\n );\n};\n"],"mappings":"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"}
|