sprintify-ui 0.6.31 → 0.6.33

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 (83) hide show
  1. package/dist/sprintify-ui.es.js +11823 -11591
  2. package/dist/style.css +1 -1
  3. package/dist/tailwindcss/button.js +260 -0
  4. package/dist/tailwindcss/index.js +16 -301
  5. package/dist/tailwindcss/input.js +24 -0
  6. package/dist/tailwindcss/overlay.js +13 -0
  7. package/dist/tailwindcss/theme.js +46 -0
  8. package/dist/types/src/components/BaseActionItemButton.vue.d.ts +2 -2
  9. package/dist/types/src/components/BaseAddressForm.vue.d.ts +10 -0
  10. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +10 -10
  11. package/dist/types/src/components/BaseAutocompleteDrawer.vue.d.ts +3 -3
  12. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +6 -6
  13. package/dist/types/src/components/BaseAvatarGroup.vue.d.ts +1 -1
  14. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +6 -6
  15. package/dist/types/src/components/BaseBelongsToFetch.vue.d.ts +6 -6
  16. package/dist/types/src/components/BaseButton.vue.d.ts +12 -12
  17. package/dist/types/src/components/BaseButtonGroup.vue.d.ts +24 -24
  18. package/dist/types/src/components/BaseCalendar.vue.d.ts +1 -1
  19. package/dist/types/src/components/BaseColor.vue.d.ts +19 -0
  20. package/dist/types/src/components/BaseDataIterator.vue.d.ts +1 -1
  21. package/dist/types/src/components/BaseDataIteratorSectionColumns.vue.d.ts +4 -4
  22. package/dist/types/src/components/BaseDataTable.vue.d.ts +1 -1
  23. package/dist/types/src/components/BaseDropdownAutocomplete.vue.d.ts +1 -1
  24. package/dist/types/src/components/BaseField.vue.d.ts +13 -3
  25. package/dist/types/src/components/BaseHasMany.vue.d.ts +9 -0
  26. package/dist/types/src/components/BaseInput.vue.d.ts +35 -4
  27. package/dist/types/src/components/BaseInputError.vue.d.ts +14 -1
  28. package/dist/types/src/components/BaseInputLabel.vue.d.ts +15 -5
  29. package/dist/types/src/components/BaseLayoutSidebarConfigurable.vue.d.ts +1 -1
  30. package/dist/types/src/components/BaseLayoutStackedConfigurable.vue.d.ts +1 -1
  31. package/dist/types/src/components/BaseLoadingCover.vue.d.ts +1 -1
  32. package/dist/types/src/components/BaseMediaGallery.vue.d.ts +1 -1
  33. package/dist/types/src/components/BaseMediaListItem.vue.d.ts +1 -1
  34. package/dist/types/src/components/BaseMediaPictures.vue.d.ts +1 -1
  35. package/dist/types/src/components/BaseMediaPicturesItem.vue.d.ts +1 -1
  36. package/dist/types/src/components/BaseMenu.vue.d.ts +1 -1
  37. package/dist/types/src/components/BaseMenuItem.vue.d.ts +1 -1
  38. package/dist/types/src/components/BaseNavbar.vue.d.ts +1 -1
  39. package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +1 -1
  40. package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +1 -1
  41. package/dist/types/src/components/BaseSelect.vue.d.ts +27 -0
  42. package/dist/types/src/components/BaseSideNavigation.vue.d.ts +3 -3
  43. package/dist/types/src/components/BaseSwitch.vue.d.ts +1 -1
  44. package/dist/types/src/components/BaseTable.vue.d.ts +1 -1
  45. package/dist/types/src/components/BaseTabs.vue.d.ts +3 -3
  46. package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +3 -3
  47. package/dist/types/src/composables/field.d.ts +3 -0
  48. package/dist/types/src/composables/inputSize.d.ts +6 -0
  49. package/dist/types/src/utils/sizes.d.ts +19 -0
  50. package/package.json +1 -1
  51. package/src/assets/form.css +1 -1
  52. package/src/components/BaseAddressForm.stories.js +7 -2
  53. package/src/components/BaseAddressForm.vue +64 -37
  54. package/src/components/BaseAutocomplete.stories.js +1 -1
  55. package/src/components/BaseAutocomplete.vue +86 -96
  56. package/src/components/BaseAutocompleteDrawer.vue +3 -2
  57. package/src/components/BaseAutocompleteFetch.stories.js +1 -1
  58. package/src/components/BaseAutocompleteFetch.vue +3 -2
  59. package/src/components/BaseBelongsTo.stories.js +1 -1
  60. package/src/components/BaseBelongsTo.vue +3 -2
  61. package/src/components/BaseBelongsToFetch.vue +3 -2
  62. package/src/components/BaseButton.stories.js +21 -0
  63. package/src/components/BaseButton.vue +42 -6
  64. package/src/components/BaseButtonGroup.stories.js +31 -1
  65. package/src/components/BaseButtonGroup.vue +46 -33
  66. package/src/components/BaseColor.stories.js +22 -0
  67. package/src/components/BaseColor.vue +28 -25
  68. package/src/components/BaseDropdown.stories.js +2 -3
  69. package/src/components/BaseDropdownAutocomplete.vue +2 -2
  70. package/src/components/BaseField.vue +19 -8
  71. package/src/components/BaseHasMany.stories.js +13 -1
  72. package/src/components/BaseHasMany.vue +39 -1
  73. package/src/components/BaseInput.stories.js +35 -1
  74. package/src/components/BaseInput.vue +154 -74
  75. package/src/components/BaseInputError.vue +32 -2
  76. package/src/components/BaseInputLabel.vue +36 -9
  77. package/src/components/BaseSelect.stories.js +34 -0
  78. package/src/components/BaseSelect.vue +57 -8
  79. package/src/components/BaseTagAutocomplete.vue +3 -2
  80. package/src/components/BaseTimelineItem.stories.js +1 -3
  81. package/src/composables/field.ts +20 -0
  82. package/src/composables/inputSize.ts +29 -0
  83. package/src/utils/sizes.ts +21 -0
