@kanso-labs/react-native-kanso-ui 0.0.0-stage → 0.1.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 (145) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +205 -2
  3. package/dist/button/index.d.ts +56 -0
  4. package/dist/button/index.js +169 -0
  5. package/dist/button/index.js.map +1 -0
  6. package/dist/button/palettes.js +47 -0
  7. package/dist/button/palettes.js.map +1 -0
  8. package/dist/chip/index.js +194 -0
  9. package/dist/chip/index.js.map +1 -0
  10. package/dist/chip/styles.js +36 -0
  11. package/dist/chip/styles.js.map +1 -0
  12. package/dist/clipboard/index.js +58 -0
  13. package/dist/clipboard/index.js.map +1 -0
  14. package/dist/components/avatar/index.d.ts +82 -0
  15. package/dist/components/avatar/index.js +62 -0
  16. package/dist/components/avatar/index.js.map +1 -0
  17. package/dist/components/button/index.d.ts +87 -0
  18. package/dist/components/button/index.js +377 -0
  19. package/dist/components/button/index.js.map +1 -0
  20. package/dist/components/card/index.d.ts +78 -0
  21. package/dist/components/card/index.js +315 -0
  22. package/dist/components/card/index.js.map +1 -0
  23. package/dist/components/checkbox/index.d.ts +76 -0
  24. package/dist/components/checkbox/index.js +360 -0
  25. package/dist/components/checkbox/index.js.map +1 -0
  26. package/dist/components/chip/index.d.ts +84 -0
  27. package/dist/components/chip/index.js +257 -0
  28. package/dist/components/chip/index.js.map +1 -0
  29. package/dist/components/chip-group/index.d.ts +143 -0
  30. package/dist/components/chip-group/index.js +669 -0
  31. package/dist/components/chip-group/index.js.map +1 -0
  32. package/dist/components/copy-field/index.d.ts +60 -0
  33. package/dist/components/copy-field/index.js +277 -0
  34. package/dist/components/copy-field/index.js.map +1 -0
  35. package/dist/components/currency/index.d.ts +69 -0
  36. package/dist/components/currency/index.js +162 -0
  37. package/dist/components/currency/index.js.map +1 -0
  38. package/dist/components/form/index.d.ts +84 -0
  39. package/dist/components/form/index.js +95 -0
  40. package/dist/components/form/index.js.map +1 -0
  41. package/dist/components/icon-button/index.d.ts +68 -0
  42. package/dist/components/icon-button/index.js +289 -0
  43. package/dist/components/icon-button/index.js.map +1 -0
  44. package/dist/components/link/index.d.ts +59 -0
  45. package/dist/components/link/index.js +191 -0
  46. package/dist/components/link/index.js.map +1 -0
  47. package/dist/components/number-field/index.d.ts +151 -0
  48. package/dist/components/number-field/index.js +832 -0
  49. package/dist/components/number-field/index.js.map +1 -0
  50. package/dist/components/product-icon/index.d.ts +70 -0
  51. package/dist/components/product-icon/index.js +60 -0
  52. package/dist/components/product-icon/index.js.map +1 -0
  53. package/dist/components/radio-group/index.d.ts +105 -0
  54. package/dist/components/radio-group/index.js +597 -0
  55. package/dist/components/radio-group/index.js.map +1 -0
  56. package/dist/components/search-field/index.d.ts +98 -0
  57. package/dist/components/search-field/index.js +521 -0
  58. package/dist/components/search-field/index.js.map +1 -0
  59. package/dist/components/segmented-button/index.d.ts +113 -0
  60. package/dist/components/segmented-button/index.js +937 -0
  61. package/dist/components/segmented-button/index.js.map +1 -0
  62. package/dist/components/separator/index.d.ts +45 -0
  63. package/dist/components/separator/index.js +109 -0
  64. package/dist/components/separator/index.js.map +1 -0
  65. package/dist/components/stack/index.d.ts +70 -0
  66. package/dist/components/stack/index.js +107 -0
  67. package/dist/components/stack/index.js.map +1 -0
  68. package/dist/components/switch/index.d.ts +76 -0
  69. package/dist/components/switch/index.js +591 -0
  70. package/dist/components/switch/index.js.map +1 -0
  71. package/dist/components/text/index.d.ts +44 -0
  72. package/dist/components/text/index.js +78 -0
  73. package/dist/components/text/index.js.map +1 -0
  74. package/dist/components/text-field/index.d.ts +146 -0
  75. package/dist/components/text-field/index.js +228 -0
  76. package/dist/components/text-field/index.js.map +1 -0
  77. package/dist/control/index.js +117 -0
  78. package/dist/control/index.js.map +1 -0
  79. package/dist/control/styles.js +36 -0
  80. package/dist/control/styles.js.map +1 -0
  81. package/dist/field/index.d.ts +13 -0
  82. package/dist/field/index.js +1007 -0
  83. package/dist/field/index.js.map +1 -0
  84. package/dist/field/styles.js +131 -0
  85. package/dist/field/styles.js.map +1 -0
  86. package/dist/form/index.d.ts +24 -0
  87. package/dist/form/index.js +209 -0
  88. package/dist/form/index.js.map +1 -0
  89. package/dist/glyphs/icon-style.d.ts +25 -0
  90. package/dist/glyphs/icon-style.js +22 -0
  91. package/dist/glyphs/icon-style.js.map +1 -0
  92. package/dist/glyphs/index.js +170 -0
  93. package/dist/glyphs/index.js.map +1 -0
  94. package/dist/glyphs/styles.js +7 -0
  95. package/dist/glyphs/styles.js.map +1 -0
  96. package/dist/hooks/useWindowSizeClass.d.ts +25 -0
  97. package/dist/hooks/useWindowSizeClass.js +39 -0
  98. package/dist/hooks/useWindowSizeClass.js.map +1 -0
  99. package/dist/index.d.ts +31 -0
  100. package/dist/index.js +27 -0
  101. package/dist/mark/image.js +61 -0
  102. package/dist/mark/image.js.map +1 -0
  103. package/dist/mark/index.d.ts +9 -0
  104. package/dist/mark/index.js +234 -0
  105. package/dist/mark/index.js.map +1 -0
  106. package/dist/mark/initials.js +65 -0
  107. package/dist/mark/initials.js.map +1 -0
  108. package/dist/mark/styles.d.ts +1 -0
  109. package/dist/mark/styles.js +73 -0
  110. package/dist/mark/styles.js.map +1 -0
  111. package/dist/number/parser.js +321 -0
  112. package/dist/number/parser.js.map +1 -0
  113. package/dist/number/state.js +235 -0
  114. package/dist/number/state.js.map +1 -0
  115. package/dist/overlay/host.js +111 -0
  116. package/dist/overlay/host.js.map +1 -0
  117. package/dist/press/index.js +350 -0
  118. package/dist/press/index.js.map +1 -0
  119. package/dist/press/styles.js +31 -0
  120. package/dist/press/styles.js.map +1 -0
  121. package/dist/router/index.d.ts +28 -0
  122. package/dist/router/index.js +82 -0
  123. package/dist/router/index.js.map +1 -0
  124. package/dist/theme/color.js +25 -0
  125. package/dist/theme/color.js.map +1 -0
  126. package/dist/theme/resolve.d.ts +6 -0
  127. package/dist/theme/resolve.js +310 -0
  128. package/dist/theme/resolve.js.map +1 -0
  129. package/dist/theme/scope.d.ts +42 -0
  130. package/dist/theme/scope.js +80 -0
  131. package/dist/theme/scope.js.map +1 -0
  132. package/dist/theme/styles.js +39 -0
  133. package/dist/theme/styles.js.map +1 -0
  134. package/dist/theme-scope.d.ts +56 -0
  135. package/dist/theme-scope.js +127 -0
  136. package/dist/theme-scope.js.map +1 -0
  137. package/dist/tokens/defaults.d.ts +407 -0
  138. package/dist/tokens/defaults.js +403 -0
  139. package/dist/tokens/defaults.js.map +1 -0
  140. package/dist/typography/fonts.js +84 -0
  141. package/dist/typography/fonts.js.map +1 -0
  142. package/dist/typography/roles.d.ts +10 -0
  143. package/dist/typography/roles.js +82 -0
  144. package/dist/typography/roles.js.map +1 -0
  145. package/package.json +132 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ReactElement","ReactNode","Ref","GestureResponderEvent","Insets","PressableProps","StyleProp","TextStyle","ViewProps","ViewStyle","AnimatedStyle","Key","Node","Selection","SelectionMode","ListProps","ListState","useId","useState","Text","NativeText","Platform","Pressable","StyleSheet","View","Animated","useListState","AnimatedPressable","toggleState","ChipGlyph","ChipLabel","measureThen","paintOf","targetOf","useEasedColors","GLYPH_SIZE","RULE_WIDTH","stylesOf","CloseGlyph","TARGET_SIZE","usePressFeedback","useTheme","composeStyles","themedStyles","useTypeRole","ChipGroupChipProps","Omit","children","icon","id","isDisabled","ref","style","textValue","ChipGroupProps","item","T","defaultSelectedKeys","Iterable","description","disabledKeys","disallowEmptySelection","error","items","label","onRemove","keys","Set","onSelectionChange","removeLabel","renderEmptyState","selectedKeys","selectionMode","REMOVE_REACH","bottom","left","right","top","styles","create","chip","maxWidth","layer","position","groupStylesOf","colors","radii","sizing","spacing","stateLayerOpacity","color","onSurfaceVariant","labelError","list","alignItems","flexDirection","flexWrap","gap","sm","minHeight","controlXs","message","messageError","messageLine","marginTop","xs","removable","paddingEnd","lg","remove","borderRadius","circle","end","height","justifyContent","width","removeHovered","opacity","hover","removeLayer","removePressed","pressed","root","rowGap","ChipGroup","t0","$","_c","props","t1","t2","undefined","theme","t3","t4","state","labelId","messageId","labelRole","messageRole","t5","own","invalid","t6","collection","nodes","t7","lineOf","t8","length","map","node","key","ChipGroupChip","_props","getCollectionNode","hasChildNodes","rendered","type","GroupChip","hitSlop","onBlur","onFocus","onHoverIn","onHoverOut","onLayout","onPress","onPressIn","onPressOut","_id","_isDisabled","t9","t10","t11","t12","_textValue","t13","setWidth","selectionManager","selectable","selected","isSelected","assist","disabled","elevated","paint","eased","corners","feedback","container","ring","pill","glyph","content","target","handlers","selectThen","removeThen","OS","RemoveButton","disableRipple","T0","T1","hovered","ringOf","backgroundColor","outlineColor","outlineOffset","outlineStyle","outlineWidth","event","select","Chip","_c","NativeText"],"sources":["../../../src/components/chip-group/index.tsx"],"sourcesContent":["import type { ReactElement, ReactNode, Ref } from 'react'\nimport type {\n GestureResponderEvent,\n Insets,\n PressableProps,\n StyleProp,\n TextStyle,\n ViewProps,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\nimport type { Key, Node, Selection, SelectionMode } from 'react-stately'\nimport type { ListProps, ListState } from 'react-stately/useListState'\n\nimport { useId, useState } from 'react'\nimport {\n Text as NativeText,\n Platform,\n Pressable,\n StyleSheet,\n View,\n} from 'react-native'\nimport Animated from 'react-native-reanimated'\nimport { useListState } from 'react-stately/useListState'\n\nimport { AnimatedPressable, toggleState } from '../../button'\nimport {\n ChipGlyph,\n ChipLabel,\n measureThen,\n paintOf,\n targetOf,\n useEasedColors,\n} from '../../chip'\nimport { GLYPH_SIZE, RULE_WIDTH, stylesOf } from '../../chip/styles'\nimport { CloseGlyph } from '../../glyphs'\nimport { TARGET_SIZE, usePressFeedback } from '../../press'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// The chips page's filter and input chips as a set, as kanso-ui's ChipGroup\n// draws them: one or more chosen from a row that wraps, each one removable.\n// The pill is src/chip's, shared with Chip, so the two cannot drift; what is\n// here is the group around them.\n//\n// **Selection is the group's, not each chip's.** It is React Stately's\n// `useListState`, as web's is React Aria's, so `selectionMode`,\n// `selectedKeys`, `defaultSelectedKeys`, `onSelectionChange` and\n// `disabledKeys` behave as they do there. A press on a chip selects it, or\n// clears it if it was selected; in a group that selects one, a press on\n// another moves the selection there. A chip in a group that selects nothing is\n// not a button at all, since a press there would change nothing.\n//\n// **A chip can be removed.** Give the group `onRemove` and each chip draws the\n// page's trailing close glyph, an 18dp glyph in the label's colour, in a\n// target of its own so a press there removes rather than selects. It is a\n// sibling of the chip's own button rather than a child, laid over the pill's\n// end: VoiceOver reaches nothing inside a button, so a close target inside one\n// could never be focused. Its target is WCAG's 24dp, as on web, since the chip\n// around it is no spacing to lean on when the group selects. It draws its\n// hover and pressed layers in the label's colour, and on focus from a key a\n// 2dp ring in the same colour, 1dp out, as web's does: a second ring in the\n// focus role inside a chip would read as two focus treatments for one focus.\n//\n// The label, the line under the chips and the gaps between them are the\n// field chrome's, as RadioGroup draws them: the label in label large and on\n// surface variant, or error while the group has one; the chips 8dp apart and\n// wrapping, from the start edge, so from the right under a right-to-left\n// layout; and the line under them in body small, 4dp further down. The row\n// keeps a chip's height while it is empty, so removing the last chip leaves\n// what sits under the group where it was.\n//\n// Three departures from web. Arrow keys do not move between the chips, and\n// Backspace and Delete do not remove one: each chip and each close target is\n// a stop of its own for a hardware keyboard. The close target is named\n// `Remove` and the chip's text in English unless `removeLabel` says\n// otherwise, where web's follows the reader's locale. And the close glyph\n// takes the label's colour at once rather than easing with it, as the check\n// does.\n\ntype ChipGroupChipProps = Omit<\n PressableProps,\n 'children' | 'disabled' | 'id' | 'style'\n> & {\n /** The chip's label. */\n readonly children: ReactNode\n /**\n * An icon before the label, in the page's 18dp slot and the primary role,\n * which the slot hands it through `useIconStyle()`. The check takes its\n * place while the chip is chosen, so the chip keeps its width.\n */\n readonly icon?: ReactNode\n /**\n * The key selection and removal report the chip by. Without one, a chip\n * drawn from `items` takes its item's `id` or `key`.\n */\n readonly id?: Key\n /**\n * Draws the chip disabled, and takes no presses on it or on its close\n * target, as a key in the group's `disabledKeys` does.\n * @default false\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<View>\n readonly style?: StyleProp<ViewStyle>\n /**\n * The chip's text, which names its close target. Read off `children` when\n * they are a plain string, so a chip whose label is an element passes it.\n */\n readonly textValue?: string\n}\n\ntype ChipGroupProps<T extends object = object> = Omit<\n ViewProps,\n 'children' | 'style'\n> & {\n /**\n * The chips, each a `ChipGroup.Chip` with an `id` of its own. With\n * `items`, a function from an item to its chip, called for each item in\n * turn.\n */\n readonly children?: ((item: T) => ReactElement) | ReactNode\n /** The keys selected at first, when the group keeps its own selection. */\n readonly defaultSelectedKeys?: 'all' | Iterable<Key>\n /**\n * A hint under the group. Replaced by `error` when there is one, so the\n * two never stack.\n */\n readonly description?: string\n /** The keys of the chips drawn disabled, which take no presses. */\n readonly disabledKeys?: Iterable<Key>\n /**\n * Keeps the last selected chip selected, so a press on it changes\n * nothing.\n * @default false\n */\n readonly disallowEmptySelection?: boolean\n /**\n * The problem with the current selection, in words. Its presence is what\n * puts the group in its error state: the message and the label's colour\n * both follow from it.\n */\n readonly error?: string\n /** The entries `children` draws a chip for, when it is a function. */\n readonly items?: Iterable<T>\n /**\n * What the group is for. Required rather than optional: a set of chips\n * with no name is a row a screen reader cannot introduce.\n */\n readonly label: string\n /**\n * Called with the key of the chip whose close target was pressed. Given\n * this, every chip draws one; the call site removes the chip from what it\n * renders.\n */\n readonly onRemove?: (keys: Set<Key>) => void\n /** Called with the selected keys whenever a press changes them. */\n readonly onSelectionChange?: (keys: Selection) => void\n readonly ref?: Ref<View>\n /**\n * What the close target on each chip is called, for a screen reader. The\n * chip's own text follows it, so this is the verb rather than the whole\n * phrase: \"Remove\" becomes \"Remove First item\".\n * @default 'Remove'\n */\n readonly removeLabel?: string\n /** What the row draws once it holds no chips. */\n readonly renderEmptyState?: () => ReactNode\n /**\n * The selected keys, for a call site holding the selection itself with\n * `onSelectionChange`.\n */\n readonly selectedKeys?: 'all' | Iterable<Key>\n /**\n * Whether a press selects a chip: one at a time, several, or none, in\n * which case the chips are not buttons.\n * @default 'none'\n */\n readonly selectionMode?: SelectionMode\n readonly style?: StyleProp<ViewStyle>\n}\n\n// The close target reaches 3dp past its 18dp glyph on every side, which is\n// WCAG's 24dp.\nconst REMOVE_REACH: Insets = { bottom: 3, left: 3, right: 3, top: 3 }\n\nconst styles = StyleSheet.create({\n // Holds the pill and the close target laid over it, and is never wider\n // than the row, so the pill inside has a width to cut its label at.\n chip: {\n maxWidth: '100%',\n },\n layer: {\n bottom: 0,\n left: 0,\n position: 'absolute',\n right: 0,\n top: 0,\n },\n})\n\nconst groupStylesOf = themedStyles(\n ({ colors, radii, sizing, spacing, stateLayerOpacity }) =>\n StyleSheet.create({\n label: {\n color: colors.onSurfaceVariant,\n },\n labelError: {\n color: colors.error,\n },\n // The chips, 8dp apart and wrapping rather than running off the end,\n // since a set is read all at once. A chip's height while empty.\n list: {\n alignItems: 'center',\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: spacing.sm,\n minHeight: sizing.controlXs,\n },\n message: {\n color: colors.onSurfaceVariant,\n },\n messageError: {\n color: colors.error,\n },\n messageLine: {\n marginTop: spacing.xs,\n },\n // A removable pill leaves room at its end for the close target, its 8dp\n // gap before it and the 8dp the page pads after it.\n removable: {\n paddingEnd: spacing.lg + GLYPH_SIZE,\n },\n // The close target, over the pill's end, where the pill's own padding\n // would end: the page pads 8dp on the side the glyph is on, and the\n // label keeps the chip's 8dp gap before it.\n remove: {\n alignItems: 'center',\n borderRadius: radii.circle,\n end: RULE_WIDTH + spacing.lg - spacing.sm,\n height: GLYPH_SIZE,\n justifyContent: 'center',\n marginTop: -GLYPH_SIZE / 2,\n position: 'absolute',\n top: '50%',\n width: GLYPH_SIZE,\n },\n removeHovered: {\n opacity: stateLayerOpacity.hover,\n },\n removeLayer: {\n borderRadius: radii.circle,\n opacity: 0,\n },\n removePressed: {\n opacity: stateLayerOpacity.pressed,\n },\n root: {\n flexDirection: 'column',\n rowGap: spacing.xs,\n },\n }),\n)\n\n/**\n * A labelled set of chips, one or more of which can be chosen, each of which\n * can be removed. Selection is React Stately's: set `selectionMode` to\n * `single` or `multiple`, and pass `selectedKeys` with `onSelectionChange` to\n * control it, or `defaultSelectedKeys` to let the group keep its own.\n *\n * ```tsx\n * <ChipGroup label=\"Label\" onRemove={remove} selectionMode=\"multiple\">\n * <ChipGroup.Chip id=\"first\">First item</ChipGroup.Chip>\n * </ChipGroup>\n * ```\n *\n * Give the group `onRemove` and each chip draws a close target. A chip that\n * toggles nothing else is Chip; this is for a set that shares a value.\n *\n * A screen reader hears a group named by its label, and each chip as a button\n * named by its label, selected or not. On the web the line under the group\n * describes it, as web's does; on iOS and Android it is read after the chips,\n * where it sits. `style`, `ref` and `testID` land on the group as a whole,\n * which is the element a layout positions.\n */\nfunction ChipGroup<T extends object = object>({\n children,\n defaultSelectedKeys,\n description,\n disabledKeys,\n disallowEmptySelection,\n error,\n items,\n label,\n onRemove,\n onSelectionChange,\n removeLabel = 'Remove',\n renderEmptyState,\n selectedKeys,\n selectionMode = 'none',\n style,\n ...props\n}: ChipGroupProps<T>) {\n const theme = useTheme()\n const state = useListState<T>({\n // Each chip builds its own entry in the collection; see\n // `ChipGroupChip.getCollectionNode`. The collection skips what is not an\n // element, as a ReactNode may be, and asks any element for its entry.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- see above\n children: children as ListProps<T>['children'],\n defaultSelectedKeys,\n disabledKeys,\n disallowEmptySelection,\n items,\n onSelectionChange,\n selectedKeys,\n selectionMode,\n })\n const labelId = useId()\n const messageId = useId()\n const labelRole = useTypeRole('labelLarge')\n const messageRole = useTypeRole('bodySmall')\n\n const own = groupStylesOf(theme)\n const invalid = error !== undefined\n const message = error ?? description\n const nodes = [...state.collection]\n\n return (\n <View\n {...props}\n aria-labelledby={labelId}\n role=\"group\"\n {...lineOf(messageId, message)}\n style={composeStyles<ViewStyle>(own.root, style)}\n >\n <NativeText\n id={labelId}\n style={composeStyles<TextStyle>(\n labelRole,\n own.label,\n invalid ? own.labelError : undefined,\n )}\n >\n {label}\n </NativeText>\n <View style={own.list}>\n {nodes.length === 0\n ? renderEmptyState?.()\n : nodes.map((node) => (\n <GroupChip\n key={node.key}\n node={node}\n onRemove={onRemove}\n removeLabel={removeLabel}\n state={state}\n />\n ))}\n </View>\n {message === undefined ? null : (\n <View style={own.messageLine}>\n <NativeText\n id={messageId}\n style={composeStyles<TextStyle>(\n messageRole,\n own.message,\n invalid ? own.messageError : undefined,\n )}\n >\n {message}\n </NativeText>\n </View>\n )}\n </View>\n )\n}\n\n/**\n * One chip of a `ChipGroup`, which draws it: the group builds its set from\n * these, so one renders nothing on its own. Give every chip an `id`, which is\n * the key selection and removal report it by.\n */\nfunction ChipGroupChip(_props: ChipGroupChipProps): null {\n return null\n}\n\n// The entry the group's collection holds for a chip, as React Stately's own\n// `Item` gives one: keyed by the chip's `id`, and carrying the props the group\n// draws it from.\nChipGroupChip.getCollectionNode = function* getCollectionNode(\n props: ChipGroupChipProps,\n) {\n yield {\n 'aria-label': props['aria-label'],\n hasChildNodes: false,\n key: props.id,\n props,\n rendered: props.children,\n textValue:\n props.textValue ??\n (typeof props.children === 'string' ? props.children : ''),\n type: 'item',\n }\n}\n\n/**\n * A chip as the group draws it, from its entry in the collection: the pill,\n * which is a button while the group selects, and the close target over its\n * end while the group removes.\n */\nfunction GroupChip<T>({\n node,\n onRemove,\n removeLabel,\n state,\n}: {\n readonly node: Node<T>\n readonly onRemove: ((keys: Set<Key>) => void) | undefined\n readonly removeLabel: string\n readonly state: ListState<T>\n}) {\n const theme = useTheme()\n // A node carries the props its chip was written with, which\n // `getCollectionNode` puts there and React Stately types as `any`.\n // oxlint-disable-next-line typescript/no-unsafe-assignment -- see above\n const {\n children,\n hitSlop,\n icon,\n id: _id,\n isDisabled: _isDisabled,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onLayout,\n onPress,\n onPressIn,\n onPressOut,\n style,\n textValue: _textValue,\n ...props\n }: ChipGroupChipProps = node.props\n // Until the chip is measured it takes no reach across, rather than one\n // sized for a chip of no width.\n const [width, setWidth] = useState(TARGET_SIZE)\n\n const { selectionManager } = state\n // The selection manager reads a chip's own `isDisabled` off its node, beside\n // the group's `disabledKeys`, so it answers for both.\n const isDisabled = selectionManager.isDisabled(node.key)\n const selectable = selectionManager.selectionMode !== 'none'\n const selected = selectionManager.isSelected(node.key)\n const paint = paintOf(theme, {\n assist: false,\n disabled: isDisabled,\n elevated: false,\n selected,\n })\n const eased = useEasedColors(paint)\n\n const feedback = usePressFeedback({\n color: paint.layer,\n corners: { borderRadius: theme.radii.sm },\n disabled: isDisabled,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n })\n\n const pill = composeStyles<AnimatedStyle<ViewStyle>>(\n stylesOf(theme).pill,\n eased.container,\n onRemove === undefined ? undefined : groupStylesOf(theme).removable,\n feedback.ring,\n style,\n )\n const content = (\n <>\n {selectable ? feedback.layer : null}\n <ChipGlyph color={paint.glyph} icon={icon} selected={selected} />\n <ChipLabel color={eased.label}>{children}</ChipLabel>\n </>\n )\n const target = hitSlop ?? targetOf(width, theme)\n\n return (\n // The view holding the two takes the chip's target too: iOS and Android\n // hand a touch to a view only once its parent has taken it.\n <View hitSlop={selectable ? target : undefined} style={styles.chip}>\n {selectable ? (\n <AnimatedPressable\n role=\"button\"\n {...toggleState(selected)}\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n hitSlop={target}\n onLayout={measureThen(setWidth, onLayout)}\n onPress={selectThen(state, node.key, onPress)}\n style={pill}\n >\n {content}\n </AnimatedPressable>\n ) : (\n // A press here changes nothing, so the chip is a view, and takes the\n // props a view has; a press handler among them is never called.\n <Animated.View\n {...props}\n aria-disabled={isDisabled}\n onLayout={onLayout ?? undefined}\n style={pill}\n >\n {content}\n </Animated.View>\n )}\n {onRemove === undefined ? null : (\n <RemoveButton\n color={paint.content}\n isDisabled={isDisabled}\n label={\n node.textValue === ''\n ? removeLabel\n : `${removeLabel} ${node.textValue}`\n }\n onPress={removeThen(onRemove, node.key)}\n />\n )}\n </View>\n )\n}\n\n/**\n * How the group is described by the line under it. On the web it points at\n * the line with `aria-describedby`, as web's group does. iOS and Android\n * focus the chips rather than the group, so there the line is left where a\n * screen reader reaches it in order, after the last chip.\n */\nfunction lineOf(id: string, message: string | undefined) {\n return Platform.OS === 'web' && message !== undefined\n ? { 'aria-describedby': id }\n : undefined\n}\n\n/**\n * A chip's close target: the close glyph in the label's colour, with a hover\n * and a pressed layer of its own and a ring for focus from a key, as the\n * header sets out.\n */\nfunction RemoveButton({\n color,\n isDisabled,\n label,\n onPress,\n}: {\n readonly color: string\n readonly isDisabled: boolean\n readonly label: string\n readonly onPress: () => void\n}) {\n const theme = useTheme()\n const feedback = usePressFeedback({\n color,\n disabled: isDisabled,\n disableRipple: true,\n })\n const own = groupStylesOf(theme)\n\n return (\n <Pressable\n aria-label={label}\n role=\"button\"\n {...feedback.handlers}\n disabled={isDisabled}\n hitSlop={REMOVE_REACH}\n onPress={onPress}\n style={composeStyles<ViewStyle>(\n own.remove,\n feedback.ring === undefined ? undefined : ringOf(color),\n )}\n >\n <View\n style={composeStyles<ViewStyle>(\n styles.layer,\n own.removeLayer,\n { backgroundColor: color },\n feedback.hovered ? own.removeHovered : undefined,\n feedback.pressed ? own.removePressed : undefined,\n )}\n />\n <CloseGlyph color={color} size={GLYPH_SIZE} />\n </Pressable>\n )\n}\n\n// What a press on a chip's close target reports. 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\n// result on its inputs.\nfunction removeThen(onRemove: (keys: Set<Key>) => void, key: Key) {\n return () => {\n onRemove(new Set([key]))\n }\n}\n\n// The close target's ring: 2dp in the label's colour, 1dp out, as web's.\nfunction ringOf(color: string): ViewStyle {\n return {\n outlineColor: color,\n outlineOffset: 1,\n outlineStyle: 'solid',\n outlineWidth: 2,\n }\n}\n\n// A press on a chip: the call site's own `onPress`, then the selection,\n// which selects the chip, or clears it if it was selected and the group\n// allows that.\nfunction selectThen<T>(\n state: ListState<T>,\n key: Key,\n onPress: ((event: GestureResponderEvent) => void) | null | undefined,\n) {\n return (event: GestureResponderEvent) => {\n onPress?.(event)\n state.selectionManager.select(key)\n }\n}\n\nChipGroup.Chip = ChipGroupChip\n\nexport { ChipGroup, ChipGroupChip }\nexport type { ChipGroupChipProps, ChipGroupProps }\n"],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { View, ViewProps } from "react-native";
2
+ import { Ref } from "react";
3
+ //#region src/components/copy-field/index.d.ts
4
+ type CopyFieldProps = Omit<ViewProps, 'children'> & {
5
+ /**
6
+ * What the button says once the value has been copied, and what is
7
+ * announced. It reverts to `copyLabel` on its own after a couple of
8
+ * seconds.
9
+ * @default 'Copied'
10
+ */
11
+ readonly copiedLabel?: string;
12
+ /**
13
+ * What the button says at rest.
14
+ * @default 'Copy'
15
+ */
16
+ readonly copyLabel?: string;
17
+ /**
18
+ * What the value is, such as "Repository URL" or "Access token", for a
19
+ * screen with more than one field. It names the field as a group and joins
20
+ * the button's name, so a screen reader hears "Copy Repository URL" rather
21
+ * than one "Copy" after another; it is not shown. The value itself stays
22
+ * out of the button's name, since a token would be read aloud. Left out,
23
+ * the button is "Copy" alone.
24
+ */
25
+ readonly label?: string;
26
+ /**
27
+ * Called with the value after it reaches the clipboard, never before.
28
+ * Named as web's is, where the root's own `onCopy` is taken.
29
+ */
30
+ readonly onCopied?: (value: string) => void;
31
+ /**
32
+ * Called with the error when the value did not reach the clipboard: under
33
+ * React Native Web, where the browser refuses the write, and anywhere
34
+ * expo-clipboard turns out not to be installed after a press. Nothing is
35
+ * announced and the button keeps offering the copy, so this is for an app
36
+ * that wants to say more, in a snackbar say.
37
+ */
38
+ readonly onCopyFailed?: (error: unknown) => void;
39
+ readonly ref?: Ref<View>;
40
+ /** The text shown, and the text copied. */
41
+ readonly value: string;
42
+ };
43
+ /**
44
+ * A value to be read and taken away, such as a repository URL, a token or a
45
+ * command. It shows the value in the mono face and copies it on request,
46
+ * confirming on the button itself and to a screen reader.
47
+ *
48
+ * ```tsx
49
+ * <CopyField label="Access token" value="first.second.third" />
50
+ * ```
51
+ *
52
+ * The copy goes through expo-clipboard, which an app installs alongside the
53
+ * library. Without it the field shows the value and no button.
54
+ *
55
+ * `style`, `ref` and `testID` land on the box.
56
+ */
57
+ declare function CopyField({ copiedLabel, copyLabel, label, onCopied, onCopyFailed, style, value, ...props }: CopyFieldProps): import("react").JSX.Element;
58
+ //#endregion
59
+ export { CopyField, type CopyFieldProps };
60
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,277 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
3
+ import { useFontFamily } from "../../typography/fonts.js";
4
+ import { useTypeRole } from "../../typography/roles.js";
5
+ import { Button } from "../button/index.js";
6
+ import { useClipboardAvailable, writeClipboard } from "../../clipboard/index.js";
7
+ import { c } from "react/compiler-runtime";
8
+ import { AccessibilityInfo, Platform, StyleSheet, Text, View } from "react-native";
9
+ import { useEffect, useRef, useState } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ //#region src/components/copy-field/index.tsx
12
+ const COPIED_RESET_MS = 2e3;
13
+ const RESERVE = {
14
+ accessibilityElementsHidden: true,
15
+ "aria-hidden": true,
16
+ importantForAccessibility: "no-hide-descendants"
17
+ };
18
+ const ATOMIC = { "aria-atomic": true };
19
+ const styles = StyleSheet.create({
20
+ announcement: {
21
+ height: 1,
22
+ opacity: 0,
23
+ overflow: "hidden",
24
+ pointerEvents: "none",
25
+ position: "absolute",
26
+ width: 1
27
+ },
28
+ button: { alignSelf: "stretch" },
29
+ reserve: {
30
+ alignItems: "center",
31
+ height: 0,
32
+ overflow: "hidden"
33
+ }
34
+ });
35
+ const stylesOf = themedStyles(({ colors, radii, spacing }) => StyleSheet.create({
36
+ reserve: { paddingHorizontal: spacing.md },
37
+ root: {
38
+ alignItems: "center",
39
+ backgroundColor: colors.surface,
40
+ borderColor: colors.outline,
41
+ borderRadius: radii.sm,
42
+ borderWidth: 1,
43
+ flexDirection: "row",
44
+ gap: spacing.sm,
45
+ paddingHorizontal: spacing.md,
46
+ paddingVertical: spacing.xs
47
+ },
48
+ value: {
49
+ alignItems: "flex-start",
50
+ flex: 1,
51
+ minWidth: 0
52
+ },
53
+ valueText: {
54
+ color: colors.onSurface,
55
+ fontVariant: [
56
+ "no-common-ligatures",
57
+ "no-contextual",
58
+ "no-discretionary-ligatures",
59
+ "no-historical-ligatures"
60
+ ],
61
+ userSelect: "all",
62
+ writingDirection: "ltr"
63
+ }
64
+ }));
65
+ /**
66
+ * A value to be read and taken away, such as a repository URL, a token or a
67
+ * command. It shows the value in the mono face and copies it on request,
68
+ * confirming on the button itself and to a screen reader.
69
+ *
70
+ * ```tsx
71
+ * <CopyField label="Access token" value="first.second.third" />
72
+ * ```
73
+ *
74
+ * The copy goes through expo-clipboard, which an app installs alongside the
75
+ * library. Without it the field shows the value and no button.
76
+ *
77
+ * `style`, `ref` and `testID` land on the box.
78
+ */
79
+ function CopyField(t0) {
80
+ const $ = c(20);
81
+ let label;
82
+ let onCopied;
83
+ let onCopyFailed;
84
+ let props;
85
+ let style;
86
+ let t1;
87
+ let t2;
88
+ let value;
89
+ if ($[0] !== t0) {
90
+ ({copiedLabel: t1, copyLabel: t2, label, onCopied, onCopyFailed, style, value, ...props} = t0);
91
+ $[0] = t0;
92
+ $[1] = label;
93
+ $[2] = onCopied;
94
+ $[3] = onCopyFailed;
95
+ $[4] = props;
96
+ $[5] = style;
97
+ $[6] = t1;
98
+ $[7] = t2;
99
+ $[8] = value;
100
+ } else {
101
+ label = $[1];
102
+ onCopied = $[2];
103
+ onCopyFailed = $[3];
104
+ props = $[4];
105
+ style = $[5];
106
+ t1 = $[6];
107
+ t2 = $[7];
108
+ value = $[8];
109
+ }
110
+ const copiedLabel = t1 === void 0 ? "Copied" : t1;
111
+ const copyLabel = t2 === void 0 ? "Copy" : t2;
112
+ const theme = useTheme();
113
+ const themed = stylesOf(theme);
114
+ const bodySmall = useTypeRole("bodySmall");
115
+ const labelLarge = useTypeRole("labelLarge");
116
+ const mono = useFontFamily(theme.typography.fontFamilyMono);
117
+ const available = useClipboardAvailable();
118
+ let t3;
119
+ if ($[9] !== copiedLabel || $[10] !== onCopied || $[11] !== onCopyFailed || $[12] !== value) {
120
+ t3 = {
121
+ copiedLabel,
122
+ onCopied,
123
+ onCopyFailed,
124
+ value
125
+ };
126
+ $[9] = copiedLabel;
127
+ $[10] = onCopied;
128
+ $[11] = onCopyFailed;
129
+ $[12] = value;
130
+ $[13] = t3;
131
+ } else t3 = $[13];
132
+ const { confirmation, onPress } = useCopy(t3);
133
+ const copied = confirmation !== void 0;
134
+ const shown = copied ? copiedLabel : copyLabel;
135
+ let t4;
136
+ if ($[14] !== label) {
137
+ t4 = label === void 0 ? void 0 : { "aria-label": label };
138
+ $[14] = label;
139
+ $[15] = t4;
140
+ } else t4 = $[15];
141
+ let t5;
142
+ if ($[16] !== confirmation || $[17] !== copied || $[18] !== copiedLabel) {
143
+ t5 = Platform.OS === "web" ? /* @__PURE__ */ jsx(View, {
144
+ "aria-live": "polite",
145
+ ...ATOMIC,
146
+ style: styles.announcement,
147
+ children: copied ? /* @__PURE__ */ jsx(Text, { children: copiedLabel }, confirmation) : null
148
+ }) : null;
149
+ $[16] = confirmation;
150
+ $[17] = copied;
151
+ $[18] = copiedLabel;
152
+ $[19] = t5;
153
+ } else t5 = $[19];
154
+ return /* @__PURE__ */ jsxs(View, {
155
+ ...t4,
156
+ role: label === void 0 ? void 0 : "group",
157
+ ...props,
158
+ style: composeStyles(themed.root, style),
159
+ children: [
160
+ /* @__PURE__ */ jsx(View, {
161
+ style: themed.value,
162
+ children: /* @__PURE__ */ jsx(Text, {
163
+ style: composeStyles(bodySmall, themed.valueText, { fontFamily: mono }),
164
+ children: value
165
+ })
166
+ }),
167
+ available ? /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(Button, {
168
+ "aria-label": label === void 0 ? void 0 : `${shown} ${label}`,
169
+ onPress,
170
+ size: "xs",
171
+ style: styles.button,
172
+ variant: "text",
173
+ children: shown
174
+ }), /* @__PURE__ */ jsxs(View, {
175
+ ...RESERVE,
176
+ style: composeStyles(styles.reserve, themed.reserve),
177
+ children: [/* @__PURE__ */ jsx(Text, {
178
+ style: labelLarge,
179
+ children: copyLabel
180
+ }), /* @__PURE__ */ jsx(Text, {
181
+ style: labelLarge,
182
+ children: copiedLabel
183
+ })]
184
+ })] }) : null,
185
+ t5
186
+ ]
187
+ });
188
+ }
189
+ /**
190
+ * Hands the call site the value it copied. What its handler throws is raised
191
+ * on its own, outside the copy, as a throw from a press handler is, so it
192
+ * reaches the app's error reporting rather than rejecting a promise nothing
193
+ * awaits, which React Native reports nowhere in a release build.
194
+ */
195
+ function reportCopied(onCopied, value) {
196
+ if (onCopied === void 0) return;
197
+ try {
198
+ onCopied(value);
199
+ } catch (thrown) {
200
+ setTimeout(() => {
201
+ throw thrown;
202
+ }, 0);
203
+ }
204
+ }
205
+ /**
206
+ * Copies the value on press and holds the confirmation for the dwell.
207
+ * `confirmation` counts the copies while the button says Copied, and is
208
+ * `undefined` otherwise.
209
+ */
210
+ function useCopy(t0) {
211
+ const $ = c(13);
212
+ const { copiedLabel, onCopied, onCopyFailed, value } = t0;
213
+ const [copy, setCopy] = useState(null);
214
+ const timer = useRef(void 0);
215
+ let t1;
216
+ let t2;
217
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
218
+ t1 = () => () => {
219
+ clearTimeout(timer.current);
220
+ };
221
+ t2 = [];
222
+ $[0] = t1;
223
+ $[1] = t2;
224
+ } else {
225
+ t1 = $[0];
226
+ t2 = $[1];
227
+ }
228
+ useEffect(t1, t2);
229
+ let t3;
230
+ if ($[2] !== copiedLabel || $[3] !== onCopied || $[4] !== value) {
231
+ t3 = () => {
232
+ clearTimeout(timer.current);
233
+ timer.current = setTimeout(() => {
234
+ setCopy(null);
235
+ }, COPIED_RESET_MS);
236
+ setCopy((current) => ({
237
+ count: (current?.count ?? 0) + 1,
238
+ text: value
239
+ }));
240
+ if (Platform.OS === "ios" || Platform.OS === "android") AccessibilityInfo.announceForAccessibility(copiedLabel);
241
+ reportCopied(onCopied, value);
242
+ };
243
+ $[2] = copiedLabel;
244
+ $[3] = onCopied;
245
+ $[4] = value;
246
+ $[5] = t3;
247
+ } else t3 = $[5];
248
+ const confirm = t3;
249
+ const t4 = copy?.text === value ? copy.count : void 0;
250
+ let t5;
251
+ if ($[6] !== confirm || $[7] !== onCopyFailed || $[8] !== value) {
252
+ t5 = () => {
253
+ writeClipboard(value).then(confirm, (error) => {
254
+ onCopyFailed?.(error);
255
+ });
256
+ };
257
+ $[6] = confirm;
258
+ $[7] = onCopyFailed;
259
+ $[8] = value;
260
+ $[9] = t5;
261
+ } else t5 = $[9];
262
+ let t6;
263
+ if ($[10] !== t4 || $[11] !== t5) {
264
+ t6 = {
265
+ confirmation: t4,
266
+ onPress: t5
267
+ };
268
+ $[10] = t4;
269
+ $[11] = t5;
270
+ $[12] = t6;
271
+ } else t6 = $[12];
272
+ return t6;
273
+ }
274
+ //#endregion
275
+ export { CopyField };
276
+
277
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["Ref","TextStyle","ViewProps","ViewStyle","useEffect","useRef","useState","AccessibilityInfo","Text","NativeText","Platform","StyleSheet","View","useClipboardAvailable","writeClipboard","useTheme","composeStyles","themedStyles","useFontFamily","useTypeRole","Button","COPIED_RESET_MS","RESERVE","accessibilityElementsHidden","importantForAccessibility","ATOMIC","const","styles","create","announcement","height","opacity","overflow","pointerEvents","position","width","button","alignSelf","reserve","alignItems","stylesOf","colors","radii","spacing","paddingHorizontal","md","root","backgroundColor","surface","borderColor","outline","borderRadius","sm","borderWidth","flexDirection","gap","paddingVertical","xs","value","flex","minWidth","valueText","color","onSurface","fontVariant","userSelect","writingDirection","CopyFieldProps","Omit","copiedLabel","copyLabel","label","onCopied","onCopyFailed","error","ref","CopyField","t0","$","_c","props","style","t1","t2","undefined","theme","themed","bodySmall","labelLarge","mono","typography","fontFamilyMono","available","t3","confirmation","onPress","useCopy","copied","shown","t4","t5","OS","fontFamily","reportCopied","thrown","setTimeout","copy","setCopy","timer","Symbol","for","clearTimeout","current","count","text","announceForAccessibility","confirm","then","t6","_c","NativeText"],"sources":["../../../src/components/copy-field/index.tsx"],"sourcesContent":["import type { Ref } from 'react'\nimport type { TextStyle, ViewProps, ViewStyle } from 'react-native'\n\nimport { useEffect, useRef, useState } from 'react'\nimport {\n AccessibilityInfo,\n Text as NativeText,\n Platform,\n StyleSheet,\n View,\n} from 'react-native'\n\nimport { useClipboardAvailable, writeClipboard } from '../../clipboard'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useFontFamily } from '../../typography/fonts'\nimport { useTypeRole } from '../../typography/roles'\nimport { Button } from '../button'\n\n// No Material Design page draws a read-only value with a copy control, so it\n// follows the outlined text field, as kanso-ui's CopyField does: the 1dp rule\n// in the outline role, the surface behind it, and the control at its end. The\n// value is body small beside a 32dp text button, so the box is shorter than\n// the field's 56, which suits a value that is read rather than edited, and\n// its corner is the shape scale's small step for the same reason. The box has\n// no height of its own: it is the button's, or the value's once that is\n// taller, so a larger OS text size grows it rather than running the value out\n// of it.\n//\n// The copy goes through expo-clipboard, an optional peer. In an app without\n// it the field shows the value and no button, since a button that could not\n// copy would be one that lies about what it does.\n\n// How long the confirmation stands before the button offers the copy again,\n// as on web: long enough to be read without leaving the button lying about\n// what it will do.\nconst COPIED_RESET_MS = 2000\n\n// The two labels the button is as wide as: laid out at no height, and kept\n// from a screen reader.\nconst RESERVE: ViewProps = {\n accessibilityElementsHidden: true,\n 'aria-hidden': true,\n importantForAccessibility: 'no-hide-descendants',\n}\n\n// What a web-only atomic live region adds, so a confirmation is read whole.\n// React Native's types carry no `aria-atomic`, which React Native Web takes.\nconst ATOMIC = { 'aria-atomic': true } as const\n\nconst styles = StyleSheet.create({\n // Under React Native Web the confirmation is said through a live region, as\n // web's `<output>` says it, which is drawn nowhere and still read.\n announcement: {\n height: 1,\n opacity: 0,\n overflow: 'hidden',\n pointerEvents: 'none',\n position: 'absolute',\n width: 1,\n },\n // The button stretches to the width the column takes, which is the wider of\n // the two labels below it, so a copy swaps the label rather than resizing\n // the button. The button sits at the end of the row, so a width that grew\n // on press would move it under the finger that had just pressed it.\n button: {\n alignSelf: 'stretch',\n },\n // Holds both labels for their width alone.\n reserve: {\n alignItems: 'center',\n height: 0,\n overflow: 'hidden',\n },\n})\n\nconst stylesOf = themedStyles(({ colors, radii, spacing }) =>\n StyleSheet.create({\n // The button's own label padding at `xs`, so the reserve is exactly as\n // wide as the button drawing the wider label.\n reserve: {\n paddingHorizontal: spacing.md,\n },\n root: {\n alignItems: 'center',\n backgroundColor: colors.surface,\n borderColor: colors.outline,\n borderRadius: radii.sm,\n borderWidth: 1,\n flexDirection: 'row',\n gap: spacing.sm,\n paddingHorizontal: spacing.md,\n paddingVertical: spacing.xs,\n },\n // The column the value sits in, beside the button. `minWidth: 0` lets a\n // long unbroken value wrap rather than push the button out of the box.\n // The value keeps to the column's start, which is its left, or its right\n // in a right-to-left layout.\n value: {\n alignItems: 'flex-start',\n flex: 1,\n minWidth: 0,\n },\n // The value in the mono face at the body small role, where a `0` and an\n // `O`, an `l`, a `1` and an `I` have to be told apart, with ligatures off\n // so what shows is each character that is copied. It reads left to right\n // whatever the layout's direction, since it is a literal: a path, a flag\n // or a command whose leading `/`, `--` or `$` would otherwise move to the\n // other end. iOS and React Native Web take `writingDirection`; Android\n // takes the direction of the value's first letter, which is the value's\n // own. Under React Native Web one click selects the whole value, which is\n // what someone copying it by hand wants, and on iOS and Android a long\n // press offers the platform's own copy.\n valueText: {\n color: colors.onSurface,\n fontVariant: [\n 'no-common-ligatures',\n 'no-contextual',\n 'no-discretionary-ligatures',\n 'no-historical-ligatures',\n ],\n userSelect: 'all',\n writingDirection: 'ltr',\n },\n }),\n)\n\ntype CopyFieldProps = Omit<ViewProps, 'children'> & {\n /**\n * What the button says once the value has been copied, and what is\n * announced. It reverts to `copyLabel` on its own after a couple of\n * seconds.\n * @default 'Copied'\n */\n readonly copiedLabel?: string\n /**\n * What the button says at rest.\n * @default 'Copy'\n */\n readonly copyLabel?: string\n /**\n * What the value is, such as \"Repository URL\" or \"Access token\", for a\n * screen with more than one field. It names the field as a group and joins\n * the button's name, so a screen reader hears \"Copy Repository URL\" rather\n * than one \"Copy\" after another; it is not shown. The value itself stays\n * out of the button's name, since a token would be read aloud. Left out,\n * the button is \"Copy\" alone.\n */\n readonly label?: string\n /**\n * Called with the value after it reaches the clipboard, never before.\n * Named as web's is, where the root's own `onCopy` is taken.\n */\n readonly onCopied?: (value: string) => void\n /**\n * Called with the error when the value did not reach the clipboard: under\n * React Native Web, where the browser refuses the write, and anywhere\n * expo-clipboard turns out not to be installed after a press. Nothing is\n * announced and the button keeps offering the copy, so this is for an app\n * that wants to say more, in a snackbar say.\n */\n readonly onCopyFailed?: (error: unknown) => void\n readonly ref?: Ref<View>\n /** The text shown, and the text copied. */\n readonly value: string\n}\n\n/**\n * A value to be read and taken away, such as a repository URL, a token or a\n * command. It shows the value in the mono face and copies it on request,\n * confirming on the button itself and to a screen reader.\n *\n * ```tsx\n * <CopyField label=\"Access token\" value=\"first.second.third\" />\n * ```\n *\n * The copy goes through expo-clipboard, which an app installs alongside the\n * library. Without it the field shows the value and no button.\n *\n * `style`, `ref` and `testID` land on the box.\n */\nfunction CopyField({\n copiedLabel = 'Copied',\n copyLabel = 'Copy',\n label,\n onCopied,\n onCopyFailed,\n style,\n value,\n ...props\n}: CopyFieldProps) {\n const theme = useTheme()\n const themed = stylesOf(theme)\n const bodySmall = useTypeRole('bodySmall')\n const labelLarge = useTypeRole('labelLarge')\n const mono = useFontFamily(theme.typography.fontFamilyMono)\n const available = useClipboardAvailable()\n const { confirmation, onPress } = useCopy({\n copiedLabel,\n onCopied,\n onCopyFailed,\n value,\n })\n const copied = confirmation !== undefined\n const shown = copied ? copiedLabel : copyLabel\n\n return (\n <View\n {...(label === undefined ? undefined : { 'aria-label': label })}\n role={label === undefined ? undefined : 'group'}\n {...props}\n style={composeStyles<ViewStyle>(themed.root, style)}\n >\n <View style={themed.value}>\n <NativeText\n style={composeStyles<TextStyle>(bodySmall, themed.valueText, {\n fontFamily: mono,\n })}\n >\n {value}\n </NativeText>\n </View>\n {available ? (\n <View>\n <Button\n aria-label={label === undefined ? undefined : `${shown} ${label}`}\n onPress={onPress}\n size=\"xs\"\n style={styles.button}\n variant=\"text\"\n >\n {shown}\n </Button>\n <View\n {...RESERVE}\n style={composeStyles<ViewStyle>(styles.reserve, themed.reserve)}\n >\n <NativeText style={labelLarge}>{copyLabel}</NativeText>\n <NativeText style={labelLarge}>{copiedLabel}</NativeText>\n </View>\n </View>\n ) : null}\n {Platform.OS === 'web' ? (\n <View aria-live=\"polite\" {...ATOMIC} style={styles.announcement}>\n {copied ? (\n <NativeText key={confirmation}>{copiedLabel}</NativeText>\n ) : null}\n </View>\n ) : null}\n </View>\n )\n}\n\n/**\n * Hands the call site the value it copied. What its handler throws is raised\n * on its own, outside the copy, as a throw from a press handler is, so it\n * reaches the app's error reporting rather than rejecting a promise nothing\n * awaits, which React Native reports nowhere in a release build.\n */\nfunction reportCopied(\n onCopied: ((value: string) => void) | undefined,\n value: string,\n) {\n if (onCopied === undefined) {\n return\n }\n\n try {\n onCopied(value)\n } catch (thrown) {\n setTimeout(() => {\n throw thrown\n }, 0)\n }\n}\n\n/**\n * Copies the value on press and holds the confirmation for the dwell.\n * `confirmation` counts the copies while the button says Copied, and is\n * `undefined` otherwise.\n */\nfunction useCopy({\n copiedLabel,\n onCopied,\n onCopyFailed,\n value,\n}: {\n readonly copiedLabel: string\n readonly onCopied: ((value: string) => void) | undefined\n readonly onCopyFailed: ((error: unknown) => void) | undefined\n readonly value: string\n}) {\n // What the last copy put on the clipboard, and how many copies there have\n // been. The confirmation is that text still being the value shown, so a\n // value that changes inside the dwell, a token regenerated say, takes the\n // label back to the copy at once rather than confirming a copy of something\n // else. The count gives each confirmation its own node in the live region,\n // so a second copy inside the dwell is said again.\n const [copy, setCopy] = useState<null | {\n readonly count: number\n readonly text: string\n }>(null)\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n\n // Without this, a field unmounted inside the dwell leaves a timer holding a\n // state update for a tree that is gone.\n useEffect(\n () => () => {\n clearTimeout(timer.current)\n },\n [],\n )\n\n // The field's own state first, the dwell and the announcement included, and\n // the call site's handler after it, so a handler that throws cannot leave\n // the button on Copied for good.\n const confirm = () => {\n clearTimeout(timer.current)\n timer.current = setTimeout(() => {\n setCopy(null)\n }, COPIED_RESET_MS)\n setCopy((current) => ({\n count: (current?.count ?? 0) + 1,\n text: value,\n }))\n\n // VoiceOver and TalkBack stay on the button, and a label changing under\n // them is not reliably read, so the confirmation is said outright. Under\n // React Native Web the field's live region says it.\n if (Platform.OS === 'ios' || Platform.OS === 'android') {\n AccessibilityInfo.announceForAccessibility(copiedLabel)\n }\n\n reportCopied(onCopied, value)\n }\n\n return {\n confirmation: copy?.text === value ? copy.count : undefined,\n onPress: () => {\n void writeClipboard(value).then(confirm, (error: unknown) => {\n onCopyFailed?.(error)\n })\n },\n }\n}\n\nexport { CopyField }\nexport type { CopyFieldProps }\n"],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { Text, TextProps } from "react-native";
2
+ import { ComponentRef, Ref } from "react";
3
+ //#region src/components/currency/index.d.ts
4
+ type CurrencyProps = Omit<TextProps, 'children'> & {
5
+ /**
6
+ * ISO 4217 code for the currency to format in.
7
+ * @default 'USD'
8
+ */
9
+ readonly currency?: string;
10
+ /**
11
+ * BCP 47 locale to format for. Defaults to the device's, which is the one
12
+ * the runtime formats in when it is handed none.
13
+ */
14
+ readonly locale?: string;
15
+ readonly ref?: Ref<ComponentRef<typeof Text>>;
16
+ /**
17
+ * When to show the sign. `auto` shows one only on negatives, `always` also
18
+ * prefixes positives with a plus, and `never` shows neither, which leaves
19
+ * colour as the only thing separating a credit from a debt, so reach for it
20
+ * only where the direction is already stated some other way.
21
+ *
22
+ * An amount that shows as zero carries no sign under any of them, since
23
+ * there is nothing owed or owing: `-0.004` reads `$0.00`, not `−$0.00`.
24
+ * @default 'auto'
25
+ */
26
+ readonly sign?: CurrencySignDisplay;
27
+ /**
28
+ * Which colour role to render in. `auto` follows the sign of the amount as
29
+ * it is shown, so one that rounds to zero, float residue or a fraction of a
30
+ * cent, reads as neutral rather than as a gain or a debt.
31
+ *
32
+ * The positive and negative roles are guaranteed legible on the surface
33
+ * family, which is what the library's own tokens and every demo scheme are
34
+ * held to. Over a container of its own, such as a filled card, the pair is
35
+ * one colour family on top of another and is not guaranteed, so a custom
36
+ * theme placing one there has to check that pair itself.
37
+ * @default 'auto'
38
+ */
39
+ readonly tone?: CurrencyTone;
40
+ /** The amount, in the currency's major units. */
41
+ readonly value: number;
42
+ };
43
+ type CurrencySignDisplay = 'always' | 'auto' | 'never';
44
+ type CurrencyTone = 'auto' | 'negative' | 'neutral' | 'positive';
45
+ /**
46
+ * An amount of money, formatted for the reader's locale in the mono face with
47
+ * tabular figures, so a column of amounts lines up on the decimal point.
48
+ * Negatives carry a true minus sign, and the tone follows the sign unless
49
+ * `tone` names one.
50
+ *
51
+ * ```tsx
52
+ * <Text variant="bodyLarge">
53
+ * <Currency currency="EUR" value={-42.5} />
54
+ * </Text>
55
+ * ```
56
+ *
57
+ * It sets no size of its own, so it takes the type of the Text around it:
58
+ * put it in one, a heading-scale one for a larger figure. On its own it draws
59
+ * at the platform's default size. The face is the mono family's first, once
60
+ * the app has registered it with expo-font, and the system font until then,
61
+ * with tabular figures either way.
62
+ *
63
+ * Web's `render` has no counterpart. `style`, `ref` and `testID` land on React
64
+ * Native's own Text.
65
+ */
66
+ declare function Currency({ currency, locale, sign, style, tone, value, ...props }: CurrencyProps): import("react").JSX.Element;
67
+ //#endregion
68
+ export { Currency, type CurrencyProps, type CurrencySignDisplay, type CurrencyTone };
69
+ //# sourceMappingURL=index.d.ts.map