Merge branch 'main' into feat/manage-all-booking-inputs
commit
020aad147e
|
@ -1,5 +1,6 @@
|
|||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { EventType } from "@prisma/client";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useMemo, useReducer, useState } from "react";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
|
@ -35,15 +36,16 @@ import { timeZone as localStorageTimeZone } from "@lib/clock";
|
|||
import useRouterQuery from "@lib/hooks/useRouterQuery";
|
||||
|
||||
import Gates, { Gate, GateState } from "@components/Gates";
|
||||
import AvailableTimes from "@components/booking/AvailableTimes";
|
||||
import BookingDescription from "@components/booking/BookingDescription";
|
||||
import TimeOptions from "@components/booking/TimeOptions";
|
||||
import PoweredByCal from "@components/ui/PoweredByCal";
|
||||
|
||||
import type { AvailabilityPageProps } from "../../../pages/[user]/[type]";
|
||||
import type { DynamicAvailabilityPageProps } from "../../../pages/d/[link]/[slug]";
|
||||
import type { AvailabilityTeamPageProps } from "../../../pages/team/[slug]/[type]";
|
||||
|
||||
const PoweredByCal = dynamic(() => import("@components/ui/PoweredByCal"));
|
||||
const AvailableTimes = dynamic(() => import("@components/booking/AvailableTimes"));
|
||||
|
||||
const useSlots = ({
|
||||
eventTypeId,
|
||||
eventTypeSlug,
|
||||
|
@ -197,22 +199,24 @@ const SlotPicker = ({
|
|||
/>
|
||||
|
||||
<div ref={slotPickerRef}>
|
||||
<AvailableTimes
|
||||
isLoading={isLoadingSelectedDateSlots}
|
||||
slots={
|
||||
selectedDate &&
|
||||
(selectedDateSlots[selectedDate.format("YYYY-MM-DD")] ||
|
||||
monthSlots[selectedDate.format("YYYY-MM-DD")])
|
||||
}
|
||||
date={selectedDate}
|
||||
timeFormat={timeFormat}
|
||||
onTimeFormatChange={onTimeFormatChange}
|
||||
eventTypeId={eventType.id}
|
||||
eventTypeSlug={eventType.slug}
|
||||
seatsPerTimeSlot={seatsPerTimeSlot}
|
||||
recurringCount={recurringEventCount}
|
||||
ethSignature={ethSignature}
|
||||
/>
|
||||
{selectedDate ? (
|
||||
<AvailableTimes
|
||||
isLoading={isLoadingSelectedDateSlots}
|
||||
slots={
|
||||
selectedDate &&
|
||||
(selectedDateSlots[selectedDate.format("YYYY-MM-DD")] ||
|
||||
monthSlots[selectedDate.format("YYYY-MM-DD")])
|
||||
}
|
||||
date={selectedDate}
|
||||
timeFormat={timeFormat}
|
||||
onTimeFormatChange={onTimeFormatChange}
|
||||
eventTypeId={eventType.id}
|
||||
eventTypeSlug={eventType.slug}
|
||||
seatsPerTimeSlot={seatsPerTimeSlot}
|
||||
recurringCount={recurringEventCount}
|
||||
ethSignature={ethSignature}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -199,7 +199,7 @@ export const EventSetupTab = (
|
|||
// We dont want to translate the string link - it doesnt exist in common.json and it gets prefixed/suffixed with __ or //
|
||||
const eventLabel =
|
||||
eventLocationType.defaultValueVariable === "link"
|
||||
? location[eventLocationType.defaultValueVariable]
|
||||
? eventLocationType.label
|
||||
: t(location[eventLocationType.defaultValueVariable] || eventLocationType.label);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
import { IS_SELF_HOSTED } from "@calcom/lib/constants";
|
||||
|
@ -22,7 +24,13 @@ export const UsernameAvailabilityField = ({
|
|||
onErrorMutation,
|
||||
user,
|
||||
}: UsernameAvailabilityFieldProps) => {
|
||||
const { username: currentUsername, setQuery: setCurrentUsername } = useRouterQuery("username");
|
||||
const router = useRouter();
|
||||
const [currentUsernameState, setCurrentUsernameState] = useState(user.username || "");
|
||||
const { username: usernameFromQuery, setQuery: setUsernameFromQuery } = useRouterQuery("username");
|
||||
const { username: currentUsername, setQuery: setCurrentUsername } =
|
||||
router.query["username"] && user.username === null
|
||||
? { username: usernameFromQuery, setQuery: setUsernameFromQuery }
|
||||
: { username: currentUsernameState || "", setQuery: setCurrentUsernameState };
|
||||
const formMethods = useForm({
|
||||
defaultValues: {
|
||||
username: currentUsername,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "2.5.15",
|
||||
"version": "2.6.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
|
@ -170,6 +170,7 @@
|
|||
"nextBundleAnalysis": {
|
||||
"budget": 358400,
|
||||
"budgetPercentIncreaseRed": 20,
|
||||
"minimumChangeThreshold": 500,
|
||||
"showDetails": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,6 +291,15 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
}
|
||||
const isDynamicGroup = users.length > 1;
|
||||
|
||||
if (isDynamicGroup) {
|
||||
// sort and be in the same order as usernameList so first user is the first user in the list
|
||||
users.sort((a, b) => {
|
||||
const aIndex = (a.username && usernameList.indexOf(a.username)) || 0;
|
||||
const bIndex = (b.username && usernameList.indexOf(b.username)) || 0;
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
}
|
||||
|
||||
const dynamicNames = isDynamicGroup
|
||||
? users.map((user) => {
|
||||
return user.name || "";
|
||||
|
|
|
@ -3,13 +3,18 @@ import { GetStaticPaths, GetStaticPropsContext } from "next";
|
|||
import { z } from "zod";
|
||||
|
||||
import { privacyFilteredLocations, LocationObject } from "@calcom/app-store/locations";
|
||||
import { getAppFromSlug } from "@calcom/app-store/utils";
|
||||
import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { getDefaultEvent, getGroupName, getUsernameList } from "@calcom/lib/defaultEvents";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { User } from "@calcom/prisma/client";
|
||||
import { EventTypeMetaDataSchema, teamMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||
import {
|
||||
EventTypeMetaDataSchema,
|
||||
teamMetadataSchema,
|
||||
userMetadata as userMetadataSchema,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { isBrandingHidden } from "@lib/isBrandingHidden";
|
||||
import { inferSSRProps } from "@lib/types/inferSSRProps";
|
||||
|
@ -215,6 +220,7 @@ async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
|
|||
darkBrandColor: true,
|
||||
defaultScheduleId: true,
|
||||
allowDynamicBooking: true,
|
||||
metadata: true,
|
||||
away: true,
|
||||
schedules: {
|
||||
select: {
|
||||
|
@ -233,7 +239,32 @@ async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
|
|||
};
|
||||
}
|
||||
|
||||
const locations = eventType.locations ? (eventType.locations as LocationObject[]) : [];
|
||||
// sort and be in the same order as usernameList so first user is the first user in the list
|
||||
let sortedUsers: typeof users = [];
|
||||
if (users.length > 1) {
|
||||
sortedUsers = users.sort((a, b) => {
|
||||
const aIndex = (a.username && usernameList.indexOf(a.username)) || 0;
|
||||
const bIndex = (b.username && usernameList.indexOf(b.username)) || 0;
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
}
|
||||
|
||||
let locations = eventType.locations ? (eventType.locations as LocationObject[]) : [];
|
||||
|
||||
// Get the prefered location type from the first user
|
||||
const firstUsersMetadata = userMetadataSchema.parse(sortedUsers[0].metadata || {});
|
||||
const preferedLocationType = firstUsersMetadata?.defaultConferencingApp;
|
||||
|
||||
if (preferedLocationType?.appSlug) {
|
||||
const foundApp = getAppFromSlug(preferedLocationType.appSlug);
|
||||
const appType = foundApp?.appData?.location?.type;
|
||||
if (appType) {
|
||||
// Replace the location with the prefered location type
|
||||
// This will still be default to daily if the app is not found
|
||||
locations = [{ type: appType, link: preferedLocationType.appLink }] as LocationObject[];
|
||||
}
|
||||
}
|
||||
|
||||
const eventTypeObject = Object.assign({}, eventType, {
|
||||
metadata: EventTypeMetaDataSchema.parse(eventType.metadata || {}),
|
||||
recurringEvent: parseRecurringEvent(eventType.recurringEvent),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { GetServerSidePropsContext } from "next";
|
||||
|
||||
import { LocationObject, privacyFilteredLocations } from "@calcom/app-store/locations";
|
||||
import { getAppFromSlug } from "@calcom/app-store/utils";
|
||||
import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/getBookingFields";
|
||||
import { parseRecurringEvent } from "@calcom/lib";
|
||||
import {
|
||||
|
@ -12,7 +13,11 @@ import {
|
|||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { bookEventTypeSelect } from "@calcom/prisma";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { customInputSchema, EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
import {
|
||||
customInputSchema,
|
||||
EventTypeMetaDataSchema,
|
||||
userMetadata as userMetadataSchema,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { asStringOrNull, asStringOrThrow } from "@lib/asStringOrNull";
|
||||
import getBooking, { GetBookingType } from "@lib/getBooking";
|
||||
|
@ -86,6 +91,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
darkBrandColor: true,
|
||||
allowDynamicBooking: true,
|
||||
away: true,
|
||||
metadata: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -118,8 +124,38 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
recurringEvent: parseRecurringEvent(eventTypeRaw.recurringEvent),
|
||||
};
|
||||
|
||||
const eventTypeObject = [eventType].map((e) => {
|
||||
const getLocations = () => {
|
||||
let locations = eventTypeRaw.locations || [];
|
||||
if (!isDynamicGroupBooking) return locations;
|
||||
|
||||
let sortedUsers: typeof users = [];
|
||||
// sort and be in the same order as usernameList so first user is the first user in the list
|
||||
if (users.length > 1) {
|
||||
sortedUsers = users.sort((a, b) => {
|
||||
const aIndex = (a.username && usernameList.indexOf(a.username)) || 0;
|
||||
const bIndex = (b.username && usernameList.indexOf(b.username)) || 0;
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
}
|
||||
|
||||
// Get the prefered location type from the first user
|
||||
const firstUsersMetadata = userMetadataSchema.parse(sortedUsers[0].metadata || {});
|
||||
const preferedLocationType = firstUsersMetadata?.defaultConferencingApp;
|
||||
|
||||
if (preferedLocationType?.appSlug) {
|
||||
const foundApp = getAppFromSlug(preferedLocationType.appSlug);
|
||||
const appType = foundApp?.appData?.location?.type;
|
||||
if (appType) {
|
||||
// Replace the location with the prefered location type
|
||||
// This will still be default to daily if the app is not found
|
||||
locations = [{ type: appType, link: preferedLocationType.appLink }] as LocationObject[];
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
};
|
||||
|
||||
const eventTypeObject = [eventType].map((e) => {
|
||||
let locations = getLocations();
|
||||
locations = privacyFilteredLocations(locations as LocationObject[]);
|
||||
return {
|
||||
...e,
|
||||
|
|
|
@ -188,6 +188,10 @@ export function getAppType(name: string): string {
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
export function getAppFromSlug(slug: string | undefined): AppMeta | undefined {
|
||||
return ALL_APPS.find((app) => app.slug === slug);
|
||||
}
|
||||
|
||||
export const getEventTypeAppData = <T extends EventTypeAppsList>(
|
||||
eventType: Pick<z.infer<typeof EventTypeModel>, "price" | "currency" | "metadata">,
|
||||
appId: T,
|
||||
|
|
|
@ -1,22 +1,30 @@
|
|||
import AttendeeScheduledEmailClass from "../../templates/attendee-rescheduled-email";
|
||||
import { AttendeeScheduledEmail } from "./AttendeeScheduledEmail";
|
||||
|
||||
export const AttendeeRequestEmail = (props: React.ComponentProps<typeof AttendeeScheduledEmail>) => (
|
||||
<AttendeeScheduledEmail
|
||||
title={props.calEvent.attendees[0].language.translate(
|
||||
props.calEvent.recurringEvent?.count ? "booking_submitted_recurring" : "booking_submitted"
|
||||
)}
|
||||
subtitle={
|
||||
<>
|
||||
{props.calEvent.attendees[0].language.translate(
|
||||
props.calEvent.recurringEvent?.count
|
||||
? "user_needs_to_confirm_or_reject_booking_recurring"
|
||||
: "user_needs_to_confirm_or_reject_booking",
|
||||
{ user: props.calEvent.organizer.name }
|
||||
)}
|
||||
</>
|
||||
}
|
||||
headerType="calendarCircle"
|
||||
subject={props.calEvent.attendees[0].language.translate("booking_submitted_subject")}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
export const AttendeeRequestEmail = (props: React.ComponentProps<typeof AttendeeScheduledEmail>) => {
|
||||
const date = new AttendeeScheduledEmailClass(props.calEvent, props.attendee).getFormattedDate();
|
||||
|
||||
return (
|
||||
<AttendeeScheduledEmail
|
||||
title={props.calEvent.attendees[0].language.translate(
|
||||
props.calEvent.recurringEvent?.count ? "booking_submitted_recurring" : "booking_submitted"
|
||||
)}
|
||||
subtitle={
|
||||
<>
|
||||
{props.calEvent.attendees[0].language.translate(
|
||||
props.calEvent.recurringEvent?.count
|
||||
? "user_needs_to_confirm_or_reject_booking_recurring"
|
||||
: "user_needs_to_confirm_or_reject_booking",
|
||||
{ user: props.calEvent.organizer.name }
|
||||
)}
|
||||
</>
|
||||
}
|
||||
headerType="calendarCircle"
|
||||
subject={props.calEvent.attendees[0].language.translate("booking_submitted_subject", {
|
||||
title: props.calEvent.title,
|
||||
date,
|
||||
})}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -105,7 +105,7 @@ ${getRichDescription(this.calEvent)}
|
|||
return this.getRecipientTime(this.calEvent.endTime, format);
|
||||
}
|
||||
|
||||
protected getFormattedDate() {
|
||||
public getFormattedDate() {
|
||||
return `${this.getInviteeStart("h:mma")} - ${this.getInviteeEnd("h:mma")}, ${this.t(
|
||||
this.getInviteeStart("dddd").toLowerCase()
|
||||
)}, ${this.t(this.getInviteeStart("MMMM").toLowerCase())} ${this.getInviteeStart("D, YYYY")}`;
|
||||
|
|
|
@ -19,7 +19,7 @@ import { metadata as GoogleMeetMetadata } from "@calcom/app-store/googlevideo/_m
|
|||
import { getLocationValueForDB, LocationObject } from "@calcom/app-store/locations";
|
||||
import { MeetLocationType } from "@calcom/app-store/locations";
|
||||
import { handleEthSignature } from "@calcom/app-store/rainbow/utils/ethereum";
|
||||
import { EventTypeAppsList, getEventTypeAppData } from "@calcom/app-store/utils";
|
||||
import { EventTypeAppsList, getAppFromSlug, getEventTypeAppData } from "@calcom/app-store/utils";
|
||||
import { cancelScheduledJobs, scheduleTrigger } from "@calcom/app-store/zapier/lib/nodeScheduler";
|
||||
import EventManager from "@calcom/core/EventManager";
|
||||
import { getEventName } from "@calcom/core/event";
|
||||
|
@ -53,6 +53,7 @@ import {
|
|||
customInputSchema,
|
||||
EventTypeMetaDataSchema,
|
||||
extendedBookingCreateBody,
|
||||
userMetadata as userMetadataSchema,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
import type { BufferedBusyTime } from "@calcom/types/BufferedBusyTime";
|
||||
import type { AdditionalInformation, AppsStatus, CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
@ -491,7 +492,10 @@ async function handler(
|
|||
in: dynamicUserList,
|
||||
},
|
||||
},
|
||||
...userSelect,
|
||||
select: {
|
||||
...userSelect.select,
|
||||
metadata: true,
|
||||
},
|
||||
})
|
||||
: !!eventType.hosts?.length
|
||||
? eventType.hosts.map(({ user, isFixed }) => ({
|
||||
|
@ -500,7 +504,10 @@ async function handler(
|
|||
}))
|
||||
: eventType.users;
|
||||
// loadUsers allows type inferring
|
||||
let users: (Awaited<ReturnType<typeof loadUsers>>[number] & { isFixed?: boolean })[] = await loadUsers();
|
||||
let users: (Awaited<ReturnType<typeof loadUsers>>[number] & {
|
||||
isFixed?: boolean;
|
||||
metadata?: Prisma.JsonValue;
|
||||
})[] = await loadUsers();
|
||||
|
||||
const isDynamicAllowed = !users.some((user) => !user.allowDynamicBooking);
|
||||
if (!isDynamicAllowed && !eventTypeId) {
|
||||
|
@ -613,8 +620,21 @@ async function handler(
|
|||
const seed = `${organizerUser.username}:${dayjs(bookingData.start).utc().format()}:${new Date().getTime()}`;
|
||||
const uid = translator.fromUUID(uuidv5(seed, uuidv5.URL));
|
||||
|
||||
const bookingLocation = getLocationValueForDB(location, eventType.locations);
|
||||
let locationBodyString = reqBody.location;
|
||||
let defaultLocationUrl = undefined;
|
||||
if (dynamicUserList.length > 1) {
|
||||
users = users.sort((a, b) => {
|
||||
const aIndex = (a.username && dynamicUserList.indexOf(a.username)) || 0;
|
||||
const bIndex = (b.username && dynamicUserList.indexOf(b.username)) || 0;
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
const firstUsersMetadata = userMetadataSchema.parse(users[0].metadata);
|
||||
const app = getAppFromSlug(firstUsersMetadata?.defaultConferencingApp?.appSlug);
|
||||
locationBodyString = app?.appData?.location?.type || locationBodyString;
|
||||
defaultLocationUrl = firstUsersMetadata?.defaultConferencingApp?.appLink;
|
||||
}
|
||||
|
||||
const bookingLocation = getLocationValueForDB(locationBodyString, eventType.locations);
|
||||
const customInputs = getCustomInputsResponses(bookingData, eventType.customInputs);
|
||||
const teamMemberPromises =
|
||||
users.length > 1
|
||||
|
@ -1153,7 +1173,7 @@ async function handler(
|
|||
metadata.conferenceData = results[0].createdEvent?.conferenceData;
|
||||
metadata.entryPoints = results[0].createdEvent?.entryPoints;
|
||||
handleAppsStatus(results, booking);
|
||||
videoCallUrl = metadata.hangoutLink || videoCallUrl;
|
||||
videoCallUrl = metadata.hangoutLink || defaultLocationUrl || videoCallUrl;
|
||||
}
|
||||
if (noEmail !== true) {
|
||||
await sendScheduledEmails({
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
|
||||
|
||||
import {
|
||||
Examples,
|
||||
Example,
|
||||
Note,
|
||||
Title,
|
||||
VariantsTable,
|
||||
VariantColumn,
|
||||
RowTitles,
|
||||
CustomArgsTable,
|
||||
} from "@calcom/storybook/components";
|
||||
|
||||
import { Tooltip } from "../tooltip";
|
||||
import { FiPlus, FiX } from "../icon";
|
||||
import { Flex } from "./Flex";
|
||||
|
||||
<Meta title="Layout/Spacing" />
|
||||
|
||||
<Title title="Spacing" suffix="Brief" subtitle="Version 2.0 — Last Update: 15 Feb 2023" />
|
||||
|
||||
## Definition
|
||||
|
||||
Defines the spacing guide used in Cal.coms design system
|
||||
|
||||
## Structure
|
||||
|
||||
<Examples title="Spacing">
|
||||
<TooltipPrimitive.Provider>
|
||||
<>
|
||||
<Example title="0"></Example>
|
||||
<Example title="px">
|
||||
<Tooltip content="1px">
|
||||
<div className="h-4 w-px bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="0.5">
|
||||
<Tooltip content="2px">
|
||||
<div className="h-4 w-0.5 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="1">
|
||||
<Tooltip content="4px">
|
||||
<div className="h-4 w-1 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="2">
|
||||
<Tooltip content="8px">
|
||||
<div className="h-4 w-2 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="3">
|
||||
<Tooltip content="12px">
|
||||
<div className="h-4 w-3 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="4">
|
||||
<Tooltip content="16px">
|
||||
<div className="h-4 w-4 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="5">
|
||||
<Tooltip content="20px">
|
||||
<div className="h-4 w-5 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="6">
|
||||
<Tooltip content="24px">
|
||||
<div className="h-4 w-6 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="8">
|
||||
<Tooltip content="32px">
|
||||
<div className="h-4 w-8 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
<Example title="10">
|
||||
<Tooltip content="48px">
|
||||
<div className="h-4 w-10 bg-gray-900 rounded-sm"> </div>
|
||||
</Tooltip>
|
||||
</Example>
|
||||
</>
|
||||
</TooltipPrimitive.Provider>
|
||||
</Examples>
|
Loading…
Reference in New Issue