@returnless/focus-ui 0.0.5 → 0.0.7

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 (257) hide show
  1. package/dist/components/Button/Button.vue.d.ts +4 -1
  2. package/dist/components/Button/types.d.ts +2 -0
  3. package/dist/components/Link/Link.vue.d.ts +1 -1
  4. package/dist/components/Tag/Tag.vue.d.ts +6 -2
  5. package/dist/focus-ui.js +1779 -1769
  6. package/dist/focus-ui.umd.cjs +21 -21
  7. package/package.json +2 -3
  8. package/src/build-utils/generate-component-meta.ts +0 -80
  9. package/src/build-utils/update-component-list.js +0 -31
  10. package/src/build-utils/update-component-list.ts +0 -32
  11. package/src/components/Accordion/Accordion.vue +0 -20
  12. package/src/components/Accordion/AccordionContent.vue +0 -43
  13. package/src/components/Accordion/AccordionItem.vue +0 -21
  14. package/src/components/Accordion/AccordionTrigger.vue +0 -38
  15. package/src/components/Accordion/README.md +0 -56
  16. package/src/components/Accordion/index.ts +0 -4
  17. package/src/components/ActionList/ActionList.vue +0 -9
  18. package/src/components/ActionList/ActionListBody.vue +0 -11
  19. package/src/components/ActionList/ActionListItem.vue +0 -37
  20. package/src/components/ActionList/ActionListSection.vue +0 -7
  21. package/src/components/ActionList/ActionListTrigger.vue +0 -9
  22. package/src/components/ActionList/README.md +0 -113
  23. package/src/components/ActionList/index.ts +0 -5
  24. package/src/components/Alert/Alert.vue +0 -68
  25. package/src/components/Alert/AlertDescription.vue +0 -20
  26. package/src/components/Alert/AlertTitle.vue +0 -11
  27. package/src/components/Alert/DismissableAlertButton.vue +0 -36
  28. package/src/components/Alert/README.md +0 -150
  29. package/src/components/Alert/index.ts +0 -5
  30. package/src/components/Alert/types.ts +0 -1
  31. package/src/components/AlertDialog/AlertDialog.vue +0 -54
  32. package/src/components/AlertDialog/AlertDialogActionButton.vue +0 -16
  33. package/src/components/AlertDialog/AlertDialogCancelButton.vue +0 -15
  34. package/src/components/AlertDialog/AlertDialogContent.vue +0 -8
  35. package/src/components/AlertDialog/AlertDialogDescription.vue +0 -17
  36. package/src/components/AlertDialog/AlertDialogFooter.vue +0 -11
  37. package/src/components/AlertDialog/AlertDialogHeader.vue +0 -8
  38. package/src/components/AlertDialog/AlertDialogTitle.vue +0 -15
  39. package/src/components/AlertDialog/README.md +0 -84
  40. package/src/components/AlertDialog/index.ts +0 -8
  41. package/src/components/AspectRatio/AspectRatio.vue +0 -19
  42. package/src/components/AspectRatio/README.md +0 -36
  43. package/src/components/AspectRatio/index.ts +0 -1
  44. package/src/components/Avatar/Avatar.vue +0 -122
  45. package/src/components/Avatar/README.md +0 -116
  46. package/src/components/Avatar/index.ts +0 -1
  47. package/src/components/Badge/Badge.vue +0 -51
  48. package/src/components/Badge/BadgeContent.vue +0 -9
  49. package/src/components/Badge/BadgeIcon.vue +0 -7
  50. package/src/components/Badge/README.md +0 -131
  51. package/src/components/Badge/index.ts +0 -3
  52. package/src/components/BarChart/BarChart.vue +0 -80
  53. package/src/components/BarChart/BarChartContainer.vue +0 -7
  54. package/src/components/BarChart/BarChartStacked.vue +0 -93
  55. package/src/components/BarChart/README.md +0 -83
  56. package/src/components/BarChart/index.ts +0 -3
  57. package/src/components/Breadcrumbs/Breadcrumb.vue +0 -7
  58. package/src/components/Breadcrumbs/BreadcrumbEllipsis.vue +0 -12
  59. package/src/components/Breadcrumbs/BreadcrumbItem.vue +0 -8
  60. package/src/components/Breadcrumbs/BreadcrumbLink.vue +0 -13
  61. package/src/components/Breadcrumbs/BreadcrumbList.vue +0 -8
  62. package/src/components/Breadcrumbs/BreadcrumbPage.vue +0 -13
  63. package/src/components/Breadcrumbs/BreadcrumbSeparator.vue +0 -12
  64. package/src/components/Breadcrumbs/README.md +0 -91
  65. package/src/components/Breadcrumbs/index.ts +0 -7
  66. package/src/components/Button/Button.vue +0 -75
  67. package/src/components/Button/ButtonContent.vue +0 -7
  68. package/src/components/Button/ButtonIcon.vue +0 -32
  69. package/src/components/Button/README.md +0 -231
  70. package/src/components/Button/index.ts +0 -5
  71. package/src/components/Button/types.ts +0 -30
  72. package/src/components/ButtonGroup/ButtonGroup.vue +0 -7
  73. package/src/components/ButtonGroup/README.md +0 -42
  74. package/src/components/ButtonGroup/index.ts +0 -1
  75. package/src/components/Card/Card.vue +0 -7
  76. package/src/components/Card/CardDescription.vue +0 -11
  77. package/src/components/Card/CardFooter.vue +0 -7
  78. package/src/components/Card/CardHeader.vue +0 -7
  79. package/src/components/Card/CardHelp.vue +0 -23
  80. package/src/components/Card/CardSection.vue +0 -22
  81. package/src/components/Card/CardTitle.vue +0 -11
  82. package/src/components/Card/README.md +0 -156
  83. package/src/components/Card/index.ts +0 -7
  84. package/src/components/Checkbox/Checkbox.vue +0 -73
  85. package/src/components/Checkbox/README.md +0 -111
  86. package/src/components/Checkbox/index.ts +0 -1
  87. package/src/components/Collapsible/README.md +0 -25
  88. package/src/components/DataTable/README.md +0 -56
  89. package/src/components/DatePicker/DatePicker.vue +0 -120
  90. package/src/components/DatePicker/DatePickerCard.vue +0 -9
  91. package/src/components/DatePicker/README.md +0 -59
  92. package/src/components/DatePicker/index.ts +0 -2
  93. package/src/components/DescriptionList/DescriptionList.vue +0 -18
  94. package/src/components/DescriptionList/DescriptionListDescription.vue +0 -8
  95. package/src/components/DescriptionList/DescriptionListItem.vue +0 -21
  96. package/src/components/DescriptionList/DescriptionListTerm.vue +0 -11
  97. package/src/components/DescriptionList/README.md +0 -159
  98. package/src/components/DescriptionList/index.ts +0 -4
  99. package/src/components/Dialog/README.md +0 -2
  100. package/src/components/Dialog/index.ts +0 -0
  101. package/src/components/DropZone/DropZone.vue +0 -105
  102. package/src/components/DropZone/README.md +0 -48
  103. package/src/components/DropZone/index.ts +0 -1
  104. package/src/components/EmptyState/EmptyState.vue +0 -13
  105. package/src/components/EmptyState/EmptyStateActions.vue +0 -11
  106. package/src/components/EmptyState/EmptyStateContent.vue +0 -7
  107. package/src/components/EmptyState/EmptyStateDescription.vue +0 -11
  108. package/src/components/EmptyState/EmptyStateTitle.vue +0 -7
  109. package/src/components/EmptyState/README.md +0 -102
  110. package/src/components/EmptyState/index.ts +0 -5
  111. package/src/components/Feed/Feed.vue +0 -7
  112. package/src/components/Feed/FeedItem.vue +0 -19
  113. package/src/components/Feed/FeedItemBlock.vue +0 -11
  114. package/src/components/Feed/FeedItemDateIndicator.vue +0 -11
  115. package/src/components/Feed/FeedItemIcon.vue +0 -26
  116. package/src/components/Feed/FeedItemSimple.vue +0 -8
  117. package/src/components/Feed/README.md +0 -115
  118. package/src/components/Feed/index.ts +0 -6
  119. package/src/components/FileUploadButton/FileUploadButton.vue +0 -62
  120. package/src/components/FileUploadButton/index.ts +0 -1
  121. package/src/components/Form/Form.vue +0 -35
  122. package/src/components/Form/README.md +0 -52
  123. package/src/components/Form/index.ts +0 -1
  124. package/src/components/FormLayout/FormLayout.vue +0 -25
  125. package/src/components/FormLayout/README.md +0 -97
  126. package/src/components/FormLayout/index.ts +0 -1
  127. package/src/components/Heading/Heading.vue +0 -32
  128. package/src/components/Heading/index.ts +0 -3
  129. package/src/components/Heading/types.ts +0 -3
  130. package/src/components/Image/Image.vue +0 -30
  131. package/src/components/Image/index.ts +0 -1
  132. package/src/components/InertiaLink/InertiaLink.vue +0 -11
  133. package/src/components/InertiaLink/index.ts +0 -1
  134. package/src/components/InlineError/InlineError.vue +0 -21
  135. package/src/components/InlineError/README.md +0 -63
  136. package/src/components/InlineError/index.ts +0 -1
  137. package/src/components/InputLabel/InputLabel.vue +0 -32
  138. package/src/components/InputLabel/index.ts +0 -1
  139. package/src/components/KPICard/KPICard.vue +0 -28
  140. package/src/components/KPICard/KPICardSection.vue +0 -30
  141. package/src/components/KPICard/README.md +0 -124
  142. package/src/components/KPICard/index.ts +0 -2
  143. package/src/components/Legend/Legend.vue +0 -7
  144. package/src/components/Legend/LegendItem.vue +0 -34
  145. package/src/components/Legend/README.md +0 -32
  146. package/src/components/Legend/index.ts +0 -2
  147. package/src/components/Link/Link.vue +0 -38
  148. package/src/components/Link/README.md +0 -119
  149. package/src/components/Link/index.ts +0 -1
  150. package/src/components/Navigation/Navigation.vue +0 -8
  151. package/src/components/Navigation/NavigationItem.vue +0 -47
  152. package/src/components/Navigation/NavigationSecondarySection.vue +0 -12
  153. package/src/components/Navigation/NavigationSection.vue +0 -27
  154. package/src/components/Navigation/README.md +0 -83
  155. package/src/components/Navigation/index.ts +0 -4
  156. package/src/components/Page/Page.vue +0 -7
  157. package/src/components/Page/PageBody.vue +0 -36
  158. package/src/components/Page/PageDescription.vue +0 -11
  159. package/src/components/Page/PageHeader.vue +0 -34
  160. package/src/components/Page/PageTitle.vue +0 -12
  161. package/src/components/Page/README.md +0 -226
  162. package/src/components/Page/index.ts +0 -5
  163. package/src/components/Pagination/Pagination.vue +0 -8
  164. package/src/components/Pagination/PaginationNextButton.vue +0 -10
  165. package/src/components/Pagination/PaginationPreviousButton.vue +0 -10
  166. package/src/components/Pagination/README.md +0 -45
  167. package/src/components/Pagination/index.ts +0 -3
  168. package/src/components/PinInput/PinInput.vue +0 -169
  169. package/src/components/PinInput/README.md +0 -35
  170. package/src/components/PinInput/index.ts +0 -1
  171. package/src/components/Popover/Popover.vue +0 -18
  172. package/src/components/Popover/PopoverBody.vue +0 -11
  173. package/src/components/Popover/PopoverTrigger.vue +0 -9
  174. package/src/components/Popover/README.md +0 -79
  175. package/src/components/Popover/index.ts +0 -3
  176. package/src/components/Popper/Popper.vue +0 -91
  177. package/src/components/Popper/PopperBody.vue +0 -19
  178. package/src/components/Popper/PopperTrigger.vue +0 -14
  179. package/src/components/Popper/README.md +0 -42
  180. package/src/components/Popper/index.ts +0 -3
  181. package/src/components/ProgressBar/ProgressBar.vue +0 -51
  182. package/src/components/ProgressBar/ProgressBarIndicator.vue +0 -7
  183. package/src/components/ProgressBar/README.md +0 -98
  184. package/src/components/ProgressBar/index.ts +0 -2
  185. package/src/components/RadioButton/README.md +0 -111
  186. package/src/components/RadioButton/RadioButton.vue +0 -49
  187. package/src/components/RadioButton/index.ts +0 -1
  188. package/src/components/ResourceList/README.md +0 -160
  189. package/src/components/ResourceList/ResourceList.vue +0 -7
  190. package/src/components/ResourceList/ResourceListItem.vue +0 -7
  191. package/src/components/ResourceList/ResourceListItemContent.vue +0 -7
  192. package/src/components/ResourceList/index.ts +0 -3
  193. package/src/components/Select/README.md +0 -74
  194. package/src/components/Select/Select.vue +0 -91
  195. package/src/components/Select/SelectGroup.vue +0 -12
  196. package/src/components/Select/SelectOption.vue +0 -12
  197. package/src/components/Select/index.ts +0 -3
  198. package/src/components/Separator/README.md +0 -39
  199. package/src/components/Separator/Separator.vue +0 -24
  200. package/src/components/Separator/index.ts +0 -1
  201. package/src/components/Spinner/README.md +0 -53
  202. package/src/components/Spinner/Spinner.vue +0 -64
  203. package/src/components/Spinner/index.ts +0 -1
  204. package/src/components/StatusIndicator/README.md +0 -51
  205. package/src/components/StatusIndicator/StatusIndicator.vue +0 -44
  206. package/src/components/StatusIndicator/index.ts +0 -1
  207. package/src/components/Stepper/README.md +0 -38
  208. package/src/components/Stepper/Stepper.vue +0 -104
  209. package/src/components/Stepper/index.ts +0 -1
  210. package/src/components/Tabs/README.md +0 -53
  211. package/src/components/Tabs/TabTrigger.vue +0 -44
  212. package/src/components/Tabs/Tabs.vue +0 -16
  213. package/src/components/Tabs/index.ts +0 -2
  214. package/src/components/Tag/README.md +0 -27
  215. package/src/components/Tag/Tag.vue +0 -45
  216. package/src/components/Tag/index.ts +0 -1
  217. package/src/components/TextField/README.md +0 -335
  218. package/src/components/TextField/TextField.vue +0 -135
  219. package/src/components/TextField/TextFieldIcon.vue +0 -19
  220. package/src/components/TextField/TextFieldPasswordIcon.vue +0 -28
  221. package/src/components/TextField/TextFieldSearchIcon.vue +0 -11
  222. package/src/components/TextField/index.ts +0 -1
  223. package/src/components/TextStyle/README.md +0 -39
  224. package/src/components/TextStyle/TextStyle.vue +0 -24
  225. package/src/components/TextStyle/index.ts +0 -1
  226. package/src/components/Toast/DismissToastAction.vue +0 -34
  227. package/src/components/Toast/README.md +0 -167
  228. package/src/components/Toast/Toast.vue +0 -39
  229. package/src/components/Toast/ToastGroup.vue +0 -9
  230. package/src/components/Toast/index.ts +0 -2
  231. package/src/components/Toggle/README.md +0 -66
  232. package/src/components/Toggle/Toggle.vue +0 -89
  233. package/src/components/Toggle/index.ts +0 -1
  234. package/src/components/Tooltip/README.md +0 -51
  235. package/src/components/Tooltip/Tooltip.vue +0 -24
  236. package/src/components/Tooltip/index.ts +0 -1
  237. package/src/components/TopBar/README.md +0 -43
  238. package/src/components/TopBar/TopBar.vue +0 -7
  239. package/src/components/TopBar/TopBarLogo.vue +0 -8
  240. package/src/components/TopBar/TopBarNavigation.vue +0 -7
  241. package/src/components/TopBar/TopBarNavigationItem.vue +0 -13
  242. package/src/components/TopBar/TopBarSearch.vue +0 -15
  243. package/src/components/TopBar/TopBarUserMenu.vue +0 -20
  244. package/src/components/TopBar/index.ts +0 -6
  245. package/src/components/VisuallyHidden/README.md +0 -19
  246. package/src/components/VisuallyHidden/VisuallyHidden.vue +0 -25
  247. package/src/components/VisuallyHidden/index.ts +0 -1
  248. package/src/components/index.ts +0 -197
  249. package/src/components/types.ts +0 -5
  250. package/src/composables/index.ts +0 -7
  251. package/src/composables/useTailwindColor.ts +0 -17
  252. package/src/composables/useTheme.ts +0 -41
  253. package/src/composables/useToastNotifications.ts +0 -55
  254. package/src/composables/useUniqueId.ts +0 -6
  255. package/src/index.css +0 -24
  256. package/src/index.ts +0 -1
  257. package/src/vite-env.d.ts +0 -1
