@jarllyng/nostromo 3.9.0 → 3.11.0
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/README.md +1 -1
- package/dist/animations.css +29 -1
- package/dist/chunk-27UORO2F.cjs +3 -0
- package/dist/chunk-27UORO2F.cjs.map +1 -0
- package/dist/chunk-BDRP7ALG.cjs +3 -0
- package/dist/chunk-BDRP7ALG.cjs.map +1 -0
- package/dist/chunk-BJPJB6IA.cjs +3 -0
- package/dist/chunk-BJPJB6IA.cjs.map +1 -0
- package/dist/chunk-K45ZUJ42.js +3 -0
- package/dist/chunk-K45ZUJ42.js.map +1 -0
- package/dist/{chunk-WW2DDHCI.js → chunk-KR6IVHNR.js} +2 -2
- package/dist/{chunk-WW2DDHCI.js.map → chunk-KR6IVHNR.js.map} +1 -1
- package/dist/chunk-MINSU2YF.js +3 -0
- package/dist/chunk-MINSU2YF.js.map +1 -0
- package/dist/chunk-NM5NVIAK.js +3 -0
- package/dist/chunk-NM5NVIAK.js.map +1 -0
- package/dist/{chunk-MLJZU63I.cjs → chunk-YLAUFUIS.cjs} +2 -2
- package/dist/{chunk-MLJZU63I.cjs.map → chunk-YLAUFUIS.cjs.map} +1 -1
- package/dist/components/core/alert.d.cts +1 -1
- package/dist/components/core/alert.d.ts +1 -1
- package/dist/components/core/badge.d.cts +1 -1
- package/dist/components/core/badge.d.ts +1 -1
- package/dist/components/core/breadcrumb.d.cts +1 -1
- package/dist/components/core/breadcrumb.d.ts +1 -1
- package/dist/components/core/button.d.cts +2 -2
- package/dist/components/core/button.d.ts +2 -2
- package/dist/components/core/carousel.cjs +3 -0
- package/dist/components/core/carousel.cjs.map +1 -0
- package/dist/components/core/carousel.d.cts +71 -0
- package/dist/components/core/carousel.d.ts +71 -0
- package/dist/components/core/carousel.js +3 -0
- package/dist/components/core/carousel.js.map +1 -0
- package/dist/components/core/checkbox.d.cts +1 -1
- package/dist/components/core/checkbox.d.ts +1 -1
- package/dist/components/core/dialog.d.cts +1 -1
- package/dist/components/core/dialog.d.ts +1 -1
- package/dist/components/core/error-message.d.cts +1 -1
- package/dist/components/core/error-message.d.ts +1 -1
- package/dist/components/core/form.cjs +3 -0
- package/dist/components/core/form.cjs.map +1 -0
- package/dist/components/core/form.d.cts +90 -0
- package/dist/components/core/form.d.ts +90 -0
- package/dist/components/core/form.js +3 -0
- package/dist/components/core/form.js.map +1 -0
- package/dist/components/core/helper-text.d.cts +1 -1
- package/dist/components/core/helper-text.d.ts +1 -1
- package/dist/components/core/icon.d.cts +2 -2
- package/dist/components/core/icon.d.ts +2 -2
- package/dist/components/core/input-otp.cjs +3 -0
- package/dist/components/core/input-otp.cjs.map +1 -0
- package/dist/components/core/input-otp.d.cts +50 -0
- package/dist/components/core/input-otp.d.ts +50 -0
- package/dist/components/core/input-otp.js +3 -0
- package/dist/components/core/input-otp.js.map +1 -0
- package/dist/components/core/input.d.cts +1 -1
- package/dist/components/core/input.d.ts +1 -1
- package/dist/components/core/label.d.cts +1 -1
- package/dist/components/core/label.d.ts +1 -1
- package/dist/components/core/pagination.d.cts +1 -1
- package/dist/components/core/pagination.d.ts +1 -1
- package/dist/components/core/progress.d.cts +3 -3
- package/dist/components/core/progress.d.ts +3 -3
- package/dist/components/core/radio-group.cjs +1 -1
- package/dist/components/core/radio-group.d.cts +2 -2
- package/dist/components/core/radio-group.d.ts +2 -2
- package/dist/components/core/radio-group.js +1 -1
- package/dist/components/core/resizable.cjs +3 -0
- package/dist/components/core/resizable.cjs.map +1 -0
- package/dist/components/core/resizable.d.cts +362 -0
- package/dist/components/core/resizable.d.ts +362 -0
- package/dist/components/core/resizable.js +3 -0
- package/dist/components/core/resizable.js.map +1 -0
- package/dist/components/core/select.d.cts +3 -3
- package/dist/components/core/select.d.ts +3 -3
- package/dist/components/core/skeleton.d.cts +1 -1
- package/dist/components/core/skeleton.d.ts +1 -1
- package/dist/components/core/switch.d.cts +1 -1
- package/dist/components/core/switch.d.ts +1 -1
- package/dist/components/core/textarea.d.cts +1 -1
- package/dist/components/core/textarea.d.ts +1 -1
- package/dist/components/core/toast.d.cts +2 -2
- package/dist/components/core/toast.d.ts +2 -2
- package/dist/components/core/tooltip.d.cts +2 -2
- package/dist/components/core/tooltip.d.ts +2 -2
- package/dist/components/marketing/features.d.cts +2 -2
- package/dist/components/marketing/features.d.ts +2 -2
- package/dist/components/marketing/gallery.d.cts +1 -1
- package/dist/components/marketing/gallery.d.ts +1 -1
- package/dist/components/marketing/pricing.d.cts +1 -1
- package/dist/components/marketing/pricing.d.ts +1 -1
- package/dist/components/marketing/testimonials.d.cts +1 -1
- package/dist/components/marketing/testimonials.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +471 -150
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import useEmblaCarousel, { UseEmblaCarouselType } from 'embla-carousel-react';
|
|
3
|
+
import { Button } from './button.cjs';
|
|
4
|
+
import 'class-variance-authority/types';
|
|
5
|
+
import 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A horizontal or vertical strip of slides that snaps as you drag it.
|
|
9
|
+
*
|
|
10
|
+
* Embla does the measuring, the dragging and the snapping. This file is the
|
|
11
|
+
* markup, the styling and the roles, plus the two buttons.
|
|
12
|
+
*
|
|
13
|
+
* ## `orientation` is the only axis control
|
|
14
|
+
*
|
|
15
|
+
* Embla takes `axis: "x" | "y"`, and this component derives it from
|
|
16
|
+
* `orientation`, because the padding on `CarouselItem` and the placement of the
|
|
17
|
+
* two buttons have to agree with it. Setting `opts={{ axis: "y" }}` will not
|
|
18
|
+
* work: `orientation` overwrites it. One control, so the styling cannot drift
|
|
19
|
+
* out of sync with the behaviour.
|
|
20
|
+
*
|
|
21
|
+
* ## Anything beyond next and previous goes through `setApi`
|
|
22
|
+
*
|
|
23
|
+
* Dots, autoplay, a progress bar, "slide 3 of 7" - all of that reads state
|
|
24
|
+
* embla owns, and wrapping each one would mean guessing which you want. `setApi`
|
|
25
|
+
* hands you the embla instance instead, and its `on("select")` event is the hook
|
|
26
|
+
* for the rest.
|
|
27
|
+
*/
|
|
28
|
+
type CarouselApi = UseEmblaCarouselType[1];
|
|
29
|
+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
|
|
30
|
+
type CarouselOptions = UseCarouselParameters[0];
|
|
31
|
+
type CarouselPlugin = UseCarouselParameters[1];
|
|
32
|
+
interface CarouselProps {
|
|
33
|
+
/** Embla options. `axis` is ignored - use `orientation`. */
|
|
34
|
+
opts?: CarouselOptions;
|
|
35
|
+
/** Embla plugins, for example autoplay. */
|
|
36
|
+
plugins?: CarouselPlugin;
|
|
37
|
+
orientation?: "horizontal" | "vertical";
|
|
38
|
+
/** Receives the embla instance, for dots, autoplay or a slide counter. */
|
|
39
|
+
setApi?: (api: CarouselApi) => void;
|
|
40
|
+
}
|
|
41
|
+
interface CarouselContextValue extends CarouselProps {
|
|
42
|
+
carouselRef: UseEmblaCarouselType[0];
|
|
43
|
+
api: CarouselApi;
|
|
44
|
+
scrollPrev: () => void;
|
|
45
|
+
scrollNext: () => void;
|
|
46
|
+
canScrollPrev: boolean;
|
|
47
|
+
canScrollNext: boolean;
|
|
48
|
+
orientation: "horizontal" | "vertical";
|
|
49
|
+
}
|
|
50
|
+
declare function useCarousel(): CarouselContextValue;
|
|
51
|
+
declare const Carousel: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & CarouselProps & React.RefAttributes<HTMLDivElement>>;
|
|
52
|
+
/**
|
|
53
|
+
* The viewport and the track.
|
|
54
|
+
*
|
|
55
|
+
* Two elements rather than one: embla measures the outer one, which must clip,
|
|
56
|
+
* and translates the inner one. The negative margin pairs with the padding on
|
|
57
|
+
* `CarouselItem` so the gap between slides does not show up as an edge inset.
|
|
58
|
+
*/
|
|
59
|
+
declare const CarouselContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
60
|
+
declare const CarouselItem: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
61
|
+
interface CarouselButtonProps extends React.ComponentPropsWithoutRef<typeof Button> {
|
|
62
|
+
/**
|
|
63
|
+
* Screen-reader text for the button. The arrow is decorative, so this is the
|
|
64
|
+
* button's only accessible name.
|
|
65
|
+
*/
|
|
66
|
+
label?: string;
|
|
67
|
+
}
|
|
68
|
+
declare const CarouselPrevious: React.ForwardRefExoticComponent<CarouselButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
69
|
+
declare const CarouselNext: React.ForwardRefExoticComponent<CarouselButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
70
|
+
|
|
71
|
+
export { Carousel, type CarouselApi, type CarouselButtonProps, CarouselContent, CarouselItem, CarouselNext, type CarouselOptions, type CarouselPlugin, CarouselPrevious, type CarouselProps, useCarousel };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import useEmblaCarousel, { UseEmblaCarouselType } from 'embla-carousel-react';
|
|
3
|
+
import { Button } from './button.js';
|
|
4
|
+
import 'class-variance-authority/types';
|
|
5
|
+
import 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A horizontal or vertical strip of slides that snaps as you drag it.
|
|
9
|
+
*
|
|
10
|
+
* Embla does the measuring, the dragging and the snapping. This file is the
|
|
11
|
+
* markup, the styling and the roles, plus the two buttons.
|
|
12
|
+
*
|
|
13
|
+
* ## `orientation` is the only axis control
|
|
14
|
+
*
|
|
15
|
+
* Embla takes `axis: "x" | "y"`, and this component derives it from
|
|
16
|
+
* `orientation`, because the padding on `CarouselItem` and the placement of the
|
|
17
|
+
* two buttons have to agree with it. Setting `opts={{ axis: "y" }}` will not
|
|
18
|
+
* work: `orientation` overwrites it. One control, so the styling cannot drift
|
|
19
|
+
* out of sync with the behaviour.
|
|
20
|
+
*
|
|
21
|
+
* ## Anything beyond next and previous goes through `setApi`
|
|
22
|
+
*
|
|
23
|
+
* Dots, autoplay, a progress bar, "slide 3 of 7" - all of that reads state
|
|
24
|
+
* embla owns, and wrapping each one would mean guessing which you want. `setApi`
|
|
25
|
+
* hands you the embla instance instead, and its `on("select")` event is the hook
|
|
26
|
+
* for the rest.
|
|
27
|
+
*/
|
|
28
|
+
type CarouselApi = UseEmblaCarouselType[1];
|
|
29
|
+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
|
|
30
|
+
type CarouselOptions = UseCarouselParameters[0];
|
|
31
|
+
type CarouselPlugin = UseCarouselParameters[1];
|
|
32
|
+
interface CarouselProps {
|
|
33
|
+
/** Embla options. `axis` is ignored - use `orientation`. */
|
|
34
|
+
opts?: CarouselOptions;
|
|
35
|
+
/** Embla plugins, for example autoplay. */
|
|
36
|
+
plugins?: CarouselPlugin;
|
|
37
|
+
orientation?: "horizontal" | "vertical";
|
|
38
|
+
/** Receives the embla instance, for dots, autoplay or a slide counter. */
|
|
39
|
+
setApi?: (api: CarouselApi) => void;
|
|
40
|
+
}
|
|
41
|
+
interface CarouselContextValue extends CarouselProps {
|
|
42
|
+
carouselRef: UseEmblaCarouselType[0];
|
|
43
|
+
api: CarouselApi;
|
|
44
|
+
scrollPrev: () => void;
|
|
45
|
+
scrollNext: () => void;
|
|
46
|
+
canScrollPrev: boolean;
|
|
47
|
+
canScrollNext: boolean;
|
|
48
|
+
orientation: "horizontal" | "vertical";
|
|
49
|
+
}
|
|
50
|
+
declare function useCarousel(): CarouselContextValue;
|
|
51
|
+
declare const Carousel: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & CarouselProps & React.RefAttributes<HTMLDivElement>>;
|
|
52
|
+
/**
|
|
53
|
+
* The viewport and the track.
|
|
54
|
+
*
|
|
55
|
+
* Two elements rather than one: embla measures the outer one, which must clip,
|
|
56
|
+
* and translates the inner one. The negative margin pairs with the padding on
|
|
57
|
+
* `CarouselItem` so the gap between slides does not show up as an edge inset.
|
|
58
|
+
*/
|
|
59
|
+
declare const CarouselContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
60
|
+
declare const CarouselItem: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
61
|
+
interface CarouselButtonProps extends React.ComponentPropsWithoutRef<typeof Button> {
|
|
62
|
+
/**
|
|
63
|
+
* Screen-reader text for the button. The arrow is decorative, so this is the
|
|
64
|
+
* button's only accessible name.
|
|
65
|
+
*/
|
|
66
|
+
label?: string;
|
|
67
|
+
}
|
|
68
|
+
declare const CarouselPrevious: React.ForwardRefExoticComponent<CarouselButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
69
|
+
declare const CarouselNext: React.ForwardRefExoticComponent<CarouselButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
70
|
+
|
|
71
|
+
export { Carousel, type CarouselApi, type CarouselButtonProps, CarouselContent, CarouselItem, CarouselNext, type CarouselOptions, type CarouselPlugin, CarouselPrevious, type CarouselProps, useCarousel };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
export{b as Carousel,c as CarouselContent,d as CarouselItem,f as CarouselNext,e as CarouselPrevious,a as useCarousel}from'../../chunk-NM5NVIAK.js';import'../../chunk-AVTJE2O2.js';import'../../chunk-COXN6XBA.js';import'../../chunk-AC2JBXHQ.js';//# sourceMappingURL=carousel.js.map
|
|
3
|
+
//# sourceMappingURL=carousel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"carousel.js"}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const checkboxVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "error" | "default" | "success" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof checkboxVariants> {
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const checkboxVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "error" | "default" | "success" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof checkboxVariants> {
|
|
@@ -8,7 +8,7 @@ declare const dialogVariants: (props?: ({
|
|
|
8
8
|
animation?: "default" | "none" | "scale" | "slide" | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
declare const backdropVariants: (props?: ({
|
|
11
|
-
variant?: "
|
|
11
|
+
variant?: "strong" | "default" | "subtle" | "colored" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
13
13
|
interface DialogProps {
|
|
14
14
|
open?: boolean;
|
|
@@ -8,7 +8,7 @@ declare const dialogVariants: (props?: ({
|
|
|
8
8
|
animation?: "default" | "none" | "scale" | "slide" | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
declare const backdropVariants: (props?: ({
|
|
11
|
-
variant?: "
|
|
11
|
+
variant?: "strong" | "default" | "subtle" | "colored" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
13
13
|
interface DialogProps {
|
|
14
14
|
open?: boolean;
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const errorMessageVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "strong" | "default" | "subtle" | "inline" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ErrorMessageProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof errorMessageVariants> {
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const errorMessageVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "strong" | "default" | "subtle" | "inline" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ErrorMessageProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof errorMessageVariants> {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';var chunkV77N662N_cjs=require('../../chunk-V77N662N.cjs'),chunk7YFUAGIW_cjs=require('../../chunk-7YFUAGIW.cjs'),chunkXPIBRXTW_cjs=require('../../chunk-XPIBRXTW.cjs'),chunkITRGJNWL_cjs=require('../../chunk-ITRGJNWL.cjs'),r=require('react'),reactSlot=require('@radix-ui/react-slot'),reactHookForm=require('react-hook-form');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var r__namespace=/*#__PURE__*/_interopNamespace(r);var v=reactHookForm.FormProvider,f=r__namespace.createContext(null);function N({...e}){let t=r__namespace.useId(),o=r__namespace.useMemo(()=>({name:e.name,id:t}),[e.name,t]);return r__namespace.createElement(f.Provider,{value:o},r__namespace.createElement(reactHookForm.Controller,{...e}))}function i(){let e=r__namespace.useContext(f);if(!e)throw new Error("useFormField must be used inside a <FormField>. Without it there is no field id to attach a label or a message to.");let{errors:t}=reactHookForm.useFormState({name:e.name}),o=e.name.split(".").reduce((s,a)=>s?.[a],t);return {name:e.name,formItemId:e.id,formDescriptionId:`${e.id}-description`,formMessageId:`${e.id}-message`,error:o}}function g({className:e,...t}){return r__namespace.createElement("div",{className:chunkITRGJNWL_cjs.a("space-y-1.5",e),...t})}g.displayName="FormItem";var y=r__namespace.forwardRef(({className:e,...t},o)=>{let{error:s,formItemId:a}=i();return r__namespace.createElement(chunkXPIBRXTW_cjs.b,{ref:o,htmlFor:a,className:chunkITRGJNWL_cjs.a(s&&"text-destructive",e),...t})});y.displayName="FormLabel";var C=r__namespace.forwardRef(({...e},t)=>{let{error:o,formItemId:s,formDescriptionId:a,formMessageId:n}=i();return r__namespace.createElement(reactSlot.Slot,{ref:t,id:s,"aria-describedby":o?`${a} ${n}`:a,"aria-invalid":o?true:void 0,...e})});C.displayName="FormControl";var I=r__namespace.forwardRef(({...e},t)=>{let{formDescriptionId:o}=i();return r__namespace.createElement(chunk7YFUAGIW_cjs.b,{ref:t,id:o,...e})});I.displayName="FormDescription";var M=r__namespace.forwardRef(({children:e,...t},o)=>{let{error:s,formMessageId:a}=i(),n=s?.message??e;return n?r__namespace.createElement(chunkV77N662N_cjs.b,{ref:o,id:a,...t},n):null});M.displayName="FormMessage";Object.defineProperty(exports,"useFormContext",{enumerable:true,get:function(){return reactHookForm.useFormContext}});exports.Form=v;exports.FormControl=C;exports.FormDescription=I;exports.FormField=N;exports.FormItem=g;exports.FormLabel=y;exports.FormMessage=M;exports.useFormField=i;//# sourceMappingURL=form.cjs.map
|
|
3
|
+
//# sourceMappingURL=form.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/core/form.tsx"],"names":["Form","FormProvider","FormFieldContext","r","FormField","props","id","value","Controller","useFormField","field","errors","useFormState","error","acc","key","FormItem","className","cn","FormLabel","ref","formItemId","Label","FormControl","formDescriptionId","formMessageId","Slot","FormDescription","HelperText","FormMessage","children","body","ErrorMessage"],"mappings":"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","file":"form.cjs","sourcesContent":["import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\";\n\nimport { cn } from \"../../lib/utils\";\nimport { ErrorMessage } from \"./error-message\";\nimport { HelperText } from \"./helper-text\";\nimport { Label } from \"./label\";\n\n/**\n * Wires react-hook-form to this library's Label, HelperText and ErrorMessage,\n * and generates the ids that connect them.\n *\n * The three pieces have always existed separately, and connecting them was left\n * to the caller: an id on the input, a matching htmlFor, an aria-describedby\n * listing the description and the error, and aria-invalid toggled by hand. That\n * is four things to get right per field, and the failure is silent - a form that\n * looks correct and tells a screen reader nothing.\n *\n * `FormField` generates one id per field and `FormControl` applies the wiring, so\n * a field is a label, a control and a message with no bookkeeping.\n *\n * ## react-hook-form is an optional peer dependency, and this is not in the barrel\n *\n * `react-hook-form` is around 25kB and most consumers of a component library do\n * not want it forced on them, so it is an optional peer: install it if you use\n * `Form`, and pay nothing if you do not.\n *\n * That only works if importing something unrelated cannot pull it in. A bundler\n * has to *resolve* every import in a module before it can tree-shake anything,\n * so a barrel that re-exported this file would fail to build for anyone without\n * the peer installed, even if they only wanted `Button`. So `Form` is reachable\n * only through its own entry point:\n *\n * import { Form, FormField } from \"@jarllyng/nostromo/components/core/form\";\n *\n * Verified rather than assumed - see the react-compat job, which installs the\n * packed tarball into a project with no react-hook-form and imports the barrel.\n */\n\nconst Form = FormProvider;\n\ninterface FormFieldContextValue {\n name: string;\n id: string;\n}\n\nconst FormFieldContext = React.createContext<FormFieldContextValue | null>(\n null,\n);\n\n/**\n * One field: a name, and the ids that tie its parts together.\n *\n * Wraps react-hook-form's `Controller`, so it works with controlled components\n * like `Select` and `Checkbox` as well as with plain inputs.\n */\nfunction FormField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({ ...props }: ControllerProps<TFieldValues, TName>) {\n const id = React.useId();\n const value = React.useMemo(\n () => ({ name: props.name as string, id }),\n [props.name, id],\n );\n return (\n <FormFieldContext.Provider value={value}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n}\n\n/**\n * The ids and error state for the field being rendered.\n *\n * Throws rather than returning undefined when used outside a `FormField`. The\n * quiet alternative is a label whose `htmlFor` points at nothing, which is the\n * exact class of silent breakage this component exists to remove.\n */\nfunction useFormField() {\n const field = React.useContext(FormFieldContext);\n if (!field) {\n throw new Error(\n \"useFormField must be used inside a <FormField>. Without it there is no field id to attach a label or a message to.\",\n );\n }\n const { errors } = useFormState({ name: field.name });\n // Nested names like \"address.city\" reach into the error object.\n const error = field.name\n .split(\".\")\n .reduce<unknown>(\n (acc, key) => (acc as Record<string, unknown>)?.[key],\n errors,\n );\n\n return {\n name: field.name,\n formItemId: field.id,\n formDescriptionId: `${field.id}-description`,\n formMessageId: `${field.id}-message`,\n error: error as { message?: string } | undefined,\n };\n}\n\nfunction FormItem({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn(\"space-y-1.5\", className)} {...props} />;\n}\nFormItem.displayName = \"FormItem\";\n\nconst FormLabel = React.forwardRef<\n React.ElementRef<typeof Label>,\n React.ComponentPropsWithoutRef<typeof Label>\n>(({ className, ...props }, ref) => {\n const { error, formItemId } = useFormField();\n return (\n <Label\n ref={ref}\n htmlFor={formItemId}\n className={cn(error && \"text-destructive\", className)}\n {...props}\n />\n );\n});\nFormLabel.displayName = \"FormLabel\";\n\n/**\n * Applies the wiring to whatever control it wraps.\n *\n * A `Slot`, so it passes the id and the aria attributes to the child rather than\n * rendering an element of its own. `aria-describedby` lists the description and,\n * when there is one, the message - both, because a field can have guidance and\n * an error at the same time and a screen reader should hear both.\n */\nconst FormControl = React.forwardRef<\n HTMLElement,\n React.HTMLAttributes<HTMLElement>\n>(({ ...props }, ref) => {\n const { error, formItemId, formDescriptionId, formMessageId } =\n useFormField();\n return (\n <Slot\n ref={ref}\n id={formItemId}\n aria-describedby={\n error ? `${formDescriptionId} ${formMessageId}` : formDescriptionId\n }\n aria-invalid={error ? true : undefined}\n {...props}\n />\n );\n});\nFormControl.displayName = \"FormControl\";\n\nconst FormDescription = React.forwardRef<\n React.ElementRef<typeof HelperText>,\n React.ComponentPropsWithoutRef<typeof HelperText>\n>(({ ...props }, ref) => {\n const { formDescriptionId } = useFormField();\n return <HelperText ref={ref} id={formDescriptionId} {...props} />;\n});\nFormDescription.displayName = \"FormDescription\";\n\n/**\n * The field's error, or nothing.\n *\n * Renders the validation message when there is one and `children` otherwise, so\n * a field can carry a persistent hint that the error replaces. Renders nothing\n * at all when there is neither, rather than an empty element that still takes up\n * space in the layout.\n */\nconst FormMessage = React.forwardRef<\n React.ElementRef<typeof ErrorMessage>,\n React.ComponentPropsWithoutRef<typeof ErrorMessage>\n>(({ children, ...props }, ref) => {\n const { error, formMessageId } = useFormField();\n const body = error?.message ?? children;\n if (!body) return null;\n\n return (\n <ErrorMessage ref={ref} id={formMessageId} {...props}>\n {body}\n </ErrorMessage>\n );\n});\nFormMessage.displayName = \"FormMessage\";\n\nexport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n useFormField,\n useFormContext,\n};\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ErrorMessageProps } from './error-message.cjs';
|
|
2
|
+
import { HelperTextProps } from './helper-text.cjs';
|
|
3
|
+
import { LabelProps } from './label.cjs';
|
|
4
|
+
import * as react_hook_form from 'react-hook-form';
|
|
5
|
+
import { FieldValues, FieldPath, ControllerProps } from 'react-hook-form';
|
|
6
|
+
export { useFormContext } from 'react-hook-form';
|
|
7
|
+
import * as React from 'react';
|
|
8
|
+
import 'class-variance-authority/types';
|
|
9
|
+
import 'class-variance-authority';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wires react-hook-form to this library's Label, HelperText and ErrorMessage,
|
|
13
|
+
* and generates the ids that connect them.
|
|
14
|
+
*
|
|
15
|
+
* The three pieces have always existed separately, and connecting them was left
|
|
16
|
+
* to the caller: an id on the input, a matching htmlFor, an aria-describedby
|
|
17
|
+
* listing the description and the error, and aria-invalid toggled by hand. That
|
|
18
|
+
* is four things to get right per field, and the failure is silent - a form that
|
|
19
|
+
* looks correct and tells a screen reader nothing.
|
|
20
|
+
*
|
|
21
|
+
* `FormField` generates one id per field and `FormControl` applies the wiring, so
|
|
22
|
+
* a field is a label, a control and a message with no bookkeeping.
|
|
23
|
+
*
|
|
24
|
+
* ## react-hook-form is an optional peer dependency, and this is not in the barrel
|
|
25
|
+
*
|
|
26
|
+
* `react-hook-form` is around 25kB and most consumers of a component library do
|
|
27
|
+
* not want it forced on them, so it is an optional peer: install it if you use
|
|
28
|
+
* `Form`, and pay nothing if you do not.
|
|
29
|
+
*
|
|
30
|
+
* That only works if importing something unrelated cannot pull it in. A bundler
|
|
31
|
+
* has to *resolve* every import in a module before it can tree-shake anything,
|
|
32
|
+
* so a barrel that re-exported this file would fail to build for anyone without
|
|
33
|
+
* the peer installed, even if they only wanted `Button`. So `Form` is reachable
|
|
34
|
+
* only through its own entry point:
|
|
35
|
+
*
|
|
36
|
+
* import { Form, FormField } from "@jarllyng/nostromo/components/core/form";
|
|
37
|
+
*
|
|
38
|
+
* Verified rather than assumed - see the react-compat job, which installs the
|
|
39
|
+
* packed tarball into a project with no react-hook-form and imports the barrel.
|
|
40
|
+
*/
|
|
41
|
+
declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, resetDefaultValues, handleSubmit, unregister, control, register, setFocus, subscribe, }: react_hook_form.FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
|
|
42
|
+
/**
|
|
43
|
+
* One field: a name, and the ids that tie its parts together.
|
|
44
|
+
*
|
|
45
|
+
* Wraps react-hook-form's `Controller`, so it works with controlled components
|
|
46
|
+
* like `Select` and `Checkbox` as well as with plain inputs.
|
|
47
|
+
*/
|
|
48
|
+
declare function FormField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ ...props }: ControllerProps<TFieldValues, TName>): React.JSX.Element;
|
|
49
|
+
/**
|
|
50
|
+
* The ids and error state for the field being rendered.
|
|
51
|
+
*
|
|
52
|
+
* Throws rather than returning undefined when used outside a `FormField`. The
|
|
53
|
+
* quiet alternative is a label whose `htmlFor` points at nothing, which is the
|
|
54
|
+
* exact class of silent breakage this component exists to remove.
|
|
55
|
+
*/
|
|
56
|
+
declare function useFormField(): {
|
|
57
|
+
name: string;
|
|
58
|
+
formItemId: string;
|
|
59
|
+
formDescriptionId: string;
|
|
60
|
+
formMessageId: string;
|
|
61
|
+
error: {
|
|
62
|
+
message?: string;
|
|
63
|
+
} | undefined;
|
|
64
|
+
};
|
|
65
|
+
declare function FormItem({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
66
|
+
declare namespace FormItem {
|
|
67
|
+
var displayName: string;
|
|
68
|
+
}
|
|
69
|
+
declare const FormLabel: React.ForwardRefExoticComponent<Omit<LabelProps & React.RefAttributes<HTMLLabelElement>, "ref"> & React.RefAttributes<HTMLLabelElement>>;
|
|
70
|
+
/**
|
|
71
|
+
* Applies the wiring to whatever control it wraps.
|
|
72
|
+
*
|
|
73
|
+
* A `Slot`, so it passes the id and the aria attributes to the child rather than
|
|
74
|
+
* rendering an element of its own. `aria-describedby` lists the description and,
|
|
75
|
+
* when there is one, the message - both, because a field can have guidance and
|
|
76
|
+
* an error at the same time and a screen reader should hear both.
|
|
77
|
+
*/
|
|
78
|
+
declare const FormControl: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>>;
|
|
79
|
+
declare const FormDescription: React.ForwardRefExoticComponent<Omit<HelperTextProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
80
|
+
/**
|
|
81
|
+
* The field's error, or nothing.
|
|
82
|
+
*
|
|
83
|
+
* Renders the validation message when there is one and `children` otherwise, so
|
|
84
|
+
* a field can carry a persistent hint that the error replaces. Renders nothing
|
|
85
|
+
* at all when there is neither, rather than an empty element that still takes up
|
|
86
|
+
* space in the layout.
|
|
87
|
+
*/
|
|
88
|
+
declare const FormMessage: React.ForwardRefExoticComponent<Omit<ErrorMessageProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
89
|
+
|
|
90
|
+
export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ErrorMessageProps } from './error-message.js';
|
|
2
|
+
import { HelperTextProps } from './helper-text.js';
|
|
3
|
+
import { LabelProps } from './label.js';
|
|
4
|
+
import * as react_hook_form from 'react-hook-form';
|
|
5
|
+
import { FieldValues, FieldPath, ControllerProps } from 'react-hook-form';
|
|
6
|
+
export { useFormContext } from 'react-hook-form';
|
|
7
|
+
import * as React from 'react';
|
|
8
|
+
import 'class-variance-authority/types';
|
|
9
|
+
import 'class-variance-authority';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wires react-hook-form to this library's Label, HelperText and ErrorMessage,
|
|
13
|
+
* and generates the ids that connect them.
|
|
14
|
+
*
|
|
15
|
+
* The three pieces have always existed separately, and connecting them was left
|
|
16
|
+
* to the caller: an id on the input, a matching htmlFor, an aria-describedby
|
|
17
|
+
* listing the description and the error, and aria-invalid toggled by hand. That
|
|
18
|
+
* is four things to get right per field, and the failure is silent - a form that
|
|
19
|
+
* looks correct and tells a screen reader nothing.
|
|
20
|
+
*
|
|
21
|
+
* `FormField` generates one id per field and `FormControl` applies the wiring, so
|
|
22
|
+
* a field is a label, a control and a message with no bookkeeping.
|
|
23
|
+
*
|
|
24
|
+
* ## react-hook-form is an optional peer dependency, and this is not in the barrel
|
|
25
|
+
*
|
|
26
|
+
* `react-hook-form` is around 25kB and most consumers of a component library do
|
|
27
|
+
* not want it forced on them, so it is an optional peer: install it if you use
|
|
28
|
+
* `Form`, and pay nothing if you do not.
|
|
29
|
+
*
|
|
30
|
+
* That only works if importing something unrelated cannot pull it in. A bundler
|
|
31
|
+
* has to *resolve* every import in a module before it can tree-shake anything,
|
|
32
|
+
* so a barrel that re-exported this file would fail to build for anyone without
|
|
33
|
+
* the peer installed, even if they only wanted `Button`. So `Form` is reachable
|
|
34
|
+
* only through its own entry point:
|
|
35
|
+
*
|
|
36
|
+
* import { Form, FormField } from "@jarllyng/nostromo/components/core/form";
|
|
37
|
+
*
|
|
38
|
+
* Verified rather than assumed - see the react-compat job, which installs the
|
|
39
|
+
* packed tarball into a project with no react-hook-form and imports the barrel.
|
|
40
|
+
*/
|
|
41
|
+
declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, resetDefaultValues, handleSubmit, unregister, control, register, setFocus, subscribe, }: react_hook_form.FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
|
|
42
|
+
/**
|
|
43
|
+
* One field: a name, and the ids that tie its parts together.
|
|
44
|
+
*
|
|
45
|
+
* Wraps react-hook-form's `Controller`, so it works with controlled components
|
|
46
|
+
* like `Select` and `Checkbox` as well as with plain inputs.
|
|
47
|
+
*/
|
|
48
|
+
declare function FormField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ ...props }: ControllerProps<TFieldValues, TName>): React.JSX.Element;
|
|
49
|
+
/**
|
|
50
|
+
* The ids and error state for the field being rendered.
|
|
51
|
+
*
|
|
52
|
+
* Throws rather than returning undefined when used outside a `FormField`. The
|
|
53
|
+
* quiet alternative is a label whose `htmlFor` points at nothing, which is the
|
|
54
|
+
* exact class of silent breakage this component exists to remove.
|
|
55
|
+
*/
|
|
56
|
+
declare function useFormField(): {
|
|
57
|
+
name: string;
|
|
58
|
+
formItemId: string;
|
|
59
|
+
formDescriptionId: string;
|
|
60
|
+
formMessageId: string;
|
|
61
|
+
error: {
|
|
62
|
+
message?: string;
|
|
63
|
+
} | undefined;
|
|
64
|
+
};
|
|
65
|
+
declare function FormItem({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
66
|
+
declare namespace FormItem {
|
|
67
|
+
var displayName: string;
|
|
68
|
+
}
|
|
69
|
+
declare const FormLabel: React.ForwardRefExoticComponent<Omit<LabelProps & React.RefAttributes<HTMLLabelElement>, "ref"> & React.RefAttributes<HTMLLabelElement>>;
|
|
70
|
+
/**
|
|
71
|
+
* Applies the wiring to whatever control it wraps.
|
|
72
|
+
*
|
|
73
|
+
* A `Slot`, so it passes the id and the aria attributes to the child rather than
|
|
74
|
+
* rendering an element of its own. `aria-describedby` lists the description and,
|
|
75
|
+
* when there is one, the message - both, because a field can have guidance and
|
|
76
|
+
* an error at the same time and a screen reader should hear both.
|
|
77
|
+
*/
|
|
78
|
+
declare const FormControl: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>>;
|
|
79
|
+
declare const FormDescription: React.ForwardRefExoticComponent<Omit<HelperTextProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
80
|
+
/**
|
|
81
|
+
* The field's error, or nothing.
|
|
82
|
+
*
|
|
83
|
+
* Renders the validation message when there is one and `children` otherwise, so
|
|
84
|
+
* a field can carry a persistent hint that the error replaces. Renders nothing
|
|
85
|
+
* at all when there is neither, rather than an empty element that still takes up
|
|
86
|
+
* space in the layout.
|
|
87
|
+
*/
|
|
88
|
+
declare const FormMessage: React.ForwardRefExoticComponent<Omit<ErrorMessageProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
89
|
+
|
|
90
|
+
export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {b as b$2}from'../../chunk-XQUZ7DUN.js';import {b as b$1}from'../../chunk-ABA7B5DE.js';import {b}from'../../chunk-LYVCB45L.js';import {a}from'../../chunk-AC2JBXHQ.js';import*as r from'react';import {Slot}from'@radix-ui/react-slot';import {useFormState,FormProvider,Controller}from'react-hook-form';export{useFormContext}from'react-hook-form';var v=FormProvider,f=r.createContext(null);function N({...e}){let t=r.useId(),o=r.useMemo(()=>({name:e.name,id:t}),[e.name,t]);return r.createElement(f.Provider,{value:o},r.createElement(Controller,{...e}))}function i(){let e=r.useContext(f);if(!e)throw new Error("useFormField must be used inside a <FormField>. Without it there is no field id to attach a label or a message to.");let{errors:t}=useFormState({name:e.name}),o=e.name.split(".").reduce((s,a)=>s?.[a],t);return {name:e.name,formItemId:e.id,formDescriptionId:`${e.id}-description`,formMessageId:`${e.id}-message`,error:o}}function g({className:e,...t}){return r.createElement("div",{className:a("space-y-1.5",e),...t})}g.displayName="FormItem";var y=r.forwardRef(({className:e,...t},o)=>{let{error:s,formItemId:a$1}=i();return r.createElement(b,{ref:o,htmlFor:a$1,className:a(s&&"text-destructive",e),...t})});y.displayName="FormLabel";var C=r.forwardRef(({...e},t)=>{let{error:o,formItemId:s,formDescriptionId:a,formMessageId:n}=i();return r.createElement(Slot,{ref:t,id:s,"aria-describedby":o?`${a} ${n}`:a,"aria-invalid":o?true:void 0,...e})});C.displayName="FormControl";var I=r.forwardRef(({...e},t)=>{let{formDescriptionId:o}=i();return r.createElement(b$1,{ref:t,id:o,...e})});I.displayName="FormDescription";var M=r.forwardRef(({children:e,...t},o)=>{let{error:s,formMessageId:a}=i(),n=s?.message??e;return n?r.createElement(b$2,{ref:o,id:a,...t},n):null});M.displayName="FormMessage";export{v as Form,C as FormControl,I as FormDescription,N as FormField,g as FormItem,y as FormLabel,M as FormMessage,i as useFormField};//# sourceMappingURL=form.js.map
|
|
3
|
+
//# sourceMappingURL=form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/core/form.tsx"],"names":["Form","FormProvider","FormFieldContext","FormField","props","id","value","Controller","useFormField","field","errors","useFormState","error","acc","key","FormItem","className","cn","FormLabel","ref","formItemId","Label","FormControl","formDescriptionId","formMessageId","Slot","FormDescription","HelperText","FormMessage","children","body","ErrorMessage"],"mappings":"6VAgDA,IAAMA,CAAAA,CAAOC,YAAAA,CAOPC,CAAAA,CAAyB,gBAC7B,IACF,EAQA,SAASC,CAAAA,CAGP,CAAE,GAAGC,CAAM,CAAA,CAAyC,CACpD,IAAMC,CAAAA,CAAW,CAAA,CAAA,KAAA,EAAM,CACjBC,CAAAA,CAAc,UAClB,KAAO,CAAE,IAAA,CAAMF,CAAAA,CAAM,KAAgB,EAAA,CAAAC,CAAG,CAAA,CAAA,CACxC,CAACD,EAAM,IAAA,CAAMC,CAAE,CACjB,CAAA,CACA,OACE,CAAA,CAAA,aAAA,CAACH,CAAAA,CAAiB,QAAA,CAAjB,CAA0B,MAAOI,CAAAA,CAAAA,CAChC,CAAA,CAAA,aAAA,CAACC,UAAAA,CAAA,CAAY,GAAGH,CAAAA,CAAO,CACzB,CAEJ,CASA,SAASI,CAAAA,EAAe,CACtB,IAAMC,CAAAA,CAAc,aAAWP,CAAgB,CAAA,CAC/C,GAAI,CAACO,CAAAA,CACH,MAAM,IAAI,KAAA,CACR,oHACF,CAAA,CAEF,GAAM,CAAE,MAAA,CAAAC,CAAO,CAAA,CAAIC,aAAa,CAAE,IAAA,CAAMF,CAAAA,CAAM,IAAK,CAAC,CAAA,CAE9CG,CAAAA,CAAQH,CAAAA,CAAM,IAAA,CACjB,MAAM,GAAG,CAAA,CACT,MAAA,CACC,CAACI,EAAKC,CAAAA,GAASD,CAAAA,GAAkCC,CAAG,CAAA,CACpDJ,CACF,CAAA,CAEF,OAAO,CACL,IAAA,CAAMD,EAAM,IAAA,CACZ,UAAA,CAAYA,EAAM,EAAA,CAClB,iBAAA,CAAmB,GAAGA,CAAAA,CAAM,EAAE,CAAA,YAAA,CAAA,CAC9B,aAAA,CAAe,GAAGA,CAAAA,CAAM,EAAE,CAAA,QAAA,CAAA,CAC1B,KAAA,CAAOG,CACT,CACF,CAEA,SAASG,CAAAA,CAAS,CAChB,SAAA,CAAAC,CAAAA,CACA,GAAGZ,CACL,EAAyC,CACvC,OAAO,CAAA,CAAA,aAAA,CAAC,KAAA,CAAA,CAAI,UAAWa,CAAAA,CAAG,aAAA,CAAeD,CAAS,CAAA,CAAI,GAAGZ,CAAAA,CAAO,CAClE,CACAW,CAAAA,CAAS,YAAc,UAAA,CAEvB,IAAMG,EAAkB,CAAA,CAAA,UAAA,CAGtB,CAAC,CAAE,SAAA,CAAAF,CAAAA,CAAW,GAAGZ,CAAM,EAAGe,CAAAA,GAAQ,CAClC,GAAM,CAAE,MAAAP,CAAAA,CAAO,UAAA,CAAAQ,GAAW,CAAA,CAAIZ,GAAa,CAC3C,OACE,CAAA,CAAA,aAAA,CAACa,CAAAA,CAAA,CACC,GAAA,CAAKF,CAAAA,CACL,OAAA,CAASC,GAAAA,CACT,UAAWH,CAAAA,CAAGL,CAAAA,EAAS,kBAAA,CAAoBI,CAAS,EACnD,GAAGZ,CAAAA,CACN,CAEJ,CAAC,EACDc,CAAAA,CAAU,WAAA,CAAc,YAUxB,IAAMI,CAAAA,CAAoB,aAGxB,CAAC,CAAE,GAAGlB,CAAM,EAAGe,CAAAA,GAAQ,CACvB,GAAM,CAAE,MAAAP,CAAAA,CAAO,UAAA,CAAAQ,CAAAA,CAAY,iBAAA,CAAAG,EAAmB,aAAA,CAAAC,CAAc,CAAA,CAC1DhB,CAAAA,GACF,OACE,CAAA,CAAA,aAAA,CAACiB,IAAAA,CAAA,CACC,IAAKN,CAAAA,CACL,EAAA,CAAIC,CAAAA,CACJ,kBAAA,CACER,EAAQ,CAAA,EAAGW,CAAiB,CAAA,CAAA,EAAIC,CAAa,GAAKD,CAAAA,CAEpD,cAAA,CAAcX,EAAQ,IAAA,CAAO,MAAA,CAC5B,GAAGR,CAAAA,CACN,CAEJ,CAAC,EACDkB,EAAY,WAAA,CAAc,aAAA,CAE1B,IAAMI,CAAAA,CAAwB,aAG5B,CAAC,CAAE,GAAGtB,CAAM,EAAGe,CAAAA,GAAQ,CACvB,GAAM,CAAE,kBAAAI,CAAkB,CAAA,CAAIf,CAAAA,EAAa,CAC3C,OAAO,CAAA,CAAA,aAAA,CAACmB,GAAAA,CAAA,CAAW,GAAA,CAAKR,EAAK,EAAA,CAAII,CAAAA,CAAoB,GAAGnB,CAAAA,CAAO,CACjE,CAAC,EACDsB,EAAgB,WAAA,CAAc,iBAAA,KAUxBE,CAAAA,CAAoB,CAAA,CAAA,UAAA,CAGxB,CAAC,CAAE,SAAAC,CAAAA,CAAU,GAAGzB,CAAM,CAAA,CAAGe,IAAQ,CACjC,GAAM,CAAE,KAAA,CAAAP,EAAO,aAAA,CAAAY,CAAc,CAAA,CAAIhB,CAAAA,GAC3BsB,CAAAA,CAAOlB,CAAAA,EAAO,OAAA,EAAWiB,CAAAA,CAC/B,OAAKC,CAAAA,CAGH,CAAA,CAAA,aAAA,CAACC,GAAAA,CAAA,CAAa,IAAKZ,CAAAA,CAAK,EAAA,CAAIK,CAAAA,CAAgB,GAAGpB,GAC5C0B,CACH,CAAA,CALgB,IAOpB,CAAC,EACDF,EAAY,WAAA,CAAc,aAAA","file":"form.js","sourcesContent":["import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\";\n\nimport { cn } from \"../../lib/utils\";\nimport { ErrorMessage } from \"./error-message\";\nimport { HelperText } from \"./helper-text\";\nimport { Label } from \"./label\";\n\n/**\n * Wires react-hook-form to this library's Label, HelperText and ErrorMessage,\n * and generates the ids that connect them.\n *\n * The three pieces have always existed separately, and connecting them was left\n * to the caller: an id on the input, a matching htmlFor, an aria-describedby\n * listing the description and the error, and aria-invalid toggled by hand. That\n * is four things to get right per field, and the failure is silent - a form that\n * looks correct and tells a screen reader nothing.\n *\n * `FormField` generates one id per field and `FormControl` applies the wiring, so\n * a field is a label, a control and a message with no bookkeeping.\n *\n * ## react-hook-form is an optional peer dependency, and this is not in the barrel\n *\n * `react-hook-form` is around 25kB and most consumers of a component library do\n * not want it forced on them, so it is an optional peer: install it if you use\n * `Form`, and pay nothing if you do not.\n *\n * That only works if importing something unrelated cannot pull it in. A bundler\n * has to *resolve* every import in a module before it can tree-shake anything,\n * so a barrel that re-exported this file would fail to build for anyone without\n * the peer installed, even if they only wanted `Button`. So `Form` is reachable\n * only through its own entry point:\n *\n * import { Form, FormField } from \"@jarllyng/nostromo/components/core/form\";\n *\n * Verified rather than assumed - see the react-compat job, which installs the\n * packed tarball into a project with no react-hook-form and imports the barrel.\n */\n\nconst Form = FormProvider;\n\ninterface FormFieldContextValue {\n name: string;\n id: string;\n}\n\nconst FormFieldContext = React.createContext<FormFieldContextValue | null>(\n null,\n);\n\n/**\n * One field: a name, and the ids that tie its parts together.\n *\n * Wraps react-hook-form's `Controller`, so it works with controlled components\n * like `Select` and `Checkbox` as well as with plain inputs.\n */\nfunction FormField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({ ...props }: ControllerProps<TFieldValues, TName>) {\n const id = React.useId();\n const value = React.useMemo(\n () => ({ name: props.name as string, id }),\n [props.name, id],\n );\n return (\n <FormFieldContext.Provider value={value}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n}\n\n/**\n * The ids and error state for the field being rendered.\n *\n * Throws rather than returning undefined when used outside a `FormField`. The\n * quiet alternative is a label whose `htmlFor` points at nothing, which is the\n * exact class of silent breakage this component exists to remove.\n */\nfunction useFormField() {\n const field = React.useContext(FormFieldContext);\n if (!field) {\n throw new Error(\n \"useFormField must be used inside a <FormField>. Without it there is no field id to attach a label or a message to.\",\n );\n }\n const { errors } = useFormState({ name: field.name });\n // Nested names like \"address.city\" reach into the error object.\n const error = field.name\n .split(\".\")\n .reduce<unknown>(\n (acc, key) => (acc as Record<string, unknown>)?.[key],\n errors,\n );\n\n return {\n name: field.name,\n formItemId: field.id,\n formDescriptionId: `${field.id}-description`,\n formMessageId: `${field.id}-message`,\n error: error as { message?: string } | undefined,\n };\n}\n\nfunction FormItem({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn(\"space-y-1.5\", className)} {...props} />;\n}\nFormItem.displayName = \"FormItem\";\n\nconst FormLabel = React.forwardRef<\n React.ElementRef<typeof Label>,\n React.ComponentPropsWithoutRef<typeof Label>\n>(({ className, ...props }, ref) => {\n const { error, formItemId } = useFormField();\n return (\n <Label\n ref={ref}\n htmlFor={formItemId}\n className={cn(error && \"text-destructive\", className)}\n {...props}\n />\n );\n});\nFormLabel.displayName = \"FormLabel\";\n\n/**\n * Applies the wiring to whatever control it wraps.\n *\n * A `Slot`, so it passes the id and the aria attributes to the child rather than\n * rendering an element of its own. `aria-describedby` lists the description and,\n * when there is one, the message - both, because a field can have guidance and\n * an error at the same time and a screen reader should hear both.\n */\nconst FormControl = React.forwardRef<\n HTMLElement,\n React.HTMLAttributes<HTMLElement>\n>(({ ...props }, ref) => {\n const { error, formItemId, formDescriptionId, formMessageId } =\n useFormField();\n return (\n <Slot\n ref={ref}\n id={formItemId}\n aria-describedby={\n error ? `${formDescriptionId} ${formMessageId}` : formDescriptionId\n }\n aria-invalid={error ? true : undefined}\n {...props}\n />\n );\n});\nFormControl.displayName = \"FormControl\";\n\nconst FormDescription = React.forwardRef<\n React.ElementRef<typeof HelperText>,\n React.ComponentPropsWithoutRef<typeof HelperText>\n>(({ ...props }, ref) => {\n const { formDescriptionId } = useFormField();\n return <HelperText ref={ref} id={formDescriptionId} {...props} />;\n});\nFormDescription.displayName = \"FormDescription\";\n\n/**\n * The field's error, or nothing.\n *\n * Renders the validation message when there is one and `children` otherwise, so\n * a field can carry a persistent hint that the error replaces. Renders nothing\n * at all when there is neither, rather than an empty element that still takes up\n * space in the layout.\n */\nconst FormMessage = React.forwardRef<\n React.ElementRef<typeof ErrorMessage>,\n React.ComponentPropsWithoutRef<typeof ErrorMessage>\n>(({ children, ...props }, ref) => {\n const { error, formMessageId } = useFormField();\n const body = error?.message ?? children;\n if (!body) return null;\n\n return (\n <ErrorMessage ref={ref} id={formMessageId} {...props}>\n {body}\n </ErrorMessage>\n );\n});\nFormMessage.displayName = \"FormMessage\";\n\nexport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n useFormField,\n useFormContext,\n};\n"]}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const helperTextVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "error" | "default" | "success" | "warning" | "info" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface HelperTextProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof helperTextVariants> {
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const helperTextVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "error" | "default" | "success" | "warning" | "info" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface HelperTextProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof helperTextVariants> {
|
|
@@ -6,8 +6,8 @@ declare const iconMap: Record<string, React__default.ElementType>;
|
|
|
6
6
|
type IconName = keyof typeof iconMap;
|
|
7
7
|
declare const iconVariants: (props?: ({
|
|
8
8
|
size?: "sm" | "lg" | "xl" | "xs" | "md" | "2xl" | "3xl" | null | undefined;
|
|
9
|
-
weight?: "
|
|
10
|
-
color?: "
|
|
9
|
+
weight?: "fill" | "bold" | "light" | "thin" | "regular" | "duotone" | null | undefined;
|
|
10
|
+
color?: "error" | "secondary" | "success" | "current" | "warning" | "muted" | "primary" | null | undefined;
|
|
11
11
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
12
12
|
interface IconProps extends Omit<React__default.HTMLAttributes<SVGSVGElement>, "color">, VariantProps<typeof iconVariants> {
|
|
13
13
|
name: IconName;
|
|
@@ -6,8 +6,8 @@ declare const iconMap: Record<string, React__default.ElementType>;
|
|
|
6
6
|
type IconName = keyof typeof iconMap;
|
|
7
7
|
declare const iconVariants: (props?: ({
|
|
8
8
|
size?: "sm" | "lg" | "xl" | "xs" | "md" | "2xl" | "3xl" | null | undefined;
|
|
9
|
-
weight?: "
|
|
10
|
-
color?: "
|
|
9
|
+
weight?: "fill" | "bold" | "light" | "thin" | "regular" | "duotone" | null | undefined;
|
|
10
|
+
color?: "error" | "secondary" | "success" | "current" | "warning" | "muted" | "primary" | null | undefined;
|
|
11
11
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
12
12
|
interface IconProps extends Omit<React__default.HTMLAttributes<SVGSVGElement>, "color">, VariantProps<typeof iconVariants> {
|
|
13
13
|
name: IconName;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';var chunkBJPJB6IA_cjs=require('../../chunk-BJPJB6IA.cjs');require('../../chunk-ITRGJNWL.cjs');Object.defineProperty(exports,"InputOTP",{enumerable:true,get:function(){return chunkBJPJB6IA_cjs.a}});Object.defineProperty(exports,"InputOTPGroup",{enumerable:true,get:function(){return chunkBJPJB6IA_cjs.b}});Object.defineProperty(exports,"InputOTPSeparator",{enumerable:true,get:function(){return chunkBJPJB6IA_cjs.d}});Object.defineProperty(exports,"InputOTPSlot",{enumerable:true,get:function(){return chunkBJPJB6IA_cjs.c}});//# sourceMappingURL=input-otp.cjs.map
|
|
3
|
+
//# sourceMappingURL=input-otp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"input-otp.cjs"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { OTPInputProps } from 'input-otp';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A one-time code, one character per box.
|
|
6
|
+
*
|
|
7
|
+
* There is exactly one `<input>`, stretched across the whole row and made
|
|
8
|
+
* invisible. The boxes are divs that read their character out of context. That
|
|
9
|
+
* is what makes paste, autofill, `autocomplete="one-time-code"`, backspace and
|
|
10
|
+
* mobile keyboards work: the browser sees a single ordinary text field. A row of
|
|
11
|
+
* six real inputs looks the same and gets all of that wrong.
|
|
12
|
+
*
|
|
13
|
+
* The consequence, and the one thing worth knowing: the caret you see is drawn
|
|
14
|
+
* by CSS, because the real caret is not where the boxes are.
|
|
15
|
+
*
|
|
16
|
+
* ## Slots are positional
|
|
17
|
+
*
|
|
18
|
+
* `InputOTPSlot` takes an `index`, and the indices must run 0..maxLength-1 in
|
|
19
|
+
* document order. Nothing enforces it, because the boxes are yours to arrange -
|
|
20
|
+
* `InputOTPSeparator` sits between groups, and the grouping is a visual choice
|
|
21
|
+
* that this component should not make for you.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* `containerClassName` styles the row of boxes; `className` styles the hidden
|
|
25
|
+
* input.
|
|
26
|
+
*
|
|
27
|
+
* A re-export rather than an interface of our own. The upstream type is a union
|
|
28
|
+
* - `render` or `children`, never both - and `interface extends` flattens a
|
|
29
|
+
* union into one object with every member optional, which would let both through
|
|
30
|
+
* at once. Same reason the props below are spread whole instead of destructured:
|
|
31
|
+
* `Omit` over a union collapses it too.
|
|
32
|
+
*/
|
|
33
|
+
type InputOTPProps = OTPInputProps;
|
|
34
|
+
declare const InputOTP: React.ForwardRefExoticComponent<OTPInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
35
|
+
/**
|
|
36
|
+
* One group of boxes.
|
|
37
|
+
*
|
|
38
|
+
* The boxes inside a group share borders, so the group reads as one field split
|
|
39
|
+
* into cells rather than as separate inputs.
|
|
40
|
+
*/
|
|
41
|
+
declare const InputOTPGroup: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
42
|
+
interface InputOTPSlotProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
43
|
+
/** Position in the code, from 0. Must match the order on screen. */
|
|
44
|
+
index: number;
|
|
45
|
+
}
|
|
46
|
+
declare const InputOTPSlot: React.ForwardRefExoticComponent<InputOTPSlotProps & React.RefAttributes<HTMLDivElement>>;
|
|
47
|
+
/** A gap between groups. Decorative, so it is hidden rather than announced. */
|
|
48
|
+
declare const InputOTPSeparator: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
49
|
+
|
|
50
|
+
export { InputOTP, InputOTPGroup, type InputOTPProps, InputOTPSeparator, InputOTPSlot, type InputOTPSlotProps };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { OTPInputProps } from 'input-otp';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A one-time code, one character per box.
|
|
6
|
+
*
|
|
7
|
+
* There is exactly one `<input>`, stretched across the whole row and made
|
|
8
|
+
* invisible. The boxes are divs that read their character out of context. That
|
|
9
|
+
* is what makes paste, autofill, `autocomplete="one-time-code"`, backspace and
|
|
10
|
+
* mobile keyboards work: the browser sees a single ordinary text field. A row of
|
|
11
|
+
* six real inputs looks the same and gets all of that wrong.
|
|
12
|
+
*
|
|
13
|
+
* The consequence, and the one thing worth knowing: the caret you see is drawn
|
|
14
|
+
* by CSS, because the real caret is not where the boxes are.
|
|
15
|
+
*
|
|
16
|
+
* ## Slots are positional
|
|
17
|
+
*
|
|
18
|
+
* `InputOTPSlot` takes an `index`, and the indices must run 0..maxLength-1 in
|
|
19
|
+
* document order. Nothing enforces it, because the boxes are yours to arrange -
|
|
20
|
+
* `InputOTPSeparator` sits between groups, and the grouping is a visual choice
|
|
21
|
+
* that this component should not make for you.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* `containerClassName` styles the row of boxes; `className` styles the hidden
|
|
25
|
+
* input.
|
|
26
|
+
*
|
|
27
|
+
* A re-export rather than an interface of our own. The upstream type is a union
|
|
28
|
+
* - `render` or `children`, never both - and `interface extends` flattens a
|
|
29
|
+
* union into one object with every member optional, which would let both through
|
|
30
|
+
* at once. Same reason the props below are spread whole instead of destructured:
|
|
31
|
+
* `Omit` over a union collapses it too.
|
|
32
|
+
*/
|
|
33
|
+
type InputOTPProps = OTPInputProps;
|
|
34
|
+
declare const InputOTP: React.ForwardRefExoticComponent<OTPInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
35
|
+
/**
|
|
36
|
+
* One group of boxes.
|
|
37
|
+
*
|
|
38
|
+
* The boxes inside a group share borders, so the group reads as one field split
|
|
39
|
+
* into cells rather than as separate inputs.
|
|
40
|
+
*/
|
|
41
|
+
declare const InputOTPGroup: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
42
|
+
interface InputOTPSlotProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
43
|
+
/** Position in the code, from 0. Must match the order on screen. */
|
|
44
|
+
index: number;
|
|
45
|
+
}
|
|
46
|
+
declare const InputOTPSlot: React.ForwardRefExoticComponent<InputOTPSlotProps & React.RefAttributes<HTMLDivElement>>;
|
|
47
|
+
/** A gap between groups. Decorative, so it is hidden rather than announced. */
|
|
48
|
+
declare const InputOTPSeparator: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
49
|
+
|
|
50
|
+
export { InputOTP, InputOTPGroup, type InputOTPProps, InputOTPSeparator, InputOTPSlot, type InputOTPSlotProps };
|