mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
fix: input-group don't have the proper validation attributes (#44703)
## Problem The input groups components introduced in #44282 don't have the validation attributes when invalid. This hurts accessibility and also break the design: <img width="1730" height="324" alt="image" src="https://github.com/user-attachments/assets/a3fb8d86-f3a8-46bb-aa53-d0599c11f056" /> ## Solution This is because the wrapper `<FormControl_Shadcn_>` passes the validation props to its direct child. The solution is to avoid applying them on the `<InputGroup>` and to apply them manually on the inputs. I also fixed a small accessibility issue by moving the addon texts after the input so that screen readers announce them in the correct order. No visual change for this <img width="587" height="158" alt="image" src="https://github.com/user-attachments/assets/1f8858ea-6659-45f9-964e-8c43a7fe14ba" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Unified numeric input layout by moving unit labels/suffixes (e.g., "seconds", "GB", "%", "connections", "digits", "IOPS", "MB/s", "rows") to appear after their inputs for a consistent, predictable form appearance. * **Accessibility** * Form controls now expose IDs and ARIA attributes from form context when available, improving screen-reader descriptions and error association. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
This commit is contained in:
1 parent
bf46092290
commit
d95fdfd566
23 files changed
+330
-248
No files matched your search
@@ -13,12 +13,12 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
FormInputGroupTextArea,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
Popover_Shadcn_,
|
||||
PopoverContent_Shadcn_,
|
||||
PopoverTrigger_Shadcn_,
|
||||
@@ -237,7 +237,13 @@ export default function FormPatternsPageLayout() {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupInput {...field} type="number" min={5} max={30} />
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
type="number"
|
||||
min={5}
|
||||
max={30}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText className="font-mono">MB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
@@ -285,7 +291,7 @@ export default function FormPatternsPageLayout() {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea
|
||||
<FormInputGroupTextArea
|
||||
{...field}
|
||||
rows={4}
|
||||
placeholder="Enter multi-line text"
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
@@ -250,7 +251,7 @@ export default function FormPatternsSidePanel() {
|
||||
>
|
||||
<FormControl_Shadcn_ className="col-span-6">
|
||||
<InputGroup>
|
||||
<InputGroupInput {...field} type="number" min={5} max={30} />
|
||||
<FormInputGroupInput {...field} type="number" min={5} max={30} />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>MB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
Calendar,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
Popover_Shadcn_,
|
||||
PopoverContent_Shadcn_,
|
||||
PopoverTrigger_Shadcn_,
|
||||
@@ -229,17 +229,17 @@ const FormField = ({
|
||||
<FormControl_Shadcn_ className="col-span-6">
|
||||
{properties.units ? (
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
|
||||
{properties.units}
|
||||
</ReactMarkdown>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
id={name}
|
||||
type="number"
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
|
||||
{properties.units}
|
||||
</ReactMarkdown>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
) : (
|
||||
<Input_Shadcn_
|
||||
|
||||
+2
-2
@@ -11,11 +11,11 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
RadioGroupStacked,
|
||||
RadioGroupStackedItem,
|
||||
@@ -296,7 +296,7 @@ export const CreateOrUpdateCustomProviderSheet = ({
|
||||
<InputGroupAddon align="inline-start">
|
||||
<InputGroupText>custom:</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
placeholder="my-company"
|
||||
disabled={isEditMode}
|
||||
|
||||
@@ -14,10 +14,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
@@ -374,16 +374,16 @@ export const MfaAuthSettingsForm = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>factors</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
max={30}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>factors</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -481,16 +481,16 @@ export const MfaAuthSettingsForm = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>digits</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={6}
|
||||
max={30}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || !hasAccessToMFA}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>digits</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -11,9 +11,9 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
@@ -226,22 +226,22 @@ export const PerformanceSettingsForm = () => {
|
||||
}
|
||||
>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FormControl_Shadcn_>
|
||||
<div className="relative">
|
||||
<div className="relative">
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={5}
|
||||
max={30}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || promptUpgrade}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</div>
|
||||
</FormControl_Shadcn_>
|
||||
</FormControl_Shadcn_>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-right text-foreground-muted">
|
||||
10+ seconds recommended
|
||||
@@ -368,16 +368,11 @@ export const PerformanceSettingsForm = () => {
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="relative">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="relative">
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>
|
||||
{chosenUnit === 'percent' ? '%' : 'connections'}
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
{...field}
|
||||
min={3}
|
||||
@@ -388,24 +383,29 @@ export const PerformanceSettingsForm = () => {
|
||||
}
|
||||
disabled={!canUpdateConfig || promptUpgrade}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>
|
||||
{chosenUnit === 'percent' ? '%' : 'connections'}
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</div>
|
||||
{isLoadingMaxConns ? (
|
||||
<ShimmeringLoader className="py-2 w-16 ml-auto" />
|
||||
) : (
|
||||
<p className="text-xs text-right text-foreground-muted">
|
||||
<span className="text-foreground-light">
|
||||
{chosenUnit === 'percent'
|
||||
? Math.floor(
|
||||
maxConnectionLimit * (Math.min(100, field.value!) / 100)
|
||||
).toString()
|
||||
: Math.min(maxConnectionLimit, field.value!)}
|
||||
</span>{' '}
|
||||
/ {maxConnectionLimit}
|
||||
</p>
|
||||
)}
|
||||
</FormControl_Shadcn_>
|
||||
</div>
|
||||
</FormControl_Shadcn_>
|
||||
{isLoadingMaxConns ? (
|
||||
<ShimmeringLoader className="py-2 w-16 ml-auto" />
|
||||
) : (
|
||||
<p className="text-xs text-right text-foreground-muted">
|
||||
<span className="text-foreground-light">
|
||||
{chosenUnit === 'percent'
|
||||
? Math.floor(
|
||||
maxConnectionLimit * (Math.min(100, field.value!) / 100)
|
||||
).toString()
|
||||
: Math.min(maxConnectionLimit, field.value!)}
|
||||
</span>{' '}
|
||||
/ {maxConnectionLimit}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -13,9 +13,9 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Switch,
|
||||
Tooltip,
|
||||
@@ -238,15 +238,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>emails/h</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || !canUpdateEmailLimit}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>emails/h</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
@@ -309,15 +309,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>sms/h</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || !canUpdateSMSRateLimit}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>sms/h</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
@@ -358,15 +358,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
@@ -406,15 +406,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
@@ -454,15 +454,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/h</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || !canUpdateAnonymousUsersRateLimit}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/h</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
@@ -501,15 +501,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
@@ -549,15 +549,15 @@ export const RateLimits = () => {
|
||||
<TooltipTrigger asChild>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || !canUpdateWeb3RateLimit}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>requests/5 min</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</TooltipTrigger>
|
||||
|
||||
+17
-17
@@ -12,9 +12,9 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Switch,
|
||||
} from 'ui'
|
||||
@@ -242,15 +242,15 @@ export const SessionsAuthSettingsForm = () => {
|
||||
>
|
||||
<FormControl_Shadcn_ className="w-full">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -329,17 +329,17 @@ export const SessionsAuthSettingsForm = () => {
|
||||
>
|
||||
<FormControl_Shadcn_ className="w-full">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>
|
||||
<HoursOrNeverText value={field.value || 0} />
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
disabled={!canUpdateConfig || !hasUserSessionsEntitlement}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>
|
||||
<HoursOrNeverText value={field.value || 0} />
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -359,17 +359,17 @@ export const SessionsAuthSettingsForm = () => {
|
||||
>
|
||||
<FormControl_Shadcn_ className="w-full">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>
|
||||
<HoursOrNeverText value={field.value || 0} />
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
{...field}
|
||||
className="flex-1"
|
||||
disabled={!canUpdateConfig || !hasUserSessionsEntitlement}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>
|
||||
<HoursOrNeverText value={field.value || 0} />
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Switch,
|
||||
} from 'ui'
|
||||
@@ -396,15 +396,15 @@ export const SmtpForm = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
value={field.value}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
+21
-21
@@ -8,9 +8,9 @@ import {
|
||||
Badge,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
@@ -71,16 +71,16 @@ export const AdvancedSettings = ({
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>milliseconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? ''}
|
||||
onChange={handleNumberChange(field)}
|
||||
placeholder="Default: 10000"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>milliseconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -105,16 +105,16 @@ export const AdvancedSettings = ({
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>workers</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? ''}
|
||||
onChange={handleNumberChange(field)}
|
||||
placeholder="Default: 4"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>workers</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -142,16 +142,16 @@ export const AdvancedSettings = ({
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? ''}
|
||||
onChange={handleNumberChange(field)}
|
||||
placeholder="Default: 2"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -217,16 +217,16 @@ export const AdvancedSettings = ({
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? ''}
|
||||
onChange={handleNumberChange(field)}
|
||||
placeholder="Default: 4"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -260,16 +260,16 @@ export const AdvancedSettings = ({
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>minutes</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? ''}
|
||||
onChange={handleNumberChange(field)}
|
||||
placeholder="Default: None (No staleness limit)"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>minutes</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
cn,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
} from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
@@ -70,10 +70,7 @@ export const AutoScaleFields = ({ form }: AutoScaleFieldProps) => {
|
||||
>
|
||||
<FormControl_Shadcn_ className="max-w-20">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>%</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? undefined}
|
||||
@@ -90,6 +87,9 @@ export const AutoScaleFields = ({ form }: AutoScaleFieldProps) => {
|
||||
}}
|
||||
placeholder={String(DISK_AUTOSCALE_CONFIG_DEFAULTS.growthPercent)}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>%</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -116,10 +116,7 @@ export const AutoScaleFields = ({ form }: AutoScaleFieldProps) => {
|
||||
>
|
||||
<FormControl_Shadcn_ className="max-w-32">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? undefined}
|
||||
@@ -136,6 +133,9 @@ export const AutoScaleFields = ({ form }: AutoScaleFieldProps) => {
|
||||
}}
|
||||
placeholder={String(DISK_AUTOSCALE_CONFIG_DEFAULTS.minIncrementSize)}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -157,10 +157,7 @@ export const AutoScaleFields = ({ form }: AutoScaleFieldProps) => {
|
||||
>
|
||||
<FormControl_Shadcn_ className="max-w-32">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
value={field.value ?? undefined}
|
||||
@@ -173,6 +170,9 @@ export const AutoScaleFields = ({ form }: AutoScaleFieldProps) => {
|
||||
}}
|
||||
placeholder={String(DISK_AUTOSCALE_CONFIG_DEFAULTS.maxSizeGb)}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -6,10 +6,10 @@ import {
|
||||
Button,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
} from 'ui'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
@@ -100,6 +100,22 @@ export function DiskSizeField({
|
||||
<FormItemLayout label="Disk Size" layout="vertical" id={field.name}>
|
||||
<FormControl_Shadcn_ className="max-w-32">
|
||||
<InputGroup>
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
id={field.name}
|
||||
{...field}
|
||||
disabled={disableInput || isError}
|
||||
onWheel={(e) => e.currentTarget.blur()}
|
||||
onChange={(e) => {
|
||||
setValue('totalSize', e.target.valueAsNumber, {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
})
|
||||
trigger('provisionedIOPS')
|
||||
trigger('throughput')
|
||||
}}
|
||||
min={includedDiskGB}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
{isDirty ? (
|
||||
@@ -118,22 +134,6 @@ export function DiskSizeField({
|
||||
</InputGroupButton>
|
||||
) : null}
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
type="number"
|
||||
id={field.name}
|
||||
{...field}
|
||||
disabled={disableInput || isError}
|
||||
onWheel={(e) => e.currentTarget.blur()}
|
||||
onChange={(e) => {
|
||||
setValue('totalSize', e.target.valueAsNumber, {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
})
|
||||
trigger('provisionedIOPS')
|
||||
trigger('throughput')
|
||||
}}
|
||||
min={includedDiskGB}
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
Button,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from 'ui'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
|
||||
@@ -107,8 +107,7 @@ export function IOPSField({ form, disableInput }: IOPSFieldProps) {
|
||||
>
|
||||
<FormControl_Shadcn_ className="max-w-32">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">IOPS</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
{...field}
|
||||
value={field.value}
|
||||
@@ -120,6 +119,7 @@ export function IOPSField({ form, disableInput }: IOPSFieldProps) {
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">IOPS</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -6,9 +6,9 @@ import { UseFormReturn } from 'react-hook-form'
|
||||
import {
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
} from 'ui'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
@@ -120,10 +120,7 @@ export function ThroughputField({ form, disableInput }: ThroughputFieldProps) {
|
||||
>
|
||||
<FormControl_Shadcn_ className="max-w-32">
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>MB/s</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
type="number"
|
||||
{...field}
|
||||
value={field.value}
|
||||
@@ -135,6 +132,9 @@ export function ThroughputField({ form, disableInput }: ThroughputFieldProps) {
|
||||
}}
|
||||
disabled={disableInput || disableIopsInput || watchedStorageType === 'io2'}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>MB/s</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -35,10 +35,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Modal,
|
||||
} from 'ui'
|
||||
@@ -329,10 +329,7 @@ const JWTSettings = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
id="JWT_EXP"
|
||||
type="number"
|
||||
@@ -344,6 +341,9 @@ const JWTSettings = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>seconds</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
FormMessage_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Switch,
|
||||
} from 'ui'
|
||||
@@ -278,15 +278,15 @@ export const RealtimeSettings = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
disabled={!canUpdateConfig}
|
||||
value={field.value || ''}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -314,15 +314,15 @@ export const RealtimeSettings = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>clients</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
disabled={!canUpdateConfig}
|
||||
value={field.value || ''}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>clients</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -341,15 +341,15 @@ export const RealtimeSettings = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>events/s</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
disabled={!isUsageBillingEnabled || !canUpdateConfig}
|
||||
value={field.value || ''}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>events/s</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -395,15 +395,15 @@ export const RealtimeSettings = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>events/s</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
disabled={!isUsageBillingEnabled || !canUpdateConfig}
|
||||
value={field.value || ''}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>events/s</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -449,15 +449,15 @@ export const RealtimeSettings = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>KB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
disabled={!isUsageBillingEnabled || !canUpdateConfig}
|
||||
value={field.value || ''}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>KB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -15,10 +15,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
FormItem_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Skeleton,
|
||||
Switch,
|
||||
@@ -611,16 +611,16 @@ export const PostgrestConfig = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>rows</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
size="small"
|
||||
disabled={!canUpdatePostgrestConfig}
|
||||
{...field}
|
||||
type="number"
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>rows</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
@@ -641,10 +641,7 @@ export const PostgrestConfig = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
size="small"
|
||||
disabled={!canUpdatePostgrestConfig}
|
||||
{...field}
|
||||
@@ -657,6 +654,9 @@ export const PostgrestConfig = () => {
|
||||
}
|
||||
value={field.value === null ? '' : field.value}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
+9
-9
@@ -15,9 +15,9 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Separator,
|
||||
} from 'ui'
|
||||
@@ -266,10 +266,7 @@ export const ConnectionPooling = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
className="w-full"
|
||||
@@ -283,6 +280,9 @@ export const ConnectionPooling = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>connections</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
{!!maxConnData &&
|
||||
@@ -330,10 +330,7 @@ export const ConnectionPooling = () => {
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>clients</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type="number"
|
||||
className="w-full"
|
||||
@@ -347,6 +344,9 @@ export const ConnectionPooling = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>clients</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
|
||||
@@ -15,10 +15,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
InfoIcon,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
Modal,
|
||||
WarningIcon,
|
||||
@@ -195,19 +195,19 @@ const DiskSizeConfigurationModal = ({
|
||||
layout="vertical"
|
||||
label="New disk size"
|
||||
>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroupInput
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroup>
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
id="new-disk-size"
|
||||
type="number"
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</InputGroup>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>GB</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
+31
-27
@@ -10,10 +10,10 @@ import {
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
Input_Shadcn_,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
SelectItem_Shadcn_,
|
||||
@@ -256,14 +256,16 @@ export const CreateTableSheet = ({ open, onOpenChange }: CreateTableSheetProps)
|
||||
control={form.control}
|
||||
name={`columns.${idx}.name`}
|
||||
render={({ field }) => (
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="Provide a column name"
|
||||
disabled={isCreating}
|
||||
className="h-auto"
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
<FormItemLayout>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="Provide a column name"
|
||||
disabled={isCreating}
|
||||
className="h-auto"
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
<FormField_Shadcn_
|
||||
@@ -308,26 +310,28 @@ export const CreateTableSheet = ({ open, onOpenChange }: CreateTableSheetProps)
|
||||
key={`columns.${idx}.${x.name}`}
|
||||
name={`columns.${idx}.${x.name}` as any}
|
||||
render={({ field }) => (
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-start">
|
||||
{x.name}
|
||||
</InputGroupAddon>
|
||||
<FormItemLayout>
|
||||
<FormControl_Shadcn_>
|
||||
<InputGroupInput
|
||||
{...field}
|
||||
type={x.type === 'number' ? 'number' : 'text'}
|
||||
disabled={isCreating}
|
||||
className="h-[34px] rounded-l-none"
|
||||
onChange={(event) =>
|
||||
field.onChange(
|
||||
isNaN(event.target.valueAsNumber)
|
||||
? null
|
||||
: event.target.valueAsNumber
|
||||
)
|
||||
}
|
||||
/>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-start">
|
||||
{x.name}
|
||||
</InputGroupAddon>
|
||||
<FormInputGroupInput
|
||||
{...field}
|
||||
type={x.type === 'number' ? 'number' : 'text'}
|
||||
disabled={isCreating}
|
||||
className="h-[34px] rounded-l-none"
|
||||
onChange={(event) =>
|
||||
field.onChange(
|
||||
isNaN(event.target.valueAsNumber)
|
||||
? null
|
||||
: event.target.valueAsNumber
|
||||
)
|
||||
}
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormControl_Shadcn_>
|
||||
</InputGroup>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -142,6 +142,8 @@ export {
|
||||
FormMessage as FormMessage_Shadcn_,
|
||||
FormField as FormField_Shadcn_,
|
||||
useWatch as useWatch_Shadcn_,
|
||||
FormInputGroupInput,
|
||||
FormInputGroupTextArea,
|
||||
} from './src/components/shadcn/ui/form'
|
||||
|
||||
export {
|
||||
|
||||
@@ -15,7 +15,10 @@ import {
|
||||
} from 'react-hook-form'
|
||||
|
||||
import { cn } from '../../../lib/utils/cn'
|
||||
import type { InputProps } from './input'
|
||||
import { InputGroupInput, InputGroupTextarea } from './input-group'
|
||||
import { Label } from './label'
|
||||
import type { TextareaProps } from './textarea'
|
||||
|
||||
const Form = FormProvider
|
||||
|
||||
@@ -179,6 +182,32 @@ const FormMessage = React.forwardRef<
|
||||
|
||||
FormMessage.displayName = 'FormMessage'
|
||||
|
||||
function FormInputGroupInput(props: InputProps) {
|
||||
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
||||
|
||||
return (
|
||||
<InputGroupInput
|
||||
id={formItemId}
|
||||
aria-describedby={!error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`}
|
||||
aria-invalid={!!error}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function FormInputGroupTextArea(props: TextareaProps) {
|
||||
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
||||
|
||||
return (
|
||||
<InputGroupTextarea
|
||||
id={formItemId}
|
||||
aria-describedby={!error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`}
|
||||
aria-invalid={!!error}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
Form,
|
||||
FormControl,
|
||||
@@ -188,5 +217,7 @@ export {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
useFormField,
|
||||
FormInputGroupInput,
|
||||
FormInputGroupTextArea,
|
||||
useWatch,
|
||||
}
|
||||
@@ -6,7 +6,39 @@ import { Button } from '../../Button'
|
||||
import { Input, type InputProps } from './input'
|
||||
import { Textarea, type TextareaProps } from './textarea'
|
||||
|
||||
function InputGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
||||
interface InputGroupProps extends React.ComponentProps<'div'> {
|
||||
/**
|
||||
* This props is passed in by <FormControl_Shadcn_> but they should be applied on the input itself. When using
|
||||
* <InputGroup> inside a <Form_Shadcn_>, use <FormInputGroupInput> and <FormInputGroupTextArea> instead of the
|
||||
* regular <Input> and <Textarea> components.
|
||||
*/
|
||||
id?: string
|
||||
/**
|
||||
* This props is passed in by <FormControl_Shadcn_> but they should be applied on the input itself. When using
|
||||
* <InputGroup> inside a <Form_Shadcn_>, use <FormInputGroupInput> and <FormInputGroupTextArea> instead of the
|
||||
* regular <Input> and <Textarea> components.
|
||||
*/
|
||||
'aria-invalid'?: React.AriaAttributes['aria-invalid']
|
||||
/**
|
||||
* This props is passed in by <FormControl_Shadcn_> but they should be applied on the input itself. When using
|
||||
* <InputGroup> inside a <Form_Shadcn_>, use <FormInputGroupInput> and <FormInputGroupTextArea> instead of the
|
||||
* regular <Input> and <Textarea> components.
|
||||
*/
|
||||
'aria-describedby'?: string
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to group input elements together with addons like labels, buttons, or text. When using this component
|
||||
* inside a <Form_Shadcn_>, use FormInputGroupInput and FormInputGroupTextArea instead of the regular Input
|
||||
* and Textarea components to ensure proper form field association and accessibility.
|
||||
*/
|
||||
function InputGroup({
|
||||
className,
|
||||
id,
|
||||
'aria-invalid': ariaInvalid,
|
||||
'aria-describedby': ariaDescribedby,
|
||||
...props
|
||||
}: InputGroupProps) {
|
||||
return (
|
||||
<div
|
||||
data-slot="input-group"
|
||||
@@ -123,6 +155,9 @@ function InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* If you need to use this component inside a <Form_Shadcn_>, use FormInputGroupInput instead.
|
||||
*/
|
||||
function InputGroupInput({ className, ...props }: InputProps) {
|
||||
return (
|
||||
<Input
|
||||
@@ -136,6 +171,9 @@ function InputGroupInput({ className, ...props }: InputProps) {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* If you need to use this component inside a <Form_Shadcn_>, use FormInputGroupTextArea instead.
|
||||
*/
|
||||
function InputGroupTextarea({ className, ...props }: TextareaProps) {
|
||||
return (
|
||||
<Textarea
|
||||
|
||||
Reference in new issue
Block a user