@jobber/components-native 0.101.5 → 0.101.6

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 (67) hide show
  1. package/dist/docs/ActionItem/ActionItem.md +65 -0
  2. package/dist/docs/ActionItemGroup/ActionItemGroup.md +33 -0
  3. package/dist/docs/ActionLabel/ActionLabel.md +43 -0
  4. package/dist/docs/ActivityIndicator/ActivityIndicator.md +116 -0
  5. package/dist/docs/Animation/Animation.md +71 -0
  6. package/dist/docs/AtlantisThemeContext/AtlantisThemeContext.md +256 -0
  7. package/dist/docs/AutoLink/AutoLink.md +47 -0
  8. package/dist/docs/Banner/Banner.md +390 -0
  9. package/dist/docs/Borders/Borders.md +45 -0
  10. package/dist/docs/BottomSheet/BottomSheet.md +67 -0
  11. package/dist/docs/Button/Button.md +918 -0
  12. package/dist/docs/ButtonGroup/ButtonGroup.md +89 -0
  13. package/dist/docs/Card/Card.md +270 -0
  14. package/dist/docs/Checkbox/Checkbox.md +69 -0
  15. package/dist/docs/Chip/Chip.md +371 -0
  16. package/dist/docs/Colors/Colors.md +217 -0
  17. package/dist/docs/Content/Content.md +67 -0
  18. package/dist/docs/ContentOverlay/ContentOverlay.md +64 -0
  19. package/dist/docs/Disclosure/Disclosure.md +161 -0
  20. package/dist/docs/Divider/Divider.md +84 -0
  21. package/dist/docs/Elevations/Elevations.md +76 -0
  22. package/dist/docs/EmptyState/EmptyState.md +72 -0
  23. package/dist/docs/Flex/Flex.md +37 -0
  24. package/dist/docs/Form/Form.md +126 -0
  25. package/dist/docs/FormField/FormField.md +57 -0
  26. package/dist/docs/FormatFile/FormatFile.md +56 -0
  27. package/dist/docs/Glimmer/Glimmer.md +143 -0
  28. package/dist/docs/Heading/Heading.md +132 -0
  29. package/dist/docs/Icon/Icon.md +585 -0
  30. package/dist/docs/IconButton/IconButton.md +25 -0
  31. package/dist/docs/InputCurrency/InputCurrency.md +61 -0
  32. package/dist/docs/InputDate/InputDate.md +133 -0
  33. package/dist/docs/InputEmail/InputEmail.md +69 -0
  34. package/dist/docs/InputFieldWrapper/InputFieldWrapper.md +70 -0
  35. package/dist/docs/InputNumber/InputNumber.md +72 -0
  36. package/dist/docs/InputPassword/InputPassword.md +61 -0
  37. package/dist/docs/InputPressable/InputPressable.md +64 -0
  38. package/dist/docs/InputSearch/InputSearch.md +49 -0
  39. package/dist/docs/InputText/InputText.md +324 -0
  40. package/dist/docs/InputTime/InputTime.md +54 -0
  41. package/dist/docs/Opacity/Opacity.md +12 -0
  42. package/dist/docs/ProgressBar/ProgressBar.md +39 -0
  43. package/dist/docs/Radii/Radii.md +23 -0
  44. package/dist/docs/ResponsiveBreakpoint/ResponsiveBreakpoint.md +74 -0
  45. package/dist/docs/Select/Select.md +213 -0
  46. package/dist/docs/Spacing/Spacing.md +103 -0
  47. package/dist/docs/StatusLabel/StatusLabel.md +119 -0
  48. package/dist/docs/Switch/Switch.md +54 -0
  49. package/dist/docs/Text/Text.md +368 -0
  50. package/dist/docs/TextList/TextList.md +29 -0
  51. package/dist/docs/ThumbnailList/ThumbnailList.md +16 -0
  52. package/dist/docs/Toast/Toast.md +71 -0
  53. package/dist/docs/Typography/Typography.md +170 -0
  54. package/dist/docs/choosing-components/choosing-components.md +76 -0
  55. package/dist/docs/customizing-components/customizing-components.md +167 -0
  56. package/dist/docs/disabled-states/disabled-states.md +86 -0
  57. package/dist/docs/empty-states/empty-states.md +126 -0
  58. package/dist/docs/errors/errors.md +114 -0
  59. package/dist/docs/index.md +64 -0
  60. package/dist/docs/interaction/interaction.md +109 -0
  61. package/dist/docs/page-layouts/page-layouts.md +323 -0
  62. package/dist/docs/scaffolding/scaffolding.md +109 -0
  63. package/dist/docs/settings/settings.md +58 -0
  64. package/dist/docs/usage-guidelines/usage-guidelines.md +177 -0
  65. package/dist/package.json +8 -4
  66. package/dist/tsconfig.build.tsbuildinfo +1 -1
  67. package/package.json +8 -4
