@pequity/squirrel 5.0.2 → 5.2.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.
@@ -0,0 +1,9 @@
1
+ const P_ICON_ALIASES = {
2
+ delete: "octicon:trash-24",
3
+ edit: "simple-line-icons:pencil",
4
+ send: "fa:paper-plane",
5
+ settings: "heroicons:cog-8-tooth-20-solid"
6
+ };
7
+ export {
8
+ P_ICON_ALIASES
9
+ };
@@ -12,6 +12,7 @@ import PDropdown from './p-dropdown/p-dropdown.vue';
12
12
  import PDropdownSelect from './p-dropdown-select/p-dropdown-select.vue';
13
13
  import PFileUpload from './p-file-upload/p-file-upload.vue';
14
14
  import PFilterIcon from './p-table-header-cell/p-table-filter-icon.vue';
15
+ import PIcon from './p-icon/p-icon.vue';
15
16
  import PInfoIcon from './p-info-icon/p-info-icon.vue';
16
17
  import PInlineDatePicker from './p-inline-date-picker/p-inline-date-picker.vue';
17
18
  import PInput from './p-input/p-input.vue';
@@ -41,6 +42,7 @@ import PToggle from './p-toggle/p-toggle.vue';
41
42
  import { type FileUploadFile } from './p-file-upload/p-file-upload.types';
42
43
  import { type HeaderCellAttrs, MIN_WIDTH_COL_RESIZE, type TableCol, type ThAttrs, colsInjectionKey, isColsResizableInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey } from './p-table/p-table.types';
43
44
  import { type PActionBarAction } from './p-action-bar/p-action-bar.types';
45
+ import { type PIconAlias, P_ICON_ALIASES } from './p-icon/p-icon.types';
44
46
  import { SORTING_TYPES, type SortingType, type SortingTypeWithoutNoSorting } from './p-table-sort/p-table-sort.config';
45
47
  import { type Size } from './p-btn/p-btn.types';
46
48
  import { usePLoading } from './p-loading/usePLoading';
@@ -48,4 +50,4 @@ import { usePModal } from './p-modal/usePModal';
48
50
  import { usePTableColResize } from './p-table/usePTableColResize';
49
51
  import { usePTableRowVirtualizer } from './p-table/usePTableRowVirtualizer';
50
52
  import { useSelectList } from './p-select-list/useSelectList';
51
- export { PActionBar, PActionBarAction, PAlert, PAvatar, PBtn, PCard, PCheckbox, PChips, PCloseBtn, PDatePicker, PDrawer, PDropdown, PDropdownSelect, PFileUpload, PFilterIcon, PInfoIcon, PInlineDatePicker, PInput, PInputNumber, PInputPercent, PInputSearch, PLink, PLoading, PModal, PPagination, PPaginationInfo, PProgressBar, PRingLoader, PSelect, PSelectBtn, PSelectList, PSelectPill, PSkeletonLoader, PTable, PTableHeaderCell, PTableLoader, PTableSort, PTableTd, PTabs, PTextarea, PToggle, SORTING_TYPES, MIN_WIDTH_COL_RESIZE, colsInjectionKey, isColsResizableInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey, usePModal, usePTableColResize, usePTableRowVirtualizer, useSelectList, usePLoading, SortingType, SortingTypeWithoutNoSorting, Size, FileUploadFile, HeaderCellAttrs, TableCol, ThAttrs, };
53
+ export { PActionBar, PActionBarAction, PAlert, PAvatar, PBtn, PCard, PCheckbox, PChips, PCloseBtn, PDatePicker, PDrawer, PDropdown, PDropdownSelect, PFileUpload, PFilterIcon, PIcon, PInfoIcon, PInlineDatePicker, PInput, PInputNumber, PInputPercent, PInputSearch, PLink, PLoading, PModal, PPagination, PPaginationInfo, PProgressBar, PRingLoader, PSelect, PSelectBtn, PSelectList, PSelectPill, PSkeletonLoader, PTable, PTableHeaderCell, PTableLoader, PTableSort, PTableTd, PTabs, PTextarea, PToggle, SORTING_TYPES, MIN_WIDTH_COL_RESIZE, P_ICON_ALIASES, colsInjectionKey, isColsResizableInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey, usePModal, usePTableColResize, usePTableRowVirtualizer, useSelectList, usePLoading, SortingType, SortingTypeWithoutNoSorting, Size, FileUploadFile, HeaderCellAttrs, TableCol, ThAttrs, PIconAlias, };
@@ -0,0 +1,7 @@
1
+ export declare const P_ICON_ALIASES: {
2
+ readonly delete: "octicon:trash-24";
3
+ readonly edit: "simple-line-icons:pencil";
4
+ readonly send: "fa:paper-plane";
5
+ readonly settings: "heroicons:cog-8-tooth-20-solid";
6
+ };
7
+ export type PIconAlias = keyof typeof P_ICON_ALIASES;
@@ -0,0 +1,17 @@
1
+ import { type IconifyIconAttributes } from 'iconify-icon';
2
+ import { type PIconAlias } from './p-icon.types';
3
+ import 'iconify-icon';
4
+ interface Props extends /* @vue-ignore */ Omit<IconifyIconAttributes, 'icon'> {
5
+ icon: IconifyIconAttributes['icon'] | PIconAlias;
6
+ }
7
+ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToOption<Props>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToOption<Props>>>, {}, {}>;
8
+ export default _default;
9
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
10
+ type __VLS_TypePropsToOption<T> = {
11
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
12
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
13
+ } : {
14
+ type: import('vue').PropType<T[K]>;
15
+ required: true;
16
+ };
17
+ };
@@ -19,6 +19,7 @@ declare function __VLS_template(): {
19
19
  };
