@kanso-labs/react-native-kanso-ui 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/button/index.d.ts +32 -2
  2. package/dist/button/index.js +38 -26
  3. package/dist/button/index.js.map +1 -1
  4. package/dist/button/pending.js +144 -0
  5. package/dist/button/pending.js.map +1 -0
  6. package/dist/button/slots.js +7 -0
  7. package/dist/button/slots.js.map +1 -0
  8. package/dist/components/avatar/index.d.ts +2 -2
  9. package/dist/components/avatar/index.js.map +1 -1
  10. package/dist/components/button/index.d.ts +3 -3
  11. package/dist/components/button/index.js +159 -111
  12. package/dist/components/button/index.js.map +1 -1
  13. package/dist/components/card/index.d.ts +2 -2
  14. package/dist/components/card/index.js.map +1 -1
  15. package/dist/components/checkbox/index.d.ts +2 -2
  16. package/dist/components/checkbox/index.js.map +1 -1
  17. package/dist/components/chip/index.d.ts +2 -2
  18. package/dist/components/chip/index.js.map +1 -1
  19. package/dist/components/chip-group/index.d.ts +3 -3
  20. package/dist/components/chip-group/index.js.map +1 -1
  21. package/dist/components/copy-field/index.d.ts +2 -2
  22. package/dist/components/copy-field/index.js.map +1 -1
  23. package/dist/components/dialog/index.d.ts +131 -0
  24. package/dist/components/dialog/index.js +861 -0
  25. package/dist/components/dialog/index.js.map +1 -0
  26. package/dist/components/icon-button/index.d.ts +3 -3
  27. package/dist/components/icon-button/index.js +165 -109
  28. package/dist/components/icon-button/index.js.map +1 -1
  29. package/dist/components/link/index.js +1 -1
  30. package/dist/components/link/index.js.map +1 -1
  31. package/dist/components/meter/index.d.ts +73 -0
  32. package/dist/components/meter/index.js +179 -0
  33. package/dist/components/meter/index.js.map +1 -0
  34. package/dist/components/number-field/index.d.ts +3 -3
  35. package/dist/components/number-field/index.js +1 -9
  36. package/dist/components/number-field/index.js.map +1 -1
  37. package/dist/components/product-icon/index.d.ts +2 -2
  38. package/dist/components/product-icon/index.js.map +1 -1
  39. package/dist/components/progress-indicator/index.d.ts +113 -0
  40. package/dist/components/progress-indicator/index.js +1024 -0
  41. package/dist/components/progress-indicator/index.js.map +1 -0
  42. package/dist/components/radio-group/index.d.ts +3 -3
  43. package/dist/components/radio-group/index.js.map +1 -1
  44. package/dist/components/search-field/index.d.ts +3 -3
  45. package/dist/components/search-field/index.js.map +1 -1
  46. package/dist/components/segmented-button/index.d.ts +3 -3
  47. package/dist/components/segmented-button/index.js.map +1 -1
  48. package/dist/components/snackbar/index.d.ts +120 -0
  49. package/dist/components/snackbar/index.js +540 -0
  50. package/dist/components/snackbar/index.js.map +1 -0
  51. package/dist/components/switch/index.d.ts +2 -2
  52. package/dist/components/switch/index.js.map +1 -1
  53. package/dist/components/text-field/index.d.ts +3 -3
  54. package/dist/components/text-field/index.js.map +1 -1
  55. package/dist/field/index.d.ts +1 -1
  56. package/dist/field/index.js.map +1 -1
  57. package/dist/form/index.d.ts +1 -1
  58. package/dist/form/index.js.map +1 -1
  59. package/dist/glyphs/hidden.js +13 -0
  60. package/dist/glyphs/hidden.js.map +1 -0
  61. package/dist/glyphs/index.js +2 -8
  62. package/dist/glyphs/index.js.map +1 -1
  63. package/dist/i18n/index.js +23 -0
  64. package/dist/i18n/index.js.map +1 -0
  65. package/dist/i18n/messages.js +41 -0
  66. package/dist/i18n/messages.js.map +1 -0
  67. package/dist/index.d.ts +5 -1
  68. package/dist/index.js +7 -3
  69. package/dist/indicator/index.d.ts +15 -0
  70. package/dist/indicator/index.js +256 -0
  71. package/dist/indicator/index.js.map +1 -0
  72. package/dist/indicator/motion.js +86 -0
  73. package/dist/indicator/motion.js.map +1 -0
  74. package/dist/indicator/paths.js +72 -0
  75. package/dist/indicator/paths.js.map +1 -0
  76. package/dist/indicator/styles.js +62 -0
  77. package/dist/indicator/styles.js.map +1 -0
  78. package/dist/mark/index.d.ts +1 -1
  79. package/dist/mark/index.js.map +1 -1
  80. package/dist/number/locale.js +14 -0
  81. package/dist/number/locale.js.map +1 -0
  82. package/dist/overlay/host.js +65 -2
  83. package/dist/overlay/host.js.map +1 -1
  84. package/dist/press/index.js +63 -63
  85. package/dist/press/index.js.map +1 -1
  86. package/dist/theme/resolve.js +1 -1
  87. package/dist/theme/resolve.js.map +1 -1
  88. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ComponentRef","Ref","TextProps","NativeTextProps","TextStyle","useState","Text","NativeText","Platform","StyleSheet","stylesOf","ringStylesOf","useLinkPress","withOpacity","useTheme","composeStyles","themedStyles","LinkProps","Omit","href","isDisabled","ref","tone","LinkTone","underline","LinkUnderline","WebProps","focusable","onBlur","onFocus","event","currentTarget","matches","selector","onKeyDown","click","key","repeat","onPointerEnter","pointerType","onPointerLeave","underlines","create","always","textDecorationLine","hover","none","colors","radii","stateLayerOpacity","disabledContent","onSurface","base","borderRadius","xs","disabled","color","textDecorationColor","hovered","primary","inherit","outline","Link","t0","$","_c","onPress","props","style","t1","t2","t3","t4","suppressHighlighting","undefined","theme","press","hoveredState","setHovered","ringShown","setRingShown","T0","t10","t5","t6","t7","t8","t9","styles","pressable","t11","OS","webPropsOf","web","ring","shown","_c","NativeText","ringStylesOf"],"sources":["../../../src/components/link/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { TextProps as NativeTextProps, TextStyle } from 'react-native'\n\nimport { useState } from 'react'\nimport { Text as NativeText, Platform, StyleSheet } from 'react-native'\n\nimport { stylesOf as ringStylesOf } from '../../press/styles'\nimport { useLinkPress } from '../../router'\nimport { withOpacity } from '../../theme/color'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\n\n// No Material Design page draws an inline link, so this takes web's reading:\n// the text button's label, the primary role on no container, with the\n// disabled treatment every page gives content, and a rule under it to say it\n// can be followed. That rule is 70% of the primary role, or the outline role\n// under `inherit`, and turns fully primary under a pointer. 70% is web's\n// figure, the least that keeps the rule at 3:1 against the surface in every\n// scheme the library is shown in.\n//\n// It is a nested Text, so it sets no type of its own and takes the size and\n// face of the sentence around it, as web's takes them from its paragraph. A\n// nested Text has no frame of its own, so it takes no `hitSlop` either.\n//\n// Where it departs from web, the platform is the reason:\n//\n// - The disabled colour is on-surface at the `disabledContent` opacity,\n// translucent over whatever the sentence sits on. Web mixes the two over\n// the surface role, and React Native has no `color-mix()`.\n// - Android draws the rule in the text's own colour, since it has no\n// `textDecorationColor`, and every platform draws it at its own thickness\n// and offset, which React Native has no properties for.\n// - Hover, the focus ring and the Enter key are the web's alone: a phone has\n// no pointer to hover with and focuses no span inside a sentence, so on\n// native `hover` draws no rule at all. The colour changes at once rather\n// than over a transition.\n// - iOS's own pressed highlight is off, since web's link draws no pressed\n// state; `suppressHighlighting={false}` turns it back on.\n\ntype LinkProps = Omit<NativeTextProps, 'disabled'> & {\n /**\n * Where the link leads. A press opens it through the `RouterProvider`\n * around the link, or through the platform for a URL with a scheme of its\n * own, after the call site's own `onPress`.\n */\n readonly href?: string\n /**\n * Fades the link to the disabled content colour, and takes no press. It is\n * still announced as a link, a disabled one.\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof NativeText>>\n /**\n * Which colour role to render in. `primary` marks the link out from the\n * text around it; `inherit` takes the colour of the Text around it and\n * leans on the underline alone, for a link in a place already understood\n * to be links, such as a footer.\n * @default 'primary'\n */\n readonly tone?: LinkTone\n /**\n * When to draw the rule. Leave it at `always` in prose: without it, colour\n * is the only thing separating the link from the sentence, which some\n * readers cannot see. `hover` and `none` are for links whose position\n * already announces them, such as a row of footer links. A phone has no\n * pointer, so `hover` draws no rule there.\n * @default 'always'\n */\n readonly underline?: LinkUnderline\n}\n\ntype LinkTone = 'inherit' | 'primary'\n\ntype LinkUnderline = 'always' | 'hover' | 'none'\n\n// What React Native Web hands a link's span, which React Native's own Text\n// declares none of: the browser's pointer, focus and key events, each typed\n// by the fields the link reads, and whether the span takes the Tab key.\ntype WebProps = {\n readonly focusable: boolean\n readonly onBlur: () => void\n readonly onFocus: (event: {\n readonly currentTarget: { readonly matches: (selector: string) => boolean }\n }) => void\n readonly onKeyDown: (event: {\n readonly currentTarget: { readonly click: () => void }\n readonly key: string\n readonly repeat: boolean\n }) => void\n readonly onPointerEnter: (event: { readonly pointerType: string }) => void\n readonly onPointerLeave: () => void\n}\n\n// React Native's underline is off unless a style turns it on, and a nested\n// Text inherits its sentence's, so `hover` and `none` say `none` outright, as\n// web's do over an anchor's own underline.\nconst underlines = StyleSheet.create({\n always: { textDecorationLine: 'underline' },\n hover: { textDecorationLine: 'none' },\n none: { textDecorationLine: 'none' },\n})\n\nconst stylesOf = themedStyles(({ colors, radii, stateLayerOpacity }) => {\n const disabledContent = withOpacity(\n colors.onSurface,\n stateLayerOpacity.disabledContent,\n )\n\n return StyleSheet.create({\n // The ring's corner on web, where an outline follows it. A nested Text\n // draws no frame on native, so there it draws nothing.\n base: {\n borderRadius: radii.xs,\n },\n disabled: {\n color: disabledContent,\n textDecorationColor: disabledContent,\n },\n // Under a pointer, either tone turns its text and its rule fully primary.\n hovered: {\n color: colors.primary,\n textDecorationColor: colors.primary,\n },\n // No colour, so the Text around it lends its own.\n inherit: {\n textDecorationColor: colors.outline,\n },\n primary: {\n color: colors.primary,\n textDecorationColor: withOpacity(colors.primary, 0.7),\n },\n })\n})\n\n/**\n * A run of text that leads somewhere, inside the sentence it belongs to.\n *\n * ```tsx\n * <Text variant=\"bodyLarge\">\n * Supporting copy with <Link href=\"/first\">a link inside it</Link>.\n * </Text>\n * ```\n *\n * It is React Native's Text with the link role, nested in the library's\n * Text, so it flows and wraps with the words around it and takes their type.\n * Given no Text around it, it draws in the platform's default face rather\n * than the theme's, so a link standing on its own, such as one of a row of\n * footer links, is a Text holding one link.\n *\n * `onPress` fires for a tap, a click and the Enter key alike, then `href` is\n * followed, through the `RouterProvider` around the link or the platform.\n * `style`, `ref` and `testID` land on React Native's own Text.\n */\nfunction Link({\n href,\n isDisabled = false,\n onPress,\n style,\n suppressHighlighting = true,\n tone = 'primary',\n underline = 'always',\n ...props\n}: LinkProps) {\n const theme = useTheme()\n const press = useLinkPress(href, onPress)\n const [hoveredState, setHovered] = useState(false)\n const [ringShown, setRingShown] = useState(false)\n\n const styles = stylesOf(theme)\n const hovered = !isDisabled && hoveredState\n const pressable = !isDisabled && (href !== undefined || onPress != null)\n const web =\n Platform.OS === 'web'\n ? webPropsOf(isDisabled, setHovered, setRingShown)\n : undefined\n\n return (\n <NativeText\n {...props}\n {...web}\n aria-disabled={isDisabled}\n onPress={pressable ? press : undefined}\n role=\"link\"\n style={composeStyles<TextStyle>(\n styles.base,\n styles[tone],\n underlines[underline],\n hovered && styles.hovered,\n hovered && underline === 'hover' && underlines.always,\n isDisabled && styles.disabled,\n !isDisabled && ringShown && ringStylesOf(theme).ring,\n style,\n )}\n suppressHighlighting={suppressHighlighting}\n />\n )\n}\n\n// The browser's events, read into the link's two states. Hover counts a mouse\n// or a pen and never a touch, which leaves a tapped link's emulated pointer\n// over it, as React Aria's hover does on web. The ring follows the browser's\n// own `:focus-visible`, the rule web's ring is drawn under, read as focus\n// arrives. Enter clicks the span, which is what a browser does for an\n// anchor and what React Native Web hands to `onPress`; a key held down\n// follows the link once.\nfunction webPropsOf(\n isDisabled: boolean,\n setHovered: (hovered: boolean) => void,\n setRingShown: (shown: boolean) => void,\n): WebProps {\n return {\n focusable: !isDisabled,\n onBlur: () => {\n setRingShown(false)\n },\n onFocus: (event) => {\n setRingShown(event.currentTarget.matches(':focus-visible'))\n },\n onKeyDown: (event) => {\n if (!isDisabled && event.key === 'Enter' && !event.repeat) {\n event.currentTarget.click()\n }\n },\n onPointerEnter: (event) => {\n setHovered(event.pointerType !== 'touch')\n },\n onPointerLeave: () => {\n setHovered(false)\n },\n }\n}\n\nexport type { LinkProps, LinkTone, LinkUnderline }\n\nexport { Link }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ComponentRef","Ref","TextProps","NativeTextProps","TextStyle","useState","Text","NativeText","Platform","StyleSheet","stylesOf","ringStylesOf","useLinkPress","withOpacity","useTheme","composeStyles","themedStyles","LinkProps","Omit","href","isDisabled","ref","tone","LinkTone","underline","LinkUnderline","WebProps","focusable","onBlur","onFocus","event","currentTarget","matches","selector","onKeyDown","click","key","repeat","onPointerEnter","nativeEvent","pointerType","onPointerLeave","underlines","create","always","textDecorationLine","hover","none","colors","radii","stateLayerOpacity","disabledContent","onSurface","base","borderRadius","xs","disabled","color","textDecorationColor","hovered","primary","inherit","outline","Link","t0","$","_c","onPress","props","style","t1","t2","t3","t4","suppressHighlighting","undefined","theme","press","hoveredState","setHovered","ringShown","setRingShown","T0","t10","t5","t6","t7","t8","t9","styles","pressable","t11","OS","webPropsOf","web","ring","shown","_c","NativeText","ringStylesOf"],"sources":["../../../src/components/link/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { TextProps as NativeTextProps, TextStyle } from 'react-native'\n\nimport { useState } from 'react'\nimport { Text as NativeText, Platform, StyleSheet } from 'react-native'\n\nimport { stylesOf as ringStylesOf } from '../../press/styles'\nimport { useLinkPress } from '../../router'\nimport { withOpacity } from '../../theme/color'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\n\n// No Material Design page draws an inline link, so this takes web's reading:\n// the text button's label, the primary role on no container, with the\n// disabled treatment every page gives content, and a rule under it to say it\n// can be followed. That rule is 70% of the primary role, or the outline role\n// under `inherit`, and turns fully primary under a pointer. 70% is web's\n// figure, the least that keeps the rule at 3:1 against the surface in every\n// scheme the library is shown in.\n//\n// It is a nested Text, so it sets no type of its own and takes the size and\n// face of the sentence around it, as web's takes them from its paragraph. A\n// nested Text has no frame of its own, so it takes no `hitSlop` either.\n//\n// Where it departs from web, the platform is the reason:\n//\n// - The disabled colour is on-surface at the `disabledContent` opacity,\n// translucent over whatever the sentence sits on. Web mixes the two over\n// the surface role, and React Native has no `color-mix()`.\n// - Android draws the rule in the text's own colour, since it has no\n// `textDecorationColor`, and every platform draws it at its own thickness\n// and offset, which React Native has no properties for.\n// - Hover, the focus ring and the Enter key are the web's alone: a phone has\n// no pointer to hover with and focuses no span inside a sentence, so on\n// native `hover` draws no rule at all. The colour changes at once rather\n// than over a transition.\n// - iOS's own pressed highlight is off, since web's link draws no pressed\n// state; `suppressHighlighting={false}` turns it back on.\n\ntype LinkProps = Omit<NativeTextProps, 'disabled'> & {\n /**\n * Where the link leads. A press opens it through the `RouterProvider`\n * around the link, or through the platform for a URL with a scheme of its\n * own, after the call site's own `onPress`.\n */\n readonly href?: string\n /**\n * Fades the link to the disabled content colour, and takes no press. It is\n * still announced as a link, a disabled one.\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof NativeText>>\n /**\n * Which colour role to render in. `primary` marks the link out from the\n * text around it; `inherit` takes the colour of the Text around it and\n * leans on the underline alone, for a link in a place already understood\n * to be links, such as a footer.\n * @default 'primary'\n */\n readonly tone?: LinkTone\n /**\n * When to draw the rule. Leave it at `always` in prose: without it, colour\n * is the only thing separating the link from the sentence, which some\n * readers cannot see. `hover` and `none` are for links whose position\n * already announces them, such as a row of footer links. A phone has no\n * pointer, so `hover` draws no rule there.\n * @default 'always'\n */\n readonly underline?: LinkUnderline\n}\n\ntype LinkTone = 'inherit' | 'primary'\n\ntype LinkUnderline = 'always' | 'hover' | 'none'\n\n// What React Native Web hands a link's span, which React Native's own Text\n// declares little of: the browser's pointer, focus and key events, each typed\n// by the fields the link reads, and whether the span takes the Tab key. The\n// pointer's type is read off the native event, which is where React Native's\n// own pointer events carry it.\ntype WebProps = {\n readonly focusable: boolean\n readonly onBlur: () => void\n readonly onFocus: (event: {\n readonly currentTarget: { readonly matches: (selector: string) => boolean }\n }) => void\n readonly onKeyDown: (event: {\n readonly currentTarget: { readonly click: () => void }\n readonly key: string\n readonly repeat: boolean\n }) => void\n readonly onPointerEnter: (event: {\n readonly nativeEvent: { readonly pointerType: string }\n }) => void\n readonly onPointerLeave: () => void\n}\n\n// React Native's underline is off unless a style turns it on, and a nested\n// Text inherits its sentence's, so `hover` and `none` say `none` outright, as\n// web's do over an anchor's own underline.\nconst underlines = StyleSheet.create({\n always: { textDecorationLine: 'underline' },\n hover: { textDecorationLine: 'none' },\n none: { textDecorationLine: 'none' },\n})\n\nconst stylesOf = themedStyles(({ colors, radii, stateLayerOpacity }) => {\n const disabledContent = withOpacity(\n colors.onSurface,\n stateLayerOpacity.disabledContent,\n )\n\n return StyleSheet.create({\n // The ring's corner on web, where an outline follows it. A nested Text\n // draws no frame on native, so there it draws nothing.\n base: {\n borderRadius: radii.xs,\n },\n disabled: {\n color: disabledContent,\n textDecorationColor: disabledContent,\n },\n // Under a pointer, either tone turns its text and its rule fully primary.\n hovered: {\n color: colors.primary,\n textDecorationColor: colors.primary,\n },\n // No colour, so the Text around it lends its own.\n inherit: {\n textDecorationColor: colors.outline,\n },\n primary: {\n color: colors.primary,\n textDecorationColor: withOpacity(colors.primary, 0.7),\n },\n })\n})\n\n/**\n * A run of text that leads somewhere, inside the sentence it belongs to.\n *\n * ```tsx\n * <Text variant=\"bodyLarge\">\n * Supporting copy with <Link href=\"/first\">a link inside it</Link>.\n * </Text>\n * ```\n *\n * It is React Native's Text with the link role, nested in the library's\n * Text, so it flows and wraps with the words around it and takes their type.\n * Given no Text around it, it draws in the platform's default face rather\n * than the theme's, so a link standing on its own, such as one of a row of\n * footer links, is a Text holding one link.\n *\n * `onPress` fires for a tap, a click and the Enter key alike, then `href` is\n * followed, through the `RouterProvider` around the link or the platform.\n * `style`, `ref` and `testID` land on React Native's own Text.\n */\nfunction Link({\n href,\n isDisabled = false,\n onPress,\n style,\n suppressHighlighting = true,\n tone = 'primary',\n underline = 'always',\n ...props\n}: LinkProps) {\n const theme = useTheme()\n const press = useLinkPress(href, onPress)\n const [hoveredState, setHovered] = useState(false)\n const [ringShown, setRingShown] = useState(false)\n\n const styles = stylesOf(theme)\n const hovered = !isDisabled && hoveredState\n const pressable = !isDisabled && (href !== undefined || onPress != null)\n const web =\n Platform.OS === 'web'\n ? webPropsOf(isDisabled, setHovered, setRingShown)\n : undefined\n\n return (\n <NativeText\n {...props}\n {...web}\n aria-disabled={isDisabled}\n onPress={pressable ? press : undefined}\n role=\"link\"\n style={composeStyles<TextStyle>(\n styles.base,\n styles[tone],\n underlines[underline],\n hovered && styles.hovered,\n hovered && underline === 'hover' && underlines.always,\n isDisabled && styles.disabled,\n !isDisabled && ringShown && ringStylesOf(theme).ring,\n style,\n )}\n suppressHighlighting={suppressHighlighting}\n />\n )\n}\n\n// The browser's events, read into the link's two states. Hover counts a mouse\n// or a pen and never a touch, which leaves a tapped link's emulated pointer\n// over it, as React Aria's hover does on web. The ring follows the browser's\n// own `:focus-visible`, the rule web's ring is drawn under, read as focus\n// arrives. Enter clicks the span, which is what a browser does for an\n// anchor and what React Native Web hands to `onPress`; a key held down\n// follows the link once.\nfunction webPropsOf(\n isDisabled: boolean,\n setHovered: (hovered: boolean) => void,\n setRingShown: (shown: boolean) => void,\n): WebProps {\n return {\n focusable: !isDisabled,\n onBlur: () => {\n setRingShown(false)\n },\n onFocus: (event) => {\n setRingShown(event.currentTarget.matches(':focus-visible'))\n },\n onKeyDown: (event) => {\n if (!isDisabled && event.key === 'Enter' && !event.repeat) {\n event.currentTarget.click()\n }\n },\n onPointerEnter: (event) => {\n setHovered(event.nativeEvent.pointerType !== 'touch')\n },\n onPointerLeave: () => {\n setHovered(false)\n },\n }\n}\n\nexport type { LinkProps, LinkTone, LinkUnderline }\n\nexport { Link }\n"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { IndicatorTone } from "../../indicator/index.js";
