@passui/react 0.1.37 → 0.1.38

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.
@@ -1,3 +1,4 @@
1
+ import { type PickerSize } from "../picker/picker-trigger";
1
2
  export interface CompactDatePickerProps {
2
3
  /** `YYYY-MM-DD`, or "" when no date is chosen. */
3
4
  value: string;
@@ -18,10 +19,12 @@ export interface CompactDatePickerProps {
18
19
  className?: string;
19
20
  /** Prevents opening the date panel. @default false */
20
21
  disabled?: boolean;
22
+ /** Trigger button density; matches Picker's sm | md | lg. @default "md" */
23
+ size?: PickerSize;
21
24
  }
22
25
  /**
23
26
  * A date as a compact button that opens a month calendar, like SwiftUI's
24
27
  * compact DatePicker: for dates on a calendar, such as an event or an
25
28
  * invoice. For dates people know by heart, like a birthday, use DatePicker.
26
29
  */
27
- export declare function CompactDatePicker({ value, onChange, label, locale, min, max, placeholder, labels, className, disabled, }: CompactDatePickerProps): import("react").JSX.Element;
30
+ export declare function CompactDatePicker({ value, onChange, label, locale, min, max, placeholder, labels, className, disabled, size, }: CompactDatePickerProps): import("react").JSX.Element;
@@ -1,3 +1,4 @@
1
+ import { type PickerSize } from "../picker/picker-trigger";
1
2
  export interface CompactTimePickerProps {
2
3
  /** `HH:MM` on a 24 hour clock, or "" when no time is chosen. */
3
4
  value: string;
@@ -17,10 +18,12 @@ export interface CompactTimePickerProps {
17
18
  className?: string;
18
19
  /** Prevents opening the time panel. @default false */
19
20
  disabled?: boolean;
21
+ /** Trigger button density; matches Picker's sm | md | lg. @default "md" */
22
+ size?: PickerSize;
20
23
  }
21
24
  /**
22
25
  * A time as a compact button that opens columns of hours and minutes,
23
26
  * like SwiftUI's compact DatePicker for times, on the clock the locale
24
27
  * reads (12 hours with AM and PM, or 24).
25
28
  */
26
- export declare function CompactTimePicker({ value, onChange, label, locale, minuteStep, placeholder, labels, className, disabled, }: CompactTimePickerProps): import("react").JSX.Element;
29
+ export declare function CompactTimePicker({ value, onChange, label, locale, minuteStep, placeholder, labels, className, disabled, size, }: CompactTimePickerProps): import("react").JSX.Element;
@@ -1,6 +1,9 @@
1
1
  import { type InputHTMLAttributes } from "react";
2
- export interface SearchFieldProps extends InputHTMLAttributes<HTMLInputElement> {
2
+ export type SearchFieldSize = "sm" | "md" | "lg";
3
+ export interface SearchFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
3
4
  /** Expand a single pill from its search icon on focus. @default false */
4
5
  collapsible?: boolean;
6
+ /** Pill height, icon size and text scale (non-collapsible variant). @default "md" */
7
+ size?: SearchFieldSize;
5
8
  }
6
9
  export declare const SearchField: import("react").ForwardRefExoticComponent<SearchFieldProps & import("react").RefAttributes<HTMLInputElement>>;
@@ -1,2 +1,9 @@
1
1
  import type { ComponentProps } from "react";
2
- export declare function TextEditor({ className, ...props }: ComponentProps<"textarea">): import("react").JSX.Element;
2
+ import { type TextFieldSize } from "../text-field/text-field";
3
+ export type TextEditorSize = TextFieldSize;
4
+ export interface TextEditorProps extends Omit<ComponentProps<"textarea">, "size"> {
5
+ /** Field surface scale; matches TextField's xs | sm | md | lg. @default "md" */
6
+ size?: TextEditorSize;
7
+ }
8
+ /** A multi-line text field that reuses TextField's shared surface treatment. */
9
+ export declare function TextEditor({ className, size, ...props }: TextEditorProps): import("react").JSX.Element;
@@ -3,6 +3,14 @@ import { type ComponentProps, type ReactNode } from "react";
3
3
  export declare const textControlClasses: string;
4
4
  /** Size scale shared across TextField, SecureField, and form fields. */
5
5
  export type TextFieldSize = "xs" | "sm" | "md" | "lg";
6
+ export interface FieldSize {
7
+ height: string;
8
+ floatingHeight: string;
9
+ padding: string;
10
+ text: string;
11
+ radius: string;
12
+ }
13
+ export declare function fieldSize(size: TextFieldSize): FieldSize;
6
14
  export type TextFieldProps = Omit<ComponentProps<"input">, "size"> & {
7
15
  label: string;
8
16
  description?: ReactNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@passui/react",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "Passui: native React controls, design tokens, presentation and appearance.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -6,7 +6,7 @@ import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from "../../icons/ico
6
6
  import { cn } from "../../lib/class-names"
7
7
  import { haptic } from "../../lib/haptics"
8
8
  import { IconButton } from "../button/icon-button"
9
- import { pickerTriggerStyle } from "../picker/picker-trigger"
9
+ import { pickerTriggerStyle, type PickerSize } from "../picker/picker-trigger"
10
10
  import {
11
11
  addDays,
12
12
  addMonths,
@@ -38,6 +38,8 @@ export interface CompactDatePickerProps {
38
38
  className?: string
39
39
  /** Prevents opening the date panel. @default false */
40
40
  disabled?: boolean
41
+ /** Trigger button density; matches Picker's sm | md | lg. @default "md" */
42
+ size?: PickerSize
41
43
  }
42
44
 
43
45
  const WIDTH = 308
@@ -69,6 +71,7 @@ export function CompactDatePicker({
69
71
  labels,
70
72
  className,
71
73
  disabled = false,
74
+ size = "md",
72
75
  }: CompactDatePickerProps) {
73
76
  const panel = useAnchoredDisclosure(disabled)
74
77
  const { open } = panel
@@ -98,7 +101,7 @@ export function CompactDatePicker({
98
101
  aria-controls={open && !disabled ? calendarId : undefined}
99
102
  disabled={disabled}
100
103
  onClick={() => panel.toggle()}
101
- className={pickerTriggerStyle(className)}
104
+ className={pickerTriggerStyle(className, size)}
102
105
  >
103
106
  <span
104
107
  className={cn(
@@ -5,7 +5,7 @@ import { createPortal } from "react-dom"
5
5
  import { ClockIcon } from "../../icons/icons"
6
6
  import { cn } from "../../lib/class-names"
7
7
  import { haptic } from "../../lib/haptics"
8
- import { pickerTriggerStyle } from "../picker/picker-trigger"
8
+ import { pickerTriggerStyle, type PickerSize } from "../picker/picker-trigger"
9
9
  import {
10
10
  formatTime,
11
11
  fromTwelveHours,
@@ -31,6 +31,8 @@ export interface CompactTimePickerProps {
31
31
  className?: string
32
32
  /** Prevents opening the time panel. @default false */
33
33
  disabled?: boolean
34
+ /** Trigger button density; matches Picker's sm | md | lg. @default "md" */
35
+ size?: PickerSize
34
36
  }
35
37
 
36
38
  /**
@@ -48,6 +50,7 @@ export function CompactTimePicker({
48
50
  labels,
49
51
  className,
50
52
  disabled = false,
53
+ size = "md",
51
54
  }: CompactTimePickerProps) {
52
55
  const panel = useAnchoredDisclosure(disabled)
53
56
  const { open } = panel
@@ -73,7 +76,7 @@ export function CompactTimePicker({
73
76
  aria-controls={open && !disabled ? panelId : undefined}
74
77
  disabled={disabled}
75
78
  onClick={() => panel.toggle()}
76
- className={pickerTriggerStyle(className)}
79
+ className={pickerTriggerStyle(className, size)}
77
80
  >
78
81
  <span
79
82
  className={cn(
@@ -3,13 +3,28 @@ import { SearchIcon } from "../../icons/icons"
3
3
  import { cn } from "../../lib/class-names"
4
4
  import { ExpandingSearchField } from "./expanding-search-field"
5
5
 
6
- export interface SearchFieldProps extends InputHTMLAttributes<HTMLInputElement> {
6
+ export type SearchFieldSize = "sm" | "md" | "lg"
7
+
8
+ const pillSizes: Record<SearchFieldSize, string> = {
9
+ sm: "control-field flex items-center gap-1.5 rounded-full px-2.5 py-1 text-caption text-label-tertiary",
10
+ md: "control-field flex items-center gap-2 rounded-full px-3 py-2 text-subheadline text-label-tertiary",
11
+ lg: "control-field flex items-center gap-2.5 rounded-full px-4 py-2.5 text-body text-label-tertiary",
12
+ }
13
+ const iconSizes: Record<SearchFieldSize, number> = {
14
+ sm: 13,
15
+ md: 15,
16
+ lg: 17,
17
+ }
18
+
19
+ export interface SearchFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
7
20
  /** Expand a single pill from its search icon on focus. @default false */
8
21
  collapsible?: boolean
22
+ /** Pill height, icon size and text scale (non-collapsible variant). @default "md" */
23
+ size?: SearchFieldSize
9
24
  }
10
25
 
11
26
  export const SearchField = forwardRef<HTMLInputElement, SearchFieldProps>(function SearchField(
12
- { className, placeholder = "Search", collapsible = false, ...props },
27
+ { className, placeholder = "Search", collapsible = false, size = "md", ...props },
13
28
  ref
14
29
  ) {
15
30
  if (collapsible)
@@ -25,14 +40,9 @@ export const SearchField = forwardRef<HTMLInputElement, SearchFieldProps>(functi
25
40
  ? undefined
26
41
  : (props["aria-label"] ?? placeholder)
27
42
  return (
28
- <label
29
- className={cn(
30
- "control-field flex items-center gap-2 rounded-full px-3 py-2 text-subheadline text-label-tertiary",
31
- className
32
- )}
33
- >
43
+ <label className={cn(pillSizes[size], className)}>
34
44
  <span aria-hidden="true" className="shrink-0">
35
- <SearchIcon size={15} strokeWidth={2} />
45
+ <SearchIcon size={iconSizes[size]} strokeWidth={2} />
36
46
  </span>
37
47
  <input
38
48
  ref={ref}
@@ -1,9 +1,37 @@
1
1
  import type { ComponentProps } from "react"
2
2
  import { cn } from "../../lib/class-names"
3
- import { textControlClasses } from "../text-field/text-field"
3
+ import { fieldSize, type TextFieldSize } from "../text-field/text-field"
4
4
 
5
- export function TextEditor({ className, ...props }: ComponentProps<"textarea">) {
5
+ const minHeights: Record<TextFieldSize, string> = {
6
+ xs: "min-h-24",
7
+ sm: "min-h-24",
8
+ md: "min-h-28",
9
+ lg: "min-h-32",
10
+ }
11
+
12
+ export type TextEditorSize = TextFieldSize
13
+
14
+ export interface TextEditorProps extends Omit<ComponentProps<"textarea">, "size"> {
15
+ /** Field surface scale; matches TextField's xs | sm | md | lg. @default "md" */
16
+ size?: TextEditorSize
17
+ }
18
+
19
+ /** A multi-line text field that reuses TextField's shared surface treatment. */
20
+ export function TextEditor({ className, size = "md", ...props }: TextEditorProps) {
21
+ const surface = fieldSize(size)
6
22
  return (
7
- <textarea {...props} className={cn(textControlClasses, "min-h-28 resize-y", className)} />
23
+ <textarea
24
+ {...props}
25
+ className={cn(
26
+ "w-full min-w-0 resize-y border border-separator bg-elevated text-label placeholder:text-label-tertiary",
27
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent-text",
28
+ "disabled:cursor-not-allowed disabled:opacity-40 aria-invalid:border-danger",
29
+ surface.radius,
30
+ surface.padding,
31
+ surface.text,
32
+ minHeights[size],
33
+ className
34
+ )}
35
+ />
8
36
  )
9
37
  }
@@ -15,7 +15,7 @@ const fieldIconClasses = "flex shrink-0 items-center text-label-secondary"
15
15
  /** Size scale shared across TextField, SecureField, and form fields. */
16
16
  export type TextFieldSize = "xs" | "sm" | "md" | "lg"
17
17
 
18
- interface FieldSize {
18
+ export interface FieldSize {
19
19
  height: string
20
20
  floatingHeight: string
21
21
  padding: string
@@ -23,7 +23,7 @@ interface FieldSize {
23
23
  radius: string
24
24
  }
25
25
 
26
- function fieldSize(size: TextFieldSize): FieldSize {
26
+ export function fieldSize(size: TextFieldSize): FieldSize {
27
27
  switch (size) {
28
28
  case "xs":
29
29
  return {