@kanso-labs/react-native-kanso-ui 0.2.0 → 0.3.1

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 (60) hide show
  1. package/dist/button/index.d.ts +8 -0
  2. package/dist/button/index.js +38 -26
  3. package/dist/button/index.js.map +1 -1
  4. package/dist/button/slots.js +7 -0
  5. package/dist/button/slots.js.map +1 -0
  6. package/dist/components/avatar/index.d.ts +2 -2
  7. package/dist/components/avatar/index.js.map +1 -1
  8. package/dist/components/button/index.d.ts +3 -3
  9. package/dist/components/button/index.js +115 -109
  10. package/dist/components/button/index.js.map +1 -1
  11. package/dist/components/card/index.d.ts +2 -2
  12. package/dist/components/card/index.js.map +1 -1
  13. package/dist/components/checkbox/index.d.ts +2 -2
  14. package/dist/components/checkbox/index.js.map +1 -1
  15. package/dist/components/chip/index.d.ts +2 -2
  16. package/dist/components/chip/index.js.map +1 -1
  17. package/dist/components/chip-group/index.d.ts +3 -3
  18. package/dist/components/chip-group/index.js.map +1 -1
  19. package/dist/components/copy-field/index.d.ts +2 -2
  20. package/dist/components/copy-field/index.js.map +1 -1
  21. package/dist/components/dialog/index.d.ts +131 -0
  22. package/dist/components/dialog/index.js +861 -0
  23. package/dist/components/dialog/index.js.map +1 -0
  24. package/dist/components/icon-button/index.d.ts +3 -3
  25. package/dist/components/icon-button/index.js +128 -122
  26. package/dist/components/icon-button/index.js.map +1 -1
  27. package/dist/components/link/index.js +1 -1
  28. package/dist/components/link/index.js.map +1 -1
  29. package/dist/components/meter/index.d.ts +2 -2
  30. package/dist/components/meter/index.js.map +1 -1
  31. package/dist/components/number-field/index.d.ts +3 -3
  32. package/dist/components/number-field/index.js.map +1 -1
  33. package/dist/components/product-icon/index.d.ts +2 -2
  34. package/dist/components/product-icon/index.js.map +1 -1
  35. package/dist/components/progress-indicator/index.d.ts +2 -2
  36. package/dist/components/progress-indicator/index.js.map +1 -1
  37. package/dist/components/radio-group/index.d.ts +3 -3
  38. package/dist/components/radio-group/index.js.map +1 -1
  39. package/dist/components/search-field/index.d.ts +3 -3
  40. package/dist/components/search-field/index.js.map +1 -1
  41. package/dist/components/segmented-button/index.d.ts +3 -3
  42. package/dist/components/segmented-button/index.js.map +1 -1
  43. package/dist/components/snackbar/index.d.ts +2 -2
  44. package/dist/components/snackbar/index.js.map +1 -1
  45. package/dist/components/switch/index.d.ts +2 -2
  46. package/dist/components/switch/index.js.map +1 -1
  47. package/dist/components/text-field/index.d.ts +3 -3
  48. package/dist/components/text-field/index.js.map +1 -1
  49. package/dist/field/index.d.ts +1 -1
  50. package/dist/field/index.js.map +1 -1
  51. package/dist/form/index.d.ts +1 -1
  52. package/dist/form/index.js.map +1 -1
  53. package/dist/index.d.ts +2 -1
  54. package/dist/index.js +3 -2
  55. package/dist/mark/index.d.ts +1 -1
  56. package/dist/mark/index.js.map +1 -1
  57. package/dist/overlay/host.js.map +1 -1
  58. package/dist/press/index.js +59 -60
  59. package/dist/press/index.js.map +1 -1
  60. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ReactNode","Ref","LayoutChangeEvent","StyleProp","TextStyle","ViewProps","ViewStyle","AnimatedStyle","SharedValue","use","useEffect","useRef","useState","useSyncExternalStore","AccessibilityInfo","Text","NativeText","Platform","Pressable","StyleSheet","View","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","SafeAreaInsetsContext","CloseGlyph","useWindowSizeClass","Overlay","hitSlop","usePressFeedback","useTheme","composeStyles","themedStyles","useTypeRole","MESSAGE_MS","UNTIL_CLOSED","MIN_WIDE","MAX_WIDE","MESSAGE_BLOCK_PADDING","RING_WIDTH","RING_OFFSET","NO_INSETS","bottom","left","right","top","stylesOf","colors","radii","shadows","sizing","spacing","create","action","alignItems","justifyContent","minHeight","controlSm","paddingHorizontal","md","paddingVertical","sm","actionLabel","color","inversePrimary","actionRing","outlineColor","outlineOffset","outlineStyle","outlineWidth","close","height","controlMd","width","closeRing","inverseOnSurface","control","borderRadius","pill","message","flexBasis","flexGrow","marginHorizontal","minWidth","messageText","region","paddingTop","pointerEvents","position","strip","backgroundColor","inverseSurface","xs","boxShadow","elevation3","flexDirection","flexWrap","styles","controls","flexShrink","marginStart","wide","maxWidth","ShownMessage","SnackbarAction","key","onClose","showCloseButton","timeout","label","onPress","SnackbarOptions","SnackbarProps","Omit","closeLabel","queue","SnackbarQueue","ref","style","added","listeners","Set","shown","add","options","clear","String","undefined","changed","subscribe","listener","delete","visible","#changed","actionOf","closeOf","flagOf","set","value","measureInto","event","nativeEvent","layout","Snackbar","t0","$","_c","props","t1","theme","insets","t2","standing","t3","paddingBottom","paddingLeft","paddingRight","t4","t5","OS","SnackbarButton","ariaLabel","children","onFocusChange","ring","corners","feedback","onBlur","onFocus","T0","handlers","t6","t7","layer","SnackbarStrip","arrives","themed","body","reduceMotion","focused","setFocused","hovered","setHovered","motion","rises","arrived","rise","progress","get","opacity","transform","translateY","duration","durationMedium1","easing","bezier","easingEmphasizedDecelerate","announceForAccessibilityWithOptions","useExpiry","useShownFor","t8","Symbol","for","paused","expire","remaining","current","started","Date","now","timer","setTimeout","clearTimeout","recommended","setRecommended","asks","ask","milliseconds","getRecommendedTimeoutMillis","Queue","_c","NativeText"],"sources":["../../../src/components/snackbar/index.tsx"],"sourcesContent":["import type { ReactNode, Ref } from 'react'\nimport type {\n LayoutChangeEvent,\n StyleProp,\n TextStyle,\n ViewProps,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle, SharedValue } from 'react-native-reanimated'\n\nimport { use, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport {\n AccessibilityInfo,\n Text as NativeText,\n Platform,\n Pressable,\n StyleSheet,\n View,\n} from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\nimport { SafeAreaInsetsContext } from 'react-native-safe-area-context'\n\nimport { CloseGlyph } from '../../glyphs'\nimport { useWindowSizeClass } from '../../hooks/useWindowSizeClass'\nimport { Overlay } from '../../overlay'\nimport { hitSlop, usePressFeedback } from '../../press'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// The snackbar page's brief message at the bottom of the screen, with an\n// optional action beside it and an optional close button after that, as\n// kanso-ui's Snackbar draws it. The page's container is the inverse surface\n// at a 4dp corner and elevation 3, its supporting text is body-medium in\n// inverse on surface, its action label is inverse primary, and its close icon\n// takes the supporting text's colour. The measurements are the page's too: 8dp\n// of margin from the edges of the screen, 8dp of padding inside the container\n// with another 8dp either side of the message, 14dp above and below on a\n// single line, and between 320 and 576dp wide from the 600dp breakpoint up,\n// the width of the window less its margins below it. The margin is counted\n// from the safe area, so a message clears the home indicator and the gesture\n// bar.\n//\n// One at a time, as on web. The page shows a single snackbar and replaces it\n// rather than stacking, so a message added while another is up closes that\n// one, whose `onClose` runs, and takes its place. Nothing waits behind it, so\n// an Undo never comes back long after the thing it undid.\n//\n// The queue is web's API: `add` a message with its options from anywhere, and\n// mount one `Snackbar` with the queue near the root. It draws in the overlay\n// host of the outermost `ThemeScope`, so it floats above every screen in the\n// theme around it.\n//\n// **A message is read out as it arrives.** On iOS and Android it is\n// announced through `AccessibilityInfo`, after whatever VoiceOver is already\n// saying, which is how CopyField says its confirmation too. Under React Native\n// Web the region it appears in is a polite live region instead, as web's is,\n// and the browser's screen reader reads it as it changes. Android is not given\n// a live region as well, since TalkBack would then read each message twice.\n//\n// **A message is a string, where web takes a node.** The announcement is the\n// message's words, and a node has none to hand VoiceOver.\n//\n// **The action and the close button are drawn here rather than through\n// Button and IconButton**, as on web: the page colours them inverse primary\n// and inverse on surface, which no variant of either carries. They take the\n// state layer, the ripple and the focus ring from src/press, with the ring\n// drawn 2dp inside the control rather than outside it: the close button is\n// 48dp in a strip 48dp tall, so a ring outside it crossed the strip's edges\n// onto the screen, in a colour chosen to read on the strip rather than on\n// the screen around it.\n\n// How long a message is shown when the call site names no `timeout`, web's\n// durations from the snackbar's guidelines and accessibility pages. A message\n// alone leaves after five seconds, which Android lengthens from the reader's\n// own accessibility setting, as its own snackbar does. A message with an\n// action stays until the action is taken or something closes it, since no\n// timer knows how long a reader needs to reach it.\nconst MESSAGE_MS = 5000\nconst UNTIL_CLOSED = 0\n\n// The width from the 600dp breakpoint up, the page's. Literals, as on web:\n// they bound the strip rather than measure anything a theme would resize.\nconst MIN_WIDE = 320\nconst MAX_WIDE = 576\n\n// The page's 14dp above and below the message, which with its 20dp line makes\n// a single-line strip 48dp tall. A literal, as on web, since no spacing step\n// is 14.\nconst MESSAGE_BLOCK_PADDING = 14\n\n// The ring's 2dp, drawn 4dp in from the control's edge so all of it lies\n// inside.\nconst RING_WIDTH = 2\nconst RING_OFFSET = -4\n\n// Outside a SafeAreaProvider the insets are unknown, and the window's own edge\n// is the best bound there is.\nconst NO_INSETS = { bottom: 0, left: 0, right: 0, top: 0 }\n\nconst stylesOf = themedStyles(({ colors, radii, shadows, sizing, spacing }) =>\n StyleSheet.create({\n // Material Design's text button in the page's inverse primary, at the\n // label large the page gives it: 40dp tall, as Button's medium size is,\n // over a 48dp target, which is the strip's own height. A least height\n // rather than a height, so a type scale with a taller line grows the\n // button instead of clipping its label.\n action: {\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: sizing.controlSm,\n paddingHorizontal: spacing.md,\n paddingVertical: spacing.sm,\n },\n actionLabel: {\n color: colors.inversePrimary,\n },\n actionRing: {\n outlineColor: colors.inversePrimary,\n outlineOffset: RING_OFFSET,\n outlineStyle: 'solid',\n outlineWidth: RING_WIDTH,\n },\n // The page's 24dp icon in the supporting text's colour, in a 48dp box,\n // the least press area the icon buttons page allows.\n close: {\n alignItems: 'center',\n height: sizing.controlMd,\n justifyContent: 'center',\n width: sizing.controlMd,\n },\n closeRing: {\n outlineColor: colors.inverseOnSurface,\n outlineOffset: RING_OFFSET,\n outlineStyle: 'solid',\n outlineWidth: RING_WIDTH,\n },\n // Both controls are pills, which the state layer and the ripple clip to.\n control: {\n borderRadius: radii.pill,\n },\n // The message: its 8dp either side inside the strip's own 8dp, and the\n // 14dp above and below. The height is the message's rather than the\n // strip's, which is what lets a 48dp close button sit beside it without\n // making the strip taller than the page draws it.\n //\n // Its basis is half the strip, which is what decides when the controls\n // drop beneath it. A word longer than the line holds breaks inside\n // itself rather than running under the controls, which the least width\n // of 0 allows on the web, where a flex item otherwise keeps the width of\n // its longest word.\n message: {\n flexBasis: '50%',\n flexGrow: 1,\n marginHorizontal: spacing.sm,\n minWidth: 0,\n paddingVertical: MESSAGE_BLOCK_PADDING,\n },\n messageText: {\n color: colors.inverseOnSurface,\n },\n // A strip along the bottom of the overlay layer, with the page's 8dp\n // above it. It passes a touch through wherever no strip is drawn, so\n // the screen under it stays usable.\n region: {\n alignItems: 'center',\n bottom: 0,\n left: 0,\n paddingTop: spacing.sm,\n pointerEvents: 'box-none',\n position: 'absolute',\n right: 0,\n },\n // The container: the page's 8dp either side, and nothing above or\n // below, since what sets its height is the message and the close\n // button. It wraps, so controls too long to leave the message half the\n // strip drop onto a line of their own beneath it, Material Design's\n // two-line snackbar with a longer action.\n strip: {\n alignItems: 'center',\n backgroundColor: colors.inverseSurface,\n borderRadius: radii.xs,\n boxShadow: shadows.elevation3,\n flexDirection: 'row',\n flexWrap: 'wrap',\n minHeight: sizing.controlMd,\n paddingHorizontal: spacing.sm,\n width: '100%',\n },\n }),\n)\n\nconst styles = StyleSheet.create({\n // The action, and the close button after it, kept together after the\n // message so they move beneath it together. The auto margin puts them at\n // the trailing edge: on the message's row the message takes all the room\n // first, and on a row of their own it is all the room there is.\n controls: {\n alignItems: 'center',\n flexDirection: 'row',\n flexShrink: 0,\n marginStart: 'auto',\n },\n wide: {\n maxWidth: MAX_WIDE,\n minWidth: MIN_WIDE,\n },\n})\n\n// A message on screen, with what it was added with.\ntype ShownMessage = {\n readonly action: SnackbarAction | undefined\n readonly key: string\n readonly message: string\n readonly onClose: (() => void) | undefined\n readonly showCloseButton: boolean\n readonly timeout: number\n}\n\ntype SnackbarAction = {\n /** What the action says. The page gives it a single word where it can. */\n readonly label: string\n /** Run when the action is pressed, just before the snackbar closes. */\n readonly onPress: () => void\n}\n\ntype SnackbarOptions = {\n /**\n * A single action shown after the message. Pressing it runs `onPress` and\n * closes the snackbar, which is what the page draws.\n */\n readonly action?: SnackbarAction\n /**\n * Run when the snackbar closes, however it was closed: by its timer, its\n * action or close button, `close`, `clear`, or a newer message added in its\n * place.\n */\n readonly onClose?: () => void\n /**\n * Whether a close button is shown at the end. The page draws one for a\n * message a reader may want out of the way before it expires.\n * @default false\n */\n readonly showCloseButton?: boolean\n /**\n * How long the snackbar is shown, in milliseconds. Defaults to five seconds\n * for a message alone, which Android lengthens from the reader's own\n * accessibility setting. A message with an action defaults to `0` and stays\n * until the action is taken or something closes it, as Material Design asks\n * of an actionable snackbar. The timer is paused while a pointer is over the\n * snackbar or one of its controls has focus, so a message never expires\n * while it is being read.\n *\n * `0` is the page's indefinite length: the snackbar stays until something\n * closes it. Give one of those an action or `showCloseButton`, or there is\n * no way to be rid of it.\n */\n readonly timeout?: number\n}\n\ntype SnackbarProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * What a screen reader calls the button that dismisses a snackbar. It sits\n * here rather than on a message's own options because it does not vary by\n * message.\n * @default 'Close'\n */\n readonly closeLabel?: string\n /** The queue the snackbar shows messages from. */\n readonly queue: SnackbarQueue\n readonly ref?: Ref<View>\n readonly style?: StyleProp<ViewStyle>\n}\n\n/**\n * The queue a snackbar is shown from. Make one where the app can reach it, a\n * module of its own being the usual place, mount `Snackbar` once with it, and\n * call `add` from anywhere.\n *\n * ```ts\n * const messages = new Snackbar.Queue()\n * messages.add('Label', { action: { label: 'Undo', onPress: undo } })\n * ```\n */\nclass SnackbarQueue {\n #added = 0\n readonly #listeners = new Set<() => void>()\n #shown: null | ShownMessage = null\n\n /**\n * Shows a message in place of the one on screen, and returns the key that\n * closes it. The message it replaces is closed, so its `onClose` runs, and\n * it does not come back.\n */\n add(message: string, options: SnackbarOptions = {}): string {\n const { action, onClose, showCloseButton = false, timeout } = options\n\n this.clear()\n this.#added += 1\n\n const key = `snackbar-${String(this.#added)}`\n\n this.#shown = {\n action,\n key,\n message,\n onClose,\n showCloseButton,\n timeout: timeout ?? (action === undefined ? MESSAGE_MS : UNTIL_CLOSED),\n }\n this.#changed()\n\n return key\n }\n\n /** Closes the snackbar on screen, running its `onClose`. */\n clear() {\n if (this.#shown !== null) {\n this.close(this.#shown.key)\n }\n }\n\n /** Closes one snackbar, by the key `add` returned. */\n close(key: string) {\n const shown = this.#shown\n\n if (shown?.key !== key) {\n return\n }\n\n // Off the screen before `onClose` runs, so one that adds the next message\n // adds it to an empty queue.\n this.#shown = null\n this.#changed()\n shown.onClose?.()\n }\n\n /**\n * Calls `listener` whenever the message on screen changes, and returns what\n * stops it. `Snackbar` reads the queue through this and `visible`, and\n * neither is meant for a call site.\n */\n readonly subscribe = (listener: () => void) => {\n this.#listeners.add(listener)\n\n return () => {\n this.#listeners.delete(listener)\n }\n }\n\n /** The message on screen, or `null`. */\n readonly visible = () => this.#shown\n\n #changed() {\n for (const listener of this.#listeners) {\n listener()\n }\n }\n}\n\n// The handlers the strip hands its views, each built by a call rather than\n// declared in the component, which is what react-perf's\n// jsx-no-new-function-as-prop is after; the React Compiler memoises the result\n// on its inputs.\nfunction actionOf(action: SnackbarAction, close: () => void) {\n return () => {\n action.onPress()\n close()\n }\n}\n\nfunction closeOf(queue: SnackbarQueue, key: string) {\n return () => {\n queue.close(key)\n }\n}\n\nfunction flagOf(set: (value: boolean) => void, value: boolean) {\n return () => {\n set(value)\n }\n}\n\nfunction measureInto(height: SharedValue<number>) {\n return (event: LayoutChangeEvent) => {\n height.set(event.nativeEvent.layout.height)\n }\n}\n\n/**\n * A brief message at the bottom of the screen, with an optional action, with\n * web's props and values. Mount one of these with a `Snackbar.Queue`, and\n * call the queue's `add` to show a message from anywhere.\n *\n * ```tsx\n * const messages = new Snackbar.Queue()\n *\n * <Snackbar queue={messages} />\n * ```\n *\n * It draws in the overlay host of the app's outermost `ThemeScope`, above the\n * screen, and needs one around it. It is one region rather than one per\n * message, so mount it once, near the root, inside the `SafeAreaProvider`\n * whose insets it keeps clear of.\n *\n * `style`, `ref` and `testID` land on that region, a view along the bottom of\n * the screen that holds the message.\n */\nfunction Snackbar({\n closeLabel = 'Close',\n queue,\n style,\n ...props\n}: SnackbarProps) {\n const theme = useTheme()\n const insets = use(SafeAreaInsetsContext) ?? NO_INSETS\n const wide = useWindowSizeClass() !== 'compact'\n const shown = useSyncExternalStore(queue.subscribe, queue.visible)\n // The message up when the snackbar mounted, which was on screen before it\n // rather than arriving, so it is put in place rather than risen to it: on\n // a screen that remounts the snackbar, and on a story seeded with one.\n const [standing] = useState(() => queue.visible()?.key)\n const { spacing } = theme\n\n return (\n <Overlay>\n <View\n aria-live={Platform.OS === 'web' ? 'polite' : undefined}\n {...props}\n style={composeStyles<ViewStyle>(\n stylesOf(theme).region,\n {\n paddingBottom: spacing.sm + insets.bottom,\n paddingLeft: spacing.sm + insets.left,\n paddingRight: spacing.sm + insets.right,\n },\n style,\n )}\n >\n {shown === null ? null : (\n <SnackbarStrip\n arrives={shown.key !== standing}\n closeLabel={closeLabel}\n key={shown.key}\n queue={queue}\n shown={shown}\n wide={wide}\n />\n )}\n </View>\n </Overlay>\n )\n}\n\n/**\n * One of the snackbar's two controls, a pill drawing the state layer, the\n * ripple and the ring in its own colour, over a target brought up to 48dp\n * from the `height` it is drawn at. It reports when it takes and loses focus,\n * which pauses the message's timer.\n */\nfunction SnackbarButton({\n 'aria-label': ariaLabel,\n children,\n color,\n height,\n onFocusChange,\n onPress,\n ring,\n style,\n}: {\n readonly 'aria-label'?: string\n readonly children: ReactNode\n readonly color: string\n readonly height: number\n readonly onFocusChange: (focused: boolean) => void\n readonly onPress: () => void\n readonly ring: ViewStyle\n readonly style: ViewStyle\n}) {\n const theme = useTheme()\n const corners = stylesOf(theme).control\n const feedback = usePressFeedback({\n color,\n corners,\n onBlur: () => {\n onFocusChange(false)\n },\n onFocus: () => {\n onFocusChange(true)\n },\n })\n\n return (\n <Pressable\n {...feedback.handlers}\n aria-label={ariaLabel}\n hitSlop={hitSlop(height)}\n onPress={onPress}\n role=\"button\"\n style={composeStyles<ViewStyle>(\n corners,\n style,\n feedback.ring === undefined ? undefined : ring,\n )}\n >\n {feedback.layer}\n {children}\n </Pressable>\n )\n}\n\n/** One message: the words, then whatever sits after them. */\nfunction SnackbarStrip({\n arrives,\n closeLabel,\n queue,\n shown,\n wide,\n}: {\n /** Whether the message rises into place, or is drawn there at once. */\n readonly arrives: boolean\n readonly closeLabel: string\n readonly queue: SnackbarQueue\n readonly shown: ShownMessage\n readonly wide: boolean\n}) {\n const theme = useTheme()\n const themed = stylesOf(theme)\n const body = useTypeRole('bodyMedium')\n const label = useTypeRole('labelLarge')\n const reduceMotion = useReducedMotion()\n const [focused, setFocused] = useState(false)\n const [hovered, setHovered] = useState(false)\n const { action, key, message, showCloseButton } = shown\n const { colors, motion, sizing } = theme\n\n // It rises its own height from the bottom edge as it fades in, which is\n // what the page draws and what says the message came from the edge of the\n // screen rather than appearing over it. Reduced motion puts it in its\n // settled place at once, as web's zeroed duration does.\n const rises = arrives && !reduceMotion\n const arrived = useSharedValue(rises ? 0 : 1)\n const height = useSharedValue(0)\n const rise = useAnimatedStyle(() => {\n 'worklet'\n const progress = arrived.get()\n\n return {\n opacity: progress,\n transform: [{ translateY: (1 - progress) * height.get() }],\n }\n })\n\n useEffect(() => {\n if (rises) {\n arrived.set(\n withTiming(1, {\n duration: motion.durationMedium1,\n easing: Easing.bezier(...motion.easingEmphasizedDecelerate),\n }),\n )\n }\n }, [arrived, motion, rises])\n\n useEffect(() => {\n if (Platform.OS === 'ios' || Platform.OS === 'android') {\n AccessibilityInfo.announceForAccessibilityWithOptions(message, {\n queue: true,\n })\n }\n }, [message])\n\n const close = closeOf(queue, key)\n\n useExpiry(useShownFor(shown.timeout), focused || hovered, close)\n\n return (\n <Animated.View\n onLayout={measureInto(height)}\n onPointerEnter={flagOf(setHovered, true)}\n onPointerLeave={flagOf(setHovered, false)}\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n themed.strip,\n wide ? styles.wide : undefined,\n rise,\n )}\n >\n <View style={themed.message}>\n <NativeText style={composeStyles<TextStyle>(body, themed.messageText)}>\n {message}\n </NativeText>\n </View>\n {action === undefined && !showCloseButton ? null : (\n <View style={styles.controls}>\n {action === undefined ? null : (\n <SnackbarButton\n color={colors.inversePrimary}\n height={sizing.controlSm}\n onFocusChange={setFocused}\n onPress={actionOf(action, close)}\n ring={themed.actionRing}\n style={themed.action}\n >\n <NativeText\n style={composeStyles<TextStyle>(label, themed.actionLabel)}\n >\n {action.label}\n </NativeText>\n </SnackbarButton>\n )}\n {showCloseButton ? (\n <SnackbarButton\n aria-label={closeLabel}\n color={colors.inverseOnSurface}\n height={sizing.controlMd}\n onFocusChange={setFocused}\n onPress={close}\n ring={themed.closeRing}\n style={themed.close}\n >\n <CloseGlyph color={colors.inverseOnSurface} size={24} />\n </SnackbarButton>\n ) : null}\n </View>\n )}\n </Animated.View>\n )\n}\n\n// Closes a message once it has been shown for `duration` milliseconds,\n// counting only the time it was not paused. Nothing for a `duration` of 0,\n// which is until closed, or of `null`, which is not yet known.\nfunction useExpiry(\n duration: null | number,\n paused: boolean,\n expire: () => void,\n) {\n const left = useRef<null | number>(null)\n\n useEffect(() => {\n if (duration === null || duration === 0 || paused) {\n return undefined\n }\n\n const remaining = left.current ?? duration\n const started = Date.now()\n const timer = setTimeout(expire, remaining)\n\n return () => {\n clearTimeout(timer)\n left.current = remaining - (Date.now() - started)\n }\n }, [duration, expire, paused])\n}\n\n// How long a message is shown: its `timeout`, which Android lengthens from\n// the reader's \"Time to take action\" setting, as its own snackbar does, and\n// is `null` until Android has answered. Nothing is asked for a message shown\n// until closed.\nfunction useShownFor(timeout: number): null | number {\n const [recommended, setRecommended] = useState<null | number>(null)\n const asks = Platform.OS === 'android' && timeout > 0\n\n useEffect(() => {\n if (!asks) {\n return undefined\n }\n\n let current = true\n\n async function ask() {\n const milliseconds =\n await AccessibilityInfo.getRecommendedTimeoutMillis(timeout)\n\n if (current) {\n setRecommended(milliseconds)\n }\n }\n\n void ask()\n\n return () => {\n current = false\n }\n }, [asks, timeout])\n\n return asks ? recommended : timeout\n}\n\nSnackbar.Queue = SnackbarQueue\n\n// The queue is reached as `Snackbar.Queue` rather than exported beside the\n// component, as on web: a module exporting something that is not a component\n// is one fast refresh reloads whole.\nexport { Snackbar }\nexport type { SnackbarAction, SnackbarOptions, SnackbarProps, SnackbarQueue }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","LayoutChangeEvent","StyleProp","TextStyle","ViewProps","ViewStyle","AnimatedStyle","SharedValue","use","useEffect","useRef","useState","useSyncExternalStore","AccessibilityInfo","Text","NativeText","Platform","Pressable","StyleSheet","View","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","SafeAreaInsetsContext","CloseGlyph","useWindowSizeClass","Overlay","hitSlop","usePressFeedback","useTheme","composeStyles","themedStyles","useTypeRole","MESSAGE_MS","UNTIL_CLOSED","MIN_WIDE","MAX_WIDE","MESSAGE_BLOCK_PADDING","RING_WIDTH","RING_OFFSET","NO_INSETS","bottom","left","right","top","stylesOf","colors","radii","shadows","sizing","spacing","create","action","alignItems","justifyContent","minHeight","controlSm","paddingHorizontal","md","paddingVertical","sm","actionLabel","color","inversePrimary","actionRing","outlineColor","outlineOffset","outlineStyle","outlineWidth","close","height","controlMd","width","closeRing","inverseOnSurface","control","borderRadius","pill","message","flexBasis","flexGrow","marginHorizontal","minWidth","messageText","region","paddingTop","pointerEvents","position","strip","backgroundColor","inverseSurface","xs","boxShadow","elevation3","flexDirection","flexWrap","styles","controls","flexShrink","marginStart","wide","maxWidth","ShownMessage","SnackbarAction","key","onClose","showCloseButton","timeout","label","onPress","SnackbarOptions","SnackbarProps","Omit","closeLabel","queue","SnackbarQueue","ref","style","added","listeners","Set","shown","add","options","clear","String","undefined","changed","subscribe","listener","delete","visible","#changed","actionOf","closeOf","flagOf","set","value","measureInto","event","nativeEvent","layout","Snackbar","t0","$","_c","props","t1","theme","insets","t2","standing","t3","paddingBottom","paddingLeft","paddingRight","t4","t5","OS","SnackbarButton","ariaLabel","children","onFocusChange","ring","corners","feedback","onBlur","onFocus","T0","handlers","t6","t7","layer","SnackbarStrip","arrives","themed","body","reduceMotion","focused","setFocused","hovered","setHovered","motion","rises","arrived","rise","progress","get","opacity","transform","translateY","duration","durationMedium1","easing","bezier","easingEmphasizedDecelerate","announceForAccessibilityWithOptions","useExpiry","useShownFor","t8","Symbol","for","paused","expire","remaining","current","started","Date","now","timer","setTimeout","clearTimeout","recommended","setRecommended","asks","ask","milliseconds","getRecommendedTimeoutMillis","Queue","_c","NativeText"],"sources":["../../../src/components/snackbar/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n LayoutChangeEvent,\n StyleProp,\n TextStyle,\n ViewProps,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle, SharedValue } from 'react-native-reanimated'\n\nimport { use, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport {\n AccessibilityInfo,\n Text as NativeText,\n Platform,\n Pressable,\n StyleSheet,\n View,\n} from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\nimport { SafeAreaInsetsContext } from 'react-native-safe-area-context'\n\nimport { CloseGlyph } from '../../glyphs'\nimport { useWindowSizeClass } from '../../hooks/useWindowSizeClass'\nimport { Overlay } from '../../overlay'\nimport { hitSlop, usePressFeedback } from '../../press'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// The snackbar page's brief message at the bottom of the screen, with an\n// optional action beside it and an optional close button after that, as\n// kanso-ui's Snackbar draws it. The page's container is the inverse surface\n// at a 4dp corner and elevation 3, its supporting text is body-medium in\n// inverse on surface, its action label is inverse primary, and its close icon\n// takes the supporting text's colour. The measurements are the page's too: 8dp\n// of margin from the edges of the screen, 8dp of padding inside the container\n// with another 8dp either side of the message, 14dp above and below on a\n// single line, and between 320 and 576dp wide from the 600dp breakpoint up,\n// the width of the window less its margins below it. The margin is counted\n// from the safe area, so a message clears the home indicator and the gesture\n// bar.\n//\n// One at a time, as on web. The page shows a single snackbar and replaces it\n// rather than stacking, so a message added while another is up closes that\n// one, whose `onClose` runs, and takes its place. Nothing waits behind it, so\n// an Undo never comes back long after the thing it undid.\n//\n// The queue is web's API: `add` a message with its options from anywhere, and\n// mount one `Snackbar` with the queue near the root. It draws in the overlay\n// host of the outermost `ThemeScope`, so it floats above every screen in the\n// theme around it.\n//\n// **A message is read out as it arrives.** On iOS and Android it is\n// announced through `AccessibilityInfo`, after whatever VoiceOver is already\n// saying, which is how CopyField says its confirmation too. Under React Native\n// Web the region it appears in is a polite live region instead, as web's is,\n// and the browser's screen reader reads it as it changes. Android is not given\n// a live region as well, since TalkBack would then read each message twice.\n//\n// **A message is a string, where web takes a node.** The announcement is the\n// message's words, and a node has none to hand VoiceOver.\n//\n// **The action and the close button are drawn here rather than through\n// Button and IconButton**, as on web: the page colours them inverse primary\n// and inverse on surface, which no variant of either carries. They take the\n// state layer, the ripple and the focus ring from src/press, with the ring\n// drawn 2dp inside the control rather than outside it: the close button is\n// 48dp in a strip 48dp tall, so a ring outside it crossed the strip's edges\n// onto the screen, in a colour chosen to read on the strip rather than on\n// the screen around it.\n\n// How long a message is shown when the call site names no `timeout`, web's\n// durations from the snackbar's guidelines and accessibility pages. A message\n// alone leaves after five seconds, which Android lengthens from the reader's\n// own accessibility setting, as its own snackbar does. A message with an\n// action stays until the action is taken or something closes it, since no\n// timer knows how long a reader needs to reach it.\nconst MESSAGE_MS = 5000\nconst UNTIL_CLOSED = 0\n\n// The width from the 600dp breakpoint up, the page's. Literals, as on web:\n// they bound the strip rather than measure anything a theme would resize.\nconst MIN_WIDE = 320\nconst MAX_WIDE = 576\n\n// The page's 14dp above and below the message, which with its 20dp line makes\n// a single-line strip 48dp tall. A literal, as on web, since no spacing step\n// is 14.\nconst MESSAGE_BLOCK_PADDING = 14\n\n// The ring's 2dp, drawn 4dp in from the control's edge so all of it lies\n// inside.\nconst RING_WIDTH = 2\nconst RING_OFFSET = -4\n\n// Outside a SafeAreaProvider the insets are unknown, and the window's own edge\n// is the best bound there is.\nconst NO_INSETS = { bottom: 0, left: 0, right: 0, top: 0 }\n\nconst stylesOf = themedStyles(({ colors, radii, shadows, sizing, spacing }) =>\n StyleSheet.create({\n // Material Design's text button in the page's inverse primary, at the\n // label large the page gives it: 40dp tall, as Button's medium size is,\n // over a 48dp target, which is the strip's own height. A least height\n // rather than a height, so a type scale with a taller line grows the\n // button instead of clipping its label.\n action: {\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: sizing.controlSm,\n paddingHorizontal: spacing.md,\n paddingVertical: spacing.sm,\n },\n actionLabel: {\n color: colors.inversePrimary,\n },\n actionRing: {\n outlineColor: colors.inversePrimary,\n outlineOffset: RING_OFFSET,\n outlineStyle: 'solid',\n outlineWidth: RING_WIDTH,\n },\n // The page's 24dp icon in the supporting text's colour, in a 48dp box,\n // the least press area the icon buttons page allows.\n close: {\n alignItems: 'center',\n height: sizing.controlMd,\n justifyContent: 'center',\n width: sizing.controlMd,\n },\n closeRing: {\n outlineColor: colors.inverseOnSurface,\n outlineOffset: RING_OFFSET,\n outlineStyle: 'solid',\n outlineWidth: RING_WIDTH,\n },\n // Both controls are pills, which the state layer and the ripple clip to.\n control: {\n borderRadius: radii.pill,\n },\n // The message: its 8dp either side inside the strip's own 8dp, and the\n // 14dp above and below. The height is the message's rather than the\n // strip's, which is what lets a 48dp close button sit beside it without\n // making the strip taller than the page draws it.\n //\n // Its basis is half the strip, which is what decides when the controls\n // drop beneath it. A word longer than the line holds breaks inside\n // itself rather than running under the controls, which the least width\n // of 0 allows on the web, where a flex item otherwise keeps the width of\n // its longest word.\n message: {\n flexBasis: '50%',\n flexGrow: 1,\n marginHorizontal: spacing.sm,\n minWidth: 0,\n paddingVertical: MESSAGE_BLOCK_PADDING,\n },\n messageText: {\n color: colors.inverseOnSurface,\n },\n // A strip along the bottom of the overlay layer, with the page's 8dp\n // above it. It passes a touch through wherever no strip is drawn, so\n // the screen under it stays usable.\n region: {\n alignItems: 'center',\n bottom: 0,\n left: 0,\n paddingTop: spacing.sm,\n pointerEvents: 'box-none',\n position: 'absolute',\n right: 0,\n },\n // The container: the page's 8dp either side, and nothing above or\n // below, since what sets its height is the message and the close\n // button. It wraps, so controls too long to leave the message half the\n // strip drop onto a line of their own beneath it, Material Design's\n // two-line snackbar with a longer action.\n strip: {\n alignItems: 'center',\n backgroundColor: colors.inverseSurface,\n borderRadius: radii.xs,\n boxShadow: shadows.elevation3,\n flexDirection: 'row',\n flexWrap: 'wrap',\n minHeight: sizing.controlMd,\n paddingHorizontal: spacing.sm,\n width: '100%',\n },\n }),\n)\n\nconst styles = StyleSheet.create({\n // The action, and the close button after it, kept together after the\n // message so they move beneath it together. The auto margin puts them at\n // the trailing edge: on the message's row the message takes all the room\n // first, and on a row of their own it is all the room there is.\n controls: {\n alignItems: 'center',\n flexDirection: 'row',\n flexShrink: 0,\n marginStart: 'auto',\n },\n wide: {\n maxWidth: MAX_WIDE,\n minWidth: MIN_WIDE,\n },\n})\n\n// A message on screen, with what it was added with.\ntype ShownMessage = {\n readonly action: SnackbarAction | undefined\n readonly key: string\n readonly message: string\n readonly onClose: (() => void) | undefined\n readonly showCloseButton: boolean\n readonly timeout: number\n}\n\ntype SnackbarAction = {\n /** What the action says. The page gives it a single word where it can. */\n readonly label: string\n /** Run when the action is pressed, just before the snackbar closes. */\n readonly onPress: () => void\n}\n\ntype SnackbarOptions = {\n /**\n * A single action shown after the message. Pressing it runs `onPress` and\n * closes the snackbar, which is what the page draws.\n */\n readonly action?: SnackbarAction\n /**\n * Run when the snackbar closes, however it was closed: by its timer, its\n * action or close button, `close`, `clear`, or a newer message added in its\n * place.\n */\n readonly onClose?: () => void\n /**\n * Whether a close button is shown at the end. The page draws one for a\n * message a reader may want out of the way before it expires.\n * @default false\n */\n readonly showCloseButton?: boolean\n /**\n * How long the snackbar is shown, in milliseconds. Defaults to five seconds\n * for a message alone, which Android lengthens from the reader's own\n * accessibility setting. A message with an action defaults to `0` and stays\n * until the action is taken or something closes it, as Material Design asks\n * of an actionable snackbar. The timer is paused while a pointer is over the\n * snackbar or one of its controls has focus, so a message never expires\n * while it is being read.\n *\n * `0` is the page's indefinite length: the snackbar stays until something\n * closes it. Give one of those an action or `showCloseButton`, or there is\n * no way to be rid of it.\n */\n readonly timeout?: number\n}\n\ntype SnackbarProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * What a screen reader calls the button that dismisses a snackbar. It sits\n * here rather than on a message's own options because it does not vary by\n * message.\n * @default 'Close'\n */\n readonly closeLabel?: string\n /** The queue the snackbar shows messages from. */\n readonly queue: SnackbarQueue\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n}\n\n/**\n * The queue a snackbar is shown from. Make one where the app can reach it, a\n * module of its own being the usual place, mount `Snackbar` once with it, and\n * call `add` from anywhere.\n *\n * ```ts\n * const messages = new Snackbar.Queue()\n * messages.add('Label', { action: { label: 'Undo', onPress: undo } })\n * ```\n */\nclass SnackbarQueue {\n #added = 0\n readonly #listeners = new Set<() => void>()\n #shown: null | ShownMessage = null\n\n /**\n * Shows a message in place of the one on screen, and returns the key that\n * closes it. The message it replaces is closed, so its `onClose` runs, and\n * it does not come back.\n */\n add(message: string, options: SnackbarOptions = {}): string {\n const { action, onClose, showCloseButton = false, timeout } = options\n\n this.clear()\n this.#added += 1\n\n const key = `snackbar-${String(this.#added)}`\n\n this.#shown = {\n action,\n key,\n message,\n onClose,\n showCloseButton,\n timeout: timeout ?? (action === undefined ? MESSAGE_MS : UNTIL_CLOSED),\n }\n this.#changed()\n\n return key\n }\n\n /** Closes the snackbar on screen, running its `onClose`. */\n clear() {\n if (this.#shown !== null) {\n this.close(this.#shown.key)\n }\n }\n\n /** Closes one snackbar, by the key `add` returned. */\n close(key: string) {\n const shown = this.#shown\n\n if (shown?.key !== key) {\n return\n }\n\n // Off the screen before `onClose` runs, so one that adds the next message\n // adds it to an empty queue.\n this.#shown = null\n this.#changed()\n shown.onClose?.()\n }\n\n /**\n * Calls `listener` whenever the message on screen changes, and returns what\n * stops it. `Snackbar` reads the queue through this and `visible`, and\n * neither is meant for a call site.\n */\n readonly subscribe = (listener: () => void) => {\n this.#listeners.add(listener)\n\n return () => {\n this.#listeners.delete(listener)\n }\n }\n\n /** The message on screen, or `null`. */\n readonly visible = () => this.#shown\n\n #changed() {\n for (const listener of this.#listeners) {\n listener()\n }\n }\n}\n\n// The handlers the strip hands its views, each built by a call rather than\n// declared in the component, which is what react-perf's\n// jsx-no-new-function-as-prop is after; the React Compiler memoises the result\n// on its inputs.\nfunction actionOf(action: SnackbarAction, close: () => void) {\n return () => {\n action.onPress()\n close()\n }\n}\n\nfunction closeOf(queue: SnackbarQueue, key: string) {\n return () => {\n queue.close(key)\n }\n}\n\nfunction flagOf(set: (value: boolean) => void, value: boolean) {\n return () => {\n set(value)\n }\n}\n\nfunction measureInto(height: SharedValue<number>) {\n return (event: LayoutChangeEvent) => {\n height.set(event.nativeEvent.layout.height)\n }\n}\n\n/**\n * A brief message at the bottom of the screen, with an optional action, with\n * web's props and values. Mount one of these with a `Snackbar.Queue`, and\n * call the queue's `add` to show a message from anywhere.\n *\n * ```tsx\n * const messages = new Snackbar.Queue()\n *\n * <Snackbar queue={messages} />\n * ```\n *\n * It draws in the overlay host of the app's outermost `ThemeScope`, above the\n * screen, and needs one around it. It is one region rather than one per\n * message, so mount it once, near the root, inside the `SafeAreaProvider`\n * whose insets it keeps clear of.\n *\n * `style`, `ref` and `testID` land on that region, a view along the bottom of\n * the screen that holds the message.\n */\nfunction Snackbar({\n closeLabel = 'Close',\n queue,\n style,\n ...props\n}: SnackbarProps) {\n const theme = useTheme()\n const insets = use(SafeAreaInsetsContext) ?? NO_INSETS\n const wide = useWindowSizeClass() !== 'compact'\n const shown = useSyncExternalStore(queue.subscribe, queue.visible)\n // The message up when the snackbar mounted, which was on screen before it\n // rather than arriving, so it is put in place rather than risen to it: on\n // a screen that remounts the snackbar, and on a story seeded with one.\n const [standing] = useState(() => queue.visible()?.key)\n const { spacing } = theme\n\n return (\n <Overlay>\n <View\n aria-live={Platform.OS === 'web' ? 'polite' : undefined}\n {...props}\n style={composeStyles<ViewStyle>(\n stylesOf(theme).region,\n {\n paddingBottom: spacing.sm + insets.bottom,\n paddingLeft: spacing.sm + insets.left,\n paddingRight: spacing.sm + insets.right,\n },\n style,\n )}\n >\n {shown === null ? null : (\n <SnackbarStrip\n arrives={shown.key !== standing}\n closeLabel={closeLabel}\n key={shown.key}\n queue={queue}\n shown={shown}\n wide={wide}\n />\n )}\n </View>\n </Overlay>\n )\n}\n\n/**\n * One of the snackbar's two controls, a pill drawing the state layer, the\n * ripple and the ring in its own colour, over a target brought up to 48dp\n * from the `height` it is drawn at. It reports when it takes and loses focus,\n * which pauses the message's timer.\n */\nfunction SnackbarButton({\n 'aria-label': ariaLabel,\n children,\n color,\n height,\n onFocusChange,\n onPress,\n ring,\n style,\n}: {\n readonly 'aria-label'?: string\n readonly children: ReactNode\n readonly color: string\n readonly height: number\n readonly onFocusChange: (focused: boolean) => void\n readonly onPress: () => void\n readonly ring: ViewStyle\n readonly style: ViewStyle\n}) {\n const theme = useTheme()\n const corners = stylesOf(theme).control\n const feedback = usePressFeedback({\n color,\n corners,\n onBlur: () => {\n onFocusChange(false)\n },\n onFocus: () => {\n onFocusChange(true)\n },\n })\n\n return (\n <Pressable\n {...feedback.handlers}\n aria-label={ariaLabel}\n hitSlop={hitSlop(height)}\n onPress={onPress}\n role=\"button\"\n style={composeStyles<ViewStyle>(\n corners,\n style,\n feedback.ring === undefined ? undefined : ring,\n )}\n >\n {feedback.layer}\n {children}\n </Pressable>\n )\n}\n\n/** One message: the words, then whatever sits after them. */\nfunction SnackbarStrip({\n arrives,\n closeLabel,\n queue,\n shown,\n wide,\n}: {\n /** Whether the message rises into place, or is drawn there at once. */\n readonly arrives: boolean\n readonly closeLabel: string\n readonly queue: SnackbarQueue\n readonly shown: ShownMessage\n readonly wide: boolean\n}) {\n const theme = useTheme()\n const themed = stylesOf(theme)\n const body = useTypeRole('bodyMedium')\n const label = useTypeRole('labelLarge')\n const reduceMotion = useReducedMotion()\n const [focused, setFocused] = useState(false)\n const [hovered, setHovered] = useState(false)\n const { action, key, message, showCloseButton } = shown\n const { colors, motion, sizing } = theme\n\n // It rises its own height from the bottom edge as it fades in, which is\n // what the page draws and what says the message came from the edge of the\n // screen rather than appearing over it. Reduced motion puts it in its\n // settled place at once, as web's zeroed duration does.\n const rises = arrives && !reduceMotion\n const arrived = useSharedValue(rises ? 0 : 1)\n const height = useSharedValue(0)\n const rise = useAnimatedStyle(() => {\n 'worklet'\n const progress = arrived.get()\n\n return {\n opacity: progress,\n transform: [{ translateY: (1 - progress) * height.get() }],\n }\n })\n\n useEffect(() => {\n if (rises) {\n arrived.set(\n withTiming(1, {\n duration: motion.durationMedium1,\n easing: Easing.bezier(...motion.easingEmphasizedDecelerate),\n }),\n )\n }\n }, [arrived, motion, rises])\n\n useEffect(() => {\n if (Platform.OS === 'ios' || Platform.OS === 'android') {\n AccessibilityInfo.announceForAccessibilityWithOptions(message, {\n queue: true,\n })\n }\n }, [message])\n\n const close = closeOf(queue, key)\n\n useExpiry(useShownFor(shown.timeout), focused || hovered, close)\n\n return (\n <Animated.View\n onLayout={measureInto(height)}\n onPointerEnter={flagOf(setHovered, true)}\n onPointerLeave={flagOf(setHovered, false)}\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n themed.strip,\n wide ? styles.wide : undefined,\n rise,\n )}\n >\n <View style={themed.message}>\n <NativeText style={composeStyles<TextStyle>(body, themed.messageText)}>\n {message}\n </NativeText>\n </View>\n {action === undefined && !showCloseButton ? null : (\n <View style={styles.controls}>\n {action === undefined ? null : (\n <SnackbarButton\n color={colors.inversePrimary}\n height={sizing.controlSm}\n onFocusChange={setFocused}\n onPress={actionOf(action, close)}\n ring={themed.actionRing}\n style={themed.action}\n >\n <NativeText\n style={composeStyles<TextStyle>(label, themed.actionLabel)}\n >\n {action.label}\n </NativeText>\n </SnackbarButton>\n )}\n {showCloseButton ? (\n <SnackbarButton\n aria-label={closeLabel}\n color={colors.inverseOnSurface}\n height={sizing.controlMd}\n onFocusChange={setFocused}\n onPress={close}\n ring={themed.closeRing}\n style={themed.close}\n >\n <CloseGlyph color={colors.inverseOnSurface} size={24} />\n </SnackbarButton>\n ) : null}\n </View>\n )}\n </Animated.View>\n )\n}\n\n// Closes a message once it has been shown for `duration` milliseconds,\n// counting only the time it was not paused. Nothing for a `duration` of 0,\n// which is until closed, or of `null`, which is not yet known.\nfunction useExpiry(\n duration: null | number,\n paused: boolean,\n expire: () => void,\n) {\n const left = useRef<null | number>(null)\n\n useEffect(() => {\n if (duration === null || duration === 0 || paused) {\n return undefined\n }\n\n const remaining = left.current ?? duration\n const started = Date.now()\n const timer = setTimeout(expire, remaining)\n\n return () => {\n clearTimeout(timer)\n left.current = remaining - (Date.now() - started)\n }\n }, [duration, expire, paused])\n}\n\n// How long a message is shown: its `timeout`, which Android lengthens from\n// the reader's \"Time to take action\" setting, as its own snackbar does, and\n// is `null` until Android has answered. Nothing is asked for a message shown\n// until closed.\nfunction useShownFor(timeout: number): null | number {\n const [recommended, setRecommended] = useState<null | number>(null)\n const asks = Platform.OS === 'android' && timeout > 0\n\n useEffect(() => {\n if (!asks) {\n return undefined\n }\n\n let current = true\n\n async function ask() {\n const milliseconds =\n await AccessibilityInfo.getRecommendedTimeoutMillis(timeout)\n\n if (current) {\n setRecommended(milliseconds)\n }\n }\n\n void ask()\n\n return () => {\n current = false\n }\n }, [asks, timeout])\n\n return asks ? recommended : timeout\n}\n\nSnackbar.Queue = SnackbarQueue\n\n// The queue is reached as `Snackbar.Queue` rather than exported beside the\n// component, as on web: a module exporting something that is not a component\n// is one fast refresh reloads whole.\nexport { Snackbar }\nexport type { SnackbarAction, SnackbarOptions, SnackbarProps, SnackbarQueue }\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { StyleProp, View, ViewProps, ViewStyle } from "react-native";
