@returnless/focus-ui 0.0.1 → 0.0.3

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 (186) hide show
  1. package/dist/focus-ui.js +10851 -0
  2. package/dist/focus-ui.umd.cjs +26 -0
  3. package/dist/style.css +1 -0
  4. package/package.json +13 -8
  5. package/src/build-utils/generate-component-meta.ts +5 -1
  6. package/src/build-utils/update-component-list.ts +1 -1
  7. package/src/components/Accordion/AccordionContent.vue +34 -5
  8. package/src/components/Accordion/AccordionItem.vue +5 -2
  9. package/src/components/Accordion/AccordionTrigger.vue +5 -2
  10. package/src/components/Accordion/README.md +1 -1
  11. package/src/components/ActionList/ActionList.vue +9 -0
  12. package/src/components/ActionList/ActionListBody.vue +11 -0
  13. package/src/components/ActionList/ActionListItem.vue +37 -0
  14. package/src/components/ActionList/ActionListSection.vue +7 -0
  15. package/src/components/ActionList/ActionListTrigger.vue +9 -0
  16. package/src/components/ActionList/README.md +113 -0
  17. package/src/components/ActionList/index.ts +5 -0
  18. package/src/components/Alert/Alert.vue +23 -10
  19. package/src/components/Alert/AlertDescription.vue +13 -1
  20. package/src/components/Alert/AlertTitle.vue +1 -1
  21. package/src/components/Alert/DismissableAlertButton.vue +6 -4
  22. package/src/components/Alert/README.md +31 -2
  23. package/src/components/Alert/index.ts +2 -0
  24. package/src/components/Alert/types.ts +1 -0
  25. package/src/components/AlertDialog/AlertDialog.vue +10 -1
  26. package/src/components/AlertDialog/AlertDialogActionButton.vue +9 -2
  27. package/src/components/AlertDialog/AlertDialogCancelButton.vue +1 -1
  28. package/src/components/AlertDialog/AlertDialogDescription.vue +7 -1
  29. package/src/components/AlertDialog/AlertDialogTitle.vue +11 -3
  30. package/src/components/AlertDialog/README.md +15 -16
  31. package/src/components/AspectRatio/AspectRatio.vue +19 -0
  32. package/src/components/AspectRatio/README.md +36 -0
  33. package/src/components/AspectRatio/index.ts +1 -0
  34. package/src/components/Avatar/Avatar.vue +57 -13
  35. package/src/components/Avatar/README.md +3 -9
  36. package/src/components/Badge/Badge.vue +1 -1
  37. package/src/components/Badge/README.md +9 -9
  38. package/src/components/BarChart/BarChart.vue +80 -0
  39. package/src/components/{MetricCard/MetricCardHeader.vue → BarChart/BarChartContainer.vue} +1 -1
  40. package/src/components/BarChart/BarChartStacked.vue +93 -0
  41. package/src/components/BarChart/README.md +83 -0
  42. package/src/components/BarChart/index.ts +3 -0
  43. package/src/components/Breadcrumbs/Breadcrumb.vue +7 -0
  44. package/src/components/Breadcrumbs/BreadcrumbEllipsis.vue +12 -0
  45. package/src/components/{MetricCard/MetricCardValue.vue → Breadcrumbs/BreadcrumbItem.vue} +2 -2
  46. package/src/components/Breadcrumbs/BreadcrumbLink.vue +13 -0
  47. package/src/components/Breadcrumbs/BreadcrumbList.vue +8 -0
  48. package/src/components/Breadcrumbs/BreadcrumbPage.vue +13 -0
  49. package/src/components/Breadcrumbs/BreadcrumbSeparator.vue +12 -0
  50. package/src/components/Breadcrumbs/README.md +91 -0
  51. package/src/components/Breadcrumbs/index.ts +7 -0
  52. package/src/components/Button/Button.vue +53 -41
  53. package/src/components/Button/ButtonContent.vue +1 -1
  54. package/src/components/Button/ButtonIcon.vue +28 -3
  55. package/src/components/Button/README.md +32 -29
  56. package/src/components/Button/index.ts +2 -0
  57. package/src/components/Button/types.ts +30 -0
  58. package/src/components/ButtonGroup/README.md +1 -1
  59. package/src/components/Card/CardHelp.vue +23 -0
  60. package/src/components/Card/CardSection.vue +17 -2
  61. package/src/components/Card/CardTitle.vue +6 -3
  62. package/src/components/Card/README.md +97 -10
  63. package/src/components/Card/index.ts +2 -1
  64. package/src/components/Checkbox/Checkbox.vue +29 -5
  65. package/src/components/Checkbox/README.md +34 -5
  66. package/src/components/DatePicker/DatePicker.vue +7 -27
  67. package/src/components/DatePicker/README.md +1 -1
  68. package/src/components/DescriptionList/DescriptionList.vue +1 -1
  69. package/src/components/DescriptionList/DescriptionListItem.vue +1 -1
  70. package/src/components/DescriptionList/README.md +2 -2
  71. package/src/components/Dialog/README.md +2 -0
  72. package/src/components/Dialog/index.ts +0 -0
  73. package/src/components/DropZone/DropZone.vue +105 -0
  74. package/src/components/DropZone/README.md +48 -0
  75. package/src/components/DropZone/index.ts +1 -0
  76. package/src/components/EmptyState/README.md +1 -1
  77. package/src/components/Feed/FeedItem.vue +4 -1
  78. package/src/components/Feed/FeedItemBlock.vue +4 -1
  79. package/src/components/Feed/README.md +1 -1
  80. package/src/components/FileUploadButton/FileUploadButton.vue +62 -0
  81. package/src/components/FileUploadButton/index.ts +1 -0
  82. package/src/components/Form/Form.vue +7 -2
  83. package/src/components/Form/README.md +1 -1
  84. package/src/components/FormLayout/FormLayout.vue +20 -2
  85. package/src/components/FormLayout/README.md +39 -1
  86. package/src/components/Heading/Heading.vue +32 -0
  87. package/src/components/Heading/index.ts +3 -0
  88. package/src/components/Heading/types.ts +3 -0
  89. package/src/components/Image/Image.vue +30 -0
  90. package/src/components/Image/index.ts +1 -0
  91. package/src/components/InertiaLink/InertiaLink.vue +11 -0
  92. package/src/components/InertiaLink/index.ts +1 -0
  93. package/src/components/InlineError/InlineError.vue +21 -0
  94. package/src/components/InlineError/README.md +63 -0
  95. package/src/components/InlineError/index.ts +1 -0
  96. package/src/components/KPICard/KPICard.vue +28 -0
  97. package/src/components/KPICard/KPICardSection.vue +30 -0
  98. package/src/components/KPICard/README.md +124 -0
  99. package/src/components/KPICard/index.ts +2 -0
  100. package/src/components/Legend/Legend.vue +7 -0
  101. package/src/components/Legend/LegendItem.vue +34 -0
  102. package/src/components/Legend/README.md +32 -0
  103. package/src/components/Legend/index.ts +2 -0
  104. package/src/components/Link/Link.vue +4 -4
  105. package/src/components/Link/README.md +1 -1
  106. package/src/components/Navigation/Navigation.vue +2 -2
  107. package/src/components/Navigation/NavigationItem.vue +14 -10
  108. package/src/components/Navigation/NavigationSecondarySection.vue +12 -0
  109. package/src/components/Navigation/NavigationSection.vue +1 -1
  110. package/src/components/Navigation/README.md +10 -15
  111. package/src/components/Navigation/index.ts +1 -0
  112. package/src/components/Page/Page.vue +2 -33
  113. package/src/components/Page/PageBody.vue +36 -0
  114. package/src/components/Page/PageTitle.vue +6 -3
  115. package/src/components/Page/README.md +45 -39
  116. package/src/components/Page/index.ts +1 -0
  117. package/src/components/Pagination/README.md +1 -1
  118. package/src/components/PinInput/README.md +1 -1
  119. package/src/components/Popover/Popover.vue +18 -0
  120. package/src/components/Popover/PopoverBody.vue +11 -0
  121. package/src/components/Popover/PopoverTrigger.vue +9 -0
  122. package/src/components/Popover/README.md +34 -6
  123. package/src/components/Popover/index.ts +3 -0
  124. package/src/components/Popper/Popper.vue +91 -0
  125. package/src/components/Popper/PopperBody.vue +19 -0
  126. package/src/components/Popper/PopperTrigger.vue +14 -0
  127. package/src/components/Popper/README.md +42 -0
  128. package/src/components/Popper/index.ts +3 -0
  129. package/src/components/ProgressBar/ProgressBar.vue +24 -6
  130. package/src/components/RadioButton/README.md +1 -1
  131. package/src/components/RadioButton/RadioButton.vue +3 -2
  132. package/src/components/ResourceList/README.md +160 -0
  133. package/src/components/ResourceList/ResourceList.vue +7 -0
  134. package/src/components/ResourceList/ResourceListItem.vue +7 -0
  135. package/src/components/ResourceList/ResourceListItemContent.vue +7 -0
  136. package/src/components/ResourceList/index.ts +3 -0
  137. package/src/components/Select/README.md +1 -1
  138. package/src/components/Select/Select.vue +1 -1
  139. package/src/components/Separator/README.md +5 -1
  140. package/src/components/Separator/Separator.vue +20 -3
  141. package/src/components/Spinner/README.md +1 -1
  142. package/src/components/Spinner/Spinner.vue +10 -4
  143. package/src/components/StatusIndicator/README.md +2 -2
  144. package/src/components/StatusIndicator/StatusIndicator.vue +11 -5
  145. package/src/components/Stepper/README.md +38 -0
  146. package/src/components/Stepper/Stepper.vue +104 -0
  147. package/src/components/Stepper/index.ts +1 -0
  148. package/src/components/Tabs/README.md +1 -1
  149. package/src/components/Tabs/TabTrigger.vue +5 -4
  150. package/src/components/Tabs/Tabs.vue +4 -1
  151. package/src/components/Tag/Tag.vue +45 -0
  152. package/src/components/Tag/index.ts +1 -0
  153. package/src/components/TextField/README.md +24 -6
  154. package/src/components/TextField/TextField.vue +25 -5
  155. package/src/components/TextField/TextFieldIcon.vue +19 -0
  156. package/src/components/TextStyle/README.md +1 -1
  157. package/src/components/TextStyle/TextStyle.vue +1 -1
  158. package/src/components/Toast/DismissToastAction.vue +1 -1
  159. package/src/components/Toast/README.md +1 -1
  160. package/src/components/Toggle/README.md +1 -1
  161. package/src/components/Toggle/Toggle.vue +8 -5
  162. package/src/components/Tooltip/README.md +1 -1
  163. package/src/components/Tooltip/Tooltip.vue +15 -41
  164. package/src/components/TopBar/TopBarSearch.vue +2 -2
  165. package/src/components/index.ts +68 -12
  166. package/src/components/types.ts +5 -0
  167. package/src/composables/useTheme.ts +13 -1
  168. package/src/composables/useToastNotifications.ts +1 -1
  169. package/src/composables/useUniqueId.ts +4 -3
  170. package/src/index.css +17 -13
  171. package/src/index.ts +0 -11
  172. package/dist/focus-ui.es.js +0 -33
  173. package/dist/types/components/Accordion/Accordion.vue.d.ts +0 -32
  174. package/dist/types/components/Accordion/AccordionItem.vue.d.ts +0 -2
  175. package/dist/types/components/Accordion/index.d.ts +0 -2
  176. package/dist/types/components/index.d.ts +0 -1
  177. package/dist/types/index.d.ts +0 -7
  178. package/src/components/CategoryBar/CategoryBar.vue +0 -25
  179. package/src/components/CategoryBar/CategoryBarItem.vue +0 -34
  180. package/src/components/CategoryBar/README.md +0 -17
  181. package/src/components/CategoryBar/index.ts +0 -2
  182. package/src/components/MetricCard/MetricCard.vue +0 -11
  183. package/src/components/MetricCard/MetricCardLabel.vue +0 -9
  184. package/src/components/MetricCard/MetricCardSection.vue +0 -11
  185. package/src/components/MetricCard/README.md +0 -53
  186. package/src/components/MetricCard/index.ts +0 -5