2
+ import { StyleProp, View, ViewProps, ViewStyle } from "react-native";
3
+ import { ComponentRef, Ref } from "react";
4
+ //#region src/components/meter/index.d.ts
5
+ type MeterProps = Omit<ViewProps, 'children' | 'style'> & {
6
+ /**
7
+ * How the value reads.
8
+ * @default { style: 'percent' }
9
+ */
10
+ readonly formatOptions?: Intl.NumberFormatOptions;
11
+ /**
12
+ * What is being measured, shown above the line. A screen reader reads it as
13
+ * the meter's name; a meter whose surroundings name it takes `aria-label`
14
+ * instead and leaves this out.
15
+ */
16
+ readonly label?: string;
17
+ /**
18
+ * The BCP 47 locale the value is written in. Defaults to the device's.
19
+ */
20
+ readonly locale?: string;
21
+ /**
22
+ * The top of the scale.
23
+ * @default 100
24
+ */
25
+ readonly maxValue?: number;
26
+ /**
27
+ * The bottom of the scale.
28
+ * @default 0
29
+ */
30
+ readonly minValue?: number;
31
+ readonly ref?: Ref<ComponentRef<typeof View>>;
32
+ /**
33
+ * Whether the value is shown beside the label.
34
+ * @default true
35
+ */
36
+ readonly showValue?: boolean;
37
+ readonly style?: StyleProp<ViewStyle>;
38
+ /**
39
+ * Which colours the measurement is drawn in. `primary` states without
40
+ * ranking; `negative` and `positive` say the value is bad or good, and
41
+ * recolour the active indicator and the stop indicator, leaving the track in
42
+ * its secondary container so a column of meters still shares one track.
43
+ * @default 'primary'
44
+ */
45
+ readonly tone?: MeterTone;
46
+ /**
47
+ * The measurement, between `minValue` and `maxValue`.
48
+ * @default 0
49
+ */
50
+ readonly value?: number;
51
+ /** The value as words, in place of the number `formatOptions` writes. */
52
+ readonly valueLabel?: string;
53
+ };
54
+ type MeterTone = Extract<IndicatorTone, 'negative' | 'positive' | 'primary'>;
55
+ /**
56
+ * How full something is, on a scale it names: disk used, storage left, a
57
+ * rating out of five. Pass `value` between `minValue` and `maxValue`, and
58
+ * `formatOptions` to say how the number reads, in `locale`. For how far along
59
+ * a task is, reach for ProgressIndicator instead: a meter has no indeterminate
60
+ * state, because a measurement always has a value.
61
+ *
62
+ * ```tsx
63
+ * <Meter label="Label" tone="negative" value={94} />
64
+ * ```
65
+ *
66
+ * A screen reader hears it as a meter named by its label, with its value as
67
+ * `formatOptions` writes it. `style`, `ref` and `testID` land on the meter as
68
+ * a whole, which is the view a layout positions.
69
+ */
70
+ declare function Meter({ 'aria-label': ariaLabel, formatOptions, label, locale, maxValue, minValue, showValue, style, tone, value, valueLabel, ...props }: MeterProps): import("react").JSX.Element;
71
+ //#endregion
72
+ export { Meter, type MeterProps, type MeterTone };
73
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,179 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles } from "../../theme/styles.js";
3
+ import { DETERMINATE_EASING, stylesOf } from "../../indicator/styles.js";
4
+ import { IndicatorLabels, IndicatorLine, readingOf, useEased, useIndicatorColors, useMeasuredWidth } from "../../indicator/index.js";
5
+ import { c } from "react/compiler-runtime";
6
+ import { StyleSheet, View } from "react-native";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/meter/index.tsx
9
+ const styles = StyleSheet.create({ line: { alignSelf: "stretch" } });
10
+ /**
11
+ * How full something is, on a scale it names: disk used, storage left, a
12
+ * rating out of five. Pass `value` between `minValue` and `maxValue`, and
13
+ * `formatOptions` to say how the number reads, in `locale`. For how far along
14
+ * a task is, reach for ProgressIndicator instead: a meter has no indeterminate
15
+ * state, because a measurement always has a value.
16
+ *
17
+ * ```tsx
18
+ * <Meter label="Label" tone="negative" value={94} />
19
+ * ```
20
+ *
21
+ * A screen reader hears it as a meter named by its label, with its value as
22
+ * `formatOptions` writes it. `style`, `ref` and `testID` land on the meter as
23
+ * a whole, which is the view a layout positions.
24
+ */
25
+ function Meter(t0) {
26
+ const $ = c(45);
27
+ let ariaLabel;
28
+ let formatOptions;
29
+ let label;
30
+ let locale;
31
+ let props;
32
+ let style;
33
+ let t1;
34
+ let t2;
35
+ let t3;
36
+ let t4;
37
+ let t5;
38
+ let valueLabel;
39
+ if ($[0] !== t0) {
40
+ ({"aria-label": ariaLabel, formatOptions, label, locale, maxValue: t1, minValue: t2, showValue: t3, style, tone: t4, value: t5, valueLabel, ...props} = t0);
41
+ $[0] = t0;
42
+ $[1] = ariaLabel;
43
+ $[2] = formatOptions;
44
+ $[3] = label;
45
+ $[4] = locale;
46
+ $[5] = props;
47
+ $[6] = style;
48
+ $[7] = t1;
49
+ $[8] = t2;
50
+ $[9] = t3;
51
+ $[10] = t4;
52
+ $[11] = t5;
53
+ $[12] = valueLabel;
54
+ } else {
55
+ ariaLabel = $[1];
56
+ formatOptions = $[2];
57
+ label = $[3];
58
+ locale = $[4];
59
+ props = $[5];
60
+ style = $[6];
61
+ t1 = $[7];
62
+ t2 = $[8];
63
+ t3 = $[9];
64
+ t4 = $[10];
65
+ t5 = $[11];
66
+ valueLabel = $[12];
67
+ }
68
+ const maxValue = t1 === void 0 ? 100 : t1;
69
+ const minValue = t2 === void 0 ? 0 : t2;
70
+ const showValue = t3 === void 0 ? true : t3;
71
+ const tone = t4 === void 0 ? "primary" : t4;
72
+ const value = t5 === void 0 ? 0 : t5;
73
+ const theme = useTheme();
74
+ const colors = useIndicatorColors(tone);
75
+ let t6;
76
+ if ($[13] !== formatOptions || $[14] !== locale || $[15] !== maxValue || $[16] !== minValue || $[17] !== value || $[18] !== valueLabel) {
77
+ t6 = readingOf({
78
+ formatOptions,
79
+ locale,
80
+ maxValue,
81
+ minValue,
82
+ value,
83
+ valueLabel
84
+ });
85
+ $[13] = formatOptions;
86
+ $[14] = locale;
87
+ $[15] = maxValue;
88
+ $[16] = minValue;
89
+ $[17] = value;
90
+ $[18] = valueLabel;
91
+ $[19] = t6;
92
+ } else t6 = $[19];
93
+ const reading = t6;
94
+ let t7;
95
+ if ($[20] !== theme.motion.durationMedium1) {
96
+ t7 = {
97
+ duration: theme.motion.durationMedium1,
98
+ easing: DETERMINATE_EASING
99
+ };
100
+ $[20] = theme.motion.durationMedium1;
101
+ $[21] = t7;
102
+ } else t7 = $[21];
103
+ const shown = useEased(reading.percentage, t7);
104
+ const { onLayout, width } = useMeasuredWidth();
105
+ const t8 = label ?? ariaLabel;
106
+ const t9 = reading.value;
107
+ const t10 = reading.text;
108
+ let t11;
109
+ if ($[22] !== style || $[23] !== theme) {
110
+ t11 = composeStyles(stylesOf(theme).root, style);
111
+ $[22] = style;
112
+ $[23] = theme;
113
+ $[24] = t11;
114
+ } else t11 = $[24];
115
+ const t12 = showValue ? reading.text : void 0;
116
+ let t13;
117
+ if ($[25] !== label || $[26] !== t12) {
118
+ t13 = /* @__PURE__ */ jsx(IndicatorLabels, {
119
+ label,
120
+ value: t12
121
+ });
122
+ $[25] = label;
123
+ $[26] = t12;
124
+ $[27] = t13;
125
+ } else t13 = $[27];
126
+ let t14;
127
+ if ($[28] !== colors || $[29] !== shown || $[30] !== width) {
128
+ t14 = /* @__PURE__ */ jsx(IndicatorLine, {
129
+ colors,
130
+ percentage: shown,
131
+ width
132
+ });
133
+ $[28] = colors;
134
+ $[29] = shown;
135
+ $[30] = width;
136
+ $[31] = t14;
137
+ } else t14 = $[31];
138
+ let t15;
139
+ if ($[32] !== onLayout || $[33] !== t14) {
140
+ t15 = /* @__PURE__ */ jsx(View, {
141
+ onLayout,
142
+ style: styles.line,
143
+ children: t14
144
+ });
145
+ $[32] = onLayout;
146
+ $[33] = t14;
147
+ $[34] = t15;
148
+ } else t15 = $[34];
149
+ let t16;
150
+ if ($[35] !== maxValue || $[36] !== minValue || $[37] !== props || $[38] !== reading.text || $[39] !== reading.value || $[40] !== t11 || $[41] !== t13 || $[42] !== t15 || $[43] !== t8) {
151
+ t16 = /* @__PURE__ */ jsxs(View, {
152
+ accessible: true,
153
+ "aria-label": t8,
154
+ "aria-valuemax": maxValue,
155
+ "aria-valuemin": minValue,
156
+ "aria-valuenow": t9,
157
+ "aria-valuetext": t10,
158
+ role: "meter",
159
+ ...props,
160
+ style: t11,
161
+ children: [t13, t15]
162
+ });
163
+ $[35] = maxValue;
164
+ $[36] = minValue;
165
+ $[37] = props;
166
+ $[38] = reading.text;
167
+ $[39] = reading.value;
168
+ $[40] = t11;
169
+ $[41] = t13;
170
+ $[42] = t15;
171
+ $[43] = t8;
172
+ $[44] = t16;
173
+ } else t16 = $[44];
174
+ return t16;
175
+ }
176
+ //#endregion
177
+ export { Meter };
178
+
179
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","Ref","StyleProp","ViewProps","ViewStyle","StyleSheet","View","IndicatorTone","IndicatorLabels","IndicatorLine","readingOf","useEased","useIndicatorColors","useMeasuredWidth","DETERMINATE_EASING","stylesOf","indicatorStylesOf","useTheme","composeStyles","MeterProps","Omit","formatOptions","Intl","NumberFormatOptions","label","locale","maxValue","minValue","ref","showValue","style","tone","MeterTone","value","valueLabel","styles","create","line","alignSelf","Extract","Meter","t0","$","_c","ariaLabel","props","t1","t2","t3","t4","t5","undefined","theme","colors","t6","reading","t7","motion","durationMedium1","duration","easing","shown","percentage","onLayout","width","t8","t9","t10","text","t11","root","t12","t13","t14","t15","t16","_c","indicatorStylesOf"],"sources":["../../../src/components/meter/index.tsx"],"sourcesContent":["import type { ComponentRef, Ref } from 'react'\nimport type { StyleProp, ViewProps, ViewStyle } from 'react-native'\n\nimport { StyleSheet, View } from 'react-native'\n\nimport type { IndicatorTone } from '../../indicator'\n\nimport {\n IndicatorLabels,\n IndicatorLine,\n readingOf,\n useEased,\n useIndicatorColors,\n useMeasuredWidth,\n} from '../../indicator'\nimport {\n DETERMINATE_EASING,\n stylesOf as indicatorStylesOf,\n} from '../../indicator/styles'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles } from '../../theme/styles'\n\n// A meter is the progress indicators page's line, drawn for a measurement\n// rather than for a task, as on web: the same three parts at the same 4dp,\n// the same label row above them, and the same motion when the number changes.\n// All of that is `src/indicator`, shared with ProgressIndicator, so what is\n// here is the two things that make it a meter rather than a progress bar.\n//\n// The first is the role. The root says `meter` rather than `progressbar`, as\n// React Aria's `Meter` does on web, and a screen reader says the two\n// differently: one is how full something is, the other how far along\n// something is. That is also why a meter has no indeterminate state: a\n// measurement whose value is unknown is not a measurement.\n//\n// The second is `tone`. The page draws one colour pair, which is right for a\n// task, since progress does not become good or bad on its way to done. A\n// measurement does, so `negative` and `positive` recolour the active\n// indicator and the stop indicator and leave the track alone. A column of\n// meters then reads as one scale with bars of different colours. Which tone a\n// value deserves is the call site's to decide: nothing here reads the number\n// and picks one.\n//\n// The value is shown by default, where a progress indicator hides it. A meter\n// is the number, and `formatOptions` is what makes it read as a percentage,\n// bytes or a plain count, in `locale`.\n\ntype MeterProps = Omit<ViewProps, 'children' | 'style'> & {\n /**\n * How the value reads.\n * @default { style: 'percent' }\n */\n readonly formatOptions?: Intl.NumberFormatOptions\n /**\n * What is being measured, shown above the line. A screen reader reads it as\n * the meter's name; a meter whose surroundings name it takes `aria-label`\n * instead and leaves this out.\n */\n readonly label?: string\n /**\n * The BCP 47 locale the value is written in. Defaults to the device's.\n */\n readonly locale?: string\n /**\n * The top of the scale.\n * @default 100\n */\n readonly maxValue?: number\n /**\n * The bottom of the scale.\n * @default 0\n */\n readonly minValue?: number\n readonly ref?: Ref<ComponentRef<typeof View>>\n /**\n * Whether the value is shown beside the label.\n * @default true\n */\n readonly showValue?: boolean\n readonly style?: StyleProp<ViewStyle>\n /**\n * Which colours the measurement is drawn in. `primary` states without\n * ranking; `negative` and `positive` say the value is bad or good, and\n * recolour the active indicator and the stop indicator, leaving the track in\n * its secondary container so a column of meters still shares one track.\n * @default 'primary'\n */\n readonly tone?: MeterTone\n /**\n * The measurement, between `minValue` and `maxValue`.\n * @default 0\n */\n readonly value?: number\n /** The value as words, in place of the number `formatOptions` writes. */\n readonly valueLabel?: string\n}\n\nconst styles = StyleSheet.create({\n // The row the line is drawn across, measured for the width it is drawn to.\n line: {\n alignSelf: 'stretch',\n },\n})\n\n// The three of the shared line's four tones a meter draws. The fourth,\n// `inherit`, is for an indicator inside something that carries its own\n// colour, which is a pending button rather than a measurement.\ntype MeterTone = Extract<IndicatorTone, 'negative' | 'positive' | 'primary'>\n\n/**\n * How full something is, on a scale it names: disk used, storage left, a\n * rating out of five. Pass `value` between `minValue` and `maxValue`, and\n * `formatOptions` to say how the number reads, in `locale`. For how far along\n * a task is, reach for ProgressIndicator instead: a meter has no indeterminate\n * state, because a measurement always has a value.\n *\n * ```tsx\n * <Meter label=\"Label\" tone=\"negative\" value={94} />\n * ```\n *\n * A screen reader hears it as a meter named by its label, with its value as\n * `formatOptions` writes it. `style`, `ref` and `testID` land on the meter as\n * a whole, which is the view a layout positions.\n */\nfunction Meter({\n 'aria-label': ariaLabel,\n formatOptions,\n label,\n locale,\n maxValue = 100,\n minValue = 0,\n showValue = true,\n style,\n tone = 'primary',\n value = 0,\n valueLabel,\n ...props\n}: MeterProps) {\n const theme = useTheme()\n const colors = useIndicatorColors(tone)\n const reading = readingOf({\n formatOptions,\n locale,\n maxValue,\n minValue,\n value,\n valueLabel,\n })\n const shown = useEased(reading.percentage, {\n duration: theme.motion.durationMedium1,\n easing: DETERMINATE_EASING,\n })\n const { onLayout, width } = useMeasuredWidth()\n\n return (\n <View\n accessible\n aria-label={label ?? ariaLabel}\n aria-valuemax={maxValue}\n aria-valuemin={minValue}\n aria-valuenow={reading.value}\n aria-valuetext={reading.text}\n role=\"meter\"\n {...props}\n style={composeStyles<ViewStyle>(indicatorStylesOf(theme).root, style)}\n >\n <IndicatorLabels\n label={label}\n value={showValue ? reading.text : undefined}\n />\n <View onLayout={onLayout} style={styles.line}>\n <IndicatorLine colors={colors} percentage={shown} width={width} />\n </View>\n </View>\n )\n}\n\nexport { Meter }\nexport type { MeterProps, MeterTone }\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 { Ref } from "react";
4
+ import { ComponentRef, Ref } from "react";
5
5
  //#region src/components/number-field/index.d.ts