2
- import { ReactNode, Ref } from "react";
2
+ import { ComponentRef, ReactNode, Ref } from "react";
3
3
  //#region src/components/switch/index.d.ts
4
4
  type SwitchProps = Omit<ViewProps, 'children' | 'style'> & {
5
5
  /**
@@ -46,7 +46,7 @@ type SwitchProps = Omit<ViewProps, 'children' | 'style'> & {
46
46
  readonly isSelected?: boolean;
47
47
  /** Called with the new state whenever a press or a drag changes it. */
48
48
  readonly onChange?: (isSelected: boolean) => void;
49
- readonly ref?: Ref<View>;
49
+ readonly ref?: Ref<ComponentRef<typeof View>>;
50
50
  readonly style?: StyleProp<ViewStyle>;
51
51
  };
52
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ReactNode","Ref","StyleProp","ViewProps","ViewStyle","AnimatedStyle","SharedValue","ToggleState","useId","useState","I18nManager","Platform","Pressable","StyleSheet","View","Gesture","GestureDetector","GestureHandlerRootView","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","useToggleState","ResolvedTheme","ControlLabel","ControlMessage","describedBy","LAYER_SIZE","messageOf","controlStylesOf","CheckGlyph","hitSlop","usePressFeedback","withOpacity","useTheme","composeStyles","themedStyles","Paint","fill","glyph","handle","rule","SwitchProps","Omit","children","defaultSelected","description","error","icon","isDisabled","isReadOnly","isSelected","onChange","ref","style","TRACK_WIDTH","TRACK_HEIGHT","TRACK_RULE","HANDLE_OFF","HANDLE_ON","HANDLE_PRESSED","ICON_SIZE","TRAVEL","DRAG_SLOP","styles","create","control","flexShrink","height","width","drag","alignItems","flexGrow","justifyContent","layer","position","start","top","seat","track","borderWidth","stylesOf","radii","spacing","borderRadius","circle","messages","marginStart","sm","pill","flipOf","state","took","get","set","toggle","paintOf","colors","stateLayerOpacity","active","on","disabledContent","onSurface","surfaceContainerHighest","disabledContainer","surface","primary","onPrimaryContainer","primaryContainer","onPrimary","onSurfaceVariant","outline","Switch","t0","$","_c","ariaLabel","props","t1","t2","t3","testID","undefined","theme","own","t4","messageId","interactive","t5","enabled","useHandleDrag","t6","t7","t8","t9","onPressIn","color","corners","disabled","disc","feedback","dragging","hovered","pressed","ring","t10","paint","size","t11","offset","motion","useSwitchMotion","T0","T1","t12","t13","t14","handlers","t15","Symbol","for","t16","pressOf","t17","t18","row","T2","T3","t20","gesture","T4","t22","t23","t24","t25","t26","t27","t28","t29","t30","t31","t32","t33","t21","t34","t35","t19","t36","t37","t38","t39","setDragging","began","follow","x","along","isRTL","Math","min","max","pan","Pan","activeOffsetX","runOnJS","onBegin","x_0","onStart","x_1","OS","onUpdate","x_2","onEnd","_event","success","stopped","setSelected","onFinalize","withTestId","reduceMotion","timing","duration","durationShort2","easing","bezier","easingStandard","direction","rest","backgroundColor","borderColor","dragged","transform","translateX","handleMotion","_c"],"sources":["../../../src/components/switch/index.tsx"],"sourcesContent":["import type { ReactNode, Ref } from 'react'\nimport type { StyleProp, ViewProps, ViewStyle } from 'react-native'\nimport type { AnimatedStyle, SharedValue } from 'react-native-reanimated'\nimport type { ToggleState } from 'react-stately/useToggleState'\n\nimport { useId, useState } from 'react'\nimport {\n I18nManager,\n Platform,\n Pressable,\n StyleSheet,\n View,\n} from 'react-native'\nimport {\n Gesture,\n GestureDetector,\n GestureHandlerRootView,\n} from 'react-native-gesture-handler'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\nimport { useToggleState } from 'react-stately/useToggleState'\n\nimport type { ResolvedTheme } from '../../theme/scope'\n\nimport {\n ControlLabel,\n ControlMessage,\n describedBy,\n LAYER_SIZE,\n messageOf,\n} from '../../control'\nimport { controlStylesOf } from '../../control/styles'\nimport { CheckGlyph } from '../../glyphs'\nimport { hitSlop, usePressFeedback } from '../../press'\nimport { withOpacity } from '../../theme/color'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\n\n// The switch page, as kanso-ui's Switch draws it: a 52 by 32dp track with a\n// 2dp outline and a full corner, a handle that is 16dp off, 24dp on and 28dp\n// while pressed, a 16dp icon in the handle when asked for, a 40dp state layer\n// around the handle and a 48dp target. Off, the track is surface container\n// highest inside an outline rule and the handle is outline, turning on surface\n// variant while hovered, pressed or focused; on, the track is primary and the\n// handle on primary, turning primary container in the same states, with the\n// icon in on primary container. Disabled, the track and its rule are on\n// surface at the disabled container opacity and the handle on surface at the\n// disabled content opacity, or surface when on. The state layer is on surface\n// off and primary on, at each state's opacity, and does not swap once pressed\n// as a checkbox's does.\n//\n// The handle travels between the two ends of the track and grows between its\n// three sizes over the motion tokens' short duration on the standard curve,\n// as web's transition does, and at once for a reader who asks the device for\n// reduced motion. The track's colours ease alongside. The state layer and the\n// ripple sit on a 40dp disc centred on the handle, so they travel with it.\n//\n// The handle follows a drag, as the page's pressed switch does: the switch\n// flips when it is let go past the middle of the track and springs back when\n// it is not. The drag is Gesture Handler's, over the whole track rather than\n// only the handle, as a drag on iOS's own switch is. A press that moves less\n// than half the travel is still a tap, which the row's `Pressable` takes and\n// which flips the switch on its own. Once a drag takes over, Gesture Handler\n// ends that press without a tap on iOS and Android, so letting go settles the\n// switch once, from where the handle is. React Native Web has nothing to end\n// the press with, and the click a pointer's release sends would flip it a\n// second time, so there the switch ignores the tap a drag took over.\n//\n// Under a right-to-left layout the handle starts from the right, and a drag\n// toward the left turns the switch on.\n//\n// Gesture Handler recognises a drag only under its root view, so the track\n// carries one of its own, as its guide asks of a library. An app that wraps\n// itself in one already makes this one a plain view.\n//\n// The row, the label and the line under it are src/control's, which Checkbox\n// and Radio draw through as well. The whole row is the `Pressable`, so a press\n// on the label flips the switch, as a press on web's label does. The line\n// under it starts where the label does, past the track.\n\ntype Paint = {\n readonly fill: string\n readonly glyph: string\n readonly handle: string\n readonly rule: string\n}\n\ntype SwitchProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * The label, beside the switch. A switch that a row labels some other way\n * leaves it out and passes `aria-label` instead.\n */\n readonly children?: ReactNode\n /**\n * Whether the switch starts on, when it keeps its own state.\n * @default false\n */\n readonly defaultSelected?: boolean\n /**\n * A hint under the label. Replaced by `error` when there is one, so the\n * two never stack.\n */\n readonly description?: string\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the switch in its error state: the line under the label is the error, in\n * the error colour.\n */\n readonly error?: string\n /**\n * Draws the check in the handle while the switch is on, the page's \"icon on\n * selected switch\" form.\n * @default false\n */\n readonly icon?: boolean\n /**\n * Draws the switch disabled, and takes no presses or drags.\n * @default false\n */\n readonly isDisabled?: boolean\n /**\n * Shows the state without letting a press or a drag change it.\n * @default false\n */\n readonly isReadOnly?: boolean\n /**\n * Whether the switch is on, for a call site holding the state itself with\n * `onChange`.\n */\n readonly isSelected?: boolean\n /** Called with the new state whenever a press or a drag changes it. */\n readonly onChange?: (isSelected: boolean) => void\n readonly ref?: Ref<View>\n readonly style?: StyleProp<ViewStyle>\n}\n\n// The track's size and its rule, from the page.\nconst TRACK_WIDTH = 52\nconst TRACK_HEIGHT = 32\nconst TRACK_RULE = 2\n\n// The handle's three sizes and the icon's, from the page.\nconst HANDLE_OFF = 16\nconst HANDLE_ON = 24\nconst HANDLE_PRESSED = 28\nconst ICON_SIZE = 16\n\n// How far the handle's seat, the pressed handle's 28dp, travels: the track's\n// 48dp inside its rule, less the seat. Off, the seat's centre is 16dp from the\n// track's start, and on, 16dp from its end, which is where the page's handles\n// sit.\nconst TRAVEL = TRACK_WIDTH - 2 * TRACK_RULE - HANDLE_PRESSED\n\n// How far a press moves before it is a drag: half the travel, the platforms'\n// own touch slop, as web's is for a finger. A finger drifts several dp on an\n// ordinary tap, and a tap inside this flips the switch. A drag past it is past\n// the middle too, so it turns the switch over unless it comes back.\nconst DRAG_SLOP = TRAVEL / 2\n\nconst styles = StyleSheet.create({\n // The 52 by 40 the switch takes in the row, the height of the state layer\n // around the handle, with the track centred in it. Gesture Handler's root\n // view, sized to the track rather than to the screen it fills by default.\n control: {\n flexShrink: 0,\n height: LAYER_SIZE,\n width: TRACK_WIDTH,\n },\n // What the drag is recognised over: the whole of the control.\n drag: {\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'center',\n },\n handle: {\n alignItems: 'center',\n justifyContent: 'center',\n },\n // The 40dp state layer, centred on the handle and so on its seat.\n layer: {\n height: LAYER_SIZE,\n position: 'absolute',\n start: (HANDLE_PRESSED - LAYER_SIZE) / 2,\n top: (HANDLE_PRESSED - LAYER_SIZE) / 2,\n width: LAYER_SIZE,\n },\n // The handle's seat, the pressed handle's size, at the start of the track\n // inside its rule. It travels by a translation, so the layout never moves.\n seat: {\n alignItems: 'center',\n height: HANDLE_PRESSED,\n justifyContent: 'center',\n position: 'absolute',\n start: 0,\n top: 0,\n width: HANDLE_PRESSED,\n },\n track: {\n borderWidth: TRACK_RULE,\n height: TRACK_HEIGHT,\n width: TRACK_WIDTH,\n },\n})\n\nconst stylesOf = themedStyles(({ radii, spacing }) =>\n StyleSheet.create({\n handle: {\n borderRadius: radii.circle,\n },\n // Past the track rather than the 40dp layer a checkbox draws, so the line\n // starts where the label's text does.\n messages: {\n marginStart: TRACK_WIDTH + spacing.sm,\n },\n track: {\n borderRadius: radii.pill,\n },\n }),\n)\n\n// A press's flip, unless a drag took the press over. Built by a call rather\n// than declared in the component, which is what react-perf's\n// jsx-no-new-function-as-prop is after.\nfunction flipOf(state: ToggleState, took: SharedValue<boolean>) {\n return () => {\n if (took.get()) {\n took.set(false)\n return\n }\n state.toggle()\n }\n}\n\n/**\n * What the switch is painted in: the track's fill and rule, the handle and\n * the icon. Where the page draws no rule it is the fill made clear rather than\n * plain transparent black, so the rule eases through its own colour rather\n * than through grey.\n */\nfunction paintOf(\n { colors, stateLayerOpacity }: ResolvedTheme,\n {\n active,\n isDisabled,\n on,\n }: {\n readonly active: boolean\n readonly isDisabled: boolean\n readonly on: boolean\n },\n): Paint {\n const disabledContent = withOpacity(\n colors.onSurface,\n stateLayerOpacity.disabledContent,\n )\n\n if (isDisabled) {\n const fill = withOpacity(\n on ? colors.onSurface : colors.surfaceContainerHighest,\n stateLayerOpacity.disabledContainer,\n )\n\n return {\n fill,\n glyph: disabledContent,\n handle: on ? colors.surface : disabledContent,\n rule: on\n ? withOpacity(fill, 0)\n : withOpacity(colors.onSurface, stateLayerOpacity.disabledContainer),\n }\n }\n\n if (on) {\n return {\n fill: colors.primary,\n glyph: colors.onPrimaryContainer,\n handle: active ? colors.primaryContainer : colors.onPrimary,\n rule: colors.primary,\n }\n }\n\n return {\n fill: colors.surfaceContainerHighest,\n glyph: colors.onPrimaryContainer,\n handle: active ? colors.onSurfaceVariant : colors.outline,\n rule: colors.outline,\n }\n}\n\n/**\n * A switch that turns a setting on or off, with its label and optionally a\n * description or an error under it. Its state is React Stately's, as web's\n * is: pass `isSelected` with `onChange` to control it, or `defaultSelected` to\n * let it keep its own. A switch takes effect as it is flipped, which is what\n * sets it apart from a checkbox in a form.\n *\n * ```tsx\n * <Switch defaultSelected description=\"Supporting line\">\n * Label\n * </Switch>\n * ```\n *\n * A screen reader hears it as a switch named by its label, on or off,\n * followed by the line under it. A press anywhere on the track or the label\n * flips it, and the handle can be dragged across the track, settling on\n * whichever side it is let go. `style`, `ref` and `testID` land on the view\n * holding the row and the line under it, which is the element a layout\n * positions. With a `testID`, the drag is registered with Gesture Handler as\n * `<testID>-drag`, which its `getByGestureTestId` finds in a test.\n */\nfunction Switch({\n 'aria-label': ariaLabel,\n children,\n defaultSelected,\n description,\n error,\n icon = false,\n isDisabled = false,\n isReadOnly = false,\n isSelected,\n onChange,\n style,\n testID,\n ...props\n}: SwitchProps) {\n const theme = useTheme()\n const own = stylesOf(theme)\n const state = useToggleState({\n defaultSelected,\n isReadOnly,\n isSelected,\n onChange,\n })\n const messageId = useId()\n\n const { colors, radii } = theme\n const on = state.isSelected\n const interactive = !isDisabled && !isReadOnly\n const drag = useHandleDrag({ enabled: interactive, on, state, testID })\n\n const feedback = usePressFeedback({\n color: on ? colors.primary : colors.onSurface,\n corners: { borderRadius: radii.circle },\n disabled: !interactive,\n disc: LAYER_SIZE,\n onPressIn: drag.onPressIn,\n })\n const active =\n interactive &&\n (drag.dragging ||\n feedback.hovered ||\n feedback.pressed ||\n feedback.ring !== undefined)\n const paint = paintOf(theme, { active, isDisabled, on })\n const size =\n drag.dragging || feedback.pressed\n ? HANDLE_PRESSED\n : on\n ? HANDLE_ON\n : HANDLE_OFF\n const motion = useSwitchMotion(paint, { offset: drag.offset, on, size })\n\n return (\n <View {...props} style={style} testID={testID}>\n <Pressable\n aria-checked={on}\n aria-label={ariaLabel}\n role=\"switch\"\n {...describedBy(messageId, messageOf(description, error))}\n {...feedback.handlers}\n disabled={isDisabled}\n hitSlop={hitSlop(LAYER_SIZE, TRACK_WIDTH)}\n onPress={drag.pressOf(state)}\n style={controlStylesOf(theme).row}\n >\n <GestureHandlerRootView style={styles.control}>\n <GestureDetector gesture={drag.gesture}>\n <View style={styles.drag}>\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.track,\n own.track,\n motion.track,\n feedback.ring,\n )}\n >\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.seat,\n motion.seat,\n )}\n >\n <View style={styles.layer}>{feedback.layer}</View>\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.handle,\n own.handle,\n motion.handle,\n )}\n >\n {icon && on ? (\n <CheckGlyph color={paint.glyph} size={ICON_SIZE} />\n ) : null}\n </Animated.View>\n </Animated.View>\n </Animated.View>\n </View>\n </GestureDetector>\n </GestureHandlerRootView>\n <ControlLabel isDisabled={isDisabled}>{children}</ControlLabel>\n </Pressable>\n <ControlMessage\n description={description}\n error={error}\n id={messageId}\n style={own.messages}\n />\n </View>\n )\n}\n\n/**\n * The handle following a drag across the track, and settling from where it\n * is let go: on past the middle, off before it. `offset` is where the drag\n * has put the handle's seat while one is under way, measured from the start\n * of the track, and nothing otherwise, when the seat rests at the end the\n * switch is on.\n *\n * The drag is recognised once it has moved `DRAG_SLOP` across the track, and\n * on the JavaScript thread, since settling sets React state and a drag moves\n * one shared value.\n */\nfunction useHandleDrag({\n enabled,\n on,\n state,\n testID,\n}: {\n readonly enabled: boolean\n readonly on: boolean\n readonly state: ToggleState\n readonly testID: string | undefined\n}) {\n const [dragging, setDragging] = useState(false)\n const offset = useSharedValue<null | number>(null)\n // Whether a drag has taken over the press in flight, whose click React\n // Native Web would otherwise turn into a second flip. Cleared by the next\n // press rather than by that click, which a touch dragged far enough never\n // sends. A shared value rather than a ref: the gesture's callbacks are\n // built while rendering, and the React Compiler lets no ref reach them.\n const took = useSharedValue(false)\n\n // Where the press began across the track. Gesture Handler measures its\n // translation from where the drag was recognised, past the slop, so the\n // distance is taken from here instead, as web's is from the press.\n const began = useSharedValue(0)\n\n // Puts the seat where the drag has carried it, from the end it started at,\n // and no further than either end.\n function follow(x: number) {\n const along = I18nManager.isRTL ? began.get() - x : x - began.get()\n offset.set(Math.min(TRAVEL, Math.max(0, (on ? TRAVEL : 0) + along)))\n }\n\n // oxlint-disable-next-line react/capitalized-calls -- a builder Gesture Handler names after the gesture, not a component\n const pan = Gesture.Pan()\n .activeOffsetX([-DRAG_SLOP, DRAG_SLOP])\n .enabled(enabled)\n .runOnJS(true)\n .onBegin(({ x }) => {\n began.set(x)\n })\n .onStart(({ x }) => {\n took.set(Platform.OS === 'web')\n setDragging(true)\n follow(x)\n })\n .onUpdate(({ x }) => {\n follow(x)\n })\n .onEnd((_event, success) => {\n const stopped = offset.get()\n if (success && stopped !== null && stopped > TRAVEL / 2 !== on) {\n state.setSelected(!on)\n }\n })\n .onFinalize(() => {\n offset.set(null)\n setDragging(false)\n })\n\n return {\n dragging,\n gesture: testID === undefined ? pan : pan.withTestId(`${testID}-drag`),\n offset,\n onPressIn: () => {\n took.set(false)\n },\n pressOf: (toggle: ToggleState) => flipOf(toggle, took),\n }\n}\n\n// The track's colours, the seat's travel and the handle's size and colour,\n// eased to as the state changes. While a drag is under way the seat follows it\n// at once, and once it ends the seat eases from wherever it was let go.\nfunction useSwitchMotion(\n { fill, handle, rule }: Paint,\n {\n offset,\n on,\n size,\n }: {\n readonly offset: SharedValue<null | number>\n readonly on: boolean\n readonly size: number\n },\n) {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const timing = {\n duration: motion.durationShort2,\n easing: Easing.bezier(...motion.easingStandard),\n }\n // A translation is not mirrored under a right-to-left layout, though the\n // seat's start is, so the seat travels the other way there.\n const direction = I18nManager.isRTL ? -1 : 1\n const rest = (on ? TRAVEL : 0) * direction\n\n const track = useAnimatedStyle(() => {\n 'worklet'\n return {\n backgroundColor: reduceMotion ? fill : withTiming(fill, timing),\n borderColor: reduceMotion ? rule : withTiming(rule, timing),\n }\n })\n const seat = useAnimatedStyle(() => {\n 'worklet'\n const dragged = offset.get()\n return {\n transform: [\n {\n translateX:\n dragged !== null\n ? dragged * direction\n : reduceMotion\n ? rest\n : withTiming(rest, timing),\n },\n ],\n }\n })\n const handleMotion = useAnimatedStyle(() => {\n 'worklet'\n return {\n backgroundColor: reduceMotion ? handle : withTiming(handle, timing),\n height: reduceMotion ? size : withTiming(size, timing),\n width: reduceMotion ? size : withTiming(size, timing),\n }\n })\n\n return { handle: handleMotion, seat, track }\n}\n\nexport { Switch }\nexport type { SwitchProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","StyleProp","ViewProps","ViewStyle","AnimatedStyle","SharedValue","ToggleState","useId","useState","I18nManager","Platform","Pressable","StyleSheet","View","Gesture","GestureDetector","GestureHandlerRootView","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","useToggleState","ResolvedTheme","ControlLabel","ControlMessage","describedBy","LAYER_SIZE","messageOf","controlStylesOf","CheckGlyph","hitSlop","usePressFeedback","withOpacity","useTheme","composeStyles","themedStyles","Paint","fill","glyph","handle","rule","SwitchProps","Omit","children","defaultSelected","description","error","icon","isDisabled","isReadOnly","isSelected","onChange","ref","style","TRACK_WIDTH","TRACK_HEIGHT","TRACK_RULE","HANDLE_OFF","HANDLE_ON","HANDLE_PRESSED","ICON_SIZE","TRAVEL","DRAG_SLOP","styles","create","control","flexShrink","height","width","drag","alignItems","flexGrow","justifyContent","layer","position","start","top","seat","track","borderWidth","stylesOf","radii","spacing","borderRadius","circle","messages","marginStart","sm","pill","flipOf","state","took","get","set","toggle","paintOf","colors","stateLayerOpacity","active","on","disabledContent","onSurface","surfaceContainerHighest","disabledContainer","surface","primary","onPrimaryContainer","primaryContainer","onPrimary","onSurfaceVariant","outline","Switch","t0","$","_c","ariaLabel","props","t1","t2","t3","testID","undefined","theme","own","t4","messageId","interactive","t5","enabled","useHandleDrag","t6","t7","t8","t9","onPressIn","color","corners","disabled","disc","feedback","dragging","hovered","pressed","ring","t10","paint","size","t11","offset","motion","useSwitchMotion","T0","T1","t12","t13","t14","handlers","t15","Symbol","for","t16","pressOf","t17","t18","row","T2","T3","t20","gesture","T4","t22","t23","t24","t25","t26","t27","t28","t29","t30","t31","t32","t33","t21","t34","t35","t19","t36","t37","t38","t39","setDragging","began","follow","x","along","isRTL","Math","min","max","pan","Pan","activeOffsetX","runOnJS","onBegin","x_0","onStart","x_1","OS","onUpdate","x_2","onEnd","_event","success","stopped","setSelected","onFinalize","withTestId","reduceMotion","timing","duration","durationShort2","easing","bezier","easingStandard","direction","rest","backgroundColor","borderColor","dragged","transform","translateX","handleMotion","_c"],"sources":["../../../src/components/switch/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type { StyleProp, ViewProps, ViewStyle } from 'react-native'\nimport type { AnimatedStyle, SharedValue } from 'react-native-reanimated'\nimport type { ToggleState } from 'react-stately/useToggleState'\n\nimport { useId, useState } from 'react'\nimport {\n I18nManager,\n Platform,\n Pressable,\n StyleSheet,\n View,\n} from 'react-native'\nimport {\n Gesture,\n GestureDetector,\n GestureHandlerRootView,\n} from 'react-native-gesture-handler'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\nimport { useToggleState } from 'react-stately/useToggleState'\n\nimport type { ResolvedTheme } from '../../theme/scope'\n\nimport {\n ControlLabel,\n ControlMessage,\n describedBy,\n LAYER_SIZE,\n messageOf,\n} from '../../control'\nimport { controlStylesOf } from '../../control/styles'\nimport { CheckGlyph } from '../../glyphs'\nimport { hitSlop, usePressFeedback } from '../../press'\nimport { withOpacity } from '../../theme/color'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\n\n// The switch page, as kanso-ui's Switch draws it: a 52 by 32dp track with a\n// 2dp outline and a full corner, a handle that is 16dp off, 24dp on and 28dp\n// while pressed, a 16dp icon in the handle when asked for, a 40dp state layer\n// around the handle and a 48dp target. Off, the track is surface container\n// highest inside an outline rule and the handle is outline, turning on surface\n// variant while hovered, pressed or focused; on, the track is primary and the\n// handle on primary, turning primary container in the same states, with the\n// icon in on primary container. Disabled, the track and its rule are on\n// surface at the disabled container opacity and the handle on surface at the\n// disabled content opacity, or surface when on. The state layer is on surface\n// off and primary on, at each state's opacity, and does not swap once pressed\n// as a checkbox's does.\n//\n// The handle travels between the two ends of the track and grows between its\n// three sizes over the motion tokens' short duration on the standard curve,\n// as web's transition does, and at once for a reader who asks the device for\n// reduced motion. The track's colours ease alongside. The state layer and the\n// ripple sit on a 40dp disc centred on the handle, so they travel with it.\n//\n// The handle follows a drag, as the page's pressed switch does: the switch\n// flips when it is let go past the middle of the track and springs back when\n// it is not. The drag is Gesture Handler's, over the whole track rather than\n// only the handle, as a drag on iOS's own switch is. A press that moves less\n// than half the travel is still a tap, which the row's `Pressable` takes and\n// which flips the switch on its own. Once a drag takes over, Gesture Handler\n// ends that press without a tap on iOS and Android, so letting go settles the\n// switch once, from where the handle is. React Native Web has nothing to end\n// the press with, and the click a pointer's release sends would flip it a\n// second time, so there the switch ignores the tap a drag took over.\n//\n// Under a right-to-left layout the handle starts from the right, and a drag\n// toward the left turns the switch on.\n//\n// Gesture Handler recognises a drag only under its root view, so the track\n// carries one of its own, as its guide asks of a library. An app that wraps\n// itself in one already makes this one a plain view.\n//\n// The row, the label and the line under it are src/control's, which Checkbox\n// and Radio draw through as well. The whole row is the `Pressable`, so a press\n// on the label flips the switch, as a press on web's label does. The line\n// under it starts where the label does, past the track.\n\ntype Paint = {\n readonly fill: string\n readonly glyph: string\n readonly handle: string\n readonly rule: string\n}\n\ntype SwitchProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * The label, beside the switch. A switch that a row labels some other way\n * leaves it out and passes `aria-label` instead.\n */\n readonly children?: ReactNode\n /**\n * Whether the switch starts on, when it keeps its own state.\n * @default false\n */\n readonly defaultSelected?: boolean\n /**\n * A hint under the label. Replaced by `error` when there is one, so the\n * two never stack.\n */\n readonly description?: string\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the switch in its error state: the line under the label is the error, in\n * the error colour.\n */\n readonly error?: string\n /**\n * Draws the check in the handle while the switch is on, the page's \"icon on\n * selected switch\" form.\n * @default false\n */\n readonly icon?: boolean\n /**\n * Draws the switch disabled, and takes no presses or drags.\n * @default false\n */\n readonly isDisabled?: boolean\n /**\n * Shows the state without letting a press or a drag change it.\n * @default false\n */\n readonly isReadOnly?: boolean\n /**\n * Whether the switch is on, for a call site holding the state itself with\n * `onChange`.\n */\n readonly isSelected?: boolean\n /** Called with the new state whenever a press or a drag changes it. */\n readonly onChange?: (isSelected: boolean) => void\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n}\n\n// The track's size and its rule, from the page.\nconst TRACK_WIDTH = 52\nconst TRACK_HEIGHT = 32\nconst TRACK_RULE = 2\n\n// The handle's three sizes and the icon's, from the page.\nconst HANDLE_OFF = 16\nconst HANDLE_ON = 24\nconst HANDLE_PRESSED = 28\nconst ICON_SIZE = 16\n\n// How far the handle's seat, the pressed handle's 28dp, travels: the track's\n// 48dp inside its rule, less the seat. Off, the seat's centre is 16dp from the\n// track's start, and on, 16dp from its end, which is where the page's handles\n// sit.\nconst TRAVEL = TRACK_WIDTH - 2 * TRACK_RULE - HANDLE_PRESSED\n\n// How far a press moves before it is a drag: half the travel, the platforms'\n// own touch slop, as web's is for a finger. A finger drifts several dp on an\n// ordinary tap, and a tap inside this flips the switch. A drag past it is past\n// the middle too, so it turns the switch over unless it comes back.\nconst DRAG_SLOP = TRAVEL / 2\n\nconst styles = StyleSheet.create({\n // The 52 by 40 the switch takes in the row, the height of the state layer\n // around the handle, with the track centred in it. Gesture Handler's root\n // view, sized to the track rather than to the screen it fills by default.\n control: {\n flexShrink: 0,\n height: LAYER_SIZE,\n width: TRACK_WIDTH,\n },\n // What the drag is recognised over: the whole of the control.\n drag: {\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'center',\n },\n handle: {\n alignItems: 'center',\n justifyContent: 'center',\n },\n // The 40dp state layer, centred on the handle and so on its seat.\n layer: {\n height: LAYER_SIZE,\n position: 'absolute',\n start: (HANDLE_PRESSED - LAYER_SIZE) / 2,\n top: (HANDLE_PRESSED - LAYER_SIZE) / 2,\n width: LAYER_SIZE,\n },\n // The handle's seat, the pressed handle's size, at the start of the track\n // inside its rule. It travels by a translation, so the layout never moves.\n seat: {\n alignItems: 'center',\n height: HANDLE_PRESSED,\n justifyContent: 'center',\n position: 'absolute',\n start: 0,\n top: 0,\n width: HANDLE_PRESSED,\n },\n track: {\n borderWidth: TRACK_RULE,\n height: TRACK_HEIGHT,\n width: TRACK_WIDTH,\n },\n})\n\nconst stylesOf = themedStyles(({ radii, spacing }) =>\n StyleSheet.create({\n handle: {\n borderRadius: radii.circle,\n },\n // Past the track rather than the 40dp layer a checkbox draws, so the line\n // starts where the label's text does.\n messages: {\n marginStart: TRACK_WIDTH + spacing.sm,\n },\n track: {\n borderRadius: radii.pill,\n },\n }),\n)\n\n// A press's flip, unless a drag took the press over. Built by a call rather\n// than declared in the component, which is what react-perf's\n// jsx-no-new-function-as-prop is after.\nfunction flipOf(state: ToggleState, took: SharedValue<boolean>) {\n return () => {\n if (took.get()) {\n took.set(false)\n return\n }\n state.toggle()\n }\n}\n\n/**\n * What the switch is painted in: the track's fill and rule, the handle and\n * the icon. Where the page draws no rule it is the fill made clear rather than\n * plain transparent black, so the rule eases through its own colour rather\n * than through grey.\n */\nfunction paintOf(\n { colors, stateLayerOpacity }: ResolvedTheme,\n {\n active,\n isDisabled,\n on,\n }: {\n readonly active: boolean\n readonly isDisabled: boolean\n readonly on: boolean\n },\n): Paint {\n const disabledContent = withOpacity(\n colors.onSurface,\n stateLayerOpacity.disabledContent,\n )\n\n if (isDisabled) {\n const fill = withOpacity(\n on ? colors.onSurface : colors.surfaceContainerHighest,\n stateLayerOpacity.disabledContainer,\n )\n\n return {\n fill,\n glyph: disabledContent,\n handle: on ? colors.surface : disabledContent,\n rule: on\n ? withOpacity(fill, 0)\n : withOpacity(colors.onSurface, stateLayerOpacity.disabledContainer),\n }\n }\n\n if (on) {\n return {\n fill: colors.primary,\n glyph: colors.onPrimaryContainer,\n handle: active ? colors.primaryContainer : colors.onPrimary,\n rule: colors.primary,\n }\n }\n\n return {\n fill: colors.surfaceContainerHighest,\n glyph: colors.onPrimaryContainer,\n handle: active ? colors.onSurfaceVariant : colors.outline,\n rule: colors.outline,\n }\n}\n\n/**\n * A switch that turns a setting on or off, with its label and optionally a\n * description or an error under it. Its state is React Stately's, as web's\n * is: pass `isSelected` with `onChange` to control it, or `defaultSelected` to\n * let it keep its own. A switch takes effect as it is flipped, which is what\n * sets it apart from a checkbox in a form.\n *\n * ```tsx\n * <Switch defaultSelected description=\"Supporting line\">\n * Label\n * </Switch>\n * ```\n *\n * A screen reader hears it as a switch named by its label, on or off,\n * followed by the line under it. A press anywhere on the track or the label\n * flips it, and the handle can be dragged across the track, settling on\n * whichever side it is let go. `style`, `ref` and `testID` land on the view\n * holding the row and the line under it, which is the element a layout\n * positions. With a `testID`, the drag is registered with Gesture Handler as\n * `<testID>-drag`, which its `getByGestureTestId` finds in a test.\n */\nfunction Switch({\n 'aria-label': ariaLabel,\n children,\n defaultSelected,\n description,\n error,\n icon = false,\n isDisabled = false,\n isReadOnly = false,\n isSelected,\n onChange,\n style,\n testID,\n ...props\n}: SwitchProps) {\n const theme = useTheme()\n const own = stylesOf(theme)\n const state = useToggleState({\n defaultSelected,\n isReadOnly,\n isSelected,\n onChange,\n })\n const messageId = useId()\n\n const { colors, radii } = theme\n const on = state.isSelected\n const interactive = !isDisabled && !isReadOnly\n const drag = useHandleDrag({ enabled: interactive, on, state, testID })\n\n const feedback = usePressFeedback({\n color: on ? colors.primary : colors.onSurface,\n corners: { borderRadius: radii.circle },\n disabled: !interactive,\n disc: LAYER_SIZE,\n onPressIn: drag.onPressIn,\n })\n const active =\n interactive &&\n (drag.dragging ||\n feedback.hovered ||\n feedback.pressed ||\n feedback.ring !== undefined)\n const paint = paintOf(theme, { active, isDisabled, on })\n const size =\n drag.dragging || feedback.pressed\n ? HANDLE_PRESSED\n : on\n ? HANDLE_ON\n : HANDLE_OFF\n const motion = useSwitchMotion(paint, { offset: drag.offset, on, size })\n\n return (\n <View {...props} style={style} testID={testID}>\n <Pressable\n aria-checked={on}\n aria-label={ariaLabel}\n role=\"switch\"\n {...describedBy(messageId, messageOf(description, error))}\n {...feedback.handlers}\n disabled={isDisabled}\n hitSlop={hitSlop(LAYER_SIZE, TRACK_WIDTH)}\n onPress={drag.pressOf(state)}\n style={controlStylesOf(theme).row}\n >\n <GestureHandlerRootView style={styles.control}>\n <GestureDetector gesture={drag.gesture}>\n <View style={styles.drag}>\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.track,\n own.track,\n motion.track,\n feedback.ring,\n )}\n >\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.seat,\n motion.seat,\n )}\n >\n <View style={styles.layer}>{feedback.layer}</View>\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.handle,\n own.handle,\n motion.handle,\n )}\n >\n {icon && on ? (\n <CheckGlyph color={paint.glyph} size={ICON_SIZE} />\n ) : null}\n </Animated.View>\n </Animated.View>\n </Animated.View>\n </View>\n </GestureDetector>\n </GestureHandlerRootView>\n <ControlLabel isDisabled={isDisabled}>{children}</ControlLabel>\n </Pressable>\n <ControlMessage\n description={description}\n error={error}\n id={messageId}\n style={own.messages}\n />\n </View>\n )\n}\n\n/**\n * The handle following a drag across the track, and settling from where it\n * is let go: on past the middle, off before it. `offset` is where the drag\n * has put the handle's seat while one is under way, measured from the start\n * of the track, and nothing otherwise, when the seat rests at the end the\n * switch is on.\n *\n * The drag is recognised once it has moved `DRAG_SLOP` across the track, and\n * on the JavaScript thread, since settling sets React state and a drag moves\n * one shared value.\n */\nfunction useHandleDrag({\n enabled,\n on,\n state,\n testID,\n}: {\n readonly enabled: boolean\n readonly on: boolean\n readonly state: ToggleState\n readonly testID: string | undefined\n}) {\n const [dragging, setDragging] = useState(false)\n const offset = useSharedValue<null | number>(null)\n // Whether a drag has taken over the press in flight, whose click React\n // Native Web would otherwise turn into a second flip. Cleared by the next\n // press rather than by that click, which a touch dragged far enough never\n // sends. A shared value rather than a ref: the gesture's callbacks are\n // built while rendering, and the React Compiler lets no ref reach them.\n const took = useSharedValue(false)\n\n // Where the press began across the track. Gesture Handler measures its\n // translation from where the drag was recognised, past the slop, so the\n // distance is taken from here instead, as web's is from the press.\n const began = useSharedValue(0)\n\n // Puts the seat where the drag has carried it, from the end it started at,\n // and no further than either end.\n function follow(x: number) {\n const along = I18nManager.isRTL ? began.get() - x : x - began.get()\n offset.set(Math.min(TRAVEL, Math.max(0, (on ? TRAVEL : 0) + along)))\n }\n\n // oxlint-disable-next-line react/capitalized-calls -- a builder Gesture Handler names after the gesture, not a component\n const pan = Gesture.Pan()\n .activeOffsetX([-DRAG_SLOP, DRAG_SLOP])\n .enabled(enabled)\n .runOnJS(true)\n .onBegin(({ x }) => {\n began.set(x)\n })\n .onStart(({ x }) => {\n took.set(Platform.OS === 'web')\n setDragging(true)\n follow(x)\n })\n .onUpdate(({ x }) => {\n follow(x)\n })\n .onEnd((_event, success) => {\n const stopped = offset.get()\n if (success && stopped !== null && stopped > TRAVEL / 2 !== on) {\n state.setSelected(!on)\n }\n })\n .onFinalize(() => {\n offset.set(null)\n setDragging(false)\n })\n\n return {\n dragging,\n gesture: testID === undefined ? pan : pan.withTestId(`${testID}-drag`),\n offset,\n onPressIn: () => {\n took.set(false)\n },\n pressOf: (toggle: ToggleState) => flipOf(toggle, took),\n }\n}\n\n// The track's colours, the seat's travel and the handle's size and colour,\n// eased to as the state changes. While a drag is under way the seat follows it\n// at once, and once it ends the seat eases from wherever it was let go.\nfunction useSwitchMotion(\n { fill, handle, rule }: Paint,\n {\n offset,\n on,\n size,\n }: {\n readonly offset: SharedValue<null | number>\n readonly on: boolean\n readonly size: number\n },\n) {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const timing = {\n duration: motion.durationShort2,\n easing: Easing.bezier(...motion.easingStandard),\n }\n // A translation is not mirrored under a right-to-left layout, though the\n // seat's start is, so the seat travels the other way there.\n const direction = I18nManager.isRTL ? -1 : 1\n const rest = (on ? TRAVEL : 0) * direction\n\n const track = useAnimatedStyle(() => {\n 'worklet'\n return {\n backgroundColor: reduceMotion ? fill : withTiming(fill, timing),\n borderColor: reduceMotion ? rule : withTiming(rule, timing),\n }\n })\n const seat = useAnimatedStyle(() => {\n 'worklet'\n const dragged = offset.get()\n return {\n transform: [\n {\n translateX:\n dragged !== null\n ? dragged * direction\n : reduceMotion\n ? rest\n : withTiming(rest, timing),\n },\n ],\n }\n })\n const handleMotion = useAnimatedStyle(() => {\n 'worklet'\n return {\n backgroundColor: reduceMotion ? handle : withTiming(handle, timing),\n height: reduceMotion ? size : withTiming(size, timing),\n width: reduceMotion ? size : withTiming(size, timing),\n }\n })\n\n return { handle: handleMotion, seat, track }\n}\n\nexport { Switch }\nexport type { SwitchProps }\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { ValidationResult } from "../../form/index.js";
2
2
  import { FieldVariant } from "../../field/index.js";
