@carlonicora/nextjs-jsonapi 3.3.9 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteEditor-BYMRWUVG.mjs → BlockNoteEditor-3D5D7YL7.mjs} +2 -2
- package/dist/{BlockNoteEditor-USRMFZGP.js → BlockNoteEditor-F6TGKMTW.js} +9 -9
- package/dist/{BlockNoteEditor-USRMFZGP.js.map → BlockNoteEditor-F6TGKMTW.js.map} +1 -1
- package/dist/billing/index.js +347 -347
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +27 -27
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-CFZW6GU4.mjs → chunk-G5LSXG5K.mjs} +2572 -2482
- package/dist/chunk-G5LSXG5K.mjs.map +1 -0
- package/dist/{chunk-5WFYQE22.js → chunk-KT4CTWCV.js} +825 -735
- package/dist/chunk-KT4CTWCV.js.map +1 -0
- package/dist/client/index.d.mts +5 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +13 -7
- package/dist/components/index.d.ts +13 -7
- package/dist/components/index.js +2 -2
- package/dist/components/index.mjs +1 -1
- package/dist/contexts/index.d.mts +13 -1
- package/dist/contexts/index.d.ts +13 -1
- package/dist/contexts/index.js +6 -2
- package/dist/contexts/index.js.map +1 -1
- package/dist/contexts/index.mjs +5 -1
- package/dist/features/help/index.js +35 -35
- package/dist/features/help/index.js.map +1 -1
- package/dist/features/help/index.mjs +6 -6
- package/dist/features/help/index.mjs.map +1 -1
- package/dist/features/tokenusage/index.js +135 -129
- package/dist/features/tokenusage/index.js.map +1 -1
- package/dist/features/tokenusage/index.mjs +74 -68
- package/dist/features/tokenusage/index.mjs.map +1 -1
- package/package.json +35 -35
- package/scripts/check-rtl-classes.mjs +60 -0
- package/scripts/check-rtl-classes.test.ts +25 -0
- package/src/components/TableCellAvatar.tsx +1 -1
- package/src/components/containers/PageContainer.tsx +1 -1
- package/src/components/containers/ReactMarkdownContainer.tsx +20 -4
- package/src/components/containers/RoundPageContainer.tsx +7 -7
- package/src/components/contents/AttributeElement.tsx +1 -1
- package/src/components/editors/BlockNoteDiffInlineContent.tsx +2 -2
- package/src/components/editors/BlockNoteEditorMentionHoverCard.tsx +1 -0
- package/src/components/forms/CommonDeleter.tsx +1 -1
- package/src/components/forms/CommonEditorButtons.tsx +1 -1
- package/src/components/forms/DatePickerPopover.tsx +2 -2
- package/src/components/forms/DateRangeSelector.tsx +2 -2
- package/src/components/forms/EditorSheet.tsx +18 -9
- package/src/components/forms/EntityMultiSelector.tsx +7 -7
- package/src/components/forms/EntitySelector.tsx +8 -8
- package/src/components/forms/FileUploader.tsx +1 -0
- package/src/components/forms/FormCheckbox.tsx +3 -3
- package/src/components/forms/FormDateTime.tsx +3 -3
- package/src/components/forms/FormFieldWrapper.tsx +1 -1
- package/src/components/forms/FormPlaceAutocomplete.tsx +2 -2
- package/src/components/forms/GdprConsentCheckbox.tsx +1 -1
- package/src/components/forms/MultiFileUploader.tsx +1 -1
- package/src/components/forms/PasswordInput.tsx +1 -1
- package/src/components/forms/__tests__/FormCheckbox.test.tsx +4 -4
- package/src/components/navigations/Header.tsx +2 -2
- package/src/components/navigations/PageSection.tsx +1 -1
- package/src/components/pages/PageContainerContentDetails.tsx +1 -1
- package/src/components/pages/PageContentContainer.tsx +5 -2
- package/src/components/tables/ContentListTable.tsx +4 -4
- package/src/components/tables/ContentTableSearch.tsx +5 -5
- package/src/contexts/DirectionContext.tsx +25 -0
- package/src/contexts/__tests__/DirectionContext.test.tsx +22 -0
- package/src/contexts/index.ts +1 -0
- package/src/features/ai-connection/components/lists/AiConnectionTypeCard.tsx +1 -1
- package/src/features/assistant/components/containers/AssistantPageContainer.tsx +1 -1
- package/src/features/assistant/components/parts/AssistantBlockNoteComposer.tsx +2 -2
- package/src/features/assistant/components/parts/AssistantComposer.tsx +2 -2
- package/src/features/assistant/components/parts/AssistantEmptyState.tsx +1 -1
- package/src/features/assistant/components/parts/AssistantSidebar.tsx +3 -3
- package/src/features/assistant-action/components/ApprovalActionCard.tsx +1 -1
- package/src/features/assistant-action/components/AssistantContainerWithApprovals.tsx +1 -1
- package/src/features/assistant-message/components/MessageItem.tsx +3 -3
- package/src/features/assistant-message/components/__tests__/MessageItem.spec.tsx +1 -0
- package/src/features/assistant-message/components/parts/MessageSourcesPanel.tsx +2 -2
- package/src/features/assistant-message/components/parts/RelevanceMeter.tsx +1 -1
- package/src/features/assistant-message/components/parts/tabs/SuggestedQuestionsTab.tsx +1 -1
- package/src/features/auth/components/buttons/GoogleSignInButton.tsx +1 -1
- package/src/features/auth/components/forms/Register.tsx +2 -2
- package/src/features/auth/components/two-factor/BackupCodesDialog.tsx +3 -3
- package/src/features/auth/utils/__tests__/clearClientStorage.spec.ts +4 -4
- package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +1 -1
- package/src/features/billing/components/cards/CustomerInfoCard.tsx +1 -1
- package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +1 -1
- package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +1 -1
- package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +1 -1
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +1 -1
- package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +1 -1
- package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +6 -6
- package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +2 -2
- package/src/features/billing/stripe-price/hooks/useStripePriceTableStructure.tsx +3 -3
- package/src/features/billing/stripe-product/hooks/useStripeProductTableStructure.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +4 -4
- package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx +1 -1
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +2 -2
- package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +2 -2
- package/src/features/company/components/forms/CompanyDeleter.tsx +4 -4
- package/src/features/content/hooks/useContentTableStructure.tsx +1 -1
- package/src/features/feature/components/forms/FormFeatures.tsx +2 -2
- package/src/features/help/components/HelpAssistantSheet.tsx +3 -2
- package/src/features/help/components/HelpHint.tsx +2 -2
- package/src/features/help/components/HelpTOC.tsx +1 -1
- package/src/features/how-to/components/containers/HowToCommand.tsx +2 -2
- package/src/features/how-to/components/containers/HowToCommandViewer.tsx +5 -5
- package/src/features/how-to/components/forms/HowToEditor.tsx +3 -3
- package/src/features/how-to/components/forms/HowToSelector.tsx +5 -5
- package/src/features/notification/components/lists/NotificationsList.tsx +2 -2
- package/src/features/notification/components/modals/NotificationModal.tsx +1 -1
- package/src/features/oauth/components/OAuthClientCard.tsx +2 -2
- package/src/features/oauth/components/OAuthClientDetail.tsx +2 -2
- package/src/features/oauth/components/OAuthClientList.tsx +3 -3
- package/src/features/oauth/components/OAuthRedirectUriInput.tsx +1 -1
- package/src/features/oauth/components/OAuthScopeSelector.tsx +2 -2
- package/src/features/onboarding/components/OnboardingCard.tsx +1 -7
- package/src/features/rbac/components/RbacByRoleContainer.tsx +3 -3
- package/src/features/rbac/components/RbacContainer.tsx +3 -3
- package/src/features/referral/components/ReferralWidget.tsx +1 -0
- package/src/features/role/components/forms/FormRoles.tsx +1 -1
- package/src/features/role/components/forms/RemoveUserFromRole.tsx +1 -1
- package/src/features/role/components/forms/UserRoleAdd.tsx +1 -1
- package/src/features/tokenusage/components/TokenUsageBreakdownTable.tsx +9 -9
- package/src/features/tokenusage/components/TokenUsageRankedBar.tsx +8 -3
- package/src/features/tokenusage/components/TokenUsageTimelineChart.tsx +5 -1
- package/src/features/user/components/details/UserStandaloneDetails.tsx +1 -1
- package/src/features/user/components/forms/UserReactivator.tsx +2 -2
- package/src/features/user/components/forms/UserResentInvitationEmail.tsx +1 -1
- package/src/features/user/components/forms/UserSelector.tsx +7 -7
- package/src/features/user/components/lists/ContributorsList.tsx +1 -1
- package/src/features/user/components/lists/UserListInAdd.tsx +1 -1
- package/src/features/user/components/widgets/UserSearchPopover.tsx +5 -5
- package/src/features/user/hooks/useUserTableStructure.tsx +1 -1
- package/src/features/waitlist/components/forms/WaitlistQuestionnaireRenderer.tsx +1 -1
- package/src/features/waitlist/hooks/useWaitlistTableStructure.tsx +1 -1
- package/src/hooks/useCustomD3Graph.tsx +16 -0
- package/src/lib/__tests__/direction.test.ts +18 -0
- package/src/lib/direction.ts +8 -0
- package/src/shadcnui/custom/multi-select.tsx +6 -6
- package/src/shadcnui/custom/multiple-selector.tsx +6 -2
- package/src/shadcnui/ui/accordion.tsx +1 -1
- package/src/shadcnui/ui/alert-dialog.tsx +2 -1
- package/src/shadcnui/ui/alert.tsx +2 -2
- package/src/shadcnui/ui/avatar.tsx +1 -1
- package/src/shadcnui/ui/badge.tsx +1 -1
- package/src/shadcnui/ui/breadcrumb.tsx +1 -1
- package/src/shadcnui/ui/button.tsx +4 -4
- package/src/shadcnui/ui/calendar.tsx +9 -8
- package/src/shadcnui/ui/carousel.tsx +18 -11
- package/src/shadcnui/ui/combobox.tsx +3 -3
- package/src/shadcnui/ui/command.tsx +2 -2
- package/src/shadcnui/ui/context-menu.tsx +15 -11
- package/src/shadcnui/ui/dialog.tsx +2 -1
- package/src/shadcnui/ui/drawer.tsx +19 -3
- package/src/shadcnui/ui/dropdown-menu.tsx +12 -10
- package/src/shadcnui/ui/field.tsx +2 -2
- package/src/shadcnui/ui/input-group.tsx +3 -3
- package/src/shadcnui/ui/input-otp.tsx +2 -0
- package/src/shadcnui/ui/navigation-menu.tsx +2 -2
- package/src/shadcnui/ui/progress.tsx +1 -1
- package/src/shadcnui/ui/radio-group.tsx +1 -0
- package/src/shadcnui/ui/resizable.tsx +1 -0
- package/src/shadcnui/ui/scroll-area.tsx +1 -1
- package/src/shadcnui/ui/select.tsx +2 -2
- package/src/shadcnui/ui/sheet.tsx +11 -4
- package/src/shadcnui/ui/sidebar.tsx +37 -20
- package/src/shadcnui/ui/sonner.tsx +6 -1
- package/src/shadcnui/ui/switch.tsx +1 -1
- package/src/shadcnui/ui/table.tsx +2 -2
- package/src/shadcnui/ui/tabs.tsx +1 -1
- package/dist/chunk-5WFYQE22.js.map +0 -1
- package/dist/chunk-CFZW6GU4.mjs.map +0 -1
- /package/dist/{BlockNoteEditor-BYMRWUVG.mjs.map → BlockNoteEditor-3D5D7YL7.mjs.map} +0 -0
|
@@ -6,6 +6,7 @@ import { DayPicker, getDefaultClassNames, type DayButton } from "react-day-picke
|
|
|
6
6
|
import { cn } from "@/lib/utils";
|
|
7
7
|
import { Button, buttonVariants } from "@/components/ui/button";
|
|
8
8
|
import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from "lucide-react";
|
|
9
|
+
import { useDir } from "../../contexts/DirectionContext";
|
|
9
10
|
|
|
10
11
|
function Calendar({
|
|
11
12
|
className,
|
|
@@ -20,14 +21,14 @@ function Calendar({
|
|
|
20
21
|
buttonVariant?: React.ComponentProps<typeof Button>["variant"];
|
|
21
22
|
}) {
|
|
22
23
|
const defaultClassNames = getDefaultClassNames();
|
|
24
|
+
const dir = useDir();
|
|
23
25
|
|
|
24
26
|
return (
|
|
25
27
|
<DayPicker
|
|
28
|
+
dir={dir}
|
|
26
29
|
showOutsideDays={showOutsideDays}
|
|
27
30
|
className={cn(
|
|
28
31
|
"p-3 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(6)] bg-background group/calendar [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
29
|
-
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
30
|
-
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
31
32
|
className,
|
|
32
33
|
)}
|
|
33
34
|
captionLayout={captionLayout}
|
|
@@ -80,19 +81,19 @@ function Calendar({
|
|
|
80
81
|
week_number_header: cn("select-none w-(--cell-size)", defaultClassNames.week_number_header),
|
|
81
82
|
week_number: cn("text-xs select-none text-muted-foreground", defaultClassNames.week_number),
|
|
82
83
|
day: cn(
|
|
83
|
-
"relative w-full rounded-(--cell-radius) h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-
|
|
84
|
+
"relative w-full rounded-(--cell-radius) h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-e-(--cell-radius) group/day aspect-square select-none",
|
|
84
85
|
props.showWeekNumber
|
|
85
|
-
? "[&:nth-child(2)[data-selected=true]_button]:rounded-
|
|
86
|
-
: "[&:first-child[data-selected=true]_button]:rounded-
|
|
86
|
+
? "[&:nth-child(2)[data-selected=true]_button]:rounded-s-(--cell-radius)"
|
|
87
|
+
: "[&:first-child[data-selected=true]_button]:rounded-s-(--cell-radius)",
|
|
87
88
|
defaultClassNames.day,
|
|
88
89
|
),
|
|
89
90
|
range_start: cn(
|
|
90
|
-
"rounded-
|
|
91
|
+
"rounded-s-(--cell-radius) bg-muted elative after:bg-muted after:absolute after:inset-y-0 after:w-4 after:end-0 -z-0 isolate",
|
|
91
92
|
defaultClassNames.range_start,
|
|
92
93
|
),
|
|
93
94
|
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
94
95
|
range_end: cn(
|
|
95
|
-
"rounded-
|
|
96
|
+
"rounded-e-(--cell-radius) bg-muted relative after:bg-muted after:absolute after:inset-y-0 after:w-4 after:start-0 -z-0 isolate",
|
|
96
97
|
defaultClassNames.range_end,
|
|
97
98
|
),
|
|
98
99
|
today: cn(
|
|
@@ -154,7 +155,7 @@ function CalendarDayButton({ className, day, modifiers, ...props }: React.Compon
|
|
|
154
155
|
data-range-end={modifiers.range_end}
|
|
155
156
|
data-range-middle={modifiers.range_middle}
|
|
156
157
|
className={cn(
|
|
157
|
-
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-foreground relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-
|
|
158
|
+
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-foreground relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-e-(--cell-radius) data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-s-(--cell-radius) [&>span]:text-xs [&>span]:opacity-70",
|
|
158
159
|
defaultClassNames.day,
|
|
159
160
|
className,
|
|
160
161
|
)}
|
|
@@ -6,6 +6,7 @@ import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-reac
|
|
|
6
6
|
import { cn } from "@/lib/utils";
|
|
7
7
|
import { Button } from "@/components/ui/button";
|
|
8
8
|
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
|
9
|
+
import { useDir } from "../../contexts/DirectionContext";
|
|
9
10
|
|
|
10
11
|
type CarouselApi = UseEmblaCarouselType[1];
|
|
11
12
|
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
|
|
@@ -49,10 +50,12 @@ function Carousel({
|
|
|
49
50
|
children,
|
|
50
51
|
...props
|
|
51
52
|
}: React.ComponentProps<"div"> & CarouselProps) {
|
|
53
|
+
const dir = useDir();
|
|
52
54
|
const [carouselRef, api] = useEmblaCarousel(
|
|
53
55
|
{
|
|
54
56
|
...opts,
|
|
55
57
|
axis: orientation === "horizontal" ? "x" : "y",
|
|
58
|
+
direction: opts?.direction ?? dir,
|
|
56
59
|
},
|
|
57
60
|
plugins,
|
|
58
61
|
);
|
|
@@ -75,15 +78,17 @@ function Carousel({
|
|
|
75
78
|
|
|
76
79
|
const handleKeyDown = React.useCallback(
|
|
77
80
|
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
78
|
-
|
|
81
|
+
// Arrow keys are physical; in RTL the previous slide sits to the right.
|
|
82
|
+
const toPrev = dir === "rtl" ? "ArrowRight" : "ArrowLeft";
|
|
83
|
+
if (event.key === toPrev) {
|
|
79
84
|
event.preventDefault();
|
|
80
85
|
scrollPrev();
|
|
81
|
-
} else if (event.key === "ArrowRight") {
|
|
86
|
+
} else if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
82
87
|
event.preventDefault();
|
|
83
88
|
scrollNext();
|
|
84
89
|
}
|
|
85
90
|
},
|
|
86
|
-
[scrollPrev, scrollNext],
|
|
91
|
+
[scrollPrev, scrollNext, dir],
|
|
87
92
|
);
|
|
88
93
|
|
|
89
94
|
React.useEffect(() => {
|
|
@@ -134,7 +139,7 @@ function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
134
139
|
|
|
135
140
|
return (
|
|
136
141
|
<div ref={carouselRef} className="overflow-hidden" data-slot="carousel-content">
|
|
137
|
-
<div className={cn("flex", orientation === "horizontal" ? "-
|
|
142
|
+
<div className={cn("flex", orientation === "horizontal" ? "-ms-4" : "-mt-4 flex-col", className)} {...props} />
|
|
138
143
|
</div>
|
|
139
144
|
);
|
|
140
145
|
}
|
|
@@ -147,7 +152,7 @@ function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
147
152
|
role="group"
|
|
148
153
|
aria-roledescription="slide"
|
|
149
154
|
data-slot="carousel-item"
|
|
150
|
-
className={cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "
|
|
155
|
+
className={cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "ps-4" : "pt-4", className)}
|
|
151
156
|
{...props}
|
|
152
157
|
/>
|
|
153
158
|
);
|
|
@@ -169,15 +174,16 @@ function CarouselPrevious({
|
|
|
169
174
|
className={cn(
|
|
170
175
|
"rounded-full absolute touch-manipulation",
|
|
171
176
|
orientation === "horizontal"
|
|
172
|
-
? "top-1/2 -
|
|
173
|
-
:
|
|
177
|
+
? "top-1/2 -start-12 -translate-y-1/2"
|
|
178
|
+
: // rtl-ok: symmetric centering (vertical carousel)
|
|
179
|
+
"-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
174
180
|
className,
|
|
175
181
|
)}
|
|
176
182
|
disabled={!canScrollPrev}
|
|
177
183
|
onClick={scrollPrev}
|
|
178
184
|
{...props}
|
|
179
185
|
>
|
|
180
|
-
<ChevronLeftIcon />
|
|
186
|
+
<ChevronLeftIcon className={orientation === "horizontal" ? "rtl:rotate-180" : undefined} />
|
|
181
187
|
<span className="sr-only">Previous slide</span>
|
|
182
188
|
</Button>
|
|
183
189
|
);
|
|
@@ -199,15 +205,16 @@ function CarouselNext({
|
|
|
199
205
|
className={cn(
|
|
200
206
|
"rounded-full absolute touch-manipulation",
|
|
201
207
|
orientation === "horizontal"
|
|
202
|
-
? "top-1/2 -
|
|
203
|
-
:
|
|
208
|
+
? "top-1/2 -end-12 -translate-y-1/2"
|
|
209
|
+
: // rtl-ok: symmetric centering (vertical carousel)
|
|
210
|
+
"-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
204
211
|
className,
|
|
205
212
|
)}
|
|
206
213
|
disabled={!canScrollNext}
|
|
207
214
|
onClick={scrollNext}
|
|
208
215
|
{...props}
|
|
209
216
|
>
|
|
210
|
-
<ChevronRightIcon />
|
|
217
|
+
<ChevronRightIcon className={orientation === "horizontal" ? "rtl:rotate-180" : undefined} />
|
|
211
218
|
<span className="sr-only">Next slide</span>
|
|
212
219
|
</Button>
|
|
213
220
|
);
|
|
@@ -131,7 +131,7 @@ function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.
|
|
|
131
131
|
>
|
|
132
132
|
{children}
|
|
133
133
|
<ComboboxPrimitive.ItemIndicator
|
|
134
|
-
render={<span className="pointer-events-none absolute
|
|
134
|
+
render={<span className="pointer-events-none absolute end-2 flex items-center justify-center" />}
|
|
135
135
|
>
|
|
136
136
|
<CheckIcon className="pointer-events-none" />
|
|
137
137
|
</ComboboxPrimitive.ItemIndicator>
|
|
@@ -208,7 +208,7 @@ function ComboboxChip({
|
|
|
208
208
|
<ComboboxPrimitive.Chip
|
|
209
209
|
data-slot="combobox-chip"
|
|
210
210
|
className={cn(
|
|
211
|
-
"bg-muted-foreground/10 text-foreground flex h-[calc(--spacing(4.75))] w-fit items-center justify-center gap-1 rounded-[calc(var(--radius-sm)-2px)] px-1.5 text-xs/relaxed font-medium whitespace-nowrap has-data-[slot=combobox-chip-remove]:
|
|
211
|
+
"bg-muted-foreground/10 text-foreground flex h-[calc(--spacing(4.75))] w-fit items-center justify-center gap-1 rounded-[calc(var(--radius-sm)-2px)] px-1.5 text-xs/relaxed font-medium whitespace-nowrap has-data-[slot=combobox-chip-remove]:pe-0 has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50",
|
|
212
212
|
className,
|
|
213
213
|
)}
|
|
214
214
|
{...props}
|
|
@@ -217,7 +217,7 @@ function ComboboxChip({
|
|
|
217
217
|
{showRemove && (
|
|
218
218
|
<ComboboxPrimitive.ChipRemove
|
|
219
219
|
render={<Button variant="ghost" size="icon-xs" />}
|
|
220
|
-
className="-
|
|
220
|
+
className="-ms-1 opacity-50 hover:opacity-100"
|
|
221
221
|
data-slot="combobox-chip-remove"
|
|
222
222
|
>
|
|
223
223
|
<XIcon className="pointer-events-none" />
|
|
@@ -137,7 +137,7 @@ function CommandItem({ className, children, ...props }: React.ComponentProps<typ
|
|
|
137
137
|
{...props}
|
|
138
138
|
>
|
|
139
139
|
{children}
|
|
140
|
-
<CheckIcon className="
|
|
140
|
+
<CheckIcon className="ms-auto opacity-0 group-has-[[data-slot=command-shortcut]]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
|
|
141
141
|
</CommandPrimitive.Item>
|
|
142
142
|
);
|
|
143
143
|
}
|
|
@@ -147,7 +147,7 @@ function CommandShortcut({ className, ...props }: React.ComponentProps<"span">)
|
|
|
147
147
|
<span
|
|
148
148
|
data-slot="command-shortcut"
|
|
149
149
|
className={cn(
|
|
150
|
-
"text-muted-foreground group-data-[selected=true]/command-item:text-foreground
|
|
150
|
+
"text-muted-foreground group-data-[selected=true]/command-item:text-foreground ms-auto text-xs tracking-widest",
|
|
151
151
|
className,
|
|
152
152
|
)}
|
|
153
153
|
{...props}
|
|
@@ -28,7 +28,9 @@ function ContextMenuContent({
|
|
|
28
28
|
className,
|
|
29
29
|
align = "start",
|
|
30
30
|
alignOffset = 4,
|
|
31
|
-
|
|
31
|
+
// Base UI 1.6.0 `Side` accepts logical values; "inline-end" resolves to the
|
|
32
|
+
// physical right in LTR (unchanged) and to the left in RTL.
|
|
33
|
+
side = "inline-end",
|
|
32
34
|
sideOffset = 0,
|
|
33
35
|
anchor,
|
|
34
36
|
...props
|
|
@@ -72,7 +74,7 @@ function ContextMenuLabel({
|
|
|
72
74
|
<ContextMenuPrimitive.GroupLabel
|
|
73
75
|
data-slot="context-menu-label"
|
|
74
76
|
data-inset={inset}
|
|
75
|
-
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-[inset]:
|
|
77
|
+
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-[inset]:ps-8", className)}
|
|
76
78
|
{...props}
|
|
77
79
|
/>
|
|
78
80
|
);
|
|
@@ -93,7 +95,7 @@ function ContextMenuItem({
|
|
|
93
95
|
data-inset={inset}
|
|
94
96
|
data-variant={variant}
|
|
95
97
|
className={cn(
|
|
96
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs/relaxed [&_svg:not([class*='size-'])]:size-3.5 group/context-menu-item relative flex cursor-pointer items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:
|
|
98
|
+
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs/relaxed [&_svg:not([class*='size-'])]:size-3.5 group/context-menu-item relative flex cursor-pointer items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:ps-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
97
99
|
className,
|
|
98
100
|
)}
|
|
99
101
|
{...props}
|
|
@@ -118,19 +120,21 @@ function ContextMenuSubTrigger({
|
|
|
118
120
|
data-slot="context-menu-sub-trigger"
|
|
119
121
|
data-inset={inset}
|
|
120
122
|
className={cn(
|
|
121
|
-
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs [&_svg:not([class*='size-'])]:size-3.5 flex cursor-pointer items-center outline-hidden select-none data-[inset]:
|
|
123
|
+
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs [&_svg:not([class*='size-'])]:size-3.5 flex cursor-pointer items-center outline-hidden select-none data-[inset]:ps-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
122
124
|
className,
|
|
123
125
|
)}
|
|
124
126
|
{...props}
|
|
125
127
|
>
|
|
126
128
|
{children}
|
|
127
|
-
<ChevronRightIcon className="
|
|
129
|
+
<ChevronRightIcon className="ms-auto rtl:rotate-180" />
|
|
128
130
|
</ContextMenuPrimitive.SubmenuTrigger>
|
|
129
131
|
);
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
function ContextMenuSubContent({ ...props }: React.ComponentProps<typeof ContextMenuContent>) {
|
|
133
|
-
|
|
135
|
+
// Base UI 1.6.0 `Side` accepts logical values, so the submenu opens on the inline-end
|
|
136
|
+
// side of its trigger in both directions (identical to "right" under LTR).
|
|
137
|
+
return <ContextMenuContent data-slot="context-menu-sub-content" className="shadow-lg" side="inline-end" {...props} />;
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
function ContextMenuCheckboxItem({ className, children, checked, ...props }: ContextMenuPrimitive.CheckboxItem.Props) {
|
|
@@ -138,13 +142,13 @@ function ContextMenuCheckboxItem({ className, children, checked, ...props }: Con
|
|
|
138
142
|
<ContextMenuPrimitive.CheckboxItem
|
|
139
143
|
data-slot="context-menu-checkbox-item"
|
|
140
144
|
className={cn(
|
|
141
|
-
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5
|
|
145
|
+
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5 pe-8 ps-2 text-xs [&_svg:not([class*='size-'])]:size-3.5 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
142
146
|
className,
|
|
143
147
|
)}
|
|
144
148
|
checked={checked}
|
|
145
149
|
{...props}
|
|
146
150
|
>
|
|
147
|
-
<span className="pointer-events-none absolute
|
|
151
|
+
<span className="pointer-events-none absolute end-2 flex items-center justify-center pointer-events-none">
|
|
148
152
|
<ContextMenuPrimitive.CheckboxItemIndicator>
|
|
149
153
|
<CheckIcon />
|
|
150
154
|
</ContextMenuPrimitive.CheckboxItemIndicator>
|
|
@@ -163,12 +167,12 @@ function ContextMenuRadioItem({ className, children, ...props }: ContextMenuPrim
|
|
|
163
167
|
<ContextMenuPrimitive.RadioItem
|
|
164
168
|
data-slot="context-menu-radio-item"
|
|
165
169
|
className={cn(
|
|
166
|
-
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5
|
|
170
|
+
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5 pe-8 ps-2 text-xs [&_svg:not([class*='size-'])]:size-3.5 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
167
171
|
className,
|
|
168
172
|
)}
|
|
169
173
|
{...props}
|
|
170
174
|
>
|
|
171
|
-
<span className="pointer-events-none absolute
|
|
175
|
+
<span className="pointer-events-none absolute end-2 flex items-center justify-center pointer-events-none">
|
|
172
176
|
<ContextMenuPrimitive.RadioItemIndicator>
|
|
173
177
|
<CheckIcon />
|
|
174
178
|
</ContextMenuPrimitive.RadioItemIndicator>
|
|
@@ -193,7 +197,7 @@ function ContextMenuShortcut({ className, ...props }: React.ComponentProps<"span
|
|
|
193
197
|
<span
|
|
194
198
|
data-slot="context-menu-shortcut"
|
|
195
199
|
className={cn(
|
|
196
|
-
"text-muted-foreground group-focus/context-menu-item:text-accent-foreground
|
|
200
|
+
"text-muted-foreground group-focus/context-menu-item:text-accent-foreground ms-auto text-xs tracking-widest",
|
|
197
201
|
className,
|
|
198
202
|
)}
|
|
199
203
|
{...props}
|
|
@@ -50,6 +50,7 @@ function DialogContent({
|
|
|
50
50
|
<DialogPrimitive.Popup
|
|
51
51
|
data-slot="dialog-content"
|
|
52
52
|
className={cn(
|
|
53
|
+
// rtl-ok: symmetric centering (`left-1/2` + `-translate-x-1/2`) — identical in LTR and RTL
|
|
53
54
|
"bg-background data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 grid gap-4 rounded-xl p-4 text-xs/relaxed ring-1 duration-100 fixed top-1/2 left-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 outline-none",
|
|
54
55
|
className,
|
|
55
56
|
)}
|
|
@@ -59,7 +60,7 @@ function DialogContent({
|
|
|
59
60
|
{showCloseButton && (
|
|
60
61
|
<DialogPrimitive.Close
|
|
61
62
|
data-slot="dialog-close"
|
|
62
|
-
render={<Button variant="ghost" className="absolute top-2
|
|
63
|
+
render={<Button variant="ghost" className="absolute top-2 end-2" size="icon-sm" />}
|
|
63
64
|
>
|
|
64
65
|
<XIcon />
|
|
65
66
|
<span className="sr-only">Close</span>
|
|
@@ -4,9 +4,24 @@ import * as React from "react";
|
|
|
4
4
|
import { Drawer as DrawerPrimitive } from "vaul";
|
|
5
5
|
|
|
6
6
|
import { cn } from "@/lib/utils";
|
|
7
|
+
import { resolvePhysicalSide } from "@/lib/direction";
|
|
8
|
+
import { useDir } from "../../contexts/DirectionContext";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
// vaul's DialogProps is an intersection with a discriminated union
|
|
11
|
+
// (WithFadeFromProps | WithoutFadeFromProps); a plain Omit collapses it and
|
|
12
|
+
// breaks the snapPoints/fadeFromIndex correlation, so distribute the Omit.
|
|
13
|
+
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
14
|
+
|
|
15
|
+
function Drawer({
|
|
16
|
+
direction,
|
|
17
|
+
...props
|
|
18
|
+
}: DistributiveOmit<React.ComponentProps<typeof DrawerPrimitive.Root>, "direction"> & {
|
|
19
|
+
direction?: "top" | "bottom" | "left" | "right" | "start" | "end";
|
|
20
|
+
}) {
|
|
21
|
+
const dir = useDir();
|
|
22
|
+
const resolved = direction === "start" || direction === "end" ? resolvePhysicalSide(direction, dir) : direction;
|
|
23
|
+
|
|
24
|
+
return <DrawerPrimitive.Root data-slot="drawer" direction={resolved} {...props} />;
|
|
10
25
|
}
|
|
11
26
|
|
|
12
27
|
function DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
|
|
@@ -40,6 +55,7 @@ function DrawerContent({ className, children, ...props }: React.ComponentProps<t
|
|
|
40
55
|
<DrawerOverlay />
|
|
41
56
|
<DrawerPrimitive.Content
|
|
42
57
|
data-slot="drawer-content"
|
|
58
|
+
// rtl-ok: data-[vaul-drawer-direction=…] classes key off the RESOLVED physical side
|
|
43
59
|
className={cn(
|
|
44
60
|
"before:bg-background relative flex h-auto flex-col bg-transparent p-2 text-xs/relaxed before:absolute before:inset-2 before:-z-10 before:rounded-xl data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm group/drawer-content fixed z-50",
|
|
45
61
|
className,
|
|
@@ -58,7 +74,7 @@ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
58
74
|
<div
|
|
59
75
|
data-slot="drawer-header"
|
|
60
76
|
className={cn(
|
|
61
|
-
"gap-1 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:text-
|
|
77
|
+
"gap-1 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:text-start flex flex-col",
|
|
62
78
|
className,
|
|
63
79
|
)}
|
|
64
80
|
{...props}
|
|
@@ -63,7 +63,7 @@ function DropdownMenuLabel({
|
|
|
63
63
|
<MenuPrimitive.GroupLabel
|
|
64
64
|
data-slot="dropdown-menu-label"
|
|
65
65
|
data-inset={inset}
|
|
66
|
-
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-[inset]:
|
|
66
|
+
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-[inset]:ps-8", className)}
|
|
67
67
|
{...props}
|
|
68
68
|
/>
|
|
69
69
|
);
|
|
@@ -84,7 +84,7 @@ function DropdownMenuItem({
|
|
|
84
84
|
data-inset={inset}
|
|
85
85
|
data-variant={variant}
|
|
86
86
|
className={cn(
|
|
87
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs/relaxed [&_svg:not([class*='size-'])]:size-3.5 group/dropdown-menu-item relative flex cursor-pointer items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:
|
|
87
|
+
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs/relaxed [&_svg:not([class*='size-'])]:size-3.5 group/dropdown-menu-item relative flex cursor-pointer items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:ps-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
88
88
|
className,
|
|
89
89
|
)}
|
|
90
90
|
{...props}
|
|
@@ -109,13 +109,13 @@ function DropdownMenuSubTrigger({
|
|
|
109
109
|
data-slot="dropdown-menu-sub-trigger"
|
|
110
110
|
data-inset={inset}
|
|
111
111
|
className={cn(
|
|
112
|
-
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs [&_svg:not([class*='size-'])]:size-3.5 flex cursor-pointer items-center outline-hidden select-none data-[inset]:
|
|
112
|
+
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs [&_svg:not([class*='size-'])]:size-3.5 flex cursor-pointer items-center outline-hidden select-none data-[inset]:ps-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
113
113
|
className,
|
|
114
114
|
)}
|
|
115
115
|
{...props}
|
|
116
116
|
>
|
|
117
117
|
{children}
|
|
118
|
-
<ChevronRightIcon className="
|
|
118
|
+
<ChevronRightIcon className="ms-auto rtl:rotate-180" />
|
|
119
119
|
</MenuPrimitive.SubmenuTrigger>
|
|
120
120
|
);
|
|
121
121
|
}
|
|
@@ -123,7 +123,9 @@ function DropdownMenuSubTrigger({
|
|
|
123
123
|
function DropdownMenuSubContent({
|
|
124
124
|
align = "start",
|
|
125
125
|
alignOffset = -3,
|
|
126
|
-
|
|
126
|
+
// Base UI 1.6.0 `Side` accepts logical values: the submenu opens on the inline-end
|
|
127
|
+
// side of its trigger in both directions (identical to "right" under LTR).
|
|
128
|
+
side = "inline-end",
|
|
127
129
|
sideOffset = 0,
|
|
128
130
|
className,
|
|
129
131
|
...props
|
|
@@ -149,14 +151,14 @@ function DropdownMenuCheckboxItem({ className, children, checked, ...props }: Me
|
|
|
149
151
|
<MenuPrimitive.CheckboxItem
|
|
150
152
|
data-slot="dropdown-menu-checkbox-item"
|
|
151
153
|
className={cn(
|
|
152
|
-
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5
|
|
154
|
+
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5 pe-8 ps-2 text-xs [&_svg:not([class*='size-'])]:size-3.5 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
153
155
|
className,
|
|
154
156
|
)}
|
|
155
157
|
checked={checked}
|
|
156
158
|
{...props}
|
|
157
159
|
>
|
|
158
160
|
<span
|
|
159
|
-
className="pointer-events-none absolute
|
|
161
|
+
className="pointer-events-none absolute end-2 flex items-center justify-center pointer-events-none"
|
|
160
162
|
data-slot="dropdown-menu-checkbox-item-indicator"
|
|
161
163
|
>
|
|
162
164
|
<MenuPrimitive.CheckboxItemIndicator>
|
|
@@ -177,13 +179,13 @@ function DropdownMenuRadioItem({ className, children, ...props }: MenuPrimitive.
|
|
|
177
179
|
<MenuPrimitive.RadioItem
|
|
178
180
|
data-slot="dropdown-menu-radio-item"
|
|
179
181
|
className={cn(
|
|
180
|
-
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5
|
|
182
|
+
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground min-h-7 gap-2 rounded-md py-1.5 pe-8 ps-2 text-xs [&_svg:not([class*='size-'])]:size-3.5 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
181
183
|
className,
|
|
182
184
|
)}
|
|
183
185
|
{...props}
|
|
184
186
|
>
|
|
185
187
|
<span
|
|
186
|
-
className="pointer-events-none absolute
|
|
188
|
+
className="pointer-events-none absolute end-2 flex items-center justify-center pointer-events-none"
|
|
187
189
|
data-slot="dropdown-menu-radio-item-indicator"
|
|
188
190
|
>
|
|
189
191
|
<MenuPrimitive.RadioItemIndicator>
|
|
@@ -210,7 +212,7 @@ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"spa
|
|
|
210
212
|
<span
|
|
211
213
|
data-slot="dropdown-menu-shortcut"
|
|
212
214
|
className={cn(
|
|
213
|
-
"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground
|
|
215
|
+
"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ms-auto text-xs tracking-widest",
|
|
214
216
|
className,
|
|
215
217
|
)}
|
|
216
218
|
{...props}
|
|
@@ -121,7 +121,7 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
|
121
121
|
<p
|
|
122
122
|
data-slot="field-description"
|
|
123
123
|
className={cn(
|
|
124
|
-
"text-muted-foreground text-
|
|
124
|
+
"text-muted-foreground text-start text-xs/relaxed [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
|
|
125
125
|
"last:mt-0 nth-last-2:-mt-1",
|
|
126
126
|
"[&>a:hover]:text-primary",
|
|
127
127
|
className,
|
|
@@ -182,7 +182,7 @@ function FieldError({
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
return (
|
|
185
|
-
<ul className="
|
|
185
|
+
<ul className="ms-4 flex list-disc flex-col gap-1">
|
|
186
186
|
{uniqueErrors.map((error, index) => error?.message && <li key={index}>{error.message}</li>)}
|
|
187
187
|
</ul>
|
|
188
188
|
);
|
|
@@ -14,7 +14,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
14
14
|
data-slot="input-group"
|
|
15
15
|
role="group"
|
|
16
16
|
className={cn(
|
|
17
|
-
"border-input bg-input/20 dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 h-7 rounded-md border transition-colors has-data-[align=block-end]:rounded-md has-data-[align=block-start]:rounded-md has-[[data-slot=input-group-control]:focus-visible]:ring-[2px] has-[[data-slot][aria-invalid=true]]:ring-[2px] has-[textarea]:rounded-md has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:
|
|
17
|
+
"border-input bg-input/20 dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 h-7 rounded-md border transition-colors has-data-[align=block-end]:rounded-md has-data-[align=block-start]:rounded-md has-[[data-slot=input-group-control]:focus-visible]:ring-[2px] has-[[data-slot][aria-invalid=true]]:ring-[2px] has-[textarea]:rounded-md has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pe-1.5 has-[>[data-align=inline-start]]:[&>input]:ps-1.5 [[data-slot=combobox-content]_&]:focus-within:border-inherit [[data-slot=combobox-content]_&]:focus-within:ring-0 group/input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto",
|
|
18
18
|
className,
|
|
19
19
|
)}
|
|
20
20
|
{...props}
|
|
@@ -27,8 +27,8 @@ const inputGroupAddonVariants = cva(
|
|
|
27
27
|
{
|
|
28
28
|
variants: {
|
|
29
29
|
align: {
|
|
30
|
-
"inline-start": "
|
|
31
|
-
"inline-end": "
|
|
30
|
+
"inline-start": "ps-2 has-[>button]:ms-[-0.275rem] has-[>kbd]:ms-[-0.275rem] order-first",
|
|
31
|
+
"inline-end": "pe-2 has-[>button]:me-[-0.275rem] has-[>kbd]:me-[-0.275rem] order-last",
|
|
32
32
|
"block-start":
|
|
33
33
|
"px-2 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2 order-first w-full justify-start",
|
|
34
34
|
"block-end": "px-2 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2 order-last w-full justify-start",
|
|
@@ -28,6 +28,7 @@ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
28
28
|
return (
|
|
29
29
|
<div
|
|
30
30
|
data-slot="input-otp-group"
|
|
31
|
+
dir="ltr" /* rtl-ok: deliberate LTR island (otp) — one-time codes read LTR in RTL locales */
|
|
31
32
|
className={cn(
|
|
32
33
|
"has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive rounded-md has-aria-invalid:ring-[2px] flex items-center",
|
|
33
34
|
className,
|
|
@@ -52,6 +53,7 @@ function InputOTPSlot({
|
|
|
52
53
|
data-slot="input-otp-slot"
|
|
53
54
|
data-active={isActive}
|
|
54
55
|
className={cn(
|
|
56
|
+
// rtl-ok: LTR island — the group is dir="ltr", so first/last rounding and borders stay physical
|
|
55
57
|
"bg-input/20 dark:bg-input/30 border-input data-[active=true]:border-ring data-[active=true]:ring-ring/30 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive size-7 border-y border-r text-xs/relaxed transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:ring-[2px] relative flex items-center justify-center data-[active=true]:z-10",
|
|
56
58
|
className,
|
|
57
59
|
)}
|
|
@@ -62,7 +62,7 @@ function NavigationMenuTrigger({
|
|
|
62
62
|
<>
|
|
63
63
|
{" "}
|
|
64
64
|
<ChevronDownIcon
|
|
65
|
-
className="relative top-[1px]
|
|
65
|
+
className="relative top-[1px] ms-1 size-3 transition duration-300 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180"
|
|
66
66
|
aria-hidden="true"
|
|
67
67
|
/>
|
|
68
68
|
</>
|
|
@@ -139,7 +139,7 @@ function NavigationMenuIndicator({
|
|
|
139
139
|
)}
|
|
140
140
|
{...props}
|
|
141
141
|
>
|
|
142
|
-
<div className="bg-border rounded-
|
|
142
|
+
<div className="bg-border rounded-ss-sm shadow-md relative top-[60%] h-2 w-2 rotate-45" />
|
|
143
143
|
</NavigationMenuPrimitive.Icon>
|
|
144
144
|
);
|
|
145
145
|
}
|
|
@@ -48,7 +48,7 @@ function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
|
|
|
48
48
|
function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {
|
|
49
49
|
return (
|
|
50
50
|
<ProgressPrimitive.Value
|
|
51
|
-
className={cn("text-muted-foreground
|
|
51
|
+
className={cn("text-muted-foreground ms-auto text-xs/relaxed tabular-nums", className)}
|
|
52
52
|
data-slot="progress-value"
|
|
53
53
|
{...props}
|
|
54
54
|
/>
|
|
@@ -24,6 +24,7 @@ function RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {
|
|
|
24
24
|
data-slot="radio-group-indicator"
|
|
25
25
|
className="group-aria-invalid/radio-group-item:text-destructive flex size-4 items-center justify-center text-white"
|
|
26
26
|
>
|
|
27
|
+
{/* rtl-ok: symmetric centering (`left-1/2` + `-translate-x-1/2`) — identical in LTR and RTL */}
|
|
27
28
|
<CircleIcon className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-current" />
|
|
28
29
|
</RadioPrimitive.Indicator>
|
|
29
30
|
</RadioPrimitive.Root>
|
|
@@ -44,6 +44,7 @@ function ResizableHandle({
|
|
|
44
44
|
"aria-[orientation=vertical]:h-full aria-[orientation=vertical]:w-px",
|
|
45
45
|
"aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full",
|
|
46
46
|
// Hit area for dragging (wider than visible line)
|
|
47
|
+
// rtl-ok: symmetric centering — react-resizable-panels is order-based, the handle sits on the axis midpoint
|
|
47
48
|
"after:absolute after:inset-y-0 after:left-1/2 after:w-3 after:-translate-x-1/2",
|
|
48
49
|
"aria-[orientation=vertical]:after:inset-y-0 aria-[orientation=vertical]:after:w-3",
|
|
49
50
|
"aria-[orientation=horizontal]:after:inset-x-0 aria-[orientation=horizontal]:after:h-3 aria-[orientation=horizontal]:after:inset-y-auto",
|
|
@@ -27,7 +27,7 @@ function ScrollBar({ className, orientation = "vertical", ...props }: ScrollArea
|
|
|
27
27
|
data-orientation={orientation}
|
|
28
28
|
orientation={orientation}
|
|
29
29
|
className={cn(
|
|
30
|
-
"data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-
|
|
30
|
+
"data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-s data-vertical:border-s-transparent flex touch-none p-px transition-colors select-none",
|
|
31
31
|
className,
|
|
32
32
|
)}
|
|
33
33
|
{...props}
|
|
@@ -14,7 +14,7 @@ function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
|
|
|
14
14
|
|
|
15
15
|
function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
|
|
16
16
|
return (
|
|
17
|
-
<SelectPrimitive.Value data-slot="select-value" className={cn("flex flex-1 text-
|
|
17
|
+
<SelectPrimitive.Value data-slot="select-value" className={cn("flex flex-1 text-start", className)} {...props} />
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -106,7 +106,7 @@ function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Prop
|
|
|
106
106
|
{children}
|
|
107
107
|
</SelectPrimitive.ItemText>
|
|
108
108
|
<SelectPrimitive.ItemIndicator
|
|
109
|
-
render={<span className="pointer-events-none absolute
|
|
109
|
+
render={<span className="pointer-events-none absolute end-2 flex items-center justify-center" />}
|
|
110
110
|
>
|
|
111
111
|
<CheckIcon className="pointer-events-none" />
|
|
112
112
|
</SelectPrimitive.ItemIndicator>
|