sprintify-ui 0.0.31 → 0.0.32

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.
@@ -0,0 +1,288 @@
1
+ import { PropType } from 'vue';
2
+ import { NormalizedOption, Option } from '@/types/types';
3
+ declare const _default: {
4
+ new (...args: any[]): {
5
+ $: import("vue").ComponentInternalInstance;
6
+ $data: {};
7
+ $props: Partial<{
8
+ required: boolean;
9
+ modelValue: Option | Option[] | undefined;
10
+ disabled: boolean;
11
+ multiple: boolean;
12
+ buttonClass: string;
13
+ buttonType: "button" | "submit";
14
+ buttonActiveClass: string;
15
+ buttonInactiveClass: string;
16
+ spacing: string;
17
+ }> & Omit<Readonly<import("vue").ExtractPropTypes<{
18
+ modelValue: {
19
+ default: undefined;
20
+ type: PropType<Option | Option[] | undefined>;
21
+ };
22
+ required: {
23
+ default: boolean;
24
+ type: BooleanConstructor;
25
+ };
26
+ disabled: {
27
+ default: boolean;
28
+ type: BooleanConstructor;
29
+ };
30
+ buttonType: {
31
+ default: string;
32
+ type: PropType<"button" | "submit">;
33
+ };
34
+ buttonClass: {
35
+ default: string;
36
+ type: StringConstructor;
37
+ };
38
+ buttonActiveClass: {
39
+ default: string;
40
+ type: StringConstructor;
41
+ };
42
+ buttonInactiveClass: {
43
+ default: string;
44
+ type: StringConstructor;
45
+ };
46
+ spacing: {
47
+ default: string;
48
+ type: StringConstructor;
49
+ };
50
+ options: {
51
+ required: true;
52
+ type: PropType<Option[]>;
53
+ };
54
+ labelKey: {
55
+ required: true;
56
+ type: StringConstructor;
57
+ };
58
+ valueKey: {
59
+ required: true;
60
+ type: StringConstructor;
61
+ };
62
+ multiple: {
63
+ default: boolean;
64
+ type: BooleanConstructor;
65
+ };
66
+ }>> & {
67
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
68
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, "required" | "modelValue" | "disabled" | "multiple" | "buttonClass" | "buttonType" | "buttonActiveClass" | "buttonInactiveClass" | "spacing">;
69
+ $attrs: {
70
+ [x: string]: unknown;
71
+ };
72
+ $refs: {
73
+ [x: string]: unknown;
74
+ };
75
+ $slots: Readonly<{
76
+ [name: string]: import("vue").Slot | undefined;
77
+ }>;
78
+ $root: import("vue").ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}, {}, string>, {}> | null;
79
+ $parent: import("vue").ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}, {}, string>, {}> | null;
80
+ $emit: (event: "update:modelValue", ...args: any[]) => void;
81
+ $el: any;
82
+ $options: import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
83
+ modelValue: {
84
+ default: undefined;
85
+ type: PropType<Option | Option[] | undefined>;
86
+ };
87
+ required: {
88
+ default: boolean;
89
+ type: BooleanConstructor;
90
+ };
91
+ disabled: {
92
+ default: boolean;
93
+ type: BooleanConstructor;
94
+ };
95
+ buttonType: {
96
+ default: string;
97
+ type: PropType<"button" | "submit">;
98
+ };
99
+ buttonClass: {
100
+ default: string;
101
+ type: StringConstructor;
102
+ };
103
+ buttonActiveClass: {
104
+ default: string;
105
+ type: StringConstructor;
106
+ };
107
+ buttonInactiveClass: {
108
+ default: string;
109
+ type: StringConstructor;
110
+ };
111
+ spacing: {
112
+ default: string;
113
+ type: StringConstructor;
114
+ };
115
+ options: {
116
+ required: true;
117
+ type: PropType<Option[]>;
118
+ };
119
+ labelKey: {
120
+ required: true;
121
+ type: StringConstructor;
122
+ };
123
+ valueKey: {
124
+ required: true;
125
+ type: StringConstructor;
126
+ };
127
+ multiple: {
128
+ default: boolean;
129
+ type: BooleanConstructor;
130
+ };
131
+ }>> & {
132
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
133
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], string, {
134
+ required: boolean;
135
+ modelValue: Option | Option[] | undefined;
136
+ disabled: boolean;
137
+ multiple: boolean;
138
+ buttonClass: string;
139
+ buttonType: "button" | "submit";
140
+ buttonActiveClass: string;
141
+ buttonInactiveClass: string;
142
+ spacing: string;
143
+ }, {}, string> & {
144
+ beforeCreate?: ((() => void) | (() => void)[]) | undefined;
145
+ created?: ((() => void) | (() => void)[]) | undefined;
146
+ beforeMount?: ((() => void) | (() => void)[]) | undefined;
147
+ mounted?: ((() => void) | (() => void)[]) | undefined;
148
+ beforeUpdate?: ((() => void) | (() => void)[]) | undefined;
149
+ updated?: ((() => void) | (() => void)[]) | undefined;
150
+ activated?: ((() => void) | (() => void)[]) | undefined;
151
+ deactivated?: ((() => void) | (() => void)[]) | undefined;
152
+ beforeDestroy?: ((() => void) | (() => void)[]) | undefined;
153
+ beforeUnmount?: ((() => void) | (() => void)[]) | undefined;
154
+ destroyed?: ((() => void) | (() => void)[]) | undefined;
155
+ unmounted?: ((() => void) | (() => void)[]) | undefined;
156
+ renderTracked?: (((e: import("vue").DebuggerEvent) => void) | ((e: import("vue").DebuggerEvent) => void)[]) | undefined;
157
+ renderTriggered?: (((e: import("vue").DebuggerEvent) => void) | ((e: import("vue").DebuggerEvent) => void)[]) | undefined;
158
+ errorCaptured?: (((err: unknown, instance: import("vue").ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}, {}, string>, {}> | null, info: string) => boolean | void) | ((err: unknown, instance: import("vue").ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, import("vue").ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}, {}, string>, {}> | null, info: string) => boolean | void)[]) | undefined;
159
+ };
160
+ $forceUpdate: () => void;
161
+ $nextTick: typeof import("vue").nextTick;
162
+ $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (args_0: R, args_1: R) => any : (...args: any) => any, options?: import("vue").WatchOptions<boolean> | undefined): import("vue").WatchStopHandle;
163
+ } & Readonly<import("vue").ExtractPropTypes<{
164
+ modelValue: {
165
+ default: undefined;
166
+ type: PropType<Option | Option[] | undefined>;
167
+ };
168
+ required: {
169
+ default: boolean;
170
+ type: BooleanConstructor;
171
+ };
172
+ disabled: {
173
+ default: boolean;
174
+ type: BooleanConstructor;
175
+ };
176
+ buttonType: {
177
+ default: string;
178
+ type: PropType<"button" | "submit">;
179
+ };
180
+ buttonClass: {
181
+ default: string;
182
+ type: StringConstructor;
183
+ };
184
+ buttonActiveClass: {
185
+ default: string;
186
+ type: StringConstructor;
187
+ };
188
+ buttonInactiveClass: {
189
+ default: string;
190
+ type: StringConstructor;
191
+ };
192
+ spacing: {
193
+ default: string;
194
+ type: StringConstructor;
195
+ };
196
+ options: {
197
+ required: true;
198
+ type: PropType<Option[]>;
199
+ };
200
+ labelKey: {
201
+ required: true;
202
+ type: StringConstructor;
203
+ };
204
+ valueKey: {
205
+ required: true;
206
+ type: StringConstructor;
207
+ };
208
+ multiple: {
209
+ default: boolean;
210
+ type: BooleanConstructor;
211
+ };
212
+ }>> & {
213
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
214
+ } & import("vue").ShallowUnwrapRef<{}> & {} & import("vue").ComponentCustomProperties & {};
215
+ __isFragment?: undefined;
216
+ __isTeleport?: undefined;
217
+ __isSuspense?: undefined;
218
+ } & import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
219
+ modelValue: {
220
+ default: undefined;
221
+ type: PropType<Option | Option[] | undefined>;
222
+ };
223
+ required: {
224
+ default: boolean;
225
+ type: BooleanConstructor;
226
+ };
227
+ disabled: {
228
+ default: boolean;
229
+ type: BooleanConstructor;
230
+ };
231
+ buttonType: {
232
+ default: string;
233
+ type: PropType<"button" | "submit">;
234
+ };
235
+ buttonClass: {
236
+ default: string;
237
+ type: StringConstructor;
238
+ };
239
+ buttonActiveClass: {
240
+ default: string;
241
+ type: StringConstructor;
242
+ };
243
+ buttonInactiveClass: {
244
+ default: string;
245
+ type: StringConstructor;
246
+ };
247
+ spacing: {
248
+ default: string;
249
+ type: StringConstructor;
250
+ };
251
+ options: {
252
+ required: true;
253
+ type: PropType<Option[]>;
254
+ };
255
+ labelKey: {
256
+ required: true;
257
+ type: StringConstructor;
258
+ };
259
+ valueKey: {
260
+ required: true;
261
+ type: StringConstructor;
262
+ };
263
+ multiple: {
264
+ default: boolean;
265
+ type: BooleanConstructor;
266
+ };
267
+ }>> & {
268
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
269
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", {
270
+ required: boolean;
271
+ modelValue: Option | Option[] | undefined;
272
+ disabled: boolean;
273
+ multiple: boolean;
274
+ buttonClass: string;
275
+ buttonType: "button" | "submit";
276
+ buttonActiveClass: string;
277
+ buttonInactiveClass: string;
278
+ spacing: string;
279
+ }, {}, string> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
280
+ $slots: {
281
+ option: (_: {
282
+ isActive: (option: NormalizedOption) => boolean;
283
+ onSelect: (option: NormalizedOption) => void;
284
+ option: NormalizedOption;
285
+ }) => any;
286
+ };
287
+ });
288
+ export default _default;
@@ -14,7 +14,7 @@ export interface DataTableQuery extends Record<string, any> {
14
14
  }
