@bethinkpl/design-system 41.0.2 → 41.1.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.
@@ -21,7 +21,11 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
21
21
  MEDIUM: string;
22
22
  LARGE: string;
23
23
  }>;
24
- }, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
24
+ }, {}, {
25
+ onError(event: Event): void;
26
+ }, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
27
+ error: (event: Event) => boolean;
28
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
25
29
  fit: {
26
30
  type: PropType<ImageFit>;
27
31
  default: string;
@@ -30,7 +34,9 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
30
34
  type: StringConstructor;
31
35
  required: true;
32
36
  };
33
- }>> & Readonly<{}>, {
37
+ }>> & Readonly<{
38
+ onError?: ((event: Event) => any) | undefined;
39
+ }>, {
34
40
  fit: string;
35
41
  }, {}, {
36
42
  DsSkeleton: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
@@ -10,6 +10,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
10
10
  type: BooleanConstructor;
11
11
  default: boolean;
12
12
  };
13
+ isLoading: {
14
+ type: BooleanConstructor;
15
+ default: boolean;
16
+ };
13
17
  isCentered: {
14
18
  type: BooleanConstructor;
15
19
  default: boolean;
@@ -342,6 +346,16 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
342
346
  readonly FAD_SQUARE: import('@fortawesome/fontawesome-common-types').IconDefinition;
343
347
  readonly FAD_SQUARE_CHECK: import('@fortawesome/fontawesome-common-types').IconDefinition;
344
348
  }>;
349
+ ICON_SIZES: Readonly<{
350
+ XXX_SMALL: string;
351
+ XX_SMALL: string;
352
+ X_SMALL: string;
353
+ SMALL: string;
354
+ MEDIUM: string;
355
+ LARGE: string;
356
+ X_LARGE: string;
357
+ XX_LARGE: string;
358
+ }>;
345
359
  FIRST_PAGE_NUMBER: number;
346
360
  }, {
347
361
  lastPage(): number;
@@ -364,6 +378,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
364
378
  type: BooleanConstructor;
365
379
  default: boolean;
366
380
  };
381
+ isLoading: {
382
+ type: BooleanConstructor;
383
+ default: boolean;
384
+ };
367
385
  isCentered: {
368
386
  type: BooleanConstructor;
369
387
  default: boolean;
@@ -380,6 +398,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
380
398
  }>> & Readonly<{
381
399
  "onChange-page"?: ((...args: any[]) => any) | undefined;
382
400
  }>, {
401
+ isLoading: boolean;
383
402
  currentPage: number;
384
403
  forceCompact: boolean;
385
404
  isCentered: boolean;
@@ -1187,5 +1206,80 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
1187
1206
  };
1188
1207
  });
1189
1208
  SelectList: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
1209
+ DsIcon: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
1210
+ icon: {
1211
+ type: ObjectConstructor;
1212
+ required: true;
1213
+ validator(icon: unknown): boolean;
1214
+ };
1215
+ size: {
1216
+ type: StringConstructor;
1217
+ default: string;
1218
+ validator: (value: string) => boolean;
1219
+ };
1220
+ rotation: {
1221
+ type: (NumberConstructor | null)[];
1222
+ default: null;
1223
+ };
1224
+ flippedVertical: {
1225
+ type: BooleanConstructor;
1226
+ default: boolean;
1227
+ };
1228
+ flippedHorizontal: {
1229
+ type: BooleanConstructor;
1230
+ default: boolean;
1231
+ };
1232
+ touchableDeprecated: {
1233
+ type: BooleanConstructor;
1234
+ default: boolean;
1235
+ };
1236
+ spinning: {
1237
+ type: BooleanConstructor;
1238
+ default: boolean;
1239
+ };
1240
+ }>, {}, {}, {
1241
+ sizeClassName(): string;
1242
+ isFontawesomeIcon(): boolean;
1243
+ }, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
1244
+ icon: {
1245
+ type: ObjectConstructor;
1246
+ required: true;
1247
+ validator(icon: unknown): boolean;
1248
+ };
1249
+ size: {
1250
+ type: StringConstructor;
1251
+ default: string;
1252
+ validator: (value: string) => boolean;
1253
+ };
1254
+ rotation: {
1255
+ type: (NumberConstructor | null)[];
1256
+ default: null;
1257
+ };
1258
+ flippedVertical: {
1259
+ type: BooleanConstructor;
1260
+ default: boolean;
1261
+ };
1262
+ flippedHorizontal: {
1263
+ type: BooleanConstructor;
1264
+ default: boolean;
1265
+ };
1266
+ touchableDeprecated: {
1267
+ type: BooleanConstructor;
1268
+ default: boolean;
1269
+ };
1270
+ spinning: {
1271
+ type: BooleanConstructor;
1272
+ default: boolean;
1273
+ };
1274
+ }>> & Readonly<{}>, {
1275
+ rotation: number | null;
1276
+ size: string;
1277
+ flippedVertical: boolean;
1278
+ flippedHorizontal: boolean;
1279
+ touchableDeprecated: boolean;
1280
+ spinning: boolean;
1281
+ }, {}, {
1282
+ FontAwesomeIcon: import('vue').DefineComponent<import('@fortawesome/vue-fontawesome').FontAwesomeIconProps>;
1283
+ }, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
1190
1284
  }, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