20
20
  refs: {
21
21
  scrollWrapper: HTMLDivElement;
22
+ tbodyElement: HTMLTableSectionElement;
22
23
  };
23
24
  attrs: Partial<{}>;
24
25
  };
@@ -33,7 +34,9 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<
33
34
  paddingTop: number;
34
35
  paddingBottom: number;
35
36
  };
36
- }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
37
+ }>, {
38
+ tbodyElement: import("vue").Ref<HTMLElement | null>;
39
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
37
40
  scroll: (val: Event) => void;
38
41
  "click-filter-icon": (val: Event, col: any) => void;
39
42
  "col-resize": (colIndex: number, width: number) => void;
package/dist/style.css CHANGED
@@ -2098,29 +2098,29 @@ to {
2098
2098
  .bg-file-upload-x-icon[data-v-d07a8f64]:hover {
2099
2099
  background-image: url("data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M0%208C0%209.58225%200.469192%2011.129%201.34824%2012.4446C2.22729%2013.7602%203.47672%2014.7855%204.93853%2015.391C6.40034%2015.9965%208.00887%2016.155%209.56072%2015.8463C11.1126%2015.5376%2012.538%2014.7757%2013.6569%2013.6569C14.7757%2012.538%2015.5376%2011.1126%2015.8463%209.56072C16.155%208.00887%2015.9965%206.40034%2015.391%204.93853C14.7855%203.47672%2013.7602%202.22729%2012.4446%201.34824C11.129%200.469192%209.58225%200%208%200C5.87827%200%203.84344%200.842855%202.34315%202.34315C0.842855%203.84344%200%205.87827%200%208ZM14.3333%208C14.3333%209.25262%2013.9619%2010.4771%2013.266%2011.5186C12.5701%2012.5601%2011.5809%2013.3719%2010.4237%2013.8512C9.2664%2014.3306%207.99298%2014.456%206.76443%2014.2116C5.53588%2013.9673%204.40739%2013.3641%203.52166%2012.4783C2.63592%2011.5926%202.03273%2010.4641%201.78836%209.23557C1.54399%208.00703%201.66941%206.7336%202.14876%205.57634C2.62812%204.41907%203.43988%203.42994%204.48139%202.73403C5.5229%202.03811%206.74739%201.66667%208%201.66667C9.67916%201.66843%2011.289%202.33626%2012.4764%203.52361C13.6637%204.71096%2014.3316%206.32084%2014.3333%208Z'%20fill='%23BB1410'%20/%3e%3cpath%20d='M5.88634%204.71322C5.73075%204.55763%205.51972%204.47021%205.29967%204.47021C5.07963%204.47021%204.8686%204.55763%204.71301%204.71322C4.55741%204.86881%204.47%205.07984%204.47%205.29989C4.47%205.51993%204.55741%205.73096%204.71301%205.88655L6.71301%207.88655C6.72914%207.9021%206.74197%207.92074%206.75073%207.94136C6.7595%207.96198%206.76401%207.98415%206.76401%208.00655C6.76401%208.02896%206.7595%208.05113%206.75073%208.07175C6.74197%208.09237%206.72914%208.11101%206.71301%208.12655L4.71301%2010.1266C4.63561%2010.2034%204.57417%2010.2948%204.53225%2010.3955C4.49033%2010.4962%204.46875%2010.6042%204.46875%2010.7132C4.46875%2010.8223%204.49033%2010.9303%204.53225%2011.031C4.57417%2011.1317%204.63561%2011.223%204.71301%2011.2999C4.78939%2011.3781%204.88063%2011.4403%204.98138%2011.4827C5.08213%2011.5251%205.19035%2011.547%205.29967%2011.547C5.409%2011.547%205.51721%2011.5251%205.61796%2011.4827C5.71871%2011.4403%205.80996%2011.3781%205.88634%2011.2999L7.88634%209.29989C7.91934%209.27037%207.96207%209.25405%208.00634%209.25405C8.05062%209.25405%208.09334%209.27037%208.12634%209.29989L10.1263%2011.2999C10.2027%2011.3781%2010.294%2011.4403%2010.3947%2011.4827C10.4955%2011.5251%2010.6037%2011.547%2010.713%2011.547C10.8223%2011.547%2010.9305%2011.5251%2011.0313%2011.4827C11.132%2011.4403%2011.2233%2011.3781%2011.2997%2011.2999C11.3771%2011.223%2011.4385%2011.1317%2011.4804%2011.031C11.5224%2010.9303%2011.5439%2010.8223%2011.5439%2010.7132C11.5439%2010.6042%2011.5224%2010.4962%2011.4804%2010.3955C11.4385%2010.2948%2011.3771%2010.2034%2011.2997%2010.1266L9.29967%208.12655C9.27016%208.09355%209.25384%208.05083%209.25384%208.00655C9.25384%207.96228%209.27016%207.91955%209.29967%207.88655L11.2997%205.88655C11.4553%205.73096%2011.5427%205.51993%2011.5427%205.29989C11.5427%205.07984%2011.4553%204.86881%2011.2997%204.71322C11.1441%204.55763%2010.9331%204.47021%2010.713%204.47021C10.493%204.47021%2010.2819%204.55763%2010.1263%204.71322L8.12634%206.71322C8.09334%206.74274%208.05062%206.75906%208.00634%206.75906C7.96207%206.75906%207.91934%206.74274%207.88634%206.71322L5.88634%204.71322Z'%20fill='%23BB1410'%20/%3e%3c/svg%3e");
2100
2100
  }
2101
- .p-table[data-v-f12e8db6] {
2101
+ .p-table[data-v-1d76cd98] {
2102
2102
  color: var(--color-night);
2103
2103
  height: 1px;
2104
2104
  }
2105
- .p-table th[data-v-f12e8db6] {
2105
+ .p-table th[data-v-1d76cd98] {
2106
2106
  position: sticky;
2107
2107
  top: 0px;
2108
2108
  z-index: 20;
2109
2109
  padding: 0px;
2110
2110
  }
2111
- .p-table.first-col-fixed th[data-v-f12e8db6]:first-child {
2111
+ .p-table.first-col-fixed th[data-v-1d76cd98]:first-child {
2112
2112
  left: 0px;
2113
2113
  z-index: 30;
2114
2114
  }
2115
- .p-table.first-col-fixed th:first-child .th-shadow[data-v-f12e8db6] {
2115
+ .p-table.first-col-fixed th:first-child .th-shadow[data-v-1d76cd98] {
2116
2116
  box-shadow: -1px 1px 5px 4px rgba(0, 0, 0, 0.15);
2117
2117
  clip-path: inset(0px -12px 0px 0px);
2118
2118
  }
2119
- .p-table.last-col-fixed th[data-v-f12e8db6]:last-child {
2119
+ .p-table.last-col-fixed th[data-v-1d76cd98]:last-child {
2120
2120
  right: 0px;
2121
2121
  z-index: 30;
2122
2122
  }
2123
- .p-table.last-col-fixed th:last-child .th-shadow[data-v-f12e8db6] {
2123
+ .p-table.last-col-fixed th:last-child .th-shadow[data-v-1d76cd98] {
2124
2124
  box-shadow: -2px 1px 8px rgba(0, 0, 0, 0.15);
2125
2125
  clip-path: inset(0px 0px 0px -12px);
2126
2126
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@pequity/squirrel",
3
3
  "description": "Squirrel component library",
4
- "version": "5.0.2",
5
- "packageManager": "pnpm@9.9.0",
4
+ "version": "5.2.0",
5
+ "packageManager": "pnpm@9.10.0",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "preinstall": "npx only-allow pnpm",
@@ -52,27 +52,27 @@
52
52
  "devDependencies": {
53
53
  "@babel/core": "^7.25.2",
54
54
  "@babel/preset-env": "^7.25.4",
55
- "@commitlint/cli": "^19.4.1",
56
- "@commitlint/config-conventional": "^19.4.1",
55
+ "@commitlint/cli": "^19.5.0",
56
+ "@commitlint/config-conventional": "^19.5.0",
57
57
  "@pequity/eslint-config": "^0.0.13",
58
58
  "@playwright/test": "^1.47.0",
59
59
  "@popperjs/core": "2.11.8",
60
60
  "@semantic-release/changelog": "^6.0.3",
61
61
  "@semantic-release/git": "^10.0.1",
62
- "@storybook/addon-a11y": "^8.2.9",
63
- "@storybook/addon-actions": "^8.2.9",
64
- "@storybook/addon-essentials": "^8.2.9",
65
- "@storybook/addon-interactions": "^8.2.9",
66
- "@storybook/addon-links": "^8.2.9",
67
- "@storybook/blocks": "^8.2.9",
68
- "@storybook/manager-api": "^8.2.9",
69
- "@storybook/test": "^8.2.9",
62
+ "@storybook/addon-a11y": "^8.3.0",
63
+ "@storybook/addon-actions": "^8.3.0",
64
+ "@storybook/addon-essentials": "^8.3.0",
65
+ "@storybook/addon-interactions": "^8.3.0",
66
+ "@storybook/addon-links": "^8.3.0",
67
+ "@storybook/blocks": "^8.3.0",
68
+ "@storybook/manager-api": "^8.3.0",
69
+ "@storybook/test": "^8.3.0",
70
70
  "@storybook/test-runner": "^0.19.1",
71
- "@storybook/theming": "^8.2.9",
72
- "@storybook/vue3": "^8.2.9",
73
- "@storybook/vue3-vite": "^8.2.9",
71
+ "@storybook/theming": "^8.3.0",
72
+ "@storybook/vue3": "^8.3.0",
73
+ "@storybook/vue3-vite": "^8.3.0",
74
74
  "@tanstack/vue-virtual": "3.10.7",
75
- "@types/jest": "^29.5.12",
75
+ "@types/jest": "^29.5.13",
76
76
  "@types/jsdom": "^21.1.7",
77
77
  "@types/lodash-es": "^4.17.12",
78
78
  "@types/node": "^22.5.4",
@@ -87,7 +87,8 @@
87
87
  "eslint-plugin-storybook": "^0.8.0",
88
88
  "floating-vue": "5.2.2",
89
89
  "glob": "^11.0.0",
90
- "husky": "^9.1.5",
90
+ "husky": "^9.1.6",
91
+ "iconify-icon": "^2.1.0",
91
92
  "jest": "^29.7.0",
92
93
  "jest-environment-jsdom": "^29.7.0",
93
94
  "lint-staged": "^15.2.10",
@@ -99,17 +100,17 @@
99
100
  "resolve-tspaths": "^0.8.19",
100
101
  "rimraf": "^6.0.1",
101
102
  "sass": "^1.78.0",
102
- "semantic-release": "^24.1.0",
103
- "storybook": "^8.2.9",
103
+ "semantic-release": "^24.1.1",
104
+ "storybook": "^8.3.0",
104
105
  "svgo": "^3.3.2",
105
- "tailwindcss": "^3.4.10",
106
+ "tailwindcss": "^3.4.11",
106
107
  "ts-jest": "^29.2.5",
107
108
  "typescript": "5.5.4",
108
109
  "v-calendar": "3.1.2",
109
- "vite": "^5.4.3",
110
+ "vite": "^5.4.4",
110
111
  "vue": "3.4.38",
111
112
  "vue-currency-input": "3.1.0",
112
- "vue-router": "4.4.3",
113
+ "vue-router": "4.4.5",
113
114
  "vue-toastification": "2.0.0-rc.5",
114
115
  "vue-tsc": "2.1.6"
115
116
  }
@@ -12,6 +12,7 @@ import PDropdown from '@squirrel/components/p-dropdown/p-dropdown.vue';
12
12
  import PDropdownSelect from '@squirrel/components/p-dropdown-select/p-dropdown-select.vue';
13
13
  import PFileUpload from '@squirrel/components/p-file-upload/p-file-upload.vue';
14
14
  import PFilterIcon from '@squirrel/components/p-table-header-cell/p-table-filter-icon.vue';
15
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
15
16
  import PInfoIcon from '@squirrel/components/p-info-icon/p-info-icon.vue';
16
17
  import PInlineDatePicker from '@squirrel/components/p-inline-date-picker/p-inline-date-picker.vue';
17
18
  import PInput from '@squirrel/components/p-input/p-input.vue';
@@ -50,6 +51,7 @@ import {
50
51
  isLastColFixedInjectionKey,
51
52
  } from '@squirrel/components/p-table/p-table.types';
52
53
  import { type PActionBarAction } from '@squirrel/components/p-action-bar/p-action-bar.types';
54
+ import { type PIconAlias, P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
53
55
  import {
54
56
  SORTING_TYPES,
55
57
  type SortingType,
@@ -78,6 +80,7 @@ export {
78
80
  PDropdownSelect,
79
81
  PFileUpload,
80
82
  PFilterIcon,
83
+ PIcon,
81
84
  PInfoIcon,
82
85
  PInlineDatePicker,
83
86
  PInput,
@@ -106,6 +109,7 @@ export {
106
109
  PToggle,
107
110
  SORTING_TYPES,
108
111
  MIN_WIDTH_COL_RESIZE,
112
+ P_ICON_ALIASES,
109
113
  colsInjectionKey,
110
114
  isColsResizableInjectionKey,
111
115
  isFirstColFixedInjectionKey,
@@ -122,4 +126,5 @@ export {
122
126
  HeaderCellAttrs,
123
127
  TableCol,
124
128
  ThAttrs,
129
+ PIconAlias,
125
130
  };
@@ -0,0 +1,79 @@
1
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
2
+ import { P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
3
+ import { createWrapperFor } from '@tests/jest.helpers';
4
+
5
+ const createWrapper = (props, attrs) => {
6
+ return createWrapperFor(PIcon, {
7
+ props: {
8
+ icon: 'ant-design:build-twotone',
9
+ ...props,
10
+ },
11
+ attrs,
12
+ global: {
13
+ stubs: {
14
+ 'iconify-icon': true,
15
+ },
16
+ },
17
+ });
18
+ };
19
+
20
+ describe('PIcon.vue', () => {
21
+ it('renders an icon', async () => {
22
+ const wrapper = createWrapper({
23
+ icon: 'ant-design:build-twotone',
24
+ });
25
+
26
+ const icon = wrapper.findComponent('iconify-icon-stub');
27
+
28
+ expect(icon.exists()).toBe(true);
29
+ expect(icon.attributes().icon).toBe('ant-design:build-twotone');
30
+ });
31
+
32
+ it('passes arbitrary attrs to the icon component', async () => {
33
+ const wrapper = createWrapper({}, { 'data-test': 'test' });
34
+
35
+ const icon = wrapper.findComponent('iconify-icon-stub');
36
+
37
+ expect(icon.attributes()['data-test']).toBe('test');
38
+ });
39
+
40
+ it('passes down events to the icon component', async () => {
41
+ const clickFn = jest.fn();
42
+
43
+ const wrapper = createWrapperFor(
44
+ {
45
+ template: '<PIcon icon="ant-design:build-twotone" @click="onClick" />',
46
+ components: {
47
+ PIcon,
48
+ },
49
+ methods: {
50
+ onClick: clickFn,
51
+ },
52
+ },
53
+ {
54
+ global: {
55
+ stubs: {
56
+ 'iconify-icon': true,
57
+ },
58
+ },
59
+ }
60
+ );
61
+
62
+ const icon = wrapper.findComponent('iconify-icon-stub');
63
+
64
+ await icon.trigger('click');
65
+
66
+ expect(clickFn).toHaveBeenCalled();
67
+ });
68
+
69
+ it.each(Object.entries(P_ICON_ALIASES))(
70
+ 'renders the %s icon when the %s is passed as an icon prop',
71
+ async (iconAliasKey, iconAlias) => {
72
+ const wrapper = createWrapper({ icon: iconAliasKey });
73
+
74
+ const icon = wrapper.findComponent('iconify-icon-stub');
75
+
76
+ expect(icon.attributes().icon).toBe(iconAlias);
77
+ }
78
+ );
79
+ });
@@ -0,0 +1,128 @@
1
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
2
+ import { P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
3
+
4
+ export default {
5
+ title: 'Components/PIcon',
6
+ component: PIcon,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component: `**PIcon** is a wrapper for the [iconify-icon](https://iconify.design/docs/iconify-icon/#attributes) web component that adds custom **icon aliases**, making it easier to maintain a consistent and unified icon set.
12
+
13
+ All the customization options provided by [iconify-icon](https://iconify.design/docs/iconify-icon/#attributes) are available.
14
+
15
+ - Learn how to control icon dimensions [here](https://iconify.design/docs/iconify-icon/dimensions.html).
16
+ - Discover how to adjust icon colors [here](https://iconify.design/docs/iconify-icon/color).
17
+ - Check out the available icons [here](https://icon-sets.iconify.design/).`,
18
+ },
19
+ },
20
+ },
21
+ args: {
22
+ icon: 'ant-design:build-twotone',
23
+ mode: 'svg',
24
+ inline: false,
25
+ width: '4rem',
26
+ height: '4rem',
27
+ flip: '',
28
+ rotate: '',
29
+ },
30
+ argTypes: {
31
+ icon: {
32
+ control: { type: 'text' },
33
+ description: 'Icon',
34
+ },
35
+ mode: {
36
+ control: { type: 'select' },
37
+ options: ['svg', 'style', 'bg', 'mask'],
38
+ description: 'Sets icon rendering mode. See [rendering modes](https://iconify.design/docs/iconify-icon/modes).',
39
+ },
40
+ inline: {
41
+ control: { type: 'boolean' },
42
+ description:
43
+ 'Changes vertical alignment. See [vertical alignment](https://iconify.design/docs/iconify-icon/inline.html).',
44
+ },
45
+ width: {
46
+ control: { type: 'text' },
47
+ description: 'Icon width. See [icon dimensions](https://iconify.design/docs/iconify-icon/dimensions.html).',
48
+ },
49
+ height: {
50
+ control: { type: 'text' },
51
+ description: 'Icon height. See [icon dimensions](https://iconify.design/docs/iconify-icon/dimensions.html).',
52
+ },
53
+ flip: {
54
+ control: { type: 'select' },
55
+ options: ['', 'horizontal', 'vertical'],
56
+ description: 'Flip icon. See [icon transformations](https://iconify.design/docs/iconify-icon/transform.html).',
57
+ },
58
+ rotate: {
59
+ control: { type: 'select' },
60
+ options: ['', '90deg', '180deg', '270deg'],
61
+ description: 'Rotates icon. See [icon transformations](https://iconify.design/docs/iconify-icon/transform.html).',
62
+ },
63
+ color: {
64
+ control: { type: 'color' },
65
+ description: 'Icon color. See [icon colors](https://iconify.design/docs/iconify-icon/color).',
66
+ },
67
+ },
68
+ };
69
+
70
+ export const Default = {
71
+ render: (args) => ({
72
+ components: { PIcon },
73
+ setup() {
74
+ return { args };
75
+ },
76
+ template: `<PIcon v-bind="args" class="text-p-purple-50" :style="{ color: args.color }" />`,
77
+ }),
78
+ };
79
+
80
+ export const IconAlias = {
81
+ ...Default,
82
+ args: {
83
+ icon: 'delete',
84
+ },
85
+ argTypes: {
86
+ icon: {
87
+ control: { type: 'select' },
88
+ options: Object.keys(P_ICON_ALIASES),
89
+ },
90
+ },
91
+ parameters: {
92
+ docs: {
93
+ description: {
94
+ story: `The **icon** prop accepts an alias that points to a specific icon. This allows for a consistent and unified icon set.`,
95
+ },
96
+ },
97
+ },
98
+ };
99
+
100
+ export const AllIconAliases = {
101
+ ...Default,
102
+ render: (args) => ({
103
+ components: { PIcon },
104
+ setup() {
105
+ return { args, P_ICON_ALIASES };
106
+ },
107
+ template: `
108
+ <div class="mt-2 flex w-full gap-4">
109
+ <div
110
+ v-for="(iconClass, iconAlias) in P_ICON_ALIASES"
111
+ :key="iconAlias"
112
+ :title="iconClass"
113
+ class="flex flex-col items-center justify-center gap-y-2"
114
+ >
115
+ <PIcon v-bind="args" :icon="iconAlias" class="text-p-purple-50" :style="{ color: args.color }" />
116
+ <div>{{ iconAlias }}</div>
117
+ </div>
118
+ </div>
119
+ `,
120
+ }),
121
+ parameters: {
122
+ docs: {
123
+ description: {
124
+ story: `All available icon aliases.`,
125
+ },
126
+ },
127
+ },
128
+ };
@@ -0,0 +1,8 @@
1
+ export const P_ICON_ALIASES = {
2
+ delete: 'octicon:trash-24',
3
+ edit: 'simple-line-icons:pencil',
4
+ send: 'fa:paper-plane',
5
+ settings: 'heroicons:cog-8-tooth-20-solid',
6
+ } as const;
7
+
8
+ export type PIconAlias = keyof typeof P_ICON_ALIASES;
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <iconify-icon v-bind="{ ...$props, icon: isPIcon(icon) ? P_ICON_ALIASES[icon] : icon }" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { type IconifyIconAttributes } from 'iconify-icon';
7
+ import { type PIconAlias, P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
8
+ import 'iconify-icon';
9
+
10
+ defineOptions({
11
+ name: 'PIcon',
12
+ });
13
+
14
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
15
+ interface Props extends /* @vue-ignore */ Omit<IconifyIconAttributes, 'icon'> {
16
+ icon: IconifyIconAttributes['icon'] | PIconAlias;
17
+ }
18
+
19
+ const isPIcon = (icon: string): icon is PIconAlias => !!P_ICON_ALIASES[icon as PIconAlias];
20
+
21
+ defineProps<Props>();
22
+ </script>
@@ -65,7 +65,7 @@
65
65
  ></th>
66
66
  </tr>
67
67
  </thead>
68
- <tbody>
68
+ <tbody ref="tbodyElement">
69
69
  <tr v-if="virtualizer.paddingTop > 0">
70
70
  <td :style="{ height: `${virtualizer.paddingTop}px` }"></td>
71
71
  </tr>
@@ -159,6 +159,7 @@ const {
159
159
  enabled: computed(() => props.colsResizable),
160
160
  ths,
161
161
  });
162
+ const tbodyElement = ref<HTMLElement | null>(null);
162
163
 
163
164
  // Methods
164
165
  const updateThsRefs = (el: unknown, index: number) => {
@@ -235,6 +236,11 @@ watch(isColResizing, (nV) => {
235
236
  emit('col-resize', colResizingIndex.value, colResizingWidth.value);
236
237
  }
237
238
  });
239
+
240
+ // Expose
241
+ defineExpose({
242
+ tbodyElement,
243
+ });
238
244
  </script>
239
245
 
240
246
  <style scoped lang="scss">