@kanso-labs/react-native-kanso-ui 0.0.0-stage → 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.
Files changed (145) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +205 -2
  3. package/dist/button/index.d.ts +56 -0
  4. package/dist/button/index.js +169 -0
  5. package/dist/button/index.js.map +1 -0
  6. package/dist/button/palettes.js +47 -0
  7. package/dist/button/palettes.js.map +1 -0
  8. package/dist/chip/index.js +194 -0
  9. package/dist/chip/index.js.map +1 -0
  10. package/dist/chip/styles.js +36 -0
  11. package/dist/chip/styles.js.map +1 -0
  12. package/dist/clipboard/index.js +58 -0
  13. package/dist/clipboard/index.js.map +1 -0
  14. package/dist/components/avatar/index.d.ts +82 -0
  15. package/dist/components/avatar/index.js +62 -0
  16. package/dist/components/avatar/index.js.map +1 -0
  17. package/dist/components/button/index.d.ts +87 -0
  18. package/dist/components/button/index.js +377 -0
  19. package/dist/components/button/index.js.map +1 -0
  20. package/dist/components/card/index.d.ts +78 -0
  21. package/dist/components/card/index.js +315 -0
  22. package/dist/components/card/index.js.map +1 -0
  23. package/dist/components/checkbox/index.d.ts +76 -0
  24. package/dist/components/checkbox/index.js +360 -0
  25. package/dist/components/checkbox/index.js.map +1 -0
  26. package/dist/components/chip/index.d.ts +84 -0
  27. package/dist/components/chip/index.js +257 -0
  28. package/dist/components/chip/index.js.map +1 -0
  29. package/dist/components/chip-group/index.d.ts +143 -0
  30. package/dist/components/chip-group/index.js +669 -0
  31. package/dist/components/chip-group/index.js.map +1 -0
  32. package/dist/components/copy-field/index.d.ts +60 -0
  33. package/dist/components/copy-field/index.js +277 -0
  34. package/dist/components/copy-field/index.js.map +1 -0
  35. package/dist/components/currency/index.d.ts +69 -0
  36. package/dist/components/currency/index.js +162 -0
  37. package/dist/components/currency/index.js.map +1 -0
  38. package/dist/components/form/index.d.ts +84 -0
  39. package/dist/components/form/index.js +95 -0
  40. package/dist/components/form/index.js.map +1 -0
  41. package/dist/components/icon-button/index.d.ts +68 -0
  42. package/dist/components/icon-button/index.js +289 -0
  43. package/dist/components/icon-button/index.js.map +1 -0
  44. package/dist/components/link/index.d.ts +59 -0
  45. package/dist/components/link/index.js +191 -0
  46. package/dist/components/link/index.js.map +1 -0
  47. package/dist/components/number-field/index.d.ts +151 -0
  48. package/dist/components/number-field/index.js +832 -0
  49. package/dist/components/number-field/index.js.map +1 -0
  50. package/dist/components/product-icon/index.d.ts +70 -0
  51. package/dist/components/product-icon/index.js +60 -0
  52. package/dist/components/product-icon/index.js.map +1 -0
  53. package/dist/components/radio-group/index.d.ts +105 -0
  54. package/dist/components/radio-group/index.js +597 -0
  55. package/dist/components/radio-group/index.js.map +1 -0
  56. package/dist/components/search-field/index.d.ts +98 -0
  57. package/dist/components/search-field/index.js +521 -0
  58. package/dist/components/search-field/index.js.map +1 -0
  59. package/dist/components/segmented-button/index.d.ts +113 -0
  60. package/dist/components/segmented-button/index.js +937 -0
  61. package/dist/components/segmented-button/index.js.map +1 -0
  62. package/dist/components/separator/index.d.ts +45 -0
  63. package/dist/components/separator/index.js +109 -0
  64. package/dist/components/separator/index.js.map +1 -0
  65. package/dist/components/stack/index.d.ts +70 -0
  66. package/dist/components/stack/index.js +107 -0
  67. package/dist/components/stack/index.js.map +1 -0
  68. package/dist/components/switch/index.d.ts +76 -0
  69. package/dist/components/switch/index.js +591 -0
  70. package/dist/components/switch/index.js.map +1 -0
  71. package/dist/components/text/index.d.ts +44 -0
  72. package/dist/components/text/index.js +78 -0
  73. package/dist/components/text/index.js.map +1 -0
  74. package/dist/components/text-field/index.d.ts +146 -0
  75. package/dist/components/text-field/index.js +228 -0
  76. package/dist/components/text-field/index.js.map +1 -0
  77. package/dist/control/index.js +117 -0
  78. package/dist/control/index.js.map +1 -0
  79. package/dist/control/styles.js +36 -0
  80. package/dist/control/styles.js.map +1 -0
  81. package/dist/field/index.d.ts +13 -0
  82. package/dist/field/index.js +1007 -0
  83. package/dist/field/index.js.map +1 -0
  84. package/dist/field/styles.js +131 -0
  85. package/dist/field/styles.js.map +1 -0
  86. package/dist/form/index.d.ts +24 -0
  87. package/dist/form/index.js +209 -0
  88. package/dist/form/index.js.map +1 -0
  89. package/dist/glyphs/icon-style.d.ts +25 -0
  90. package/dist/glyphs/icon-style.js +22 -0
  91. package/dist/glyphs/icon-style.js.map +1 -0
  92. package/dist/glyphs/index.js +170 -0
  93. package/dist/glyphs/index.js.map +1 -0
  94. package/dist/glyphs/styles.js +7 -0
  95. package/dist/glyphs/styles.js.map +1 -0
  96. package/dist/hooks/useWindowSizeClass.d.ts +25 -0
  97. package/dist/hooks/useWindowSizeClass.js +39 -0
  98. package/dist/hooks/useWindowSizeClass.js.map +1 -0
  99. package/dist/index.d.ts +31 -0
  100. package/dist/index.js +27 -0
  101. package/dist/mark/image.js +61 -0
  102. package/dist/mark/image.js.map +1 -0
  103. package/dist/mark/index.d.ts +9 -0
  104. package/dist/mark/index.js +234 -0
  105. package/dist/mark/index.js.map +1 -0
  106. package/dist/mark/initials.js +65 -0
  107. package/dist/mark/initials.js.map +1 -0
  108. package/dist/mark/styles.d.ts +1 -0
  109. package/dist/mark/styles.js +73 -0
  110. package/dist/mark/styles.js.map +1 -0
  111. package/dist/number/parser.js +321 -0
  112. package/dist/number/parser.js.map +1 -0
  113. package/dist/number/state.js +235 -0
  114. package/dist/number/state.js.map +1 -0
  115. package/dist/overlay/host.js +111 -0
  116. package/dist/overlay/host.js.map +1 -0
  117. package/dist/press/index.js +350 -0
  118. package/dist/press/index.js.map +1 -0
  119. package/dist/press/styles.js +31 -0
  120. package/dist/press/styles.js.map +1 -0
  121. package/dist/router/index.d.ts +28 -0
  122. package/dist/router/index.js +82 -0
  123. package/dist/router/index.js.map +1 -0
  124. package/dist/theme/color.js +25 -0
  125. package/dist/theme/color.js.map +1 -0
  126. package/dist/theme/resolve.d.ts +6 -0
  127. package/dist/theme/resolve.js +310 -0
  128. package/dist/theme/resolve.js.map +1 -0
  129. package/dist/theme/scope.d.ts +42 -0
  130. package/dist/theme/scope.js +80 -0
  131. package/dist/theme/scope.js.map +1 -0
  132. package/dist/theme/styles.js +39 -0
  133. package/dist/theme/styles.js.map +1 -0
  134. package/dist/theme-scope.d.ts +56 -0
  135. package/dist/theme-scope.js +127 -0
  136. package/dist/theme-scope.js.map +1 -0
  137. package/dist/tokens/defaults.d.ts +407 -0
  138. package/dist/tokens/defaults.js +403 -0
  139. package/dist/tokens/defaults.js.map +1 -0
  140. package/dist/typography/fonts.js +84 -0
  141. package/dist/typography/fonts.js.map +1 -0
  142. package/dist/typography/roles.d.ts +10 -0
  143. package/dist/typography/roles.js +82 -0
  144. package/dist/typography/roles.js.map +1 -0
  145. package/package.json +132 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ReactNode","Ref","RefObject","LayoutChangeEvent","StyleProp","TextInputProps","TextStyle","ViewProps","ViewStyle","AnimatedStyle","DerivedValue","createContext","use","useEffect","useId","useMemo","useRef","useState","AccessibilityInfo","Text","NativeText","Platform","Pressable","TextInput","useWindowDimensions","View","Animated","Easing","useAnimatedStyle","useDerivedValue","useReducedMotion","withTiming","IconStyle","ResolvedTheme","useInsideForm","IconStyleContext","usePressFeedback","withOpacity","useTheme","composeStyles","useFontFamily","useTypeRole","fieldStylesOf","BoxControl","disabled","floated","invalid","label","required","underLabel","DescribedBy","Pick","FieldBoxProps","children","control","end","floatingLabel","isDisabled","isFocused","isInvalid","isPopulated","isRequired","leading","trailing","variant","FieldVariant","FieldDescriptionPart","id","text","FieldInputProps","Omit","described","numeric","prefix","ref","suffix","FieldMessageProps","characterCount","characterLimitLabel","description","error","length","maxLength","FieldState","focused","hovered","FieldStatesProps","FieldStrokeProps","StrokeMotion","sides","style","LabelPlace","fontSize","letterSpacing","lineHeight","top","color","width","WebState","ICON_SIZE","OUTSIDE_BOX","BoxContext","NO_PARTS","counterFormat","Intl","NumberFormat","describedBy","ids","idsOf","message","undefined","limit","limitOf","FieldBox","t0","$","_c","t1","t2","t3","t4","t5","t6","t7","theme","styles","fontScale","notch","setNotch","colors","radii","spacing","stateLayerOpacity","typography","t8","xs","borderTopEndRadius","borderTopStartRadius","t9","onSurface","corners","disableRipple","feedback","outlined","t10","state","rule","useRuleMotion","t11","t12","boxControlOf","boxControl","t13","disabledContent","T0","t14","t15","t16","handlers","onHoverIn","t17","onHoverOut","t18","focusOf","t19","box","boxLeading","boxTrailing","boxOutlined","boxDisabled","minHeightOf","lg","bodyLargeLineHeight","sm","bodySmallLineHeight","t20","outline","outlineStart","widthOf","outlineInset","outlineStartBox","outlineNotch","outlineNotchBox","outlineEnd","minWidthOf","outlineEndBox","layer","indicator","t21","onSurfaceVariant","icon","iconStyleOf","t22","t23","t24","t25","column","t26","t27","FieldInput","props","role","mono","fontFamilyMono","content","caret","primary","muted","affixed","clearance","marginTopOf","affixStyle","colorOf","descriptionOf","affixPart","webStateOf","OS","INHERITS_DIRECTION","input","numericOf","affixLine","FieldMessage","insideForm","collapsed","messageStyle","SHRINKS","useErrorAnnouncement","messageLine","messageLineCollapsed","OUT_OF_FLOW","ATOMIC","HIDDEN","NOT_DRAWN","counter","countOf","FieldStates","states","useFieldFocus","onBlur","onFocus","setFocused","event","event_0","const","dir","display","position","flexShrink","Affix","motion","reduceMotion","opacity","timing","duration","durationShort3","easing","bezier","easingStandard","fade","affix","String","BoxLabel","large","small","smallRole","place","bodyLargeSize","bodyLargeTracking","motionStyle","labelOutlined","labelTextOutlined","REQUIRED_MARK","format","parts","map","part","join","said","filter","accessibilityHint","current","focus","size","marginTop","minHeight","minWidth","NotchMeasure","onMeasure","notchMeasure","T1","widthTo","fontFamily","fontVariant","md","FieldStroke","stroke","borderColor","get","borderWidth","borderTopWidth","announceForAccessibility","onErrorContainer","disabledContainer","useStrokeMotion","durationShort2","nativeEvent","layout","_c","state","NativeText","color"],"sources":["../../src/field/index.tsx"],"sourcesContent":["import type { ReactNode, Ref, RefObject } from 'react'\nimport type {\n LayoutChangeEvent,\n StyleProp,\n TextInputProps,\n TextStyle,\n ViewProps,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle, DerivedValue } from 'react-native-reanimated'\n\nimport {\n createContext,\n use,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n AccessibilityInfo,\n Text as NativeText,\n Platform,\n Pressable,\n TextInput,\n useWindowDimensions,\n View,\n} from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useDerivedValue,\n useReducedMotion,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { IconStyle } from '../glyphs/icon-style'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { useInsideForm } from '../form'\nimport { IconStyleContext } from '../glyphs/icon-style'\nimport { usePressFeedback } from '../press'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles } from '../theme/styles'\nimport { useFontFamily } from '../typography/fonts'\nimport { useTypeRole } from '../typography/roles'\nimport { fieldStylesOf } from './styles'\n\n// The chrome every field shares, as on web: the box with its label, the\n// control inside it, and the line of supporting text under it. Each field is\n// the parts it renders inside a root of its own, and these are not exported\n// from the package.\n//\n// The text fields page draws two boxes. The filled one carries surface\n// container highest with an active indicator along its bottom, 1dp in the\n// outline role at rest and 2dp in primary while focused, and its label floats\n// within it. The outlined one has no fill and a 1dp outline all round that\n// thickens the same way, and its label floats up onto the outline, cutting a\n// notch in it.\n//\n// **The label floats by changing its type and its place**, eased by\n// Reanimated over `durationShort3` on the standard curve, as web transitions\n// them: body large on the value's line while the field is empty and\n// unfocused, body small at the top once it is focused or holds a value.\n// `floatingLabel={false}` keeps it small at the top in label medium, as web's\n// fixed label is. Under reduced motion it moves at once.\n//\n// **The box grows with the device's text size.** Its height is a floor rather\n// than a height, the padding above and below plus the lines it holds, and the\n// lines are the type tokens' line heights at the device's font scale, which\n// is what React Native draws the text at. So the 56dp the page gives is the\n// floor at the default text size, and a larger one makes the box taller\n// rather than running the value out of it.\n//\n// **The outline is drawn from views**, since there is no fieldset to cut it:\n// three pieces in a row, the stretch before the label, the notch under it,\n// which draws only the bottom of the outline, and the stretch after it. The\n// notch is the label's width in its floated type, measured from a copy of it\n// out of sight, as web's legend holds one. Before the label floats it is\n// closed, and the two stretches meet.\n//\n// **A pointer over the filled box draws the state layer**, the one every\n// control draws through `usePressFeedback`, on surface at the hover opacity,\n// and turns the indicator on surface, as the page's hovered state does; one\n// over the outlined box turns the outline on surface. Web's filled box draws\n// neither. Focus wins over hover, and an error takes the\n// error role, or on error container under a pointer.\n//\n// **Disabled is the page's colour at an opacity, translucent**: the filled\n// container and the rule are on surface at the `disabledContainer` opacity,\n// and the label, the value and the icons on surface at `disabledContent`,\n// over whatever the field sits on rather than mixed over the surface role as\n// web's are.\n\n// What a control needs to know about the box around it: how the label is\n// drawn, whether the control clears it, and the states it takes its colours\n// from.\ntype BoxControl = {\n readonly disabled: boolean\n readonly floated: boolean\n readonly invalid: boolean\n readonly label: 'fixed' | 'floating' | 'none'\n readonly required: boolean\n readonly underLabel: boolean\n}\n\ntype DescribedBy = Pick<ViewProps, 'accessibilityHint'> & {\n readonly 'aria-describedby'?: string\n}\n\ntype FieldBoxProps = {\n readonly children?: ReactNode\n /**\n * The control the box focuses when it is pressed anywhere, as the whole\n * of a native text field's box takes a press.\n */\n readonly control: RefObject<null | TextInput>\n /**\n * What the box holds after the label and the control's column, drawn as\n * it is rather than in an icon's slot, for a part laid out against the\n * box's own edges: a number field's steppers. The column, and the label\n * in it, end where this starts, 16dp before it.\n */\n readonly end?: ReactNode\n /**\n * Whether the label sits in the empty box and floats to the top once the\n * field is focused or holds a value. `false` keeps it small at the top.\n * @default true\n */\n readonly floatingLabel?: boolean\n /** @default false */\n readonly isDisabled?: boolean\n /** Whether the control has focus, which the box draws. */\n readonly isFocused?: boolean\n /** @default false */\n readonly isInvalid?: boolean\n /** Whether the control holds anything, which floats the label. */\n readonly isPopulated?: boolean\n /**\n * Marks the label with an asterisk, as the text fields page marks a field\n * that must be filled.\n * @default false\n */\n readonly isRequired?: boolean\n /** What the field is for. */\n readonly label: string\n /** An icon at the start of the box, before the label and the control. */\n readonly leading?: ReactNode\n /** An icon at the end of the box, after the control. */\n readonly trailing?: ReactNode\n /** @default 'filled' */\n readonly variant?: FieldVariant\n}\n\n/**\n * One piece of what describes a field's control: the text a screen reader\n * hears on iOS and Android, and the id of the element showing it, which the\n * control points at under React Native Web.\n */\ntype FieldDescriptionPart = {\n readonly id: string\n readonly text: string\n}\n\ntype FieldInputProps = Omit<\n TextInputProps,\n | 'accessibilityHint'\n | 'cursorColor'\n | 'multiline'\n | 'placeholderTextColor'\n | 'selectionColor'\n | 'style'\n | 'underlineColorAndroid'\n> & {\n /** What describes the control, after its prefix and suffix. */\n readonly described?: readonly FieldDescriptionPart[]\n /**\n * The value in the mono face with tabular figures.\n * @default false\n */\n readonly numeric?: boolean\n /** Text before the value on its line. */\n readonly prefix?: ReactNode\n readonly ref?: Ref<TextInput>\n /** Text after the value on its line. */\n readonly suffix?: ReactNode\n}\n\ntype FieldMessageProps = {\n /**\n * Counts the characters, against `maxLength` where there is one.\n * @default false\n */\n readonly characterCount?: boolean\n /** How the limit is said to a screen reader. */\n readonly characterLimitLabel?: string | undefined\n /** The hint, which the error replaces while there is one. */\n readonly description?: string | undefined\n /** The problem with the value, in words. */\n readonly error?: string | undefined\n /** The field's id, as handed to {@link describedBy}. */\n readonly id: string\n /** How many characters the control holds. */\n readonly length?: number\n readonly maxLength?: number | undefined\n}\n\ntype FieldState = {\n readonly disabled: boolean\n readonly focused: boolean\n readonly hovered: boolean\n readonly invalid: boolean\n}\n\ntype FieldStatesProps = {\n readonly children?: ReactNode\n /** @default false */\n readonly isDisabled?: boolean\n /** @default false */\n readonly isInvalid?: boolean\n /** @default false */\n readonly isRequired?: boolean\n}\n\ntype FieldStrokeProps = StrokeMotion & {\n /** Every side of the view, or the top alone. */\n readonly sides: 'all' | 'top'\n readonly style: StyleProp<ViewStyle>\n}\n\n/**\n * The filled box, or the outlined one: no fill, an outline that thickens and\n * takes the primary role while focused, and the label cutting it once it\n * floats, the text fields page's two fields.\n */\ntype FieldVariant = 'filled' | 'outlined'\n\n// Where the label is and what type it is in, at rest or floated.\ntype LabelPlace = {\n readonly fontSize: number\n readonly letterSpacing: number\n readonly lineHeight: number\n readonly top: number\n}\n\n// The control's state as React Native Web hands it to a browser, which reads\n// `aria-invalid` and `aria-required` off the input. React Native has neither.\n// A rule's colour and width as they ease.\ntype StrokeMotion = {\n readonly color: DerivedValue<string>\n readonly width: DerivedValue<number>\n}\n\ntype WebState = {\n readonly 'aria-invalid'?: true\n readonly 'aria-required'?: true\n}\n\n// The page's icon, which the box's outline is laid out around.\nconst ICON_SIZE = 24\n\n// A control outside any box has no label over it.\nconst OUTSIDE_BOX: BoxControl = {\n disabled: false,\n floated: true,\n invalid: false,\n label: 'none',\n required: false,\n underLabel: false,\n}\n\nconst BoxContext = createContext<BoxControl>(OUTSIDE_BOX)\n\nconst NO_PARTS: readonly FieldDescriptionPart[] = []\n\nlet counterFormat: Intl.NumberFormat | undefined\n\n/**\n * How a field's control is described by the line under it: the error while\n * there is one, otherwise the description, then the limit where there is a\n * `maxLength`. Hand the result to {@link FieldInput} as `described`, and the\n * same `id` to {@link FieldMessage}.\n */\nfunction describedBy(\n id: string,\n {\n characterLimitLabel,\n description,\n error,\n maxLength,\n }: Pick<\n FieldMessageProps,\n 'characterLimitLabel' | 'description' | 'error' | 'maxLength'\n >,\n): readonly FieldDescriptionPart[] {\n const ids = idsOf(id)\n const message =\n error === undefined\n ? { id: ids.description, text: description ?? '' }\n : { id: ids.error, text: error }\n const limit = limitOf(maxLength, characterLimitLabel)\n\n return [\n ...(message.text === '' ? [] : [message]),\n ...(limit === undefined ? [] : [{ id: ids.limit, text: limit }]),\n ]\n}\n\n/**\n * The box a control sits in, filled or outlined, with its label. Pressed\n * anywhere, it focuses its control. The states it draws are handed to it,\n * since the field around it is what knows them.\n */\nfunction FieldBox({\n children,\n control,\n end,\n floatingLabel = true,\n isDisabled = false,\n isFocused = false,\n isInvalid = false,\n isPopulated = false,\n isRequired = false,\n label,\n leading,\n trailing,\n variant = 'filled',\n}: FieldBoxProps) {\n const theme = useTheme()\n const styles = fieldStylesOf(theme)\n const { fontScale } = useWindowDimensions()\n const [notch, setNotch] = useState(0)\n const { colors, radii, spacing, stateLayerOpacity, typography } = theme\n // The hover layer alone: a text field's box takes no pressed or focus\n // layer, since the indicator and the label are what mark its focus.\n const feedback = usePressFeedback({\n color: colors.onSurface,\n corners: {\n borderTopEndRadius: radii.xs,\n borderTopStartRadius: radii.xs,\n },\n disabled: isDisabled,\n disableRipple: true,\n })\n const outlined = variant === 'outlined'\n const floated = !floatingLabel || isFocused || isPopulated\n const state: FieldState = {\n disabled: isDisabled,\n focused: isFocused,\n hovered: feedback.hovered,\n invalid: isInvalid,\n }\n const rule = useRuleMotion(theme, state)\n const boxControl = useMemo(\n () =>\n boxControlOf(\n floatingLabel,\n floated,\n isDisabled,\n isInvalid,\n isRequired,\n !outlined,\n ),\n [floatingLabel, floated, isDisabled, isInvalid, isRequired, outlined],\n )\n const disabledContent = withOpacity(\n colors.onSurface,\n stateLayerOpacity.disabledContent,\n )\n\n return (\n <Pressable\n accessible={false}\n disabled={isDisabled}\n focusable={false}\n onHoverIn={feedback.handlers.onHoverIn}\n onHoverOut={feedback.handlers.onHoverOut}\n onPress={focusOf(control)}\n style={composeStyles<ViewStyle>(\n styles.box,\n leading === undefined ? undefined : styles.boxLeading,\n trailing === undefined ? undefined : styles.boxTrailing,\n outlined ? styles.boxOutlined : undefined,\n isDisabled && !outlined ? styles.boxDisabled : undefined,\n minHeightOf(\n outlined\n ? 2 * spacing.lg + typography.bodyLargeLineHeight * fontScale\n : 2 * spacing.sm +\n (typography.bodySmallLineHeight +\n typography.bodyLargeLineHeight) *\n fontScale,\n ),\n )}\n >\n {outlined ? (\n <View aria-hidden style={styles.outline}>\n <View\n style={composeStyles<ViewStyle>(\n styles.outlineStart,\n widthOf(outlineInset(spacing, leading)),\n )}\n >\n <FieldStroke\n color={rule.color}\n sides=\"all\"\n style={styles.outlineStartBox}\n width={rule.width}\n />\n </View>\n <View\n style={composeStyles<ViewStyle>(\n styles.outlineNotch,\n widthOf(floated ? notch : 0),\n )}\n >\n <FieldStroke\n color={rule.color}\n sides=\"all\"\n style={styles.outlineNotchBox}\n width={rule.width}\n />\n </View>\n <View\n style={composeStyles<ViewStyle>(\n styles.outlineEnd,\n minWidthOf(outlineInset(spacing, trailing)),\n )}\n >\n <FieldStroke\n color={rule.color}\n sides=\"all\"\n style={styles.outlineEndBox}\n width={rule.width}\n />\n </View>\n </View>\n ) : (\n <>\n {feedback.layer}\n <FieldStroke\n color={rule.color}\n sides=\"top\"\n style={styles.indicator}\n width={rule.width}\n />\n </>\n )}\n {leading === undefined ? null : (\n <View style={styles.icon}>\n <IconStyleContext\n value={iconStyleOf(\n isDisabled ? disabledContent : colors.onSurfaceVariant,\n )}\n >\n {leading}\n </IconStyleContext>\n </View>\n )}\n <View style={styles.column}>\n <BoxLabel\n floated={floated}\n floatingLabel={floatingLabel}\n isDisabled={isDisabled}\n isFocused={isFocused}\n isInvalid={isInvalid}\n isRequired={isRequired}\n variant={variant}\n >\n {label}\n </BoxLabel>\n {outlined ? (\n <NotchMeasure\n floatingLabel={floatingLabel}\n isRequired={isRequired}\n onMeasure={setNotch}\n >\n {label}\n </NotchMeasure>\n ) : null}\n <BoxContext value={boxControl}>{children}</BoxContext>\n </View>\n {end}\n {trailing === undefined ? null : (\n <View style={styles.icon}>\n <IconStyleContext\n value={iconStyleOf(\n isDisabled\n ? disabledContent\n : isInvalid\n ? colors.error\n : colors.onSurfaceVariant,\n )}\n >\n {trailing}\n </IconStyleContext>\n </View>\n )}\n </Pressable>\n )\n}\n\n/**\n * A field's text control, in a {@link FieldBox}, or in {@link FieldStates}\n * inside a container of a field's own. In a box it clears the label at the\n * top where the box is filled, and shows a prefix and a suffix only while the\n * label has floated, since at rest the label sits on their line. It takes the\n * error role for its caret while the field has an error, and draws a\n * placeholder in the muted role.\n *\n * It is described by its prefix and suffix, ahead of what the field hands it\n * in `described`, so a reader hears the unit the value is read against as a\n * sighted one sees it beside the value: on iOS and Android as its hint, and\n * under React Native Web through `aria-describedby`, which drops the hint.\n */\nfunction FieldInput({\n described = NO_PARTS,\n numeric = false,\n prefix,\n suffix,\n ...props\n}: FieldInputProps) {\n const box = use(BoxContext)\n const theme = useTheme()\n const styles = fieldStylesOf(theme)\n const { fontScale } = useWindowDimensions()\n const role = useTypeRole('bodyLarge')\n const mono = useFontFamily(theme.typography.fontFamilyMono)\n const id = useId()\n const { colors, stateLayerOpacity, typography } = theme\n const content = box.disabled\n ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n : colors.onSurface\n const caret = box.invalid ? colors.error : colors.primary\n const muted = box.disabled\n ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n : colors.onSurfaceVariant\n const affixed = prefix !== undefined || suffix !== undefined\n const clearance = box.underLabel\n ? marginTopOf(typography.bodySmallLineHeight * fontScale)\n : undefined\n const affixStyle = composeStyles<TextStyle>(role, colorOf(muted))\n\n const control = (\n <TextInput\n {...(Platform.OS === 'web' ? INHERITS_DIRECTION : undefined)}\n {...props}\n {...descriptionOf([\n ...affixPart(`${id}-prefix`, prefix),\n ...affixPart(`${id}-suffix`, suffix),\n ...described,\n ])}\n {...webStateOf(box)}\n aria-disabled={box.disabled}\n cursorColor={caret}\n placeholderTextColor={muted}\n selectionColor={caret}\n style={composeStyles<TextStyle>(\n role,\n styles.input,\n colorOf(content),\n numeric ? numericOf(mono) : undefined,\n minHeightOf(typography.bodyLargeLineHeight * fontScale),\n affixed ? undefined : clearance,\n )}\n underlineColorAndroid=\"transparent\"\n />\n )\n\n if (!affixed) {\n return control\n }\n\n return (\n <View style={composeStyles<ViewStyle>(styles.affixLine, clearance)}>\n {prefix === undefined ? null : (\n <Affix floated={box.floated} id={`${id}-prefix`} style={affixStyle}>\n {prefix}\n </Affix>\n )}\n {control}\n {suffix === undefined ? null : (\n <Affix floated={box.floated} id={`${id}-suffix`} style={affixStyle}>\n {suffix}\n </Affix>\n )}\n </View>\n )\n}\n\n/**\n * The line under a field: the error while there is one, the description\n * otherwise, and the count of characters at its end. With nothing to show it\n * is out of the flow, so the field ends at its box. Inside a form it is drawn\n * anyway, empty, since a form is where an error arrives after the fact, from\n * a server or on a submission, and every field below this one would\n * otherwise move by the line's height when it does.\n *\n * On iOS and Android the control reads the line out as its hint, so the line\n * itself is hidden from VoiceOver and TalkBack rather than read twice. An\n * error is announced as it arrives, since a hint that changes is not read\n * again: on iOS through `announceForAccessibility`, and on Android, where the\n * error is left reachable for it, by a polite live region around it, which\n * is also what announces it under React Native Web. An error the field opens\n * with is not announced, as a live region in a browser does not read what it\n * was mounted holding.\n *\n * The count is hidden everywhere. It changes on every keystroke, and read\n * back at that rate it is worse than not hearing it, so the limit is said\n * once in the control's description instead.\n */\nfunction FieldMessage({\n characterCount = false,\n characterLimitLabel,\n description,\n error,\n id,\n length = 0,\n maxLength,\n}: FieldMessageProps) {\n const theme = useTheme()\n const styles = fieldStylesOf(theme)\n const role = useTypeRole('bodySmall')\n const { fontScale } = useWindowDimensions()\n const ids = idsOf(id)\n const invalid = error !== undefined\n const limit = limitOf(maxLength, characterLimitLabel)\n const insideForm = useInsideForm()\n const collapsed =\n !invalid && description === undefined && !characterCount && !insideForm\n const { colors, typography } = theme\n const messageStyle = composeStyles<TextStyle>(\n role,\n colorOf(invalid ? colors.error : colors.onSurfaceVariant),\n SHRINKS,\n )\n\n useErrorAnnouncement(error)\n\n return (\n <View\n style={composeStyles<ViewStyle>(\n styles.messageLine,\n collapsed\n ? styles.messageLineCollapsed\n : minHeightOf(typography.bodySmallLineHeight * fontScale),\n )}\n >\n <View\n aria-live=\"polite\"\n {...(Platform.OS === 'web' ? ATOMIC : undefined)}\n {...(Platform.OS === 'ios' ? HIDDEN : undefined)}\n style={invalid && error !== '' ? SHRINKS : OUT_OF_FLOW}\n >\n {invalid && error !== '' ? (\n <NativeText id={ids.error} style={messageStyle}>\n {error}\n </NativeText>\n ) : null}\n </View>\n {invalid || description === undefined ? null : (\n <NativeText\n {...(Platform.OS === 'web' ? undefined : HIDDEN)}\n id={ids.description}\n style={messageStyle}\n >\n {description}\n </NativeText>\n )}\n {limit === undefined || Platform.OS !== 'web' ? null : (\n <NativeText id={ids.limit} style={NOT_DRAWN}>\n {limit}\n </NativeText>\n )}\n {characterCount ? (\n <NativeText\n aria-hidden\n style={composeStyles<TextStyle>(messageStyle, styles.counter)}\n >\n {countOf(length, maxLength)}\n </NativeText>\n ) : null}\n </View>\n )\n}\n\n/**\n * Hands a control outside a box the states it is drawn in, for a field that\n * draws a container of its own around the control, as SearchField's bar is.\n * The control takes its colours and the state a screen reader reads from\n * these, as it does from the box around it.\n */\nfunction FieldStates({\n children,\n isDisabled = false,\n isInvalid = false,\n isRequired = false,\n}: FieldStatesProps) {\n const states = useMemo(\n () => ({\n ...OUTSIDE_BOX,\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n }),\n [isDisabled, isInvalid, isRequired],\n )\n\n return <BoxContext value={states}>{children}</BoxContext>\n}\n\n/**\n * Tracks whether the control has focus, around the handlers the field was\n * given, which are called after.\n */\nfunction useFieldFocus({\n onBlur,\n onFocus,\n}: Pick<TextInputProps, 'onBlur' | 'onFocus'>) {\n const [focused, setFocused] = useState(false)\n\n return {\n focused,\n handlers: {\n onBlur: ((event) => {\n setFocused(false)\n onBlur?.(event)\n }) satisfies TextInputProps['onBlur'],\n onFocus: ((event) => {\n setFocused(true)\n onFocus?.(event)\n }) satisfies TextInputProps['onFocus'],\n },\n }\n}\n\n// What a web-only atomic live region adds, so a changed message is read whole.\n// React Native's types carry no `aria-atomic`, which React Native Web takes.\nconst ATOMIC = { 'aria-atomic': true } as const\n\n// What hides a part of the line under a field from VoiceOver and TalkBack,\n// where the control reads it out as its hint.\nconst HIDDEN: ViewProps = { 'aria-hidden': true }\n\n// What leaves the control's writing direction to the page under React Native\n// Web, which gives a TextInput `dir=\"auto\"` otherwise and so aligns a value by\n// its own script: a Latin value at the left of a right-to-left field, away\n// from its label. Null rather than left out, since left out is what it writes\n// `auto` for. React Native's types carry no `dir`.\nconst INHERITS_DIRECTION = { dir: null } as const\n\n// The limit under React Native Web: in the document for the control to point\n// at, and drawn nowhere.\nconst NOT_DRAWN: TextStyle = { display: 'none' }\n\n// The live region with nothing in it, which takes no place in the line.\nconst OUT_OF_FLOW: ViewStyle = { position: 'absolute' }\n\nconst SHRINKS: TextStyle = { flexShrink: 1 }\n\n/**\n * A prefix or a suffix, faded in once the label has floated and out when it\n * comes back to rest, over the label's own `durationShort3`.\n */\nfunction Affix({\n children,\n floated,\n id,\n style,\n}: {\n readonly children: ReactNode\n readonly floated: boolean\n readonly id: string\n readonly style: StyleProp<TextStyle>\n}) {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const opacity = floated ? 1 : 0\n const timing = {\n duration: motion.durationShort3,\n easing: Easing.bezier(...motion.easingStandard),\n }\n const fade = useAnimatedStyle(() => {\n 'worklet'\n return {\n opacity: reduceMotion ? opacity : withTiming(opacity, timing),\n }\n })\n\n return (\n <Animated.Text\n id={id}\n style={composeStyles<AnimatedStyle<TextStyle>>(style, fade)}\n >\n {children}\n </Animated.Text>\n )\n}\n\nfunction affixPart(\n id: string,\n affix: ReactNode,\n): readonly FieldDescriptionPart[] {\n if (affix === undefined) {\n return []\n }\n\n return [\n {\n id,\n text:\n typeof affix === 'string' || typeof affix === 'number'\n ? String(affix)\n : '',\n },\n ]\n}\n\nfunction boxControlOf(\n floatingLabel: boolean,\n floated: boolean,\n disabled: boolean,\n invalid: boolean,\n required: boolean,\n underLabel: boolean,\n): BoxControl {\n return {\n disabled,\n floated,\n invalid,\n label: floatingLabel ? 'floating' : 'fixed',\n required,\n underLabel,\n }\n}\n\n/**\n * The box's label: one line, cut short with an ellipsis, moving between its\n * resting place and its floated one. Hidden from screen readers, since the\n * control is named by the same words.\n */\nfunction BoxLabel({\n children,\n floated,\n floatingLabel,\n isDisabled,\n isFocused,\n isInvalid,\n isRequired,\n variant,\n}: {\n readonly children: string\n readonly floated: boolean\n readonly floatingLabel: boolean\n readonly isDisabled: boolean\n readonly isFocused: boolean\n readonly isInvalid: boolean\n readonly isRequired: boolean\n readonly variant: FieldVariant\n}) {\n const theme = useTheme()\n const styles = fieldStylesOf(theme)\n const { fontScale } = useWindowDimensions()\n const reduceMotion = useReducedMotion()\n const large = useTypeRole('bodyLarge')\n const small = useTypeRole(floatingLabel ? 'bodySmall' : 'labelMedium')\n const { colors, motion, spacing, stateLayerOpacity, typography } = theme\n const outlined = variant === 'outlined'\n const smallRole = floatingLabel ? 'bodySmall' : 'labelMedium'\n const place: LabelPlace = floated\n ? {\n fontSize: typography[`${smallRole}Size`],\n letterSpacing: typography[`${smallRole}Tracking`],\n lineHeight: typography[`${smallRole}LineHeight`],\n top: outlined\n ? -(\n spacing.lg +\n (typography[`${smallRole}LineHeight`] * fontScale) / 2\n )\n : 0,\n }\n : {\n fontSize: typography.bodyLargeSize,\n letterSpacing: typography.bodyLargeTracking,\n lineHeight: typography.bodyLargeLineHeight,\n top: outlined ? 0 : (typography.bodySmallLineHeight * fontScale) / 2,\n }\n const color = isDisabled\n ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n : isInvalid\n ? colors.error\n : isFocused\n ? colors.primary\n : colors.onSurfaceVariant\n const timing = {\n duration: motion.durationShort3,\n easing: Easing.bezier(...motion.easingStandard),\n }\n\n const motionStyle = useAnimatedStyle(() => {\n 'worklet'\n return {\n color: reduceMotion ? color : withTiming(color, timing),\n fontSize: reduceMotion\n ? place.fontSize\n : withTiming(place.fontSize, timing),\n letterSpacing: reduceMotion\n ? place.letterSpacing\n : withTiming(place.letterSpacing, timing),\n lineHeight: reduceMotion\n ? place.lineHeight\n : withTiming(place.lineHeight, timing),\n top: reduceMotion ? place.top : withTiming(place.top, timing),\n }\n })\n\n return (\n <View\n aria-hidden\n style={composeStyles<ViewStyle>(\n styles.label,\n outlined ? styles.labelOutlined : undefined,\n )}\n >\n <Animated.Text\n numberOfLines={1}\n style={composeStyles<AnimatedStyle<TextStyle>>(\n floated ? small : large,\n outlined ? styles.labelTextOutlined : undefined,\n motionStyle,\n )}\n >\n {children}\n {isRequired ? REQUIRED_MARK : null}\n </Animated.Text>\n </View>\n )\n}\n\nfunction colorOf(color: string): TextStyle {\n return { color }\n}\n\n// The count in the device's digits and grouping, as web writes it in the\n// reader's locale. One formatter, since the count changes on every keystroke.\nfunction countOf(length: number, maxLength: number | undefined) {\n counterFormat ??= new Intl.NumberFormat()\n\n return maxLength === undefined\n ? counterFormat.format(length)\n : `${counterFormat.format(length)}/${counterFormat.format(maxLength)}`\n}\n\nfunction descriptionOf(\n parts: readonly FieldDescriptionPart[],\n): DescribedBy | undefined {\n if (Platform.OS === 'web') {\n return parts.length === 0\n ? undefined\n : { 'aria-describedby': parts.map((part) => part.id).join(' ') }\n }\n\n const said = parts.map((part) => part.text).filter((text) => text !== '')\n\n return said.length === 0 ? undefined : { accessibilityHint: said.join(' ') }\n}\n\nfunction focusOf(control: RefObject<null | TextInput>) {\n return () => {\n control.current?.focus()\n }\n}\n\nfunction iconStyleOf(color: string): IconStyle {\n return { color, size: ICON_SIZE }\n}\n\nfunction idsOf(id: string) {\n return {\n description: `${id}-description`,\n error: `${id}-error`,\n limit: `${id}-limit`,\n }\n}\n\n/**\n * The limit in words where there is one: the field's own, or English, which\n * an app in another language replaces through `characterLimitLabel`.\n */\nfunction limitOf(maxLength: number | undefined, label: string | undefined) {\n if (maxLength === undefined) {\n return undefined\n }\n\n return (\n label ??\n (maxLength === 1\n ? 'Up to 1 character'\n : `Up to ${String(maxLength)} characters`)\n )\n}\n\nfunction marginTopOf(marginTop: number): ViewStyle {\n return { marginTop }\n}\n\nfunction minHeightOf(minHeight: number): ViewStyle {\n return { minHeight }\n}\n\nfunction minWidthOf(minWidth: number): ViewStyle {\n return { minWidth }\n}\n\n/**\n * The label's text in its floated type, out of sight, measured for the\n * outlined box's notch.\n */\nfunction NotchMeasure({\n children,\n floatingLabel,\n isRequired,\n onMeasure,\n}: {\n readonly children: string\n readonly floatingLabel: boolean\n readonly isRequired: boolean\n readonly onMeasure: (width: number) => void\n}) {\n const styles = fieldStylesOf(useTheme())\n const small = useTypeRole(floatingLabel ? 'bodySmall' : 'labelMedium')\n\n return (\n <View\n aria-hidden\n style={composeStyles<ViewStyle>(\n styles.label,\n styles.labelOutlined,\n styles.notchMeasure,\n )}\n >\n <NativeText\n numberOfLines={1}\n onLayout={widthTo(onMeasure)}\n style={composeStyles<TextStyle>(small, styles.labelTextOutlined)}\n >\n {children}\n {isRequired ? REQUIRED_MARK : null}\n </NativeText>\n </View>\n )\n}\n\nfunction numericOf(fontFamily: string | undefined): TextStyle {\n return { fontFamily, fontVariant: ['tabular-nums'] }\n}\n\n// How far an outline stretch reaches along the box before the label's place\n// begins or after it ends: the box's padding at that end, and past an icon\n// the page's 12dp, the icon and its 16dp, less the notch's own 4dp beside the\n// label.\nfunction outlineInset(spacing: ResolvedTheme['spacing'], icon: ReactNode) {\n return (\n (icon === undefined ? spacing.lg : spacing.md + ICON_SIZE + spacing.lg) -\n spacing.xs\n )\n}\n\n// The asterisk after a required field's label, which is how the text fields\n// page marks one. In the label rather than beside it, so it floats and takes\n// the label's colour with it.\nconst REQUIRED_MARK = '*'\n\n/**\n * One view drawing a field's rule in its eased colour and width, from\n * {@link useStrokeMotion}: on every side, for the outlined box's outline,\n * which the piece around it clips, and a bar's ring, or on the top alone,\n * for the filled box's indicator.\n */\nfunction FieldStroke({ color, sides, style, width }: FieldStrokeProps) {\n const stroke = useAnimatedStyle(() => {\n 'worklet'\n return sides === 'all'\n ? { borderColor: color.get(), borderWidth: width.get() }\n : { borderColor: color.get(), borderTopWidth: width.get() }\n })\n\n return (\n <Animated.View\n aria-hidden\n style={composeStyles<AnimatedStyle<ViewStyle>>(style, stroke)}\n />\n )\n}\n\n// Says an error on iOS as it arrives. An error the field opened with is not\n// said, and neither is one that has not changed.\nfunction useErrorAnnouncement(error: string | undefined) {\n const said = useRef(error)\n\n useEffect(() => {\n if (\n Platform.OS === 'ios' &&\n error !== undefined &&\n error !== '' &&\n error !== said.current\n ) {\n AccessibilityInfo.announceForAccessibility(error)\n }\n said.current = error\n }, [error])\n}\n\n/**\n * The rule the box draws, the filled box's indicator or the outlined box's\n * outline: its colour and its width by state.\n */\nfunction useRuleMotion(theme: ResolvedTheme, state: FieldState) {\n const { colors, stateLayerOpacity } = theme\n const width = !state.disabled && state.focused ? 2 : 1\n const color = state.disabled\n ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContainer)\n : state.focused\n ? state.invalid\n ? colors.error\n : colors.primary\n : state.hovered\n ? state.invalid\n ? colors.onErrorContainer\n : colors.onSurface\n : state.invalid\n ? colors.error\n : colors.outline\n\n return useStrokeMotion(color, width)\n}\n\n/**\n * A rule's colour and width, eased to each new pair over `durationShort2` as\n * web transitions them, and moved at once under reduced motion. Hand the\n * result to {@link FieldStroke}.\n */\nfunction useStrokeMotion(color: string, width: number): StrokeMotion {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const timing = {\n duration: motion.durationShort2,\n easing: Easing.bezier(...motion.easingStandard),\n }\n\n return {\n color: useDerivedValue<string>(() =>\n reduceMotion ? color : withTiming(color, timing),\n ),\n width: useDerivedValue<number>(() =>\n reduceMotion ? width : withTiming(width, timing),\n ),\n }\n}\n\nfunction webStateOf(box: BoxControl): undefined | WebState {\n if (Platform.OS !== 'web') {\n return undefined\n }\n\n return {\n ...(box.invalid ? { 'aria-invalid': true } : undefined),\n ...(box.required ? { 'aria-required': true } : undefined),\n }\n}\n\nfunction widthOf(width: number): ViewStyle {\n return { width }\n}\n\nfunction widthTo(onMeasure: (width: number) => void) {\n return (event: LayoutChangeEvent) => {\n onMeasure(event.nativeEvent.layout.width)\n }\n}\n\nexport {\n describedBy,\n FieldBox,\n FieldInput,\n FieldMessage,\n FieldStates,\n FieldStroke,\n useFieldFocus,\n useStrokeMotion,\n}\nexport type {\n FieldBoxProps,\n FieldDescriptionPart,\n FieldInputProps,\n FieldMessageProps,\n FieldStatesProps,\n FieldStrokeProps,\n FieldVariant,\n}\n"],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ import { themedStyles } from "../theme/styles.js";