1191
1285
  export default _default;
@@ -3,6 +3,7 @@ import { Value } from '../../utils/type.utils';
3
3
  export declare const WELL_PADDINGS: {
4
4
  readonly SMALL: "small";
5
5
  readonly MEDIUM: "medium";
6
+ readonly LARGE: "large";
6
7
  };
7
8
  export type WellPadding = Value<typeof WELL_PADDINGS>;
8
9
  export declare const WELL_COLORS: {
@@ -9,7 +9,7 @@
9
9
  draggable="false"
10
10
  loading="lazy"
11
11
  :src="src"
12
- @error="isLoading = false"
12
+ @error="onError"
13
13
  @load="isLoading = false"
14
14
  />
15
15
  <div v-if="isLoading" class="ds-image__loader">
@@ -73,6 +73,9 @@ export default defineComponent({
73
73
  required: true,
74
74
  },
75
75
  },
76
+ emits: {
77
+ error: (event: Event) => event instanceof Event,
78
+ },
76
79
  data() {
77
80
  return {
78
81
  isLoading: true,
@@ -80,5 +83,11 @@ export default defineComponent({
80
83
  SKELETON_RADIUS_SIZES: Object.freeze(SKELETON_RADIUS_SIZES),
81
84
  };
82
85
  },
86
+ methods: {
87
+ onError(event: Event) {
88
+ this.isLoading = false;
89
+ this.$emit('error', event);
90
+ },
91
+ },
83
92
  });
84
93
  </script>
@@ -4,11 +4,16 @@ import { shallowMount } from '@vue/test-utils';
4
4
  import Pagination from './Pagination.vue';
5
5
 
6
6
  describe('Pagination', () => {
7
- const createComponent = ({ currentPage = 1, itemsTotalAmount = 30 } = {}) => {
7
+ const createComponent = ({
8
+ currentPage = 1,
9
+ itemsTotalAmount = 30,
10
+ isLoading = false,
11
+ } = {}) => {
8
12
  return shallowMount(Pagination, {
9
13
  props: {
10
14
  currentPage,
11
15
  itemsTotalAmount,
16
+ isLoading,
12
17
  } as any,
13
18
  global: {
14
19
  stubs: {
@@ -32,6 +37,18 @@ describe('Pagination', () => {
32
37
  expect(component.exists()).toBe(true);
33
38
  });
34
39
 
40
+ it('should not render the loading spinner by default', () => {
41
+ const component = createComponent({ itemsTotalAmount: 60 });
42
+
43
+ expect(component.find('.ds-pagination__loading').exists()).toBe(false);
44
+ });
45
+
46
+ it('should render the loading spinner when isLoading is true', () => {
47
+ const component = createComponent({ itemsTotalAmount: 60, isLoading: true });
48
+
49
+ expect(component.find('.ds-pagination__loading').exists()).toBe(true);
50
+ });
51
+
35
52
  test.each([
36
53
  {
37
54
  props: {
@@ -22,9 +22,9 @@ const StoryTemplate: StoryFn<typeof Pagination> = (args) => {
22
22
  },
23
23
  },
24
24
  template: `
25
- <Pagination v-bind=args @change-page="onChangePage">
26
- <template #accessory>
27
- <div v-if="args.accessory" v-html="args.accessory" />
25
+ <Pagination v-bind="args" @change-page="onChangePage">
26
+ <template v-if="args.accessory" #accessory>
27
+ <div v-html="args.accessory" />
28
28
  </template>
29
29
  </Pagination>`,
30
30
  };
@@ -35,6 +35,7 @@ export const Interactive = StoryTemplate.bind({});
35
35
  const argTypes = {
36
36
  currentPage: { control: { type: 'number', min: 1 } },
37
37
  forceCompact: { control: 'boolean' },
38
+ isLoading: { control: 'boolean' },
38
39
  isCentered: { control: 'boolean' },
39
40
  itemsPerPage: { control: { type: 'number', min: 1 } },
40
41
  itemsTotalAmount: { control: { type: 'number', min: 1 } },
@@ -45,6 +46,7 @@ Interactive.argTypes = argTypes;
45
46
  Interactive.args = {
46
47
  currentPage: 1,
47
48
  forceCompact: false,
49
+ isLoading: false,
48
50
  isCentered: false,
49
51
  itemsPerPage: 30,
50
52
  itemsTotalAmount: 600,
@@ -65,6 +65,10 @@
65
65
  </dropdown>
66
66
  </div>
67
67
  </template>
68
+
69
+ <div v-if="isLoading" class="ds-pagination__loading">
70
+ <ds-icon :icon="ICONS.FAD_SPINNER_THIRD" :size="ICON_SIZES.SMALL" spinning />
71
+ </div>
68
72
  </div>
69
73
 
70
74
  <div v-if="navigationItems.length > 1" class="ds-pagination__items -ds-compact">
@@ -109,10 +113,14 @@
109
113
  "
110
114
  @click="changePage(currentPage + 1)"
111
115
  />
116
+
117
+ <div v-if="isLoading" class="ds-pagination__loading">
118
+ <ds-icon :icon="ICONS.FAD_SPINNER_THIRD" :size="ICON_SIZES.SMALL" spinning />
119
+ </div>
112
120
  </div>
113
121
  </div>
114
122
 
115
- <div class="ds-pagination__accessorySlot">
123
+ <div v-if="$slots.accessory" class="ds-pagination__accessorySlot">
116
124
  <slot name="accessory" />
117
125
  </div>
118
126
  </div>
@@ -138,6 +146,8 @@ $pagination-input-height: 32px;
138
146
  align-items: stretch;
139
147
  flex-direction: row;
140
148
  flex-grow: 1;
149
+ // leaves room for the loading spinner so it doesn't overlap the accessory slot
150
+ gap: $space-20;
141
151
 
142
152
  &__itemsWrapper {
143
153
  align-content: center;
@@ -157,6 +167,7 @@ $pagination-input-height: 32px;
157
167
  align-items: center;
158
168
  flex-direction: row;
159
169
  padding: 0;
170
+ position: relative;
160
171
 
161
172
  &.-ds-default {
162
173
  display: none;
@@ -260,6 +271,17 @@ $pagination-input-height: 32px;
260
271
  min-height: 0;
261
272
  padding: 0;
262
273
  }
274
+
275
+ &__loading {
276
+ align-items: center;
277
+ color: $color-primary-icon;
278
+ display: flex;
279
+ left: 100%;
280
+ margin-left: $space-6;
281
+ position: absolute;
282
+ top: 50%;
283
+ transform: translateY(-50%);
284
+ }
263
285
  }
264
286
  </style>
265
287
 
@@ -267,7 +289,8 @@ $pagination-input-height: 32px;
267
289
  import { PAGINATION_DEFAULT_ITEMS_PER_PAGE } from './Pagination.consts';
268
290
  import IconButton from '../Buttons/IconButton/IconButton.vue';
269
291
  import { ICON_BUTTON_COLORS, ICON_BUTTON_SIZES, ICON_BUTTON_STATES } from '../Buttons/IconButton';
270
- import { ICONS } from '../Icons/Icon';
292
+ import DsIcon from '../Icons/Icon/Icon.vue';
293
+ import { ICON_SIZES, ICONS } from '../Icons/Icon';
271
294
 
272
295
  import { DROPDOWN_PLACEMENTS, DROPDOWN_RADIUSES } from '../Dropdown/Dropdown.consts';
273
296
  import Dropdown from '../Dropdown/Dropdown.vue';
@@ -283,7 +306,7 @@ const FIRST_PAGE_NUMBER = 1;
283
306
 
284
307
  export default defineComponent({
285
308
  name: 'Pagination',
286
- components: { IconButton, Dropdown, SelectListItem, SelectList },
309
+ components: { IconButton, Dropdown, SelectListItem, SelectList, DsIcon },
287
310
  props: {
288
311
  currentPage: {
289
312
  type: Number,
@@ -296,6 +319,10 @@ export default defineComponent({
296
319
  type: Boolean,
297
320
  default: false,
298
321
  },
322
+ isLoading: {
323
+ type: Boolean,
324
+ default: false,
325
+ },
299
326
  isCentered: {
300
327
  type: Boolean,
301
328
  default: false,
@@ -328,6 +355,7 @@ export default defineComponent({
328
355
  ICON_BUTTON_COLORS: Object.freeze(ICON_BUTTON_COLORS),
329
356
  ICON_BUTTON_STATES: Object.freeze(ICON_BUTTON_STATES),
330
357
  ICONS: Object.freeze(ICONS),
358
+ ICON_SIZES: Object.freeze(ICON_SIZES),
331
359
  FIRST_PAGE_NUMBER,
332
360
  };
333
361
  },
@@ -4,6 +4,7 @@ import { CONTAINER_RIBBON_COLORS, CONTAINER_RIBBON_SIZES } from '../ContainerRib
4
4
  export const WELL_PADDINGS = {
5
5
  SMALL: 'small',
6
6
  MEDIUM: 'medium',
7
+ LARGE: 'large',
7
8
  } as const;
8
9
 
9
10
  export type WellPadding = Value<typeof WELL_PADDINGS>;
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest';
2
2
  import { ComponentMountingOptions, mount } from '@vue/test-utils';
3
3
 
4
4
  import Well from './Well.vue';
5
- import { WELL_RIBBON_POSITIONS } from './Well.consts';
5
+ import { WELL_PADDINGS, WELL_RIBBON_POSITIONS } from './Well.consts';
6
6
 
7
7
  describe('Well', () => {
8
8
  const createComponent = (options: ComponentMountingOptions<typeof Well> = {}) => {
@@ -24,6 +24,14 @@ describe('Well', () => {
24
24
  expect(component.find('.ds-well__content').text()).toContain(content);
25
25
  });
26
26
 
27
+ it.each(Object.values(WELL_PADDINGS))('should set the padding class for %s', (padding) => {
28
+ const component = createComponent({
29
+ props: { padding },
30
+ });
31
+
32
+ expect(component.find('.ds-well').classes()).toContain(`-ds-${padding}`);
33
+ });
34
+
27
35
  it('should not set no-radius class by default', () => {
28
36
  const component = createComponent();
29
37
 
@@ -4,6 +4,7 @@
4
4
  :class="[
5
5
  colorClass,
6
6
  {
7
+ '-ds-large': WELL_PADDINGS.LARGE === padding,
7
8
  '-ds-medium': WELL_PADDINGS.MEDIUM === padding,
8
9
  '-ds-small': WELL_PADDINGS.SMALL === padding,
9
10
  '-ds-noRadius': !hasRadius,
@@ -144,6 +145,16 @@
144
145
  top: -10px;
145
146
  }
146
147
 
148
+ &.-ds-large {
149
+ #{$root}__content {
150
+ padding: $space-12;
151
+ }
152
+
153
+ #{$root}__accessorySlot {
154
+ right: $space-12;
155
+ }
156
+ }
157
+
147
158
  &.-ds-medium {
148
159
  #{$root}__content {
149
160
  padding: $space-8;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bethinkpl/design-system",
3
- "version": "41.0.2",
3
+ "version": "41.1.1",
4
4
  "description": "Bethink universe design-system",
5
5
  "repository": {
6
6
  "type": "git",