sevago-library 1.2.1 → 1.2.3
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/CHANGELOG.md +12 -0
- package/dist/index.cjs.js +267 -52
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +267 -52
- package/dist/index.esm.js.map +1 -1
- package/dist/src/common/utils/time.util.d.ts +7 -7
- package/dist/src/components/elements/filters/advanced-filter-dialog.component/advanced-filter-dialog.component.d.ts +24 -0
- package/dist/src/components/elements/filters/advanced-filter-dialog.component/advanced-filter-dialog.component.stories.d.ts +7 -0
- package/dist/src/components/elements/filters/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -25875,6 +25875,57 @@ const other_util = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
25875
25875
|
lightenColor,
|
|
25876
25876
|
scrollTo
|
|
25877
25877
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
25878
|
+
var relativeTime$2 = { exports: {} };
|
|
25879
|
+
var relativeTime$1 = relativeTime$2.exports;
|
|
25880
|
+
var hasRequiredRelativeTime;
|
|
25881
|
+
function requireRelativeTime() {
|
|
25882
|
+
if (hasRequiredRelativeTime) return relativeTime$2.exports;
|
|
25883
|
+
hasRequiredRelativeTime = 1;
|
|
25884
|
+
(function(module, exports) {
|
|
25885
|
+
!(function(r2, e) {
|
|
25886
|
+
module.exports = e();
|
|
25887
|
+
})(relativeTime$1, (function() {
|
|
25888
|
+
return function(r2, e, t) {
|
|
25889
|
+
r2 = r2 || {};
|
|
25890
|
+
var n = e.prototype, o = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" };
|
|
25891
|
+
function i(r3, e2, t2, o2) {
|
|
25892
|
+
return n.fromToBase(r3, e2, t2, o2);
|
|
25893
|
+
}
|
|
25894
|
+
t.en.relativeTime = o, n.fromToBase = function(e2, n2, i2, d2, u) {
|
|
25895
|
+
for (var f, a, s, l = i2.$locale().relativeTime || o, h = r2.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m = h.length, c = 0; c < m; c += 1) {
|
|
25896
|
+
var y = h[c];
|
|
25897
|
+
y.d && (f = d2 ? t(e2).diff(i2, y.d, true) : i2.diff(e2, y.d, true));
|
|
25898
|
+
var p = (r2.rounding || Math.round)(Math.abs(f));
|
|
25899
|
+
if (s = f > 0, p <= y.r || !y.r) {
|
|
25900
|
+
p <= 1 && c > 0 && (y = h[c - 1]);
|
|
25901
|
+
var v = l[y.l];
|
|
25902
|
+
u && (p = u("" + p)), a = "string" == typeof v ? v.replace("%d", p) : v(p, n2, y.l, s);
|
|
25903
|
+
break;
|
|
25904
|
+
}
|
|
25905
|
+
}
|
|
25906
|
+
if (n2) return a;
|
|
25907
|
+
var M = s ? l.future : l.past;
|
|
25908
|
+
return "function" == typeof M ? M(a) : M.replace("%s", a);
|
|
25909
|
+
}, n.to = function(r3, e2) {
|
|
25910
|
+
return i(r3, e2, this, true);
|
|
25911
|
+
}, n.from = function(r3, e2) {
|
|
25912
|
+
return i(r3, e2, this);
|
|
25913
|
+
};
|
|
25914
|
+
var d = function(r3) {
|
|
25915
|
+
return r3.$u ? t.utc() : t();
|
|
25916
|
+
};
|
|
25917
|
+
n.toNow = function(r3) {
|
|
25918
|
+
return this.to(d(this), r3);
|
|
25919
|
+
}, n.fromNow = function(r3) {
|
|
25920
|
+
return this.from(d(this), r3);
|
|
25921
|
+
};
|
|
25922
|
+
};
|
|
25923
|
+
}));
|
|
25924
|
+
})(relativeTime$2);
|
|
25925
|
+
return relativeTime$2.exports;
|
|
25926
|
+
}
|
|
25927
|
+
var relativeTimeExports = requireRelativeTime();
|
|
25928
|
+
const relativeTime = /* @__PURE__ */ getDefaultExportFromCjs(relativeTimeExports);
|
|
25878
25929
|
var utc$2 = { exports: {} };
|
|
25879
25930
|
var utc$1 = utc$2.exports;
|
|
25880
25931
|
var hasRequiredUtc;
|
|
@@ -25957,57 +26008,6 @@ function requireUtc() {
|
|
|
25957
26008
|
}
|
|
25958
26009
|
var utcExports = requireUtc();
|
|
25959
26010
|
const utc = /* @__PURE__ */ getDefaultExportFromCjs(utcExports);
|
|
25960
|
-
var relativeTime$2 = { exports: {} };
|
|
25961
|
-
var relativeTime$1 = relativeTime$2.exports;
|
|
25962
|
-
var hasRequiredRelativeTime;
|
|
25963
|
-
function requireRelativeTime() {
|
|
25964
|
-
if (hasRequiredRelativeTime) return relativeTime$2.exports;
|
|
25965
|
-
hasRequiredRelativeTime = 1;
|
|
25966
|
-
(function(module, exports) {
|
|
25967
|
-
!(function(r2, e) {
|
|
25968
|
-
module.exports = e();
|
|
25969
|
-
})(relativeTime$1, (function() {
|
|
25970
|
-
return function(r2, e, t) {
|
|
25971
|
-
r2 = r2 || {};
|
|
25972
|
-
var n = e.prototype, o = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" };
|
|
25973
|
-
function i(r3, e2, t2, o2) {
|
|
25974
|
-
return n.fromToBase(r3, e2, t2, o2);
|
|
25975
|
-
}
|
|
25976
|
-
t.en.relativeTime = o, n.fromToBase = function(e2, n2, i2, d2, u) {
|
|
25977
|
-
for (var f, a, s, l = i2.$locale().relativeTime || o, h = r2.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m = h.length, c = 0; c < m; c += 1) {
|
|
25978
|
-
var y = h[c];
|
|
25979
|
-
y.d && (f = d2 ? t(e2).diff(i2, y.d, true) : i2.diff(e2, y.d, true));
|
|
25980
|
-
var p = (r2.rounding || Math.round)(Math.abs(f));
|
|
25981
|
-
if (s = f > 0, p <= y.r || !y.r) {
|
|
25982
|
-
p <= 1 && c > 0 && (y = h[c - 1]);
|
|
25983
|
-
var v = l[y.l];
|
|
25984
|
-
u && (p = u("" + p)), a = "string" == typeof v ? v.replace("%d", p) : v(p, n2, y.l, s);
|
|
25985
|
-
break;
|
|
25986
|
-
}
|
|
25987
|
-
}
|
|
25988
|
-
if (n2) return a;
|
|
25989
|
-
var M = s ? l.future : l.past;
|
|
25990
|
-
return "function" == typeof M ? M(a) : M.replace("%s", a);
|
|
25991
|
-
}, n.to = function(r3, e2) {
|
|
25992
|
-
return i(r3, e2, this, true);
|
|
25993
|
-
}, n.from = function(r3, e2) {
|
|
25994
|
-
return i(r3, e2, this);
|
|
25995
|
-
};
|
|
25996
|
-
var d = function(r3) {
|
|
25997
|
-
return r3.$u ? t.utc() : t();
|
|
25998
|
-
};
|
|
25999
|
-
n.toNow = function(r3) {
|
|
26000
|
-
return this.to(d(this), r3);
|
|
26001
|
-
}, n.fromNow = function(r3) {
|
|
26002
|
-
return this.from(d(this), r3);
|
|
26003
|
-
};
|
|
26004
|
-
};
|
|
26005
|
-
}));
|
|
26006
|
-
})(relativeTime$2);
|
|
26007
|
-
return relativeTime$2.exports;
|
|
26008
|
-
}
|
|
26009
|
-
var relativeTimeExports = requireRelativeTime();
|
|
26010
|
-
const relativeTime = /* @__PURE__ */ getDefaultExportFromCjs(relativeTimeExports);
|
|
26011
26011
|
var timezone$2 = { exports: {} };
|
|
26012
26012
|
var timezone$1 = timezone$2.exports;
|
|
26013
26013
|
var hasRequiredTimezone;
|
|
@@ -75208,6 +75208,220 @@ const parseDateMacroToTimestamp = (macroStr) => {
|
|
|
75208
75208
|
}
|
|
75209
75209
|
return { fromDate: start2.unix(), toDate: end2.unix() };
|
|
75210
75210
|
};
|
|
75211
|
+
const createDefaultState = (fields) => {
|
|
75212
|
+
return fields.reduce((acc, field) => {
|
|
75213
|
+
acc[field.key] = field.defaultValue;
|
|
75214
|
+
return acc;
|
|
75215
|
+
}, {});
|
|
75216
|
+
};
|
|
75217
|
+
const createRowsFromValue = (fields, value) => {
|
|
75218
|
+
const activeRows = fields.filter((field) => ((value == null ? void 0 : value[field.key]) ?? field.defaultValue) !== field.defaultValue).map((field) => ({
|
|
75219
|
+
id: generateId(),
|
|
75220
|
+
fieldKey: field.key,
|
|
75221
|
+
value: (value == null ? void 0 : value[field.key]) ?? field.defaultValue
|
|
75222
|
+
}));
|
|
75223
|
+
if (activeRows.length > 0) return activeRows;
|
|
75224
|
+
const firstField = fields[0];
|
|
75225
|
+
if (!firstField) return [];
|
|
75226
|
+
return [
|
|
75227
|
+
{
|
|
75228
|
+
id: generateId(),
|
|
75229
|
+
fieldKey: firstField.key,
|
|
75230
|
+
value: (value == null ? void 0 : value[firstField.key]) ?? firstField.defaultValue
|
|
75231
|
+
}
|
|
75232
|
+
];
|
|
75233
|
+
};
|
|
75234
|
+
const AdvancedFilterDialog = ({
|
|
75235
|
+
open: open2,
|
|
75236
|
+
title = "Tùy chỉnh bộ lọc",
|
|
75237
|
+
fields,
|
|
75238
|
+
value,
|
|
75239
|
+
anchorEl,
|
|
75240
|
+
offset: offset2,
|
|
75241
|
+
onClose,
|
|
75242
|
+
onApply
|
|
75243
|
+
}) => {
|
|
75244
|
+
const defaults = useMemo(() => createDefaultState(fields), [fields]);
|
|
75245
|
+
const fieldOptions = useMemo(() => fields.map((field) => ({ label: field.label, value: field.key })), [fields]);
|
|
75246
|
+
const [rows, setRows] = useState(() => createRowsFromValue(fields, value));
|
|
75247
|
+
const [draggingIndex, setDraggingIndex] = useState(null);
|
|
75248
|
+
useEffect(() => {
|
|
75249
|
+
if (open2) {
|
|
75250
|
+
setRows(createRowsFromValue(fields, value));
|
|
75251
|
+
setDraggingIndex(null);
|
|
75252
|
+
}
|
|
75253
|
+
}, [fields, open2, value]);
|
|
75254
|
+
const handleReset = () => {
|
|
75255
|
+
const firstField = fields[0];
|
|
75256
|
+
if (!firstField) {
|
|
75257
|
+
setRows([]);
|
|
75258
|
+
return;
|
|
75259
|
+
}
|
|
75260
|
+
setRows([{ id: generateId(), fieldKey: firstField.key, value: firstField.defaultValue }]);
|
|
75261
|
+
};
|
|
75262
|
+
const handleRemove = (index) => {
|
|
75263
|
+
setRows((prev) => {
|
|
75264
|
+
const next = prev.filter((_, currentIndex) => currentIndex !== index);
|
|
75265
|
+
if (next.length > 0) return next;
|
|
75266
|
+
const firstField = fields[0];
|
|
75267
|
+
if (!firstField) return [];
|
|
75268
|
+
return [{ id: generateId(), fieldKey: firstField.key, value: firstField.defaultValue }];
|
|
75269
|
+
});
|
|
75270
|
+
};
|
|
75271
|
+
const handleAdd = () => {
|
|
75272
|
+
setRows((prev) => {
|
|
75273
|
+
const usedFieldKeys = new Set(prev.map((row) => row.fieldKey));
|
|
75274
|
+
const nextField = fields.find((field) => !usedFieldKeys.has(field.key));
|
|
75275
|
+
if (!nextField) return prev;
|
|
75276
|
+
return [...prev, { id: generateId(), fieldKey: nextField.key, value: nextField.defaultValue }];
|
|
75277
|
+
});
|
|
75278
|
+
};
|
|
75279
|
+
const handleDrop = (dropIndex) => {
|
|
75280
|
+
if (draggingIndex === null || dropIndex === draggingIndex) return;
|
|
75281
|
+
setRows((prev) => {
|
|
75282
|
+
const next = [...prev];
|
|
75283
|
+
const [movedRow] = next.splice(draggingIndex, 1);
|
|
75284
|
+
next.splice(dropIndex, 0, movedRow);
|
|
75285
|
+
return next;
|
|
75286
|
+
});
|
|
75287
|
+
setDraggingIndex(null);
|
|
75288
|
+
};
|
|
75289
|
+
const handleApply = () => {
|
|
75290
|
+
const mergedValue = { ...defaults };
|
|
75291
|
+
rows.forEach((row) => {
|
|
75292
|
+
if (row.fieldKey) mergedValue[row.fieldKey] = row.value;
|
|
75293
|
+
});
|
|
75294
|
+
onApply(mergedValue);
|
|
75295
|
+
onClose();
|
|
75296
|
+
};
|
|
75297
|
+
const canAddRow = rows.length < fields.length;
|
|
75298
|
+
return /* @__PURE__ */ jsx(
|
|
75299
|
+
Popover$1,
|
|
75300
|
+
{
|
|
75301
|
+
open: open2,
|
|
75302
|
+
anchorEl,
|
|
75303
|
+
onClose,
|
|
75304
|
+
disableScrollLock: true,
|
|
75305
|
+
anchorOrigin: { vertical: "bottom", horizontal: "left" },
|
|
75306
|
+
transformOrigin: { vertical: "top", horizontal: "left" },
|
|
75307
|
+
slotProps: {
|
|
75308
|
+
paper: {
|
|
75309
|
+
sx: {
|
|
75310
|
+
mt: `${(offset2 == null ? void 0 : offset2.y) ?? 8}px`,
|
|
75311
|
+
ml: `${(offset2 == null ? void 0 : offset2.x) ?? 0}px`,
|
|
75312
|
+
minWidth: 320,
|
|
75313
|
+
maxWidth: "calc(100vw - 48px)",
|
|
75314
|
+
borderRadius: BORDER_RADIUS_ELEMENT_MIDDLE,
|
|
75315
|
+
border: `1px solid ${NEUTRAL[300]}`,
|
|
75316
|
+
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.12)",
|
|
75317
|
+
overflow: "hidden"
|
|
75318
|
+
}
|
|
75319
|
+
}
|
|
75320
|
+
},
|
|
75321
|
+
children: /* @__PURE__ */ jsx(Box, { sx: { backgroundColor: WHITE[50], padding: 2 }, children: /* @__PURE__ */ jsxs(StackAlignCenter, { sx: { alignItems: "stretch", gap: 2 }, children: [
|
|
75322
|
+
/* @__PURE__ */ jsxs(StackRowAlignCenterJustBetween, { sx: { gap: 1 }, children: [
|
|
75323
|
+
/* @__PURE__ */ jsx(Typography$1, { sx: { ...TYPOGRAPHY.textMd.semiBold }, children: title }),
|
|
75324
|
+
/* @__PURE__ */ jsx(IconButton$1, { onClick: onClose, sx: { padding: PADDING_GAP_ITEM_SMALL }, children: /* @__PURE__ */ jsx(IconElement, { icon: "close" }) })
|
|
75325
|
+
] }),
|
|
75326
|
+
/* @__PURE__ */ jsx(StackAlignCenter, { sx: { alignItems: "stretch", gap: 1.25 }, children: rows.map((row, index) => {
|
|
75327
|
+
const field = fields.find((currentField) => currentField.key === row.fieldKey);
|
|
75328
|
+
if (!field) return null;
|
|
75329
|
+
const usedFieldKeys = new Set(rows.map((currentRow) => currentRow.fieldKey));
|
|
75330
|
+
const selectableFieldOptions = fieldOptions.filter(
|
|
75331
|
+
(option) => option.value === row.fieldKey || !usedFieldKeys.has(option.value)
|
|
75332
|
+
);
|
|
75333
|
+
return /* @__PURE__ */ jsxs(
|
|
75334
|
+
StackRowAlignCenter,
|
|
75335
|
+
{
|
|
75336
|
+
onDragOver: (event) => event.preventDefault(),
|
|
75337
|
+
onDrop: () => handleDrop(index),
|
|
75338
|
+
sx: { gap: 1, alignItems: "flex-end" },
|
|
75339
|
+
children: [
|
|
75340
|
+
/* @__PURE__ */ jsx(
|
|
75341
|
+
Box,
|
|
75342
|
+
{
|
|
75343
|
+
draggable: true,
|
|
75344
|
+
onDragStart: () => setDraggingIndex(index),
|
|
75345
|
+
onDragEnd: () => setDraggingIndex(null),
|
|
75346
|
+
sx: { paddingBottom: "10px", cursor: "grab" },
|
|
75347
|
+
children: /* @__PURE__ */ jsx(IconElement, { icon: "drag_indicator", sx: { color: NEUTRAL[500] } })
|
|
75348
|
+
}
|
|
75349
|
+
),
|
|
75350
|
+
/* @__PURE__ */ jsx(Box, { sx: { flex: 1, minWidth: 220 }, children: /* @__PURE__ */ jsx(
|
|
75351
|
+
TextFieldSelectElement,
|
|
75352
|
+
{
|
|
75353
|
+
label: "",
|
|
75354
|
+
value: row.fieldKey,
|
|
75355
|
+
options: selectableFieldOptions,
|
|
75356
|
+
placeholder: "",
|
|
75357
|
+
onChange: (event) => {
|
|
75358
|
+
const nextFieldKey = event.target.value;
|
|
75359
|
+
const nextField = fields.find((currentField) => currentField.key === nextFieldKey);
|
|
75360
|
+
if (!nextField) return;
|
|
75361
|
+
setRows(
|
|
75362
|
+
(prev) => prev.map(
|
|
75363
|
+
(currentRow, currentIndex) => currentIndex === index ? {
|
|
75364
|
+
...currentRow,
|
|
75365
|
+
fieldKey: nextFieldKey,
|
|
75366
|
+
value: nextField.defaultValue
|
|
75367
|
+
} : currentRow
|
|
75368
|
+
)
|
|
75369
|
+
);
|
|
75370
|
+
}
|
|
75371
|
+
}
|
|
75372
|
+
) }),
|
|
75373
|
+
/* @__PURE__ */ jsx(Box, { sx: { flex: 1, minWidth: 220 }, children: /* @__PURE__ */ jsx(
|
|
75374
|
+
TextFieldSelectElement,
|
|
75375
|
+
{
|
|
75376
|
+
label: "",
|
|
75377
|
+
value: row.value ?? field.defaultValue,
|
|
75378
|
+
options: field.options,
|
|
75379
|
+
placeholder: "Tất cả",
|
|
75380
|
+
onChange: (event) => {
|
|
75381
|
+
const nextValue = event.target.value;
|
|
75382
|
+
setRows(
|
|
75383
|
+
(prev) => prev.map(
|
|
75384
|
+
(currentRow, currentIndex) => currentIndex === index ? { ...currentRow, value: nextValue } : currentRow
|
|
75385
|
+
)
|
|
75386
|
+
);
|
|
75387
|
+
}
|
|
75388
|
+
}
|
|
75389
|
+
) }),
|
|
75390
|
+
/* @__PURE__ */ jsx(IconButton$1, { onClick: () => handleRemove(index), children: /* @__PURE__ */ jsx(IconElement, { icon: "delete_outline" }) })
|
|
75391
|
+
]
|
|
75392
|
+
},
|
|
75393
|
+
row.id
|
|
75394
|
+
);
|
|
75395
|
+
}) }),
|
|
75396
|
+
canAddRow && /* @__PURE__ */ jsx(
|
|
75397
|
+
ButtonElement,
|
|
75398
|
+
{
|
|
75399
|
+
content: "Thêm điều kiện",
|
|
75400
|
+
onClick: handleAdd,
|
|
75401
|
+
startIcon: "add",
|
|
75402
|
+
variant: "text",
|
|
75403
|
+
sx: { color: PRIMARY[500], minWidth: 0, paddingX: 0 }
|
|
75404
|
+
}
|
|
75405
|
+
),
|
|
75406
|
+
/* @__PURE__ */ jsxs(StackRowAlignCenterJustBetween, { sx: { marginTop: 1 }, children: [
|
|
75407
|
+
/* @__PURE__ */ jsx(
|
|
75408
|
+
ButtonElement,
|
|
75409
|
+
{
|
|
75410
|
+
content: "Mặc định",
|
|
75411
|
+
onClick: handleReset,
|
|
75412
|
+
variant: "text",
|
|
75413
|
+
sx: { color: PRIMARY[500], minWidth: 0, paddingX: 0 }
|
|
75414
|
+
}
|
|
75415
|
+
),
|
|
75416
|
+
/* @__PURE__ */ jsxs(StackRowAlignCenter, { sx: { gap: 1 }, children: [
|
|
75417
|
+
/* @__PURE__ */ jsx(ButtonElement, { onClick: onClose, variant: "outlined", content: "Hủy" }),
|
|
75418
|
+
/* @__PURE__ */ jsx(ButtonElement, { onClick: handleApply, variant: "contained", content: "Áp dụng" })
|
|
75419
|
+
] })
|
|
75420
|
+
] })
|
|
75421
|
+
] }) })
|
|
75422
|
+
}
|
|
75423
|
+
);
|
|
75424
|
+
};
|
|
75211
75425
|
const FilterValueInput = ({ field, rowValue, onChange }) => {
|
|
75212
75426
|
switch (field.type) {
|
|
75213
75427
|
case "select":
|
|
@@ -75454,7 +75668,7 @@ const AdvancedOperatorFilterDialog = ({
|
|
|
75454
75668
|
placeholder: "",
|
|
75455
75669
|
onChange: (e) => {
|
|
75456
75670
|
const nextOp = e.target.value;
|
|
75457
|
-
|
|
75671
|
+
const nextValue = row.value;
|
|
75458
75672
|
handleUpdateRow(index, { operator: nextOp, value: nextValue });
|
|
75459
75673
|
},
|
|
75460
75674
|
sx: { width: OPERATOR_WIDTH }
|
|
@@ -78425,6 +78639,7 @@ const SearchDropdownComponent = ({
|
|
|
78425
78639
|
};
|
|
78426
78640
|
export {
|
|
78427
78641
|
apps_const as APPS,
|
|
78642
|
+
AdvancedFilterDialog,
|
|
78428
78643
|
AdvancedOperatorFilterDialog,
|
|
78429
78644
|
AppGrid,
|
|
78430
78645
|
AppGridItem,
|