@pequity/squirrel 7.0.2 → 7.1.0

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 (29) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/chunks/p-btn.js +22 -26
  3. package/dist/cjs/chunks/p-dropdown-select.js +3 -1
  4. package/dist/cjs/chunks/p-select-btn.js +1 -1
  5. package/dist/cjs/p-chips.js +2 -3
  6. package/dist/cjs/p-icon.js +2 -1
  7. package/dist/cjs/p-input-search.js +77 -89
  8. package/dist/es/chunks/p-btn.js +23 -27
  9. package/dist/es/chunks/p-dropdown-select.js +3 -1
  10. package/dist/es/chunks/p-select-btn.js +1 -1
  11. package/dist/es/p-chips.js +2 -3
  12. package/dist/es/p-icon.js +2 -1
  13. package/dist/es/p-input-search.js +77 -89
  14. package/dist/squirrel/components/p-btn/p-btn.vue.d.ts +6 -6
  15. package/dist/squirrel/components/p-chips/p-chips.vue.d.ts +0 -2
  16. package/dist/squirrel/components/p-icon/p-icon.types.d.ts +1 -0
  17. package/dist/squirrel/components/p-input-search/p-input-search.vue.d.ts +11 -171
  18. package/dist/squirrel.css +10 -34
  19. package/package.json +23 -20
  20. package/squirrel/components/p-btn/p-btn.spec.js +33 -35
  21. package/squirrel/components/p-btn/p-btn.vue +24 -28
  22. package/squirrel/components/p-chips/p-chips.vue +0 -1
  23. package/squirrel/components/p-dropdown-select/p-dropdown-select.spec.js +10 -0
  24. package/squirrel/components/p-dropdown-select/p-dropdown-select.vue +1 -0
  25. package/squirrel/components/p-icon/p-icon.types.ts +1 -0
  26. package/squirrel/components/p-input-search/p-input-search.spec.js +3 -3
  27. package/squirrel/components/p-input-search/p-input-search.vue +50 -86
  28. package/squirrel/components/p-select-btn/p-select-btn.vue +1 -1
  29. package/squirrel/assets/magnifying-glass.svg +0 -10
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pequity/squirrel",
3
3
  "description": "Squirrel component library",
4
- "version": "7.0.2",
4
+ "version": "7.1.0",
5
5
  "packageManager": "pnpm@9.15.9",
6
6
  "type": "module",
