sprintify-ui 0.6.33 → 0.6.35

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 (58) hide show
  1. package/dist/sprintify-ui.es.js +12984 -12888
  2. package/dist/style.css +1 -1
  3. package/dist/tailwindcss/button.js +3 -2
  4. package/dist/tailwindcss/theme.js +14 -7
  5. package/dist/types/src/components/BaseButtonGroup.vue.d.ts +9 -0
  6. package/dist/types/src/components/BaseDataIterator.vue.d.ts +3 -3
  7. package/dist/types/src/components/BaseDataIteratorSectionButton.vue.d.ts +2 -2
  8. package/dist/types/src/components/BaseDataIteratorSectionColumns.vue.d.ts +8 -8
  9. package/dist/types/src/components/BaseDataTable.vue.d.ts +3 -3
  10. package/dist/types/src/components/BaseDataTableRowAction.vue.d.ts +4 -3
  11. package/dist/types/src/components/BaseDatePicker.vue.d.ts +10 -0
  12. package/dist/types/src/components/BaseDateSelect.vue.d.ts +9 -0
  13. package/dist/types/src/components/BaseInput.vue.d.ts +18 -0
  14. package/dist/types/src/components/BasePassword.vue.d.ts +13 -0
  15. package/dist/types/src/components/BaseRichText.vue.d.ts +9 -0
  16. package/dist/types/src/components/BaseTable.vue.d.ts +3 -3
  17. package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +11 -2
  18. package/dist/types/src/components/BaseTextarea.vue.d.ts +18 -0
  19. package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +12 -2
  20. package/dist/types/src/stories/PageInputSizes.vue.d.ts +2 -0
  21. package/dist/types/src/utils/slots.d.ts +1 -0
  22. package/package.json +1 -1
  23. package/src/assets/base-rich-text.css +148 -26
  24. package/src/components/BaseButton.vue +3 -2
  25. package/src/components/BaseButtonGroup.vue +37 -9
  26. package/src/components/BaseColor.vue +29 -31
  27. package/src/components/BaseDataIterator.stories.js +8 -1
  28. package/src/components/BaseDataIterator.vue +36 -76
  29. package/src/components/BaseDataIteratorSectionButton.vue +8 -19
  30. package/src/components/BaseDataTable.vue +25 -18
  31. package/src/components/BaseDataTableRowAction.vue +8 -7
  32. package/src/components/BaseDatePicker.stories.js +23 -0
  33. package/src/components/BaseDatePicker.vue +71 -11
  34. package/src/components/BaseDateSelect.stories.js +25 -1
  35. package/src/components/BaseDateSelect.vue +80 -101
  36. package/src/components/BaseDraggable.vue +5 -1
  37. package/src/components/BaseDropdownAutocomplete.stories.js +30 -15
  38. package/src/components/BaseHasMany.stories.js +22 -1
  39. package/src/components/BaseInput.stories.js +4 -4
  40. package/src/components/BaseInput.vue +61 -15
  41. package/src/components/BaseMediaPicturesItem.vue +2 -2
  42. package/src/components/BasePassword.stories.js +25 -0
  43. package/src/components/BasePassword.vue +35 -55
  44. package/src/components/BaseRichText.stories.js +6 -0
  45. package/src/components/BaseRichText.vue +12 -2
  46. package/src/components/BaseSelect.vue +5 -0
  47. package/src/components/BaseTable.vue +2 -1
  48. package/src/components/BaseTagAutocomplete.stories.js +1 -1
  49. package/src/components/BaseTagAutocomplete.vue +143 -88
  50. package/src/components/BaseTagAutocompleteFetch.stories.js +22 -1
  51. package/src/components/BaseTextarea.stories.js +25 -0
  52. package/src/components/BaseTextarea.vue +34 -3
  53. package/src/components/BaseTextareaAutoresize.stories.js +27 -2
  54. package/src/components/BaseTextareaAutoresize.vue +28 -9
  55. package/src/composables/inputSize.ts +5 -1
  56. package/src/stories/InputSizes.stories.js +22 -0
  57. package/src/stories/PageInputSizes.vue +205 -0
  58. package/src/utils/slots.ts +13 -0
@@ -8,17 +8,23 @@
8
8
  :disabled="disabled"
9
9
  :required="requiredInternal"
10
10
  :rows="rows"
11
- :class="[hasErrorInternal ? 'border-red-500' : 'border-slate-300']"
12
- class="mb-0 block rounded disabled:cursor-not-allowed disabled:text-slate-300"
11
+ :autocomplete="autocomplete ? 'on' : 'off'"
12
+ :class="classes"
13
13
  @input="emitUpdate(transformInputValue($event))"