@@ -0,0 +1,64 @@
1
+ # ContentOverlay
2
+
3
+ ContentOverlay allows the user to quickly access information that supports their
4
+ understanding of the primary content of their current view.
5
+
6
+ ## Design & usage guidelines
7
+
8
+ The ContentOverlay component will allow users to quickly access detailed
9
+ information about a topic without having to navigate away from their current
10
+ view.
11
+
12
+ ## Content guidelines
13
+
14
+ The ContentOverlay should be able to present any type of content, but its most
15
+ common use case will probably be text and images.
16
+
17
+ While the ContentOverlay can have input such as InputText within it, and the
18
+ keyboard will adjust its location to make the currently focused field visible,
19
+ it is advisable to be cautious about how much content it contains if there are
20
+ inputs. If an input ends up near the bottom of the ContentOverlay with no room
21
+ to move up, it will become obstructed by the keyboard. Only enabling scrolling
22
+ will allow it to be visible.
23
+
24
+ ## Accessibility
25
+
26
+ ContentOverlay responds to touch events, specifically swiping.
27
+
28
+ ## Responsiveness
29
+
30
+ ContentOverlay will take up as much vertical space as needed, minus a small
31
+ amount of space between the top of the overlay and the top of the screen. It
32
+ will also take up the full width of the screen up to a breakpoint of 640px,
33
+ where it will be a maximum width of 640px and be centered on the screen.
34
+
35
+ ## Mockup
36
+
37
+
38
+ ## Developer notes
39
+
40
+ `ContentOverlay` uses the same library internally as
41
+ [BottomSheet.](../BottomSheet/BottomSheet.md)
42
+
43
+
44
+ ## Props
45
+
46
+ ### Mobile
47
+
48
+ | Prop | Type | Required | Default | Description |
49
+ |------|------|----------|---------|-------------|
50
+ | `children` | `ReactNode` | Yes | — | Content to be passed into the overlay |
51
+ | `accessibilityLabel` | `string` | No | `"Close {title} modal"` | Optional accessibilityLabel describing the overlay. This will read out when the overlay is opened. |
52
+ | `adjustToContentHeight` | `boolean` | No | `false` | If true, automatically adjusts the overlay height to the content height. This will disable the ability to drag the ov... |
53
+ | `fullScreen` | `boolean` | No | `false` | Force overlay height to fill the screen. Width not impacted. |
54
+ | `isDraggable` | `boolean` | No | `true` | If false, hides the handle and turns off dragging. |
55
+ | `keyboardShouldPersistTaps` | `boolean` | No | `false` | Allows taps to be registered behind keyboard if enabled |
56
+ | `loading` | `boolean` | No | `false` | Boolean to show a disabled state |
57
+ | `modalBackgroundColor` | `ModalBackgroundColor` | No | `surface` | Set the background color of the modal window |
58
+ | `onBeforeExit` | `() => void` | No | — | Callback that is called between overlay is closed and when the "x" button is pressed |
59
+ | `onClose` | `() => void` | No | — | Callback that is called when the overlay is closed. |
60
+ | `onOpen` | `() => void` | No | — | Callback that is called when the overlay is opened. |
61
+ | `ref` | `Ref<{ open?: () => void; close?: () => void; }>` | No | — | Ref to the content overlay component. |
62
+ | `scrollEnabled` | `boolean` | No | `false` | Enables scrolling in the content body of overlay |
63
+ | `showDismiss` | `boolean` | No | `false` | Display the dismiss button in the header of the overlay. |
64
+ | `title` | `string` | No | — | Title of overlay, appears in the header next to the close button. |
@@ -0,0 +1,161 @@
1
+ # Disclosure
2
+
3
+ Disclosure is a component that allows users to progressively reveal content that
4
+ is not essential to the primary objective of a given view.
5
+
6
+ ## Design & usage guidelines
7
+
8
+ Disclosure is useful for revealing or hiding content that is not essential for
9
+ the user to view all at once. You may want to put content inside of a Disclosure
10
+ to:
11
+
12
+ * reduce distractions or avoid overwhelming the user
13
+ * hide non-critical controls or options in a form
14
+
15
+ Disclosure should only be used to contain content or controls that aren't
16
+ required for the user to complete the primary objective of a given view.
17
+
18
+ For example, if a user has to make a selection between two options to complete a
19
+ task, do not put the selection controls in a Disclosure. A better example of
20
+ using a Disclosure would be if there is an optional setting that a user may want
21
+ to change but is not required to.
22
+
23
+ ## Content guidelines
24
+
25
+ * `title` should be informative and label the type of content grouped in the
26
+ body of the Disclosure.
27
+ * This can either be a string or a React component. If a React component is
28
+ used (containing multiple children), it should be wrapped in a container
29
+ element and not a `<Fragment>` to maintain correct UI styling.
30
+ * Caveat: The container element should NOT be `<div>` as it would break the
31
+ semantics of the `<summary>` element. Instead, use a `<span>` or `<p>`
32
+ tag.
33
+ * The elements passed as a `title` can be plain text, or HTML that can be used
34
+ within a paragraph (AKA
35
+ ["phrasing content"](https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#phrasing_content))
36
+ to ensure that the title is accessible and can be properly read by screen
37
+ readers. A heading may also be used but will not be treated as a heading by
38
+ assistive technologies.
39
+ * `children` should be actionable and clear. The contents of a Disclosure can
40
+ be:
41
+ * plain text
42
+ * any React component (except [Page](/components/Page) and
43
+ [Table](/components/Table))
44
+
45
+ ## Accessibility
46
+
47
+ * Users should be able to use their keyboard and toggle the component's
48
+ open/close state
49
+ * A single Heading element is permitted in `summary` elements, however, it might
50
+ lose some accessibility benefits, since according to
51
+ [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary#summaries_as_headings):
52
+ > Warning: Because the `<summary>` element has a default role of button (which
53
+ > strips all roles from child elements), this example will not work for users
54
+ > of assistive technologies such as screen readers. The `<h4>` will have its
55
+ > role removed and thus will not be treated as a heading for these users.
56
+ * Include aria-expanded attribute on the trigger to communicate to assistive
57
+ technology
58
+ * Include aria-controls attribute ties on the trigger to the content it controls
59
+ using the id of the collapsible container
60
+ * The trigger contains a downward-pointing-arrow to hint that it can be
61
+ expanded. When the disclosure item is in an expanded state, this is rotated
62
+ 180 degrees to point upwards
63
+ * The icon will be given an `aria-hidden="true"` attribute to hide it from
64
+ assistive technologies, as well as `focusable="false"` to address an
65
+ inconsistency in IE and older versions of Edge
66
+
67
+ ## Responsiveness
68
+
69
+ The Disclosure component should handle both click and touch, as well as keyboard
70
+ inputs. It should fill the width of its container and if the component is less
71
+ than 375px wide, the title will wrap and should not be truncated.
72
+
73
+
74
+ ## Component customization
75
+
76
+ ### UNSAFE\_ props (advanced usage)
77
+
78
+ General information for using `UNSAFE_` props can be found
79
+ [here](../customizing-components/customizing-components.md).
80
+
81
+ **Note**: Use of `UNSAFE_` props is **at your own risk** and should be
82
+ considered a **last resort**. Future Disclosure updates may lead to unintended
83
+ breakages.
84
+
85
+ Disclosure has multiple elements that can be targeted with classes or styles:
86
+
87
+ * `container`: The container element of the Disclosure
88
+ * `summary`: The clickable header area of the Disclosure
89
+ * `summaryWrap`: The inner content within the summary, containing the title and
90
+ toggle arrow
91
+ * `title`: The title element of the Disclosure
92
+ * `icon`: The toggle arrow of the Disclosure
93
+ * `arrowIconWrapper`: The wrapper element for the toggle arrow
94
+ * `content`: The content inside the Disclosure
95
+
96
+ #### UNSAFE\_className (web)
97
+
98
+ Use `UNSAFE_className` to apply custom classes to the Disclosure. This can be
99
+ useful for applying styles via CSS Modules.
100
+
101
+ ```tsx
102
+ // Disclosure.tsx
103
+ UNSAFE_className={{
104
+ container: styles.customDisclosure,
105
+ summary: styles.customSummary,
106
+ }}
107
+
108
+ // Disclosure.stories.css
109
+ .customDisclosure {
110
+ border: 3px solid var(--color-interactive);
111
+ border-radius: var(--radius-base);
112
+ }
113
+
114
+ .customSummary {
115
+ padding: var(--space-base);
116
+ }
117
+ ```
118
+
119
+ #### UNSAFE\_style (web)
120
+
121
+ The `UNSAFE_style` prop provides granular control over the Disclosure's
122
+ appearance through inline styles, allowing you to modify the dimensions and
123
+ colors independently.
124
+
125
+ ```tsx
126
+ <Disclosure
127
+ ...
128
+ UNSAFE_style={{
129
+ container: {
130
+ border: "3px solid var(--color-interactive)",
131
+ borderRadius: "var(--radius-base)",
132
+ },
133
+ title: {
134
+ textStyle: {
135
+ color: "var(--color-interactive--hover)",
136
+ },
137
+ },
138
+ icon: {
139
+ path: {
140
+ fill: "var(--color-interactive--subtle)",
141
+ },
142
+ },
143
+ }}
144
+ >
145
+ ...
146
+ </Disclosure>
147
+ ```
148
+
149
+
150
+ ## Props
151
+
152
+ ### Mobile
153
+
154
+ | Prop | Type | Required | Default | Description |
155
+ |------|------|----------|---------|-------------|
156
+ | `content` | `ReactNode` | Yes | — | Specifies the main content of the disclosure component. It can be any React Node - simple text, JSX, or a complex Rea... |
157
+ | `header` | `ReactNode` | Yes | — | Defines the header of the disclosure component. Similar to `content`, it can be any React Node. |
158
+ | `isEmpty` | `boolean` | Yes | — | A boolean that indicates whether the disclosure component is empty or not. If `isEmpty` is `true`, there is no conten... |
159
+ | `onToggle` | `() => void` | Yes | — | A function that is called whenever the disclosure component is toggled between its open and closed states. |
160
+ | `open` | `boolean` | Yes | — | A boolean that determines whether the disclosure component is in an open or closed state. If `open` is true, the disc... |
161
+ | `animationDuration` | `number` | No | `staticTokens["timing-slowest"]` | An optional property that determines the duration of the opening and closing animation of the disclosure component. I... |
@@ -0,0 +1,84 @@
1
+ # Divider
2
+
3
+ The Divider component is used to separate content into different sections.
4
+
5
+ ## Design & usage guidelines
6
+
7
+ Divider comes with no spacing around it. This means that it should be used
8
+ within a [Content](../Content/Content.md) component.
9
+
10
+ ### Size
11
+
12
+ For different levels of segmentation, you may find the need to use larger
13
+ Dividers. As Dividers increase in size, they get lighter to offset the visual
14
+ impact of their additional weight.
15
+
16
+ ## Related components
17
+
18
+ * To segment different groups of content, use [Card](../Card/Card.md)
19
+ * For guidance on borders in general, see our [Borders guide](../Borders/Borders.md)
20
+
21
+
22
+ ## Component customization
23
+
24
+ ### UNSAFE\_ props (advanced usage)
25
+
26
+ General information for using `UNSAFE_` props can be found
27
+ [here](../customizing-components/customizing-components.md).
28
+
29
+ **Note**: Use of `UNSAFE_` props is **at your own risk** and should be
30
+ considered a **last resort**. Future Divider updates may lead to unintended
31
+ breakages.
32
+
33
+ Divider has one element that can be targeted with classes or styles:
34
+
35
+ * `container`: The main `div` element of the Divider
36
+
37
+ #### UNSAFE\_className (web)
38
+
39
+ Use `UNSAFE_className` to apply custom classes to the Divider. This can be
40
+ useful for applying styles via CSS Modules.
41
+
42
+ ```tsx
43
+ // YourComponent.tsx
44
+ import styles from "./YourStyles.module.css";
45
+
46
+ <Divider
47
+ UNSAFE_className={{
48
+ container: styles.customDivider,
49
+ }}
50
+ />
51
+
52
+ // YourStyles.module.css
53
+ .customDivider {
54
+ background-color: var(--color-background-brand-bold);
55
+ height: 5px;
56
+ }
57
+ ```
58
+
59
+ #### UNSAFE\_style (web)
60
+
61
+ The `UNSAFE_style` prop provides granular control over the Divider's appearance
62
+ through inline styles.
63
+
64
+ ```tsx
65
+ <Divider
66
+ UNSAFE_style={{
67
+ container: {
68
+ backgroundColor: "var(--color-background-danger-bold)",
69
+ height: "10px",
70
+ },
71
+ }}
72
+ />
73
+ ```
74
+
75
+
76
+ ## Props
77
+
78
+ ### Mobile
79
+
80
+ | Prop | Type | Required | Default | Description |
81
+ |------|------|----------|---------|-------------|
82
+ | `direction` | `"horizontal" | "vertical"` | No | `horizontal` | The direction of the divider |
83
+ | `size` | `"base" | "large" | "larger" | "largest"` | No | `base` | The weight of the divider. |
84
+ | `testID` | `string` | No | `Divider` | Used to locate this view in end-to-end tests. |
@@ -0,0 +1,76 @@
1
+ # Elevation
2
+
3
+ > Elevation is the relative distance between two surfaces along the z-axis.
4
+ > –[Material Design](https://material.io/design/environment/elevation.html)
5
+
6
+ In Atlantis, our web components use elevation to specify position on the z-axis,
7
+ with shadows separately responsible for conveying that depth. Our mobile
8
+ components combine these two concepts in keeping with Android and iOS patterns.
9
+
10
+ Generally speaking, the "higher" an element sits in the z-axis, the broader its'
11
+ shadow should spread, to reflect diffusion in the distance between the element
12
+ and the ground. As an element gets nearer to the ground, or "lower", the
13
+ shadow's spread should reduce and the shadow may appear darker.
14
+
15
+ We also include a *slight* y-axis offset of elevation shadows to imply that the
16
+ light source is coming from an angle slightly over the head of a user looking
17
+ directly into the screen.
18
+
19
+ ### Low
20
+
21
+ A low element may have a slight elevation, but is not necessarily something that
22
+ will glide across the surface. A basic card on mobile that is not tappable would
23
+ be represented as having a "low" elevation.
24
+
25
+ ### Base
26
+
27
+ This shadow should be used for most instances of shadows to convey that an
28
+ element is floating overtop related elements, such as in
29
+ [Menu](/components/Menu) or [Popover](/components/Popover). An element with a
30
+ base elevation is likely interactive, and this level can indicate and invite the
31
+ use of gesture controls in a mobile app.
32
+
33
+ ### High
34
+
35
+ High elements should be elements that float overtop the entire interface,
36
+ typically with a fixed position. The "high" elevation indicates that the element
37
+ has broken the plane of the view. A good example for web would be
38
+ [Toast](../Toast/Toast.md).
39
+
40
+ ## Web
41
+
42
+ ### Z-index elevation
43
+
44
+ The following table lists Atlantis components that have a z-index specified.
45
+
46
+ These values can be referenced when you are building a view so that you can
47
+ ensure the elements you are using do not unintentionally overlap, if you end up
48
+ using z-index on non-Atlantis components.
49
+
50
+ | Component | Value |
51
+ | :--------------- | :---- |
52
+ | Form field label | |
53
+ | Menu | |
54
+ | Modal | |
55
+ | Tooltip | |
56
+ | Toast | |
57
+
58
+ ### Shadow elevation
59
+
60
+ These are the box-shadows rendered to signify elevation on given UI elements;
61
+ they map to our low/base/high pattern.
62
+
63
+ | Name | Visual |
64
+ | :-------------- | :----- |
65
+ | `--shadow-low` | |
66
+ | `--shadow-base` | |
67
+ | `--shadow-high` | |
68
+
69
+ ## Mobile
70
+
71
+ For mobile designs, the concept of elevation applies to both shadows and
72
+ hierarchy of the element along the z-index. Android accepts a single "elevation"
73
+ value, while iOS accepts more granular shadow values similar to CSS.
74
+
75
+ When using the mobile tokens imported from `@jobber/design`, the shadow tokens
76
+ will be resolved to apply to either android or iOS devices automatically.
@@ -0,0 +1,72 @@
1
+ # Empty State
2
+
3
+ EmptyState is a component we show when there is nothing here for the user. This
4
+ component should be used for lists with no content, search with no results,
5
+ error states etc.
6
+ [Here is a document](https://jobber.atlassian.net/wiki/spaces/DES/pages/2103541908/Empty+states)
7
+ that explores this in more detail.
8
+
9
+ ## Design & usage guidelines
10
+
11
+ By considering and accounting for often “un-happy” paths in the user’s journey,
12
+ we can allow the user to learn how to use Jobber more effectively, guide them
13
+ out of troublesome scenarios, and ensure that they never feel like they’ve hit a
14
+ dead-end in the product.
15
+
16
+ For more detail you can read about our
17
+ [Empty State patterns.](https://jobber.atlassian.net/wiki/spaces/DES/pages/2103541908/Empty+states)
18
+
19
+ ## Content guidelines
20
+
21
+ An Empty State can display an Icon, text-based title, text-based description,
22
+ and 1–2 actions in Buttons.
23
+
24
+ If there is an icon that is relevant to helping the user understand the Empty
25
+ State, and the layout has space to comfortably accommodate it, you can use an
26
+ icon to help add an element of “glanceability”.
27
+
28
+ When providing a title, ensure that it is succinct. It should not take up more
29
+ than 1 line on a small (320px) device, so the user can quickly assess what's
30
+ going on.
31
+
32
+ A description can be longer and provide more context or instruction, but as with
33
+ the title, keep it brief as possible so the user can spend less time reading and
34
+ more time getting into a happier state.
35
+
36
+ Action labels should be–you guessed it–short and succinct. Labels should be
37
+ clear about what will happen when the Button is pressed.
38
+
39
+ ## Accessibility
40
+
41
+ Icons are not read out by assistive technology as they are decorative in nature.
42
+
43
+ Title has a role of Heading and will be announced as such to assistive
44
+ technology like "Heading - {title content}".
45
+
46
+ Description has a role of Text and will be read to assistive technology without
47
+ any modifiers.
48
+
49
+ Actions have a role of Button and will be announced as such to assistive
50
+ technology.
51
+
52
+ ## Responsiveness
53
+
54
+ Empty State will take up as much width as possible - all UI elements will remain
55
+ in the centre as the width increases or decreases. Text-based elements will
56
+ reflow to a second line if enough content is provided.
57
+
58
+ ## Mockup
59
+
60
+
61
+ ## Props
62
+
63
+ ### Mobile
64
+
65
+ | Prop | Type | Required | Default | Description |
66
+ |------|------|----------|---------|-------------|
67
+ | `description` | `string` | No | — | Description of the empty state. |
68
+ | `icon` | `IconNames` | No | — | Icon to display. |
69
+ | `iconColor` | `"task" | "text" | "warning" | "icon" | "white" | "grey" | "greyBlue" | "greyBlueDark" | "greyBlueLighter" | "blue" | "lightBlue" | "green" | "yellow" | "red" | "navy" | "orange" | ... 33 more ... | "brandHighlight"` | No | `blue` | Color of Icon to display. |
70
+ | `primaryAction` | `Action` | No | — | Handler for the primary action. |
71
+ | `secondaryAction` | `Action` | No | — | Handler for the secondary action. |
72
+ | `title` | `string` | No | — | Title of the empty state. |
@@ -0,0 +1,37 @@
1
+ # Flex
2
+
3
+ Flex is a component that allows you to easily create a flexible layout.
4
+
5
+ ## Design & usage guidelines
6
+
7
+ The Flex component facilitates the rendering of multiple child components into a
8
+ grid layout with as many rows as needed. Each column of the Flex grid can be
9
+ programmed to take the smallest space possible or grow depending on available
10
+ space. Once the number of child components exceeds the length of the template
11
+ array, new rows will be created to accomodate the extra children, styled
12
+ similarily to the children above.
13
+
14
+ It is also possible to nest grids within each other. This can be helpful when
15
+ wanting to apply different grid styles to different groups of children. For
16
+ example, nested grids with different `align` and `template` props can be used to
17
+ further control the layout of the children.
18
+
19
+ ## Related components
20
+
21
+ Use [Grid](/components/Grid) to create grid layouts. Using Flex inside of Grid
22
+ gives you the ability to achieve complex layouts without needing custom
23
+ wrappers.
24
+
25
+ Use [Content](../Content/Content.md) to evenly space elements in a simple
26
+ one-directional layout.
27
+
28
+
29
+ ## Props
30
+
31
+ ### Mobile
32
+
33
+ | Prop | Type | Required | Default | Description |
34
+ |------|------|----------|---------|-------------|
35
+ | `align` | `FlexAlignType` | No | `center` | It works the same way as `alignItems` style with flex. |
36
+ | `gap` | `"none" | "smallest" | "smaller" | "small" | "base" | "large"` | No | `base` | The spacing between the children. |
37
+ | `template` | `ColumnKeys[]` | No | `[]` | Determine how the children gets laid out on the flex grid. If there are more Children than elements in the template, ... |
@@ -0,0 +1,126 @@
1
+ # Form
2
+
3
+ The Form component is a wrapper component that handles the submission and
4
+ validation of forms.
5
+
6
+ For more information about `validations` using any of the Input components, see
7
+ the [InputText](../InputText/InputText.md) documentation.
8
+
9
+ ## Design & usages guidelines
10
+
11
+ The Form component has a lot of built-in features which rely on its internal
12
+ state. To take advantage of these features, do not bypass the Form's internal
13
+ state — the fields or inputs within the Form must have a `name` prop and **NOT**
14
+ have a `value` and `onChange` prop.
15
+
16
+ ## Content guidelines
17
+
18
+ ### Inputs
19
+
20
+ Form can accept various inputs and selection elements such as (but not limited
21
+ to) [InputText](../InputText/InputText.md), [Select](../Select/Select.md),
22
+ [Switch](../Switch/Switch.md), [Checkbox](../Checkbox/Checkbox.md), and
23
+ [Chips](/components/Chips). They should be placed [Cards](../Card/Card.md) to
24
+ indicate grouping when relevant, and groups of Cards can be spaced appropriately
25
+ using ContentSection.
26
+
27
+ ### Save Button label
28
+
29
+ The `saveButtonLabel` property defaults to "Save", but should be made more
30
+ verbose to add context for the user. Use the format "Save {object}", such as
31
+ "Save Job". This helps clarify to the user that tapping the Save Button is not
32
+ saving the single input they are editing, but the entire object.
33
+
34
+ ### Form errors
35
+
36
+ All error messaging should follow our
37
+ [Product Vocabulary.](/content/product-vocabulary)
38
+
39
+ ## Setup (mobile)
40
+
41
+ Consuming apps using the mobile Form must wrap their app root with
42
+ `KeyboardProvider` from `react-native-keyboard-controller`.
43
+
44
+ ## Accessibility (mobile)
45
+
46
+ The individual inputs are responsible for accessibility concerns such as the
47
+ labels, types, values, and error messages of each input.
48
+
49
+
50
+ ## Platform considerations
51
+
52
+ #### iOS
53
+
54
+ On iOS, the save button will be fixed to the bottom of the viewport until the
55
+ keyboard is opened.
56
+
57
+ Once the keyboard is open, the save button will be inline beneath the Form's
58
+ inputs, unless the Form is so short that it does not scroll. In this case, the
59
+ save button will remain fixed above the keyboard.
60
+
61
+ This prevents the user from accidentally submitting the Form before they have
62
+ completed entering all the relevant information for their work, especially since
63
+ many data points in Jobber cannot be edited once saved.
64
+
65
+ #### Android
66
+
67
+ On Android, the save button will always be inline with the contents of the Form.
68
+
69
+ ### Error handling
70
+
71
+ #### Server-side errors
72
+
73
+ Server-side error messages will be displayed in a banner at the top the Form
74
+ upon a failed submission attempt. These are errors where something has gone
75
+ wrong with the data either on the way to, or on the way back from, our servers.
76
+ If the user can address the errors, inform them how to do so in the banner.
77
+ Otherwise, a generic message informing the user that something went wrong is an
78
+ appropriate fallback.
79
+
80
+ Note: When a server-side error happens, inside the `onSubmit` function, an error
81
+ must be thrown. Throwing an error inside the `onSubmit` function will ensure
82
+ that your `onSubmitError` function is called instead of your `onSubmitSuccess`.
83
+
84
+ #### Client-side errors
85
+
86
+ Client-side errors are issues that we can catch and inform the user of before
87
+ they attempt to submit the Form, such as a required field left blank or an
88
+ incorrect email address format.
89
+
90
+ Error messages for individual inputs should appear inline on each impacted
91
+ input. Form will automatically scroll to the first invalid (has an error)
92
+ element and display the error message.
93
+
94
+ When an error occurs, either server-side or client-side, Form will announce the
95
+ message to screen-readers and set focus to the impacted portion of the Form.
96
+
97
+
98
+ ## Props
99
+
100
+ ### Mobile
101
+
102
+ | Prop | Type | Required | Default | Description |
103
+ |------|------|----------|---------|-------------|
104
+ | `children` | `ReactNode` | Yes | — | Content to be passed into the form |
105
+ | `onSubmit` | `(data: T) => Promise<S>` | Yes | — | A callback function that handles the submission of form data. If an error occurs during submission, it should not be ... |
106
+ | `onSubmitError` | `(error: FormErrors) => void` | Yes | — | A callback function that handles any error that occurs during "onSubmit" |
107
+ | `onSubmitSuccess` | `(data: S) => void` | Yes | — | A callback function that handles a successful form submission from "onSubmit" |
108
+ | `bannerErrors` | `FormBannerErrors` | No | — | Network or user errors to be displayed as a banner at the top of the form |
109
+ | `bannerMessages` | `FormBannerMessage[]` | No | — | Status messages to be displayed as a banner at the top of the form |
110
+ | `disableKeyboardAwareScroll` | `boolean` | No | — | @internal Do not use this prop. It is a hack and will be removed. TODO: JOB-147156 This is a HACK for multiline input... |
111
+ | `formRef` | `RefObject<UseFormReturn<T> & { scrollViewRef?: RefObject<KeyboardAwareScrollViewRef>; saveButtonHeight?: number; messageBannerHeight?: number; }>` | No | — | ref object to access react hook form methods and state |
112
+ | `initialLoading` | `boolean` | No | — | Loading when the initial form data is being fetched |
113
+ | `initialValues` | `{ [x: string]: any; } | ((BrowserNativeObject | NestedValue) & FieldValues) | { [x: string]: any; }` | No | — | The initial values of the form inputs This should be available as soon as initialLoading is set to false |
114
+ | `localCacheExclude` | `string[]` | No | — | Forms field names that will not be considered for caching. Useful for omitting sensitive data. |
115
+ | `localCacheId` | `string | string[]` | No | — | A string or array of strings that can be used to identify the pre-filled data on the form. This can be used to suppor... |
116
+ | `localCacheKey` | `string` | No | — | Adding a key will save a local copy of the form data that will be used to recover values when the app is backgrounded... |
117
+ | `mode` | `"onBlur" | "onChange" | "onSubmit" | "onTouched" | "all"` | No | — | When the validation should happen. Possible values are "onBlur", "onChange", "onSubmit", "onTouched", and "all". The ... |
118
+ | `onBeforeSubmit` | `(data: T) => Promise<boolean>` | No | — | A callback function that is run before invoking onSubmit. Form submission is canceled if the promise resolves to false. |
119
+ | `renderFooter` | `ReactNode` | No | — | Renders a footer below the save button. |
120
+ | `renderStickySection` | `(onSubmit: () => void, label: string, isSubmitting: boolean) => ReactElement<unknown, string | JSXElementConstructor<any>>` | No | — | @deprecated use `secondaryAction` instead. Override default save button in the sticky section of the form with anothe... |
121
+ | `reValidateMode` | `"onBlur" | "onChange" | "onSubmit"` | No | — | When the validation after submission should happen. Possible values are "onBlur", "onChange", and "onSubmit". The def... |
122
+ | `saveButtonLabel` | `string` | No | — | Label to be displayed for the save button |
123
+ | `saveButtonOffset` | `number` | No | — | A number that will pull down the save button when the position is sticky. Useful when there's a footer or content bel... |
124
+ | `secondaryActions` | `SecondaryActionProp[]` | No | — | Secondary Action for ButtonGroup |
125
+ | `showStickySaveButton` | `boolean` | No | — | Forces to render the sticky save button instead of the inline. The sticky save button is default for iOS but not for ... |
126
+ | `UNSAFE_allowDiscardLocalCacheWhenOffline` | `boolean` | No | — | If true, the local cache will be removed when the user navigates away from the dirty form even when offline. By defau... |
@@ -0,0 +1,57 @@
1
+ # Form Field
2
+
3
+ FormField is a helper component that allows other components to use form logic.
4
+ Interacting with a component wrapped in a FormField will automatically update
5
+ the form value for the field used by the component.
6
+
7
+ ## Related components
8
+
9
+ Refer to the [Form](../Form/Form.md) documentation to learn more about inputs
10
+ within a form.
11
+
12
+
13
+ ## Configuration
14
+
15
+ ### Mobile
16
+
17
+ FormField should not be used to wrap separate instances of a given input
18
+ component, it should be done at the component level. For example, say you had
19
+ four SpecialInput components on a given form. Instead of the four SpecialInput
20
+ components in FormField, it would be better to go to the SpecialInput component
21
+ where it is exported and wrap it there.
22
+
23
+ ```ts
24
+ // The SpecialInput implementation, without any form logic
25
+ function SpecialInputInternal(props) {
26
+ ...
27
+ }
28
+
29
+ // This is what would be exported and used by other views or components
30
+ export function SpecialInput(props) {
31
+ return (
32
+ <FormField name={props.name}>
33
+ {(field) => {
34
+ return (
35
+ <SpecialInput
36
+ ...props
37
+ onChange={field.onChange}
38
+ value={field.value}
39
+ />
40
+ );
41
+ }}
42
+ </FormField>
43
+ );
44
+ }
45
+ ```
46
+
47
+
48
+ ## Props
49
+
50
+ ### Mobile
51
+
52
+ | Prop | Type | Required | Default | Description |
53
+ |------|------|----------|---------|-------------|
54
+ | `children` | `(field: ControllerRenderProps<FieldValues, string>, error?: FieldError) => ReactNode` | Yes | — | Children to render. |
55
+ | `name` | `string` | Yes | — | Name of the field. |
56
+ | `defaultValue` | `T` | No | — | The initial value of the form field. |
57
+ | `validations` | `RegisterOptions` | No | — | Rules for returning an error when validations are violated. WARNING: This component needs to be nested inside a FormP... |