6
6
  type NumberFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilityLabel' | 'aria-disabled' | 'aria-label' | 'autoComplete' | 'autoCorrect' | 'children' | 'cursorColor' | 'defaultValue' | 'editable' | 'inputMode' | 'keyboardType' | 'maxLength' | 'multiline' | 'numberOfLines' | 'onChange' | 'onChangeText' | 'placeholder' | 'placeholderTextColor' | 'readOnly' | 'selectionColor' | 'spellCheck' | 'style' | 'underlineColorAndroid' | 'value'> & {
7
7
  /**
@@ -46,7 +46,7 @@ type NumberFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilit
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, no input and no steps.
52
52
  * @default false
@@ -95,7 +95,7 @@ type NumberFieldProps = Omit<TextInputProps, 'accessibilityHint' | 'accessibilit
95
95
  * stepped to. `NaN` is an empty field.
96
96
  */
97
97
  readonly onChange?: (value: number) => void;
98
- readonly ref?: Ref<View>;
98
+ readonly ref?: Ref<ComponentRef<typeof View>>;
99
99
  /**
100
100
  * The amount the steppers move the value by, and the multiple of it, from
101
101
  * `minValue`, that a committed value snaps to.
@@ -4,6 +4,7 @@ import { useTheme } from "../../theme/scope.js";
4
4
  import { composeStyles, themedStyles } from "../../theme/styles.js";
5
5
  import { useFieldValidation } from "../../form/index.js";
6
6
  import { withOpacity } from "../../theme/color.js";
7
+ import { localeOf } from "../../number/locale.js";
7
8
  import { hitSlop, usePressFeedback } from "../../press/index.js";
8
9
  import { IconButton } from "../icon-button/index.js";
9
10
  import { FieldBox, FieldInput, FieldMessage, describedBy, useFieldFocus } from "../../field/index.js";
@@ -18,7 +19,6 @@ const STEPPER_WIDTH = 32;
18
19
  const GLYPH_SIZE = 20;
19
20
  const SPIN_DELAY = 600;
20
21
  const SPIN_INTERVAL = 60;
21
- let deviceLocale;
22
22
  const stylesOf = themedStyles(({ radii, spacing }) => StyleSheet.create({
23
23
  stepper: {
24
24
  alignItems: "center",
@@ -79,14 +79,6 @@ function keyboardOf(minValue, hasDecimals) {
79
79
  if (minValue === void 0 || Number.isNaN(minValue) || minValue < 0) return Platform.OS === "ios" ? "numbers-and-punctuation" : "numeric";
80
80
  return hasDecimals ? "decimal-pad" : "number-pad";
81
81
  }
82
- function localeOf(locale) {
83
- if (locale !== void 0) try {
84
- Intl.NumberFormat.supportedLocalesOf(locale);
85
- return locale;
86
- } catch {}
87
- deviceLocale ??= new Intl.NumberFormat().resolvedOptions().locale;
88
- return deviceLocale;
89
- }
90
82
  function marginVerticalOf(margin) {
91
83
  return { marginVertical: margin };
92
84
  }