@@ -1,44 +0,0 @@
1
- <script lang="ts" setup>
2
- import { TextStyle } from '../TextStyle';
3
- import { computed, inject, onMounted, Ref } from 'vue';
4
- import { useUniqueId } from '../../composables';
5
-
6
- const props = withDefaults(defineProps<{
7
- /** Whether the tab item is active */
8
- active?: boolean;
9
- }>(), {
10
- active: false,
11
- });
12
-
13
- const tabItemId = useUniqueId('tabItem');
14
- const activeTabItem = inject<Ref<string>>('activeTabItem')!;
15
-
16
- onMounted((): void => {
17
- if (props.active) {
18
- activeTabItem.value = tabItemId;
19
- }
20
- });
21
-
22
- function toggleTabItem(): void {
23
- activeTabItem.value = tabItemId;
24
- }
25
-
26
- const classList = computed((): Record<string, boolean>[] => {
27
- return [
28
- { 'bg-white shadow': activeTabItem.value === tabItemId },
29
- ];
30
- });
31
- </script>
32
-
33
- <template>
34
- <button
35
- :class="classList"
36
- class="rounded px-3 py-2"
37
- role="tab"
38
- @click="toggleTabItem"
39
- >
40
- <TextStyle variant="strong">
41
- <slot />
42
- </TextStyle>
43
- </button>
44
- </template>
@@ -1,16 +0,0 @@
1
- <script lang="ts" setup>
2
- import { provide, ref } from 'vue';
3
-
4
- const activeTabItem = ref<string | null>(null);
5
-
6
- provide('activeTabItem', activeTabItem);
7
- </script>
8
-
9
- <template>
10
- <div
11
- class="inline-flex rounded-md bg-slate-200 p-1"
12
- role="tablist"
13
- >
14
- <slot />
15
- </div>
16
- </template>
@@ -1,2 +0,0 @@
1
- export { default as Tabs } from './Tabs.vue';
2
- export { default as TabTrigger } from './TabTrigger.vue';
@@ -1,27 +0,0 @@
1
- # Tag
2
-
3
- Tags represent a set of interactive, user-supplied keywords that help label, organize, and categorize objects. Tags can
4
- be added or removed from an object by users.
5
-
6
- ## Best practices
7
-
8
- Tags should:
9
-
10
- - Be presented close to or within the input control that allows users to add and remove tags.
11
-
12
- ## Accessibility
13
-
14
- ### Labeling
15
-
16
- The button to remove a tag is automatically given a label using `aria-label` so that screen reader users can
17
- distinguish which tag will be removed.
18
-
19
- ### Keyboard support
20
-
21
- The control to remove a tag is implemented as a button with standard keyboard support.
22
-
23
- - Give buttons keyboard focus with the tab key (or shift + tab when navigating backwards).
24
- - To activate a button, press the enter/return or space key.
25
-
26
- When a user uses the button to remove a tag, it is important to make sure that keyboard focus is managed. Moving
27
- focus to the next element in the page is recommended.
@@ -1,45 +0,0 @@
1
- <script lang="ts" setup>
2
- import { TailwindColor, useTailwindColor } from '../../composables';
3
- import { computed, CSSProperties } from 'vue';
4
- import { TextStyle } from '../TextStyle';
5
- import { VisuallyHidden } from '../VisuallyHidden';
6
- import { XMarkIcon } from '@heroicons/vue/16/solid';
7
-
8
- const props = withDefaults(defineProps<{
9
- /** Accessible label for the avatar image. */
10
- accessibilityLabel?: string | null;
11
-
12
- /** The color of the badge. */
13
- color: TailwindColor;
14
- }>(), {
15
- accessibilityLabel: null,
16
- });
17
-
18
- const colorValues = computed((): CSSProperties => {
19
- return {
20
- backgroundColor: useTailwindColor(props.color, '200'),
21
- color: useTailwindColor(props.color, '900'),
22
- };
23
- });
24
- </script>
25
-
26
- <template>
27
- <span
28
- class="text-xs px-2 py-1 inline-flex items-center rounded bg-slate-200"
29
- :style="colorValues"
30
- >
31
- <TextStyle variant="strong">
32
- <div class="flex items-center space-x-2">
33
- <slot />
34
- </div>
35
- </TextStyle>
36
-
37
- <span
38
- class="rounded flex items-center cursor-pointer ml-1"
39
- >
40
- <XMarkIcon class="w-4 h-4" />
41
- </span>
42
-
43
- <VisuallyHidden v-if="accessibilityLabel">{{ accessibilityLabel }}</VisuallyHidden>
44
- </span>
45
- </template>
@@ -1 +0,0 @@
1
- export { default as Tag } from './Tag.vue';
@@ -1,335 +0,0 @@
1
- <script lang="ts" setup>
2
- import { TextField } from '../../src/components';
3
- import api from '../component-meta/TextField.json';
4
- </script>
5
-
6
- # Text field
7
-
8
- a text field is an input field that users can type into. It has a range of options and supports several text formats
9
- including numbers.
10
-
11
- <ComponentApi :api="api" />
12
-
13
- ## Usage
14
-
15
- Use to allow users to provide text input when the expected input is short. For longer input, use the auto grow or
16
- multiline options.
17
-
18
- <ComponentWrapper>
19
- <TextField name="first_name" label="First name" />
20
- </ComponentWrapper>
21
-
22
- ```js-vue
23
- <script lang="ts" setup>
24
- import { TextField } from '@returnless/focus-ui';
25
- </script>
26
-
27
- <template>
28
- <TextField label="First name" />
29
- </template>
30
- ```
31
-
32
- ### Field with help-text
33
-
34
- Use to provide additional information about the expected input. Help text is always visible, so don’t rely on it for
35
- important information.
36
-
37
- <ComponentWrapper>
38
- <TextField name="first_name" label="First name" help-text="Fill in your first name" />
39
- </ComponentWrapper>
40
-
41
- ```js-vue
42
- <script lang="ts" setup>
43
- import { TextField } from '@returnless/focus-ui';
44
- </script>
45
-
46
- <template>
47
- <TextField label="First name" />
48
- </template>
49
- ```
50
-
51
- ### Field with placeholder
52
-
53
- Use to provide a short, non-essential hint about the expected input. Placeholder text is low-contrast, so don’t rely on
54
- it for important information.
55
-
56
- <ComponentWrapper>
57
- <TextField name="shipping_zone" label="Shipping zone" placeholder="Example: North America, Europe" />
58
- </ComponentWrapper>
59
-
60
- ```js-vue
61
- <script lang="ts" setup>
62
- import { TextField } from '@returnless/focus-ui';
63
- </script>
64
-
65
- <template>
66
- <TextField label="Shipping zone" placeholder="Example: North America, Europe" />
67
- </template>
68
- ```
69
-
70
- ### Search field
71
-
72
- Use to allow users to search for a specific item or category. Search fields are typically used in the header of an
73
- application.
74
-
75
- <ComponentWrapper>
76
- <TextField name="search" type="search" label="Search" placeholder="Search…" label-hidden />
77
- </ComponentWrapper>
78
-
79
- ```js-vue
80
- <script lang="ts" setup>
81
- import { TextField } from '@returnless/focus-ui';
82
- </script>
83
-
84
- <template>
85
- <TextField type="password" label="Password" />
86
- </template>
87
- ```
88
-
89
- ### Password field
90
-
91
- <ComponentWrapper>
92
- <TextField name="password" type="password" label="Password" />
93
- </ComponentWrapper>
94
-
95
- ```js-vue
96
- <script lang="ts" setup>
97
- import { TextField } from '@returnless/focus-ui';
98
- </script>
99
-
100
- <template>
101
- <TextField type="password" label="Password" />
102
- </template>
103
- ```
104
-
105
- ### Textarea
106
-
107
- <ComponentWrapper>
108
- <TextField multiline name="textarea" label="Textarea" rows="5" />
109
- </ComponentWrapper>
110
-
111
- ```js-vue
112
- <script lang="ts" setup>
113
- import { TextField } from '@returnless/focus-ui';
114
- </script>
115
-
116
- <template>
117
- <TextField multiline name="textarea" label="Textarea" rows="5" />
118
- </template>
119
- ```
120
-
121
- ### With error
122
-
123
- Use to indicate that there is a problem with the input. Error messages should be concise and helpful.
124
-
125
- <ComponentWrapper>
126
- <TextField name="element_with_error" label="Store name" error="Store name is required" />
127
- </ComponentWrapper>
128
-
129
- ```js-vue
130
- <script lang="ts" setup>
131
- import { TextField } from '@returnless/focus-ui';
132
- </script>
133
-
134
- <template>
135
- <TextField multiline name="textarea" label="Textarea" rows="5" />
136
- </template>
137
- ```
138
-
139
- ## Best practices
140
-
141
- Text fields should:
142
-
143
- - Be clearly labeled, so it's obvious to users what they should enter into a field.
144
- - Be labeled as "Optional" when you need to request input that's not request.
145
- - Only ask for information that's really needed.
146
- - Validate input as soon as users have finished interacting with a field (but not before).
147
-
148
- ### Autocomplete
149
-
150
- The autocomplete attribute in an `input` field controls two types of browser behaviour:
151
-
152
- 1. **Browser autofill**: a feature that automatically populates form fields with previously-saved information, such
153
- as passwords, addresses, and credit card data.
154
-
155
- - Autofill is an important feature for users. Google has found
156
- that [users complete forms 30% faster](https://developers.google.com/web/updates/2015/06/checkout-faster-with-autofill?hl=en)
157
- when using autofill.
158
- - The WHATWG has a list of supported autofill values for the `autocomplete` attribute. [Review the section "4.10.
159
- 18.7 Autofill](https://polaris.shopify.com/components/selection-and-input/text-field#:~:text=Review%20the%20section%20%224.10.18.7%20Autofill%22)
160
- for all the input types and their corresponding autocomplete attribute values.
161
-
162
- 2. Browser autocomplete: a feature that displays previously submitted values for that field.
163
-
164
- - When this is on for a field, a user is presented with a list of previously submitted values for the input.
165
-
166
- Always add an autocomplete attribute and value to inputs if the type is: color, date, datetime-local, email, month,
167
- number, password, range, search, tel, text, time, url, or week.
168
-
169
- ### Turning autofill/autocomplete off
170
-
171
- Even if you do not want the browser to autofill a user's information, it is recommended you still have an
172
- autocomplete attribute with the value "off" or "nope".
173
-
174
- Unfortunately, [not all browsers support](https://polaris.shopify.com/components/selection-and-input/text-field#:~:text=not%20all%20browsers%20support)
175
- or respect autocomplete="off". This makes things challenging. Chrome, for
176
- example, [has a long outstanding bug](https://polaris.shopify.com/components/selection-and-input/text-field#:~:text=has%20a%20long%20outstanding%20bug)
177
- and won't add support for "off" for now.
178
-
179
- Chrome does seem to turn autocomplete off when using the value nope (or any non-valid string). However, we have seen
180
- some inconsistencies even with that support.
181
-
182
- ## Content guidelines
183
-
184
- Text fields can be grouped in a form or placed individually in the UI. Placeholder text should generally be avoided
185
- in text fields. Help text can be used below the text input area to guide the user on acceptable inputs.
186
-
187
- ### Field labels
188
-
189
- Field labels act as a title for the text field. Labels should typically be short and in noun form. For example, "Name".
190
-
191
- ### Placeholder text
192
-
193
- In general, avoid using placeholder text in text fields. It can pose a range of accessibility problems, like:
194
-
195
- - Low color contrast, making the text hard to read.
196
- - Inconsistent behaviour between browsers and screen readers.
197
- - Text disappearing when the user starts typing, which can be confusing to people with cognitive impairments.
198
- - Limited space available for additional content, due to field size.
199
-
200
- Exception: read the guidelines on [search fields].
201
-
202
- ### Help text
203
-
204
- Help text provides extra guidance or instructions to people filling out a form field. It and also be used to clarify
205
- how the information will be used.
206
-
207
- Use help text:
208
-
209
- - When the text field label doesn't clearly explain the purpose of the text input.
210
- - To provide guidance or instructions on the type of information needed.
211
- - To show examples of the required format for modeled text inputs.
212
-
213
- Best practices for help text:
214
-
215
- - Avoid repeating the field label. If the field label provides sufficient context for completing the action, then
216
- you likely don't need to add help text.
217
- - If there's not enough room to include both instructions and an example, then only include the example.
218
-
219
- ### Text input types
220
-
221
- There are three types of text inputs:
222
-
223
- 1. **Modeled text inputs**: These are fields that require a specific format to be valid. They're often used for tags,
224
- dates, and some tracking numbers. Modeled text is highly structured, so providing examples is useful.
225
- 2. **Free text inputs**: These are fields that accept short strings of text. They're often used for SKU's, barcodes,
226
- and titles. Only provide example text if you know how the text should be structured, such as a tracking number of
227
- discount code.
228
- 3. Multiline text inputs: These are fields that are rendered as multiline textarea elements, as well as text input
229
- elements that accept long strings of text. They're often used for product descriptions, order comments, and
230
- customer notes. Users can write whatever they want, so providing example text is less useful.
231
-
232
- ### Modeled text inputs
233
-
234
- Modeled text inputs are text field inputs that require text to be formatted in a specific way. For instance, tags
235
- need to be separated by commas, and dates need to be typed in YYYY-MM-DD format. Because modeled text inputs
236
- require a particular structure, always include examples that demonstrate how the user should enter the information.
237
-
238
- - Use help text to include an instructional call to action and an example that shows the required text format.
239
- - If there's not enough room to include both an instructional call to action and an example, then include only the
240
- example.
241
- - Use the word "Example" followed by a colon to introduce the example.
242
-
243
- ### Free text inputs
244
-
245
- Free text inputs accept a single string of text, without any particular structure. Use the field label to clearly
246
- indicate what should go in the text field.
247
-
248
- Don't provide an example for free text inputs. The text doesn't follow a specific format, and we shouldn't assume
249
- what belongs in the field. If more context is needed, use help text.
250
-
251
- #### Avoid redundancy
252
-
253
- If a text field label has a call to action, there's no need to repeat it in the help text. Instead, add a sentence
254
- that provides extra context.
255
-
256
- For example, when a free text input is located independent of a form and has no surrounding context, you can make
257
- the field label a call to action.
258
-
259
- #### Point in the right direction
260
-
261
- If the text field label isn't clear about where the user can find the information, use help text to guide them.
262
-
263
- ### Titles, names, and descriptions
264
-
265
- Don't use placeholder text for free input titles, names, and descriptions; use help text instead.
266
-
267
- ### Codes and tracking numbers
268
-
269
- Don't use placeholder text for codes or tracking numbers; use help text instead. If the code follows a standardized
270
- format, include an example, using the same format as help text for modeled content. If not, omit the example since
271
- the field's content can vary.
272
-
273
- Choose clear names for the field label, and don't repeat it in the help text if possible. Instead, offer context
274
- that will help the user understand and complete the task quickly.
275
-
276
- ### Multiline text inputs
277
-
278
- Multiline fields let users type long blocks of text. There are a few different versions:
279
-
280
- - Plain textarea elements with no formatting options.
281
- - Formatted textarea elements with what-you-see-is-what-you-get (WYSIWYG) menus.
282
- - Plain text input elements that accept long strings of text.
283
- - Plain text input elements that accept long strings of text and expand as the user types.
284
-
285
- Multiline inputs hold things like product and collection descriptions, notes about an order, and anything else the
286
- user wants to type into them.
287
-
288
- We usually don't know what will go in multiline fields, so providing example text isn't helpful. Instead, include
289
- help text that explains how the text will be used and who can view it.
290
-
291
- ## Accessibility
292
-
293
- ### Structure
294
-
295
- Screen readers convey information about text fields automatically through native HTML.
296
-
297
- - Use the `disabled` prop to add the HTML `disabled` attribute to the text field.
298
- - Use the `readOnly` prop to add the HTML `readonly` attribute to the text field.
299
- - If you use the `type` prop, then some assistive technologies will adept the software keyboard to the current task.
300
- This helps users with mobility, vision, and cognitive issues to enter information more easily.
301
-
302
- Use the `id` prop to provide a unique `id` attribute value for the text field. If you don't provide an `id`, then
303
- the component generates one automatically. All text fields need to have unique `id` values.
304
-
305
- ### Labeling
306
-
307
- The `label` prop is required to convey the purpose of the checkbox to all users.
308
-
309
- If there are separate visual cues that convey the purpose of the text field to sighted users, then the label can be
310
- visually hidden with the `labelHidden` prop.
311
-
312
- When you provide help text via the `helpText` prop or an inline error message via the `error` prop, the help or
313
- error content is conveyed to screen reader users with the `aria-describedby` attribute. This attribute causes the
314
- content to be read along with the label, either immediately or after a short delay.
315
-
316
- Use the `placeholder` prop to provide additional instructions. However, don't rely on placeholders alon since the
317
- content isn't always conveyed.
318
-
319
- ### Keyboard support
320
-
321
- Text fields have standard keyboard support.
322
-
323
- - Users who rely on the keyboard expect to move focus to each text field using the tab key (or shift + tab when
324
- tabbing backwards).
325
- - If the `type` is set to `number`, then users can use the up and down arrow keys to adjust the value typed into the
326
- field when hovering over or focusing the field to make the arrows appear.
327
- - Using the `disabled` prop will prevent the text field from receiving focus, and users won't be able to interact
328
- with it using the keyboard.
329
- - The `readOnly` prop allows focus on the text field but prevents input or editing.
330
-
331
- ### Automatically focusing
332
-
333
- Although you can use the `autoFocus` prop to automatically move focus to the text field, it's generally best to
334
- avoid focusing on fields automatically. The `autoFocus` prop is set to `false` by default and should only be used in
335
- cases where it won't force focus to skip other controls or content of equal or greater importance.
@@ -1,135 +0,0 @@
1
- <script lang="ts" setup>
2
- import { computed, provide, ref } from 'vue';
3
- import { InputLabel } from '../InputLabel';
4
- import { InlineError } from '../InlineError';
5
- import { useTheme, useUniqueId } from '../../composables';
6
- import TextFieldIcon from './TextFieldIcon.vue';
7
- import TextFieldPasswordIcon from './TextFieldPasswordIcon.vue';
8
- import TextFieldSearchIcon from './TextFieldSearchIcon.vue';
9
-
10
- const props = withDefaults(defineProps<{
11
- /** Enable automatic completion by the browser. Set to "off" when you do not want the browser to fill in info */
12
- autoComplete?: string | null;
13
-
14
- /** Whether the input is disabled. */
15
- disabled?: boolean;
16
-
17
- /** The error to display below the input. */
18
- error?: string | null;
19
-
20
- /** The help text to display below the input. */
21
- helpText?: string | null;
22
-
23
- /** The icon to display inside the input. */
24
- icon?: (() => void) | string | undefined;
25
-
26
- /** The ID of the input the label is associated with. */
27
- id?: string | null;
28
-
29
- /** The label text. */
30
- label: string;
31
-
32
- /** Whether the label is hidden. */
33
- labelHidden?: boolean;
34
-
35
- /** Whether the input is a textarea. */
36
- multiline?: boolean;
37
-
38
- /** The name of the input. */
39
- name: string;
40
-
41
- /** The placeholder text. */
42
- placeholder?: string | null;
43
-
44
- /** Whether the input is read-only. */
45
- readonly?: boolean;
46
-
47
- /** Whether the input is required. */
48
- required?: boolean;
49
-
50
- /** The type of the input. */
51
- type?: 'text' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'url' | 'date' | 'datetime-local' | 'month' | 'time' | 'week' | 'currency';
52
- }>(), {
53
- autoComplete: null,
54
- disabled: false,
55
- error: null,
56
- helpText: null,
57
- icon: undefined,
58
- id: null,
59
- labelHidden: false,
60
- multiline: false,
61
- placeholder: null,
62
- readonly: false,
63
- required: false,
64
- type: 'text',
65
- });
66
-
67
- const model = defineModel<string>();
68
-
69
- const internalInputType = ref(props.type);
70
-
71
- const elementId = props.id || useUniqueId('textField');
72
-
73
- const classList = computed((): Record<string, boolean>[] => {
74
- return [
75
- { 'pl-10': props.type === 'search' || props.icon !== undefined },
76
- ];
77
- });
78
-
79
- const componentType = computed((): string => {
80
- return props.multiline ? 'textarea' : 'input';
81
- });
82
-
83
- provide('internalInputType', internalInputType);
84
- </script>
85
-
86
- <template>
87
- <div class="w-full space-y-1">
88
- <InputLabel
89
- :id="`${elementId}-label`"
90
- :label="label"
91
- :label-for="elementId"
92
- :label-hidden="labelHidden"
93
- />
94
-
95
- <div
96
- :class="[useTheme('focusWithin'), { 'border-red-500': error }]"
97
- class="relative flex w-full items-center overflow-hidden rounded border bg-white shadow-sm"
98
- >
99
- <component
100
- :is="componentType"
101
- :id="elementId"
102
- :aria-disabled="disabled"
103
- :aria-labelledby="`${elementId}-label`"
104
- :aria-readonly="readonly"
105
- :aria-required="required"
106
- :autocomplete="autoComplete"
107
- :class="classList"
108
- :disabled="disabled"
109
- :placeholder="placeholder"
110
- :readonly="readonly"
111
- :type="internalInputType"
112
- :value="model"
113
- class="block w-full appearance-none border-none px-3 py-2 placeholder:text-slate-400 text-slate-700 outline-none placeholder-slate-400 disabled:cursor-not-allowed disabled:bg-slate-50"
114
- v-bind="$attrs"
115
- @input="model = $event.target.value"
116
- />
117
- <TextFieldIcon
118
- v-if="icon"
119
- :icon="icon"
120
- />
121
- <TextFieldSearchIcon v-if="type === 'search'" />
122
- <TextFieldPasswordIcon v-if="type === 'password' && model" />
123
- </div>
124
-
125
- <InlineError
126
- v-if="error"
127
- id="test"
128
- :message="error"
129
- />
130
-
131
- <p class="text-sm text-slate-500">
132
- {{ helpText }}
133
- </p>
134
- </div>
135
- </template>
@@ -1,19 +0,0 @@
1
- <script lang="ts" setup>
2
- defineProps<{
3
- icon: (() => void) | string;
4
- }>();
5
- </script>
6
-
7
- <template>
8
- <span
9
- v-if="icon"
10
- class="w-4 h-4 absolute left-4 text-slate-500 leading-4"
11
- >
12
- <component
13
- :is="icon"
14
- v-if="icon && typeof icon === 'function'"
15
- class=""
16
- />
17
- <span v-if="icon && typeof icon === 'string'">{{ icon }}</span>
18
- </span>
19
- </template>
@@ -1,28 +0,0 @@
1
- <script lang="ts" setup>
2
- import { EyeIcon, EyeSlashIcon } from '@heroicons/vue/16/solid';
3
- import { inject, Ref } from 'vue';
4
-
5
- const internalInputType = inject<Ref<string>>('internalInputType')!;
6
-
7
- function toggleInternalPasswordType(): void {
8
- internalInputType.value = internalInputType.value === 'password'
9
- ? 'text'
10
- : 'password';
11
- }
12
- </script>
13
-
14
- <template>
15
- <div
16
- class="cursor-pointer rounded bg-slate-200 p-1 text-xs font-medium leading-none mr-1.5 hover:opacity-80"
17
- @click="toggleInternalPasswordType()"
18
- >
19
- <EyeSlashIcon
20
- v-if="internalInputType !== 'password'"
21
- class="h-4 w-4"
22
- />
23
- <EyeIcon
24
- v-if="internalInputType === 'password'"
25
- class="h-4 w-4"
26
- />
27
- </div>
28
- </template>
@@ -1,11 +0,0 @@
1
- <script setup lang="ts">
2
- import { MagnifyingGlassIcon } from '@heroicons/vue/16/solid';
3
- </script>
4
-
5
- <template>
6
- <div
7
- class="w-4 h-4 absolute left-4"
8
- >
9
- <MagnifyingGlassIcon />
10
- </div>
11
- </template>
@@ -1 +0,0 @@
1
- export { default as TextField } from './TextField.vue';