@weni/unnnic-system 3.32.0 → 3.32.1

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.
@@ -16,7 +16,9 @@
16
16
  :type="page === modelValue ? 'secondary' : 'tertiary'"
17
17
  size="small"
18
18
  :text="
19
- ['left-hidden', 'right-hidden'].includes(page) ? '...' : String(page)
19
+ ['left-hidden', 'right-hidden'].includes(page as string)
20
+ ? '...'
21
+ : String(page)
20
22
  "
21
23
  :disabled="disabled"
22
24
  data-test="page-button"
@@ -34,148 +36,129 @@
34
36
  </div>
35
37
  </template>
36
38
 
37
- <script>
39
+ <script setup lang="ts">
40
+ import { computed, ref } from 'vue';
38
41
  import UnnnicButton from '../Button/Button.vue';
39
42
 
40
- export default {
41
- components: {
42
- UnnnicButton,
43
- },
44
-
45
- props: {
46
- modelValue: {
47
- type: Number,
48
- default: 1,
49
- },
50
-
51
- max: {
52
- type: Number,
53
- default: 1,
54
- },
55
-
56
- show: {
57
- type: Number,
58
- default: 5,
59
- },
60
-
61
- disabled: {
62
- type: Boolean,
63
- default: false,
64
- },
65
- },
66
-
67
- emits: ['update:model-value'],
68
-
69
- data() {
70
- return {
71
- reference: 3,
72
- };
73
- },
74
-
75
- computed: {
76
- pages() {
77
- const pages = [];
78
-
79
- for (let i = 1; i <= this.max; i += 1) {
80
- pages.push(i);
81
- }
82
-
83
- const plus = this.show - 4;
84
- const maxToRemove = this.max - plus - 3;
85
-
86
- if (this.reference > 3) {
87
- const toRemove = this.reference - 2;
88
- const maxRemove = toRemove > maxToRemove ? maxToRemove : toRemove;
89
- pages.splice(1, maxRemove, 'left-hidden');
90
- }
91
-
92
- if (this.reference < this.max - plus - 1) {
93
- const toRemove = this.max - plus - this.reference;
94
- const maxRemove = toRemove > maxToRemove ? maxToRemove : toRemove;
95
- pages.splice(-(maxRemove + 1), maxRemove, 'right-hidden');
96
- }
97
-
98
- return pages;
99
- },
100
-
101
- canPrevious() {
102
- return this.modelValue > 1;
103
- },
104
-
105
- canNext() {
106
- return this.modelValue < this.max;
107
- },
108
- },
109
-
110
- created() {
111
- const pageNumber = this.modelValue;
112
-
113
- this.selectPage(pageNumber, true);
114
-
115
- if (!this.pages.includes(pageNumber)) {
116
- this.setReference(pageNumber);
43
+ defineOptions({
44
+ name: 'UnnnicPagination',
45
+ });
46
+
47
+ export type PaginationPage = number | 'left-hidden' | 'right-hidden';
48
+
49
+ export interface PaginationProps {
50
+ modelValue?: number;
51
+ max?: number;
52
+ show?: number;
53
+ disabled?: boolean;
54
+ }
55
+
56
+ const props = withDefaults(defineProps<PaginationProps>(), {
57
+ modelValue: 1,
58
+ max: 1,
59
+ show: 5,
60
+ disabled: false,
61
+ });
62
+
63
+ const emit = defineEmits<{
64
+ 'update:model-value': [value: number];
65
+ }>();
66
+
67
+ const reference = ref(3);
68
+
69
+ const pages = computed((): PaginationPage[] => {
70
+ const pagesList: PaginationPage[] = [];
71
+
72
+ for (let i = 1; i <= props.max; i += 1) {
73
+ pagesList.push(i);
74
+ }
75
+
76
+ const plus = props.show - 4;
77
+ const maxToRemove = props.max - plus - 3;
78
+
79
+ if (reference.value > 3) {
80
+ const toRemove = reference.value - 2;
81
+ const maxRemove = toRemove > maxToRemove ? maxToRemove : toRemove;
82
+ pagesList.splice(1, maxRemove, 'left-hidden');
83
+ }
84
+
85
+ if (reference.value < props.max - plus - 1) {
86
+ const toRemove = props.max - plus - reference.value;
87
+ const maxRemove = toRemove > maxToRemove ? maxToRemove : toRemove;
88
+ pagesList.splice(-(maxRemove + 1), maxRemove, 'right-hidden');
89
+ }
90
+
91
+ return pagesList;
92
+ });
93
+
94
+ const canPrevious = computed(() => props.modelValue > 1);
95
+
96
+ const canNext = computed(() => props.modelValue < props.max);
97
+
98
+ function setReference(value: number) {
99
+ reference.value = value;
100
+ }
101
+
102
+ function selectPage(page: PaginationPage, dontEmit?: boolean) {
103
+ if (page === 'left-hidden') {
104
+ const pageNumber =
105
+ (pages.value[pages.value.indexOf('left-hidden') + 1] as number) - 1;
106
+
107
+ if (!dontEmit) {
108
+ emit('update:model-value', pageNumber);
117
109
  }
118
- },
119
-
120
- methods: {
121
- selectPage(page, dontEmit) {
122
- if (page === 'left-hidden') {
123
- const pageNumber =
124
- this.pages[this.pages.indexOf('left-hidden') + 1] - 1;
125
-
126
- if (!dontEmit) {
127
- this.$emit('update:model-value', pageNumber);
128
- }
129
- this.setReference(pageNumber);
130
- } else if (page === 'right-hidden') {
131
- const pageNumber =
132
- this.pages[this.pages.indexOf('right-hidden') - 1] + 1;
133
-
134
- if (!dontEmit) {
135
- this.$emit('update:model-value', pageNumber);
136
- }
137
-
138
- if (this.pages.includes('left-hidden')) {
139
- this.setReference(
140
- this.pages[this.pages.indexOf('left-hidden') + 1] + 1,
141
- );
142
- } else {
143
- this.setReference(4);
144
- }
145
- } else if (!dontEmit) {
146
- this.$emit('update:model-value', page);
147
- }
148
- },
149
-
150
- previousPage() {
151
- if (this.canPrevious) {
152
- const pageNumber = this.modelValue - 1;
153
-
154
- this.selectPage(pageNumber);
155
-
156
- if (!this.pages.includes(pageNumber)) {
157
- this.setReference(pageNumber);
158
- }
159
- }
160
- },
161
-
162
- nextPage() {
163
- if (this.canNext) {
164
- const pageNumber = this.modelValue + 1;
165
-
166
- this.selectPage(pageNumber);
167
-
168
- if (!this.pages.includes(pageNumber)) {
169
- this.setReference(pageNumber);
170
- }
171
- }
172
- },
173
-
174
- setReference(reference) {
175
- this.reference = reference;
176
- },
177
- },
178
- };
110
+ setReference(pageNumber);
111
+ } else if (page === 'right-hidden') {
112
+ const pageNumber =
113
+ (pages.value[pages.value.indexOf('right-hidden') - 1] as number) + 1;
114
+
115
+ if (!dontEmit) {
116
+ emit('update:model-value', pageNumber);
117
+ }
118
+
119
+ if (pages.value.includes('left-hidden')) {
120
+ setReference(
121
+ (pages.value[pages.value.indexOf('left-hidden') + 1] as number) + 1,
122
+ );
123
+ } else {
124
+ setReference(4);
125
+ }
126
+ } else if (!dontEmit) {
127
+ emit('update:model-value', page);
128
+ }
129
+ }
130
+
131
+ function previousPage() {
132
+ if (canPrevious.value) {
133
+ const pageNumber = props.modelValue - 1;
134
+
135
+ selectPage(pageNumber);
136
+
137
+ if (!pages.value.includes(pageNumber)) {
138
+ setReference(pageNumber);
139
+ }
140
+ }
141
+ }
142
+
143
+ function nextPage() {
144
+ if (canNext.value) {
145
+ const pageNumber = props.modelValue + 1;
146
+
147
+ selectPage(pageNumber);
148
+
149
+ if (!pages.value.includes(pageNumber)) {
150
+ setReference(pageNumber);
151
+ }
152
+ }
153
+ }
154
+
155
+ const pageNumber = props.modelValue;
156
+
157
+ selectPage(pageNumber, true);
158
+
159
+ if (!pages.value.includes(pageNumber)) {
160
+ setReference(pageNumber);
161
+ }
179
162
  </script>
180
163
 
181
164
  <style lang="scss" scoped>
@@ -184,7 +167,7 @@ export default {
184
167
  .pagination {
185
168
  display: flex;
186
169
  align-items: center;
187
- column-gap: $unnnic-spacing-inline-xs;
170
+ column-gap: $unnnic-space-2;
188
171
  user-select: none;
189
172
  }
190
173
  </style>
@@ -37,41 +37,46 @@
37
37
  </section>
38
38
  </template>
39
39
 
40
- <script setup>
40
+ <script setup lang="ts">
41
41
  import { pick } from 'lodash';
42
- import { inject, computed } from 'vue';
43
-
44
- const props = defineProps({
45
- modelValue: {
46
- type: [String, Number],
47
- default: '',
48
- },
49
- value: {
50
- type: [String, Number],
51
- default: '',
52
- },
53
- disabled: {
54
- type: Boolean,
55
- default: false,
56
- },
57
- label: {
58
- type: String,
59
- default: '',
60
- },
61
- name: {
62
- type: String,
63
- default: '',
64
- },
65
- helper: {
66
- type: String,
67
- default: '',
68
- },
42
+ import { inject, computed, useAttrs, type Ref, type ComputedRef } from 'vue';
43
+
44
+ defineOptions({
45
+ name: 'UnnnicRadio',
46
+ });
47
+
48
+ export interface RadioProps {
49
+ modelValue?: string | number;
50
+ value?: string | number;
51
+ disabled?: boolean;
52
+ label?: string;
53
+ name?: string;
54
+ helper?: string;
55
+ }
56
+
57
+ const props = withDefaults(defineProps<RadioProps>(), {
58
+ modelValue: '',
59
+ value: '',
60
+ disabled: false,
61
+ label: '',
62
+ name: '',
63
+ helper: '',
69
64
  });
70
65
 
71
- const emit = defineEmits(['update:modelValue']);
66
+ const emit = defineEmits<{
67
+ 'update:modelValue': [value: string | number];
68
+ }>();
69
+
70
+ const $attrs = useAttrs();
72
71
 
73
- const contextModelValue = inject('contextModelValue', undefined);
74
- const contextName = inject('contextName', undefined);
72
+ const contextModelValue = inject<Ref<string | number> | undefined>(
73
+ 'contextModelValue',
74
+ undefined,
75
+ );
76
+ const contextName = inject<ComputedRef<string> | Ref<string> | undefined>(
77
+ 'contextName',
78
+ undefined,
79
+ );
75
80
 
76
81
  function click() {
77
82
  if (!props.disabled) {
@@ -7,7 +7,7 @@
7
7
  'unnnic-select-item--selectable': selectable,
8
8
  'text-focused': textFocused,
9
9
  }"
10
- @click="$emit('click')"
10
+ @click="emit('click')"
11
11
  >
12
12
  <span
13
13
  :class="[
@@ -20,36 +20,36 @@
20
20
  </div>
21
21
  </template>
22
22
 
23
- <script>
24
- export default {
23
+ <script setup lang="ts">
24
+ defineOptions({
25
25
  name: 'UnnicSelectItem',
26
- props: {
27
- size: {
28
- type: String,
29
- default: '',
30
- },
31
- selectable: {
32
- type: Boolean,
33
- default: true,
34
- },
35
- active: {
36
- type: Boolean,
37
- default: false,
38
- },
39
- textFocused: {
40
- type: Boolean,
41
- default: false,
42
- },
43
- },
44
- };
26
+ });
27
+
28
+ export interface SelectItemProps {
29
+ size?: string;
30
+ selectable?: boolean;
31
+ active?: boolean;
32
+ textFocused?: boolean;
33
+ }
34
+
35
+ withDefaults(defineProps<SelectItemProps>(), {
36
+ size: '',
37
+ selectable: true,
38
+ active: false,
39
+ textFocused: false,
40
+ });
41
+
42
+ const emit = defineEmits<{
43
+ click: [];
44
+ }>();
45
45
  </script>
46
46
 
47
47
  <style lang="scss">
48
48
  @use '@/assets/scss/unnnic' as *;
49
49
  .unnnic-select-item {
50
50
  background-color: $unnnic-color-bg-base;
51
- padding: $unnnic-spacing-stack-nano $unnnic-inline-xs;
52
- margin: $unnnic-inline-xs;
51
+ padding: $unnnic-space-1 $unnnic-space-2;
52
+ margin: $unnnic-space-2;
53
53
 
54
54
  font-family: $unnnic-font-family-secondary;
55
55
  color: $unnnic-color-fg-base;
@@ -21,96 +21,95 @@
21
21
  </component>
22
22
  </template>
23
23
 
24
- <script>
25
- import { ref, inject } from 'vue';
26
- import { SkeletonStyle } from './skeletonTheme.vue';
24
+ <script setup lang="ts">
25
+ import {
26
+ computed,
27
+ inject,
28
+ ref,
29
+ useSlots,
30
+ type Ref,
31
+ type CSSProperties,
32
+ } from 'vue';
33
+ import { SkeletonStyle, type SkeletonStyleVars } from './skeletonTheme.vue';
27
34
 
28
- export default {
35
+ defineOptions({
29
36
  name: 'UnnnicSkeletonLoading',
30
- props: {
31
- prefix: {
32
- type: String,
33
- default: 'unnnic',
34
- },
35
- count: {
36
- type: Number,
37
- default: 1,
38
- },
39
- duration: {
40
- type: Number,
41
- default: 2,
42
- },
43
- tag: {
44
- type: String,
45
- default: 'span',
46
- },
47
- width: [String, Number],
48
- height: [String, Number],
49
- circle: {
50
- type: Boolean,
51
- default: false,
52
- },
53
- loading: {
54
- type: Boolean,
55
- default: undefined,
56
- },
57
- direct: {
58
- type: Boolean,
59
- },
60
- },
61
- setup() {
62
- const themeStyle = inject('_themeStyle', ref({ ...SkeletonStyle }));
63
- const theme = inject('_skeletonTheme', ref({}));
64
-
65
- return {
66
- themeStyle,
67
- theme,
68
- };
69
- },
70
- computed: {
71
- classes() {
72
- return [
73
- `${this.prefix}-skeleton`,
74
- this.circle ? `${this.prefix}-skeleton--circle` : '',
75
- ];
76
- },
77
- styles() {
78
- const styles = {};
79
-
80
- styles['--skeleton-bg'] = this.themeStyle['--skeleton-bg'];
81
- styles['--skeleton-highlight'] = this.themeStyle['--skeleton-highlight'];
82
- styles['--skeleton-duration'] = this.duration
83
- ? `${this.duration}s`
84
- : '0s';
85
-
86
- if (this.width) styles.width = this.width;
87
- if (this.height) styles.height = this.height;
88
-
89
- return styles;
90
- },
91
- elements() {
92
- return Array.from({ length: this.count }, () => ({}));
93
- },
94
- showLoading() {
95
- return typeof this.loading !== 'undefined'
96
- ? this.loading
97
- : this.isEmptyVNode(this.$slots.default);
98
- },
99
- },
100
- methods: {
101
- isEmptyVNode(children) {
102
- if (!children) return true;
103
- const [firstNode] = children();
104
- let str = firstNode.children;
105
-
106
- if (str) {
107
- // remove all line-break and space character
108
- str = str.replace(/(\n|\r\n|\s)/g, '');
109
- }
110
- return !str;
111
- },
112
- },
113
- };
37
+ });
38
+
39
+ export interface SkeletonLoadingProps {
40
+ prefix?: string;
41
+ count?: number;
42
+ duration?: number;
43
+ tag?: string;
44
+ width?: string | number;
45
+ height?: string | number;
46
+ circle?: boolean;
47
+ loading?: boolean;
48
+ direct?: boolean;
49
+ }
50
+
51
+ const props = withDefaults(defineProps<SkeletonLoadingProps>(), {
52
+ prefix: 'unnnic',
53
+ count: 1,
54
+ duration: 2,
55
+ tag: 'span',
56
+ width: undefined,
57
+ height: undefined,
58
+ circle: false,
59
+ loading: undefined,
60
+ direct: false,
61
+ });
62
+
63
+ const slots = useSlots();
64
+
65
+ const themeStyle = inject<Ref<SkeletonStyleVars>>(
66
+ '_themeStyle',
67
+ ref({ ...SkeletonStyle }),
68
+ );
69
+
70
+ const classes = computed(() => {
71
+ return [
72
+ `${props.prefix}-skeleton`,
73
+ props.circle ? `${props.prefix}-skeleton--circle` : '',
74
+ ];
75
+ });
76
+
77
+ const styles = computed((): CSSProperties => {
78
+ const nextStyles: Record<string, string | number> = {};
79
+
80
+ nextStyles['--skeleton-bg'] = themeStyle.value['--skeleton-bg'];
81
+ nextStyles['--skeleton-highlight'] = themeStyle.value['--skeleton-highlight'];
82
+ nextStyles['--skeleton-duration'] = props.duration
83
+ ? `${props.duration}s`
84
+ : '0s';
85
+
86
+ if (props.width) nextStyles.width = props.width;
87
+ if (props.height) nextStyles.height = props.height;
88
+
89
+ return nextStyles as CSSProperties;
90
+ });
91
+
92
+ const elements = computed(() => {
93
+ return Array.from({ length: props.count }, () => ({}));
94
+ });
95
+
96
+ function isEmptyVNode(children: (() => unknown[]) | undefined): boolean {
97
+ if (!children) return true;
98
+ const [firstNode] = children() as Array<{ children?: string } | undefined>;
99
+ let str = firstNode?.children;
100
+
101
+ if (str) {
102
+ // remove all line-break and space character
103
+ str = str.replace(/(\n|\r\n|\s)/g, '');
104
+ }
105
+ return !str;
106
+ }
107
+
108
+ const showLoading = computed(() => {
109
+ return typeof props.loading !== 'undefined'
110
+ ? props.loading
111
+ : isEmptyVNode(slots.default as (() => unknown[]) | undefined);
112
+ });
114
113
  </script>
115
114
 
116
115
  <style lang="scss">