@@ -2,10 +2,18 @@ import { createFieldStory } from '../../.storybook/utils';
2
2
  import BaseColor from './BaseColor.vue';
3
3
  import ShowValue from '../../.storybook/components/ShowValue.vue';
4
4
 
5
+ const sizes = ['xs', 'sm', 'md'];
6
+
5
7
  export default {
6
8
  title: 'Form/BaseColor',
7
9
  component: BaseColor,
8
10
  decorators: [() => ({ template: '<div class="mb-36"><story/></div>' })],
11
+ argTypes: {
12
+ size: {
13
+ control: { type: 'select' },
14
+ options: sizes,
15
+ },
16
+ },
9
17
  };
10
18
 
11
19
  const Template = (args) => ({
@@ -39,6 +47,20 @@ Disabled.args = {
39
47
  modelValue: '#16a34a',
40
48
  };
41
49
 
50
+ export const Sizes = (args) => ({
51
+ components: { BaseColor },
52
+ setup() {
53
+ const value = ref(null);
54
+ return { args, sizes, value };
55
+ },
56
+ template: `
57
+ <div v-for="size in sizes" :key="size" class="mb-4">
58
+ <p class="text-xs text-slate-600 leading-tight mb-1"> {{ size }}</p>
59
+ <BaseColor v-bind="args" v-model="value" :size="size"></BaseColor>
60
+ </div>
61
+ `,
62
+ });
63
+
42
64
  export const Field = createFieldStory({
43
65
  component: BaseColor,
44
66
  componentName: 'BaseColor',
@@ -5,36 +5,28 @@
5
5
  :disabled="disabled"
6
6
  value-key="value"
7
7
  label-key="label"
8
+ :size="size"
8
9
  :required="required"
9
10
  :options="colorOptions"
10
11
  :multiple="multiple"
11
12
  :button-type="buttonType"
12
- tw-button=""
13
- tw-button-selected=""
14
- tw-button-unselected=""
13
+ :button-color="buttonColor"
14
+ tw-button="p-0 aspect-1 justify-center items-center"
15
15
  @update:model-value="(value) => transformModelValue(value)"
16
16
  >
17
17
  <template #option="option">
18
18
  <div
19
- :style="{ backgroundColor: option.option.value + '' }"
20
- class="box-border rounded-md border p-3"
21
- :class="[
22
- option.selected.value
23
- ? option.option.option.hasLowContrast
24
- ? 'text-slate-700'
25
- : 'text-white'
26
- : 'text-transparent',
27
- disabled ? ' cursor-not-allowed opacity-50' : '',
28
- option.option.option.hasLowContrast
29
- ? 'border-slate-400'
30
- : 'border-transparent',
31
- ]"
19
+ v-if="option.selected.value"
20
+ class="overflow-hidden flex h-full"
32
21
  >
33
22
  <BaseIcon
34
23
  icon="heroicons-solid:check-circle"
35
- class="h-5 w-5"
24
+ class="block leading-none"
25
+ width="18"
26
+ height="18"
36
27
  />
37
28
  </div>
29
+ <div v-else />
38
30
  </template>
39
31
  </BaseButtonGroup>
40
32
  </div>
@@ -48,6 +40,7 @@ import { useField } from '@/composables/field';
48
40
  import { Option } from '@/types';
49
41
  import { palette } from '@/utils/colors';
50
42
  import { getContrast } from 'color2k';
43
+ import { Size } from '@/utils/sizes';
51
44
 
52
45
  const props = defineProps({
53
46
  modelValue: {
@@ -64,6 +57,10 @@ const props = defineProps({
64
57
  default: false,
65
58
  type: Boolean,
66
59
  },
60
+ size: {
61
+ default: undefined,
62
+ type: String as PropType<Size>,
63
+ },
67
64
  buttonType: {
68
65
  default: 'button',
69
66
  type: String as PropType<'button' | 'submit'>,
@@ -74,6 +71,12 @@ const props = defineProps({
74
71
  return Object.values(palette).map((p) => p.high.backgroundColor);
75
72
  },
76
73
  },
74
+ buttonColor: {
75
+ default(option: Option, selected: boolean) {
76
+ return option.value;
77
+ },
78
+ type: Function as PropType<(option: Option, selected: boolean) => string>,
79
+ },
77
80
  multiple: {
78
81
  default: false,
79
82
  type: Boolean,
@@ -107,15 +110,15 @@ function hasLowContrast(color: string): boolean {
107
110
  const normalizeModelValue = computed(() => {
108
111
  return isArray(props.modelValue)
109
112
  ? props.modelValue?.map((m) => {
110
- return {
111
- label: m,
112
- value: m,
113
- };
114
- })
115
- : {
116
- label: props.modelValue,
117
- value: props.modelValue,
113
+ return {
114
+ label: m,
115
+ value: m,
118
116
  };
117
+ })
118
+ : {
119
+ label: props.modelValue,
120
+ value: props.modelValue,
121
+ };
119
122
  });
120
123
 
121
124
  const { emitUpdate } = useField({
@@ -93,7 +93,6 @@ export const WithAutocomplete = (args) => ({
93
93
  size="xs"
94
94
  :options="options"
95
95
  :inline="true"
96
- :visibleFocus="false"
97
96
  dropdownShow="always"
98
97
  :showModelValue="false"
99
98
  focus-on-mount
@@ -143,14 +142,14 @@ export const ModalWithScroll = (args) => ({
143
142
  },
144
143
  template: `
145
144
  <BaseModalCenter v-model="open">
146
- <div class="p-10 bg-white">
145
+ <div class="p-10">
147
146
  <BaseDropdown v-bind="args">
148
147
  <template #button>
149
148
  <div class="btn btn-primary">Click me</div>
150
149
  </template>
151
150
  <template #dropdown>
152
151
  <div
153
- class="bg-white shadow py-1 px-1 rounded"
152
+ class="bg-white ring-1 shadow-xl ring-black ring-opacity-10 py-1 px-1 rounded-md"
154
153
  style="max-height: 200px; overflow: auto;"
155
154
  data-scroll-lock-scrollable>
156
155
  <button type="button" v-for="item in items" :key="item.label" class="block text-sm px-4 py-1.5">{{ item.label }}</button>
@@ -13,7 +13,7 @@
13
13
  </template>
14
14
  <template #dropdown="{ close }">
15
15
  <div
16
- class="inline-block w-[320px] overflow-hidden rounded-md ring-1 ring-black ring-opacity-10 bg-white px-2 pt-2 shadow-2xl"
16
+ class="inline-block w-[320px] overflow-hidden input-rounded ring-1 ring-black ring-opacity-10 bg-white px-2 pt-2 shadow-2xl"
17
17
  >
18
18
  <component
19
19
  :is="componentName"
@@ -33,7 +33,7 @@
33
33
  <template #option="optionProps">
34
34
  <div
35
35
  :class="[optionProps.active ? 'bg-slate-100' : 'bg-white']"
36
- class="mb-px flex items-center rounded px-1 py-1"
36
+ class="mb-px flex items-center input-rounded px-1 py-1"
37
37
  >
38
38
  <div class="flex grow items-center">
39
39
  <slot
@@ -4,7 +4,8 @@
4
4
  v-if="labelNormalized"
5
5
  :label="labelNormalized"
6
6
  :required="required"
7
- :class="labelClassInternal"
7
+ :size="inputSize.size.value"
8
+ :class="labelClassInternalMerged"
8
9
  :help="help"
9
10
  />
10
11
 
@@ -19,6 +20,7 @@
19
20
  <template v-if="errorMessage">
20
21
  <BaseInputError
21
22
  v-if="errorTypeInternal == 'default'"
23
+ :size="inputSize.size.value"
22
24
  class="mt-1"
23
25
  >
24
26
  {{ errorMessage }}
@@ -40,6 +42,9 @@ import { PropType } from 'vue';
40
42
  import BaseAlert from './BaseAlert.vue';
41
43
  import BaseInputError from './BaseInputError.vue';
42
44
  import BaseInputLabel from './BaseInputLabel.vue';
45
+ import { useInputSize } from '@/composables/inputSize';
46
+ import { Size } from '@/utils/sizes';
47
+ import { ClassNameValue, twMerge } from 'tailwind-merge';
43
48
 
44
49
  const props = defineProps({
45
50
  name: {
@@ -50,6 +55,10 @@ const props = defineProps({
50
55
  type: String,
51
56
  default: '',
52
57
  },
58
+ size: {
59
+ default: undefined,
60
+ type: String as PropType<Size>,
61
+ },
53
62
  required: {
54
63
  type: Boolean,
55
64
  default: false,
@@ -68,25 +77,26 @@ const props = defineProps({
68
77
  },
69
78
  labelClass: {
70
79
  default: '',
71
- type: [String, Array, Object] as PropType<
72
- string | string[] | Record<string, boolean>
73
- >,
80
+ type: [String, Array] as PropType<ClassNameValue>,
74
81
  },
75
82
  });
76
83
 
77
84
  const errorTypeInternal = ref(props.errorType);
78
85
 
86
+ const inputSize = useInputSize(computed(() => props.size));
87
+
79
88
  function setErrorType(errorType: 'default' | 'alert' | null) {
80
89
  if (errorType != null) {
81
90
  errorTypeInternal.value = errorType;
82
91
  }
83
92
  }
84
93
 
85
- const labelClassInternal = ref(props.labelClass);
94
+ const labelClassInternal = ref<any>('');
95
+ const labelClassInternalMerged = computed(() => {
96
+ return twMerge(labelClassInternal.value, props.labelClass);
97
+ });
86
98
 
87
- function setLabelClass(
88
- labelClass: string | string[] | Record<string, boolean> | null
89
- ) {
99
+ function setLabelClass(labelClass: ClassNameValue) {
90
100
  if (labelClass != null) {
91
101
  labelClassInternal.value = labelClass;
92
102
  }
@@ -122,6 +132,7 @@ const errorMessage = computed((): string | null | undefined => {
122
132
 
123
133
  provide('field:name', readonly(ref(props.name)));
124
134
  provide('field:required', readonly(ref(props.required)));
135
+ provide('field:size', readonly(inputSize.size));
125
136
  provide('field:onUpdate', fieldOnUpdate);
126
137
  provide('field:errorMessage', errorMessage);
127
138
  provide('field:setErrorType', setErrorType);
@@ -2,6 +2,7 @@ import BaseHasMany from './BaseHasMany.vue';
2
2
  import ShowValue from '@/../.storybook/components/ShowValue.vue';
3
3
  import { createFieldStory, options } from '../../.storybook/utils';
4
4
  import BaseAppNotifications from './BaseAppNotifications.vue';
5
+ import QueryString from 'qs';
5
6
 
6
7
  export default {
7
8
  title: 'Form/BaseHasMany',
@@ -19,7 +20,9 @@ const Template = (args) => {
19
20
  return {
20
21
  components: { BaseHasMany, ShowValue, BaseAppNotifications },
21
22
  setup() {
22
- const value = ref([]);
23
+ const value = ref([
24
+ "9acd34f6-ecf3-43e3-b84e-d8fcf5382bf4"
25
+ ]);
23
26
  return { args, value };
24
27
  },
25
28
  template: `
@@ -60,6 +63,15 @@ Maximum.args = {
60
63
  max: 3,
61
64
  };
62
65
 
66
+ export const ShowRouteUrl = Template.bind({});
67
+ ShowRouteUrl.args = {
68
+ max: 3,
69
+ showRouteUrl: (ids) => {
70
+ const params = QueryString.stringify({ filter: { id: ids } });
71
+ return `https://effettandem.com/api/content/articles?${params}`;
72
+ },
73
+ };
74
+
63
75
  export const SlotOption = (args) => {
64
76
  return {
65
77
  components: { BaseHasMany },
@@ -46,8 +46,10 @@
46
46
  <script lang="ts" setup>
47
47
  import { isEqual } from 'lodash';
48
48
  import { Option } from '@/types';
49
- import BaseTagAutocompleteFetch from './BaseTagAutocompleteFetch.vue';
49
+ import { config } from '@/index';
50
50
  import { PropType } from 'vue';
51
+ import BaseTagAutocompleteFetch from './BaseTagAutocompleteFetch.vue';
52
+ import { AxiosResponse } from 'axios';
51
53
 
52
54
  const props = defineProps({
53
55
  modelValue: {
@@ -58,6 +60,10 @@ const props = defineProps({
58
60
  required: true,
59
61
  type: String,
60
62
  },
63
+ showRouteUrl: {
64
+ default: undefined,
65
+ type: Function as PropType<((ids: (string | number)[]) => string) | undefined>,
66
+ },
61
67
  primaryKey: {
62
68
  default: 'id',
63
69
  type: String,
@@ -98,6 +104,8 @@ const props = defineProps({
98
104
  },
99
105
  });
100
106
 
107
+ const http = config.http;
108
+
101
109
  const emit = defineEmits(['update:modelValue']);
102
110
 
103
111
  const tagAutocompleteFetch = ref<InstanceType<
@@ -118,6 +126,36 @@ watch(
118
126
  { deep: true }
119
127
  );
120
128
 
129
+ watch(
130
+ () => props.modelValue,
131
+ (newValue, oldValue) => {
132
+ if (!props.modelValue) {
133
+ models.value = [];
134
+ return;
135
+ }
136
+
137
+ if (newValue == oldValue) {
138
+ return;
139
+ }
140
+
141
+ if (props.showRouteUrl == null) {
142
+ return;
143
+ }
144
+
145
+ const ids = props.modelValue.map((id) => id.toString());
146
+
147
+ http
148
+ .get(props.showRouteUrl(ids))
149
+ .then((response: AxiosResponse) => {
150
+ models.value = response.data.data.filter((i: any) => {
151
+ return ids.includes(i[props.primaryKey]);
152
+ });
153
+ })
154
+ .catch((e: Error) => e);
155
+ },
156
+ { immediate: true }
157
+ );
158
+
121
159
  function onUpdate(newModels: Option[]) {
122
160
  models.value = newModels;
123
161
  emit(
@@ -19,6 +19,10 @@ export default {
19
19
  placeholder: 'Enter your name',
20
20
  },
21
21
  argTypes: {
22
+ size: {
23
+ control: { type: 'select' },
24
+ options: ['xs', 'sm', 'md'],
25
+ },
22
26
  mask: {
23
27
  control: { type: 'select' },
24
28
  options: [
@@ -144,12 +148,42 @@ CustomMask.args = {
144
148
  mask: (value) => (value.startsWith('1') ? '#-#' : '##-##'),
145
149
  };
146
150
 
151
+ const CustomClassesT = (args) => ({
152
+ components: { BaseInput, ShowValue },
153
+ setup() {
154
+ const value = ref(null);
155
+ return { args, value };
156
+ },
157
+ template: `
158
+ <BaseInput v-model="value" v-bind="args" suffix="$$$" class="w-full bg-green-100 text-green-700 border-green-700 focus-within:border-red-500 focus-within:ring-red-800 placeholder:text-green-400 shadow-xl"></BaseInput>
159
+ <ShowValue :value="value" />
160
+ `,
161
+ });
162
+
163
+ export const CustomClasses = CustomClassesT.bind({});
164
+
147
165
  export const Field = createFieldStory({
148
166
  component: BaseInput,
149
167
  componentName: 'BaseInput',
150
168
  label: 'Name',
151
169
  });
152
170
 
171
+ const TemplateSizes = (args) => ({
172
+ components: { BaseInput, ShowValue },
173
+ setup() {
174
+ const value = ref(null);
175
+ const sizes = ['xs', 'sm', 'md'];
176
+ return { args, value, sizes };
177
+ },
178
+ template: `
179
+ <div v-for="size in sizes" :key="size" class="mb-4">
180
+ <p class="text-xs text-slate-600 leading-tight mb-1">btn {{ size }}</p>
181
+ <BaseInput v-model="value" v-bind="args" :size="size" class="w-full"></BaseInput>
182
+ </div>
183
+ `,
184
+ });
185
+
186
+ export const Sizes = TemplateSizes.bind({});
153
187
 
154
188
  const FocusTemplate = (args) => ({
155
189
  components: { BaseInput },
@@ -161,7 +195,7 @@ const FocusTemplate = (args) => ({
161
195
  template: `
162
196
  <BaseInput ref="input" v-model="value" v-bind="args" class="w-full"></BaseInput>
163
197
 
164
- <button @click="input.focus()" class="mt-4 underline">Focus</button>
198
+ <button @click="input.focus()" class="mt-4 btn btn-sm">Focus</button>
165
199
  `,
166
200
  });
167
201