@@ -0,0 +1,13 @@
1
+ <script lang="ts" setup>
2
+ import { InertiaLink } from '../InertiaLink';
3
+ </script>
4
+
5
+ <template>
6
+ <InertiaLink
7
+ class="hover:underline hover:text-black"
8
+ href="/"
9
+ role="link"
10
+ >
11
+ <slot />
12
+ </InertiaLink>
13
+ </template>
@@ -0,0 +1,8 @@
1
+ <script lang="ts" setup>
2
+ </script>
3
+
4
+ <template>
5
+ <ol class="flex flex-wrap items-center gap-2 break-words">
6
+ <slot />
7
+ </ol>
8
+ </template>
@@ -0,0 +1,13 @@
1
+ <script lang="ts" setup>
2
+ </script>
3
+
4
+ <template>
5
+ <span
6
+ aria-current="page"
7
+ aria-disabled="true"
8
+ class="text-black"
9
+ role="link"
10
+ >
11
+ <slot />
12
+ </span>
13
+ </template>
@@ -0,0 +1,12 @@
1
+ <script lang="ts" setup>
2
+ import { ChevronRightIcon } from '@heroicons/vue/16/solid';
3
+ </script>
4
+
5
+ <template>
6
+ <li
7
+ aria-hidden="true"
8
+ role="presentation"
9
+ >
10
+ <ChevronRightIcon class="w-4 h-4" />
11
+ </li>
12
+ </template>
@@ -0,0 +1,91 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ Breadcrumb,
4
+ BreadcrumbEllipsis,
5
+ BreadcrumbItem,
6
+ BreadcrumbLink,
7
+ BreadcrumbList,
8
+ BreadcrumbPage,
9
+ BreadcrumbSeparator,
10
+ } from '../../src/components';
11
+ import api from '../component-meta/Breadcrumb.json';
12
+ </script>
13
+
14
+ # Breadcrumbs
15
+
16
+ Breadcrumbs are a secondary navigation aid that helps users understand where they are in the application and how to
17
+ navigate back to a previous page.
18
+
19
+ <ComponentApi :api="api" />
20
+
21
+ ## Usage
22
+
23
+ <ComponentWrapper>
24
+ <Breadcrumb>
25
+ <BreadcrumbList>
26
+ <BreadcrumbItem>
27
+ <BreadcrumbLink href="/">
28
+ Home
29
+ </BreadcrumbLink>
30
+ </BreadcrumbItem>
31
+ <BreadcrumbSeparator />
32
+ <BreadcrumbItem>
33
+ <BreadcrumbEllipsis />
34
+ </BreadcrumbItem>
35
+ <BreadcrumbSeparator />
36
+ <BreadcrumbItem>
37
+ <BreadcrumbLink href="/">
38
+ Components
39
+ </BreadcrumbLink>
40
+ </BreadcrumbItem>
41
+ <BreadcrumbSeparator />
42
+ <BreadcrumbItem>
43
+ <BreadcrumbPage>
44
+ Breadcrumb
45
+ </BreadcrumbPage>
46
+ </BreadcrumbItem>
47
+ </BreadcrumbList>
48
+ </Breadcrumb>
49
+ </ComponentWrapper>
50
+
51
+ ```js-vue
52
+ <script lang="ts" setup>
53
+ import {
54
+ Breadcrumb,
55
+ BreadcrumbEllipsis,
56
+ BreadcrumbItem,
57
+ BreadcrumbLink,
58
+ BreadcrumbList,
59
+ BreadcrumbPage,
60
+ BreadcrumbSeparator,
61
+ } from '@returnless/focus-ui';
62
+ </script>
63
+
64
+ <template>
65
+ <Breadcrumb>
66
+ <BreadcrumbList>
67
+ <BreadcrumbItem>
68
+ <BreadcrumbLink href="/">
69
+ Home
70
+ </BreadcrumbLink>
71
+ </BreadcrumbItem>
72
+ <BreadcrumbSeparator />
73
+ <BreadcrumbItem>
74
+ <BreadcrumbEllipsis />
75
+ </BreadcrumbItem>
76
+ <BreadcrumbSeparator />
77
+ <BreadcrumbItem>
78
+ <BreadcrumbLink href="/">
79
+ Components
80
+ </BreadcrumbLink>
81
+ </BreadcrumbItem>
82
+ <BreadcrumbSeparator />
83
+ <BreadcrumbItem>
84
+ <BreadcrumbPage>
85
+ Breadcrumb
86
+ </BreadcrumbPage>
87
+ </BreadcrumbItem>
88
+ </BreadcrumbList>
89
+ </Breadcrumb>
90
+ </template>
91
+ ```
@@ -0,0 +1,7 @@
1
+ export { default as Breadcrumb } from './Breadcrumb.vue';
2
+ export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue';
3
+ export { default as BreadcrumbItem } from './BreadcrumbItem.vue';
4
+ export { default as BreadcrumbLink } from './BreadcrumbLink.vue';
5
+ export { default as BreadcrumbList } from './BreadcrumbList.vue';
6
+ export { default as BreadcrumbPage } from './BreadcrumbPage.vue';
7
+ export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue';
@@ -1,63 +1,75 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed } from 'vue';
3
3
  import { Spinner } from '../';
