a11y: right-to-left improvements (#6235)

* fixed a ton of rtl issues

* removed duplicant

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
This commit is contained in:
Peer Richelsen
2023-01-04 07:38:45 +00:00
committed by GitHub
co-authored by kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> sean-brydon
parent 9250b20c1d
commit 45d10a3bc4
90 changed files with 248 additions and 207 deletions
+3 -3
View File
@@ -639,7 +639,7 @@ const ChooseEmbedTypesDialogContent = () => {
<div className="flex items-start">
{embeds.map((embed, index) => (
<button
className="mr-2 w-1/3 border border-transparent p-3 text-left hover:rounded-md hover:border-gray-200 hover:bg-neutral-100"
className="w-1/3 border border-transparent p-3 text-left hover:rounded-md hover:border-gray-200 hover:bg-neutral-100 ltr:mr-2 rtl:ml-2"
key={index}
data-testid={embed.type}
onClick={() => {
@@ -914,7 +914,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
<div
className={classNames(
"mt-4 flex items-center justify-start",
embedType === "floating-popup" ? "space-x-2" : "hidden"
embedType === "floating-popup" ? "space-x-2 rtl:space-x-reverse" : "hidden"
)}>
<Switch
defaultChecked={true}
@@ -1010,7 +1010,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
</CollapsibleTrigger>
<CollapsibleContent>
<div className="mt-6 text-sm">
<div className="mb-4 flex items-center justify-start space-x-2">
<div className="mb-4 flex items-center justify-start space-x-2 rtl:space-x-reverse">
<Switch
checked={previewState.hideEventTypeDetails}
onCheckedChange={(checked) => {
@@ -56,7 +56,7 @@ function IntegrationListItem(props: {
<ListItemText component="p">{props.description}</ListItemText>
{/* Alert error that key stopped working. */}
{props.invalidCredential && (
<div className="flex items-center space-x-2">
<div className="flex items-center space-x-2 rtl:space-x-reverse">
<Icon.FiAlertCircle className="w-8 text-red-500 sm:w-4" />
<ListItemText component="p" className="whitespace-pre-wrap text-red-500">
{t("invalid_credential")}
@@ -16,12 +16,12 @@ export function AvailableEventLocations({ locations }: { locations: Props["event
return (
<div key={location.type} className="flex flex-row items-center text-sm font-medium">
{eventLocationType.iconUrl === "/link.svg" ? (
<Icon.FiLink className="dark:text-darkgray-600 mr-[10px] ml-[2px] h-4 w-4 opacity-70 dark:opacity-100 " />
<Icon.FiLink className="dark:text-darkgray-600 ml-[2px] h-4 w-4 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 " />
) : (
<img
src={eventLocationType.iconUrl}
className={classNames(
"mr-[10px] ml-[2px] h-4 w-4 opacity-70 dark:opacity-100 ",
"ml-[2px] h-4 w-4 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 ",
!eventLocationType.iconUrl?.includes("api") ? "dark:invert" : ""
)}
alt={`${eventLocationType.label} icon`}
@@ -95,7 +95,7 @@ const BookingDescription: FC<Props> = (props) => {
<div>
<Icon.FiInfo
className={classNames(
"mr-[10px] ml-[2px] inline-block h-4 w-4",
"ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]",
isBookingPage && "dark:text-darkgray-600 -mt-1 text-gray-500"
)}
/>
@@ -112,7 +112,7 @@ const BookingDescription: FC<Props> = (props) => {
isBookingPage && "dark:text-darkgray-600 text-sm font-medium text-gray-600"
)}>
<div>
<Icon.FiCheckSquare className="mr-[10px] ml-[2px] inline-block h-4 w-4 " />
<Icon.FiCheckSquare className="ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] " />
</div>
{requiresConfirmationText}
</div>
@@ -127,7 +127,7 @@ const BookingDescription: FC<Props> = (props) => {
)}>
<Icon.FiClock
className={classNames(
"min-h-4 min-w-4 mr-[10px] ml-[2px] inline-block",
"min-h-4 min-w-4 ml-[2px] inline-block ltr:mr-[10px] rtl:ml-[10px]",
isBookingPage && "mt-[2px]"
)}
/>
@@ -363,7 +363,7 @@ function BookingListItem(booking: BookingItemProps) {
<span> </span>
{!!booking?.eventType?.price && !booking.paid && (
<Badge className="hidden ltr:ml-2 rtl:mr-2 sm:inline-flex" variant="orange">
<Badge className="hidden ltr:ml-2 ltr:mr-2 rtl:ml-2 sm:inline-flex" variant="orange">
{t("pending_payment")}
</Badge>
)}
@@ -221,7 +221,7 @@ function TimezoneDropdown({
<Popover.Root open={isTimeOptionsOpen} onOpenChange={setIsTimeOptionsOpen}>
<Popover.Trigger className="min-w-32 dark:text-darkgray-600 radix-state-open:bg-gray-200 dark:radix-state-open:bg-darkgray-200 group relative mb-2 -ml-2 !mt-2 inline-block self-start rounded-md px-2 py-2 text-left text-gray-600">
<p className="flex items-center text-sm font-medium">
<Icon.FiGlobe className="min-h-4 min-w-4 mr-[10px] ml-[2px] -mt-[2px] inline-block" />
<Icon.FiGlobe className="min-h-4 min-w-4 ml-[2px] -mt-[2px] inline-block ltr:mr-[10px] rtl:ml-[10px]" />
{timeZone}
{isTimeOptionsOpen ? (
<Icon.FiChevronUp className="min-h-4 min-w-4 ml-1 inline-block" />
@@ -368,7 +368,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
<BookingDescription profile={profile} eventType={eventType} rescheduleUid={rescheduleUid}>
{!rescheduleUid && eventType.recurringEvent && (
<div className="flex items-start text-sm font-medium">
<Icon.FiRefreshCcw className="float-left mr-[10px] mt-[7px] ml-[2px] inline-block h-4 w-4 " />
<Icon.FiRefreshCcw className="float-left mt-[7px] ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] " />
<div>
<p className="mb-1 -ml-2 inline px-2 py-1">
{getRecurringFreq({ t, recurringEvent: eventType.recurringEvent })}
@@ -393,7 +393,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
)}
{stripeAppData.price > 0 && (
<p className="-ml-2 px-2 text-sm font-medium">
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
<Icon.FiCreditCard className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<IntlProvider locale="en">
<FormattedNumber
value={stripeAppData.price / 100.0}
@@ -414,7 +414,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
{t("former_time")}
</p>
<p className="text-gray-500 line-through dark:text-darkgray-600">
<CalendarIcon className="mr-[10px] -mt-1 inline-block h-4 w-4 text-gray-500" />
<CalendarIcon className="ltr:mr-[10px] rtl:ml-[10px] -mt-1 inline-block h-4 w-4 text-gray-500" />
{typeof booking.startTime === "string" && parseDate(dayjs(booking.startTime), i18n)}
</p>
</div>
@@ -501,7 +501,7 @@ const BookingPage = ({
<BookingDescription isBookingPage profile={profile} eventType={eventType}>
{stripeAppData.price > 0 && (
<p className="text-bookinglight -ml-2 px-2 text-sm ">
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
<Icon.FiCreditCard className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<IntlProvider locale="en">
<FormattedNumber
value={stripeAppData.price / 100.0}
@@ -513,7 +513,7 @@ const BookingPage = ({
)}
{!rescheduleUid && eventType.recurringEvent?.freq && recurringEventCount && (
<div className="items-start text-sm font-medium text-gray-600 dark:text-white">
<Icon.FiRefreshCw className="mr-[10px] ml-[2px] inline-block h-4 w-4" />
<Icon.FiRefreshCw className="ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<p className="-ml-2 inline-block items-center px-2">
{getEveryFreqFor({
t,
@@ -524,7 +524,7 @@ const BookingPage = ({
</div>
)}
<div className="text-bookinghighlight flex items-start text-sm">
<Icon.FiCalendar className="mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4" />
<Icon.FiCalendar className="ml-[2px] mt-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<div className="text-sm font-medium">
{(rescheduleUid || !eventType.recurringEvent?.freq) && `${parseDate(date, i18n)}`}
{!rescheduleUid &&
@@ -552,7 +552,7 @@ const BookingPage = ({
{t("former_time")}
</p>
<p className="line-through ">
<Icon.FiCalendar className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
<Icon.FiCalendar className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
{typeof booking.startTime === "string" && parseDate(dayjs(booking.startTime), i18n)}
</p>
</div>
@@ -560,7 +560,7 @@ const BookingPage = ({
{!!eventType.seatsPerTimeSlot && (
<div className="text-bookinghighlight flex items-start text-sm">
<Icon.FiUser
className={`mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4 ${
className={`ml-[2px] mt-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] ${
booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.5
? "text-rose-600"
: booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.33
@@ -623,7 +623,7 @@ const BookingPage = ({
/>
{bookingForm.formState.errors.email && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="mr-2 h-3 w-3" />
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("email_validation_error")}</p>
</div>
)}
@@ -664,7 +664,7 @@ const BookingPage = ({
value={location.type}
defaultChecked={i === 0}
/>
<span className="text-sm ltr:ml-2 rtl:mr-2 dark:text-white">
<span className="text-sm ltr:ml-2 ltr:mr-2 rtl:ml-2 dark:text-white">
{locationKeyToString(location)}
</span>
</label>
@@ -716,7 +716,7 @@ const BookingPage = ({
</div>
{bookingForm.formState.errors.phone && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="mr-2 h-3 w-3" />
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("invalid_number")}</p>
</div>
)}
@@ -834,7 +834,7 @@ const BookingPage = ({
/>
{bookingForm.formState.errors?.customInputs?.[input.id] && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="mr-2 h-3 w-3" />
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("invalid_number")}</p>
</div>
)}
@@ -914,7 +914,7 @@ const BookingPage = ({
</div>
{bookingForm.formState.errors.smsReminderNumber && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="mr-2 h-3 w-3" />
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("invalid_number")}</p>
</div>
)}
@@ -354,7 +354,7 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
/>
{selectedLocation && LocationOptions}
<DialogFooter>
<div className="mt-4 flex justify-end space-x-2">
<div className="mt-4 flex justify-end space-x-2 rtl:space-x-reverse">
<Button
onClick={() => {
setShowLocationModal(false);
@@ -149,7 +149,7 @@ export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
<span className="w-16 sm:w-28 sm:text-left">
{format(dayRange.startTime, timeFormat === 12)}
</span>
<span className="ml-4">-</span>
<span className="ltr:ml-4 rtl:mr-4">-</span>
<div className="ml-6">{format(dayRange.endTime, timeFormat === 12)}</div>
</div>
))}
@@ -164,7 +164,7 @@ export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
<hr />
<div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between">
<span className="flex items-center justify-center text-sm text-gray-600 sm:justify-start">
<Icon.FiGlobe className="mr-2" />
<Icon.FiGlobe className="ltr:mr-2 rtl:ml-2" />
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
</span>
<Button
@@ -134,8 +134,8 @@ const CustomInputTypeForm: FC<Props> = (props) => {
value={selectedCustomInput?.id || -1}
{...register("id", { valueAsNumber: true })}
/>
<div className="mt-5 flex justify-end space-x-2 sm:mt-4">
<Button onClick={onCancel} type="button" color="secondary" className="ltr:mr-2">
<div className="mt-5 flex justify-end space-x-2 rtl:space-x-reverse sm:mt-4">
<Button onClick={onCancel} type="button" color="secondary" className="ltr:mr-2 rtl:ml-2">
{t("cancel")}
</Button>
<Button
@@ -197,7 +197,7 @@ export const EventLimitsTab = ({ eventType }: Pick<EventTypeSetupProps, "eventTy
label={t("minimum_booking_notice")}
type="number"
placeholder="120"
className="mr-2 mb-0 h-[38px] rounded-[4px]"
className="mb-0 h-[38px] rounded-[4px] ltr:mr-2 rtl:ml-2"
{...formMethods.register("minimumBookingNoticeInDurationType", {
onChange: (event: React.ChangeEvent<HTMLInputElement>) =>
onMinimumNoticeChange(event.target.value),
@@ -327,7 +327,7 @@ export const EventLimitsTab = ({ eventType }: Pick<EventTypeSetupProps, "eventTy
</div>
)}
{period.type === "RANGE" && (
<div className="inline-flex space-x-2 ltr:ml-2 rtl:mr-2 rtl:space-x-reverse">
<div className="inline-flex space-x-2 ltr:ml-2 ltr:mr-2 rtl:ml-2 rtl:space-x-reverse">
<Controller
name="periodDates"
control={formMethods.control}
@@ -347,7 +347,9 @@ export const EventLimitsTab = ({ eventType }: Pick<EventTypeSetupProps, "eventTy
/>
</div>
)}
{period.suffix ? <span className="ltr:ml-2 rtl:mr-2">&nbsp;{period.suffix}</span> : null}
{period.suffix ? (
<span className="ltr:ml-2 ltr:mr-2 rtl:ml-2">&nbsp;{period.suffix}</span>
) : null}
</div>
);
})}
@@ -410,7 +412,9 @@ const BookingLimits = () => {
.map(([key, bookingAmount]) => {
const bookingLimitKey = key as BookingLimitsKey;
return (
<div className="mb-2 flex items-center space-x-2 text-sm" key={bookingLimitKey}>
<div
className="mb-2 flex items-center space-x-2 text-sm rtl:space-x-reverse"
key={bookingLimitKey}>
<Input
id={`${bookingLimitKey}-limit`}
type="number"
@@ -57,7 +57,7 @@ export default function RecurringEventController({
{recurringEventState && (
<div data-testid="recurring-event-collapsible" className="text-sm">
<div className="flex items-center">
<p className="mr-2 text-neutral-900">{t("repeats_every")}</p>
<p className="text-neutral-900 ltr:mr-2 rtl:ml-2">{t("repeats_every")}</p>
<input
type="number"
min="1"
@@ -89,7 +89,7 @@ export default function RecurringEventController({
/>
</div>
<div className="mt-4 flex items-center">
<p className="mr-2 text-neutral-900">{t("for_a_maximum_of")}</p>
<p className="text-neutral-900 ltr:mr-2 rtl:ml-2">{t("for_a_maximum_of")}</p>
<input
type="number"
min="1"
@@ -105,7 +105,7 @@ export default function RecurringEventController({
setRecurringEventState(newVal);
}}
/>
<p className="mr-2 text-neutral-900">
<p className="text-neutral-900 ltr:mr-2 rtl:ml-2">
{t("events", {
count: recurringEventState.count,
})}
@@ -82,7 +82,7 @@ const DisableTwoFactorAuthModal = ({ onDisable, onCancel }: DisableTwoFactorAuth
</div>
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<Button type="submit" className="ltr:ml-2 rtl:mr-2" disabled={isDisabling}>
<Button type="submit" className="ltr:ml-2 ltr:mr-2 rtl:ml-2" disabled={isDisabling}>
{t("disable")}
</Button>
<Button color="secondary" onClick={onCancel}>
@@ -177,7 +177,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps)
<WithStep step={SetupStep.ConfirmPassword} current={step}>
<Button
type="submit"
className="ltr:ml-2 rtl:mr-2"
className="ltr:ml-2 ltr:mr-2 rtl:ml-2"
onClick={handleSetup}
disabled={password.length === 0 || isSubmitting}>
{t("continue")}
@@ -186,13 +186,13 @@ const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps)
<WithStep step={SetupStep.DisplayQrCode} current={step}>
<Button
type="submit"
className="ltr:ml-2 rtl:mr-2"
className="ltr:ml-2 ltr:mr-2 rtl:ml-2"
onClick={() => setStep(SetupStep.EnterTotpCode)}>
{t("continue")}
</Button>
</WithStep>
<WithStep step={SetupStep.EnterTotpCode} current={step}>
<Button type="submit" className="ltr:ml-2 rtl:mr-2" disabled={isSubmitting}>
<Button type="submit" className="ltr:ml-2 ltr:mr-2 rtl:ml-2" disabled={isSubmitting}>
{t("enable")}
</Button>
</WithStep>
@@ -62,7 +62,7 @@ export function CalendarSwitch(props: {
}
);
return (
<div className="flex space-x-2 py-1">
<div className="flex space-x-2 py-1 rtl:space-x-reverse">
<Switch
key={props.externalId}
name="enabled"
@@ -90,7 +90,7 @@ const DisableTwoFactorAuthModal = ({
</div>
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<Button type="submit" className="ltr:ml-2 rtl:mr-2" disabled={isDisabling}>
<Button type="submit" className="ltr:ml-2 ltr:mr-2 rtl:ml-2" disabled={isDisabling}>
{t("disable")}
</Button>
<Button color="secondary" onClick={onCancel}>
@@ -170,7 +170,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel, open, onOpenChange }: Enable
<WithStep step={SetupStep.ConfirmPassword} current={step}>
<Button
type="submit"
className="ltr:ml-2 rtl:mr-2"
className="ltr:ml-2 ltr:mr-2 rtl:ml-2"
onClick={handleSetup}
disabled={password.length === 0 || isSubmitting}>
{t("continue")}
@@ -179,13 +179,13 @@ const EnableTwoFactorModal = ({ onEnable, onCancel, open, onOpenChange }: Enable
<WithStep step={SetupStep.DisplayQrCode} current={step}>
<Button
type="submit"
className="ltr:ml-2 rtl:mr-2"
className="ltr:ml-2 ltr:mr-2 rtl:ml-2"
onClick={() => setStep(SetupStep.EnterTotpCode)}>
{t("continue")}
</Button>
</WithStep>
<WithStep step={SetupStep.EnterTotpCode} current={step}>
<Button type="submit" className="ltr:ml-2 rtl:mr-2" disabled={isSubmitting}>
<Button type="submit" className="ltr:ml-2 ltr:mr-2 rtl:ml-2" disabled={isSubmitting}>
{t("enable")}
</Button>
</WithStep>
+1 -1
View File
@@ -34,7 +34,7 @@ export const AvatarGroup = function AvatarGroup(props: AvatarGroupProps) {
);
return (
<li key={idx} className="-mr-2 inline-block">
<li key={idx} className="-ltr:mr-2 inline-block rtl:ml-2">
{item.href ? (
<Link href={item.href}>
<a>{avatar}</a>
@@ -7,7 +7,17 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { TRPCClientErrorLike } from "@calcom/trpc/client";
import { trpc } from "@calcom/trpc/react";
import { AppRouter } from "@calcom/trpc/server/routers/_app";
import { Button, Dialog, DialogClose, DialogContent, DialogHeader, Icon, Input, Label } from "@calcom/ui";
import {
Button,
Dialog,
DialogClose,
DialogContent,
DialogHeader,
Icon,
Input,
Label,
TextField,
} from "@calcom/ui";
interface ICustomUsernameProps {
currentUsername: string | undefined;
@@ -77,10 +87,9 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
const ActionButtons = () => {
return usernameIsAvailable && currentUsername !== inputUsernameValue ? (
<div className="flex flex-row">
<div className="rlt:space-x-reverse mt-px flex flex-row space-x-2 ltr:ml-2 ltr:mr-2 rtl:ml-2 rtl:space-x-reverse">
<Button
type="button"
className="mx-2"
onClick={() => setOpenDialogSaveUsername(true)}
data-testid="update-username-btn">
{t("update")}
@@ -88,7 +97,6 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
<Button
type="button"
color="minimal"
className="mx-2"
onClick={() => {
if (currentUsername) {
setInputUsernameValue(currentUsername);
@@ -110,26 +118,20 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
return (
<div>
<div>
<Label htmlFor="username">{t("username")}</Label>
</div>
<div className="mt-2 flex rounded-md">
<span
className={classNames(
"inline-flex items-center rounded-l-md border border-r-0 border-gray-300 bg-gray-50 px-3 text-sm text-gray-500"
)}>
{process.env.NEXT_PUBLIC_WEBSITE_URL.replace("https://", "").replace("http://", "")}/
</span>
<div className="relative w-full">
<Input
<TextField
ref={usernameRef}
name="username"
value={inputUsernameValue}
addOnLeading={
<>{process.env.NEXT_PUBLIC_WEBSITE_URL.replace("https://", "").replace("http://", "")}/</>
}
autoComplete="none"
autoCapitalize="none"
autoCorrect="none"
className={classNames(
"mb-0 mt-0 h-6 rounded-md rounded-l-none",
"mb-0 mt-0 h-6 rounded-md ltr:rounded-l-none rtl:rounded-r-none",
markAsError
? "focus:shadow-0 focus:ring-shadow-0 border-red-500 focus:border-red-500 focus:outline-none focus:ring-0"
: ""
@@ -141,18 +143,18 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
data-testid="username-input"
/>
{currentUsername !== inputUsernameValue && (
<div className="absolute right-[2px] top-0 flex flex-row">
<div className="absolute right-[2px] top-6 flex flex-row">
<span className={classNames("mx-2 py-2")}>
{usernameIsAvailable ? <Icon.FiCheck className="mt-[2px] w-6" /> : <></>}
{usernameIsAvailable ? <Icon.FiCheck className="w-6" /> : <></>}
</span>
</div>
)}
</div>
<div className="hidden md:inline">
<div className="mt-5 hidden md:inline">
<ActionButtons />
</div>
</div>
{markAsError && <p className="mt-1 text-xs text-red-500">Username is already taken</p>}
{markAsError && <p className="mt-1 text-xs text-red-500">{t("username_already_taken")}</p>}
{usernameIsAvailable && currentUsername !== inputUsernameValue && (
<div className="mt-2 flex justify-end md:hidden">
+1 -1
View File
@@ -132,7 +132,7 @@ export default function Login({
{...register("email")}
/>
<div className="relative">
<div className="absolute right-0 -top-[6px] z-10">
<div className="absolute -top-[6px] z-10 ltr:right-0 rtl:left-0">
<Link href="/auth/forgot-password">
<a tabIndex={-1} className="text-sm font-medium text-gray-600">
{t("forgot")}
@@ -97,7 +97,7 @@ const SetupFormStep1 = (props: { setIsLoading: (val: boolean) => void }) => {
<TextField
addOnLeading={
!longWebsiteUrl && (
<span className="items-centerpx-3 inline-flex rounded-none text-sm text-gray-500">
<span className="inline-flex items-center rounded-none px-3 text-sm text-gray-500">
{process.env.NEXT_PUBLIC_WEBSITE_URL}/
</span>
)
+1 -1
View File
@@ -635,7 +635,7 @@ export default function Success(props: SuccessProps) {
encodeURIComponent(new RRule(props.eventType.recurringEvent).toString())
: "")
}>
<a className="mr-2 h-10 w-10 rounded-sm border border-neutral-200 px-3 py-2 dark:border-neutral-700 dark:text-white">
<a className="h-10 w-10 rounded-sm border border-neutral-200 px-3 py-2 ltr:mr-2 rtl:ml-2 dark:border-neutral-700 dark:text-white">
<svg
className="-mt-1.5 inline-block h-4 w-4"
fill="currentColor"
+3 -3
View File
@@ -78,7 +78,7 @@ const Item = ({ type, group, readOnly }: { type: EventType; group: EventTypeGrou
className="hidden font-normal leading-4 text-gray-600 sm:inline"
data-testid={"event-type-slug-" + type.id}>{`/${group.profile.slug}/${type.slug}`}</small>
{readOnly && (
<span className="rtl:mr-2inline items-center rounded-sm bg-gray-100 px-1.5 py-0.5 text-xs font-medium text-gray-800 ltr:ml-2">
<span className="rtl:ml-2inline items-center rounded-sm bg-gray-100 px-1.5 py-0.5 text-xs font-medium text-gray-800 ltr:ml-2 ltr:mr-2">
{t("readonly") as string}
</span>
)}
@@ -394,7 +394,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
</div>
</div>
</div>
<div className="min-w-9 mr-5 flex sm:hidden">
<div className="min-w-9 mx-5 flex sm:hidden">
<Dropdown>
<DropdownMenuTrigger asChild data-testid={"event-type-options-" + type.id}>
<Button type="button" size="icon" color="secondary" StartIcon={Icon.FiMoreHorizontal} />
@@ -531,7 +531,7 @@ const EventTypeListHeading = ({
<a className="font-bold">{profile?.name || ""}</a>
</Link>
{membershipCount && teamId && (
<span className="relative -top-px text-xs text-neutral-500 ltr:ml-2 rtl:mr-2">
<span className="relative -top-px text-xs text-neutral-500 ltr:ml-2 ltr:mr-2 rtl:ml-2">
<Link href={`/settings/teams/${teamId}/members`}>
<a>
<Badge variant="gray">
@@ -21,7 +21,7 @@ function AdminView() {
const enteredUsername = usernameRef.current?.value.toLowerCase();
signIn("impersonation-auth", { username: enteredUsername });
}}>
<div className="flex items-center space-x-2">
<div className="flex items-center space-x-2 rtl:space-x-reverse">
<TextField
containerClassName="w-full"
name={t("user_impersonation_heading")}
@@ -177,7 +177,9 @@ const AppearanceView = () => {
<div className="flex w-full text-sm">
<div className="mr-1 flex-grow">
<div className="flex items-center">
<p className="mr-2 font-semibold">{t("disable_cal_branding", { appName: APP_NAME })}</p>
<p className="font-semibold ltr:mr-2 rtl:ml-2">
{t("disable_cal_branding", { appName: APP_NAME })}
</p>
<Badge variant="gray">{t("pro")}</Badge>
</div>
<p className="mt-0.5 text-gray-600">{t("removes_cal_branding", { appName: APP_NAME })}</p>
@@ -156,7 +156,7 @@ const CalendarsView = () => {
)
}
<div className="flex-grow truncate pl-2">
<ListItemTitle component="h3" className="mb-1 space-x-2">
<ListItemTitle component="h3" className="mb-1 space-x-2 rtl:space-x-reverse">
<Link href={"/apps/" + item.integration.slug}>
{item.integration.name || item.integration.title}
</Link>
@@ -82,7 +82,7 @@ const ConferencingLayout = () => {
app.logo && <img className="h-10 w-10" src={app.logo} alt={app.title} />
}
<div className="flex-grow truncate pl-2">
<ListItemTitle component="h3" className="mb-1 space-x-2">
<ListItemTitle component="h3" className="mb-1 space-x-2 rtl:space-x-reverse">
<h3 className="truncate text-sm font-medium text-neutral-900">{app.title}</h3>
</ListItemTitle>
<ListItemText component="p">{app.description}</ListItemText>
@@ -340,7 +340,7 @@ const ProfileForm = ({
render={({ field: { value } }) => (
<>
<Avatar alt="" imageSrc={value} gravatarFallbackMd5={emailMd5} size="lg" />
<div className="ml-4">
<div className="ltr:ml-4 rtl:mr-4">
<ImageUploader
target="avatar"
id="avatar-upload"
+1 -1
View File
@@ -49,7 +49,7 @@ function TeamPage({ team }: TeamPageProps) {
<Link href={`/team/${team.slug}/${type.slug}`}>
<a className="flex justify-between px-6 py-4" data-testid="event-type-link">
<div className="flex-shrink">
<div className="flex flex-wrap items-center space-x-2">
<div className="flex flex-wrap items-center space-x-2 rtl:space-x-reverse">
<h2 className="dark:text-darkgray-700 text-sm font-semibold text-gray-700">{type.title}</h2>
</div>
<EventTypeDescription className="text-sm" eventType={type} />
@@ -1484,5 +1484,6 @@
"create_webhook_team_event_type": "Create a webhook for this team event type",
"disable_success_page":"Disable Success Page (only works if you have a redirect URL)",
"invalid_admin_password": "You are set as an admin but you do not have a password length of at least 15 characters",
"change_password_admin": "Change Password to gain admin access"
"change_password_admin": "Change Password to gain admin access",
"username_already_taken": "Username is already taken"
}
@@ -28,8 +28,8 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
switchChecked={enabled}>
<div className="mt-2 text-sm">
<div className="flex">
<span className="mr-2">{isSunrise ? <Icon.FiSunrise /> : <Icon.FiSunset />}</span>I am an AppCard
for Event with Title: {eventType.title}
<span className="ltr:mr-2 rtl:ml-2">{isSunrise ? <Icon.FiSunrise /> : <Icon.FiSunset />}</span>I am
an AppCard for Event with Title: {eventType.title}
</div>{" "}
<div className="mt-2">
Edit <span className="italic">packages/app-store/{app.slug}/extensions/EventTypeAppCard.tsx</span>{" "}
@@ -83,7 +83,7 @@ export default function AppleCalendarSetup() {
</fieldset>
{errorMessage && <Alert severity="error" title={errorMessage} className="my-4" />}
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
<div className="mt-5 justify-end space-x-2 rtl:space-x-reverse sm:mt-4 sm:flex">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -100,7 +100,7 @@ export default function CalDavCalendarSetup() {
className="my-4"
/>
)}
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
<div className="mt-5 justify-end space-x-2 rtl:space-x-reverse sm:mt-4 sm:flex">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -98,7 +98,7 @@ export default function CloseComSetup() {
)}
/>
</fieldset>
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
<div className="mt-5 justify-end space-x-2 rtl:space-x-reverse sm:mt-4 sm:flex">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -77,7 +77,7 @@ export default function Exchange2013CalendarSetup() {
</fieldset>
{errorMessage && <Alert severity="error" title={errorMessage} className="my-4" />}
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
<div className="mt-5 justify-end space-x-2 rtl:space-x-reverse sm:mt-4 sm:flex">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -77,7 +77,7 @@ export default function Exchange2016CalendarSetup() {
</fieldset>
{errorMessage && <Alert severity="error" title={errorMessage} className="my-4" />}
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
<div className="mt-5 justify-end space-x-2 rtl:space-x-reverse sm:mt-4 sm:flex">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -120,7 +120,7 @@ export default function ExchangeSetup() {
/>
</fieldset>
{errorMessage && <Alert severity="error" title={errorMessage} className="my-4" />}
<div className="mt-4 flex justify-end space-x-2">
<div className="mt-4 flex justify-end space-x-2 rtl:space-x-reverse">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -94,7 +94,7 @@ export const SearchDialog = (props: ISearchDialog) => {
setGifImage("");
setSelectedMode(mode);
}}>
<Icon color={selectedMode === mode ? "black" : "grey"} className="mr-2 h-4 w-4" />
<Icon color={selectedMode === mode ? "black" : "grey"} className="h-4 w-4 ltr:mr-2 rtl:ml-2" />
{text}
</div>
);
@@ -120,7 +120,9 @@ export const SearchDialog = (props: ISearchDialog) => {
{renderTab(SearchIcon, t("search_giphy"), MODE_SEARCH)}
{renderTab(LinkIcon, t("add_link_from_giphy"), MODE_URL)}
</div>
<form className="flex w-full justify-center space-x-2 space-y-2" onSubmit={handleFormSubmit}>
<form
className="flex w-full justify-center space-x-2 space-y-2 rtl:space-x-reverse"
onSubmit={handleFormSubmit}>
<div className="relative block w-full pt-2">
<input
type="text"
@@ -141,7 +143,7 @@ export const SearchDialog = (props: ISearchDialog) => {
</Button>
</form>
{gifImage && (
<div className="flex flex-col items-center space-x-2 space-y-2 pt-3">
<div className="flex flex-col items-center space-x-2 space-y-2 pt-3 rtl:space-x-reverse">
<div className="flex w-full items-center justify-center bg-gray-100">
{isLoading ? (
<div className="flex h-[200px] w-full items-center justify-center bg-gray-400 pt-3 pb-3">
@@ -173,7 +175,7 @@ export const SearchDialog = (props: ISearchDialog) => {
)}
{errorMessage && <Alert severity="error" title={errorMessage} className="my-4" />}
{gifImage && selectedMode === MODE_SEARCH && (
<div className="mt-4 flex items-center justify-between space-x-2">
<div className="mt-4 flex items-center justify-between space-x-2 rtl:space-x-reverse">
<div className="text-sm font-light text-neutral-500">Not the perfect GIF?</div>
<Button
size="sm"
@@ -16,7 +16,7 @@ export default function SelectGifInput(props: ISelectGifInput) {
const [showDialog, setShowDialog] = useState(false);
return (
<div className="flex flex-col items-start space-x-2 space-y-2">
<div className="flex flex-col items-start space-x-2 space-y-2 rtl:space-x-reverse">
{selectedGif && (
<div className="min-h-[200px]">
<img alt="Selected Gif Image" src={selectedGif} />
@@ -93,7 +93,7 @@ export default function SendgridSetup() {
)}
/>
</fieldset>
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
<div className="mt-5 justify-end space-x-2 rtl:space-x-reverse sm:mt-4 sm:flex">
<Button type="button" color="secondary" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -14,7 +14,7 @@ export default function HowToUse() {
</div>
<div className="ml-5">
<div className="text-md text-gray-800">How to route a Typeform with Cal.com Routing</div>
<ol className="mt-5 mb-5 ml-5 mr-5 list-decimal">
<ol className="mt-5 mb-5 ml-5 list-decimal ltr:mr-5 rtl:ml-5">
<li>
Make sure that you have{" "}
<Link href="/apps/routing-forms" className="text-base text-gray-500">
@@ -51,7 +51,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
<div className="invisible md:visible">
<img className="h-11" src="/api/app-store/zapier/icon.svg" alt="Zapier Logo" />
</div>
<div className="ml-2 mr-2 md:ml-5">
<div className="ml-2 ltr:mr-2 rtl:ml-2 md:ml-5">
<div className="text-gray-600">{t("setting_up_zapier")}</div>
{!newApiKey ? (
<>
@@ -75,7 +75,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
}}
type="button"
className="mt-4 text-base sm:mt-0 sm:rounded-l-none">
<ClipboardCopyIcon className="mr-2 h-5 w-5 text-neutral-100" />
<ClipboardCopyIcon className="h-5 w-5 text-neutral-100 ltr:mr-2 rtl:ml-2" />
{t("copy")}
</Button>
</Tooltip>
@@ -86,7 +86,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
</>
)}
<ol className="mt-5 mb-5 ml-5 mr-5 list-decimal">
<ol className="mt-5 mb-5 ml-5 list-decimal ltr:mr-5 rtl:ml-5">
{isCalDev && (
<li>
{t("go_to")}
@@ -63,7 +63,7 @@ export const EventTypeFilter = () => {
type="checkbox"
name=""
id=""
className="text-primary-600 focus:ring-primary-500 mr-2 h-4 w-4 rounded border-gray-300 "
className="text-primary-600 focus:ring-primary-500 h-4 w-4 rounded border-gray-300 ltr:mr-2 rtl:ml-2 "
/>
</div>
</div>
@@ -29,7 +29,7 @@ const filters: Filter[] = [
export function FiltersContainer() {
return (
<div className="flex w-full space-x-2 overflow-x-scroll lg:justify-end ">
<div className="flex w-full space-x-2 overflow-x-scroll rtl:space-x-reverse lg:justify-end ">
{filters.map((filter) => {
if (!filter.showByDefault) {
// TODO: check if any of the controllingQueryParams are present in the query params and show the filter if so
@@ -18,7 +18,7 @@ export const PeopleFilter = () => {
<AnimatedPopover
text={userNames && userNames.length > 0 ? `${userNames.join(", ")}` : t("all_users_filter_label")}>
<div className="item-center flex px-4 py-[6px] focus-within:bg-gray-100">
<div className="mr-2 flex h-6 w-6 items-center justify-center">
<div className="flex h-6 w-6 items-center justify-center ltr:mr-2 rtl:ml-2">
<Icon.FiUser className="h-full w-full" />
</div>
<label htmlFor="allUsers" className="mr-auto self-center truncate text-sm font-medium text-gray-700">
@@ -18,7 +18,7 @@ export const TeamsMemberFilter = () => {
<AnimatedPopover
text={teamNames && teamNames.length > 0 ? `${teamNames.join(", ")}` : t("all_bookings_filter_label")}>
<div className="item-center flex px-4 py-[6px] focus-within:bg-gray-100">
<div className="mr-2 flex h-6 w-6 items-center justify-center">
<div className="flex h-6 w-6 items-center justify-center ltr:mr-2 rtl:ml-2">
<Icon.FiLayers className="h-full w-full" />
</div>
<label
@@ -16,7 +16,7 @@ export function SchedulerHeading() {
{startDate.format("MMM DD")}-{endDate.format("DD")}
<span className="text-gray-500">,{startDate.format("YYYY")}</span>
</h1>
<div className="flex items-center space-x-2">
<div className="flex items-center space-x-2 rtl:space-x-reverse">
{/* TODO: Renable when we have daily/mobile support */}
{/* <ToggleGroup
options={[
@@ -83,7 +83,7 @@ export default function ApiKeyDialogForm({
}}
type="button"
className="rounded-l-none py-[19px] text-base ">
<ClipboardCopyIcon className="mr-2 h-5 w-5 text-neutral-100" />
<ClipboardCopyIcon className="h-5 w-5 text-neutral-100 ltr:mr-2 rtl:ml-2" />
{t("copy")}
</Button>
</Tooltip>
@@ -137,7 +137,7 @@ const PendingMemberItem = (props: { member: TeamMember; index: number; teamId: n
key={member.email}
className={classNames("flex items-center justify-between p-6 text-sm", index !== 0 && "border-t")}
data-testid="pending-member-item">
<div className="flex space-x-2">
<div className="flex space-x-2 rtl:space-x-reverse">
<Avatar
gravatarFallbackMd5="teamMember"
size="mdLg"
@@ -109,7 +109,7 @@ export const CreateANewTeamForm = () => {
render={({ field: { value } }) => (
<div className="flex items-center">
<Avatar alt="" imageSrc={value || null} gravatarFallbackMd5="newTeam" size="lg" />
<div className="ml-4">
<div className="ltr:ml-4 rtl:mr-4">
<ImageUploader
target="avatar"
id="avatar-upload"
@@ -125,7 +125,7 @@ export const CreateANewTeamForm = () => {
/>
</div>
<div className="flex space-x-2">
<div className="flex space-x-2 rtl:space-x-reverse">
<Button
disabled={createTeamMutation.isLoading}
color="secondary"
@@ -98,7 +98,7 @@ export default function MemberChangeRoleModal(props: {
</p>
)}
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<Button type="submit" color="primary" className="ltr:ml-2 rtl:mr-2">
<Button type="submit" color="primary" className="ltr:ml-2 ltr:mr-2 rtl:ml-2">
{t("save")}
</Button>
<Button type="button" color="secondary" onClick={props.onExit}>
@@ -151,7 +151,7 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
<Button
type="submit"
color="primary"
className="ltr:ml-2 rtl:mr-2"
className="ltr:ml-2 ltr:mr-2 rtl:ml-2"
data-testid="invite-new-member-button">
{t("invite_new_member")}
</Button>
@@ -104,7 +104,7 @@ export default function MemberListItem(props: Props) {
className="h-10 w-10 rounded-full"
/>
<div className="ml-3 inline-block">
<div className="inline-block ltr:ml-3 rtl:mr-3">
<div className="mb-1 flex">
<span className="mr-1 text-sm font-bold leading-4">{name}</span>
@@ -18,7 +18,7 @@ function SkeletonItem() {
return (
<li className="group flex w-full items-center justify-between px-3 py-4">
<div className="flex-grow truncate text-sm">
<div className="flex justify-start space-x-2 px-2">
<div className="flex justify-start space-x-2 px-2 rtl:space-x-reverse">
<SkeletonText className="h-10 w-10 rounded-full" />
<div className="flex flex-col space-y-2">
<SkeletonText className="h-4 w-32" />
@@ -37,7 +37,7 @@ export default function TeamAvailabilityModal(props: Props) {
alt={props.member?.name || ""}
className="h-14 w-14 rounded-full"
/>
<div className="ml-3 inline-block pt-1">
<div className="inline-block pt-1 ltr:ml-3 rtl:mr-3">
<span className="text-lg font-bold text-neutral-700">{props.member?.name}</span>
<span className="-mt-1 block text-sm text-gray-400">{props.member?.email}</span>
</div>
@@ -47,7 +47,7 @@ export default function TeamAvailabilityScreen(props: Props) {
alt={member?.name || ""}
className="min-w-10 min-h-10 mt-1 h-10 w-10 rounded-full"
/>
<div className="ml-3 inline-block overflow-hidden pt-1">
<div className="inline-block overflow-hidden pt-1 ltr:ml-3 rtl:mr-3">
<span className="truncate text-lg font-bold text-neutral-700">{member?.name}</span>
<span className="-mt-1 block truncate text-sm text-gray-400">{member?.email}</span>
</div>
@@ -66,7 +66,7 @@ export default function TeamInviteListItem(props: Props) {
alt="Team Logo"
className=""
/>
<div className="ml-3 inline-block">
<div className="inline-block ltr:ml-3 rtl:mr-3">
<span className="text-sm font-semibold text-black">{team.name}</span>
<span className="block text-sm leading-5 text-gray-700">
{t("invited_by_team", { teamName: team.name, role: t(team.role.toLocaleLowerCase()) })}
@@ -71,7 +71,7 @@ export default function TeamListItem(props: Props) {
alt="Team Logo"
className="min-h-9 min-w-9 h-9 w-9 rounded-full"
/>
<div className="ml-3 inline-block">
<div className="inline-block ltr:ml-3 rtl:mr-3">
<span className="text-sm font-bold text-neutral-700">{team.name}</span>
<span className="block text-xs text-gray-400">
{team.slug ? `${process.env.NEXT_PUBLIC_WEBSITE_URL}/team/${team.slug}` : "Unpublished team"}
@@ -103,7 +103,11 @@ export default function TeamListItem(props: Props) {
<Button type="button" color="secondary" onClick={declineInvite}>
{t("reject")}
</Button>
<Button type="button" color="primary" className="ltr:ml-2 rtl:mr-2" onClick={acceptInvite}>
<Button
type="button"
color="primary"
className="ltr:ml-2 ltr:mr-2 rtl:ml-2"
onClick={acceptInvite}>
{t("accept")}
</Button>
</div>
@@ -64,7 +64,7 @@ export function TeamsListing() {
<div className="mt-3 px-14">
<h1 className="font-cal text-3xl">{t("calcom_is_better_with_team")}</h1>
<p className="my-4 max-w-sm text-gray-600">{t("add_your_team_members")}</p>
<div className="space-y-2 sm:space-x-2">
<div className="space-y-2 rtl:space-x-reverse sm:space-x-2">
<Button color="primary" href={`${WEBAPP_URL}/settings/teams/new`}>
{t("create_team")}
</Button>
@@ -47,7 +47,7 @@ export default function TeamAvailabilityScreen(props: Props) {
alt={member?.name || ""}
className="min-w-10 min-h-10 mt-1 h-10 w-10 rounded-full"
/>
<div className="ml-3 inline-block overflow-hidden pt-1">
<div className="inline-block overflow-hidden pt-1 ltr:ml-3 rtl:mr-3">
<span className="truncate text-lg font-bold text-neutral-700">{member?.name}</span>
<span className="-mt-1 block truncate text-sm text-gray-400">{member?.email}</span>
</div>
@@ -160,7 +160,7 @@ const ProfileView = () => {
render={({ field: { value } }) => (
<>
<Avatar alt="" imageSrc={getPlaceholderAvatar(value, team?.name as string)} size="lg" />
<div className="ml-4">
<div className="ltr:ml-4 rtl:mr-4">
<ImageUploader
target="avatar"
id="avatar-upload"
@@ -125,14 +125,14 @@ const WorkflowListItem = (props: ItemProps) => {
<Link href={`/workflows/${workflow.id}`} passHref={true}>
<a target="_blank">
<Button type="button" color="minimal" className="mr-4">
<div className="mr-2 hidden sm:block">{t("edit")}</div>
<div className="hidden ltr:mr-2 rtl:ml-2 sm:block">{t("edit")}</div>
<Icon.FiExternalLink className="-mt-[2px] h-4 w-4 stroke-2 text-gray-600" />
</Button>
</a>
</Link>
</div>
<Tooltip content={t("turn_off") as string}>
<div className="mr-2">
<div className="ltr:mr-2 rtl:ml-2">
<Switch
checked={isActive}
onCheckedChange={() => {
@@ -21,7 +21,7 @@ function SkeletonItem() {
<div className="mt-1 ml-4 flex flex-col space-y-1">
<SkeletonText className="h-5 w-20 sm:w-24" />
<div className="flex">
<SkeletonText className="mr-2 h-4 w-16 sm:w-28" />
<SkeletonText className="h-4 w-16 ltr:mr-2 rtl:ml-2 sm:w-28" />
</div>
</div>
</div>
@@ -21,7 +21,7 @@ function SkeletonItem() {
<SkeletonText className="h-4 w-16 sm:w-24" />
<div className="flex">
<Icon.FiBell className="mt-0.5 mr-1.5 inline h-4 w-4 text-gray-200" />
<SkeletonText className="mr-2 h-4 w-16 sm:w-28" />
<SkeletonText className="h-4 w-16 ltr:mr-2 rtl:ml-2 sm:w-28" />
<Icon.FiLink className="mt-0.5 mr-1.5 inline h-4 w-4 text-gray-200" />
<SkeletonText className="h-4 w-28 sm:w-36" />
</div>
@@ -196,7 +196,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<div className="flex justify-center">
<div className="min-w-80 w-full rounded-md border border-gray-200 bg-white p-7">
<div className="flex">
<div className="mt-[3px] mr-5 flex h-5 w-5 items-center justify-center rounded-full bg-gray-100 p-1 text-xs font-medium">
<div className="mt-[3px] flex h-5 w-5 items-center justify-center rounded-full bg-gray-100 p-1 text-xs font-medium ltr:mr-5 rtl:ml-5">
1
</div>
<div>
@@ -277,7 +277,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<div className="flex">
<div className="w-full">
<div className="flex">
<div className="mt-[3px] mr-5 flex h-5 w-5 items-center justify-center rounded-full bg-gray-100 p-1 text-xs">
<div className="mt-[3px] flex h-5 w-5 items-center justify-center rounded-full bg-gray-100 p-1 text-xs ltr:mr-5 rtl:ml-5">
{step.stepNumber + 1}
</div>
<div>
@@ -603,7 +603,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<div className="mt-3 ">
<button type="button" onClick={() => setIsAdditionalInputsDialogOpen(true)}>
<div className="mt-2 flex text-sm text-gray-600">
<Icon.FiHelpCircle className="mt-[3px] mr-2 h-3 w-3" />
<Icon.FiHelpCircle className="mt-[3px] h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p className="text-left">{t("using_additional_inputs_as_variables")}</p>
</div>
</button>
@@ -723,7 +723,9 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<div className="mt-6">
<p className="test-sm w-full font-medium">{t("example_1")}</p>
<div className="mt-2 grid grid-cols-12">
<div className="test-sm col-span-5 mr-2 text-gray-600">{t("additional_input_label")}</div>
<div className="test-sm col-span-5 text-gray-600 ltr:mr-2 rtl:ml-2">
{t("additional_input_label")}
</div>
<div className="test-sm col-span-7 text-gray-900">{t("company_size")}</div>
<div className="test-sm col-span-5 w-full text-gray-600">{t("variable")}</div>
@@ -740,7 +742,9 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<div className="mt-6">
<p className="test-sm w-full font-medium">{t("example_2")}</p>
<div className="mt-2 grid grid-cols-12">
<div className="test-sm col-span-5 mr-2 text-gray-600">{t("additional_input_label")}</div>
<div className="test-sm col-span-5 text-gray-600 ltr:mr-2 rtl:ml-2">
{t("additional_input_label")}
</div>
<div className="test-sm col-span-7 text-gray-900">{t("what_help_needed")}</div>
<div className="test-sm col-span-5 text-gray-600">{t("variable")}</div>
<div className="test-sm col-span-7 break-words text-gray-900">
@@ -4,16 +4,16 @@ const SkeletonEventType = () => {
return (
<div className="dark:bg-darkgray-100 h-24 w-full bg-white">
<div className="p-5">
<div className="flex space-x-2">
<div className="flex space-x-2 rtl:space-x-reverse">
<div className="dark:bg-darkgray-400 h-2 w-1/6 rounded-md bg-neutral-200" />
<div className="dark:bg-darkgray-400 h-2 w-1/6 rounded-md bg-neutral-200" />
</div>
<div className="flex space-x-2 py-2">
<div className="flex space-x-2 py-2 rtl:space-x-reverse">
<div className="dark:bg-darkgray-400 h-2 w-1/12 rounded-md bg-neutral-200" />
<div className="dark:bg-darkgray-400 h-2 w-1/6 rounded-md bg-neutral-200" />
<div className="dark:bg-darkgray-400 h-2 w-1/12 rounded-md bg-neutral-200" />
</div>
<div className="flex space-x-2 py-1">
<div className="flex space-x-2 py-1 rtl:space-x-reverse">
<div className="dark:bg-darkgray-200 h-6 w-1/6 rounded-md bg-neutral-300" />
<div className="dark:bg-darkgray-200 h-6 w-1/6 rounded-md bg-neutral-300" />
</div>
@@ -39,7 +39,7 @@ export const EventTypeDescription = ({ eventType, className }: EventTypeDescript
{eventType.description.length > 300 && "..."}
</p>
)}
<ul className="mt-2 flex flex-wrap space-x-2 sm:flex-nowrap">
<ul className="mt-2 flex flex-wrap space-x-2 rtl:space-x-reverse sm:flex-nowrap">
{eventType.metadata?.multipleDuration ? (
eventType.metadata.multipleDuration.map((dur, idx) => (
<li key={idx}>
@@ -59,7 +59,7 @@ const DateOverrideList = ({
))
)}
</div>
<div className="space-x-2">
<div className="space-x-2 rtl:space-x-reverse">
<DateOverrideInputDialog
excludedDates={excludedDates}
workingHours={workingHours}
@@ -55,7 +55,7 @@ const ScheduleDay = <TFieldValues extends FieldValues>({
{/* Label & switch container */}
<div className="flex h-11 items-center justify-between sm:w-32">
<div>
<label className="flex flex-row items-center space-x-2">
<label className="flex flex-row items-center space-x-2 rtl:space-x-reverse">
<div>
<Switch
disabled={!watchDayRange}
@@ -400,7 +400,7 @@ const CopyTimes = ({
</ol>
</div>
<hr />
<div className="space-x-2 px-2">
<div className="space-x-2 px-2 rtl:space-x-reverse">
<Button color="minimal" onClick={() => onCancel()}>
{t("cancel")}
</Button>
@@ -42,7 +42,7 @@ export function ScheduleListItem({
<div className="group flex w-full items-center justify-between hover:bg-neutral-50 sm:px-6">
<Link href={"/availability/" + schedule.id}>
<a className="flex-grow truncate text-sm" title={schedule.name}>
<div className="space-x-2">
<div className="space-x-2 rtl:space-x-reverse">
<span className="truncate font-medium text-neutral-900">{schedule.name}</span>
{schedule.isDefault && (
<Badge variant="success" className="text-xs">
@@ -73,7 +73,7 @@ export function ScheduleListItem({
</Link>
</div>
<Dropdown>
<DropdownMenuTrigger asChild className="mr-5">
<DropdownMenuTrigger asChild className="mx-5">
<Button type="button" size="icon" color="secondary" StartIcon={Icon.FiMoreHorizontal} />
</DropdownMenuTrigger>
{!isLoading && data && (
@@ -45,7 +45,12 @@ export default function WebhookListItem(props: {
<Tooltip content={t("triggers_when")}>
<div className="mt-2.5 w-4/5">
{webhook.eventTriggers.map((trigger) => (
<Badge key={trigger} className="mr-2" variant="gray" bold StartIcon={Icon.FiAlertCircle}>
<Badge
key={trigger}
className="ltr:mr-2 rtl:ml-2"
variant="gray"
bold
StartIcon={Icon.FiAlertCircle}>
{t(`${trigger.toLowerCase()}`)}
</Badge>
))}
+4 -2
View File
@@ -107,7 +107,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
<StartIcon
className={classNames(
"inline",
size === "icon" ? "h-4 w-4 " : "-ml-1 h-4 w-4 ltr:mr-2 rtl:ml-2 rtl:-mr-1",
size === "icon" ? "h-4 w-4 " : "h-4 w-4 ltr:-ml-1 ltr:mr-2 rtl:ml-2 rtl:-mr-1",
startIconClassName || ""
)}
/>
@@ -133,7 +133,9 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
</div>
)}
{EndIcon && (
<EndIcon className={classNames("-mr-1 inline h-5 w-5 ltr:ml-2 rtl:mr-2", endIconClassName || "")} />
<EndIcon
className={classNames("inline h-5 w-5 ltr:-mr-1 ltr:ml-2 rtl:mr-2", endIconClassName || "")}
/>
)}
</>
);
+2 -2
View File
@@ -53,8 +53,8 @@ export const Badge = function Badge(props: BadgeProps) {
className
)}>
<>
{StartIcon && <StartIcon className="mr-1 h-3 w-3 stroke-[3px]" />}
{withDot && <GoPrimitiveDot className="mr-1 h-3 w-3 stroke-[3px]" />}
{StartIcon && <StartIcon className="h-3 w-3 stroke-[3px] ltr:mr-1 rtl:ml-1" />}
{withDot && <GoPrimitiveDot className="h-3 w-3 stroke-[3px] ltr:mr-1 rtl:ml-1" />}
{props.children}
</>
</div>
@@ -24,7 +24,7 @@ export const Breadcrumb = ({ children }: BreadcrumbProps) => {
return (
<nav className="text-sm font-normal leading-5 text-gray-600">
<ol className="flex items-center space-x-2">{childrenSeperated}</ol>
<ol className="flex items-center space-x-2 rtl:space-x-reverse">{childrenSeperated}</ol>
</nav>
);
};
+4 -4
View File
@@ -183,14 +183,14 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
<>
{size === "fab" ? (
<>
<StartIcon className="mr-2 hidden h-4 w-4 stroke-[1.5px] sm:inline-flex" />
<StartIcon className="hidden h-4 w-4 stroke-[1.5px] ltr:mr-2 rtl:ml-2 sm:inline-flex" />
<Icon.FiPlus className="inline h-6 w-6 sm:hidden" />
</>
) : (
<StartIcon
className={classNames(
"inline-flex",
size === "icon" ? "h-4 w-4 " : "mr-2 h-4 w-4 stroke-[1.5px]"
size === "icon" ? "h-4 w-4 " : "h-4 w-4 stroke-[1.5px] ltr:mr-2 rtl:ml-2"
)}
/>
)}
@@ -217,11 +217,11 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
<>
{size === "fab" ? (
<>
<EndIcon className="-mr-1 hidden h-5 w-5 ltr:ml-2 rtl:mr-2 sm:inline" />
<EndIcon className="-mr-1 hidden h-5 w-5 ltr:ml-2 rtl:-ml-1 rtl:mr-2 sm:inline" />
<Icon.FiPlus className="inline h-6 w-6 sm:hidden" />
</>
) : (
<EndIcon className="-mr-1 inline h-5 w-5 ltr:ml-2 rtl:mr-2" />
<EndIcon className="inline h-5 w-5 ltr:-mr-1 ltr:ml-2 rtl:mr-2" />
)}
</>
)}
@@ -20,8 +20,8 @@ export function ButtonGroup({ children, combined = false, containerProps }: Prop
className={classNames(
"flex",
!combined
? "space-x-2"
: "[&_button]:rounded-none [&_button]:border-l-0 [&>*:first-child]:rounded-l-md [&>*:first-child]:border-l [&_a]:rounded-none [&_a]:border-l-0 [&>*:last-child]:rounded-r-md",
? "space-x-2 rtl:space-x-reverse"
: "[&_button]:rounded-none [&_button]:ltr:border-l-0 rtl:[&_button]:border-r-0 ltr:[&>*:first-child]:rounded-l-md ltr:[&>*:first-child]:border-l rtl:[&>*:first-child]:rounded-r-md rtl:[&>*:first-child]:border-r [&_a]:rounded-none ltr:[&_a]:border-l-0 rtl:[&_a]:border-r-0 ltr:[&>*:last-child]:rounded-r-md rtl:[&>*:last-child]:rounded-l-md",
containerProps?.className
)}>
{children}
@@ -51,7 +51,7 @@ const CheckboxField = forwardRef<HTMLInputElement, Props>(
type="checkbox"
disabled={disabled}
className={classNames(
"text-primary-600 focus:ring-primary-500 mr-2 h-4 w-4 rounded border-gray-300 ",
"text-primary-600 focus:ring-primary-500 h-4 w-4 rounded border-gray-300 ltr:mr-2 rtl:ml-2 ",
!error && disabled
? "bg-gray-300 checked:bg-gray-300"
: "checked:bg-gray-800 hover:bg-gray-100",
@@ -49,12 +49,12 @@ export function HintsOrErrors<T extends FieldValues = FieldValues>(props: {
className={error !== undefined ? (submitted ? "text-red-700" : "") : "text-green-600"}>
{error !== undefined ? (
submitted ? (
<Icon.FiX size="12" strokeWidth="3" className="mr-2 -ml-1 inline-block" />
<Icon.FiX size="12" strokeWidth="3" className="-ml-1 inline-block ltr:mr-2 rtl:ml-2" />
) : (
<Icon.FiCircle fill="currentColor" size="5" className="mr-2 inline-block" />
<Icon.FiCircle fill="currentColor" size="5" className="inline-block ltr:mr-2 rtl:ml-2" />
)
) : (
<Icon.FiCheck size="12" strokeWidth="3" className="mr-2 -ml-1 inline-block" />
<Icon.FiCheck size="12" strokeWidth="3" className="-ml-1 inline-block ltr:mr-2 rtl:ml-2" />
)}
{t(`${fieldName}_hint_${key}`)}
</li>
@@ -87,9 +87,9 @@ export function HintsOrErrors<T extends FieldValues = FieldValues>(props: {
return (
<li key={key} className={!!dirty ? "text-green-600" : ""}>
{!!dirty ? (
<Icon.FiCheck size="12" strokeWidth="3" className="mr-2 -ml-1 inline-block" />
<Icon.FiCheck size="12" strokeWidth="3" className="-ml-1 inline-block ltr:mr-2 rtl:ml-2" />
) : (
<Icon.FiCircle fill="currentColor" size="5" className="mr-2 inline-block" />
<Icon.FiCircle fill="currentColor" size="5" className="inline-block ltr:mr-2 rtl:ml-2" />
)}
{t(`${fieldName}_hint_${key}`)}
</li>
+18 -8
View File
@@ -30,7 +30,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
export function InputLeading(props: JSX.IntrinsicElements["div"]) {
return (
<span className="inline-flex flex-shrink-0 items-center rounded-l-sm border border-r-0 border-gray-300 bg-gray-50 px-3 text-gray-500 sm:text-sm">
<span className="inline-flex flex-shrink-0 items-center rounded-l-sm border border-gray-300 bg-gray-50 px-3 text-gray-500 ltr:border-r-0 rtl:border-l-0 sm:text-sm">
{props.children}
</span>
);
@@ -118,7 +118,12 @@ export const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function
{addOnLeading || addOnSuffix ? (
<div className="relative mb-1 flex items-center rounded-md focus-within:outline-none focus-within:ring-2 focus-within:ring-neutral-800 focus-within:ring-offset-1">
{addOnLeading && (
<Addon isFilled={addOnFilled} className={classNames("rounded-l-md border-r-0", addOnClassname)}>
<Addon
isFilled={addOnFilled}
className={classNames(
"ltr:rounded-l-md ltr:border-r-0 rtl:rounded-r-md rtl:border-l-0",
addOnClassname
)}>
{addOnLeading}
</Addon>
)}
@@ -129,8 +134,8 @@ export const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function
isFullWidth={inputIsFullWidth}
className={classNames(
className,
addOnLeading && "rounded-l-none",
addOnSuffix && "rounded-r-none",
addOnLeading && "ltr:rounded-l-none rtl:rounded-r-none",
addOnSuffix && "ltr:rounded-r-none rtl:rounded-l-none",
type === "search" && "pr-8",
"!my-0 !ring-0"
)}
@@ -147,13 +152,18 @@ export const InputField = forwardRef<HTMLInputElement, InputFieldProps>(function
ref={ref}
/>
{addOnSuffix && (
<Addon isFilled={addOnFilled} className={classNames("rounded-r-md border-l-0", addOnClassname)}>
<Addon
isFilled={addOnFilled}
className={classNames(
"ltr:rounded-r-md ltr:border-l-0 rtl:rounded-l-md rtl:border-r-0",
addOnClassname
)}>
{addOnSuffix}
</Addon>
)}
{type === "search" && inputValue?.toString().length > 0 && (
<Icon.FiX
className="absolute right-2 top-2.5 h-4 w-4 cursor-pointer text-gray-500"
className="absolute top-2.5 h-4 w-4 cursor-pointer text-gray-500 ltr:right-2 rtl:left-2"
onClick={(e) => {
setInputValue("");
props.onChange && props.onChange(e as unknown as React.ChangeEvent<HTMLInputElement>);
@@ -201,12 +211,12 @@ export const PasswordField = forwardRef<HTMLInputElement, InputFieldProps>(funct
placeholder={props.placeholder || "•••••••••••••"}
ref={ref}
{...props}
className={classNames("mb-0 border-r-0 pr-10", props.className)}
className={classNames("mb-0 ltr:border-r-0 ltr:pr-10 rtl:border-l-0 rtl:pl-10", props.className)}
addOnFilled={false}
addOnSuffix={
<Tooltip content={textLabel}>
<button
className="absolute bottom-0 right-3 h-9 text-gray-900"
className="absolute bottom-0 h-9 text-gray-900 ltr:right-3 rtl:left-3"
type="button"
onClick={() => toggleIsPasswordVisible()}>
{isPasswordVisible ? (
+1 -1
View File
@@ -45,7 +45,7 @@ const InputOption: React.FC<OptionProps<any, boolean, GroupBase<any>>> = ({
innerProps={props}>
<input
type="checkbox"
className="text-primary-600 focus:ring-primary-500 mr-2 h-4 w-4 rounded border-gray-300"
className="text-primary-600 focus:ring-primary-500 h-4 w-4 rounded border-gray-300 ltr:mr-2 rtl:ml-2"
checked={isSelected}
readOnly
/>
+1 -1
View File
@@ -15,7 +15,7 @@ function PageHeader({ title, description, rightAlignedComponent, badgeText, badg
return (
<div className="flex items-center">
<div className="mr-4 flex-col">
<div className="flex w-full items-center space-x-2">
<div className="flex w-full items-center space-x-2 rtl:space-x-reverse">
<h1 className="font-cal text-xl font-semibold text-black">{title}</h1>
{badgeText && badgeVariant && <Badge variant={badgeVariant}>{badgeText}</Badge>}
</div>
+20 -20
View File
@@ -249,7 +249,7 @@ function UserDropdown({ small }: { small?: boolean }) {
<button className="group mx-0 flex w-full cursor-pointer appearance-none items-center rounded-full p-2 text-left outline-none hover:bg-gray-200 focus:outline-none focus:ring-0 sm:mx-2.5 sm:pl-3 md:rounded-none lg:rounded lg:pl-2">
<span
className={classNames(
small ? "h-6 w-6" : "h-8 w-8 ltr:mr-2 rtl:ml-3",
small ? "h-6 w-6" : "h-8 w-8 ltr:mr-2 rtl:ml-2",
"relative flex-shrink-0 rounded-full bg-gray-300 "
)}>
{
@@ -282,7 +282,7 @@ function UserDropdown({ small }: { small?: boolean }) {
</span>
</span>
<Icon.FiMoreVertical
className="h-4 w-4 flex-shrink-0 text-gray-400 group-hover:text-gray-500 rtl:mr-2"
className="h-4 w-4 flex-shrink-0 text-gray-400 group-hover:text-gray-500 ltr:mr-2 rtl:ml-2 rtl:mr-4"
aria-hidden="true"
/>
</span>
@@ -308,13 +308,13 @@ function UserDropdown({ small }: { small?: boolean }) {
mutation.mutate({ away: !user?.away });
utils.viewer.me.invalidate();
}}
className="flex w-full min-w-max cursor-pointer items-center px-4 py-2 text-sm">
className="flex w-full min-w-max cursor-pointer items-center px-4 py-2 text-sm ltr:flex-row rtl:flex-row-reverse">
<Icon.FiMoon
className={classNames(
user.away
? "text-purple-500 group-hover:text-purple-700"
: "text-gray-500 group-hover:text-gray-700",
"h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-3"
"h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-2"
)}
aria-hidden="true"
/>
@@ -329,8 +329,8 @@ function UserDropdown({ small }: { small?: boolean }) {
target="_blank"
rel="noopener noreferrer"
href={`${process.env.NEXT_PUBLIC_WEBSITE_URL}/${user.username}`}
className="flex items-center px-4 py-2 text-sm text-gray-700">
<Icon.FiExternalLink className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-3" />{" "}
className="flex items-center px-4 py-2 text-sm text-gray-700 ltr:flex-row rtl:flex-row-reverse">
<Icon.FiExternalLink className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-2" />{" "}
{t("view_public_page")}
</a>
</DropdownMenuItem>
@@ -344,8 +344,8 @@ function UserDropdown({ small }: { small?: boolean }) {
);
showToast(t("link_copied"), "success");
}}
className="flex items-center px-4 py-2 text-sm text-gray-700">
<Icon.FiLink className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-3" />{" "}
className="flex items-center px-4 py-2 text-sm text-gray-700 ltr:flex-row rtl:flex-row-reverse">
<Icon.FiLink className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-2" />{" "}
{t("copy_public_page_link")}
</a>
</DropdownMenuItem>
@@ -357,8 +357,8 @@ function UserDropdown({ small }: { small?: boolean }) {
href={JOIN_SLACK}
target="_blank"
rel="noreferrer"
className="flex items-center px-4 py-2 text-sm text-gray-700">
<Icon.FiSlack strokeWidth={1.5} className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-3" />{" "}
className="flex items-center px-4 py-2 text-sm text-gray-700 ltr:flex-row rtl:flex-row-reverse">
<Icon.FiSlack strokeWidth={1.5} className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-2" />{" "}
{t("join_our_slack")}
</a>
</DropdownMenuItem>
@@ -367,18 +367,18 @@ function UserDropdown({ small }: { small?: boolean }) {
target="_blank"
rel="noopener noreferrer"
href={ROADMAP}
className="flex items-center px-4 py-2 text-sm text-gray-700">
<Icon.FiMap className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-3" /> {t("visit_roadmap")}
className="flex items-center px-4 py-2 text-sm text-gray-700 ltr:flex-row rtl:flex-row-reverse">
<Icon.FiMap className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-2" /> {t("visit_roadmap")}
</a>
</DropdownMenuItem>
<DropdownMenuItem>
<button
onClick={() => setHelpOpen(true)}
className="flex w-full items-center px-4 py-2 text-sm text-gray-700">
className="flex w-full items-center px-4 py-2 text-sm text-gray-700 ltr:flex-row rtl:flex-row-reverse">
<Icon.FiHelpCircle
className={classNames(
"text-gray-500 group-hover:text-neutral-500",
"h-4 w-4 flex-shrink-0 ltr:mr-2"
"h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-2"
)}
aria-hidden="true"
/>
@@ -391,8 +391,8 @@ function UserDropdown({ small }: { small?: boolean }) {
target="_blank"
rel="noopener noreferrer"
href={DESKTOP_APP_LINK}
className="desktop-hidden hidden items-center px-4 py-2 text-sm text-gray-700 lg:flex">
<Icon.FiDownload className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-3" />{" "}
className="desktop-hidden hidden items-center px-4 py-2 text-sm text-gray-700 ltr:flex-row rtl:flex-row-reverse lg:flex">
<Icon.FiDownload className="h-4 w-4 text-gray-500 ltr:mr-2 rtl:ml-2" />{" "}
{t("download_desktop_app")}
</a>
</DropdownMenuItem>
@@ -401,11 +401,11 @@ function UserDropdown({ small }: { small?: boolean }) {
<DropdownMenuItem>
<a
onClick={() => signOut({ callbackUrl: "/auth/logout" })}
className="flex cursor-pointer items-center px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900">
className="flex cursor-pointer items-center px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900 ltr:flex-row rtl:flex-row-reverse">
<Icon.FiLogOut
className={classNames(
"text-gray-500 group-hover:text-gray-700",
"h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-3"
"h-4 w-4 flex-shrink-0 ltr:mr-2 rtl:ml-2"
)}
aria-hidden="true"
/>
@@ -732,7 +732,7 @@ function SideBar() {
<Logo small />
</a>
</Link>
<div className="flex space-x-2">
<div className="flex space-x-2 rtl:space-x-reverse">
<button
color="minimal"
onClick={() => window.history.back()}
@@ -820,7 +820,7 @@ export function ShellMain(props: LayoutProps) {
{props.CTA && (
<div
className={classNames(
props.backPath ? "relative" : " fixed right-4 bottom-[88px] z-40 sm:z-auto",
props.backPath ? "relative" : " fixed bottom-[88px] z-40 ltr:right-4 rtl:left-4 sm:z-auto",
"flex-shrink-0 sm:relative sm:bottom-auto sm:right-auto"
)}>
{props.CTA}
+2 -4
View File
@@ -32,9 +32,7 @@ const Switch = (
// Since we dont support global dark mode - we have to style dark mode components specifically on the instance for now
// TODO: Remove once we support global dark mode
className={classNames(
"block h-[14px] w-[14px] rounded-full bg-white",
"translate-x-[4px] transition will-change-transform",
"[&[data-state='checked']]:translate-x-[17px]",
"block h-[14px] w-[14px] rounded-full bg-white transition will-change-transform ltr:translate-x-[4px] rtl:-translate-x-[4px] ltr:[&[data-state='checked']]:translate-x-[17px] rtl:[&[data-state='checked']]:-translate-x-[17px]",
props.checked && "shadow-inner",
props.thumbProps?.className
)}
@@ -44,7 +42,7 @@ const Switch = (
<Label.Root
htmlFor={id}
className={classNames(
"ml-2 align-text-top text-sm font-medium text-gray-900 ltr:ml-3 rtl:mr-3 dark:text-white",
"align-text-top text-sm font-medium text-gray-900 ltr:ml-3 rtl:mr-3 dark:text-white",
primitiveProps.disabled ? "cursor-not-allowed opacity-25" : "cursor-pointer "
)}>
{label}
+1 -1
View File
@@ -31,7 +31,7 @@ function SkeletonItem() {
return (
<li className="group flex w-full items-center justify-between p-3">
<div className="flex-grow truncate text-sm">
<div className="flex justify-start space-x-2">
<div className="flex justify-start space-x-2 rtl:space-x-reverse">
<SkeletonText className="h-10 w-10" />
<div className="space-y-2">
<SkeletonText className="h-4 w-32" />
+1 -2
View File
@@ -73,7 +73,6 @@ const ColorPicker = (props: ColorPickerProps) => {
return (
<div className="relative mt-1 flex items-center justify-center">
<Swatch size="sm" backgroundColor={color} onClick={() => toggle(!isOpen)} />
{isOpen && (
<div className="popover" ref={popover}>
<HexColorPicker
@@ -87,7 +86,7 @@ const ColorPicker = (props: ColorPickerProps) => {
</div>
)}
<HexColorInput
className="ml-1 block w-full rounded-r-md border border-gray-300 px-3 py-2 sm:text-sm"
className="block w-full border border-gray-300 px-3 py-2 ltr:ml-1 ltr:rounded-r-md rtl:mr-1 rtl:rounded-l-md sm:text-sm"
color={color}
onChange={(val) => {
setColor(val);
@@ -37,7 +37,7 @@ export const BooleanToggleGroup = function BooleanToggleGroup({
<ToggleGroupPrimitive
value={yesNoValue}
type="single"
className="space-x-2 rounded-sm"
className="space-x-2 rounded-sm rtl:space-x-reverse"
onValueChange={(yesNoValue: "yes" | "no") => {
setYesNoValue(yesNoValue);
onValueChange(boolean(yesNoValue));
@@ -40,7 +40,7 @@ const InputOption: React.FC<OptionProps<any, boolean, GroupBase<any>>> = ({
innerProps={props}>
<input
type="checkbox"
className="text-primary-600 focus:ring-primary-500 mr-2 h-4 w-4 rounded border-gray-300"
className="text-primary-600 focus:ring-primary-500 h-4 w-4 rounded border-gray-300 ltr:mr-2 rtl:ml-2"
checked={isSelected}
readOnly
/>
+14 -8
View File
@@ -118,7 +118,7 @@ const BackButtonInSidebar = ({ name }: { name: string }) => {
target="_self"
className="group my-6 flex h-6 max-h-6 w-64 flex-row items-center rounded-md py-2 px-3 text-sm font-medium leading-4 text-black hover:bg-gray-100 group-hover:text-gray-700 [&[aria-current='page']]:bg-gray-200 [&[aria-current='page']]:text-gray-900"
data-testid={`vertical-tab-${name}`}>
<Icon.FiArrowLeft className="mr-[10px] h-4 w-4 stroke-[2px] md:mt-0" />
<Icon.FiArrowLeft className="h-4 w-4 stroke-[2px] ltr:mr-[10px] rtl:ml-[10px] md:mt-0" />
<Skeleton title={name} as="p" className="max-w-36 min-h-4 truncate">
{name}
</Skeleton>
@@ -178,10 +178,14 @@ const SettingsSidebarContainer = ({
<div className={`${!tab.children?.length ? "!mb-3" : ""}`}>
<div className="group flex h-9 w-64 flex-row items-center rounded-md px-3 text-sm font-medium leading-none text-gray-600 [&[aria-current='page']]:bg-gray-200 [&[aria-current='page']]:text-gray-900">
{tab && tab.icon && (
<tab.icon className="mr-[12px] h-[16px] w-[16px] stroke-[2px] md:mt-0" />
<tab.icon className="h-[16px] w-[16px] stroke-[2px] ltr:mr-3 rtl:ml-3 md:mt-0" />
)}
{!tab.icon && tab?.avatar && (
<img className="mr-3 h-4 w-4 rounded-full" src={tab?.avatar} alt="User Avatar" />
<img
className="h-4 w-4 rounded-full ltr:mr-3 rtl:ml-3"
src={tab?.avatar}
alt="User Avatar"
/>
)}
<p className="text-sm font-medium leading-5">{t(tab.name)}</p>
</div>
@@ -207,7 +211,7 @@ const SettingsSidebarContainer = ({
<a>
<div className="group flex h-9 w-64 flex-row items-center rounded-md px-3 py-[10px] text-sm font-medium leading-none text-gray-600 hover:bg-gray-100 group-hover:text-gray-700 [&[aria-current='page']]:bg-gray-200 [&[aria-current='page']]:text-gray-900">
{tab && tab.icon && (
<tab.icon className="mr-[12px] h-[16px] w-[16px] stroke-[2px] md:mt-0" />
<tab.icon className="h-[16px] w-[16px] stroke-[2px] ltr:mr-3 rtl:ml-3 md:mt-0" />
)}
<p className="text-sm font-medium leading-5">{t(tab.name)}</p>
</div>
@@ -242,7 +246,7 @@ const SettingsSidebarContainer = ({
}),
])
}>
<div className="mr-[13px]">
<div className="ltr:mr-3 rtl:ml-3">
{teamMenuState[index].teamMenuOpen ? (
<Icon.FiChevronDown />
) : (
@@ -251,12 +255,12 @@ const SettingsSidebarContainer = ({
</div>
<img
src={getPlaceholderAvatar(team.logo, team?.name as string)}
className="mr-[8px] h-[16px] w-[16px] self-start rounded-full stroke-[2px] md:mt-0"
className="h-[16px] w-[16px] self-start rounded-full stroke-[2px] ltr:mr-2 rtl:ml-2 md:mt-0"
alt={team.name || "Team logo"}
/>
<p>{team.name}</p>
{!team.accepted && (
<Badge className="ml-3" variant="orange">
<Badge className="ltr:ml-3 rtl:mr-3" variant="orange">
Inv.
</Badge>
)}
@@ -339,7 +343,9 @@ const MobileSettingsContainer = (props: { onSideContainerOpen?: () => void }) =>
<span className="sr-only">{t("show_navigation")}</span>
</Button>
<a href="/" className="flex items-center space-x-2 rounded-md px-3 py-1 hover:bg-gray-200">
<a
href="/"
className="flex items-center space-x-2 rounded-md px-3 py-1 hover:bg-gray-200 rtl:space-x-reverse">
<Icon.FiArrowLeft className="text-gray-700" />
<p className="font-semibold text-black">{t("settings")}</p>
</a>
@@ -50,15 +50,17 @@ const VerticalTabItem = function ({
props.textClassNames || "text-sm font-medium leading-none text-gray-600",
"min-h-9 group flex w-64 flex-row items-center rounded-md px-2 py-[10px] hover:bg-gray-100 group-hover:text-gray-700 [&[aria-current='page']]:bg-gray-200 [&[aria-current='page']]:text-gray-900",
props.disabled && "pointer-events-none !opacity-30",
(isChild || !props.icon) && "ml-7 mr-5 w-auto",
(isChild || !props.icon) && "ml-7 w-auto ltr:mr-5 rtl:ml-5",
!info ? "h-6" : "h-14",
props.className
)}
data-testid={`vertical-tab-${name}`}
aria-current={isCurrent ? "page" : undefined}>
{props.icon && <props.icon className="mr-[10px] h-[16px] w-[16px] stroke-[2px] md:mt-0" />}
{props.icon && (
<props.icon className="h-[16px] w-[16px] stroke-[2px] ltr:mr-[10px] rtl:ml-[10px] md:mt-0" />
)}
<div className="h-fit">
<span className="flex items-center space-x-2">
<span className="flex items-center space-x-2 rtl:space-x-reverse">
<Skeleton title={t(name)} as="p" className="max-w-36 min-h-4 truncate">
{t(name)}
</Skeleton>
+4 -4
View File
@@ -10,7 +10,7 @@ export function showToast(message: string, variant: "success" | "warning" | "err
(t) => (
<div
className={classNames(
"data-testid-toast-success bg-brand-500 mb-2 flex h-9 items-center space-x-2 rounded-md p-3 text-sm font-semibold text-white shadow-md",
"data-testid-toast-success bg-brand-500 mb-2 flex h-9 items-center space-x-2 rounded-md p-3 text-sm font-semibold text-white shadow-md rtl:space-x-reverse",
t.visible && "animate-fade-in-up"
)}>
<Icon.FiCheck className="h-4 w-4" />
@@ -25,7 +25,7 @@ export function showToast(message: string, variant: "success" | "warning" | "err
(t) => (
<div
className={classNames(
"animate-fade-in-up mb-2 flex h-9 items-center space-x-2 rounded-md bg-red-100 p-3 text-sm font-semibold text-red-900 shadow-md",
"animate-fade-in-up mb-2 flex h-9 items-center space-x-2 rounded-md bg-red-100 p-3 text-sm font-semibold text-red-900 shadow-md rtl:space-x-reverse",
t.visible && "animate-fade-in-up"
)}>
<Icon.FiInfo className="h-4 w-4" />
@@ -40,7 +40,7 @@ export function showToast(message: string, variant: "success" | "warning" | "err
(t) => (
<div
className={classNames(
"animate-fade-in-up bg-brand-500 mb-2 flex h-9 items-center space-x-2 rounded-md p-3 text-sm font-semibold text-white shadow-md",
"animate-fade-in-up bg-brand-500 mb-2 flex h-9 items-center space-x-2 rounded-md p-3 text-sm font-semibold text-white shadow-md rtl:space-x-reverse",
t.visible && "animate-fade-in-up"
)}>
<Icon.FiInfo className="h-4 w-4" />
@@ -55,7 +55,7 @@ export function showToast(message: string, variant: "success" | "warning" | "err
(t) => (
<div
className={classNames(
"animate-fade-in-up bg-brand-500 mb-2 flex h-9 items-center space-x-2 rounded-md p-3 text-sm font-semibold text-white shadow-md",
"animate-fade-in-up bg-brand-500 mb-2 flex h-9 items-center space-x-2 rounded-md p-3 text-sm font-semibold text-white shadow-md rtl:space-x-reverse",
t.visible && "animate-fade-in-up"
)}>
<Icon.FiCheck className="h-4 w-4" />