diff --git a/bun.lockb b/bun.lockb
index 804b7f34..961603e4 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/components/docs/colors/color-field/color-field-validation-demo.tsx b/components/docs/colors/color-field/color-field-validation-demo.tsx
new file mode 100644
index 00000000..2329b351
--- /dev/null
+++ b/components/docs/colors/color-field/color-field-validation-demo.tsx
@@ -0,0 +1,16 @@
+"use client"
+
+import { Button, ColorField, Form } from "ui"
+
+export default function ColorFieldValidationDemo() {
+ function submit(e: React.FormEvent) {
+ e.preventDefault()
+ }
+
+ return (
+
diff --git a/components/docs/date-and-time/time-field/time-field-prefix-demo.tsx b/components/docs/date-and-time/time-field/time-field-prefix-demo.tsx
new file mode 100644
index 00000000..e20ead13
--- /dev/null
+++ b/components/docs/date-and-time/time-field/time-field-prefix-demo.tsx
@@ -0,0 +1,8 @@
+"use client"
+
+import { Time } from "@internationalized/date"
+import { TimeField } from "ui"
+
+export default function TimeFieldPrefixDemo() {
+ return
+}
diff --git a/components/docs/date-and-time/time-field/time-field-readonly-demo.tsx b/components/docs/date-and-time/time-field/time-field-readonly-demo.tsx
new file mode 100644
index 00000000..58924353
--- /dev/null
+++ b/components/docs/date-and-time/time-field/time-field-readonly-demo.tsx
@@ -0,0 +1,8 @@
+"use client"
+
+import { Time } from "@internationalized/date"
+import { TimeField } from "ui"
+
+export default function TimeFieldReadonlyDemo() {
+ return
+}
diff --git a/components/docs/date-and-time/time-field/time-field-suffix-demo.tsx b/components/docs/date-and-time/time-field/time-field-suffix-demo.tsx
new file mode 100644
index 00000000..d335a6f0
--- /dev/null
+++ b/components/docs/date-and-time/time-field/time-field-suffix-demo.tsx
@@ -0,0 +1,9 @@
+"use client"
+
+import { Time } from "@internationalized/date"
+import { IconClock } from "justd-icons"
+import { TimeField } from "ui"
+
+export default function TimeFieldSuffixDemo() {
+ return
} defaultValue={new Time()} label="Event time" />
+}
diff --git a/components/docs/forms/number-field/number-field-invalid-demo.tsx b/components/docs/forms/number-field/number-field-invalid-demo.tsx
index 2a56d03e..ddd2df7d 100644
--- a/components/docs/forms/number-field/number-field-invalid-demo.tsx
+++ b/components/docs/forms/number-field/number-field-invalid-demo.tsx
@@ -1,7 +1,12 @@
"use client"
-import { NumberField } from "ui"
+import { Button, Form, NumberField } from "ui"
export default function NumberFieldInvalidDemo() {
- return
+ return (
+
+ )
}
diff --git a/components/docs/forms/text-field/text-field-disabled-demo.tsx b/components/docs/forms/text-field/text-field-disabled-demo.tsx
index 9ad9fc4a..1e7a5fb5 100644
--- a/components/docs/forms/text-field/text-field-disabled-demo.tsx
+++ b/components/docs/forms/text-field/text-field-disabled-demo.tsx
@@ -3,5 +3,5 @@
import { TextField } from "ui"
export default function TextFieldDisabledDemo() {
- return
+ return
}
diff --git a/components/docs/forms/text-field/text-field-validation-demo.tsx b/components/docs/forms/text-field/text-field-validation-demo.tsx
index 2a5b9d3f..9113bc6b 100644
--- a/components/docs/forms/text-field/text-field-validation-demo.tsx
+++ b/components/docs/forms/text-field/text-field-validation-demo.tsx
@@ -4,8 +4,8 @@ import { Button, Form, TextField } from "ui"
export default function TextFieldValidationDemo() {
return (
-
)
diff --git a/components/docs/forms/textarea/textarea-validation-demo.tsx b/components/docs/forms/textarea/textarea-validation-demo.tsx
index 31df2a34..ac92e487 100644
--- a/components/docs/forms/textarea/textarea-validation-demo.tsx
+++ b/components/docs/forms/textarea/textarea-validation-demo.tsx
@@ -7,8 +7,8 @@ import { Button, Form, Textarea } from "ui"
export default function TextareaValidationDemo() {
const [value, setValue] = React.useState("")
return (
-
)
diff --git a/components/docs/generated/previews.ts b/components/docs/generated/previews.ts
index 63c61fa5..bec5d403 100644
--- a/components/docs/generated/previews.ts
+++ b/components/docs/generated/previews.ts
@@ -8,12 +8,24 @@ export const previews: Record
= {
"date-and-time/date-field/date-field-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-demo")),
},
+ "date-and-time/date-field/date-field-prefix-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-prefix-demo")),
+ },
"date-and-time/date-field/date-field-controlled-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-controlled-demo")),
},
+ "date-and-time/date-field/date-field-suffix-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-suffix-demo")),
+ },
+ "date-and-time/date-field/date-field-uncontrolled-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-uncontrolled-demo")),
+ },
"date-and-time/date-field/date-field-disabled-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-disabled-demo")),
},
+ "date-and-time/date-field/date-field-readonly-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-field-readonly-demo")),
+ },
"date-and-time/date-field/date-time-field-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/date-field/date-time-field-demo")),
},
@@ -50,14 +62,11 @@ export const previews: Record = {
"date-and-time/time-field/time-field-disabled-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-disabled-demo")),
},
- "date-and-time/time-field/date-field-controlled-demo": {
- component: React.lazy(() => import("@/components/docs/date-and-time/time-field/date-field-controlled-demo")),
- },
"date-and-time/time-field/time-field-validation-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-validation-demo")),
},
- "date-and-time/time-field/date-field-disabled-demo": {
- component: React.lazy(() => import("@/components/docs/date-and-time/time-field/date-field-disabled-demo")),
+ "date-and-time/time-field/time-field-suffix-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-suffix-demo")),
},
"date-and-time/time-field/time-field-hc-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-hc-demo")),
@@ -65,8 +74,11 @@ export const previews: Record = {
"date-and-time/time-field/time-field-controlled-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-controlled-demo")),
},
- "date-and-time/time-field/date-field-validation-demo": {
- component: React.lazy(() => import("@/components/docs/date-and-time/time-field/date-field-validation-demo")),
+ "date-and-time/time-field/time-field-prefix-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-prefix-demo")),
+ },
+ "date-and-time/time-field/time-field-readonly-demo": {
+ component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-readonly-demo")),
},
"date-and-time/time-field/time-field-demo": {
component: React.lazy(() => import("@/components/docs/date-and-time/time-field/time-field-demo")),
@@ -890,6 +902,9 @@ export const previews: Record = {
"colors/color-field/color-field-with-prefix-demo": {
component: React.lazy(() => import("@/components/docs/colors/color-field/color-field-with-prefix-demo")),
},
+ "colors/color-field/color-field-validation-demo": {
+ component: React.lazy(() => import("@/components/docs/colors/color-field/color-field-validation-demo")),
+ },
"colors/color-field/color-field-with-suffix-demo": {
component: React.lazy(() => import("@/components/docs/colors/color-field/color-field-with-suffix-demo")),
},
diff --git a/components/table-of-contents.tsx b/components/table-of-contents.tsx
index fb3084c6..da3f0841 100644
--- a/components/table-of-contents.tsx
+++ b/components/table-of-contents.tsx
@@ -112,7 +112,7 @@ function TocLink({ item, activeId }: { item: TableOfContentsProps; activeId: str
) {
- const { resolvedTheme, theme, setTheme } = useTheme()
+ const { theme, setTheme } = useTheme()
+ const [mounted, setMounted] = useState(false)
+
+ useEffect(() => {
+ setMounted(true)
+ }, [])
const toggleTheme = () => {
const nextTheme = theme === "light" ? "dark" : theme === "dark" ? "system" : "light"
setTheme(nextTheme)
}
+ if (!mounted) return null
+
return (
)
}
diff --git a/components/ui/color-field.tsx b/components/ui/color-field.tsx
index b5a1f8b6..33f73d4d 100644
--- a/components/ui/color-field.tsx
+++ b/components/ui/color-field.tsx
@@ -10,7 +10,7 @@ import { ColorField as ColorFieldPrimitive } from "react-aria-components"
import { ColorPicker } from "./color-picker"
import { ColorSwatch } from "./color-swatch"
-import { Description, FieldError, FieldGroup, fieldGroupPrefixStyles, Input, Label } from "./field"
+import { Description, FieldError, FieldGroup, Input, Label } from "./field"
import { ctr } from "./primitive"
interface ColorFieldProps extends ColorFieldPrimitiveProps {
@@ -47,10 +47,7 @@ const ColorField = ({
)}
>
{label && }
-
+
{prefix ? (
{prefix}
@@ -58,7 +55,7 @@ const ColorField = ({
) : null}
{value && (
-
+
{enableColorPicker ? (
) : (
diff --git a/components/ui/color-picker.tsx b/components/ui/color-picker.tsx
index a86e796d..c44903ad 100644
--- a/components/ui/color-picker.tsx
+++ b/components/ui/color-picker.tsx
@@ -21,7 +21,7 @@ import { focusButtonStyles } from "./primitive"
const buttonStyles = tv({
extend: focusButtonStyles,
- base: "flex cursor-pointer disabled:cursor-default disabled:opacity-50 items-center rounded text-sm"
+ base: "flex btn-trigger cursor-pointer disabled:cursor-default disabled:opacity-50 items-center rounded text-sm"
})
export interface ColorPickerProps extends ColorPickerPrimitiveProps {
diff --git a/components/ui/date-field.tsx b/components/ui/date-field.tsx
index 90b3a395..2cb2ccee 100644
--- a/components/ui/date-field.tsx
+++ b/components/ui/date-field.tsx
@@ -1,5 +1,7 @@
"use client"
+import * as React from "react"
+
import {
DateField as DateFieldPrimitive,
type DateFieldProps as DateFieldPrimitiveProps,
@@ -11,25 +13,36 @@ import {
} from "react-aria-components"
import { tv } from "tailwind-variants"
-import { Description, FieldError, fieldGroupStyles, Label } from "./field"
-import { cn, cr, ctr } from "./primitive"
+import { Description, FieldError, FieldGroup, Label } from "./field"
+import { cn, ctr } from "./primitive"
interface DateFieldProps extends DateFieldPrimitiveProps {
label?: string
description?: string
errorMessage?: string | ((validation: ValidationResult) => string)
+ prefix?: React.ReactNode
+ suffix?: React.ReactNode
}
const DateField = ({
+ prefix,
+ suffix,
label,
description,
errorMessage,
...props
}: DateFieldProps) => {
return (
-
+
{label && }
-
+
+ {prefix ? {prefix} : null}
+
+ {suffix ? {suffix} : null}
+
{description && {description}}
{errorMessage}
@@ -37,7 +50,7 @@ const DateField = ({
}
const segmentStyles = tv({
- base: "inline shrink-0 tabular-nums rounded p-0.5 tracking-wider text-fg caret-transparent outline outline-0 forced-color-adjust-none type-literal:px-0 lg:text-sm forced-colors:text-[ButtonText]",
+ base: "inline shrink-0 sm:uppercase tabular-nums rounded p-0.5 tracking-wider text-fg caret-transparent outline outline-0 forced-color-adjust-none type-literal:px-0 lg:text-sm forced-colors:text-[ButtonText]",
variants: {
isPlaceholder: {
true: "text-muted-fg"
@@ -54,17 +67,12 @@ const segmentStyles = tv({
}
})
-const DateInput = (props: Omit) => {
+const DateInput = ({ className, ...props }: Omit) => {
return (
- fieldGroupStyles({
- ...renderProps,
- className: cn(
- "min-w-sm block disabled:bg-secondary uppercase w-full py-2 px-2.5 text-base lg:text-sm/[1.4rem]",
- className
- )
- })
+ className={cn(
+ "bg-transparent p-2 text-base text-fg placeholder-muted-fg lg:text-sm",
+ className
)}
{...props}
>
diff --git a/components/ui/date-picker.tsx b/components/ui/date-picker.tsx
index ef3a7f0e..ff0886d0 100644
--- a/components/ui/date-picker.tsx
+++ b/components/ui/date-picker.tsx
@@ -25,11 +25,11 @@ const datePickerStyles = tv({
slots: {
base: "group flex flex-col gap-y-1.5",
datePickerIcon:
- "group mr-1 h-7 [&>[data-slot=icon]]:text-muted-fg w-8 rounded outline-offset-0 hover:bg-transparent pressed:bg-transparent",
- calendarIcon: "size-4 text-muted-fg group-open:text-fg",
- datePickerInput: "w-full px-2 uppercase text-base lg:text-sm",
- dateRangePickerInputStart: "px-2 lg:text-sm uppercase text-base",
- dateRangePickerInputEnd: "flex-1 px-2 py-1.5 lg:text-sm uppercase text-base",
+ "group mr-1 h-7 [&_[data-slot=icon]]:text-muted-fg w-8 rounded outline-offset-0 hover:bg-transparent pressed:bg-transparent",
+ calendarIcon: "group-open:text-fg",
+ datePickerInput: "w-full px-2 text-base lg:text-sm",
+ dateRangePickerInputStart: "px-2 lg:text-sm text-base",
+ dateRangePickerInputEnd: "flex-1 px-2 py-1.5 lg:text-sm text-base",
dateRangePickerDash:
"text-fg group-disabled:opacity-50 forced-colors:text-[ButtonText] group-disabled:forced-colors:text-[GrayText]"
}
diff --git a/components/ui/date-range-picker.tsx b/components/ui/date-range-picker.tsx
index 8377eec6..e4a83ca4 100644
--- a/components/ui/date-range-picker.tsx
+++ b/components/ui/date-range-picker.tsx
@@ -18,8 +18,8 @@ import { ctr } from "./primitive"
const dateRangePickerStyles = tv({
slots: {
base: "group flex flex-col gap-y-1.5",
- dateRangePickerInputStart: "px-2 lg:text-sm tabular-nums uppercase text-base",
- dateRangePickerInputEnd: "flex-1 px-2 py-1.5 tabular-nums uppercase text-base lg:text-sm",
+ dateRangePickerInputStart: "px-2 lg:text-sm tabular-nums text-base",
+ dateRangePickerInputEnd: "flex-1 px-2 py-1.5 tabular-nums text-base lg:text-sm",
dateRangePickerDash:
"text-fg group-disabled:text-muted-fg forced-colors:text-[ButtonText] group-disabled:forced-colors:text-[GrayText]"
}
diff --git a/components/ui/field.tsx b/components/ui/field.tsx
index 2fc2d89c..43f674ff 100644
--- a/components/ui/field.tsx
+++ b/components/ui/field.tsx
@@ -20,7 +20,7 @@ import {
} from "react-aria-components"
import { tv } from "tailwind-variants"
-import { cr, ctr } from "./primitive"
+import { cn, ctr } from "./primitive"
interface FieldProps {
label?: string
@@ -31,25 +31,6 @@ interface FieldProps {
"aria-labelledby"?: TextFieldPrimitiveProps["aria-labelledby"]
}
-const fieldBorderStyles = tv({
- base: "group-focus-within:border-ring/85 forced-colors:border-[Highlight]",
- variants: {
- isInvalid: {
- true: "border-danger/70 group-focus-within:border-danger/70 forced-colors:border-[Mark]"
- }
- }
-})
-
-const fieldGroupPrefixStyles = tv({
- base: [
- "flex group-invalid:border-danger group-disabled:bg-secondary group-disabled:opacity-50 items-center group-invalid:focus-within:ring-danger/20",
- "has-[[data-slot=prefix]]:-mx-0.5 has-[[data-slot=suffix]]:-mx-0.5",
- "[&_button]:h-8 [&_button]:rounded-md [&_button]:px-2.5 [&_button]:before:rounded-[calc(theme(borderRadius.md)-1px)] [&_button]:after:rounded-[calc(theme(borderRadius.md)-1px)] dark:[&_button]:after:rounded-md",
- "[&>[role=progressbar]]:mr-2.5 [&>[data-slot=prefix]]:ml-2.5 [&>[data-slot=prefix]]:text-muted-fg [&>[data-slot=prefix]>button]:ml-[-7px]",
- "[&>[data-slot=suffix]]:mr-2.5 [&>[data-slot=suffix]]:text-muted-fg [&>[data-slot=suffix]>button]:mr-[-7px]"
- ]
-})
-
const fieldStyles = tv({
slots: {
description: "text-pretty text-base/6 text-muted-fg sm:text-sm/6",
@@ -86,28 +67,21 @@ const FieldError = ({ className, ...props }: FieldErrorProps) => {
return
}
-const fieldGroupStyles = tv({
- base: [
- "group [&>[data-slot=icon]]:shrink-0 flex h-10 items-center overflow-hidden rounded-lg border border-input bg-bg transition forced-colors:bg-[Field]"
- ],
- variants: {
- isDisabled: {
- true: "opacity-50 bg-secondary"
- },
- isInvalid: {
- false: "focus-within:border-ring/85 focus-within:ring-4 focus-within:ring-ring/20",
- true: "border-danger focus-within:border-danger focus-within:ring-4 focus-within:ring-danger/20"
- }
- }
-})
-
const FieldGroup = ({ className, ...props }: GroupProps) => {
return (
- fieldGroupStyles({ ...renderProps, className })
- )}
+ className={cn([
+ "border border-input transition duration-200 ease-out rounded-lg flex items-center",
+ "focus-within:border-primary/70 focus-within:ring-4 focus-within:ring-primary/20",
+ "group-invalid:focus-within:border-danger focus-within:ring-4 group-invalid:focus-within:ring-danger/20",
+ "[&>[role=progressbar]]:mr-2.5",
+ "[&_[data-slot=icon]]:size-4 [&_[data-slot=icon]]:shrink-0",
+ "[&>[data-slot=suffix]]:mr-2.5 [&>[data-slot=suffix]]:text-muted-fg",
+ "[&>[data-slot=prefix]]:ml-2.5 [&>[data-slot=prefix]]:text-muted-fg",
+ "group-disabled:opacity-50",
+ className
+ ])}
/>
)
}
@@ -115,17 +89,7 @@ const FieldGroup = ({ className, ...props }: GroupProps) => {
const Input = React.forwardRef(({ className, ...props }, ref) => {
return
})
+
Input.displayName = "Input"
-export {
- Description,
- fieldBorderStyles,
- FieldError,
- FieldGroup,
- fieldGroupPrefixStyles,
- fieldGroupStyles,
- Input,
- InputPrimitive,
- Label,
- type FieldProps
-}
+export { Description, FieldError, FieldGroup, Input, Label, type FieldProps }
diff --git a/components/ui/link.tsx b/components/ui/link.tsx
index dff4990b..2fa15257 100644
--- a/components/ui/link.tsx
+++ b/components/ui/link.tsx
@@ -9,7 +9,7 @@ import { cr } from "./primitive"
const linkStyles = tv({
base: [
- "relative focus-visible:outline-2 outline outline-offset-2 outline-0 outline-primary transition-colors",
+ "relative focus-visible:outline-2 outline-offset-2 outline-0 outline-primary transition-colors",
"forced-colors:outline-[Highlight] forced-colors:disabled:text-[GrayText] disabled:focus-visible:outline-0",
"disabled:cursor-default disabled:opacity-60"
],
diff --git a/components/ui/number-field.tsx b/components/ui/number-field.tsx
index d5bb97dc..9a04dc89 100644
--- a/components/ui/number-field.tsx
+++ b/components/ui/number-field.tsx
@@ -10,14 +10,26 @@ import {
} from "react-aria-components"
import { tv } from "tailwind-variants"
-import { Description, fieldBorderStyles, FieldError, FieldGroup, Input, Label } from "./field"
+import { Description, FieldError, FieldGroup, Input, Label } from "./field"
import { ctr, useMediaQuery } from "./primitive"
+const fieldBorderStyles = tv({
+ base: "group-focus:border-primary/70 forced-colors:border-[Highlight]",
+ variants: {
+ isInvalid: {
+ true: "group-focus:border-danger/70 forced-colors:border-[Mark]"
+ },
+ isDisabled: {
+ true: "group-focus:border-input/70"
+ }
+ }
+})
+
const numberFieldStyles = tv({
slots: {
base: "group flex flex-col gap-y-1.5",
stepperButton:
- "h-10 cursor-default px-2 text-muted-fg pressed:bg-primary pressed:text-primary-fg group-disabled:bg-secondary forced-colors:group-disabled:text-[GrayText]"
+ "h-10 cursor-default px-3 text-muted-fg pressed:bg-primary pressed:text-primary-fg group-disabled:bg-secondary/70 forced-colors:group-disabled:text-[GrayText]"
}
})
@@ -42,7 +54,7 @@ const NumberField = ({
return (
{label && }
-
+
{(renderProps) => (
<>
{isMobile ? : null}
@@ -61,7 +73,7 @@ const NumberField = ({
@@ -108,4 +120,4 @@ const StepperButton = ({
)
}
-export { NumberField, type NumberFieldProps }
+export { NumberField }
diff --git a/components/ui/text-field.tsx b/components/ui/text-field.tsx
index 159e3499..276876ac 100644
--- a/components/ui/text-field.tsx
+++ b/components/ui/text-field.tsx
@@ -11,7 +11,7 @@ import {
} from "react-aria-components"
import type { FieldProps } from "./field"
-import { Description, FieldError, FieldGroup, fieldGroupPrefixStyles, Input, Label } from "./field"
+import { Description, FieldError, FieldGroup, Input, Label } from "./field"
import { Loader } from "./loader"
import { ctr } from "./primitive"
@@ -62,10 +62,7 @@ const TextField = ({
className={ctr(className, "group flex flex-col gap-y-1.5")}
>
{label && }
-
+
{prefix ? (
{prefix}
@@ -77,16 +74,14 @@ const TextField = ({
type="button"
aria-label="Toggle password visibility"
onPress={handleTogglePasswordVisibility}
- className="atrs relative [&>[data-slot=icon]]:text-muted-fg focus:outline-none focus-visible:ring-1 focus-visible:ring-primary rounded"
+ className="mr-2.5 relative [&>[data-slot=icon]]:text-muted-fg focus:outline-none focus-visible:ring-1 focus-visible:ring-primary rounded"
>
<>{isPasswordVisible ? : }>
) : isPending ? (
) : suffix ? (
-
- {suffix}
-
+ {suffix}
) : null}
{description && {description}}
diff --git a/components/ui/time-field.tsx b/components/ui/time-field.tsx
index 51517bde..331ad9a9 100644
--- a/components/ui/time-field.tsx
+++ b/components/ui/time-field.tsx
@@ -11,21 +11,24 @@ import {
import { tv } from "tailwind-variants"
import { DateInput } from "./date-field"
-import { Description, FieldError, fieldGroupStyles, Label } from "./field"
+import { Description, FieldError, FieldGroup, Label } from "./field"
import { ctr } from "./primitive"
export interface TimeFieldProps extends TimeFieldPrimitiveProps {
label?: string
description?: string
errorMessage?: string | ((validation: ValidationResult) => string)
+ prefix?: React.ReactNode
+ suffix?: React.ReactNode
}
const timeFieldStyles = tv({
- extend: fieldGroupStyles,
base: "flex w-fit min-w-28 justify-around whitespace-nowrap p-2 lg:text-sm"
})
const TimeField = ({
+ prefix,
+ suffix,
label,
className,
description,
@@ -33,9 +36,13 @@ const TimeField = ({
...props
}: TimeFieldProps) => {
return (
-
+
{label && }
-
+
+ {prefix ? {prefix} : null}
+
+ {suffix ? {suffix} : null}
+
{description && {description}}
{errorMessage}
diff --git a/package.json b/package.json
index 5f46348e..580069a4 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,6 @@
"framer-motion": "12.0.0-alpha.1",
"input-otp": "^1.4.1",
"justd-icons": "^1.7.9",
- "mitt": "^3.0.1",
"next": "^15.0.3",
"next-themes": "^0.2.1",
"ntcjs": "^1.1.3",
@@ -36,7 +35,6 @@
"react-aria-components": "^1.4.1",
"react-dom": "19.0.0-rc-02c0e824-20241028",
"react-intersection-observer": "^9.13.1",
- "react-use-measure": "^2.1.1",
"recharts": "^2.13.3",
"rehype-pretty-code": "^0.13.2",
"rehype-stringify": "^10.0.1",
@@ -71,10 +69,10 @@
"eslint-config-next": "15.0.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
- "husky": "^9.1.6",
+ "husky": "^9.1.7",
"postcss": "^8.4.49",
"prettier": "^3.3.3",
- "prettier-plugin-tailwindcss": "^0.6.8",
+ "prettier-plugin-tailwindcss": "^0.6.9",
"rehype-autolink-headings": "^7.1.0",
"rehype-slug": "^6.0.0",
"tailwindcss": "^3.4.15",
diff --git a/resources/content/docs/components/colors/color-field.mdx b/resources/content/docs/components/colors/color-field.mdx
index 771d1b85..2be43613 100644
--- a/resources/content/docs/components/colors/color-field.mdx
+++ b/resources/content/docs/components/colors/color-field.mdx
@@ -44,16 +44,21 @@ You can typically click the color swatch to open the color picker. To disable th
You can disable the color field, making it non-interactive.
+## Validation
+In this example, we’ll ensure it’s treated as a strict requirement.
+
+
+
## Props
The `ColorField` component includes all standard props from `react-aria-components`, plus these additional features:
-| Property | Type | Optional |
-|-------------------|------------------------------------------------------|---------------------|
-| label | string | Yes |
-| description | string | Yes |
-| errorMessage | string \| ((validation: ValidationResult) => string) | Yes |
-| placeholder | string | Yes |
-| prefix | React.ReactNode | Yes |
-| suffix | React.ReactNode | Yes |
-| isLoading | boolean | Yes |
+| Property | Type | Optional |
+|-------------------|------------------------------------------------------|----------------------|
+| label | string | Yes |
+| description | string | Yes |
+| errorMessage | string \| ((validation: ValidationResult) => string) | Yes |
+| placeholder | string | Yes |
+| prefix | React.ReactNode | Yes |
+| suffix | React.ReactNode | Yes |
+| isLoading | boolean | Yes |
| enableColorPicker | boolean | Yes ( default: true) |
diff --git a/resources/content/docs/components/date-and-time/date-field.mdx b/resources/content/docs/components/date-and-time/date-field.mdx
index cdb1bd38..08a20237 100644
--- a/resources/content/docs/components/date-and-time/date-field.mdx
+++ b/resources/content/docs/components/date-and-time/date-field.mdx
@@ -22,10 +22,6 @@ A date field allows users to enter and adjust date and time values using a keybo
-## Controlled
-In a controlled date field, the value must be passed as a prop, and the field is not directly editable by the user.
-
-
## Date Time Field
You can also use the date field to select both date and time.
@@ -34,6 +30,28 @@ You can also use the date field to select both date and time.
When validation is applied, the date field will show a validation message if the entered value is invalid.
+## Prefix
+A demonstration of how to add a prefix to the date field component for enhanced clarity or customization.
+
+
+## Suffix
+A demonstration of how to add a suffix to the date field component to provide additional context or customization.
+
+
+
+## Controlled
+In a controlled date field, the value must be passed as a prop, and the field is not directly editable by the user.
+
+
+## Uncontrolled
+In a controlled date field, the value must be passed as a prop, and the field is not directly editable by the user.
+
+
+## Readonly
+In a readonly date field, the value is provided as a prop, and the field is not editable by the user.
+
+
+
## Disabled
A disabled date field is non-interactive and visually represented in a disabled state.
diff --git a/resources/content/docs/components/date-and-time/time-field.mdx b/resources/content/docs/components/date-and-time/time-field.mdx
index f6edb9f6..5779bec9 100644
--- a/resources/content/docs/components/date-and-time/time-field.mdx
+++ b/resources/content/docs/components/date-and-time/time-field.mdx
@@ -26,6 +26,14 @@ A time field allows users to input and adjust time values using a keyboard, with
Change the hour format in the time field by using the `hourCycle` prop.
+## Prefix
+A demonstration of how to add a prefix to the time field component for enhanced clarity or customization.
+
+
+## Suffix
+A demonstration of how to add a suffix to the time field component to provide additional context or customization.
+
+
## Validation
To ensure the time field is properly filled out, use the `isRequired` prop.
@@ -34,6 +42,10 @@ To ensure the time field is properly filled out, use the `isRequired` prop.
In a controlled time field, the value is provided as a prop, and the field is not editable by the user.
+## Readonly
+In a readonly time field, the value is provided as a prop, and the field is not editable by the user.
+
+
## Disabled
A disabled time field cannot be interacted with and is visually represented as being inactive.
diff --git a/resources/content/docs/components/forms/number-field.mdx b/resources/content/docs/components/forms/number-field.mdx
index 1d63b27c..8729292b 100644
--- a/resources/content/docs/components/forms/number-field.mdx
+++ b/resources/content/docs/components/forms/number-field.mdx
@@ -34,8 +34,8 @@ You can use the number field as a controlled component by managing its state ext
Like other fields, the search field can be controlled by managing its value through the `defaultValue` prop.
-## Invalid
-The field is in an error state, typically due to invalid input.
+## Validation
+The field is in an error state, usually caused by invalid input. Try submitting the form without filling it out to see the error state in action.
## Disabled
diff --git a/resources/content/docs/components/forms/text-field.mdx b/resources/content/docs/components/forms/text-field.mdx
index eef503ae..c880d730 100644
--- a/resources/content/docs/components/forms/text-field.mdx
+++ b/resources/content/docs/components/forms/text-field.mdx
@@ -43,7 +43,7 @@ When using a text field as a password input, you may want the option to reveal t
## Validation
-Validate the TextField input using the `isInvalid` prop.
+In this example, we’ll ensure it’s treated as a strict requirement.
## Controlled
diff --git a/resources/content/docs/components/forms/textarea.mdx b/resources/content/docs/components/forms/textarea.mdx
index 32eb90fe..917d5661 100644
--- a/resources/content/docs/components/forms/textarea.mdx
+++ b/resources/content/docs/components/forms/textarea.mdx
@@ -38,6 +38,10 @@ You can control the textarea value by using the `value` prop.
You can control the textarea value by using the `defaultValue` prop.
+## Validation
+Try submitting the form without filling it out to see the error state in action.
+
+
## Readonly
When the textarea is set to readonly, it cannot be edited.
diff --git a/resources/lib/emitter.ts b/resources/lib/emitter.ts
index 291507eb..4d48de9a 100644
--- a/resources/lib/emitter.ts
+++ b/resources/lib/emitter.ts
@@ -1,7 +1,7 @@
-import mitt from "mitt"
-
-type Events = {
- thereIsAnAdVisibilityChange: "hidden" | "visible"
-}
-
-export const emitter = mitt()
+// import mitt from "mitt"
+//
+// type Events = {
+// thereIsAnAdVisibilityChange: "hidden" | "visible"
+// }
+//
+// export const emitter = mitt()