3
3
  import { StyleProp, TextInput, TextInputProps, View, ViewStyle } from "react-native";
4
- import { ReactNode, Ref } from "react";
4
+ import { ComponentRef, ReactNode, Ref } from "react";
5
5
  //#region src/components/text-field/index.d.ts
6
6
  type TextFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityLabel' | 'aria-disabled' | 'aria-label' | 'children' | 'cursorColor' | 'defaultValue' | 'editable' | 'multiline' | 'numberOfLines' | 'onChange' | 'onChangeText' | 'placeholder' | 'placeholderTextColor' | 'readOnly' | 'selectionColor' | 'style' | 'underlineColorAndroid' | 'value'> & {
7
7
  /**
@@ -46,7 +46,7 @@ type TextFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityL
46
46
  * A ref to the field's own `TextInput`, which is what a call site moves
47
47
  * focus to, after a server's error, say. `ref` is the field as a whole.
48
48
  */
49
- readonly inputRef?: Ref<TextInput>;
49
+ readonly inputRef?: Ref<ComponentRef<typeof TextInput>>;
50
50
  /**
51
51
  * Draws the field disabled: it takes no focus and no input.
52
52
  * @default false
@@ -92,7 +92,7 @@ type TextFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityL
92
92
  * field is focused or holds a value.
93
93
  */