4
- import { useTheme } from '../../composables';
4
+ import { useTheme, useUniqueId } from '../../composables';
5
+ import { ChevronDownIcon } from '@heroicons/vue/16/solid';
6
+ import { ButtonProps } from './types';
5
7
 
6
- const props = withDefaults(defineProps<{
7
- /** Whether the button is disabled. */
8
- disabled?: boolean;
9
-
10
- /** Whether the button should open the link in a new tab. */
11
- external?: boolean;
12
-
13
- /** The URL the button should navigate to. */
14
- href?: string | null;
15
-
16
- /** Whether the button is in a loading state. */
17
- loading?: boolean;
18
-
19
- /** The variant of the button. */
20
- variant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost';
21
- }>(), {
8
+ const props = withDefaults(defineProps<ButtonProps>(), {
22
9
  disabled: false,
10
+ disclosure: false,
23
11
  external: false,
12
+ fullWidth: false,
24
13
  href: null,
25
14
  loading: false,
15
+ size: 'normal',
16
+ type: 'button',
26
17
  variant: 'primary',
27
18
  });
28
19
 
29
- const classList = computed(() => {
20
+ const buttonLabelId = useUniqueId('buttonLabel');
21
+
22
+ const classList = computed((): (Record<string, boolean> | string)[] => {
30
23
  return [
31
- { 'bg-brand-500 hover:bg-brand-600 text-white border-brand-500': props.variant === 'primary' },
32
- { 'bg-slate-200 hover:bg-slate-300 border-slate-100': props.variant === 'secondary' },
33
- { 'bg-red-500 hover:bg-red-600 text-white border-red-500': props.variant === 'destructive' },
34
- { 'border-slate-300 hover:bg-slate-100': props.variant === 'outline' },
35
- { 'border-transparent hover:bg-slate-200': props.variant === 'ghost' },
24
+ { 'bg-brand-500 hover:bg-brand-600 text-white': props.variant === 'primary' },
25
+ { 'bg-slate-200 hover:bg-slate-300': props.variant === 'secondary' },
26
+ { 'bg-red-500/20 hover:bg-red-500/30 text-red-600': props.variant === 'destructive' },
27
+ { 'hover:bg-slate-200': props.variant === 'ghost' },
28
+
29
+ { 'px-4 py-3': props.size === 'normal' },
30
+ { 'px-3 py-2': props.size === 'small' },
36
31
 
37
32
  { 'opacity-50 cursor-not-allowed': props.disabled },
38
- { 'pointer-events-none opacity-75': props.loading },
33
+ { 'pointer-events-none opacity-75 justify-center': props.loading },
34
+
35
+ { 'w-full': props.fullWidth },
39
36
 
40
- ...useTheme('focus'),
37
+ ...useTheme('focus', props.variant === 'destructive' ? 'destructive' : 'default'),
41
38
  ];
42
39
  });
43
40
  </script>
44
41
 
45
42
  <template>
46
- <button
47
- class="inline-flex items-center justify-center rounded border px-4 py-3 text-sm font-medium leading-none active:opacity-80 active:shadow-inner"
48
- :class="classList"
49
- :disabled="disabled || loading"
50
- >
51
- <span
52
- class="inline-flex items-center justify-center space-x-4"
53
- :class="{ 'invisible': loading }"
43
+ <span>
44
+ <button
45
+ :aria-busy="loading"
46
+ :aria-disabled="disabled || loading"
47
+ :aria-labelledby="buttonLabelId"
48
+ :class="classList"
49
+ :disabled="disabled || loading"
50
+ :type="type"
51
+ class="inline-flex items-center rounded text-sm font-medium leading-none active:opacity-80 active:shadow-inner"
52
+ role="button"
54
53
  >
55
- <slot />
56
- </span>
57
-
58
- <Spinner
59
- v-if="loading"
60
- class="absolute"
61
- />
62
- </button>
54
+ <span
55
+ :id="buttonLabelId"
56
+ :class="{ 'invisible': loading }"
57
+ class="inline-flex items-center justify-center space-x-4"
58
+ >
59
+ <slot />
60
+
61
+ <span
62
+ v-if="disclosure"
63
+ class="ml-2"
64
+ >
65
+ <ChevronDownIcon class="h-4 w-4" />
66
+ </span>
67
+ </span>
68
+
69
+ <Spinner
70
+ v-if="loading"
71
+ class="absolute"
72
+ />
73
+ </button>
74
+ </span>
63
75
  </template>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup></script>
2
2
 
3
3
  <template>
4
- <span>
4
+ <span class="text-sm leading-none">
5
5
  <slot />
6
6
  </span>
7
7
  </template>
@@ -1,7 +1,32 @@
1
- <script lang="ts" setup></script>
1
+ <script lang="ts" setup>
2
+ import { Image } from '../Image';
3
+
4
+ withDefaults(defineProps<{
5
+ /** The alt text for the icon */
6
+ alt?: string | undefined;
7
+
8
+ /** The name of the icon to display */
9
+ name?: (() => void) | null;
10
+
11
+ /** The source of the icon to display */
12
+ source?: string | null;
13
+ }>(), {
14
+ alt: undefined,
15
+ name: null,
16
+ source: null,
17
+ });
18
+ </script>
2
19
 
3
20
  <template>
4
- <div class="h-4 w-4 -mt-0.5 -mb-0.5">
5
- <slot />
21
+ <div class="flex-shrink-0 h-4 w-4 -mt-0.5 -mb-0.5">
22
+ <component
23
+ :is="name"
24
+ v-if="name"
25
+ />
26
+ <Image
27
+ v-if="source"
28
+ :alt="alt!"
29
+ :source="source"
30
+ />
6
31
  </div>
7
32
  </template>
@@ -24,7 +24,7 @@ screen to avoid overwhelming users.
24
24
 
25
25
  ```js-vue
26
26
  <script lang="ts" setup>
27
- import { Button } from 'focus-ui';
27
+ import { Button } from '@returnless/focus-ui';
28
28
  </script>
29
29
 
30
30
  <template>
@@ -42,7 +42,7 @@ Used most in the interface. Only use another style if a button requires more or
42
42
 
43
43
  ```js-vue
44
44
  <script lang="ts" setup>
45
- import { Button } from 'focus-ui';
45
+ import { Button } from '@returnless/focus-ui';
46
46
  </script>
47
47
 
48
48
  <template>
@@ -62,7 +62,7 @@ they can feel stressful for users.
62
62
 
63
63
  ```js-vue
64
64
  <script lang="ts" setup>
65
- import { Button } from 'focus-ui';
65
+ import { Button } from '@returnless/focus-ui';
66
66
  </script>
67
67
 
68
68
  <template>
@@ -70,24 +70,6 @@ import { Button } from 'focus-ui';
70
70
  </template>
71
71
  ```
72
72
 
73
- ### Outline
74
-
75
- Used for actions that are less important than primary or secondary actions.
76
-
77
- <ComponentWrapper>
78
- <Button variant="outline">Outline</Button>
79
- </ComponentWrapper>
80
-
81
- ```js-vue
82
- <script lang="ts" setup>
83
- import { Button } from 'focus-ui';
84
- </script>
85
-
86
- <template>
87
- <Button variant="outline">Outline</Button>
88
- </template>
89
- ```
90
-
91
73
  ### Ghost
92
74
 
93
75
  Used for less important or less commonly used actions. Ghost buttons are less prominent than other button styles,
@@ -98,7 +80,7 @@ Used for less important or less commonly used actions. Ghost buttons are less pr
98
80
 
99
81
  ```js-vue
100
82
  <script lang="ts" setup>
101
- import { Button } from 'focus-ui';
83
+ import { Button } from '@returnless/focus-ui';
102
84
  </script>
103
85
 
104
86
  <template>
@@ -118,7 +100,7 @@ Use when a button has been pressed and the associated action is in progress.
118
100
 
119
101
  ```js-vue
120
102
  <script lang="ts" setup>
121
- import { Button } from 'focus-ui';
103
+ import { Button } from '@returnless/focus-ui';
122
104
  </script>
123
105
 
124
106
  <template>
@@ -133,12 +115,33 @@ import { Button } from 'focus-ui';
133
115
  Use when a button needs to be paired with an icon to help convey its purpose.
134
116
 
135
117
  <ComponentWrapper>
136
- <Button variant="primary">
137
- <ButtonIcon>
138
- <ArrowDownTrayIcon />
139
- </ButtonIcon>
140
- <ButtonContent>Button with icon</ButtonContent>
141
- </Button>
118
+ <ComponentGrid>
119
+ <Button variant="primary">
120
+ <ButtonIcon :name="ArrowDownTrayIcon" />
121
+ <ButtonContent>Button with icon on the left</ButtonContent>
122
+ </Button>
123
+ <Button variant="primary">
124
+ <ButtonContent>Button with icon on the right</ButtonContent>
125
+ <ButtonIcon :name="ArrowDownTrayIcon" />
126
+ </Button>
127
+ </ComponentGrid>
128
+ </ComponentWrapper>
129
+
130
+ ### Button with image
131
+
132
+ Use when a button needs to be paired with an image to help convey its purpose.
133
+
134
+ <ComponentWrapper>
135
+ <ComponentGrid>
136
+ <Button variant="secondary">
137
+ <ButtonIcon source="https://panel.returnless.test/img/integrations/demo-logo.svg" />
138
+ <ButtonContent>Create coupon</ButtonContent>
139
+ </Button>
140
+ <Button variant="secondary">
141
+ <ButtonContent>Button with icon on the right</ButtonContent>
142
+ <ButtonIcon source="https://panel.returnless.test/img/integrations/demo-logo.svg" />
143
+ </Button>
144
+ </ComponentGrid>
142
145
  </ComponentWrapper>
143
146
 
144
147
  ## Best practices
@@ -1,3 +1,5 @@
1
+ export { type ButtonVariant, type ButtonProps } from './types';
2
+
1
3
  export { default as Button } from './Button.vue';
2
4
  export { default as ButtonContent } from './ButtonContent.vue';
3
5
  export { default as ButtonIcon } from './ButtonIcon.vue';
@@ -0,0 +1,30 @@
1
+ export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'ghost';
2
+
3
+ export interface ButtonProps {
4
+ /** Whether the button is disabled. */
5
+ disabled?: boolean;
6
+
7
+ /** Displays the button with a disclosure icon. Defaults to `down` when set to true. */
8
+ disclosure?: boolean;
9
+
10
+ /** Whether the button should open the link in a new tab. */
11
+ external?: boolean;
12
+
13
+ /** Whether the button should span the full width of its parent. (INTERNAL USE ONLY) */
14
+ fullWidth?: boolean;
15
+
16
+ /** The URL the button should navigate to. */
17
+ href?: string | null;
18
+
19
+ /** Whether the button is in a loading state. */
20
+ loading?: boolean;
21
+
22
+ /** The button size. (INTERNAL USE ONLY) */
23
+ size?: 'small' | 'normal';
24
+
25
+ /** The type of the button. */
26
+ type?: 'button' | 'reset' | 'submit';
27
+
28
+ /** The variant of the button. */
29
+ variant?: ButtonVariant;
30
+ }
@@ -20,7 +20,7 @@ Button group displays multiple related actions stacked or in a horizontal row to
20
20
 
21
21
  ```js-vue
22
22
  <script lang="ts" setup>
23
- import { Button, ButtonGroup } from 'focus-ui';
23
+ import { Button, ButtonGroup } from '@returnless/focus-ui';
24
24
  </script>
25
25
 
26
26
  <template>
@@ -0,0 +1,23 @@
1
+ <script lang="ts" setup>
2
+ import { Link } from '@inertiajs/vue3';
3
+ import { InformationCircleIcon } from '@heroicons/vue/16/solid';
4
+
5
+ defineProps<{
6
+ href: string;
7
+ }>();
8
+ </script>
9
+
10
+ <template>
11
+ <Link
12
+ :href="href"
13
+ class="ml-2 flex items-center rounded-full border border-transparent px-1 py-1 pr-2 text-xs font-normal leading-none text-slate-500 group hover:border-slate-300 hover:bg-slate-100"
14
+ native
15
+ target="_blank"
16
+ v-bind="$attrs"
17
+ >
18
+ <InformationCircleIcon class="h-4 w-4 group-hover:text-brand-500" />
19
+ <span class="ml-1 hidden text-black group-hover:block">
20
+ <slot />
21
+ </span>
22
+ </Link>
23
+ </template>
@@ -1,7 +1,22 @@
1
- <script lang="ts" setup></script>
1
+ <script lang="ts" setup>
2
+ import { computed } from 'vue';
3
+
4
+ const props = withDefaults(defineProps<{
5
+ flush?: boolean;
6
+ }>(), {
7
+ flush: false,
8
+ });
9
+
10
+ const classList = computed((): Record<string, boolean> => {
11
+ return {
12
+ 'py-6': props.flush,
13
+ 'p-6': !props.flush,
14
+ };
15
+ });
16
+ </script>
2
17
 
3
18
  <template>
4
- <div class="p-6">
19
+ <div :class="classList">
5
20
  <slot />
6
21
  </div>
7
22
  </template>
@@ -1,8 +1,11 @@
1
1
  <script lang="ts" setup>
2
+ import { Heading } from '../Heading';
2
3
  </script>
3
4
 
4
5
  <template>
5
- <div class="text-xl font-semibold leading-none">
6
- <slot />
7
- </div>
6
+ <Heading level="h2">
7
+ <div class="flex items-center">
8
+ <slot />
9
+ </div>
10
+ </Heading>
8
11
  </template>
@@ -1,6 +1,21 @@
1
1
  <script lang="ts" setup>
2
- import { Button, Card, CardSection, CardDescription, CardFooter, CardHeader, CardTitle } from '../../src/components';
2
+ import {
3
+ AspectRatio,
4
+ Button,
5
+ ButtonIcon,
6
+ ButtonContent,
7
+ ButtonGroup,
8
+ Card,
9
+ CardDescription,
10
+ CardFooter,
11
+ CardHeader,
12
+ CardHelp,
13
+ CardSection,
14
+ CardTitle,
15
+ Heading,
16
+ } from '../../src/components';
3
17
  import api from '../component-meta/Card.json';
18
+ import { ArrowDownTrayIcon } from '@heroicons/vue/16/solid';
4
19
  </script>
5
20
 
6
21
  # Card
@@ -15,7 +30,10 @@ content in a familiar and recognizable style.
15
30
  <ComponentWrapper>
16
31
  <Card>
17
32
  <CardHeader>
18
- <CardTitle>Notifications</CardTitle>
33
+ <CardTitle>
34
+ Notifications
35
+ <CardHelp href="/help">Learn more</CardHelp>
36
+ </CardTitle>
19
37
  <CardDescription>You have 3 unread messages.</CardDescription>
20
38
  </CardHeader>
21
39
  <CardSection>
@@ -30,20 +48,24 @@ content in a familiar and recognizable style.
30
48
  ```js-vue
31
49
  <script lang="ts" setup>
32
50
  import {
33
- Button,
34
- Card,
35
- CardSection,
36
- CardDescription,
37
- CardFooter,
38
- CardHeader,
51
+ Button,
52
+ Card,
53
+ CardDescription,
54
+ CardFooter,
55
+ CardHeader,
56
+ CardHelp,
57
+ CardSection,
39
58
  CardTitle,
40
- } from 'focus-ui';
59
+ } from '@returnless/focus-ui';
41
60
  </script>
42
61
 
43
62
  <template>
44
63
  <Card>
45
64
  <CardHeader>
46
- <CardTitle>Notifications</CardTitle>
65
+ <CardTitle>
66
+ Notifications
67
+ <CardHelp href="/help">Learn more</CardHelp>
68
+ </CardTitle>
47
69
  <CardDescription>You have 3 unread messages.</CardDescription>
48
70
  </CardHeader>
49
71
  <CardSection>
@@ -56,6 +78,71 @@ import {
56
78
  </template>
57
79
  ```
58
80
 
81
+ ### Example with media image
82
+
83
+ <ComponentWrapper>
84
+ <div style="width: 400px;">
85
+ <Card>
86
+ <AspectRatio :ratio="16 / 9">
87
+ <img
88
+ src="https://www.retourneren.nl/media/catalog/product/cache/8d4d2075b1a30681853bef5bdc41b164/r/e/returnless_afbeelding.jpg"
89
+ class="h-full w-full object-cover"
90
+ >
91
+ </AspectRatio>
92
+ <CardHeader>
93
+ <CardTitle>Focus-UI return form</CardTitle>
94
+ <CardDescription>Returnless webshop</CardDescription>
95
+ </CardHeader>
96
+ <CardSection>
97
+ <ButtonGroup>
98
+ <Button variant="secondary">Settings</Button>
99
+ <Button variant="ghost">Preview</Button>
100
+ </ButtonGroup>
101
+ </CardSection>
102
+ </Card>
103
+ </div>
104
+ </ComponentWrapper>
105
+
106
+ ```js-vue
107
+ <script lang="ts" setup>
108
+ import {
109
+ AspectRatio,
110
+ Button,
111
+ ButtonGroup,
112
+ Card,
113
+ CardDescription,
114
+ CardFooter,
115
+ CardHeader,
116
+ CardHelp,
117
+ CardSection,
118
+ CardTitle,
119
+ } from '@returnless/focus-ui';
120
+ </script>
121
+
122
+ <template>
123
+ <div style="width: 400px;">
124
+ <Card>
125
+ <AspectRatio :ratio="16 / 9">
126
+ <img
127
+ src="https://www.retourneren.nl/media/catalog/product/cache/8d4d2075b1a30681853bef5bdc41b164/r/e/returnless_afbeelding.jpg"
128
+ class="h-full w-full object-cover"
129
+ >
130
+ </AspectRatio>
131
+ <CardHeader>
132
+ <CardTitle>Focus-UI return form</CardTitle>
133
+ <CardDescription>Returnless webshop</CardDescription>
134
+ </CardHeader>
135
+ <CardSection>
136
+ <ButtonGroup>
137
+ <Button variant="secondary">Settings</Button>
138
+ <Button variant="ghost">Preview</Button>
139
+ </ButtonGroup>
140
+ </CardSection>
141
+ </Card>
142
+ </div>
143
+ </template>
144
+ ```
145
+
59
146
  ## Best practices
60
147
 
61
148
  Cards should: