orynn 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/cx.ts","../src/controls/Field/Field.tsx","../src/controls/Dropdown/Dropdown.tsx","../src/controls/Input/Input.tsx","../src/internal/dev.ts","../src/core/registry/registry.ts","../src/layout/resolve-columns.ts","../src/core/config/normalize.ts","../src/core/validation/messages.ts","../src/core/validation/rules.ts","../src/core/validation/resolver.ts","../src/core/state/reducer.ts","../src/core/state/use-latest-ref.ts","../src/core/state/use-controllable-state.ts","../src/core/state/use-fieldset-state.ts","../src/layout/FieldGrid.tsx","../src/fieldset/FieldRenderer.tsx","../src/fieldset/register-builtins.tsx","../src/fieldset/Fieldset.tsx","../src/types/validation.ts"],"names":["Dropdown","jsx","jsxs","forwardRef","Input","useCallback","registry","useRef","defaultRegistry"],"mappings":"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","file":"index.js","sourcesContent":["/** Join truthy class names with a space. */\nexport function cx(...names: Array<string | false | null | undefined>): string {\n return names.filter(Boolean).join(\" \");\n}\n","import { useId } from \"react\";\nimport { cx } from \"../../internal/cx\";\nimport type { ErrorProp, FieldProps, FieldRenderContext } from \"../../types/props\";\n\nfunction toMessages(error: ErrorProp): string[] {\n if (error == null) return [];\n return (Array.isArray(error) ? error : [error]).filter((m): m is string => Boolean(m));\n}\n\nfunction joinIds(...ids: Array<string | undefined>): string | undefined {\n const list = ids.filter((id): id is string => Boolean(id));\n return list.length > 0 ? list.join(\" \") : undefined;\n}\n\n/**\n * Layout + accessibility wrapper for a single control. Renders the label,\n * optional description, and an error region, and wires the ARIA relationships\n * (`htmlFor`, `aria-describedby`, `aria-invalid`, `aria-required`).\n *\n * Pass a render function as `children` to receive the resolved ids:\n *\n * ```tsx\n * <Field label=\"Name\" error={error}>\n * {({ id, describedById, invalid }) => (\n * <input id={id} aria-describedby={describedById} aria-invalid={invalid} />\n * )}\n * </Field>\n * ```\n */\nexport function Field(props: FieldProps) {\n const { label, description, error, required, disabled, className, children } = props;\n\n const reactId = useId();\n const id = props.id ?? reactId;\n\n const messages = toMessages(error);\n const invalid = messages.length > 0;\n\n const descriptionId = description != null ? `${id}-description` : undefined;\n const errorId = invalid ? `${id}-error` : undefined;\n const describedById = joinIds(descriptionId, errorId);\n\n const ctx: FieldRenderContext = { id, describedById, invalid, required, disabled };\n\n return (\n <div\n className={cx(\"orynn-field\", className)}\n data-invalid={invalid || undefined}\n data-disabled={disabled || undefined}\n data-required={required || undefined}\n >\n {label != null && (\n <label className=\"orynn-field__label\" htmlFor={id}>\n {label}\n </label>\n )}\n\n {description != null && (\n <p className=\"orynn-field__description\" id={descriptionId}>\n {description}\n </p>\n )}\n\n <div className=\"orynn-field__control\">\n {typeof children === \"function\" ? children(ctx) : children}\n </div>\n\n {invalid && (\n <p className=\"orynn-field__error\" id={errorId} role=\"alert\">\n {messages.length === 1 ? messages[0] : messages.map((m) => <span key={m}>{m}</span>)}\n </p>\n )}\n </div>\n );\n}\n","import { type ChangeEvent, forwardRef, useCallback } from \"react\";\nimport type { DropdownProps } from \"../../types/props\";\nimport { Field } from \"../Field/Field\";\n\n/**\n * A labelled single-select built on the native `<select>` element (accessible\n * and keyboard-navigable out of the box). Works with or without `<Fieldset>`.\n */\nexport const Dropdown = /* @__PURE__ */ forwardRef<HTMLSelectElement, DropdownProps>(\n function Dropdown(props, ref) {\n const {\n label,\n description,\n error,\n className,\n options,\n value,\n onChange,\n placeholder,\n id,\n required,\n disabled,\n onBlur,\n onFocus,\n ...rest\n } = props;\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLSelectElement>) => onChange?.(event.target.value, event),\n [onChange],\n );\n\n const controlled = value !== undefined;\n\n return (\n <Field\n label={label}\n description={description}\n error={error}\n required={required}\n disabled={disabled}\n id={id}\n className={className}\n >\n {({ id: fieldId, describedById, invalid }) => (\n <select\n {...rest}\n ref={ref}\n id={fieldId}\n className=\"orynn-dropdown\"\n required={required}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={describedById}\n {...(controlled ? { value } : {})}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n >\n {placeholder != null && (\n <option value=\"\" disabled={required}>\n {placeholder}\n </option>\n )}\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n </Field>\n );\n },\n);\n","import { type ChangeEvent, forwardRef, useCallback } from \"react\";\nimport type { InputProps } from \"../../types/props\";\nimport { Field } from \"../Field/Field\";\n\n/**\n * A labelled text input. Controlled when `value` is passed, uncontrolled\n * otherwise (`defaultValue` flows through to the native element). Works with or\n * without `<Fieldset>`.\n */\nexport const Input = /* @__PURE__ */ forwardRef<HTMLInputElement, InputProps>(\n function Input(props, ref) {\n const {\n label,\n description,\n error,\n className,\n value,\n onChange,\n type = \"text\",\n id,\n required,\n disabled,\n readOnly,\n onBlur,\n onFocus,\n ...rest\n } = props;\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => onChange?.(event.target.value, event),\n [onChange],\n );\n\n const controlled = value !== undefined;\n\n return (\n <Field\n label={label}\n description={description}\n error={error}\n required={required}\n disabled={disabled}\n id={id}\n className={className}\n >\n {({ id: fieldId, describedById, invalid }) => (\n <input\n {...rest}\n ref={ref}\n id={fieldId}\n className=\"orynn-input\"\n type={type}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={invalid || undefined}\n aria-describedby={describedById}\n {...(controlled ? { value } : {})}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n )}\n </Field>\n );\n },\n);\n","/**\n * Development-only helpers. `__DEV__` is statically replaceable by bundlers, so\n * `invariant` / `warnOnce` bodies tree-shake out of production builds.\n */\nexport const __DEV__: boolean =\n typeof process !== \"undefined\" && process.env?.NODE_ENV !== \"production\";\n\n/** Throws in development when `condition` is falsy. No-op in production. */\nexport function invariant(condition: unknown, message: string): asserts condition {\n if (condition) return;\n if (__DEV__) {\n throw new Error(`[orynn] ${message}`);\n }\n}\n\nconst warned = new Set<string>();\n\n/** Logs a warning once per unique message. Silent in production. */\nexport function warnOnce(message: string): void {\n if (!__DEV__ || warned.has(message)) return;\n warned.add(message);\n console.warn(`[orynn] ${message}`);\n}\n\n/** Test-only: clear the warn-once cache between cases. */\nexport function resetWarnings(): void {\n warned.clear();\n}\n","import { __DEV__, warnOnce } from \"../../internal/dev\";\nimport type { FieldRegistration, FieldRegistry } from \"../../types/control\";\n\nclass Registry implements FieldRegistry {\n #entries = new Map<string, FieldRegistration>();\n\n register(type: string, registration: FieldRegistration): void {\n if (__DEV__ && this.#entries.has(type)) {\n warnOnce(`Field type \"${type}\" is being re-registered; the previous definition is replaced.`);\n }\n this.#entries.set(type, registration);\n }\n\n get(type: string): FieldRegistration | undefined {\n return this.#entries.get(type);\n }\n\n has(type: string): boolean {\n return this.#entries.has(type);\n }\n\n types(): string[] {\n return [...this.#entries.keys()];\n }\n}\n\n/**\n * Create an isolated field registry. Use this to give a `<Fieldset>` its own set\n * of field types without touching the module-global {@link defaultRegistry}\n * (recommended on the server, where mutating a shared registry per request would\n * leak between requests).\n *\n * @experimental The registry API may change before 1.0.\n */\nexport function createRegistry(): FieldRegistry {\n return new Registry();\n}\n\n/**\n * The module-global registry used by `<Fieldset>` when no `registry` prop is\n * passed. Seeded with the built-in `input` and `dropdown` fields.\n *\n * @experimental\n */\nexport const defaultRegistry: FieldRegistry = /* @__PURE__ */ createRegistry();\n\n/**\n * Register a field type on the {@link defaultRegistry}. Call this once at\n * application start-up, not per render or per request.\n *\n * @experimental\n */\nexport function registerField(type: string, registration: FieldRegistration): void {\n defaultRegistry.register(type, registration);\n}\n","import type { ColumnSpec } from \"../types/config\";\n\n/** V1 default: 3 columns on desktop, 2 on tablet, 1 on mobile. */\nexport const DEFAULT_COLUMNS: ColumnSpec = { desktop: 3, tablet: 2, mobile: 1 };\n\nconst clampCount = (n: unknown, fallback: number): number =>\n typeof n === \"number\" && Number.isFinite(n) && n >= 1 ? Math.floor(n) : fallback;\n\n/** Merge a partial column spec onto the defaults. */\nexport function resolveColumns(partial?: Partial<ColumnSpec>): ColumnSpec {\n return {\n desktop: clampCount(partial?.desktop, DEFAULT_COLUMNS.desktop),\n tablet: clampCount(partial?.tablet, DEFAULT_COLUMNS.tablet),\n mobile: clampCount(partial?.mobile, DEFAULT_COLUMNS.mobile),\n };\n}\n\n/** Clamp a field's column span so it never exceeds the row's column count. */\nexport function clampSpan(span: unknown, columnCount: number): number {\n const n = clampCount(span, 1);\n return Math.min(n, Math.max(columnCount, 1));\n}\n","import { invariant } from \"../../internal/dev\";\nimport { resolveColumns } from \"../../layout/resolve-columns\";\nimport type { ColumnSpec, FieldConfig, FieldsetConfig } from \"../../types/config\";\nimport type { FieldRegistry } from \"../../types/control\";\n\n/** A validated `FieldsetConfig` with every default resolved. */\nexport interface NormalizedFieldsetConfig {\n fields: FieldConfig[];\n columns: ColumnSpec;\n /** CSS length for the grid gap, or `undefined` to use the token default. */\n gap: string | undefined;\n legend: string | undefined;\n id: string | undefined;\n}\n\nfunction normalizeGap(gap: FieldsetConfig[\"gap\"]): string | undefined {\n if (gap == null) return undefined;\n return typeof gap === \"number\" ? `${gap}px` : gap;\n}\n\n/**\n * Validate a `FieldsetConfig` and resolve its defaults. Structural problems\n * throw in development with an actionable message; in production the checks are\n * stripped and normalization is defensive.\n *\n * Pass `registry` (as `<Fieldset>` does) to also validate each field's `type`\n * and run type-specific config checks.\n */\nexport function normalizeConfig(\n config: FieldsetConfig,\n registry?: FieldRegistry,\n): NormalizedFieldsetConfig {\n invariant(\n config != null && typeof config === \"object\" && Array.isArray(config.fields),\n \"`config` must be an object with a `fields` array.\",\n );\n\n const seen = new Set<string>();\n\n for (const field of config.fields) {\n invariant(\n field != null && typeof field === \"object\",\n \"Every entry in `config.fields` must be an object.\",\n );\n invariant(\n typeof field.name === \"string\" && field.name.length > 0,\n \"Every field needs a non-empty string `name`.\",\n );\n invariant(!seen.has(field.name), `Duplicate field name \"${field.name}\" in config.fields.`);\n seen.add(field.name);\n invariant(\n typeof field.type === \"string\" && field.type.length > 0,\n `Field \"${field.name}\" is missing a \"type\".`,\n );\n\n if (registry) {\n invariant(\n registry.has(field.type),\n `Unknown field type \"${field.type}\" on field \"${field.name}\". ` +\n `Registered types: ${registry.types().join(\", \") || \"(none)\"}.`,\n );\n const typeError = registry.get(field.type)?.validateConfig?.(field);\n invariant(typeError == null, `Field \"${field.name}\" (${field.type}): ${typeError}`);\n }\n }\n\n return {\n fields: config.fields,\n columns: resolveColumns(config.columns),\n gap: normalizeGap(config.gap),\n legend: config.legend,\n id: config.id,\n };\n}\n","/** Formats the default message for a built-in rule token. */\ntype MessageFormatter = (ctx: { param: unknown; label: string }) => string;\n\nconst plural = (n: unknown, word: string) => `${n} ${word}${n === 1 ? \"\" : \"s\"}`;\n\n/** Default message templates for the built-in rules. */\nexport const defaultMessages: Record<string, MessageFormatter> = {\n required: ({ label }) => `${label} is required`,\n minLength: ({ param, label }) => `${label} must be at least ${plural(param, \"character\")}`,\n maxLength: ({ param, label }) => `${label} must be at most ${plural(param, \"character\")}`,\n};\n\nconst FALLBACK_LABEL = \"This field\";\n\n/**\n * Resolve the message for a failed rule.\n *\n * Precedence: a per-field override (`validation.messages[token]`) wins; otherwise\n * a built-in template is used; otherwise the token itself is the message (custom\n * rules return a ready-to-show string).\n */\nexport function resolveMessage(\n token: string,\n param: unknown,\n label: string | undefined,\n overrides: Partial<Record<string, string>> | undefined,\n): string {\n const override = overrides?.[token];\n if (override != null) return override;\n\n const formatter = defaultMessages[token];\n if (formatter) return formatter({ param, label: label ?? FALLBACK_LABEL });\n\n return token;\n}\n","import type { RuleFn } from \"../../types/validation\";\n\nconst isEmpty = (value: unknown): boolean =>\n value == null || value === \"\" || (Array.isArray(value) && value.length === 0);\n\nconst asLength = (value: unknown): number =>\n typeof value === \"string\" || Array.isArray(value) ? value.length : String(value ?? \"\").length;\n\n/**\n * Built-in rules. Each returns a token (rule name) on failure or `null` on\n * success; the resolver turns the token into a user-facing message.\n *\n * `minLength` deliberately ignores empty values so `required` owns that error.\n */\nexport const builtInRules: { required: RuleFn; minLength: RuleFn; maxLength: RuleFn } = {\n required: (value, param) => {\n if (param === false) return null;\n return isEmpty(value) ? \"required\" : null;\n },\n minLength: (value, param) => {\n if (typeof param !== \"number\" || isEmpty(value)) return null;\n return asLength(value) < param ? \"minLength\" : null;\n },\n maxLength: (value, param) => {\n if (typeof param !== \"number\" || isEmpty(value)) return null;\n return asLength(value) > param ? \"maxLength\" : null;\n },\n};\n\nconst registry = new Map<string, RuleFn>(Object.entries(builtInRules));\n\n/**\n * Register a validation rule for the built-in resolver. A field opts in by\n * adding a key of the same name to its `validation` config.\n *\n * @experimental The rule API may change before 1.0.\n */\nexport function registerRule(name: string, fn: RuleFn): void {\n registry.set(name, fn);\n}\n\nexport function getRule(name: string): RuleFn | undefined {\n return registry.get(name);\n}\n\nexport function ruleNames(): string[] {\n return [...registry.keys()];\n}\n","import { __DEV__, warnOnce } from \"../../internal/dev\";\nimport type { FieldsetConfig } from \"../../types/config\";\nimport type {\n FieldError,\n ValidationContext,\n ValidationResolver,\n ValidationResult,\n} from \"../../types/validation\";\nimport { resolveMessage } from \"./messages\";\nimport { getRule } from \"./rules\";\n\n/** A synchronous resolver — the built-in resolver's precise return type. */\nexport type SyncResolver = (\n values: Record<string, unknown>,\n config: FieldsetConfig,\n context: ValidationContext,\n) => ValidationResult;\n\n/**\n * The default, rule-based {@link ValidationResolver}. For every field with a\n * `validation` block, each key (other than `messages`) is looked up in the rule\n * registry and run against the field's current value. All fields are validated\n * on every call; callers decide which errors to surface.\n *\n * Synchronous today. Async, schema-based, and cross-field resolvers plug in at\n * the same seam without an API change.\n */\nexport function createRuleResolver(): SyncResolver {\n return (values, config): ValidationResult => {\n const result: ValidationResult = {};\n\n for (const field of config.fields) {\n const validation = field.validation;\n if (!validation) continue;\n\n const value = values[field.name];\n const errors: FieldError[] = [];\n\n for (const key of Object.keys(validation)) {\n if (key === \"messages\") continue;\n\n const param = (validation as Record<string, unknown>)[key];\n if (param === undefined || param === false) continue;\n\n const rule = getRule(key);\n if (!rule) {\n if (__DEV__) {\n warnOnce(`No validator registered for rule \"${key}\" (field \"${field.name}\").`);\n }\n continue;\n }\n\n const token = rule(value, param, values);\n if (token == null) continue;\n\n errors.push({\n rule: key,\n message: resolveMessage(token, param, field.label, validation.messages),\n });\n }\n\n if (errors.length > 0) result[field.name] = errors;\n }\n\n return result;\n };\n}\n\n/** Shared default instance. */\nexport const defaultResolver: ValidationResolver = /* @__PURE__ */ createRuleResolver();\n","import type { FieldStatus } from \"../../types/state\";\nimport type { FieldError, ValidationResult } from \"../../types/validation\";\n\n/** Internal state: everything the fieldset tracks except `values`. */\nexport interface MetaState {\n touched: Record<string, boolean>;\n errors: ValidationResult;\n validating: boolean;\n /** True once any validation run has completed — distinguishes \"idle\" from \"valid\". */\n everValidated: boolean;\n}\n\nexport const initialMeta: MetaState = {\n touched: {},\n errors: {},\n validating: false,\n everValidated: false,\n};\n\nexport type MetaAction =\n | { type: \"touch\"; name: string }\n | { type: \"touchAll\"; names: string[] }\n | { type: \"validation:start\" }\n | { type: \"validation:field\"; name: string; errors: FieldError[] }\n | { type: \"validation:all\"; result: ValidationResult }\n | { type: \"reset\" };\n\nexport function metaReducer(state: MetaState, action: MetaAction): MetaState {\n switch (action.type) {\n case \"touch\": {\n if (state.touched[action.name]) return state;\n return { ...state, touched: { ...state.touched, [action.name]: true } };\n }\n case \"touchAll\": {\n const touched = { ...state.touched };\n for (const name of action.names) touched[name] = true;\n return { ...state, touched };\n }\n case \"validation:start\":\n return { ...state, validating: true };\n case \"validation:field\": {\n const errors = { ...state.errors };\n if (action.errors.length > 0) errors[action.name] = action.errors;\n else delete errors[action.name];\n return { ...state, errors, validating: false, everValidated: true };\n }\n case \"validation:all\":\n return { ...state, errors: action.result, validating: false, everValidated: true };\n case \"reset\":\n return { ...initialMeta };\n default:\n return state;\n }\n}\n\n/** Derive the form-level status roll-up. */\nexport function deriveStatus(meta: MetaState): FieldStatus {\n if (meta.validating) return \"validating\";\n if (!meta.everValidated) return \"idle\";\n return Object.keys(meta.errors).length > 0 ? \"invalid\" : \"valid\";\n}\n\n/** Shallow per-field dirty map: current value differs from initial. */\nexport function computeDirty(\n values: Record<string, unknown>,\n initial: Record<string, unknown>,\n): Record<string, boolean> {\n const dirty: Record<string, boolean> = {};\n for (const key of Object.keys(values)) {\n if (!Object.is(values[key], initial[key])) dirty[key] = true;\n }\n return dirty;\n}\n","import { useRef } from \"react\";\n\n/** A ref whose `.current` always holds the latest value passed on render. */\nexport function useLatestRef<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","import { useCallback, useState } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\n/**\n * The single place the controlled / uncontrolled fork lives. When `value` is\n * provided the component is controlled and internal state is bypassed; otherwise\n * `defaultValue` seeds local state. `onChange` fires on every committed change in\n * both modes.\n */\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: {\n value: T | undefined;\n defaultValue: T;\n onChange: ((value: T) => void) | undefined;\n}): readonly [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = value !== undefined;\n const [uncontrolled, setUncontrolled] = useState<T>(defaultValue);\n\n const current = isControlled ? (value as T) : uncontrolled;\n const currentRef = useLatestRef(current);\n const onChangeRef = useLatestRef(onChange);\n const isControlledRef = useLatestRef(isControlled);\n\n const setValue = useCallback((next: T | ((prev: T) => T)) => {\n const resolved =\n typeof next === \"function\" ? (next as (prev: T) => T)(currentRef.current) : next;\n if (Object.is(resolved, currentRef.current)) return;\n if (!isControlledRef.current) setUncontrolled(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [current, setValue] as const;\n}\n","import { useCallback, useMemo, useReducer, useRef } from \"react\";\nimport type { FormEvent } from \"react\";\nimport type { FieldsetConfig } from \"../../types/config\";\nimport type { FieldRegistry } from \"../../types/control\";\nimport type { FieldStatus, FieldsetState } from \"../../types/state\";\nimport type {\n FieldError,\n ValidationResolver,\n ValidationResult,\n ValidationTrigger,\n} from \"../../types/validation\";\nimport { type NormalizedFieldsetConfig, normalizeConfig } from \"../config/normalize\";\nimport { defaultResolver } from \"../validation/resolver\";\nimport { computeDirty, deriveStatus, initialMeta, metaReducer } from \"./reducer\";\nimport { useControllableState } from \"./use-controllable-state\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\ntype Values = Record<string, unknown>;\n\n/** Shared empty errors array so unchanged field slices keep a stable identity. */\nconst NO_ERRORS: readonly FieldError[] = Object.freeze([]);\n\nexport interface UseFieldsetStateOptions<TValues extends Values = Values> {\n /** Controlled values. Omit and pass `defaultValue` for uncontrolled. */\n value?: TValues;\n defaultValue?: Partial<TValues>;\n onChange?: (values: TValues) => void;\n /** Called after a full validation pass (`validate()` / submit), not per blur. */\n onValidationChange?: (result: ValidationResult) => void;\n resolver?: ValidationResolver;\n registry?: FieldRegistry;\n /** `\"blur\"` (default) also always validates on submit. */\n validateOn?: ValidationTrigger;\n}\n\n/** Everything a renderer needs for one field. Handlers are referentially stable. */\nexport interface FieldSlice {\n name: string;\n value: unknown;\n errors: FieldError[];\n touched: boolean;\n dirty: boolean;\n setValue: (value: unknown) => void;\n markTouched: () => void;\n}\n\nexport interface UseFieldsetStateReturn<TValues extends Values = Values> {\n config: NormalizedFieldsetConfig;\n state: FieldsetState;\n values: TValues;\n errors: ValidationResult;\n touched: Record<string, boolean>;\n dirty: Record<string, boolean>;\n status: FieldStatus;\n isValid: boolean;\n setFieldValue: (name: string, value: unknown) => void;\n setValues: (values: TValues) => void;\n reset: (next?: Partial<TValues>) => void;\n validate: () => Promise<ValidationResult>;\n handleSubmit: (\n onValid: (values: TValues) => void,\n onInvalid?: (result: ValidationResult) => void,\n ) => (event?: FormEvent) => void;\n getFieldProps: (name: string) => FieldSlice;\n}\n\nfunction computeInitialValues(\n config: NormalizedFieldsetConfig,\n registry: FieldRegistry | undefined,\n provided: Values | undefined,\n): Values {\n const out: Values = {};\n for (const field of config.fields) {\n if (provided && Object.prototype.hasOwnProperty.call(provided, field.name)) {\n out[field.name] = provided[field.name];\n } else if (field.defaultValue !== undefined) {\n out[field.name] = field.defaultValue;\n } else {\n out[field.name] = registry?.get(field.type)?.defaultValue ?? \"\";\n }\n }\n return out;\n}\n\ninterface RunScope {\n field?: string;\n trigger: ValidationTrigger;\n values?: Values;\n}\n\n/**\n * The form engine behind `<Fieldset>`, usable directly when you want to own the\n * markup. Manages values (controlled or uncontrolled), touched/dirty tracking,\n * and validation through a pluggable resolver.\n */\nexport function useFieldsetState<TValues extends Values = Values>(\n config: FieldsetConfig,\n options: UseFieldsetStateOptions<TValues> = {},\n): UseFieldsetStateReturn<TValues> {\n const {\n value,\n defaultValue,\n onChange,\n onValidationChange,\n resolver = defaultResolver,\n registry,\n validateOn = \"blur\",\n } = options;\n\n const normalized = useMemo(() => normalizeConfig(config, registry), [config, registry]);\n\n const initialRef = useRef<Values | null>(null);\n if (initialRef.current === null) {\n initialRef.current = computeInitialValues(\n normalized,\n registry,\n (value ?? defaultValue) as Values | undefined,\n );\n }\n\n const [rawValues, setRawValues] = useControllableState<Values>({\n value: value as Values | undefined,\n defaultValue: initialRef.current,\n onChange: onChange as ((v: Values) => void) | undefined,\n });\n\n const values = useMemo(() => ({ ...initialRef.current, ...rawValues }) as TValues, [rawValues]);\n\n const [meta, dispatch] = useReducer(metaReducer, initialMeta);\n\n const valuesRef = useLatestRef<Values>(values);\n const resolverRef = useLatestRef(resolver);\n const configRef = useLatestRef(config);\n const normalizedRef = useLatestRef(normalized);\n const registryRef = useLatestRef(registry);\n const validateOnRef = useLatestRef(validateOn);\n const onValidationChangeRef = useLatestRef(onValidationChange);\n const runIdRef = useRef(0);\n\n const runValidation = useCallback(async (scope: RunScope): Promise<ValidationResult> => {\n const runId = ++runIdRef.current;\n const input = scope.values ?? valuesRef.current;\n dispatch({ type: \"validation:start\" });\n\n const result = await resolverRef.current(input, configRef.current, {\n trigger: scope.trigger,\n ...(scope.field ? { changedField: scope.field } : {}),\n });\n\n if (runId !== runIdRef.current) return result; // superseded\n\n if (scope.field) {\n dispatch({ type: \"validation:field\", name: scope.field, errors: result[scope.field] ?? [] });\n } else {\n dispatch({ type: \"validation:all\", result });\n onValidationChangeRef.current?.(result);\n }\n return result;\n // refs only — safe to keep stable\n }, []);\n\n const setFieldValue = useCallback(\n (name: string, next: unknown) => {\n setRawValues((prev) => ({ ...prev, [name]: next }));\n if (validateOnRef.current === \"change\") {\n void runValidation({\n field: name,\n trigger: \"change\",\n values: { ...valuesRef.current, [name]: next },\n });\n }\n },\n [setRawValues, runValidation],\n );\n\n const setValues = useCallback((next: TValues) => setRawValues(next as Values), [setRawValues]);\n\n const markTouched = useCallback(\n (name: string) => {\n dispatch({ type: \"touch\", name });\n if (validateOnRef.current === \"blur\") {\n void runValidation({ field: name, trigger: \"blur\" });\n }\n },\n [runValidation],\n );\n\n const validate = useCallback(() => runValidation({ trigger: \"submit\" }), [runValidation]);\n\n const handleSubmit = useCallback(\n (onValid: (values: TValues) => void, onInvalid?: (result: ValidationResult) => void) =>\n async (event?: FormEvent) => {\n event?.preventDefault?.();\n dispatch({\n type: \"touchAll\",\n names: normalizedRef.current.fields.map((f) => f.name),\n });\n const result = await runValidation({ trigger: \"submit\" });\n if (Object.keys(result).length === 0) onValid(valuesRef.current as TValues);\n else onInvalid?.(result);\n },\n [runValidation],\n );\n\n const reset = useCallback(\n (next?: Partial<TValues>) => {\n const fresh = computeInitialValues(\n normalizedRef.current,\n registryRef.current,\n next as Values | undefined,\n );\n initialRef.current = fresh;\n setRawValues(fresh);\n dispatch({ type: \"reset\" });\n runIdRef.current++;\n },\n [setRawValues],\n );\n\n // Stable per-field handler identities so memoized rows don't re-render.\n const handlerCacheRef = useRef(\n new Map<string, { setValue: (v: unknown) => void; markTouched: () => void }>(),\n );\n const getHandlers = useCallback(\n (name: string) => {\n const cache = handlerCacheRef.current;\n let entry = cache.get(name);\n if (!entry) {\n entry = {\n setValue: (v: unknown) => setFieldValue(name, v),\n markTouched: () => markTouched(name),\n };\n cache.set(name, entry);\n }\n return entry;\n },\n [setFieldValue, markTouched],\n );\n\n const dirty = useMemo(() => computeDirty(values, initialRef.current ?? {}), [values]);\n const status = deriveStatus(meta);\n const isValid = Object.keys(meta.errors).length === 0;\n\n const getFieldProps = useCallback(\n (name: string): FieldSlice => {\n const handlers = getHandlers(name);\n return {\n name,\n value: (values as Values)[name],\n errors: meta.errors[name] ?? (NO_ERRORS as FieldError[]),\n touched: meta.touched[name] ?? false,\n dirty: dirty[name] ?? false,\n setValue: handlers.setValue,\n markTouched: handlers.markTouched,\n };\n },\n [values, meta.errors, meta.touched, dirty, getHandlers],\n );\n\n const state: FieldsetState = useMemo(\n () => ({\n values: values as Values,\n touched: meta.touched,\n dirty,\n errors: meta.errors,\n status,\n }),\n [values, meta.touched, dirty, meta.errors, status],\n );\n\n return {\n config: normalized,\n state,\n values,\n errors: meta.errors,\n touched: meta.touched,\n dirty,\n status,\n isValid,\n setFieldValue,\n setValues,\n reset,\n validate,\n handleSubmit,\n getFieldProps,\n };\n}\n","import type { CSSProperties, ReactNode } from \"react\";\nimport { cx } from \"../internal/cx\";\nimport type { ColumnSpec } from \"../types/config\";\nimport { clampSpan } from \"./resolve-columns\";\n\n/** CSS custom properties are set inline; the stylesheet consumes them. */\ntype CssVars = CSSProperties & Record<`--${string}`, string | number>;\n\nexport interface FieldGridProps {\n columns: ColumnSpec;\n /** CSS length for the gap; falls back to the `--orynn-grid-gap` token. */\n gap?: string | undefined;\n className?: string | undefined;\n children: ReactNode;\n}\n\n/**\n * Responsive grid. Column counts per breakpoint are passed as CSS variables and\n * applied by the stylesheet through container queries, so the grid responds to\n * its own width rather than the viewport.\n */\nexport function FieldGrid({ columns, gap, className, children }: FieldGridProps) {\n const style: CssVars = {\n \"--orynn-cols-desktop\": columns.desktop,\n \"--orynn-cols-tablet\": columns.tablet,\n \"--orynn-cols-mobile\": columns.mobile,\n ...(gap ? { \"--orynn-grid-gap\": gap } : {}),\n };\n\n return (\n <div className={cx(\"orynn-grid\", className)} style={style}>\n <div className=\"orynn-grid__track\">{children}</div>\n </div>\n );\n}\n\nexport interface FieldGridItemProps {\n /** Per-breakpoint column span; missing breakpoints default to 1. */\n span?: Partial<ColumnSpec> | undefined;\n columns: ColumnSpec;\n children: ReactNode;\n}\n\n/** One cell of a {@link FieldGrid}, optionally spanning multiple columns. */\nexport function FieldGridItem({ span, columns, children }: FieldGridItemProps) {\n if (!span) return <>{children}</>;\n\n const style: CssVars = {\n \"--orynn-span-desktop\": clampSpan(span.desktop, columns.desktop),\n \"--orynn-span-tablet\": clampSpan(span.tablet, columns.tablet),\n \"--orynn-span-mobile\": clampSpan(span.mobile, columns.mobile),\n };\n\n return (\n <div className=\"orynn-grid__item\" style={style}>\n {children}\n </div>\n );\n}\n","import { memo } from \"react\";\nimport { Field } from \"../controls/Field/Field\";\nimport type { FieldSlice } from \"../core/state/use-fieldset-state\";\nimport { invariant } from \"../internal/dev\";\nimport type { FieldConfig } from \"../types/config\";\nimport type { FieldRegistry } from \"../types/control\";\n\nconst noop = () => {};\n\nexport interface FieldRendererProps {\n field: FieldConfig;\n registry: FieldRegistry;\n slice: FieldSlice;\n disabled?: boolean;\n}\n\nfunction FieldRendererImpl({ field, registry, slice, disabled }: FieldRendererProps) {\n const registration = registry.get(field.type);\n invariant(\n registration,\n `No control registered for field type \"${field.type}\" (field \"${field.name}\").`,\n );\n if (!registration) return null;\n\n const Control = registration.component;\n const required = field.validation?.required === true;\n const isDisabled = disabled === true || field.disabled === true;\n\n const value = registration.parseValue ? registration.parseValue(slice.value) : slice.value;\n // The hook decides *when* a field is validated (per `validateOn`); if it has\n // produced errors for this field, show them.\n const messages = slice.errors.map((e) => e.message);\n\n const handleChange = (next: unknown) => {\n slice.setValue(registration.formatValue ? registration.formatValue(next) : next);\n };\n\n return (\n <Field\n label={field.label}\n description={field.description}\n error={messages}\n required={required}\n disabled={isDisabled}\n >\n {({ id, describedById, invalid }) => (\n <Control\n id={id}\n name={field.name}\n value={value}\n onChange={handleChange}\n onBlur={slice.markTouched}\n onFocus={noop}\n disabled={isDisabled}\n readOnly={field.readOnly === true}\n required={required}\n invalid={invalid}\n describedById={describedById}\n config={field}\n />\n )}\n </Field>\n );\n}\n\n/**\n * Resolves a field config to its registered control and wraps it in `<Field>`.\n * Memoized on the parts of the slice that affect output so that changing one\n * field in a large fieldset does not re-render the others.\n */\nexport const FieldRenderer = /* @__PURE__ */ memo(\n FieldRendererImpl,\n (prev, next) =>\n prev.field === next.field &&\n prev.registry === next.registry &&\n prev.disabled === next.disabled &&\n prev.slice.value === next.slice.value &&\n prev.slice.touched === next.slice.touched &&\n prev.slice.errors === next.slice.errors &&\n prev.slice.setValue === next.slice.setValue &&\n prev.slice.markTouched === next.slice.markTouched,\n);\n","import type { DropdownFieldConfig, InputFieldConfig } from \"../types/config\";\nimport type { ControlComponent, FieldRegistry } from \"../types/control\";\n\nconst toStringValue = (value: unknown): string =>\n typeof value === \"string\" ? value : value == null ? \"\" : String(value);\n\n/** Raw `<input>` bound to the {@link ControlProps} contract. `<Field>` wraps it. */\nconst InputControl: ControlComponent<string> = ({\n id,\n name,\n value,\n onChange,\n onBlur,\n onFocus,\n disabled,\n readOnly,\n required,\n invalid,\n describedById,\n config,\n}) => {\n const field = config as InputFieldConfig;\n return (\n <input\n id={id}\n name={name}\n className=\"orynn-input\"\n type={field.inputType ?? \"text\"}\n value={toStringValue(value)}\n placeholder={field.placeholder}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={invalid || undefined}\n aria-describedby={describedById}\n onChange={(event) => onChange(event.target.value, event)}\n onBlur={onBlur}\n onFocus={onFocus}\n {...field.props}\n />\n );\n};\n\n/** Raw `<select>` bound to the {@link ControlProps} contract. */\nconst DropdownControl: ControlComponent<string> = ({\n id,\n name,\n value,\n onChange,\n onBlur,\n onFocus,\n disabled,\n required,\n invalid,\n describedById,\n config,\n}) => {\n const field = config as DropdownFieldConfig;\n return (\n <select\n id={id}\n name={name}\n className=\"orynn-dropdown\"\n value={toStringValue(value)}\n required={required}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={describedById}\n onChange={(event) => onChange(event.target.value, event)}\n onBlur={onBlur}\n onFocus={onFocus}\n {...field.props}\n >\n {field.placeholder != null && (\n <option value=\"\" disabled={required}>\n {field.placeholder}\n </option>\n )}\n {field.options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n );\n};\n\n/**\n * Seed a registry with the V1 built-in field types. Idempotent: existing\n * registrations (e.g. a consumer override) are left untouched.\n */\nexport function registerBuiltins(registry: FieldRegistry): void {\n if (!registry.has(\"input\")) {\n registry.register(\"input\", { component: InputControl, defaultValue: \"\" });\n }\n if (!registry.has(\"dropdown\")) {\n registry.register(\"dropdown\", {\n component: DropdownControl,\n defaultValue: \"\",\n validateConfig: (config) =>\n Array.isArray((config as Partial<DropdownFieldConfig>).options)\n ? null\n : \"a dropdown field requires an `options` array\",\n });\n }\n}\n\nlet seeded = false;\n\n/**\n * Register the built-ins on the module-global registry exactly once, lazily.\n * Called from `useFieldsetState` / `<Fieldset>` rather than at module load so\n * that importing a standalone control never pulls the built-ins (and the\n * validation engine) into the bundle.\n */\nexport function ensureBuiltins(defaultRegistry: FieldRegistry): void {\n if (seeded) return;\n seeded = true;\n registerBuiltins(defaultRegistry);\n}\n","import { defaultRegistry } from \"../core/registry/registry\";\nimport { type UseFieldsetStateOptions, useFieldsetState } from \"../core/state/use-fieldset-state\";\nimport { cx } from \"../internal/cx\";\nimport { FieldGrid, FieldGridItem } from \"../layout/FieldGrid\";\nimport type { FieldsetProps } from \"../types/props\";\nimport { FieldRenderer } from \"./FieldRenderer\";\nimport { ensureBuiltins } from \"./register-builtins\";\n\n/**\n * Renders a form (or a form section) from a `FieldsetConfig`. Controlled when\n * `value` is passed, uncontrolled otherwise. Renders a native `<fieldset>` — so\n * `disabled` cascades to every control — and does not render its own `<form>`;\n * wrap it in one and use `useFieldsetState().handleSubmit` for submission.\n */\nexport function Fieldset<TValues extends Record<string, unknown> = Record<string, unknown>>(\n props: FieldsetProps<TValues>,\n) {\n const {\n config,\n value,\n defaultValue,\n onChange,\n onValidationChange,\n resolver,\n registry,\n validateOn,\n disabled,\n className,\n id,\n } = props;\n\n ensureBuiltins(defaultRegistry);\n const activeRegistry = registry ?? defaultRegistry;\n\n const options: UseFieldsetStateOptions<TValues> = {\n registry: activeRegistry,\n ...(value !== undefined ? { value } : {}),\n ...(defaultValue !== undefined ? { defaultValue } : {}),\n ...(onChange ? { onChange } : {}),\n ...(onValidationChange ? { onValidationChange } : {}),\n ...(resolver ? { resolver } : {}),\n ...(validateOn ? { validateOn } : {}),\n };\n\n const fs = useFieldsetState<TValues>(config, options);\n const { columns, gap, legend, fields, id: configId } = fs.config;\n\n return (\n <fieldset\n className={cx(\"orynn-fieldset\", className)}\n id={id ?? configId}\n disabled={disabled || undefined}\n >\n {legend != null && <legend className=\"orynn-fieldset__legend\">{legend}</legend>}\n <FieldGrid columns={columns} gap={gap}>\n {fields.map((field) => (\n <FieldGridItem key={field.name} span={field.layout} columns={columns}>\n <FieldRenderer\n field={field}\n registry={activeRegistry}\n slice={fs.getFieldProps(field.name)}\n disabled={disabled === true}\n />\n </FieldGridItem>\n ))}\n </FieldGrid>\n </fieldset>\n );\n}\n","import type { FieldsetConfig } from \"./config\";\n\n/**\n * Per-field validation config. V1 ships `required` / `minLength` / `maxLength`.\n * Future rule keys (regex, email, min, max, validate, ...) are added here without\n * a breaking change.\n */\nexport interface FieldValidation {\n required?: boolean;\n minLength?: number;\n maxLength?: number;\n /** Per-rule message overrides, e.g. `{ required: \"Name is required\" }`. */\n messages?: Partial<Record<string, string>>;\n}\n\n/** A single validation failure. Shape is frozen — new fields must stay optional. */\nexport interface FieldError {\n /** Rule that failed: `\"required\"`, `\"minLength\"`, `\"custom\"`, `\"async\"`, ... */\n rule: string;\n message: string;\n /** Reserved for cross-field / nested errors. Unused in V1. */\n path?: string;\n}\n\n/**\n * Validation output. Key = field name. The reserved key `\"$form\"` holds\n * form-level / cross-field errors.\n */\nexport type ValidationResult = Record<string, FieldError[]>;\n\n/** Reserved key in {@link ValidationResult} for form-level errors. */\nexport const FORM_ERROR_KEY = \"$form\" as const;\n\n/** What triggered a validation run. */\nexport type ValidationTrigger = \"change\" | \"blur\" | \"submit\";\n\nexport interface ValidationContext {\n /** Field whose change/blur triggered this run, if any. */\n changedField?: string;\n trigger: ValidationTrigger;\n}\n\n/**\n * The single seam through which all validation flows. V1's default resolver is\n * rule-based and synchronous; the `Promise` return type keeps async, schema, and\n * cross-field validation additive.\n */\nexport type ValidationResolver = (\n values: Record<string, unknown>,\n config: FieldsetConfig,\n context: ValidationContext,\n) => ValidationResult | Promise<ValidationResult>;\n\n/**\n * A single rule implementation. Returns an error message string on failure, or\n * `null` on success. `allValues` is passed so cross-field rules need no\n * signature change later.\n */\nexport type RuleFn = (\n value: unknown,\n param: unknown,\n allValues: Record<string, unknown>,\n) => string | null;\n"]}
@@ -0,0 +1,201 @@
1
+ /*
2
+ * orynn — default stylesheet
3
+ * Import once in your app: import "orynn/styles.css";
4
+ *
5
+ * Every value below is a CSS custom property on :root. Override them (globally,
6
+ * or scoped to a container) to theme the components — no build step, no JS.
7
+ */
8
+
9
+ :root {
10
+ /* palette */
11
+ --orynn-color-text: #1a1d21;
12
+ --orynn-color-text-muted: #5b6470;
13
+ --orynn-color-bg: #ffffff;
14
+ --orynn-color-bg-disabled: #f1f3f5;
15
+ --orynn-color-border: #c7ccd1;
16
+ --orynn-color-border-hover: #9aa2ab;
17
+ --orynn-color-focus: #2563eb;
18
+ --orynn-color-focus-ring: rgba(37, 99, 235, 0.35);
19
+ --orynn-color-error: #d1242f;
20
+ --orynn-color-error-border: #e5484d;
21
+
22
+ /* typography */
23
+ --orynn-font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
24
+ --orynn-font-size: 0.9375rem;
25
+ --orynn-label-font-size: 0.875rem;
26
+ --orynn-help-font-size: 0.8125rem;
27
+ --orynn-label-weight: 600;
28
+ --orynn-line-height: 1.5;
29
+
30
+ /* spacing & shape */
31
+ --orynn-space-2xs: 0.25rem;
32
+ --orynn-space-xs: 0.375rem;
33
+ --orynn-space-sm: 0.5rem;
34
+ --orynn-space-md: 0.75rem;
35
+ --orynn-radius: 6px;
36
+ --orynn-control-min-height: 2.5rem;
37
+ --orynn-control-padding-x: 0.6875rem;
38
+ --orynn-border-width: 1px;
39
+
40
+ /* layout */
41
+ --orynn-grid-gap: 1rem;
42
+ --orynn-cols-desktop: 3;
43
+ --orynn-cols-tablet: 2;
44
+ --orynn-cols-mobile: 1;
45
+ }
46
+
47
+ /* ---------------------------------------------------------------- fieldset -- */
48
+
49
+ .orynn-fieldset {
50
+ min-inline-size: 0;
51
+ margin: 0;
52
+ padding: 0;
53
+ border: 0;
54
+ font-family: var(--orynn-font-family);
55
+ color: var(--orynn-color-text);
56
+ }
57
+
58
+ .orynn-fieldset__legend {
59
+ padding: 0;
60
+ margin-block-end: var(--orynn-space-md);
61
+ font-size: 1rem;
62
+ font-weight: var(--orynn-label-weight);
63
+ }
64
+
65
+ /* ------------------------------------------------------------------- grid --- */
66
+
67
+ .orynn-grid {
68
+ container-type: inline-size;
69
+ }
70
+
71
+ .orynn-grid__track {
72
+ display: grid;
73
+ gap: var(--orynn-grid-gap);
74
+ grid-template-columns: repeat(var(--orynn-cols-mobile, 1), minmax(0, 1fr));
75
+ }
76
+
77
+ @container (min-width: 30rem) {
78
+ .orynn-grid__track {
79
+ grid-template-columns: repeat(var(--orynn-cols-tablet, 2), minmax(0, 1fr));
80
+ }
81
+ .orynn-grid__item {
82
+ grid-column: span var(--orynn-span-tablet, 1);
83
+ }
84
+ }
85
+
86
+ @container (min-width: 48rem) {
87
+ .orynn-grid__track {
88
+ grid-template-columns: repeat(var(--orynn-cols-desktop, 3), minmax(0, 1fr));
89
+ }
90
+ .orynn-grid__item {
91
+ grid-column: span var(--orynn-span-desktop, 1);
92
+ }
93
+ }
94
+
95
+ .orynn-grid__item {
96
+ grid-column: span var(--orynn-span-mobile, 1);
97
+ min-inline-size: 0;
98
+ }
99
+
100
+ /* Fallback for engines without container-query support. */
101
+ @supports not (container-type: inline-size) {
102
+ .orynn-grid__track {
103
+ grid-template-columns: repeat(var(--orynn-cols-desktop, 3), minmax(0, 1fr));
104
+ }
105
+ }
106
+
107
+ /* ------------------------------------------------------------------ field --- */
108
+
109
+ .orynn-field {
110
+ display: flex;
111
+ flex-direction: column;
112
+ gap: var(--orynn-space-xs);
113
+ font-family: var(--orynn-font-family);
114
+ font-size: var(--orynn-font-size);
115
+ line-height: var(--orynn-line-height);
116
+ color: var(--orynn-color-text);
117
+ }
118
+
119
+ .orynn-field__label {
120
+ font-size: var(--orynn-label-font-size);
121
+ font-weight: var(--orynn-label-weight);
122
+ }
123
+
124
+ .orynn-field[data-required] .orynn-field__label::after {
125
+ content: " *";
126
+ color: var(--orynn-color-error);
127
+ }
128
+
129
+ .orynn-field__description {
130
+ margin: 0;
131
+ font-size: var(--orynn-help-font-size);
132
+ color: var(--orynn-color-text-muted);
133
+ }
134
+
135
+ .orynn-field__control {
136
+ display: block;
137
+ }
138
+
139
+ .orynn-field__error {
140
+ margin: 0;
141
+ font-size: var(--orynn-help-font-size);
142
+ color: var(--orynn-color-error);
143
+ }
144
+
145
+ .orynn-field__error span {
146
+ display: block;
147
+ }
148
+
149
+ /* --------------------------------------------------------------- controls --- */
150
+
151
+ .orynn-input,
152
+ .orynn-dropdown {
153
+ inline-size: 100%;
154
+ min-block-size: var(--orynn-control-min-height);
155
+ padding: var(--orynn-space-sm) var(--orynn-control-padding-x);
156
+ font-family: inherit;
157
+ font-size: var(--orynn-font-size);
158
+ line-height: var(--orynn-line-height);
159
+ color: var(--orynn-color-text);
160
+ background-color: var(--orynn-color-bg);
161
+ border: var(--orynn-border-width) solid var(--orynn-color-border);
162
+ border-radius: var(--orynn-radius);
163
+ box-sizing: border-box;
164
+ transition: border-color 0.12s ease, box-shadow 0.12s ease;
165
+ }
166
+
167
+ .orynn-input:hover:not(:disabled),
168
+ .orynn-dropdown:hover:not(:disabled) {
169
+ border-color: var(--orynn-color-border-hover);
170
+ }
171
+
172
+ .orynn-input:focus-visible,
173
+ .orynn-dropdown:focus-visible {
174
+ outline: none;
175
+ border-color: var(--orynn-color-focus);
176
+ box-shadow: 0 0 0 3px var(--orynn-color-focus-ring);
177
+ }
178
+
179
+ .orynn-input[aria-invalid="true"],
180
+ .orynn-dropdown[aria-invalid="true"] {
181
+ border-color: var(--orynn-color-error-border);
182
+ }
183
+
184
+ .orynn-input:disabled,
185
+ .orynn-dropdown:disabled {
186
+ background-color: var(--orynn-color-bg-disabled);
187
+ color: var(--orynn-color-text-muted);
188
+ cursor: not-allowed;
189
+ }
190
+
191
+ .orynn-input:read-only {
192
+ background-color: var(--orynn-color-bg-disabled);
193
+ }
194
+
195
+ .orynn-dropdown {
196
+ appearance: none;
197
+ padding-inline-end: 2rem;
198
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%235b6470' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
199
+ background-repeat: no-repeat;
200
+ background-position: right var(--orynn-control-padding-x) center;
201
+ }
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "orynn",
3
+ "version": "0.1.0",
4
+ "description": "A small, strongly-typed JSON-driven form library for React. Fieldset + standalone Input and Dropdown.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "rajveer",
8
+ "keywords": [
9
+ "react",
10
+ "form",
11
+ "forms",
12
+ "json-schema",
13
+ "json-driven",
14
+ "fieldset",
15
+ "typescript",
16
+ "form-builder"
17
+ ],
18
+ "sideEffects": ["**/*.css"],
19
+ "main": "./dist/index.cjs",
20
+ "module": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "import": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ },
28
+ "require": {
29
+ "types": "./dist/index.d.cts",
30
+ "default": "./dist/index.cjs"
31
+ }
32
+ },
33
+ "./styles.css": "./dist/styles.css",
34
+ "./package.json": "./package.json"
35
+ },
36
+ "files": ["dist"],
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "scripts": {
44
+ "build": "tsup",
45
+ "dev": "tsup --watch",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest",
48
+ "test:types": "tsc --noEmit",
49
+ "lint": "biome check .",
50
+ "lint:fix": "biome check --write .",
51
+ "format": "biome format --write .",
52
+ "check:pkg": "publint && attw --pack .",
53
+ "prepublishOnly": "npm run build"
54
+ },
55
+ "peerDependencies": {
56
+ "react": ">=18",
57
+ "react-dom": ">=18"
58
+ },
59
+ "peerDependenciesMeta": {
60
+ "react-dom": {
61
+ "optional": true
62
+ }
63
+ },
64
+ "devDependencies": {
65
+ "@arethetypeswrong/cli": "^0.17.4",
66
+ "@biomejs/biome": "^1.9.4",
67
+ "@changesets/cli": "^2.27.11",
68
+ "@testing-library/jest-dom": "^6.6.3",
69
+ "@testing-library/react": "^16.1.0",
70
+ "@testing-library/user-event": "^14.5.2",
71
+ "@types/react": "^18.3.18",
72
+ "@types/react-dom": "^18.3.5",
73
+ "expect-type": "^1.1.0",
74
+ "jsdom": "^25.0.1",
75
+ "publint": "^0.3.2",
76
+ "react": "^18.3.1",
77
+ "react-dom": "^18.3.1",
78
+ "tsup": "^8.3.5",
79
+ "typescript": "^5.7.2",
80
+ "vitest": "^2.1.8"
81
+ }
82
+ }