94
94
  readonly prefix?: ReactNode;
95
- readonly ref?: Ref<View>;
95
+ readonly ref?: Ref<ComponentRef<typeof View>>;
96
96
  /** Positions and sizes the field as a whole. */
97
97
  readonly style?: StyleProp<ViewStyle>;
98
98
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ReactNode","Ref","StyleProp","TextInput","TextInputProps","ViewStyle","useId","useImperativeHandle","useRef","useState","View","FieldVariant","ValidationResult","describedBy","FieldBox","FieldInput","FieldMessage","useFieldFocus","useFieldValidation","TextFieldProps","Omit","characterCount","characterLimitLabel","defaultValue","description","error","floatingLabel","inputRef","isDisabled","isReadOnly","isRequired","label","leadingIcon","name","numeric","onChange","value","prefix","ref","style","suffix","trailingIcon","validate","variant","blurThen","onBlur","then","event","editInto","setOwn","onEdit","text","TextField","t0","$","_c","t1","t2","t3","t4","t5","t6","t7","onFocus","t8","props","undefined","id","control","own","current","t9","t10","isEmpty","submitted","validation","t11","t12","focus","shownError","t13","t14","Symbol","for","T0","T1","t15","focused","t16","t17","T2","t18","handlers","t19","maxLength","t20","t21","t22","t23","t24","length","t25","_c"],"sources":["../../../src/components/text-field/index.tsx"],"sourcesContent":["import type { ReactNode, Ref } from 'react'\nimport type {\n StyleProp,\n TextInput,\n TextInputProps,\n ViewStyle,\n} from 'react-native'\n\nimport { useId, useImperativeHandle, useRef, useState } from 'react'\nimport { View } from 'react-native'\n\nimport type { FieldVariant } from '../../field'\nimport type { ValidationResult } from '../../form'\n\nimport {\n describedBy,\n FieldBox,\n FieldInput,\n FieldMessage,\n useFieldFocus,\n} from '../../field'\nimport { useFieldValidation } from '../../form'\n\n// kanso-ui's TextField, drawn through the field chrome in src/field: the box\n// with its label and icons, the control on the value's line with its prefix\n// and suffix, and the supporting line under it with the count. What the\n// chrome draws, and how it draws it, is written there.\n//\n// The value is the field's own or the call site's. Given `value` it shows\n// that and reports edits through `onChange`; given `defaultValue`, or\n// nothing, it keeps what is typed itself. `onChange` is handed the string, as\n// web's is, rather than React Native's event.\n//\n// **Web's `isInvalid` is not a prop here either.** The error is what puts the\n// field in its error state, the message and the colours and the invalid\n// state a screen reader reads following from it, so a field cannot be\n// invalid with nothing to say why. The error shown is `error`, or what the\n// field's `validate` and the `Form` around it say, which src/form decides.\n\ntype TextFieldProps = Omit<\n TextInputProps,\n | 'accessibilityHint'\n | 'accessibilityLabel'\n | 'aria-disabled'\n | 'aria-label'\n | 'children'\n | 'cursorColor'\n | 'defaultValue'\n | 'editable'\n | 'multiline'\n | 'numberOfLines'\n | 'onChange'\n | 'onChangeText'\n | 'placeholder'\n | 'placeholderTextColor'\n | 'readOnly'\n | 'selectionColor'\n | 'style'\n | 'underlineColorAndroid'\n | 'value'\n> & {\n /**\n * Counts the characters the field holds at the end of the supporting line,\n * against `maxLength` where there is one, as the text fields page's\n * character counter does. The count is written in the device's digits.\n * @default false\n */\n readonly characterCount?: boolean\n /**\n * How the limit is said to a screen reader, where there is a `maxLength`.\n * Read with the field rather than as the value changes, so it names the\n * limit and not what is left of it; the visible count is hidden from\n * screen readers, which is what this replaces. Left out, it is the English\n * sentence, \"Up to 20 characters\", singular for a limit of one.\n */\n readonly characterLimitLabel?: string\n /** The value the field opens with, when it keeps its own. */\n readonly defaultValue?: string\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n readonly description?: string\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state: the message, the error colours, and the\n * invalid state a screen reader reads all follow from it. The line under\n * the field arrives with the message, so the field grows when this does,\n * unless it is inside a `Form`, which keeps the line drawn. It wins over\n * what `validate` and the form say, and holds a `native` form back.\n */\n readonly error?: string\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, as the text fields page draws it.\n * `false` keeps it small at the top in every state.\n * @default true\n */\n readonly floatingLabel?: boolean\n /**\n * A ref to the field's own `TextInput`, which is what a call site moves\n * focus to, after a server's error, say. `ref` is the field as a whole.\n */\n readonly inputRef?: Ref<TextInput>\n /**\n * Draws the field disabled: it takes no focus and no input.\n * @default false\n */\n readonly isDisabled?: boolean\n /**\n * Shows the value and takes focus, but takes no input.\n * @default false\n */\n readonly isReadOnly?: 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 /**\n * What the field is for, and the name a screen reader reads for it.\n * Required, since a text field with no label is a box nobody can name.\n */\n readonly label: string\n /**\n * An icon at the start of the box, before the label and the value: the\n * page's 24dp leading icon, in the muted role. The slot hands it that\n * colour and size through `useIconStyle()`.\n */\n readonly leadingIcon?: ReactNode\n /**\n * The name the value is submitted under by the `Form` around the field,\n * and the key its `validationErrors` reach the field by.\n */\n readonly name?: string\n /**\n * Renders the value in the mono face with tabular figures, for amounts and\n * other numbers meant to be compared down a column.\n * @default false\n */\n readonly numeric?: boolean\n /** Called with the new value as it is edited. */\n readonly onChange?: (value: string) => void\n /**\n * Text before the value on its line, in the muted role, shown while the\n * field is focused or holds a value.\n */\n readonly prefix?: ReactNode\n readonly ref?: Ref<View>\n /** Positions and sizes the field as a whole. */\n readonly style?: StyleProp<ViewStyle>\n /**\n * Text after the value on its line, in the muted role, shown while the\n * field is focused or holds a value.\n */\n readonly suffix?: ReactNode\n /**\n * An icon at the end of the box, after the value: the page's 24dp trailing\n * icon, in the muted role and the error role while the field has an\n * error. The slot hands it that colour and size through `useIconStyle()`.\n */\n readonly trailingIcon?: ReactNode\n /**\n * Checks the value, and returns its problem in words, or several, where\n * there is one, and `true`, `null` or `undefined` where there is none.\n * Under the default `aria` validation the error shows as the value\n * changes; inside a `native` form it shows once a submission is tried, or\n * once the field loses focus after an edit, and holds the form back.\n */\n readonly validate?: (value: string) => ValidationResult\n /** The value, when the call site keeps it. */\n readonly value?: string\n /**\n * The filled box, or the outlined one: no fill, an outline that thickens\n * and takes the primary role while focused, and the label cutting it once\n * it floats, the text fields page's two fields.\n * @default 'filled'\n */\n readonly variant?: FieldVariant\n}\n\n// The field's own blur handling, then the call site's.\nfunction blurThen(\n onBlur: () => void,\n then: TextInputProps['onBlur'],\n): TextInputProps['onBlur'] {\n return (event) => {\n onBlur()\n then?.(event)\n }\n}\n\n// Keeps an edit as the field's own value and reports it, so a field the call\n// site controls is told and one it does not still shows what was typed, and\n// tells the field's validation it was edited.\nfunction editInto(\n setOwn: (value: string) => void,\n onChange: ((value: string) => void) | undefined,\n onEdit: () => void,\n) {\n return (text: string) => {\n setOwn(text)\n onEdit()\n onChange?.(text)\n }\n}\n\n/**\n * A labelled single-line input, the text fields page's filled or outlined\n * field. Pass `value` with `onChange` to control it, or `defaultValue` to let\n * it keep its own; `onChange` is handed the string.\n *\n * The page's configurations are props: `leadingIcon` and `trailingIcon` at\n * the box's ends, `prefix` and `suffix` on the value's line, and\n * `characterCount` opposite the supporting text, counting against\n * `maxLength`. React Native's own `TextInput` props, the keyboard and the\n * return key among them, reach the control; `style` and `ref` are the field\n * as a whole, and `inputRef` the control.\n *\n * ```tsx\n * <TextField label=\"Label\" description=\"Supporting line\" />\n * ```\n */\nfunction TextField({\n characterCount = false,\n characterLimitLabel,\n defaultValue = '',\n description,\n error,\n floatingLabel = true,\n inputRef,\n isDisabled = false,\n isReadOnly = false,\n isRequired = false,\n label,\n leadingIcon,\n name,\n numeric = false,\n onBlur,\n onChange,\n onFocus,\n prefix,\n ref,\n style,\n suffix,\n trailingIcon,\n validate,\n value,\n variant = 'filled',\n ...props\n}: TextFieldProps) {\n const id = useId()\n const control = useRef<TextInput>(null)\n const [own, setOwn] = useState(defaultValue)\n const current = value ?? own\n const validation = useFieldValidation({\n control,\n error,\n isDisabled,\n isEmpty: current === '',\n isReadOnly,\n isRequired,\n name,\n submitted: current,\n validate,\n value: current,\n })\n const focus = useFieldFocus({\n onBlur: blurThen(validation.onBlur, onBlur),\n onFocus,\n })\n const shownError = validation.error\n\n useImperativeHandle<null | TextInput, null | TextInput>(\n inputRef,\n () => control.current,\n [],\n )\n\n return (\n <View ref={ref} style={style}>\n <FieldBox\n control={control}\n floatingLabel={floatingLabel}\n isDisabled={isDisabled}\n isFocused={focus.focused}\n isInvalid={shownError !== undefined}\n isPopulated={current !== ''}\n isRequired={isRequired}\n label={label}\n leading={leadingIcon}\n trailing={trailingIcon}\n variant={variant}\n >\n <FieldInput\n {...props}\n {...focus.handlers}\n aria-label={label}\n described={describedBy(id, {\n characterLimitLabel,\n description,\n error: shownError,\n maxLength: props.maxLength,\n })}\n editable={!isDisabled && !isReadOnly}\n numeric={numeric}\n onChangeText={editInto(setOwn, onChange, validation.onEdit)}\n prefix={prefix}\n ref={control}\n suffix={suffix}\n value={current}\n />\n </FieldBox>\n <FieldMessage\n characterCount={characterCount}\n characterLimitLabel={characterLimitLabel}\n description={description}\n error={shownError}\n id={id}\n length={current.length}\n maxLength={props.maxLength}\n />\n </View>\n )\n}\n\nexport { TextField }\nexport type { TextFieldProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","StyleProp","TextInput","TextInputProps","ViewStyle","useId","useImperativeHandle","useRef","useState","View","FieldVariant","ValidationResult","describedBy","FieldBox","FieldInput","FieldMessage","useFieldFocus","useFieldValidation","TextFieldProps","Omit","characterCount","characterLimitLabel","defaultValue","description","error","floatingLabel","inputRef","isDisabled","isReadOnly","isRequired","label","leadingIcon","name","numeric","onChange","value","prefix","ref","style","suffix","trailingIcon","validate","variant","blurThen","onBlur","then","event","editInto","setOwn","onEdit","text","TextField","t0","$","_c","t1","t2","t3","t4","t5","t6","t7","onFocus","t8","props","undefined","id","control","own","current","t9","t10","isEmpty","submitted","validation","t11","t12","focus","shownError","t13","t14","Symbol","for","T0","T1","t15","focused","t16","t17","T2","t18","handlers","t19","maxLength","t20","t21","t22","t23","t24","length","t25","_c"],"sources":["../../../src/components/text-field/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n StyleProp,\n TextInput,\n TextInputProps,\n ViewStyle,\n} from 'react-native'\n\nimport { useId, useImperativeHandle, useRef, useState } from 'react'\nimport { View } from 'react-native'\n\nimport type { FieldVariant } from '../../field'\nimport type { ValidationResult } from '../../form'\n\nimport {\n describedBy,\n FieldBox,\n FieldInput,\n FieldMessage,\n useFieldFocus,\n} from '../../field'\nimport { useFieldValidation } from '../../form'\n\n// kanso-ui's TextField, drawn through the field chrome in src/field: the box\n// with its label and icons, the control on the value's line with its prefix\n// and suffix, and the supporting line under it with the count. What the\n// chrome draws, and how it draws it, is written there.\n//\n// The value is the field's own or the call site's. Given `value` it shows\n// that and reports edits through `onChange`; given `defaultValue`, or\n// nothing, it keeps what is typed itself. `onChange` is handed the string, as\n// web's is, rather than React Native's event.\n//\n// **Web's `isInvalid` is not a prop here either.** The error is what puts the\n// field in its error state, the message and the colours and the invalid\n// state a screen reader reads following from it, so a field cannot be\n// invalid with nothing to say why. The error shown is `error`, or what the\n// field's `validate` and the `Form` around it say, which src/form decides.\n\ntype TextFieldProps = Omit<\n TextInputProps,\n | 'accessibilityHint'\n | 'accessibilityLabel'\n | 'aria-disabled'\n | 'aria-label'\n | 'children'\n | 'cursorColor'\n | 'defaultValue'\n | 'editable'\n | 'multiline'\n | 'numberOfLines'\n | 'onChange'\n | 'onChangeText'\n | 'placeholder'\n | 'placeholderTextColor'\n | 'readOnly'\n | 'selectionColor'\n | 'style'\n | 'underlineColorAndroid'\n | 'value'\n> & {\n /**\n * Counts the characters the field holds at the end of the supporting line,\n * against `maxLength` where there is one, as the text fields page's\n * character counter does. The count is written in the device's digits.\n * @default false\n */\n readonly characterCount?: boolean\n /**\n * How the limit is said to a screen reader, where there is a `maxLength`.\n * Read with the field rather than as the value changes, so it names the\n * limit and not what is left of it; the visible count is hidden from\n * screen readers, which is what this replaces. Left out, it is the English\n * sentence, \"Up to 20 characters\", singular for a limit of one.\n */\n readonly characterLimitLabel?: string\n /** The value the field opens with, when it keeps its own. */\n readonly defaultValue?: string\n /**\n * A hint shown under the field. Replaced by `error` when there is one, so\n * the two never stack.\n */\n readonly description?: string\n /**\n * The problem with the current value, in words. Its presence is what puts\n * the field in its error state: the message, the error colours, and the\n * invalid state a screen reader reads all follow from it. The line under\n * the field arrives with the message, so the field grows when this does,\n * unless it is inside a `Form`, which keeps the line drawn. It wins over\n * what `validate` and the form say, and holds a `native` form back.\n */\n readonly error?: string\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, as the text fields page draws it.\n * `false` keeps it small at the top in every state.\n * @default true\n */\n readonly floatingLabel?: boolean\n /**\n * A ref to the field's own `TextInput`, which is what a call site moves\n * focus to, after a server's error, say. `ref` is the field as a whole.\n */\n readonly inputRef?: Ref<ComponentRef<typeof TextInput>>\n /**\n * Draws the field disabled: it takes no focus and no input.\n * @default false\n */\n readonly isDisabled?: boolean\n /**\n * Shows the value and takes focus, but takes no input.\n * @default false\n */\n readonly isReadOnly?: 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 /**\n * What the field is for, and the name a screen reader reads for it.\n * Required, since a text field with no label is a box nobody can name.\n */\n readonly label: string\n /**\n * An icon at the start of the box, before the label and the value: the\n * page's 24dp leading icon, in the muted role. The slot hands it that\n * colour and size through `useIconStyle()`.\n */\n readonly leadingIcon?: ReactNode\n /**\n * The name the value is submitted under by the `Form` around the field,\n * and the key its `validationErrors` reach the field by.\n */\n readonly name?: string\n /**\n * Renders the value in the mono face with tabular figures, for amounts and\n * other numbers meant to be compared down a column.\n * @default false\n */\n readonly numeric?: boolean\n /** Called with the new value as it is edited. */\n readonly onChange?: (value: string) => void\n /**\n * Text before the value on its line, in the muted role, shown while the\n * field is focused or holds a value.\n */\n readonly prefix?: ReactNode\n readonly ref?: Ref<ComponentRef<typeof View>>\n /** Positions and sizes the field as a whole. */\n readonly style?: StyleProp<ViewStyle>\n /**\n * Text after the value on its line, in the muted role, shown while the\n * field is focused or holds a value.\n */\n readonly suffix?: ReactNode\n /**\n * An icon at the end of the box, after the value: the page's 24dp trailing\n * icon, in the muted role and the error role while the field has an\n * error. The slot hands it that colour and size through `useIconStyle()`.\n */\n readonly trailingIcon?: ReactNode\n /**\n * Checks the value, and returns its problem in words, or several, where\n * there is one, and `true`, `null` or `undefined` where there is none.\n * Under the default `aria` validation the error shows as the value\n * changes; inside a `native` form it shows once a submission is tried, or\n * once the field loses focus after an edit, and holds the form back.\n */\n readonly validate?: (value: string) => ValidationResult\n /** The value, when the call site keeps it. */\n readonly value?: string\n /**\n * The filled box, or the outlined one: no fill, an outline that thickens\n * and takes the primary role while focused, and the label cutting it once\n * it floats, the text fields page's two fields.\n * @default 'filled'\n */\n readonly variant?: FieldVariant\n}\n\n// The field's own blur handling, then the call site's.\nfunction blurThen(\n onBlur: () => void,\n then: TextInputProps['onBlur'],\n): TextInputProps['onBlur'] {\n return (event) => {\n onBlur()\n then?.(event)\n }\n}\n\n// Keeps an edit as the field's own value and reports it, so a field the call\n// site controls is told and one it does not still shows what was typed, and\n// tells the field's validation it was edited.\nfunction editInto(\n setOwn: (value: string) => void,\n onChange: ((value: string) => void) | undefined,\n onEdit: () => void,\n) {\n return (text: string) => {\n setOwn(text)\n onEdit()\n onChange?.(text)\n }\n}\n\n/**\n * A labelled single-line input, the text fields page's filled or outlined\n * field. Pass `value` with `onChange` to control it, or `defaultValue` to let\n * it keep its own; `onChange` is handed the string.\n *\n * The page's configurations are props: `leadingIcon` and `trailingIcon` at\n * the box's ends, `prefix` and `suffix` on the value's line, and\n * `characterCount` opposite the supporting text, counting against\n * `maxLength`. React Native's own `TextInput` props, the keyboard and the\n * return key among them, reach the control; `style` and `ref` are the field\n * as a whole, and `inputRef` the control.\n *\n * ```tsx\n * <TextField label=\"Label\" description=\"Supporting line\" />\n * ```\n */\nfunction TextField({\n characterCount = false,\n characterLimitLabel,\n defaultValue = '',\n description,\n error,\n floatingLabel = true,\n inputRef,\n isDisabled = false,\n isReadOnly = false,\n isRequired = false,\n label,\n leadingIcon,\n name,\n numeric = false,\n onBlur,\n onChange,\n onFocus,\n prefix,\n ref,\n style,\n suffix,\n trailingIcon,\n validate,\n value,\n variant = 'filled',\n ...props\n}: TextFieldProps) {\n const id = useId()\n const control = useRef<ComponentRef<typeof TextInput>>(null)\n const [own, setOwn] = useState(defaultValue)\n const current = value ?? own\n const validation = useFieldValidation({\n control,\n error,\n isDisabled,\n isEmpty: current === '',\n isReadOnly,\n isRequired,\n name,\n submitted: current,\n validate,\n value: current,\n })\n const focus = useFieldFocus({\n onBlur: blurThen(validation.onBlur, onBlur),\n onFocus,\n })\n const shownError = validation.error\n\n useImperativeHandle<\n ComponentRef<typeof TextInput> | null,\n ComponentRef<typeof TextInput> | null\n >(inputRef, () => control.current, [])\n\n return (\n <View ref={ref} style={style}>\n <FieldBox\n control={control}\n floatingLabel={floatingLabel}\n isDisabled={isDisabled}\n isFocused={focus.focused}\n isInvalid={shownError !== undefined}\n isPopulated={current !== ''}\n isRequired={isRequired}\n label={label}\n leading={leadingIcon}\n trailing={trailingIcon}\n variant={variant}\n >\n <FieldInput\n {...props}\n {...focus.handlers}\n aria-label={label}\n described={describedBy(id, {\n characterLimitLabel,\n description,\n error: shownError,\n maxLength: props.maxLength,\n })}\n editable={!isDisabled && !isReadOnly}\n numeric={numeric}\n onChangeText={editInto(setOwn, onChange, validation.onEdit)}\n prefix={prefix}\n ref={control}\n suffix={suffix}\n value={current}\n />\n </FieldBox>\n <FieldMessage\n characterCount={characterCount}\n characterLimitLabel={characterLimitLabel}\n description={description}\n error={shownError}\n id={id}\n length={current.length}\n maxLength={props.maxLength}\n />\n </View>\n )\n}\n\nexport { TextField }\nexport type { TextFieldProps }\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { StyleProp, TextInput, TextInputProps, ViewStyle } from "react-native";
2
- import { ReactNode, Ref } from "react";
2
+ import { ComponentRef, ReactNode, Ref } from "react";
3
3
  import "react-native-reanimated";
4
4
  //#region src/field/index.d.ts
5
5
  /**