@pequity/squirrel 8.5.2 → 9.0.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.
- package/README.md +1 -1
- package/dist/cjs/chunks/p-icon.js +1 -2058
- package/dist/cjs/chunks/p-table-header-cell.js +8 -10
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/number.js +3 -2
- package/dist/es/chunks/p-icon.js +1 -2058
- package/dist/es/chunks/p-table-header-cell.js +9 -11
- package/dist/es/index.js +8 -3
- package/dist/es/number.js +3 -2
- package/dist/squirrel/components/p-table/p-table.vue.d.ts +4 -0
- package/dist/squirrel/components/p-table-header-cell/p-table-header-cell.vue.d.ts +11 -1
- package/dist/squirrel.css +8 -8
- package/package.json +16 -15
- package/squirrel/components/p-table/p-table.spec.js +26 -0
- package/squirrel/components/p-table/p-table.vue +5 -1
- package/squirrel/components/p-table-header-cell/p-table-header-cell.spec.js +17 -3
- package/squirrel/components/p-table-header-cell/p-table-header-cell.stories.js +31 -6
- package/squirrel/components/p-table-header-cell/p-table-header-cell.vue +8 -11
- package/squirrel/utils/number.spec.js +13 -3
- package/squirrel/utils/number.ts +5 -2
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { defineComponent, computed, createElementBlock, openBlock, createElementVNode, createCommentVNode, createVNode, normalizeStyle, normalizeClass, toDisplayString } from "vue";
|
|
1
|
+
import { defineComponent, computed, createElementBlock, openBlock, createElementVNode, createBlock, createCommentVNode, renderSlot, createVNode, normalizeStyle, normalizeClass, toDisplayString } from "vue";
|
|
2
2
|
import { _ as _sfc_main$2 } from "./p-icon.js";
|
|
3
3
|
import { _ as _sfc_main$1 } from "./p-info-icon.js";
|
|
4
|
-
const _hoisted_1 = { class: "flex items-center overflow-hidden" };
|
|
4
|
+
const _hoisted_1 = { class: "flex items-center gap-x-1 overflow-hidden" };
|
|
5
5
|
const _hoisted_2 = ["title"];
|
|
6
|
-
const _hoisted_3 = {
|
|
7
|
-
key: 0,
|
|
8
|
-
class: "relative ml-1 mr-auto h-3 w-3 shrink-0"
|
|
9
|
-
};
|
|
10
6
|
const DEFAULT_CLASSES = `text-xs font-semibold line-clamp-2 break-words hyphens-auto whitespace-normal max-h-10 shrink`;
|
|
11
7
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
12
8
|
...{
|
|
@@ -31,18 +27,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
31
27
|
return (_ctx, _cache) => {
|
|
32
28
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
33
29
|
createElementVNode("div", {
|
|
34
|
-
class: normalizeClass([DEFAULT_CLASSES, _ctx.textClass, textColorClass.value
|
|
30
|
+
class: normalizeClass([DEFAULT_CLASSES, _ctx.textClass, textColorClass.value]),
|
|
35
31
|
style: normalizeStyle(style.value),
|
|
36
32
|
title: _ctx.text,
|
|
37
33
|
"data-p-table-header-text": ""
|
|
38
34
|
}, toDisplayString(_ctx.text), 15, _hoisted_2),
|
|
39
|
-
_ctx.tooltipText ? (openBlock(),
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
_ctx.tooltipText ? (openBlock(), createBlock(_sfc_main$1, {
|
|
36
|
+
key: 0,
|
|
37
|
+
text: _ctx.tooltipText
|
|
38
|
+
}, null, 8, ["text"])) : createCommentVNode("", true),
|
|
39
|
+
renderSlot(_ctx.$slots, "icon"),
|
|
42
40
|
createVNode(_sfc_main$2, {
|
|
43
41
|
icon: _ctx.filterActive ? "ph:funnel-fill" : "si:filter-list-alt-duotone",
|
|
44
42
|
class: normalizeClass([
|
|
45
|
-
"ml-
|
|
43
|
+
"ml-auto cursor-pointer rounded-sm",
|
|
46
44
|
{ hidden: !_ctx.showFilterIcon },
|
|
47
45
|
_ctx.filterActive ? "text-active-blue hover:bg-p-blue-10 hover:text-p-blue-60 hover:ring-1 hover:ring-p-blue-10" : "text-p-gray-60 hover:bg-p-gray-10 hover:text-night hover:ring-1 hover:ring-p-gray-10"
|
|
48
46
|
]),
|
package/dist/es/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { default as default5 } from "./p-drawer.js";
|
|
|
11
11
|
import { default as default6 } from "./p-dropdown.js";
|
|
12
12
|
import { _ as _imports_0$1 } from "./chunks/p-dropdown-select.js";
|
|
13
13
|
import { a } from "./chunks/p-dropdown-select.js";
|
|
14
|
-
import { defineComponent, shallowRef, ref, computed, onMounted, createElementBlock, openBlock, normalizeClass, createCommentVNode, createElementVNode, withDirectives, unref, toDisplayString, withModifiers, createVNode, createTextVNode, Fragment, renderList, vShow, useAttrs, resolveDirective, normalizeStyle, isRef, renderSlot, provide, useTemplateRef, onBeforeUnmount, watch, mergeProps, toHandlers,
|
|
14
|
+
import { defineComponent, shallowRef, ref, computed, onMounted, createElementBlock, openBlock, normalizeClass, createCommentVNode, createElementVNode, withDirectives, unref, toDisplayString, withModifiers, createVNode, createTextVNode, Fragment, renderList, vShow, useAttrs, resolveDirective, normalizeStyle, isRef, renderSlot, provide, useTemplateRef, onBeforeUnmount, watch, mergeProps, toHandlers, withCtx, createBlock } from "vue";
|
|
15
15
|
import { formatBytes, getFileExtension } from "./p-file-upload.js";
|
|
16
16
|
import { _ as _sfc_main$4 } from "./chunks/p-icon.js";
|
|
17
17
|
import { useInputClasses } from "./useInputClasses.js";
|
|
@@ -881,7 +881,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
881
881
|
"text-color": headerCellTextColor(col)
|
|
882
882
|
}, { ref_for: true }, col.headerCellAttrs, {
|
|
883
883
|
onClickFilterIcon: ($event) => _ctx.$emit("click-filter-icon", $event, col)
|
|
884
|
-
}),
|
|
884
|
+
}), {
|
|
885
|
+
icon: withCtx(() => [
|
|
886
|
+
renderSlot(_ctx.$slots, `header-cell-icon-${unref(kebabCase)(col.name)}`, { col }, void 0, true)
|
|
887
|
+
]),
|
|
888
|
+
_: 2
|
|
889
|
+
}, 1040, ["text", "filter-active", "show-filter-icon", "tooltip-text", "class", "text-color", "onClickFilterIcon"])
|
|
885
890
|
], 2),
|
|
886
891
|
_ctx.colsResizable && i2 !== 0 && !(i2 === _ctx.cols.length - 1 && _ctx.isLastColFixed) ? (openBlock(), createElementBlock("div", {
|
|
887
892
|
key: 0,
|
|
@@ -947,7 +952,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
947
952
|
};
|
|
948
953
|
}
|
|
949
954
|
});
|
|
950
|
-
const pTable = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-
|
|
955
|
+
const pTable = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-9bbf6a22"]]);
|
|
951
956
|
const _imports_0 = "data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_1019_75838)'%3e%3cpath%20d='M11.6533%203.37331L8.47329%200.18664C8.41131%200.124154%208.33758%200.074558%208.25634%200.0407122C8.1751%200.00686641%208.08796%20-0.0105591%207.99995%20-0.0105591C7.91194%20-0.0105591%207.82481%200.00686641%207.74357%200.0407122C7.66233%200.074558%207.58859%200.124154%207.52662%200.18664L4.34662%203.37331C4.253%203.46615%204.18902%203.58468%204.16277%203.71388C4.13651%203.84309%204.14916%203.97719%204.19911%204.09921C4.24906%204.22123%204.33407%204.3257%204.44339%204.39941C4.55271%204.47312%204.68144%204.51275%204.81329%204.51331H6.81329C6.83571%204.51054%206.85846%204.51235%206.88016%204.51865C6.90186%204.52494%206.92205%204.53559%206.93951%204.54993C6.95697%204.56427%206.97133%204.58201%206.98172%204.60207C6.99211%204.62214%206.99832%204.6441%206.99995%204.66664V14.9933C6.99995%2015.2585%207.10531%2015.5129%207.29285%2015.7004C7.48038%2015.888%207.73474%2015.9933%207.99995%2015.9933C8.26517%2015.9933%208.51952%2015.888%208.70706%2015.7004C8.8946%2015.5129%208.99995%2015.2585%208.99995%2014.9933V4.66664C8.99995%204.62244%209.01751%204.58004%209.04877%204.54879C9.08002%204.51753%209.12242%204.49997%209.16662%204.49997H11.1666C11.2985%204.49942%2011.4272%204.45978%2011.5365%204.38608C11.6458%204.31237%2011.7308%204.2079%2011.7808%204.08587C11.8307%203.96385%2011.8434%203.82976%2011.8171%203.70055C11.7909%203.57134%2011.7269%203.45282%2011.6333%203.35997L11.6533%203.37331Z'%20fill='%23424E6E'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_1019_75838'%3e%3crect%20width='16'%20height='16'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e";
|
|
952
957
|
const _imports_1 = "data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_1019_80096)'%3e%3cpath%20d='M11.6533%203.37331L8.47329%200.18664C8.41131%200.124154%208.33758%200.074558%208.25634%200.0407122C8.1751%200.00686641%208.08796%20-0.0105591%207.99995%20-0.0105591C7.91194%20-0.0105591%207.82481%200.00686641%207.74357%200.0407122C7.66233%200.074558%207.58859%200.124154%207.52662%200.18664L4.34662%203.37331C4.253%203.46615%204.18902%203.58468%204.16277%203.71388C4.13651%203.84309%204.14916%203.97719%204.19911%204.09921C4.24906%204.22123%204.33407%204.3257%204.44339%204.39941C4.55271%204.47312%204.68144%204.51275%204.81329%204.51331H6.81329C6.83571%204.51054%206.85846%204.51235%206.88016%204.51865C6.90186%204.52494%206.92205%204.53559%206.93951%204.54993C6.95697%204.56427%206.97133%204.58201%206.98172%204.60207C6.99211%204.62214%206.99832%204.6441%206.99995%204.66664V14.9933C6.99995%2015.2585%207.10531%2015.5129%207.29285%2015.7004C7.48038%2015.888%207.73474%2015.9933%207.99995%2015.9933C8.26517%2015.9933%208.51952%2015.888%208.70706%2015.7004C8.8946%2015.5129%208.99995%2015.2585%208.99995%2014.9933V4.66664C8.99995%204.62244%209.01751%204.58004%209.04877%204.54879C9.08002%204.51753%209.12242%204.49997%209.16662%204.49997H11.1666C11.2985%204.49942%2011.4272%204.45978%2011.5365%204.38608C11.6458%204.31237%2011.7308%204.2079%2011.7808%204.08587C11.8307%203.96385%2011.8434%203.82976%2011.8171%203.70055C11.7909%203.57134%2011.7269%203.45282%2011.6333%203.35997L11.6533%203.37331Z'%20fill='%23323CEB'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_1019_80096'%3e%3crect%20width='16'%20height='16'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e";
|
|
953
958
|
const _imports_2 = "data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_1019_75842)'%3e%3cpath%20d='M11.8%2011.8933C11.75%2011.7716%2011.665%2011.6674%2011.5559%2011.5938C11.4467%2011.5203%2011.3183%2011.4807%2011.1866%2011.48H9.18664C9.16473%2011.4828%209.14248%2011.4812%209.12119%2011.4753C9.0999%2011.4694%209.07999%2011.4594%209.06262%2011.4457C9.04525%2011.4321%209.03077%2011.4151%209.02001%2011.3958C9.00926%2011.3765%209.00245%2011.3553%208.99997%2011.3333V1C8.99997%200.734784%208.89462%200.48043%208.70708%200.292893C8.51954%200.105357%208.26519%200%207.99997%200C7.73476%200%207.4804%200.105357%207.29287%200.292893C7.10533%200.48043%206.99997%200.734784%206.99997%201V11.3333C6.99997%2011.3775%206.98241%2011.4199%206.95116%2011.4512C6.9199%2011.4824%206.87751%2011.5%206.83331%2011.5H4.83331C4.70146%2011.5006%204.57273%2011.5402%204.46341%2011.6139C4.35409%2011.6876%204.26908%2011.7921%204.21913%2011.9141C4.16918%2012.0361%204.15653%2012.1702%204.18279%2012.2994C4.20904%2012.4286%204.27302%2012.5472%204.36664%2012.64L7.54664%2015.8267C7.60861%2015.8892%207.68235%2015.9387%207.76359%2015.9726C7.84483%2016.0064%207.93196%2016.0239%208.01997%2016.0239C8.10798%2016.0239%208.19512%2016.0064%208.27636%2015.9726C8.3576%2015.9387%208.43133%2015.8892%208.49331%2015.8267L11.6733%2012.64C11.7677%2012.5431%2011.8303%2012.4198%2011.853%2012.2864C11.8756%2012.153%2011.8571%2012.0159%2011.8%2011.8933Z'%20fill='%23424E6E'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_1019_75842'%3e%3crect%20width='16'%20height='16'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e";
|
package/dist/es/number.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const toNumberOrNull = (val) => {
|
|
2
|
-
if (val === "" || val === null
|
|
2
|
+
if (val === "" || val === null) {
|
|
3
3
|
return null;
|
|
4
4
|
}
|
|
5
|
-
|
|
5
|
+
const num = Number(val);
|
|
6
|
+
return isFinite(num) ? num : null;
|
|
6
7
|
};
|
|
7
8
|
export {
|
|
8
9
|
toNumberOrNull
|
|
@@ -57,6 +57,10 @@ declare const _default: <T extends Record<string, unknown>>(__VLS_props: NonNull
|
|
|
57
57
|
[x: `prepend-header-cell-${string}`]: ((props: {
|
|
58
58
|
col: TableCol;
|
|
59
59
|
}) => any) | undefined;
|
|
60
|
+
} & {
|
|
61
|
+
[x: `header-cell-icon-${string}`]: ((props: {
|
|
62
|
+
col: TableCol;
|
|
63
|
+
}) => any) | undefined;
|
|
60
64
|
} & {
|
|
61
65
|
[x: `subheader-cell-${string}`]: ((props: {}) => any) | undefined;
|
|
62
66
|
} & {
|
|
@@ -6,7 +6,11 @@ type Props = {
|
|
|
6
6
|
tooltipText?: string;
|
|
7
7
|
textColor?: string;
|
|
8
8
|
};
|
|
9
|
-
declare
|
|
9
|
+
declare var __VLS_5: {};
|
|
10
|
+
type __VLS_Slots = {} & {
|
|
11
|
+
icon?: (props: typeof __VLS_5) => any;
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
14
|
"click-filter-icon": (event: Event, filterActive: boolean) => any;
|
|
11
15
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
12
16
|
"onClick-filter-icon"?: ((event: Event, filterActive: boolean) => any) | undefined;
|
|
@@ -18,4 +22,10 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
|
|
|
18
22
|
showFilterIcon: boolean;
|
|
19
23
|
textColor: string;
|
|
20
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
21
26
|
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
package/dist/squirrel.css
CHANGED
|
@@ -1117,35 +1117,35 @@ to {
|
|
|
1117
1117
|
background-image: url("data:image/svg+xml,%3csvg%20width='33'%20height='30'%20viewBox='0%200%2033%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M31.0143%2029.9524C31.1862%2029.9516%2031.3551%2029.9066%2031.5045%2029.8215C31.6539%2029.7365%2031.7789%2029.6144%2031.8674%2029.4669C31.9558%2029.3195%2032.0048%2029.1517%2032.0095%2028.9799C32.0142%2028.808%2031.9745%2028.6378%2031.8943%2028.4857L16.8943%200.485744C16.8006%200.337008%2016.6708%200.214443%2016.5169%200.129498C16.363%200.0445534%2016.1901%200%2016.0143%200C15.8385%200%2015.6656%200.0445534%2015.5117%200.129498C15.3578%200.214443%2015.228%200.337008%2015.1343%200.485744L0.134286%2028.4857C0.0463617%2028.6353%200%2028.8056%200%2028.9791C0%2029.1526%200.0463617%2029.3229%200.134286%2029.4724C0.221436%2029.6207%200.346313%2029.7432%200.496207%2029.8275C0.6461%2029.9118%200.815658%2029.9549%200.98762%2029.9524H31.0143ZM16.0143%2026.2857C15.6176%2026.2857%2015.2299%2026.1677%2014.9004%2025.9467C14.571%2025.7258%2014.3147%2025.4118%2014.1641%2025.0448C14.0136%2024.6778%2013.9755%2024.2743%2014.0549%2023.8857C14.1342%2023.497%2014.3274%2023.1407%2014.6098%2022.8621C14.8922%2022.5835%2015.251%2022.3951%2015.6407%2022.321C16.0304%2022.2468%2016.4334%2022.2903%2016.7983%2022.4458C17.1633%2022.6012%2017.4737%2022.8617%2017.6903%2023.1941C17.9068%2023.5265%2018.0196%2023.9158%2018.0143%2024.3124C18.0073%2024.8382%2017.7935%2025.3401%2017.4192%2025.7094C17.0448%2026.0787%2016.5401%2026.2858%2016.0143%2026.2857ZM16.0143%209.95241C16.3679%209.95241%2016.707%2010.0929%2016.9571%2010.3429C17.2071%2010.593%2017.3476%2010.9321%2017.3476%2011.2857V18.5791C17.3476%2018.9327%2017.2071%2019.2718%2016.9571%2019.5219C16.707%2019.7719%2016.3679%2019.9124%2016.0143%2019.9124C15.6607%2019.9124%2015.3215%2019.7719%2015.0715%2019.5219C14.8214%2019.2718%2014.681%2018.9327%2014.681%2018.5791V11.2857C14.681%2010.9321%2014.8214%2010.593%2015.0715%2010.3429C15.3215%2010.0929%2015.6607%209.95241%2016.0143%209.95241Z'%20fill='%23F2C94C'%20/%3e%3c/svg%3e");
|
|
1118
1118
|
}
|
|
1119
1119
|
|
|
1120
|
-
/*# sourceMappingURL=squirrel.css.map */.p-table[data-v-
|
|
1120
|
+
/*# sourceMappingURL=squirrel.css.map */.p-table[data-v-9bbf6a22] {
|
|
1121
1121
|
color: rgb(var(--color-night));
|
|
1122
1122
|
height: 1px;
|
|
1123
1123
|
}
|
|
1124
|
-
.p-table th[data-v-
|
|
1124
|
+
.p-table th[data-v-9bbf6a22] {
|
|
1125
1125
|
position: sticky;
|
|
1126
1126
|
top: 0px;
|
|
1127
1127
|
z-index: 20;
|
|
1128
1128
|
padding: 0px;
|
|
1129
1129
|
}
|
|
1130
|
-
.p-table.first-col-fixed th[data-v-
|
|
1130
|
+
.p-table.first-col-fixed th[data-v-9bbf6a22]:first-child {
|
|
1131
1131
|
left: 0px;
|
|
1132
1132
|
z-index: 30;
|
|
1133
1133
|
}
|
|
1134
|
-
.p-table.first-col-fixed th:first-child .th-shadow[data-v-
|
|
1134
|
+
.p-table.first-col-fixed th:first-child .th-shadow[data-v-9bbf6a22] {
|
|
1135
1135
|
box-shadow: -1px 1px 5px 4px rgba(0, 0, 0, 0.15);
|
|
1136
1136
|
clip-path: inset(0px -12px 0px 0px);
|
|
1137
1137
|
}
|
|
1138
|
-
.p-table.last-col-fixed th[data-v-
|
|
1138
|
+
.p-table.last-col-fixed th[data-v-9bbf6a22]:last-child {
|
|
1139
1139
|
right: 0px;
|
|
1140
1140
|
z-index: 30;
|
|
1141
1141
|
}
|
|
1142
|
-
.p-table.last-col-fixed th:last-child .th-shadow[data-v-
|
|
1142
|
+
.p-table.last-col-fixed th:last-child .th-shadow[data-v-9bbf6a22] {
|
|
1143
1143
|
box-shadow: -2px 1px 8px rgba(0, 0, 0, 0.15);
|
|
1144
1144
|
clip-path: inset(0px 0px 0px -12px);
|
|
1145
1145
|
}
|
|
1146
|
-
[data-v-
|
|
1146
|
+
[data-v-9bbf6a22] .p-table tr:last-child td {
|
|
1147
1147
|
border-bottom-width: 0px;
|
|
1148
1148
|
}
|
|
1149
|
-
[data-v-
|
|
1149
|
+
[data-v-9bbf6a22] .p-table tr:last-child td.td-col-fixed-border-b::after {
|
|
1150
1150
|
height: 0px;
|
|
1151
1151
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pequity/squirrel",
|
|
3
3
|
"description": "Squirrel component library",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "9.0.0",
|
|
5
5
|
"packageManager": "pnpm@10.15.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@tanstack/vue-virtual": "^3.8.3",
|
|
42
42
|
"@vuepic/vue-datepicker": "^11.0.1",
|
|
43
43
|
"floating-vue": "^5.2.2",
|
|
44
|
+
"iconify-icon": "^3.0.0",
|
|
44
45
|
"lodash-es": "^4.17.21",
|
|
45
46
|
"vue": "^3.4.33",
|
|
46
47
|
"vue-currency-input": "^3.1.0",
|
|
@@ -54,15 +55,15 @@
|
|
|
54
55
|
"@playwright/test": "^1.55.0",
|
|
55
56
|
"@semantic-release/changelog": "^6.0.3",
|
|
56
57
|
"@semantic-release/git": "^10.0.1",
|
|
57
|
-
"@storybook/addon-a11y": "^9.1.
|
|
58
|
-
"@storybook/addon-docs": "^9.1.
|
|
59
|
-
"@storybook/addon-links": "^9.1.
|
|
60
|
-
"@storybook/addon-vitest": "^9.1.
|
|
61
|
-
"@storybook/vue3-vite": "^9.1.
|
|
58
|
+
"@storybook/addon-a11y": "^9.1.5",
|
|
59
|
+
"@storybook/addon-docs": "^9.1.5",
|
|
60
|
+
"@storybook/addon-links": "^9.1.5",
|
|
61
|
+
"@storybook/addon-vitest": "^9.1.5",
|
|
62
|
+
"@storybook/vue3-vite": "^9.1.5",
|
|
62
63
|
"@tanstack/vue-virtual": "3.13.12",
|
|
63
64
|
"@types/jsdom": "^21.1.7",
|
|
64
65
|
"@types/lodash-es": "^4.17.12",
|
|
65
|
-
"@types/node": "^24.3.
|
|
66
|
+
"@types/node": "^24.3.1",
|
|
66
67
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
67
68
|
"@vitest/browser": "3.2.4",
|
|
68
69
|
"@vitest/coverage-v8": "^3.2.4",
|
|
@@ -70,8 +71,8 @@
|
|
|
70
71
|
"@vue/test-utils": "^2.4.6",
|
|
71
72
|
"@vuepic/vue-datepicker": "11.0.2",
|
|
72
73
|
"autoprefixer": "^10.4.21",
|
|
73
|
-
"eslint": "^9.
|
|
74
|
-
"eslint-plugin-storybook": "^9.1.
|
|
74
|
+
"eslint": "^9.35.0",
|
|
75
|
+
"eslint-plugin-storybook": "^9.1.5",
|
|
75
76
|
"floating-vue": "5.2.2",
|
|
76
77
|
"glob": "^11.0.3",
|
|
77
78
|
"husky": "^9.1.7",
|
|
@@ -86,13 +87,13 @@
|
|
|
86
87
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
|
87
88
|
"resolve-tspaths": "^0.8.23",
|
|
88
89
|
"rimraf": "^6.0.1",
|
|
89
|
-
"sass": "^1.92.
|
|
90
|
-
"semantic-release": "^24.2.
|
|
91
|
-
"storybook": "^9.1.
|
|
90
|
+
"sass": "^1.92.1",
|
|
91
|
+
"semantic-release": "^24.2.8",
|
|
92
|
+
"storybook": "^9.1.5",
|
|
92
93
|
"svgo": "^4.0.0",
|
|
93
94
|
"tailwindcss": "^3.4.17",
|
|
94
|
-
"typescript": "5.
|
|
95
|
-
"vite": "^7.1.
|
|
95
|
+
"typescript": "5.9.2",
|
|
96
|
+
"vite": "^7.1.5",
|
|
96
97
|
"vitest": "^3.2.4",
|
|
97
98
|
"vue": "3.5.21",
|
|
98
99
|
"vue-currency-input": "3.2.1",
|
|
@@ -102,6 +103,6 @@
|
|
|
102
103
|
},
|
|
103
104
|
"dependencies": {
|
|
104
105
|
"tailwind-merge": "^3.3.1",
|
|
105
|
-
"tailwind-variants": "^3.1.
|
|
106
|
+
"tailwind-variants": "^3.1.1"
|
|
106
107
|
}
|
|
107
108
|
}
|
|
@@ -458,4 +458,30 @@ describe('PTable.vue', () => {
|
|
|
458
458
|
expect(typeof wrapper.emitted()['col-resize'][0][0]).toBe('number');
|
|
459
459
|
expect(typeof wrapper.emitted()['col-resize'][0][1]).toBe('number');
|
|
460
460
|
});
|
|
461
|
+
|
|
462
|
+
it('renders header cell icon slots correctly', async () => {
|
|
463
|
+
const cols = cloneDeep(columns);
|
|
464
|
+
const wrapper = createWrapperFor(PTable, {
|
|
465
|
+
props: { cols },
|
|
466
|
+
slots: {
|
|
467
|
+
'header-cell-icon-first-column': `<div class="custom-icon">📊</div>`,
|
|
468
|
+
'header-cell-icon-second-column': `<span class="icon-span">⚡</span>`,
|
|
469
|
+
},
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Check that the first column has the custom icon
|
|
473
|
+
const firstColumnIcon = wrapper.find('th[data-col-id="1"] .custom-icon');
|
|
474
|
+
expect(firstColumnIcon.exists()).toBe(true);
|
|
475
|
+
expect(firstColumnIcon.text()).toBe('📊');
|
|
476
|
+
|
|
477
|
+
// Check that the second column has the custom icon
|
|
478
|
+
const secondColumnIcon = wrapper.find('th[data-col-id="2"] .icon-span');
|
|
479
|
+
expect(secondColumnIcon.exists()).toBe(true);
|
|
480
|
+
expect(secondColumnIcon.text()).toBe('⚡');
|
|
481
|
+
|
|
482
|
+
// Check that the third column doesn't have a custom icon (no slot provided)
|
|
483
|
+
const thirdColumnHeader = wrapper.find('th[data-col-id="3"]');
|
|
484
|
+
expect(thirdColumnHeader.find('.custom-icon').exists()).toBe(false);
|
|
485
|
+
expect(thirdColumnHeader.find('.icon-span').exists()).toBe(false);
|
|
486
|
+
});
|
|
461
487
|
});
|
|
@@ -48,7 +48,11 @@
|
|
|
48
48
|
:text-color="headerCellTextColor(col)"
|
|
49
49
|
v-bind="col.headerCellAttrs"
|
|
50
50
|
@click-filter-icon="$emit('click-filter-icon', $event, col)"
|
|
51
|
-
|
|
51
|
+
>
|
|
52
|
+
<template #icon>
|
|
53
|
+
<slot :name="`header-cell-icon-${kebabCase(col.name)}`" :col="col"></slot>
|
|
54
|
+
</template>
|
|
55
|
+
</PTableHeaderCell>
|
|
52
56
|
</div>
|
|
53
57
|
<div
|
|
54
58
|
v-if="colsResizable && i !== 0 && !(i === cols.length - 1 && isLastColFixed)"
|
|
@@ -20,7 +20,7 @@ describe('PTableHeaderCell.vue', () => {
|
|
|
20
20
|
const icon = wrapper.findComponent({ name: 'PIcon' });
|
|
21
21
|
const tooltipIcon = await wrapper.findComponent({ name: 'PInfoIcon' });
|
|
22
22
|
|
|
23
|
-
expect(wrapper.classes()).toEqual(['flex', 'items-center', 'overflow-hidden']);
|
|
23
|
+
expect(wrapper.classes()).toEqual(['flex', 'items-center', 'gap-x-1', 'overflow-hidden']);
|
|
24
24
|
expect(icon.exists()).toBe(true);
|
|
25
25
|
expect(icon.classes()).toContain('hidden');
|
|
26
26
|
expect(div.text()).toBe('Test text');
|
|
@@ -36,7 +36,6 @@ describe('PTableHeaderCell.vue', () => {
|
|
|
36
36
|
'shrink',
|
|
37
37
|
'test-class',
|
|
38
38
|
'text-p-gray-60',
|
|
39
|
-
'mr-auto',
|
|
40
39
|
]);
|
|
41
40
|
expect(tooltipIcon.exists()).toBe(false);
|
|
42
41
|
});
|
|
@@ -78,7 +77,7 @@ describe('PTableHeaderCell.vue', () => {
|
|
|
78
77
|
const tooltipIcon = await wrapper.findComponent({ name: 'PInfoIcon' });
|
|
79
78
|
const tooltipIconDivElClasses = [...wrapper.find('p-info-icon-stub').element.parentNode.classList];
|
|
80
79
|
|
|
81
|
-
expect(tooltipIconDivElClasses).toEqual(['
|
|
80
|
+
expect(tooltipIconDivElClasses).toEqual(['flex', 'items-center', 'gap-x-1', 'overflow-hidden']);
|
|
82
81
|
expect(tooltipIcon.exists()).toBe(true);
|
|
83
82
|
});
|
|
84
83
|
|
|
@@ -103,4 +102,19 @@ describe('PTableHeaderCell.vue', () => {
|
|
|
103
102
|
expect(mouseEvent).toBeInstanceOf(MouseEvent);
|
|
104
103
|
expect(active).toBe(false);
|
|
105
104
|
});
|
|
105
|
+
|
|
106
|
+
it('renders the icon slot', async () => {
|
|
107
|
+
const wrapper = createWrapperFor(PTableHeaderCell, {
|
|
108
|
+
props: {
|
|
109
|
+
text: 'Test text',
|
|
110
|
+
textClass: 'test-class',
|
|
111
|
+
showFilterIcon: false,
|
|
112
|
+
},
|
|
113
|
+
slots: { icon: '<div class="icon-slot">Icon</div>' },
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const iconSlotContent = wrapper.find('div.icon-slot');
|
|
117
|
+
|
|
118
|
+
expect(iconSlotContent.exists()).toBe(true);
|
|
119
|
+
});
|
|
106
120
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import PIcon from '@squirrel/components/p-icon/p-icon.vue';
|
|
1
2
|
import PTableHeaderCell from '@squirrel/components/p-table-header-cell/p-table-header-cell.vue';
|
|
2
3
|
import { action } from 'storybook/actions';
|
|
3
4
|
|
|
@@ -50,17 +51,41 @@ export const WithTooltip = {
|
|
|
50
51
|
},
|
|
51
52
|
};
|
|
52
53
|
|
|
53
|
-
export const
|
|
54
|
+
export const WithIconSlot = {
|
|
54
55
|
render: (args) => ({
|
|
55
|
-
components: { PTableHeaderCell },
|
|
56
|
+
components: { PTableHeaderCell, PIcon },
|
|
56
57
|
setup() {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return { args, onFilterIconClick };
|
|
58
|
+
return { args };
|
|
60
59
|
},
|
|
60
|
+
template: `
|
|
61
|
+
<div class="w-52">
|
|
62
|
+
<PTableHeaderCell v-bind="args">
|
|
63
|
+
<template #icon>
|
|
64
|
+
${args.icon}
|
|
65
|
+
</template>
|
|
66
|
+
</PTableHeaderCell>
|
|
67
|
+
</div>
|
|
68
|
+
`,
|
|
69
|
+
}),
|
|
70
|
+
args: {
|
|
71
|
+
...Default.args,
|
|
72
|
+
icon: '<PIcon icon="refresh" width="14" class="text-p-gray-60" />',
|
|
73
|
+
},
|
|
74
|
+
parameters: {
|
|
75
|
+
docs: {
|
|
76
|
+
description: {
|
|
77
|
+
story: 'Shows how to use the icon slot to display a custom icon after the header text.',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const WithBackground = {
|
|
84
|
+
render: (args) => ({
|
|
85
|
+
components: { PTableHeaderCell },
|
|
61
86
|
template: `
|
|
62
87
|
<div class="w-52 px-2 py-2 bg-p-blue-10">
|
|
63
|
-
<PTableHeaderCell v-bind="args"
|
|
88
|
+
<PTableHeaderCell v-bind="args" />
|
|
64
89
|
</div>
|
|
65
90
|
`,
|
|
66
91
|
}),
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex items-center overflow-hidden">
|
|
3
|
-
<div
|
|
4
|
-
:class="[DEFAULT_CLASSES, textClass, textColorClass, { 'mr-auto': !tooltipText }]"
|
|
5
|
-
:style="style"
|
|
6
|
-
:title="text"
|
|
7
|
-
data-p-table-header-text
|
|
8
|
-
>
|
|
2
|
+
<div class="flex items-center gap-x-1 overflow-hidden">
|
|
3
|
+
<div :class="[DEFAULT_CLASSES, textClass, textColorClass]" :style="style" :title="text" data-p-table-header-text>
|
|
9
4
|
{{ text }}
|
|
10
5
|
</div>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
|
|
7
|
+
<PInfoIcon v-if="tooltipText" :text="tooltipText" />
|
|
8
|
+
|
|
9
|
+
<slot name="icon"></slot>
|
|
10
|
+
|
|
14
11
|
<PIcon
|
|
15
12
|
:icon="filterActive ? 'ph:funnel-fill' : 'si:filter-list-alt-duotone'"
|
|
16
13
|
:class="[
|
|
17
|
-
'ml-
|
|
14
|
+
'ml-auto cursor-pointer rounded-sm',
|
|
18
15
|
{ hidden: !showFilterIcon },
|
|
19
16
|
filterActive
|
|
20
17
|
? 'text-active-blue hover:bg-p-blue-10 hover:text-p-blue-60 hover:ring-1 hover:ring-p-blue-10'
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { toNumberOrNull } from '@squirrel/utils/number';
|
|
2
2
|
|
|
3
3
|
describe('toNumberOrNull', () => {
|
|
4
|
-
it.each(['', null, 'abc', NaN, {}])('returns null if input is %s', (val) => {
|
|
4
|
+
it.each(['', null, 'abc', NaN, {}, Infinity, -Infinity])('returns null if input is %s', (val) => {
|
|
5
5
|
expect(toNumberOrNull(val)).toBeNull();
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
it('
|
|
9
|
-
|
|
8
|
+
it.each([123, '123', 0, '0', -42, '-42', 3.14, '3.14'])(
|
|
9
|
+
'returns a number if input is a valid finite number: %s',
|
|
10
|
+
(val) => {
|
|
11
|
+
expect(toNumberOrNull(val)).toBe(Number(val));
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
it('handles edge cases for infinite values', () => {
|
|
16
|
+
expect(toNumberOrNull('Infinity')).toBeNull();
|
|
17
|
+
expect(toNumberOrNull('-Infinity')).toBeNull();
|
|
18
|
+
expect(toNumberOrNull(Number.POSITIVE_INFINITY)).toBeNull();
|
|
19
|
+
expect(toNumberOrNull(Number.NEGATIVE_INFINITY)).toBeNull();
|
|
10
20
|
});
|
|
11
21
|
});
|
package/squirrel/utils/number.ts
CHANGED
|
@@ -7,8 +7,11 @@
|
|
|
7
7
|
* @returns a number or null
|
|
8
8
|
*/
|
|
9
9
|
export const toNumberOrNull = (val: unknown) => {
|
|
10
|
-
if (val === '' || val === null
|
|
10
|
+
if (val === '' || val === null) {
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
const num = Number(val);
|
|
15
|
+
|
|
16
|
+
return isFinite(num) ? num : null;
|
|
14
17
|
};
|