15
15
  export type OptionValue = string | number;
16
16
  export type Option = Record<string, any>;
17
- export type Selection = Record<string, any> | null | undefined;
17
+ export type Selection = Option | null | undefined;
18
18
  export type NormalizedOption = {
19
19
  option: Option;
20
20
  value: OptionValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "scripts": {
5
5
  "build": "rimraf dist && vue-tsc && vite build",
6
6
  "build-fast": "rimraf dist && vite build",
@@ -0,0 +1,87 @@
1
+ import BaseButtonGroup from './BaseButtonGroup.vue';
2
+
3
+ export default {
4
+ title: 'Form/BaseButtonGroup',
5
+ component: BaseButtonGroup,
6
+ argTypes: {},
7
+ args: {
8
+ labelKey: 'label',
9
+ valueKey: 'value',
10
+ options: [
11
+ { label: 'Dark Vader', value: 'dark_vader' },
12
+ { label: 'Darth Maul', value: 'darth_maul' },
13
+ { label: 'Dark Sidious', value: 'dark_sidious' },
14
+ { label: 'Obi Wan Kenobi', value: 'obiwan' },
15
+ { label: 'Anakin Skywalker', value: 'anakin' },
16
+ { label: 'Mace Windu', value: 'windu' },
17
+ ],
18
+ },
19
+ decorators: [() => ({ template: '<div class="mb-36"><story/></div>' })],
20
+ };
21
+
22
+ const Template = (args) => ({
23
+ components: { BaseButtonGroup },
24
+ setup() {
25
+ const value = ref(null);
26
+ return { args, value };
27
+ },
28
+ template: `
29
+ <BaseButtonGroup v-model="value" v-bind="args"></BaseButtonGroup>
30
+ <p class="mt-5 text-sm">Value: <span class="bg-slate-200 font-mono px-1 py-px rounded">{{ value ?? 'NULL' }}</span></p>
31
+ `,
32
+ });
33
+
34
+ export const Single = Template.bind({});
35
+ Single.args = {};
36
+
37
+ export const SingleRequired = Template.bind({});
38
+ SingleRequired.args = {
39
+ required: true,
40
+ };
41
+
42
+ export const Multiple = Template.bind({});
43
+ Multiple.args = {
44
+ multiple: true,
45
+ };
46
+
47
+ export const Disabled = Template.bind({});
48
+ Disabled.args = {
49
+ disabled: true,
50
+ modelValue: { label: 'Dark Maul', value: 'darth_maul' },
51
+ };
52
+
53
+ export const SlotOption = (args) => ({
54
+ components: { BaseButtonGroup },
55
+ setup() {
56
+ const value = ref(null);
57
+
58
+ const options = [
59
+ { label: 'Red', value: 'red' },
60
+ { label: 'Blue', value: 'blue' },
61
+ { label: 'Green', value: 'green' },
62
+ { label: 'Black', value: 'black' },
63
+ { label: 'Gray', value: 'gray' },
64
+ ];
65
+
66
+ return { value, options, args };
67
+ },
68
+ template: `
69
+ <BaseButtonGroup
70
+ v-bind="args"
71
+ v-model="value"
72
+ :options="options"
73
+ >
74
+ <template #option="{ option, isActive, onSelect }">
75
+ <button
76
+ class="btn btn-xs flex items-center space-x-1 font-semibold"
77
+ :class="[isActive(option) ? 'btn-black' : '']"
78
+ type="button"
79
+ @click="onSelect(option)"
80
+ >
81
+ <div class="w-3 h-3 rounded" :style="{ backgroundColor: option.value }"></div>
82
+ <div>{{ option.label }}</div>
83
+ </button>
84
+ </template>
85
+ </BaseButtonGroup>
86
+ `,
87
+ });
@@ -0,0 +1,176 @@
1
+ <template>
2
+ <div class="flex flex-wrap" :style="{ margin: '-' + spacing }">
3
+ <div
4
+ v-for="option in normalizedOptions"
5
+ :key="option.value"
6
+ :style="{ padding: spacing }"
7
+ >
8
+ <slot
9
+ name="option"
10
+ :is-active="isActive"
11
+ :on-select="onSelect"
12
+ :option="option"
13
+ >
14
+ <button
15
+ :type="buttonType"
16
+ :disabled="disabled"
17
+ :class="[
18
+ buttonClass,
19
+ isActive(option) ? buttonActiveClass : buttonInactiveClass,
20
+ ]"
21
+ @click="onSelect(option)"
22
+ >
23
+ {{ option.label }}
24
+ </button>
25
+ </slot>
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script lang="ts" setup>
31
+ import { PropType } from 'vue';
32
+ import { NormalizedOption, Option } from '@/types/types';
33
+ import { cloneDeep, isArray, isObject } from 'lodash';
34
+
35
+ const props = defineProps({
36
+ modelValue: {
37
+ default: undefined,
38
+ type: [Array, String, Number, null] as PropType<
39
+ Option[] | Option | undefined
40
+ >,
41
+ },
42
+ required: {
43
+ default: false,
44
+ type: Boolean,
45
+ },
46
+ disabled: {
47
+ default: false,
48
+ type: Boolean,
49
+ },
50
+ buttonType: {
51
+ default: 'button',
52
+ type: String as PropType<'button' | 'submit'>,
53
+ },
54
+ buttonClass: {
55
+ default: 'btn btn-sm',
56
+ type: String,
57
+ },
58
+ buttonActiveClass: {
59
+ default: 'btn-primary',
60
+ type: String,
61
+ },
62
+ buttonInactiveClass: {
63
+ default: '',
64
+ type: String,
65
+ },
66
+ spacing: {
67
+ default: '0.15rem',
68
+ type: String,
69
+ },
70
+ options: {
71
+ required: true,
72
+ type: Array as PropType<Option[]>,
73
+ },
74
+ labelKey: {
75
+ required: true,
76
+ type: String,
77
+ },
78
+ valueKey: {
79
+ required: true,
80
+ type: String,
81
+ },
82
+ multiple: {
83
+ default: false,
84
+ type: Boolean,
85
+ },
86
+ });
87
+
88
+ const emit = defineEmits(['update:modelValue']);
89
+
90
+ const normalizedModelValue = computed(
91
+ (): NormalizedOption[] | NormalizedOption | null => {
92
+ if (props.multiple) {
93
+ if (!isArray(props.modelValue)) {
94
+ return [];
95
+ }
96
+ return props.modelValue.map((option) => {
97
+ return {
98
+ label: option[props.labelKey] as string,
99
+ value: option[props.valueKey] as string | number,
100
+ option: option,
101
+ } as NormalizedOption;
102
+ });
103
+ } else {
104
+ if (!isObject(props.modelValue)) {
105
+ return null;
106
+ }
107
+
108
+ return {
109
+ label: props.modelValue[props.labelKey as never] as string,
110
+ value: props.modelValue[props.valueKey as never] as string | number,
111
+ option: props.modelValue,
112
+ } as NormalizedOption;
113
+ }
114
+ }
115
+ );
116
+
117
+ const normalizedOptions = computed((): NormalizedOption[] => {
118
+ return props.options.map((option) => {
119
+ return {
120
+ label: option[props.labelKey] as string,
121
+ value: option[props.valueKey] as string | number,
122
+ option: option,
123
+ } as NormalizedOption;
124
+ });
125
+ });
126
+
127
+ function isActive(option: NormalizedOption): boolean {
128
+ if (isArray(normalizedModelValue.value)) {
129
+ return normalizedModelValue.value.some((modelValue) => {
130
+ return modelValue.value === option.value;
131
+ });
132
+ }
133
+
134
+ if (isObject(normalizedModelValue.value)) {
135
+ return normalizedModelValue.value.value == option.value;
136
+ }
137
+
138
+ return false;
139
+ }
140
+
141
+ function onSelect(option: NormalizedOption) {
142
+ if (props.multiple) {
143
+ let newModalValue = [] as NormalizedOption[];
144
+
145
+ if (isArray(normalizedModelValue.value)) {
146
+ newModalValue = cloneDeep(normalizedModelValue.value);
147
+ }
148
+
149
+ const exists = newModalValue.find((o) => o.value == option.value);
150
+
151
+ if (exists) {
152
+ newModalValue = newModalValue.filter((o) => o.value != option.value);
153
+ } else {
154
+ newModalValue.push(option);
155
+ }
156
+
157
+ emit(
158
+ 'update:modelValue',
159
+ newModalValue.map((o) => o.option)
160
+ );
161
+ } else {
162
+ if (!props.required) {
163
+ if (
164
+ !isArray(normalizedModelValue.value) &&
165
+ option.value == normalizedModelValue.value?.value
166
+ ) {
167
+ emit('update:modelValue', null);
168
+ return;
169
+ }
170
+ }
171
+
172
+ const newOption = option.option;
173
+ emit('update:modelValue', newOption);
174
+ }
175
+ }
176
+ </script>
@@ -21,7 +21,7 @@ export type OptionValue = string | number;
21
21
 
22
22
  export type Option = Record<string, any>;
23
23
 
24
- export type Selection = Record<string, any> | null | undefined;
24
+ export type Selection = Option | null | undefined;
25
25
 
26
26
  export type NormalizedOption = {
27
27
  option: Option;