7
7
  "scripts": {
@@ -39,7 +39,6 @@
39
39
  "peerDependencies": {
40
40
  "@tanstack/vue-virtual": "^3.8.3",
41
41
  "@vuepic/vue-datepicker": "^11.0.1",
42
- "dayjs": "^1.11.12",
43
42
  "floating-vue": "^5.2.2",
44
43
  "lodash-es": "^4.17.21",
45
44
  "vue": "^3.4.33",
@@ -50,23 +49,23 @@
50
49
  "devDependencies": {
51
50
  "@commitlint/cli": "^19.8.0",
52
51
  "@commitlint/config-conventional": "^19.8.0",
53
- "@pequity/eslint-config": "^1.1.1",
52
+ "@pequity/eslint-config": "^2.0.0",
54
53
  "@playwright/test": "^1.51.0",
55
54
  "@semantic-release/changelog": "^6.0.3",
56
55
  "@semantic-release/git": "^10.0.1",
57
- "@storybook/addon-a11y": "^8.6.4",
58
- "@storybook/addon-actions": "^8.6.4",
59
- "@storybook/addon-essentials": "^8.6.4",
60
- "@storybook/addon-interactions": "^8.6.4",
61
- "@storybook/addon-links": "^8.6.4",
62
- "@storybook/blocks": "^8.6.4",
63
- "@storybook/manager-api": "^8.6.4",
64
- "@storybook/test": "^8.6.4",
56
+ "@storybook/addon-a11y": "^8.6.6",
57
+ "@storybook/addon-actions": "^8.6.6",
58
+ "@storybook/addon-essentials": "^8.6.6",
59
+ "@storybook/addon-interactions": "^8.6.6",
60
+ "@storybook/addon-links": "^8.6.6",
61
+ "@storybook/blocks": "^8.6.6",
62
+ "@storybook/manager-api": "^8.6.6",
63
+ "@storybook/test": "^8.6.6",
65
64
  "@storybook/test-runner": "^0.22.0",
66
- "@storybook/theming": "^8.6.4",
67
- "@storybook/vue3": "^8.6.4",
68
- "@storybook/vue3-vite": "^8.6.4",
69
- "@tanstack/vue-virtual": "3.13.2",
65
+ "@storybook/theming": "^8.6.6",
66
+ "@storybook/vue3": "^8.6.6",
67
+ "@storybook/vue3-vite": "^8.6.6",
68
+ "@tanstack/vue-virtual": "3.13.4",
70
69
  "@types/jsdom": "^21.1.7",
71
70
  "@types/lodash-es": "^4.17.12",
72
71
  "@types/node": "^22.13.10",
@@ -76,7 +75,6 @@
76
75
  "@vue/test-utils": "^2.4.6",
77
76
  "@vuepic/vue-datepicker": "11.0.1",
78
77
  "autoprefixer": "^10.4.21",
79
- "dayjs": "1.11.13",
80
78
  "eslint": "^9.22.0",
81
79
  "eslint-plugin-storybook": "^0.11.4",
82
80
  "floating-vue": "5.2.2",
@@ -84,7 +82,7 @@
84
82
  "husky": "^9.1.7",
85
83
  "iconify-icon": "^2.3.0",
86
84
  "jsdom": "^26.0.0",
87
- "lint-staged": "^15.4.3",
85
+ "lint-staged": "^15.5.0",
88
86
  "lodash-es": "4.17.21",
89
87
  "make-coverage-badge": "^1.2.0",
90
88
  "postcss": "^8.5.3",
@@ -94,11 +92,11 @@
94
92
  "rimraf": "^6.0.1",
95
93
  "sass": "^1.85.1",
96
94
  "semantic-release": "^24.2.3",
97
- "storybook": "^8.6.4",
95
+ "storybook": "^8.6.6",
98
96
  "svgo": "^3.3.2",
99
97
  "tailwindcss": "^3.4.17",
100
- "typescript": "5.7.3",
101
- "vite": "^6.2.1",
98
+ "typescript": "5.8.2",
99
+ "vite": "^6.2.2",
102
100
  "vitest": "^3.0.8",
103
101
  "vue": "3.5.13",
104
102
  "vue-currency-input": "3.2.1",
@@ -108,5 +106,10 @@
108
106
  },
109
107
  "dependencies": {
110
108
  "tailwind-variants": "^1.0.0"
109
+ },
110
+ "pnpm": {
111
+ "overrides": {
112
+ "typescript": "5.8.2"
113
+ }
111
114
  }
112
115
  }
@@ -2,6 +2,7 @@ import PBtn from '@squirrel/components/p-btn/p-btn.vue';
2
2
  import { sanitizeUrl } from '@squirrel/utils/sanitization';
3
3
  import { createWrapperFor } from '@tests/vitest.helpers';
4
4
  import { describe } from 'vitest';
5
+ import { ref } from 'vue';
5
6
 
6
7
  vi.mock('@squirrel/utils/sanitization', () => {
7
8
  return {
@@ -109,43 +110,40 @@ describe('PBtn.vue', () => {
109
110
  expect(button.text()).toContain(`This is a button`);
110
111
  });
111
112
 
112
- it.each([
113
- ['button', undefined],
114
- ['a', 'https://pequity.com/'],
115
- ['a', { name: 'home', params: { id: 1 } }],
116
- ])('gets disabled when the element is a %s and points to %s', async (el, to) => {
117
- const wrapper = createWrapperFor(PBtn, {
118
- props: {
119
- to,
120
- },
121
- attrs: {
122
- disabled: true,
123
- },
124
- global: {
125
- stubs: { RouterLink: { template: '<a class="router-link-stub"><slot /></a>' } },
126
- },
127
- });
128
-
129
- const button = await wrapper.find(el);
130
-
131
- await button.trigger('click');
113
+ it.each(['https://pequity.com/', { name: 'home', params: { id: 1 } }])(
114
+ 'gets disabled when the link points to %s',
115
+ async (to) => {
116
+ const wrapper = createWrapperFor(
117
+ {
118
+ template: `
119
+ <PBtn :disabled="disabled" :to="to" >Button</PBtn>
120
+ <button class="set-disabled" @click="disabled = true" :to="to">Set disabled</button>
121
+ `,
122
+ components: { PBtn },
123
+ setup() {
124
+ const disabled = ref(null);
125
+
126
+ return { disabled, to };
127
+ },
128
+ },
129
+ {
130
+ global: {
131
+ stubs: { RouterLink: { template: '<a class="router-link-stub"><slot /></a>' } },
132
+ },
133
+ }
134
+ );
132
135
 
133
- if (el === 'button') {
134
- expect(wrapper.emitted().click).toBeFalsy();
135
- }
136
- expect(button.attributes()).toHaveProperty('disabled');
137
- expect(button.attributes()['aria-disabled']).toBe('true');
136
+ const pBtn = await wrapper.findComponent({ name: 'PBtn' });
138
137
 
139
- await wrapper.setProps({ disabled: false });
138
+ expect(pBtn.attributes()).not.toHaveProperty('disabled');
139
+ expect(pBtn.attributes()['aria-disabled']).toBe('false');
140
140
 
141
- await button.trigger('click');
141
+ await wrapper.find('.set-disabled').trigger('click');
142
142
 
143
- if (el === 'button') {
144
- expect(wrapper.emitted().click[0][0] instanceof MouseEvent).toBe(true);
143
+ expect(pBtn.attributes().disabled).toBe('true');
144
+ expect(pBtn.attributes()['aria-disabled']).toBe('true');
145
145
  }
146
- expect(button.attributes()).not.toHaveProperty('disabled');
147
- expect(button.attributes()['aria-disabled']).toBe('false');
148
- });
146
+ );
149
147
 
150
148
  it('has a loading state', async () => {
151
149
  const wrapper = createWrapperFor(PBtn, {
@@ -257,7 +255,7 @@ describe('PBtn.vue', () => {
257
255
 
258
256
  describe('icon button', () => {
259
257
  it.each([
260
- ['sm', ['shrink-0', 'text-[20px]']],
258
+ ['sm', ['shrink-0', 'text-base', 'p-0.5']],
261
259
  ['md', ['shrink-0', 'text-xl']],
262
260
  ['lg', ['shrink-0', 'text-2xl']],
263
261
  ])('renders a button with icon of size %s', async (size, classes) => {
@@ -273,7 +271,7 @@ describe('PBtn.vue', () => {
273
271
  });
274
272
 
275
273
  it.each([
276
- ['sm', ['shrink-0', 'text-[20px]']],
274
+ ['sm', ['shrink-0', 'text-base', 'p-0.5']],
277
275
  ['md', ['shrink-0', 'text-xl']],
278
276
  ['lg', ['shrink-0', 'text-2xl']],
279
277
  ])('renders a button with a right icon of size %s', async (size, classes) => {
@@ -289,7 +287,7 @@ describe('PBtn.vue', () => {
289
287
  });
290
288
 
291
289
  it.each([
292
- ['sm', ['shrink-0', 'text-[20px]'], ['has-[.slot-wrapper:empty]:px-1.5']],
290
+ ['sm', ['shrink-0', 'text-base', 'p-0.5'], ['has-[.slot-wrapper:empty]:px-1.5']],
293
291
  ['md', ['shrink-0', 'text-xl'], ['has-[.slot-wrapper:empty]:px-2.5']],
294
292
  ['lg', ['shrink-0', 'text-2xl'], ['has-[.slot-wrapper:empty]:px-3']],
295
293
  ])('renders a button with an icon without text of size %s', async (size, classes, buttonClasses) => {
@@ -1,26 +1,5 @@
1
1
  <template>
2
- <a
3
- v-if="typeof to === 'string' && isExternalLink(to)"
4
- v-bind="$attrs"
5
- :href="sanitizeUrl(to)"
6
- target="_blank"
7
- :class="classes.button"
8
- :disabled="!!$attrs.disabled ? true : null"
9
- :aria-disabled="!!$attrs.disabled"
10
- >
11
- <slot></slot>
12
- </a>
13
- <Component
14
- :is="to ? 'RouterLink' : 'button'"
15
- v-else
16
- :type="to ? null : nativeType"
17
- :to="to ? to : null"
18
- :aria-selected="selected"
19
- :class="classes.button"
20
- v-bind="$attrs"
21
- :disabled="!!$attrs.disabled || loading ? true : null"
22
- :aria-disabled="$attrs.disabled"
23
- >
2
+ <Component :is="isExternal ? 'a' : to ? 'RouterLink' : 'button'" v-bind="btnAttrs" :class="classes.button">
24
3
  <div :class="[{ invisible: loading }, classes.content]">
25
4
  <PIcon v-if="icon" :icon="icon" :class="classes.icon" />
26
5
  <span class="slot-wrapper empty:hidden">
@@ -28,7 +7,7 @@
28
7
  </span>
29
8
  <PIcon v-if="iconRight" :icon="iconRight" :class="classes.icon" />
30
9
  </div>
31
- <PRingLoader v-if="loading" :size="loaderSize" :class="classes.loader" />
10
+ <PRingLoader v-if="loading" :size="LOADER_SIZES[props.size]" :class="classes.loader" />
32
11
  </Component>
33
12
  </template>
34
13
 
@@ -39,7 +18,7 @@ import PRingLoader from '@squirrel/components/p-ring-loader/p-ring-loader.vue';
39
18
  import { isExternalLink } from '@squirrel/utils/link';
40
19
  import { sanitizeUrl } from '@squirrel/utils/sanitization';
41
20
  import { tv, type VariantProps } from 'tailwind-variants';
42
- import { computed, type PropType } from 'vue';
21
+ import { computed, type PropType, useAttrs } from 'vue';
43
22
  import { type RouteLocationRaw } from 'vue-router';
44
23
 
45
24
  type Icon = InstanceType<typeof PIcon>['$props']['icon'];
@@ -86,7 +65,7 @@ const btnClasses = {
86
65
  sm: {
87
66
  button: 'px-3 has-[.slot-wrapper:empty]:px-1.5 py-1.5 text-sm leading-5',
88
67
  content: 'gap-1',
89
- icon: 'text-[20px]',
68
+ icon: 'text-base p-0.5',
90
69
  },
91
70
  md: {
92
71
  button: 'px-6 has-[.slot-wrapper:empty]:px-2.5 has-[.slot-wrapper:empty]:py-2.5 py-2 text-base',
@@ -119,9 +98,10 @@ type ButtonType = NonNullable<VariantProps<typeof btn>['type']>;
119
98
  <script setup lang="ts">
120
99
  defineOptions({
121
100
  name: 'PBtn',
122
- inheritAttrs: false,
123
101
  });
124
102
 
103
+ const attrs = useAttrs();
104
+
125
105
  const props = defineProps({
126
106
  /**
127
107
  * The button style e.g primary, secondary, primary-outline, secondary-outline, error, success, primary-link
@@ -197,7 +177,23 @@ const classes = computed(() => {
197
177
  return { button: button(), content: content(), loader: loader(), icon: icon() };
198
178
  });
199
179
 
200
- const loaderSize = computed(() => {
201
- return Number(`${LOADER_SIZES[props.size]}`);
180
+ const isExternal = computed(() => isExternalLink(String(props.to)));
181
+
182
+ const btnAttrs = computed(() => {
183
+ const res: Record<string, unknown> = {
184
+ target: isExternal.value ? '_blank' : null,
185
+ to: !isExternal.value && props.to ? props.to : null,
186
+ type: props.to ? null : props.nativeType,
187
+ disabled: attrs.disabled || props.loading ? '' : null,
188
+ 'aria-selected': !isExternal.value ? props.selected : false,
189
+ 'aria-disabled': attrs.disabled || props.loading,
190
+ };
191
+
192
+ // We need to add the href attribute conditionally so that it doesn't override the RouterLink's href
193
+ if (isExternal.value) {
194
+ res.href = sanitizeUrl(String(props.to));
195
+ }
196
+
197
+ return res;
202
198
  });
203
199
  </script>
@@ -37,7 +37,6 @@ export default defineComponent({
37
37
  items: {
38
38
  type: Array,
39
39
  default: () => [],
40
- required: true,
41
40
  },
42
41
  itemText: {
43
42
  type: String,
@@ -764,6 +764,16 @@ describe('PDropdownSelect.vue', () => {
764
764
  cleanup(wrapper);
765
765
  });
766
766
 
767
+ it('shows "Type to add" message when creatable is true and no search term', async () => {
768
+ useVirtualizer.mockImplementation(() => createMockedVirtualizer(0));
769
+ const wrapper = createWrapper({ selected: null, items: [] }, { searchable: true, creatable: true });
770
+ await wrapper.find('button').trigger('click');
771
+ await sleep(200);
772
+ const noItemsMessage = wrapper.find('div.flex.items-center.justify-center.h-10.text-base');
773
+ expect(noItemsMessage.text()).toBe('No items found. Type to add');
774
+ cleanup(wrapper);
775
+ });
776
+
767
777
  it('does not show create option when creatable is false', async () => {
768
778
  useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
769
779
  const wrapper = createWrapper({ selected: null }, { searchable: true, creatable: false });
@@ -160,6 +160,7 @@
160
160
  Add '{{ search }}'
161
161
  </button>
162
162
  </template>
163
+ <template v-else-if="creatable">No items found. Type to add</template>
163
164
  <template v-else>No items found</template>
164
165
  </div>
165
166
  </slot>
@@ -33,6 +33,7 @@ export const P_ICON_ALIASES = {
33
33
  download: 'tdesign:download',
34
34
  upload: 'tdesign:upload',
35
35
  info: 'streamline:information-circle',
36
+ search: 'streamline:magnifying-glass-solid',
36
37
  } as const;
37
38
 
38
39
  export type PIconAlias = keyof typeof P_ICON_ALIASES;
@@ -8,12 +8,12 @@ describe('PInputSearch.vue', () => {
8
8
  const input = await wrapper.find('input');
9
9
  const button = wrapper.find('button.cursor-pointer');
10
10
  const icons = wrapper.findAll('i');
11
- const searchIcon = wrapper.find('i.search');
11
+ const searchIcon = wrapper.findComponent({ name: 'PIcon' });
12
12
  const enterIcon = wrapper.find('i.enter');
13
13
 
14
14
  expect(input.exists()).toBe(true);
15
15
  expect(button.exists()).toBe(false);
16
- expect(icons.length).toBe(1);
16
+ expect(icons.length).toBe(0);
17
17
  expect(searchIcon.exists()).toBe(true);
18
18
  expect(enterIcon.exists()).toBe(false);
19
19
  });
@@ -78,7 +78,7 @@ describe('PInputSearch.vue', () => {
78
78
  const icons = await wrapper.findAll('i');
79
79
  const enterIcon = wrapper.find('i.enter.v-popper--has-tooltip');
80
80
 
81
- expect(icons.length).toBe(2);
81
+ expect(icons.length).toBe(1);
82
82
  expect(enterIcon.exists()).toBe(true);
83
83
  });
84
84
  });
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <PInput
3
3
  ref="searchInput"
4
- v-model="query"
4
+ v-model="model"
5
5
  :size="size"
6
6
  v-bind="$attrs"
7
7
  role="searchbox"
@@ -11,95 +11,83 @@
11
11
  @keydown.enter="keydownEnter"
12
12
  >
13
13
  <template #prefix>
14
- <i class="icon absolute bg-no-repeat outline-none" :class="searchIconClasses"></i>
14
+ <PIcon icon="search" class="absolute text-p-gray-40" :class="searchIconClasses[size]" />
15
15
  </template>
16
16
  <template #suffix>
17
17
  <i
18
- v-if="query && showEnterIcon && showEnterIconOnFocus"
18
+ v-if="model && showEnterIcon && showEnterIconOnFocus"
19
19
  v-tooltip.bottom="{ content: 'Press enter to search', delay: { show: 100, hide: 0 } }"
20
20
  class="icon absolute bg-no-repeat outline-none"
21
21
  :class="enterIconClasses"
22
22
  ></i>
23
23
  <button
24
- v-if="query"
24
+ v-if="model"
25
25
  role="button"
26
26
  aria-label="Clear search input"
27
27
  class="icon absolute cursor-pointer bg-no-repeat"
28
28
  :class="clearIconClasses"
29
29
  @click="clearSearch"
30
- />
30
+ ></button>
31
31
  </template>
32
32
  </PInput>
33
33
  </template>
34
34
 
35
- <script lang="ts">
35
+ <script setup lang="ts">
36
36
  import { type Size, SIZES } from '@squirrel/components/p-btn/p-btn.types';
37
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
37
38
  import PInput from '@squirrel/components/p-input/p-input.vue';
38
- import { defineComponent, type PropType } from 'vue';
39
+ import { computed, type PropType, ref, useTemplateRef } from 'vue';
39
40
 
40
41
  type PInputInstance = InstanceType<typeof PInput>;
41
42
 
42
- export default defineComponent({
43
+ const searchIconClasses = {
44
+ sm: 'text-xs top-2.5 left-2',
45
+ md: 'text-base top-3 left-3',
46
+ lg: 'text-lg top-4 left-5',
47
+ } as const;
48
+
49
+ defineOptions({
43
50
  name: 'PInputSearch',
44
- components: {
45
- PInput,
46
- },
47
51
  inheritAttrs: false,
48
- props: {
49
- modelValue: {
50
- type: String,
51
- default: '',
52
- },
53
- size: {
54
- type: String as PropType<Size>,
55
- default: 'md',
56
- validator(value: Size) {
57
- return SIZES.includes(value);
58
- },
59
- },
60
- showEnterIcon: {
61
- type: Boolean,
62
- default: false,
63
- },
64
- },
65
- emits: ['update:modelValue', 'enter'],
66
- data() {
67
- return {
68
- query: this.modelValue,
69
- showEnterIconOnFocus: false,
70
- };
71
- },
72
- computed: {
73
- searchIconClasses() {
74
- return `search search-${this.size}`;
75
- },
76
- enterIconClasses() {
77
- return `enter enter-${this.size}`;
78
- },
79
- clearIconClasses() {
80
- return `clear clear-${this.size}`;
81
- },
82
- },
83
- watch: {
84
- modelValue(value) {
85
- this.query = value;
86
- },
87
- query(value) {
88
- this.$emit('update:modelValue', value);
52
+ });
53
+
54
+ const model = defineModel<string>({ default: '' });
55
+ const showEnterIconOnFocus = ref(false);
56
+ const searchInput = useTemplateRef<PInputInstance>('searchInput');
57
+
58
+ const emit = defineEmits<{
59
+ enter: [value: string];
60
+ }>();
61
+
62
+ const props = defineProps({
63
+ size: {
64
+ type: String as PropType<Size>,
65
+ default: 'md',
66
+ validator(value: Size) {
67
+ return SIZES.includes(value);
89
68
  },
90
69
  },
91
- methods: {
92
- clearSearch() {
93
- this.query = '';
94
- requestAnimationFrame(() => {
95
- (this.$refs.searchInput as PInputInstance)?.$el.querySelector('input').focus();
96
- });
97
- },
98
- keydownEnter() {
99
- this.$emit('enter', this.query);
100
- },
70
+ showEnterIcon: {
71
+ type: Boolean,
72
+ default: false,
101
73
  },
102
74
  });
75
+
76
+ const enterIconClasses = computed(() => `enter enter-${props.size}`);
77
+
78
+ const clearIconClasses = computed(() => `clear clear-${props.size}`);
79
+
80
+ const clearSearch = () => {
81
+ model.value = '';
82
+
83
+ requestAnimationFrame(() => {
84
+ searchInput.value?.$el.querySelector('input').focus();
85
+ });
86
+ };
87
+
88
+ const keydownEnter = () => {
89
+ emit('enter', model.value);
90
+ };
103
91
  </script>
104
92
 
105
93
  <style scoped lang="scss">
@@ -132,30 +120,6 @@ export default defineComponent({
132
120
  .icon.clear:hover {
133
121
  background-image: url('@squirrel/assets/clear-input-hovered.svg');
134
122
  }
135
- .icon.search {
136
- background-image: url('@squirrel/assets/magnifying-glass.svg');
137
- }
138
- .icon.search-sm {
139
- background-size: 0.75rem 0.75rem;
140
- left: 0.5rem;
141
- bottom: 0.625rem;
142
- width: 0.75rem;
143
- height: 0.75rem;
144
- }
145
- .icon.search-md {
146
- background-size: 1rem 1rem;
147
- width: 1rem;
148
- height: 1rem;
149
- left: 0.75rem;
150
- bottom: 0.75rem;
151
- }
152
- .icon.search-lg {
153
- background-size: 1rem 1rem;
154
- width: 1rem;
155
- height: 1rem;
156
- left: 1.125rem;
157
- bottom: 1rem;
158
- }
159
123
  .icon.enter {
160
124
  background-image: url('@squirrel/assets/keyboard-press-enter.svg');
161
125
  }
@@ -10,7 +10,7 @@
10
10
  :size="size"
11
11
  type="secondary-outline-blue"
12
12
  :disabled="item.disabled"
13
- :icon="String(item.icon)"
13
+ :icon="item.icon ? String(item.icon) : ''"
14
14
  :class="{
15
15
  'rounded-none': index !== 0 && index !== items.length - 1 && items.length > 1,
16
16
  'rounded-br-none rounded-tr-none': index === 0 && items.length > 1,
@@ -1,10 +0,0 @@
1
- <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g clip-path="url(#clip0_9127_330342)">
3
- <path d="M11.705 10.295L9.38501 8.00004C10.0193 7.0497 10.3178 5.91467 10.2331 4.77526C10.1484 3.63584 9.68546 2.5574 8.91771 1.71124C8.14996 0.86508 7.12147 0.299735 5.99563 0.105014C4.8698 -0.0897079 3.71117 0.0973621 2.70383 0.636506C1.69648 1.17565 0.898177 2.03595 0.435738 3.08073C-0.0267015 4.12552 -0.126757 5.29487 0.151467 6.40303C0.429691 7.51119 1.07024 8.4946 1.97135 9.19704C2.87246 9.89948 3.98246 10.2807 5.12501 10.28C6.13901 10.2811 7.13002 9.97801 7.97001 9.41004L10.295 11.735C10.4824 11.9213 10.7358 12.0258 11 12.0258C11.2642 12.0258 11.5176 11.9213 11.705 11.735C11.8018 11.6418 11.8788 11.5299 11.9314 11.4062C11.9839 11.2825 12.011 11.1495 12.011 11.015C12.011 10.8806 11.9839 10.7476 11.9314 10.6239C11.8788 10.5002 11.8018 10.3883 11.705 10.295ZM5.12501 1.50004C5.84176 1.50004 6.54241 1.71251 7.13843 2.11061C7.73445 2.50871 8.19908 3.07456 8.47359 3.73666C8.74811 4.39875 8.82019 5.12736 8.68072 5.8304C8.54125 6.53345 8.1965 7.17937 7.69004 7.68653C7.18357 8.19369 6.53813 8.53934 5.83527 8.67977C5.13242 8.82021 4.40371 8.74913 3.74125 8.47553C3.07878 8.20193 2.51228 7.73808 2.11336 7.14261C1.71444 6.54714 1.501 5.84678 1.50001 5.13004C1.50001 4.16817 1.88177 3.24562 2.56145 2.565C3.24112 1.88439 4.16314 1.50136 5.12501 1.50004Z" fill="#718096"/>
4
- </g>
5
- <defs>
6
- <clipPath id="clip0_9127_330342">
7
- <rect width="12" height="12" fill="white"/>
8
- </clipPath>
9
- </defs>
10
- </svg>