2
+ import { withOpacity } from "../theme/color.js";
3
+ import { StyleSheet } from "react-native";
4
+ //#region src/field/styles.ts
5
+ const fieldStylesOf = themedStyles(({ colors, radii, spacing, stateLayerOpacity }) => StyleSheet.create({
6
+ affixLine: {
7
+ alignItems: "baseline",
8
+ flexDirection: "row",
9
+ flexGrow: 1,
10
+ gap: spacing.xxs
11
+ },
12
+ box: {
13
+ backgroundColor: colors.surfaceContainerHighest,
14
+ borderTopEndRadius: radii.xs,
15
+ borderTopStartRadius: radii.xs,
16
+ flexDirection: "row",
17
+ gap: spacing.lg,
18
+ paddingHorizontal: spacing.lg,
19
+ paddingVertical: spacing.sm
20
+ },
21
+ boxDisabled: { backgroundColor: withOpacity(colors.onSurface, stateLayerOpacity.disabledContainer) },
22
+ boxLeading: { paddingStart: spacing.md },
23
+ boxOutlined: {
24
+ backgroundColor: "transparent",
25
+ paddingVertical: spacing.lg
26
+ },
27
+ boxTrailing: { paddingEnd: spacing.md },
28
+ column: {
29
+ flexGrow: 1,
30
+ flexShrink: 1,
31
+ justifyContent: "flex-start",
32
+ minWidth: 0
33
+ },
34
+ counter: {
35
+ flexShrink: 0,
36
+ fontVariant: ["tabular-nums"],
37
+ marginStart: "auto"
38
+ },
39
+ icon: {
40
+ alignItems: "center",
41
+ alignSelf: "center",
42
+ justifyContent: "center"
43
+ },
44
+ indicator: {
45
+ bottom: 0,
46
+ end: 0,
47
+ position: "absolute",
48
+ start: 0
49
+ },
50
+ input: {
51
+ flexGrow: 1,
52
+ flexShrink: 1,
53
+ margin: 0,
54
+ minWidth: 0,
55
+ outlineStyle: "solid",
56
+ outlineWidth: 0,
57
+ padding: 0
58
+ },
59
+ label: {
60
+ alignItems: "flex-start",
61
+ end: 0,
62
+ pointerEvents: "none",
63
+ position: "absolute",
64
+ start: 0,
65
+ top: 0
66
+ },
67
+ labelOutlined: {
68
+ end: -spacing.xs,
69
+ start: -spacing.xs
70
+ },
71
+ labelTextOutlined: { paddingHorizontal: spacing.xs },
72
+ messageLine: {
73
+ flexDirection: "row",
74
+ gap: spacing.lg,
75
+ marginTop: spacing.xs,
76
+ paddingHorizontal: spacing.lg
77
+ },
78
+ messageLineCollapsed: {
79
+ marginTop: 0,
80
+ position: "absolute"
81
+ },
82
+ notchMeasure: { opacity: 0 },
83
+ outline: {
84
+ bottom: 0,
85
+ flexDirection: "row",
86
+ left: 0,
87
+ pointerEvents: "none",
88
+ position: "absolute",
89
+ right: 0,
90
+ top: 0
91
+ },
92
+ outlineEnd: {
93
+ flexGrow: 1,
94
+ overflow: "hidden"
95
+ },
96
+ outlineEndBox: {
97
+ borderRadius: radii.xs,
98
+ bottom: 0,
99
+ end: 0,
100
+ position: "absolute",
101
+ start: -8,
102
+ top: 0
103
+ },
104
+ outlineNotch: {
105
+ flexShrink: 1,
106
+ overflow: "hidden"
107
+ },
108
+ outlineNotchBox: {
109
+ bottom: 0,
110
+ end: -8,
111
+ position: "absolute",
112
+ start: -8,
113
+ top: -8
114
+ },
115
+ outlineStart: {
116
+ flexShrink: 0,
117
+ overflow: "hidden"
118
+ },
119
+ outlineStartBox: {
120
+ borderRadius: radii.xs,
121
+ bottom: 0,
122
+ end: -8,
123
+ position: "absolute",
124
+ start: 0,
125
+ top: 0
126
+ }
127
+ }));
128
+ //#endregion
129
+ export { fieldStylesOf };
130
+
131
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","names":["StyleSheet","withOpacity","themedStyles","OUTLINE_REACH","fieldStylesOf","colors","radii","spacing","stateLayerOpacity","create","affixLine","alignItems","flexDirection","flexGrow","gap","xxs","box","backgroundColor","surfaceContainerHighest","borderTopEndRadius","xs","borderTopStartRadius","lg","paddingHorizontal","paddingVertical","sm","boxDisabled","onSurface","disabledContainer","boxLeading","paddingStart","md","boxOutlined","boxTrailing","paddingEnd","column","flexShrink","justifyContent","minWidth","counter","fontVariant","marginStart","icon","alignSelf","indicator","bottom","end","position","start","input","margin","outlineStyle","outlineWidth","padding","label","pointerEvents","top","labelOutlined","labelTextOutlined","messageLine","marginTop","messageLineCollapsed","notchMeasure","opacity","outline","left","right","outlineEnd","overflow","outlineEndBox","borderRadius","outlineNotch","outlineNotchBox","outlineStart","outlineStartBox"],"sources":["../../src/field/styles.ts"],"sourcesContent":["import { StyleSheet } from 'react-native'\n\nimport { withOpacity } from '../theme/color'\nimport { themedStyles } from '../theme/styles'\n\n// The chrome's styles, apart from ./index.tsx so that file holds components\n// alone. What follows the device's text size, the box's height and the\n// label's places, is worked out where it renders, since a stylesheet is built\n// once per theme and the text size can change under it.\n//\n// The box is a row: an icon slot at either end, if the field has one, with the\n// label and the control in a column between them. The page gives the icons\n// 24dp, 12dp from the box's edge and 16dp from the text, centred in the box's\n// height, which the slot is with the box's padding the same above and below.\n\n/**\n * How far an outline piece's own box reaches past the piece that clips it, so\n * the borders and corners on that side fall outside it. A corner's radius and\n * the thickest border are enough; this is that, with room to spare.\n */\nconst OUTLINE_REACH = 8\n\nconst fieldStylesOf = themedStyles(\n ({ colors, radii, spacing, stateLayerOpacity }) =>\n StyleSheet.create({\n // The control's line, holding the affixes beside it. The 2dp is\n // Compose's padding between the two, since the page gives none.\n affixLine: {\n alignItems: 'baseline',\n flexDirection: 'row',\n flexGrow: 1,\n gap: spacing.xxs,\n },\n // The filled box: surface container highest, the page's 4dp corners at\n // the top and square at the bottom, where the indicator runs the full\n // width. 8dp above the label and below the value, and 16dp at either\n // end, or 12dp beside an icon.\n box: {\n backgroundColor: colors.surfaceContainerHighest,\n borderTopEndRadius: radii.xs,\n borderTopStartRadius: radii.xs,\n flexDirection: 'row',\n gap: spacing.lg,\n paddingHorizontal: spacing.lg,\n paddingVertical: spacing.sm,\n },\n boxDisabled: {\n backgroundColor: withOpacity(\n colors.onSurface,\n stateLayerOpacity.disabledContainer,\n ),\n },\n boxLeading: {\n paddingStart: spacing.md,\n },\n // The outlined box: no fill, and 16dp above and below the value, which\n // centres it, since the label sits on the outline rather than over it.\n boxOutlined: {\n backgroundColor: 'transparent',\n paddingVertical: spacing.lg,\n },\n boxTrailing: {\n paddingEnd: spacing.md,\n },\n // The label and the control's column, which the label is placed\n // against, so it moves past a leading icon with the text.\n column: {\n flexGrow: 1,\n flexShrink: 1,\n justifyContent: 'flex-start',\n minWidth: 0,\n },\n // The count of characters, at the end of the message line in tabular\n // figures so it does not jitter as it counts.\n counter: {\n flexShrink: 0,\n fontVariant: ['tabular-nums'],\n marginStart: 'auto',\n },\n // An icon slot, centred in the box's height whatever it holds: the\n // page's 24dp icon, or an icon button around one.\n icon: {\n alignItems: 'center',\n alignSelf: 'center',\n justifyContent: 'center',\n },\n // The filled box's active indicator: a rule across the bottom, laid\n // over the box so it thickening on focus moves nothing. A border\n // rather than a fill, since a forced palette on the web keeps a\n // border and paints over a background.\n indicator: {\n bottom: 0,\n end: 0,\n position: 'absolute',\n start: 0,\n },\n input: {\n flexGrow: 1,\n flexShrink: 1,\n margin: 0,\n minWidth: 0,\n // The box draws the focus, so a ring around the control inside it\n // would be two treatments for one focus. Solid as well as no width:\n // a browser's own ring is the `auto` style, which ignores the width.\n outlineStyle: 'solid',\n outlineWidth: 0,\n padding: 0,\n },\n // The label's place: the column's width at its top, the label at its\n // start as wide as its text, so it sits at the right end of a\n // right-to-left field whatever script it is in. One line, cut short\n // with an ellipsis where the column ends, which is before an icon at\n // either end. It takes no touches, so a press on it lands on the\n // control or the box under it.\n label: {\n alignItems: 'flex-start',\n end: 0,\n pointerEvents: 'none',\n position: 'absolute',\n start: 0,\n top: 0,\n },\n // Outlined, the label has the page's 4dp either side, which the notch\n // has too, so the two line up and the label's text starts where the\n // value does.\n labelOutlined: {\n end: -spacing.xs,\n start: -spacing.xs,\n },\n labelTextOutlined: {\n paddingHorizontal: spacing.xs,\n },\n // The line under the box: the message at the start, the counter at the\n // end, the page's 4dp under the box and 16dp between the two, indented\n // to the box's own padding so the message starts where the value does.\n messageLine: {\n flexDirection: 'row',\n gap: spacing.lg,\n marginTop: spacing.xs,\n paddingHorizontal: spacing.lg,\n },\n // The line with nothing to show: out of the flow, so the field ends at\n // its box, and still there for the live region inside it, which has to\n // be in place before the error it announces arrives.\n messageLineCollapsed: {\n marginTop: 0,\n position: 'absolute',\n },\n // The label's text in its floated type, out of sight, which is what\n // the notch takes its width from. In the outlined label's own place, so\n // a label with no room is cut short where the label is.\n notchMeasure: {\n opacity: 0,\n },\n // The outline: three pieces in a row over the whole box, the stretch\n // before the label, the notch under it and the stretch after it. Each\n // piece clips a whole outlined box of its own to the part of the\n // outline it draws, so the width and the colour are one shorthand\n // that eases, and the corners turn over with the row in a\n // right-to-left layout.\n outline: {\n bottom: 0,\n flexDirection: 'row',\n left: 0,\n pointerEvents: 'none',\n position: 'absolute',\n right: 0,\n top: 0,\n },\n outlineEnd: {\n flexGrow: 1,\n overflow: 'hidden',\n },\n outlineEndBox: {\n borderRadius: radii.xs,\n bottom: 0,\n end: 0,\n position: 'absolute',\n start: -OUTLINE_REACH,\n top: 0,\n },\n // The notch draws only the bottom of the outline, its box reaching past\n // the top and both sides.\n outlineNotch: {\n flexShrink: 1,\n overflow: 'hidden',\n },\n outlineNotchBox: {\n bottom: 0,\n end: -OUTLINE_REACH,\n position: 'absolute',\n start: -OUTLINE_REACH,\n top: -OUTLINE_REACH,\n },\n outlineStart: {\n flexShrink: 0,\n overflow: 'hidden',\n },\n outlineStartBox: {\n borderRadius: radii.xs,\n bottom: 0,\n end: -OUTLINE_REACH,\n position: 'absolute',\n start: 0,\n top: 0,\n },\n }),\n)\n\nexport { fieldStylesOf, OUTLINE_REACH }\n"],"mappings":";;;;AAsBA,MAAMI,gBAAgBF,cACnB,EAAEG,QAAQC,OAAOC,SAASC,wBACzBR,WAAWS,OAAO;CAGhBC,WAAW;EACTC,YAAY;EACZC,eAAe;EACfC,UAAU;EACVC,KAAKP,QAAQQ;CACf;CAKAC,KAAK;EACHC,iBAAiBZ,OAAOa;EACxBC,oBAAoBb,MAAMc;EAC1BC,sBAAsBf,MAAMc;EAC5BR,eAAe;EACfE,KAAKP,QAAQe;EACbC,mBAAmBhB,QAAQe;EAC3BE,iBAAiBjB,QAAQkB;CAC3B;CACAC,aAAa,EACXT,iBAAiBhB,YACfI,OAAOsB,WACPnB,kBAAkBoB,iBACpB,EACF;CACAC,YAAY,EACVC,cAAcvB,QAAQwB,GACxB;CAGAC,aAAa;EACXf,iBAAiB;EACjBO,iBAAiBjB,QAAQe;CAC3B;CACAW,aAAa,EACXC,YAAY3B,QAAQwB,GACtB;CAGAI,QAAQ;EACNtB,UAAU;EACVuB,YAAY;EACZC,gBAAgB;EAChBC,UAAU;CACZ;CAGAC,SAAS;EACPH,YAAY;EACZI,aAAa,CAAC,cAAc;EAC5BC,aAAa;CACf;CAGAC,MAAM;EACJ/B,YAAY;EACZgC,WAAW;EACXN,gBAAgB;CAClB;CAKAO,WAAW;EACTC,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,OAAO;CACT;CACAC,OAAO;EACLpC,UAAU;EACVuB,YAAY;EACZc,QAAQ;EACRZ,UAAU;EAIVa,cAAc;EACdC,cAAc;EACdC,SAAS;CACX;CAOAC,OAAO;EACL3C,YAAY;EACZmC,KAAK;EACLS,eAAe;EACfR,UAAU;EACVC,OAAO;EACPQ,KAAK;CACP;CAIAC,eAAe;EACbX,KAAK,CAACvC,QAAQa;EACd4B,OAAO,CAACzC,QAAQa;CAClB;CACAsC,mBAAmB,EACjBnC,mBAAmBhB,QAAQa,GAC7B;CAIAuC,aAAa;EACX/C,eAAe;EACfE,KAAKP,QAAQe;EACbsC,WAAWrD,QAAQa;EACnBG,mBAAmBhB,QAAQe;CAC7B;CAIAuC,sBAAsB;EACpBD,WAAW;EACXb,UAAU;CACZ;CAIAe,cAAc,EACZC,SAAS,EACX;CAOAC,SAAS;EACPnB,QAAQ;EACRjC,eAAe;EACfqD,MAAM;EACNV,eAAe;EACfR,UAAU;EACVmB,OAAO;EACPV,KAAK;CACP;CACAW,YAAY;EACVtD,UAAU;EACVuD,UAAU;CACZ;CACAC,eAAe;EACbC,cAAchE,MAAMc;EACpByB,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,OAAO;EACPQ,KAAK;CACP;CAGAe,cAAc;EACZnC,YAAY;EACZgC,UAAU;CACZ;CACAI,iBAAiB;EACf3B,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,OAAO;EACPQ,KAAK;CACP;CACAiB,cAAc;EACZrC,YAAY;EACZgC,UAAU;CACZ;CACAM,iBAAiB;EACfJ,cAAchE,MAAMc;EACpByB,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,OAAO;EACPQ,KAAK;CACP;AACF,CAAC,CACL"}
@@ -0,0 +1,24 @@
1
+ import { TextInput } from "react-native";
2
+ import "react";
3
+ //#region src/form/index.d.ts
4
+ /**
5
+ * `aria` shows a field's error as soon as the field says so, and lets the
6
+ * form submit regardless. `native` holds the form back while a field in it is
7
+ * required and empty, or rejected by its `validate`, and shows that field's
8
+ * error once a submission is tried.
9
+ */
10
+ type FormValidationBehavior = 'aria' | 'native';
11
+ /** The values a form submits, as strings by each field's `name`. */
12
+ type FormValues = Readonly<Record<string, string>>;
13
+ /** A field's problem in words: one message, or several read as one line. */
14
+ type ValidationError = readonly string[] | string;
15
+ /** Errors keyed by each field's `name`, such as a server's answer. */
16
+ type ValidationErrors = Readonly<Record<string, ValidationError>>;
17
+ /**
18
+ * What a field's `validate` returns for a value: its problem in words, or
19
+ * `true`, `null` or `undefined` where there is none, as on web.
20
+ */
21
+ type ValidationResult = null | true | undefined | ValidationError;
22
+ //#endregion
23
+ export type { FormValidationBehavior, FormValues, ValidationError, ValidationErrors, ValidationResult };
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,209 @@
1
+ import { c } from "react/compiler-runtime";
2
+ import { createContext, use, useEffect, useId, useRef, useState } from "react";
3
+ //#region src/form/index.ts
4
+ /**
5
+ * What a field outside a form, and a form told nothing, validates by. The
6
+ * library shows its own message under a field, so an error shows as the
7
+ * field reports it rather than once a submission is tried.
8
+ */
9
+ const FIELD_VALIDATION_BEHAVIOR = "aria";
10
+ /** The error a required field left empty shows under `native`. */
11
+ const REQUIRED_ERROR = "Fill out this field.";
12
+ const NO_ERRORS = {};
13
+ const NO_MESSAGES = [];
14
+ const FormContext = createContext(null);
15
+ /**
16
+ * The fields a form holds, in the order they registered. A field that is
17
+ * already in it keeps its place as it reports again, so the order is the one
18
+ * they mounted in.
19
+ */
20
+ function createRegistry() {
21
+ const fields = /* @__PURE__ */ new Map();
22
+ return {
23
+ entries: () => [...fields.values()],
24
+ remove: (id) => {
25
+ fields.delete(id);
26
+ },
27
+ set: (id, entry) => {
28
+ fields.set(id, entry);
29
+ }
30
+ };
31
+ }
32
+ function focusOf(control) {
33
+ return () => {
34
+ control.current?.focus();
35
+ };
36
+ }
37
+ function lineOf(messages) {
38
+ return messages.length === 0 ? void 0 : messages.join(" ");
39
+ }
40
+ function messagesOf(result) {
41
+ if (typeof result === "string") return result === "" ? NO_MESSAGES : [result];
42
+ return result === null || result === void 0 || result === true ? NO_MESSAGES : result;
43
+ }
44
+ /**
45
+ * Submits a form: under `native`, holds it back while any field blocks,
46
+ * showing each blocking field's error and focusing the first, and otherwise
47
+ * hands `onSubmit` every named field's value.
48
+ */
49
+ function submitOf(registry, validationBehavior, onSubmit) {
50
+ return () => {
51
+ const entries = registry.entries();
52
+ if (validationBehavior === "native") {
53
+ const blocking = entries.filter((entry) => entry.blocks);
54
+ const first = blocking.at(0);
55
+ if (first !== void 0) {
56
+ for (const entry of blocking) entry.show();
57
+ first.focus();
58
+ return;
59
+ }
60
+ }
61
+ onSubmit?.(Object.fromEntries(entries.flatMap((entry) => entry.submits === void 0 ? [] : [entry.submits])));
62
+ };
63
+ }
64
+ /**
65
+ * A field's validation, as React Aria's is on web, and its place in the form
66
+ * around it. It hands back the error the field shows, and two handlers the
67
+ * field calls: `onEdit` as its value is edited, and `onBlur` as its control
68
+ * loses focus.
69
+ *
70
+ * The error is the field's own `error` where it has one. Otherwise it is the
71
+ * server's, from the form's `validationErrors` under the field's `name`,
72
+ * until the field is edited; a new `validationErrors` from the form shows it
73
+ * again. Otherwise, under `aria`, it is what `validate` says about the value
74
+ * as it changes.
75
+ *
76
+ * Under `native` that last one, or the required field's own error when it is
77
+ * empty, is shown late and taken back early, as on web: once a submission it
78
+ * holds back is tried, or once the control loses focus after an edit, and no
79
+ * longer once the value is right, so a field shows nothing new in the middle
80
+ * of being typed in. A disabled or read-only field holds nothing back, and a
81
+ * disabled one submits nothing, as a browser bars both from validation and
82
+ * leaves a disabled input out of what a form submits.
83
+ */
84
+ function useFieldValidation(t0) {
85
+ const $ = c(28);
86
+ const { control, error, isDisabled, isEmpty, isReadOnly, isRequired, name, submitted, validate, value } = t0;
87
+ const form = use(FormContext);
88
+ const id = useId();
89
+ const behavior = form?.validationBehavior ?? "aria";
90
+ const serverErrors = form?.validationErrors ?? NO_ERRORS;
91
+ const registry = form?.registry;
92
+ const [clearedFrom, setClearedFrom] = useState(null);
93
+ const [showing, setShowing] = useState(false);
94
+ const edited = useRef(false);
95
+ const native = behavior === "native";
96
+ const barred = isDisabled || isReadOnly;
97
+ const server = name === void 0 || clearedFrom === serverErrors ? NO_MESSAGES : messagesOf(serverErrors[name]);
98
+ const client = validate === void 0 ? NO_MESSAGES : messagesOf(validate(value));
99
+ const own = client.length > 0 ? client : native && isRequired && isEmpty && !barred ? [REQUIRED_ERROR] : NO_MESSAGES;
100
+ if (showing && own.length === 0) setShowing(false);
101
+ const shown = native ? showing ? own : NO_MESSAGES : client;
102
+ const t1 = !barred && (error !== void 0 || server.length > 0 || own.length > 0);
103
+ let t2;
104
+ if ($[0] !== control) {
105
+ t2 = focusOf(control);
106
+ $[0] = control;
107
+ $[1] = t2;
108
+ } else t2 = $[1];
109
+ let t3;
110
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
111
+ t3 = () => {
112
+ setShowing(true);
113
+ };
114
+ $[2] = t3;
115
+ } else t3 = $[2];
116
+ let t4;
117
+ if ($[3] !== isDisabled || $[4] !== name || $[5] !== submitted) {
118
+ t4 = isDisabled || name === void 0 ? void 0 : [name, submitted];
119
+ $[3] = isDisabled;
120
+ $[4] = name;
121
+ $[5] = submitted;
122
+ $[6] = t4;
123
+ } else t4 = $[6];
124
+ let t5;
125
+ if ($[7] !== t1 || $[8] !== t2 || $[9] !== t4) {
126
+ t5 = {
127
+ blocks: t1,
128
+ focus: t2,
129
+ show: t3,
130
+ submits: t4
131
+ };
132
+ $[7] = t1;
133
+ $[8] = t2;
134
+ $[9] = t4;
135
+ $[10] = t5;
136
+ } else t5 = $[10];
137
+ const entry = t5;
138
+ let t6;
139
+ if ($[11] !== entry || $[12] !== id || $[13] !== registry) {
140
+ t6 = () => {
141
+ registry?.set(id, entry);
142
+ };
143
+ $[11] = entry;
144
+ $[12] = id;
145
+ $[13] = registry;
146
+ $[14] = t6;
147
+ } else t6 = $[14];
148
+ useEffect(t6);
149
+ let t7;
150
+ let t8;
151
+ if ($[15] !== id || $[16] !== registry) {
152
+ t7 = () => () => {
153
+ registry?.remove(id);
154
+ };
155
+ t8 = [id, registry];
156
+ $[15] = id;
157
+ $[16] = registry;
158
+ $[17] = t7;
159
+ $[18] = t8;
160
+ } else {
161
+ t7 = $[17];
162
+ t8 = $[18];
163
+ }
164
+ useEffect(t7, t8);
165
+ const t9 = error ?? lineOf(server) ?? lineOf(shown);
166
+ let t10;
167
+ if ($[19] !== native || $[20] !== serverErrors) {
168
+ t10 = () => {
169
+ if (edited.current) {
170
+ edited.current = false;
171
+ setClearedFrom(serverErrors);
172
+ setShowing(native);
173
+ }
174
+ };
175
+ $[19] = native;
176
+ $[20] = serverErrors;
177
+ $[21] = t10;
178
+ } else t10 = $[21];
179
+ let t11;
180
+ if ($[22] !== serverErrors) {
181
+ t11 = () => {
182
+ edited.current = true;
183
+ setClearedFrom(serverErrors);
184
+ };
185
+ $[22] = serverErrors;
186
+ $[23] = t11;
187
+ } else t11 = $[23];
188
+ let t12;
189
+ if ($[24] !== t10 || $[25] !== t11 || $[26] !== t9) {
190
+ t12 = {
191
+ error: t9,
192
+ onBlur: t10,
193
+ onEdit: t11
194
+ };
195
+ $[24] = t10;
196
+ $[25] = t11;
197
+ $[26] = t9;
198
+ $[27] = t12;
199
+ } else t12 = $[27];
200
+ return t12;
201
+ }
202
+ /** Whether the field is inside a form, which keeps its message line drawn. */
203
+ function useInsideForm() {
204
+ return use(FormContext) !== null;
205
+ }
206
+ //#endregion
207
+ export { FIELD_VALIDATION_BEHAVIOR, FormContext, createRegistry, submitOf, useFieldValidation, useInsideForm };
208
+
209
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["RefObject","TextInput","createContext","use","useEffect","useId","useRef","useState","FieldValidationOptions","control","error","isDisabled","isEmpty","isReadOnly","isRequired","name","submitted","validate","value","T","ValidationResult","FormEntry","blocks","focus","show","submits","FormRegistry","entries","remove","id","set","entry","FormState","registry","requestSubmit","validationBehavior","FormValidationBehavior","validationErrors","ValidationErrors","FormValues","Readonly","Record","ValidationError","FIELD_VALIDATION_BEHAVIOR","REQUIRED_ERROR","NO_ERRORS","NO_MESSAGES","FormContext","createRegistry","fields","Map","values","delete","focusOf","current","lineOf","messages","length","undefined","join","messagesOf","result","submitOf","onSubmit","blocking","filter","first","at","Object","fromEntries","flatMap","useFieldValidation","t0","$","_c","form","behavior","serverErrors","clearedFrom","setClearedFrom","showing","setShowing","edited","native","barred","server","client","own","shown","t1","t2","t3","Symbol","for","t4","t5","t6","t7","t8","t9","t10","t11","t12","onBlur","onEdit","useInsideForm","_c"],"sources":["../../src/form/index.ts"],"sourcesContent":["import type { RefObject } from 'react'\nimport type { TextInput } from 'react-native'\n\nimport { createContext, use, useEffect, useId, useRef, useState } from 'react'\n\n// What a Form tells the fields inside it, and what each field tells it back,\n// as React Aria's Form and its fields do through context on web. The form\n// hands down how its fields validate and the errors a server sent back, by\n// field name. Each field registers with the form around it while it is\n// mounted, in the order the tree mounts them, which is the order they are\n// drawn in, and the form reads that list when it is submitted: the values by\n// name, and under `native` which fields hold it back and which of them takes\n// focus.\n\ntype FieldValidationOptions<T> = {\n /** The control a failed native submission focuses. */\n readonly control: RefObject<null | TextInput>\n /** The field's own error, which wins over anything the form says. */\n readonly error: string | undefined\n readonly isDisabled: boolean\n /** Whether the value is what a required field must not be left as. */\n readonly isEmpty: boolean\n readonly isReadOnly: boolean\n readonly isRequired: boolean\n readonly name: string | undefined\n /** The value as the form submits it. */\n readonly submitted: string\n readonly validate: ((value: T) => ValidationResult) | undefined\n readonly value: T\n}\n\n/** What a field tells the form it is in, as of its last render. */\ntype FormEntry = {\n /** Whether the field holds a native submission back. */\n readonly blocks: boolean\n /** Moves focus to the field's control. */\n readonly focus: () => void\n /** Shows the field's own error, once a submission it held back is tried. */\n readonly show: () => void\n /** The name and value the field submits, where it submits one. */\n readonly submits: readonly [string, string] | undefined\n}\n\ntype FormRegistry = {\n readonly entries: () => readonly FormEntry[]\n readonly remove: (id: string) => void\n readonly set: (id: string, entry: FormEntry) => void\n}\n\ntype FormState = {\n readonly registry: FormRegistry\n readonly requestSubmit: () => void\n readonly validationBehavior: FormValidationBehavior\n readonly validationErrors: ValidationErrors\n}\n\n/**\n * `aria` shows a field's error as soon as the field says so, and lets the\n * form submit regardless. `native` holds the form back while a field in it is\n * required and empty, or rejected by its `validate`, and shows that field's\n * error once a submission is tried.\n */\ntype FormValidationBehavior = 'aria' | 'native'\n\n/** The values a form submits, as strings by each field's `name`. */\ntype FormValues = Readonly<Record<string, string>>\n\n/** A field's problem in words: one message, or several read as one line. */\ntype ValidationError = readonly string[] | string\n\n/** Errors keyed by each field's `name`, such as a server's answer. */\ntype ValidationErrors = Readonly<Record<string, ValidationError>>\n\n/**\n * What a field's `validate` returns for a value: its problem in words, or\n * `true`, `null` or `undefined` where there is none, as on web.\n */\ntype ValidationResult = null | true | undefined | ValidationError\n\n/**\n * What a field outside a form, and a form told nothing, validates by. The\n * library shows its own message under a field, so an error shows as the\n * field reports it rather than once a submission is tried.\n */\nconst FIELD_VALIDATION_BEHAVIOR: FormValidationBehavior = 'aria'\n\n/** The error a required field left empty shows under `native`. */\nconst REQUIRED_ERROR = 'Fill out this field.'\n\nconst NO_ERRORS: ValidationErrors = {}\n\nconst NO_MESSAGES: readonly string[] = []\n\nconst FormContext = createContext<FormState | null>(null)\n\n/**\n * The fields a form holds, in the order they registered. A field that is\n * already in it keeps its place as it reports again, so the order is the one\n * they mounted in.\n */\nfunction createRegistry(): FormRegistry {\n const fields = new Map<string, FormEntry>()\n\n return {\n entries: () => [...fields.values()],\n remove: (id) => {\n fields.delete(id)\n },\n set: (id, entry) => {\n fields.set(id, entry)\n },\n }\n}\n\n// Focuses a field's control, through the ref the field holds it in.\nfunction focusOf(control: RefObject<null | TextInput>) {\n return () => {\n control.current?.focus()\n }\n}\n\n// One line of a field's messages, or nothing where there are none.\nfunction lineOf(messages: readonly string[]): string | undefined {\n return messages.length === 0 ? undefined : messages.join(' ')\n}\n\n// A validation result as the messages it holds.\nfunction messagesOf(result: ValidationResult): readonly string[] {\n if (typeof result === 'string') {\n return result === '' ? NO_MESSAGES : [result]\n }\n\n return result === null || result === undefined || result === true\n ? NO_MESSAGES\n : result\n}\n\n/**\n * Submits a form: under `native`, holds it back while any field blocks,\n * showing each blocking field's error and focusing the first, and otherwise\n * hands `onSubmit` every named field's value.\n */\nfunction submitOf(\n registry: FormRegistry,\n validationBehavior: FormValidationBehavior,\n onSubmit: ((values: FormValues) => void) | undefined,\n) {\n return () => {\n const entries = registry.entries()\n\n if (validationBehavior === 'native') {\n const blocking = entries.filter((entry) => entry.blocks)\n const first = blocking.at(0)\n\n if (first !== undefined) {\n for (const entry of blocking) {\n entry.show()\n }\n first.focus()\n return\n }\n }\n\n onSubmit?.(\n Object.fromEntries(\n entries.flatMap((entry) =>\n entry.submits === undefined ? [] : [entry.submits],\n ),\n ),\n )\n }\n}\n\n/**\n * A field's validation, as React Aria's is on web, and its place in the form\n * around it. It hands back the error the field shows, and two handlers the\n * field calls: `onEdit` as its value is edited, and `onBlur` as its control\n * loses focus.\n *\n * The error is the field's own `error` where it has one. Otherwise it is the\n * server's, from the form's `validationErrors` under the field's `name`,\n * until the field is edited; a new `validationErrors` from the form shows it\n * again. Otherwise, under `aria`, it is what `validate` says about the value\n * as it changes.\n *\n * Under `native` that last one, or the required field's own error when it is\n * empty, is shown late and taken back early, as on web: once a submission it\n * holds back is tried, or once the control loses focus after an edit, and no\n * longer once the value is right, so a field shows nothing new in the middle\n * of being typed in. A disabled or read-only field holds nothing back, and a\n * disabled one submits nothing, as a browser bars both from validation and\n * leaves a disabled input out of what a form submits.\n */\nfunction useFieldValidation<T>({\n control,\n error,\n isDisabled,\n isEmpty,\n isReadOnly,\n isRequired,\n name,\n submitted,\n validate,\n value,\n}: FieldValidationOptions<T>) {\n const form = use(FormContext)\n const id = useId()\n const behavior = form?.validationBehavior ?? FIELD_VALIDATION_BEHAVIOR\n const serverErrors = form?.validationErrors ?? NO_ERRORS\n const registry = form?.registry\n // The errors object the field was edited under. Its server error stays\n // cleared until the form is handed a new one.\n const [clearedFrom, setClearedFrom] = useState<null | ValidationErrors>(null)\n const [showing, setShowing] = useState(false)\n // Whether the value has been edited since the control last lost focus,\n // which is when a browser fires `change`, and so when React Aria commits.\n const edited = useRef(false)\n const native = behavior === 'native'\n const barred = isDisabled || isReadOnly\n const server =\n name === undefined || clearedFrom === serverErrors\n ? NO_MESSAGES\n : messagesOf(serverErrors[name])\n const client =\n validate === undefined ? NO_MESSAGES : messagesOf(validate(value))\n const own =\n client.length > 0\n ? client\n : native && isRequired && isEmpty && !barred\n ? [REQUIRED_ERROR]\n : NO_MESSAGES\n\n // Taken back as soon as the value is right, however it got there.\n if (showing && own.length === 0) {\n setShowing(false)\n }\n\n const shown = native ? (showing ? own : NO_MESSAGES) : client\n const entry: FormEntry = {\n blocks:\n !barred && (error !== undefined || server.length > 0 || own.length > 0),\n focus: focusOf(control),\n show: () => {\n setShowing(true)\n },\n submits: isDisabled || name === undefined ? undefined : [name, submitted],\n }\n\n // Reported after every render, so the form reads what the field shows.\n useEffect(() => {\n registry?.set(id, entry)\n })\n\n useEffect(\n () => () => {\n registry?.remove(id)\n },\n [id, registry],\n )\n\n return {\n error: error ?? lineOf(server) ?? lineOf(shown),\n onBlur: () => {\n if (edited.current) {\n edited.current = false\n setClearedFrom(serverErrors)\n setShowing(native)\n }\n },\n onEdit: () => {\n edited.current = true\n setClearedFrom(serverErrors)\n },\n }\n}\n\n/** Whether the field is inside a form, which keeps its message line drawn. */\nfunction useInsideForm() {\n return use(FormContext) !== null\n}\n\nexport {\n createRegistry,\n FIELD_VALIDATION_BEHAVIOR,\n FormContext,\n submitOf,\n useFieldValidation,\n useInsideForm,\n}\nexport type {\n FormValidationBehavior,\n FormValues,\n ValidationError,\n ValidationErrors,\n ValidationResult,\n}\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { ColorValue } from "react-native";
2
+ //#region src/glyphs/icon-style.d.ts
3
+ /** The colour and size a slot gives the icon drawn in it. */
4
+ type IconStyle = {
5
+ /** The colour the icon fills with. */
6
+ readonly color?: ColorValue;
7
+ /** The side of the icon's square, in dp. */
8
+ readonly size: number;
9
+ };
10
+ /**
11
+ * The colour and size of the slot an icon sits in, as a slot that takes an
12
+ * icon provides them. The library's own glyphs read it, and an icon of the
13
+ * app's own reads it to match them.
14
+ *
15
+ * ```tsx
16
+ * function StarIcon() {
17
+ * const { color, size } = useIconStyle()
18
+ * return <Star color={color} size={size} />
19
+ * }
20
+ * ```
21
+ */
22
+ declare function useIconStyle(): IconStyle;
23
+ //#endregion
24
+ export { type IconStyle, useIconStyle };
25
+ //# sourceMappingURL=icon-style.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { createContext, use } from "react";
2
+ //#region src/glyphs/icon-style.ts
3
+ const IconStyleContext = createContext({ size: 24 });
4
+ /**
5
+ * The colour and size of the slot an icon sits in, as a slot that takes an
6
+ * icon provides them. The library's own glyphs read it, and an icon of the
7
+ * app's own reads it to match them.
8
+ *
9
+ * ```tsx
10
+ * function StarIcon() {
11
+ * const { color, size } = useIconStyle()
12
+ * return <Star color={color} size={size} />
13
+ * }
14
+ * ```
15
+ */
16
+ function useIconStyle() {
17
+ return use(IconStyleContext);
18
+ }
19
+ //#endregion
20
+ export { IconStyleContext, useIconStyle };
21
+
22
+ //# sourceMappingURL=icon-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-style.js","names":["ColorValue","createContext","use","IconStyle","color","size","IconStyleContext","useIconStyle"],"sources":["../../src/glyphs/icon-style.ts"],"sourcesContent":["import type { ColorValue } from 'react-native'\n\nimport { createContext, use } from 'react'\n\n/** The colour and size a slot gives the icon drawn in it. */\ntype IconStyle = {\n /** The colour the icon fills with. */\n readonly color?: ColorValue\n /** The side of the icon's square, in dp. */\n readonly size: number\n}\n\n// Outside any slot an icon draws at 24dp, the grid Material Symbols are drawn\n// on, in whatever colour its own drawing falls back to.\nconst IconStyleContext = createContext<IconStyle>({ size: 24 })\n\n/**\n * The colour and size of the slot an icon sits in, as a slot that takes an\n * icon provides them. The library's own glyphs read it, and an icon of the\n * app's own reads it to match them.\n *\n * ```tsx\n * function StarIcon() {\n * const { color, size } = useIconStyle()\n * return <Star color={color} size={size} />\n * }\n * ```\n */\nfunction useIconStyle(): IconStyle {\n return use(IconStyleContext)\n}\n\nexport { IconStyleContext, useIconStyle }\nexport type { IconStyle }\n"],"mappings":";;AAcA,MAAMM,mBAAmBL,cAAyB,EAAEI,MAAM,GAAG,CAAC;;;;;;;;;;;;;AAc9D,SAASE,eAA0B;CACjC,OAAOL,IAAII,gBAAgB;AAC7B"}