14
14
  />
15
15
  </template>
16
16
 
17
17
  <script lang="ts" setup>
18
18
  import { useField } from '@/composables/field';
19
+ import { Size, sizes } from '@/utils/sizes';
19
20
  import { get, isString } from 'lodash';
21
+ import { twMerge } from 'tailwind-merge';
20
22
  import { PropType } from 'vue';
21
23
 
24
+ defineOptions({
25
+ inheritAttrs: false,
26
+ });
27
+
22
28
  const props = defineProps({
23
29
  modelValue: {
24
30
  default: undefined,
@@ -28,6 +34,14 @@ const props = defineProps({
28
34
  type: String,
29
35
  default: 'text',
30
36
  },
37
+ size: {
38
+ default: undefined,
39
+ type: String as PropType<Size>,
40
+ },
41
+ class: {
42
+ default: '',
43
+ type: [String, Array] as PropType<string | string[]>,
44
+ },
31
45
  autocomplete: {
32
46
  default: true,
33
47
  type: Boolean,
@@ -64,10 +78,11 @@ const props = defineProps({
64
78
 
65
79
  const emit = defineEmits(['update:modelValue']);
66
80
 
67
- const { nameInternal, requiredInternal, hasErrorInternal, emitUpdate } =
81
+ const { nameInternal, requiredInternal, hasErrorInternal, emitUpdate, sizeInternal } =
68
82
  useField({
69
83
  name: computed(() => props.name),
70
84
  required: computed(() => props.required),
85
+ size: computed(() => props.size),
71
86
  hasError: computed(() => props.hasError),
72
87
  emit: emit,
73
88
  });
@@ -96,6 +111,22 @@ function blur() {
96
111
  textareaRef.value?.blur();
97
112
  }
98
113
 
114
+ const classes = computed(() => {
115
+ const base = 'mb-0 block input-rounded transition-colors duration-200';
116
+ const disabled = 'disabled:cursor-not-allowed disabled:text-slate-300';
117
+ const focus = 'focus:input-focus';
118
+ const error = hasErrorInternal.value ? 'border-red-500 focus:input-focus-error' : 'border-slate-300';
119
+ const sizeConfig = sizes[sizeInternal.value];
120
+
121
+ const padding = {
122
+ xs: 'p-2',
123
+ sm: 'p-2.5',
124
+ md: 'p-3',
125
+ }[sizeInternal.value];
126
+
127
+ return twMerge(base, disabled, error, focus, sizeConfig.fontSize, padding, props.class);
128
+ });
129
+
99
130
  defineExpose({
100
131
  focus,
101
132
  blur,
@@ -2,6 +2,8 @@ import BaseTextareaAutoresize from './BaseTextareaAutoresize.vue';
2
2
  import ShowValue from '@/../.storybook/components/ShowValue.vue';
3
3
  import { createFieldStory } from '../../.storybook/utils';
4
4
 
5
+ const sizes = ['xs', 'sm', 'md'];
6
+
5
7
  export default {
6
8
  title: 'Form/BaseTextareaAutoresize',
7
9
  component: BaseTextareaAutoresize,
@@ -9,6 +11,12 @@ export default {
9
11
  name: 'name',
10
12
  placeholder: 'Describe your complete life in 4 sentences...',
11
13
  },
14
+ argTypes: {
15
+ size: {
16
+ control: { type: 'select' },
17
+ options: sizes,
18
+ },
19
+ },
12
20
  };
13
21
 
14
22
  const Template = (args) => ({
@@ -68,8 +76,8 @@ const TemplateTWTextarea = (args) => ({
68
76
  <BaseTextareaAutoresize
69
77
  v-model="value"
70
78
  v-bind="args"
71
- class="w-full shadow rounded"
72
- tw-textarea="p-5 bg-slate-100 text-slate-700 focus:ring-blue-200 focus:ring-4 text-sm"
79
+ class="w-full"
80
+ tw-textarea="shadow-xl rounded-none p-5 duration-500 transition-all bg-slate-100 text-slate-900 ring-2 ring-purple-700 border-none ring-opacity-60 focus:ring-pink-500 focus:ring-4 focus:bg-pink-100"
73
81
  @submit="onSubmit"
74
82
  ></BaseTextareaAutoresize>
75
83
  </form>
@@ -86,6 +94,23 @@ export const Field = createFieldStory({
86
94
  label: 'Biography',
87
95
  });
88
96
 
97
+ const TemplateSizes = (args) => ({
98
+ components: { BaseTextareaAutoresize },
99
+ setup() {
100
+ const value = ref(null);
101
+ const sizes = ['xs', 'sm', 'md'];
102
+ return { args, value, sizes };
103
+ },
104
+ template: `
105
+ <div v-for="size in sizes" :key="size" class="mb-4">
106
+ <p class="text-xs text-slate-600 leading-tight mb-1">{{ size }}</p>
107
+ <BaseTextareaAutoresize v-model="value" v-bind="args" :size="size" class="w-full"></BaseTextareaAutoresize>
108
+ </div>
109
+ `,
110
+ });
111
+
112
+ export const Sizes = TemplateSizes.bind({});
113
+
89
114
  const FocusTemplate = (args) => ({
90
115
  components: { BaseTextareaAutoresize },
91
116
  setup() {
@@ -36,12 +36,10 @@
36
36
 
37
37
  <script lang="ts" setup>
38
38
  import { useField } from '@/composables/field';
39
+ import { sizes, Size } from '@/utils/sizes';
39
40
  import { twMerge } from 'tailwind-merge';
40
41
  import { PropType } from 'vue';
41
42
 
42
- const BASE_TEXTAREA_CLASSES =
43
- 'py-2 px-3 font-normal text-base disabled:cursor-not-allowed disabled:text-slate-300 font-sans rounded leading-normal tracking-normal border placeholder:text-slate-400 placeholder:font-light';
44
-
45
43
  const BASE_GRID_AREA = '1 / 1 / 2 / 2';
46
44
 
47
45
  /* Note the weird space! Needed to prevent jumpy behavior */
@@ -57,13 +55,17 @@ const props = defineProps({
57
55
  type: String,
58
56
  },
59
57
  name: {
60
- required: true,
58
+ default: undefined,
61
59
  type: String,
62
60
  },
63
61
  required: {
64
62
  default: false,
65
63
  type: Boolean,
66
64
  },
65
+ size: {
66
+ default: undefined,
67
+ type: String as PropType<Size>,
68
+ },
67
69
  maxHeight: {
68
70
  default: 100,
69
71
  type: Number,
@@ -98,10 +100,11 @@ const emit = defineEmits(['update:modelValue', 'submit', 'focus', 'input']);
98
100
 
99
101
  const textareaRef = ref<null | HTMLTextAreaElement>(null);
100
102
 
101
- const { nameInternal, requiredInternal, hasErrorInternal } =
103
+ const { nameInternal, requiredInternal, hasErrorInternal, sizeInternal } =
102
104
  useField({
103
105
  name: computed(() => props.name),
104
106
  required: computed(() => props.required),
107
+ size: computed(() => props.size),
105
108
  hasError: computed(() => props.hasError),
106
109
  emit: emit,
107
110
  });
@@ -142,11 +145,27 @@ function onFocus(event: FocusEvent) {
142
145
  }
143
146
 
144
147
  const textareaClasses = computed(() => {
148
+ const base = 'input-rounded leading-normal tracking-normal border transition-colors duration-200';
149
+ const disabled = 'disabled:cursor-not-allowed disabled:text-slate-300';
150
+ const focus = 'focus:input-focus';
151
+ const error = hasErrorInternal.value ? 'border-red-500 focus:input-focus-error' : 'border-slate-300';
152
+ const placeholder = 'placeholder:text-slate-400 placeholder:font-light';
153
+ const sizeConfig = sizes[sizeInternal.value];
154
+
155
+ const sizeClasses = {
156
+ xs: 'px-2 py-[0.26rem] min-h-control-xs',
157
+ sm: 'px-2.5 py-[0.31rem] min-h-control-sm',
158
+ md: 'px-3 py-[0.43rem] min-h-control-md',
159
+ }[sizeInternal.value];
160
+
145
161
  return twMerge(
146
- [
147
- BASE_TEXTAREA_CLASSES,
148
- hasErrorInternal.value ? 'border-red-500' : 'border-slate-300',
149
- ],
162
+ base,
163
+ disabled,
164
+ error,
165
+ placeholder,
166
+ focus,
167
+ sizeConfig.fontSize,
168
+ sizeClasses,
150
169
  props.twTextarea
151
170
  );
152
171
  });
@@ -1,5 +1,5 @@
1
1
  import { useBreakpoints } from "./breakpoints";
2
- import { Size } from "@/utils/sizes";
2
+ import { Size, sizes } from "@/utils/sizes";
3
3
  import { MaybeRef } from "vue";
4
4
 
5
5
  function useInputSize(size: MaybeRef<Size | '' | undefined | null>) {
@@ -18,6 +18,10 @@ function useInputSize(size: MaybeRef<Size | '' | undefined | null>) {
18
18
  s = 'md';
19
19
  }
20
20
 
21
+ if (!Object.keys(sizes).includes(s)) {
22
+ s = 'md';
23
+ }
24
+
21
25
  return s;
22
26
  });
23
27
 
@@ -0,0 +1,22 @@
1
+ import InputSizes from './PageInputSizes.vue';
2
+
3
+ export default {
4
+ title: 'Pages/InputSize',
5
+ component: InputSizes,
6
+ parameters: {
7
+ layout: 'fullscreen',
8
+ },
9
+ };
10
+
11
+
12
+ const Template = (args) => ({
13
+ components: {
14
+ InputSizes
15
+ },
16
+ template: `<InputSizes></InputSizes>`,
17
+ setup() {
18
+ return { args };
19
+ },
20
+ });
21
+
22
+ export const Demo = Template.bind({});
@@ -0,0 +1,205 @@
1
+ <template>
2
+ <div class="p-5 flex flex-col gap-4 overflow-x-scroll overflow-y-visible pb-[400px]">
3
+ <div
4
+ v-for="size in sizes"
5
+ :key="size"
6
+ >
7
+ <div class="flex gap-1">
8
+ <BaseField :size="size">
9
+ <BaseInput
10
+ v-model="text"
11
+ placeholder="Name"
12
+ icon-left="heroicons:calendar"
13
+ />
14
+ </BaseField>
15
+ <BaseField :size="size">
16
+ <BaseSelect
17
+ v-model="valueId"
18
+ placeholder="Name"
19
+ label-key="label"
20
+ value-key="value"
21
+ :options="options"
22
+ />
23
+ </BaseField>
24
+ <BaseField
25
+ :size="size"
26
+ class="min-w-[200px]"
27
+ >
28
+ <BaseDatePicker v-model="date" />
29
+ </BaseField>
30
+ <BaseField
31
+ :size="size"
32
+ >
33
+ <BaseDateSelect v-model="date" />
34
+ </BaseField>
35
+ <BaseField :size="size">
36
+ <BaseAutocomplete
37
+ v-model="valueObject"
38
+ label-key="label"
39
+ value-key="value"
40
+ :options="options"
41
+ />
42
+ </BaseField>
43
+ <BaseField
44
+ v-if="false"
45
+ :size="size"
46
+ >
47
+ <BaseAutocompleteFetch
48
+ v-model="valueObjectFetch"
49
+ label-key="name"
50
+ value-key="id"
51
+ url="https://jsonplaceholder.typicode.com/users"
52
+ />
53
+ </BaseField>
54
+ <BaseField
55
+ v-if="false"
56
+ :size="size"
57
+ >
58
+ <BaseBelongsTo
59
+ v-model="valueId"
60
+ field="label"
61
+ primary-key="value"
62
+ :options="options"
63
+ />
64
+ </BaseField>
65
+ <BaseField
66
+ v-if="false"
67
+ :size="size"
68
+ >
69
+ <BaseBelongsToFetch
70
+ v-model="valueIdFetch"
71
+ field="name"
72
+ primary-key="id"
73
+ url="https://jsonplaceholder.typicode.com/users"
74
+ />
75
+ </BaseField>
76
+ <BaseField :size="size">
77
+ <BaseTagAutocomplete
78
+ v-model="valueArrayOfObjects"
79
+ label-key="label"
80
+ value-key="value"
81
+ :options="options"
82
+ />
83
+ </BaseField>
84
+ <BaseField
85
+ v-if="false"
86
+ :size="size"
87
+ >
88
+ <BaseTagAutocompleteFetch
89
+ v-model="valueArrayOfObjectFetch"
90
+ label-key="name"
91
+ value-key="id"
92
+ url="https://jsonplaceholder.typicode.com/users"
93
+ />
94
+ </BaseField>
95
+ <BaseField :size="size">
96
+ <BasePassword
97
+ v-model="text"
98
+ placeholder="Password"
99
+ />
100
+ </BaseField>
101
+ <BaseField :size="size">
102
+ <BaseInputPercent
103
+ v-model="number"
104
+ placeholder="Enter a value"
105
+ />
106
+ </BaseField>
107
+ <BaseField
108
+ :size="size"
109
+ class="min-w-[200px]"
110
+ >
111
+ <BaseTextareaAutoresize
112
+ v-model="text"
113
+ placeholder="Tell me a story"
114
+ />
115
+ </BaseField>
116
+ <BaseField :size="size">
117
+ <BaseButtonGroup
118
+ v-model="valueArrayOfObjects"
119
+ label-key="label"
120
+ value-key="value"
121
+ spacing="none"
122
+ :options="options.slice(0, 3)"
123
+ />
124
+ </BaseField>
125
+ <BaseField :size="size">
126
+ <BaseColor
127
+ v-model="colors"
128
+ class="flex-nowrap"
129
+ />
130
+ </BaseField>
131
+ </div>
132
+ </div>
133
+
134
+ <div
135
+ v-for="size in sizes"
136
+ :key="size"
137
+ class="flex flex-col gap-3"
138
+ >
139
+ <BaseInput
140
+ v-model="text"
141
+ :size="size"
142
+ placeholder="Name"
143
+ icon-left="heroicons:calendar"
144
+ />
145
+ <BaseDatePicker
146
+ v-model="date"
147
+ :size="size"
148
+ />
149
+ </div>
150
+ </div>
151
+ </template>
152
+
153
+ <script lang="ts" setup>
154
+ import { Size } from '@/utils/sizes';
155
+ import BaseField from '@/components/BaseField.vue';
156
+ import BaseSelect from '@/components/BaseSelect.vue';
157
+ import BaseAutocomplete from '@/components/BaseAutocomplete.vue';
158
+ import BaseInput from '@/components/BaseInput.vue';
159
+ import BaseAutocompleteFetch from '@/components/BaseAutocompleteFetch.vue';
160
+ import BaseBelongsTo from '@/components/BaseBelongsTo.vue';
161
+ import BaseBelongsToFetch from '@/components/BaseBelongsToFetch.vue';
162
+ import BaseTagAutocomplete from '@/components/BaseTagAutocomplete.vue';
163
+ import BaseTagAutocompleteFetch from '@/components/BaseTagAutocompleteFetch.vue';
164
+ import BaseButtonGroup from '@/components/BaseButtonGroup.vue';
165
+ import BaseColor from '@/components/BaseColor.vue';
166
+ import BasePassword from '@/components/BasePassword.vue';
167
+ import BaseInputPercent from '@/components/BaseInputPercent.vue';
168
+ import BaseTextareaAutoresize from '@/components/BaseTextareaAutoresize.vue';
169
+ import BaseDatePicker from '@/components/BaseDatePicker.vue';
170
+ import BaseDateSelect from '@/components/BaseDateSelect.vue';
171
+
172
+ const sizes = ref<Size[]>(['xs', 'sm', 'md']);
173
+
174
+ const text = ref('');
175
+ const number = ref('');
176
+
177
+ const valueObject = ref(null);
178
+ const valueObjectFetch = ref(null);
179
+
180
+ const valueId = ref(null);
181
+ const valueIdFetch = ref(null);
182
+
183
+ const valueArrayOfObjects = ref([]);
184
+ const valueArrayOfObjectFetch = ref([]);
185
+
186
+ const colors = ref([]);
187
+
188
+ const date = ref(null);
189
+
190
+ const options = [
191
+ { label: 'Dark Vader', value: 'dark_vader', type: 'sith' },
192
+ { label: 'Darth Maul', value: 'darth_maul', type: 'sith' },
193
+ { label: 'Dark Sidious', value: 'dark_sidious', type: 'sith' },
194
+ { label: 'Obi Wan Kenobi', value: 'obiwan', type: 'jedi' },
195
+ { label: 'Anakin Skywalker', value: 'anakin', type: 'jedi' },
196
+ { label: 'Mace Windu', value: 'windu', type: 'jedi' },
197
+ { label: 'Padme Amidala', value: 'padme', type: 'jedi' },
198
+ { label: 'Princesse Leila', value: 'leila', type: 'jedi' },
199
+ { label: 'Qui Gon Gin', value: 'quigon', type: 'jedi' },
200
+ { label: 'Chewbaca', value: 'chewbaca', type: 'jedi' },
201
+ { label: 'C3P0', value: 'c3p0', type: 'jedi' },
202
+ { label: 'R2D2', value: 'r2d2', type: 'jedi' },
203
+ ];
204
+
205
+ </script>
@@ -0,0 +1,13 @@
1
+ import { Comment } from 'vue';
2
+
3
+ export function isSlotEmpty(slot: any, props = {}) {
4
+ return isVNodeEmpty(slot?.(props))
5
+ }
6
+
7
+ function isVNodeEmpty(vnode: any) {
8
+ return !vnode || asArray(vnode).every((vnode) => vnode.type === Comment)
9
+ }
10
+
11
+ function asArray(arg: any) {
12
+ return Array.isArray(arg) ? arg : arg != null ? [arg] : []
13
+ }