@hitachivantara/uikit-react-core 6.2.0 → 6.4.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.
@@ -8,21 +8,17 @@ const { staticClasses, useClasses } = createClasses("HvPagination", {
8
8
  position: "relative",
9
9
  zIndex: 1,
10
10
  display: "flex",
11
- justifyContent: "center",
12
- alignItems: "stretch",
11
+ justifyContent: "space-between",
12
+ alignItems: "center",
13
13
  flexWrap: "wrap",
14
14
  marginTop: theme.space.sm,
15
- ...theme.typography.caption2
15
+ ...theme.typography.caption1
16
16
  },
17
17
  /** Styles applied to the page size selector container. */
18
18
  pageSizeOptions: {
19
19
  display: "flex",
20
- position: "absolute",
21
20
  gap: theme.space.xs,
22
- height: 24,
23
- top: "50%",
24
- transform: "translateY(-50%)",
25
- left: "0"
21
+ height: 24
26
22
  },
27
23
  pageSizeHeader: {
28
24
  height: 24,
@@ -55,8 +51,9 @@ const { staticClasses, useClasses } = createClasses("HvPagination", {
55
51
  pageNavigator: {
56
52
  display: "flex",
57
53
  alignItems: "center",
58
- height: "32px",
59
- gap: 8
54
+ justifyContent: "center",
55
+ flex: 1,
56
+ gap: theme.space.xs
60
57
  },
61
58
  /** Styles applied to each navigation `HvButton` icon container. */
62
59
  iconContainer: {
@@ -66,22 +63,17 @@ const { staticClasses, useClasses } = createClasses("HvPagination", {
66
63
  icon: {},
67
64
  /** Styles applied to the central page information container. */
68
65
  pageInfo: {
69
- display: "inline-block",
66
+ display: "inline-flex",
67
+ gap: 4,
70
68
  whiteSpace: "nowrap",
71
- height: "32px",
72
- lineHeight: "32px"
69
+ alignItems: "center"
73
70
  },
74
71
  /** Styles applied to the page selector input container. */
75
72
  pageJump: {
76
- marginRight: 4,
77
73
  width: 24,
78
74
  minWidth: 24,
79
- maxWidth: theme.spacing(8),
80
75
  backgroundColor: "transparent",
81
76
  height: "24px",
82
- "&:focus, &:focus-within, &:hover": {
83
- backgroundColor: theme.colors.bgHover
84
- },
85
77
  "&, & $pageSizeInput": {
86
78
  fontSize: "inherit",
87
79
  lineHeight: "inherit"
@@ -89,19 +81,9 @@ const { staticClasses, useClasses } = createClasses("HvPagination", {
89
81
  },
90
82
  /** Styles passed down to the page selector Input component as `input`. */
91
83
  pageSizeInput: {
92
- paddingLeft: 4,
93
- paddingRight: 4,
94
84
  margin: 0,
95
85
  textAlign: "center",
96
- borderRadius: theme.radii.base,
97
- MozAppearance: "textfield",
98
- "&:focus": {
99
- padding: 0,
100
- backgroundColor: theme.colors.bgHover
101
- },
102
- "&:hover": {
103
- cursor: "pointer"
104
- }
86
+ MozAppearance: "textfield"
105
87
  }
106
88
  });
107
89
  export {
@@ -36,7 +36,7 @@ const HvSection = forwardRef(
36
36
  {
37
37
  ref,
38
38
  className: cx(classes.root, className, {
39
- [classes.raisedHeader]: raisedHeader && isOpen
39
+ [classes.raisedHeader]: hasHeader && raisedHeader && isOpen
40
40
  }),
41
41
  ...others,
42
42
  children: [
@@ -85,7 +85,7 @@ const HvSection = forwardRef(
85
85
  "div",
86
86
  {
87
87
  ref: contentRef,
88
- hidden: !isOpen,
88
+ hidden: expandable && !isOpen,
89
89
  className: cx(classes.content, {
90
90
  [classes.hidden]: expandable && !isOpen,
91
91
  [classes.hasHeader]: hasHeader
@@ -15,10 +15,10 @@ function getSortedBreakpoints(breakpoints) {
15
15
  return breakpoints;
16
16
  }
17
17
  const property = "maxWidth" in breakpoints[0] ? "maxWidth" : "minWidth";
18
- const sorted = [...breakpoints].sort(
18
+ const sorted = breakpoints.toSorted(
19
19
  (a, b) => getSize(b[property]) - getSize(a[property])
20
20
  );
21
- return property === "minWidth" ? sorted.reverse() : sorted;
21
+ return property === "minWidth" ? sorted.toReversed() : sorted;
22
22
  }
23
23
  const getContainerStyle = (breakpoints, spacing = "sm", cols = 1) => {
24
24
  return {
@@ -13,14 +13,14 @@ const { staticClasses, useClasses } = createClasses("HvStatusIcon", {
13
13
  display: "inline-flex",
14
14
  lineHeight: 0,
15
15
  flexShrink: 0,
16
- padding: theme.space.xxs,
17
16
  borderRadius: theme.radii.base,
18
17
  "--icsize": "auto",
19
18
  ":where([data-size=md])": { borderRadius: theme.radii.round },
20
19
  ":where([data-size=lg])": { borderRadius: theme.radii.large },
21
20
  ":where([data-size=xl])": { borderRadius: theme.radii.large },
22
21
  ":where([data-type=full])": {
23
- outline: "1px solid currentcolor"
22
+ outline: "1px solid currentcolor",
23
+ padding: theme.space.xxs
24
24
  },
25
25
  ...Object.fromEntries(
26
26
  Object.entries(notificationMap).map(([variant, color]) => [
@@ -7,7 +7,7 @@ const { staticClasses, useClasses } = createClasses("HvTableCell", {
7
7
  alignContent: "inherit",
8
8
  textAlign: "left",
9
9
  borderColor: theme.colors.border,
10
- padding: `calc(${theme.space.xs} - 2px ) ${theme.space.xs} calc(${theme.space.xs} - 3px ) ${theme.spacing(4)}`,
10
+ padding: theme.spacing(0, "sm"),
11
11
  borderBottomWidth: 1
12
12
  },
13
13
  /** Styles applied to the cell when it's in the table head. */
@@ -7,9 +7,9 @@ import TableContext from "../TableContext.js";
7
7
  import { TableSectionContext } from "../TableSectionContext.js";
8
8
  import { useClasses } from "./TableHeader.styles.js";
9
9
  import { staticClasses } from "./TableHeader.styles.js";
10
- import { getSortIconName, isParagraph } from "./utils.js";
11
- import { HvButton } from "../../Button/Button.js";
10
+ import { isParagraph, getSortIconName } from "./utils.js";
12
11
  import { HvTypography } from "../../Typography/Typography.js";
12
+ import { HvButtonBase } from "../../ButtonBase/ButtonBase.js";
13
13
  const defaultComponent = "th";
14
14
  const HvTableHeader = forwardRef(
15
15
  function HvTableHeader2(props, ref) {
@@ -80,40 +80,40 @@ const HvTableHeader = forwardRef(
80
80
  /* @__PURE__ */ jsxs(
81
81
  "div",
82
82
  {
83
+ "data-align": align !== "inherit" ? align : void 0,
83
84
  className: cx(
84
85
  classes.headerContent,
85
86
  align !== "inherit" && classes[`alignFlex${capitalize(align)}`]
86
87
  ),
87
88
  children: [
89
+ /* @__PURE__ */ jsx(
90
+ HvTypography,
91
+ {
92
+ component: "div",
93
+ className: cx(classes.headerText, {
94
+ [classes.headerParagraph]: paragraph,
95
+ [classes.sortableHeaderText]: sortable
96
+ }),
97
+ variant: "label",
98
+ ...headerTextProps,
99
+ children
100
+ }
101
+ ),
88
102
  isHeadCell && sortable && /* @__PURE__ */ jsx(
89
- HvButton,
103
+ HvButtonBase,
90
104
  {
91
105
  className: classes.sortButton,
92
- icon: true,
93
106
  "aria-label": "Sort",
94
107
  ...sortButtonProps,
95
108
  children: /* @__PURE__ */ jsx(
96
109
  HvIcon,
97
110
  {
111
+ compact: true,
98
112
  name: getSortIconName(sorted && sortDirection),
99
113
  className: classes.sortIcon
100
114
  }
101
115
  )
102
116
  }
103
- ),
104
- /* @__PURE__ */ jsx(
105
- HvTypography,
106
- {
107
- component: "div",
108
- className: cx({
109
- [classes.headerText]: !paragraph,
110
- [classes.headerParagraph]: paragraph,
111
- [classes.sortableHeaderText]: sortable
112
- }),
113
- variant: "label",
114
- ...headerTextProps,
115
- children
116
- }
117
117
  )
118
118
  ]
119
119
  }
@@ -2,21 +2,18 @@ import { createClasses } from "@hitachivantara/uikit-react-utils";
2
2
  import { theme } from "@hitachivantara/uikit-styles";
3
3
  const { staticClasses, useClasses } = createClasses("HvTableHeader", {
4
4
  root: {
5
- "--first-row-cell-height": "52px",
5
+ "--first-row-cell-height": "32px",
6
6
  "--cell-height": "32px",
7
7
  height: "var(--cell-height)",
8
8
  verticalAlign: "inherit",
9
9
  alignContent: "inherit",
10
10
  textAlign: "left",
11
- padding: theme.spacing(0, 1, 0, 4),
11
+ padding: theme.spacing(0, "sm"),
12
12
  borderColor: theme.colors.border,
13
13
  borderBottomWidth: 1
14
14
  },
15
15
  head: {
16
- paddingTop: 8,
17
- verticalAlign: "top",
18
- alignContent: "start",
19
- ...theme.typography.label,
16
+ fontWeight: theme.fontWeights.semibold,
20
17
  backgroundColor: theme.colors.bgContainer,
21
18
  borderBottomWidth: 1,
22
19
  "*:first-of-type > &": {
@@ -31,14 +28,10 @@ const { staticClasses, useClasses } = createClasses("HvTableHeader", {
31
28
  }
32
29
  },
33
30
  "&$sortable": {
34
- verticalAlign: "initial",
35
- alignContent: "initial",
36
- paddingTop: 0,
37
- paddingLeft: 0,
38
31
  cursor: "pointer",
39
32
  ":hover, :focus-within": {
40
33
  backgroundColor: theme.colors.bgHover,
41
- "& $sortIcon": {
34
+ "& $sortButton": {
42
35
  opacity: 1
43
36
  }
44
37
  }
@@ -49,9 +42,6 @@ const { staticClasses, useClasses } = createClasses("HvTableHeader", {
49
42
  ...theme.typography.body,
50
43
  ":where($sorted)": {
51
44
  backgroundColor: theme.alpha("bgContainer", 0.4)
52
- },
53
- "&$sortable:not($variantNone)": {
54
- paddingLeft: 32
55
45
  }
56
46
  },
57
47
  footer: {},
@@ -78,31 +68,40 @@ const { staticClasses, useClasses } = createClasses("HvTableHeader", {
78
68
  borderLeftWidth: 0
79
69
  }
80
70
  },
81
- headerContent: { display: "flex", alignItems: "flex-start", width: "100%" },
71
+ headerContent: {
72
+ display: "flex",
73
+ alignItems: "center",
74
+ gap: theme.space.xxs,
75
+ width: "100%"
76
+ },
82
77
  headerText: { overflow: "hidden", textOverflow: "ellipsis" },
83
- headerParagraph: { overflow: "hidden", display: "-webkit-box" },
84
- sortableHeaderText: { paddingTop: "8px" },
78
+ headerParagraph: { textOverflow: "inherit", display: "-webkit-box" },
79
+ /** @deprecated use `sortable: &$headerText` */
80
+ sortableHeaderText: {},
85
81
  sorted: {
86
- "& $sortIcon": {
82
+ "& $sortButton": {
87
83
  opacity: 1
88
84
  }
89
85
  },
90
86
  sortable: {},
91
87
  sortButton: {
88
+ opacity: 0,
92
89
  paddingLeft: 4,
93
90
  paddingTop: 4,
94
- ":focus-visible": {
91
+ ":focus-visible,:hover": {
95
92
  boxShadow: "none",
96
93
  backgroundColor: "transparent"
97
94
  }
98
95
  },
99
- sortIcon: { opacity: 0 },
96
+ /** @deprecated use `classes.sortButton` instead */
97
+ sortIcon: {},
98
+ // TODO: deprecate & merge these classes in favour of data-align
100
99
  alignLeft: { textAlign: "left" },
101
100
  alignRight: { textAlign: "right", flexDirection: "row-reverse" },
102
101
  alignCenter: { textAlign: "center" },
103
102
  alignJustify: { textAlign: "justify" },
104
103
  alignFlexLeft: { justifyContent: "flex-start" },
105
- alignFlexRight: { justifyContent: "flex-end" },
104
+ alignFlexRight: { flexDirection: "row-reverse" },
106
105
  alignFlexCenter: { justifyContent: "center" },
107
106
  alignFlexJustify: { textAlign: "justify" },
108
107
  variantCheckbox: {
@@ -1,21 +1,18 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { useDefaultProps } from "@hitachivantara/uikit-react-utils";
4
- import { useUniqueId } from "../../hooks/useUniqueId.js";
5
4
  import { useClasses } from "./TableSection.styles.js";
6
5
  import { staticClasses } from "./TableSection.styles.js";
7
6
  import { HvSection } from "../../Section/Section.js";
8
7
  const HvTableSection = forwardRef(
9
8
  function HvTableSection2(props, ref) {
10
9
  const {
11
- id,
12
10
  classes: classesProp,
13
11
  children,
14
12
  ...others
15
13
  } = useDefaultProps("HvTableSection", props);
16
14
  const { classes } = useClasses(classesProp);
17
- const elementId = useUniqueId(id);
18
- return /* @__PURE__ */ jsx(HvSection, { id: elementId, ref, classes, ...others, children });
15
+ return /* @__PURE__ */ jsx(HvSection, { ref, classes, ...others, children });
19
16
  }
20
17
  );
21
18
  export {
@@ -55,27 +55,30 @@ function hvExpandColumn(col, expandRowButtonAriaLabel, collapseRowButtonAriaLabe
55
55
  const { value, row } = cellProps;
56
56
  const expandedProps = row.getToggleRowExpandedProps?.();
57
57
  const hasContent = getCanRowExpand?.(row) ?? true;
58
- return /* @__PURE__ */ jsx(ClassNames, { children: ({ css }) => /* @__PURE__ */ jsxs(Fragment, { children: [
59
- hasContent && /* @__PURE__ */ jsx(
60
- HvButton,
61
- {
62
- icon: true,
63
- "aria-label": row.isExpanded ? collapseRowButtonAriaLabel : expandRowButtonAriaLabel,
64
- "aria-expanded": row.isExpanded,
65
- onClick: expandedProps?.onClick,
66
- classes: {
67
- root: css({
68
- position: "absolute",
69
- left: 0,
70
- top: "50%",
71
- transform: "translateY(-50%)"
72
- })
73
- },
74
- children: row.isExpanded ? ExpandedIcon : CollapsedIcon
75
- }
76
- ),
77
- /* @__PURE__ */ jsx(HvOverflowTooltip, { data: hvStringFallback(value) })
78
- ] }) });
58
+ return /* @__PURE__ */ jsx(ClassNames, { children: ({ css }) => /* @__PURE__ */ jsxs(
59
+ "div",
60
+ {
61
+ className: css({
62
+ display: "flex",
63
+ alignItems: "center",
64
+ position: "relative",
65
+ left: -16
66
+ }),
67
+ children: [
68
+ hasContent && /* @__PURE__ */ jsx(
69
+ HvButton,
70
+ {
71
+ icon: true,
72
+ "aria-label": row.isExpanded ? collapseRowButtonAriaLabel : expandRowButtonAriaLabel,
73
+ "aria-expanded": row.isExpanded,
74
+ onClick: expandedProps?.onClick,
75
+ children: row.isExpanded ? ExpandedIcon : CollapsedIcon
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsx(HvOverflowTooltip, { data: hvStringFallback(value) })
79
+ ]
80
+ }
81
+ ) });
79
82
  },
80
83
  sortType: "alphanumeric",
81
84
  cellStyle: {
@@ -1,31 +1,15 @@
1
- const isDateInPeriod = (timeAgoMs, period, referenceDate = /* @__PURE__ */ new Date()) => {
2
- const date = new Date(timeAgoMs);
3
- const startOfToday = new Date(referenceDate);
4
- startOfToday.setHours(0, 0, 0, 0);
5
- const startOfTomorrow = new Date(startOfToday);
6
- startOfTomorrow.setDate(startOfToday.getDate() + 1);
7
- const startOfDayAfterTomorrow = new Date(startOfTomorrow);
8
- startOfDayAfterTomorrow.setDate(startOfTomorrow.getDate() + 1);
9
- if (period === "tomorrow") {
10
- return date >= startOfTomorrow && date < startOfDayAfterTomorrow;
11
- }
12
- if (period === "afterTomorrow") {
13
- return date >= startOfDayAfterTomorrow;
14
- }
15
- return false;
16
- };
17
1
  const formatTimeAgo = (timeAgoMs, locale, showSeconds = false, referenceDate = /* @__PURE__ */ new Date()) => {
18
2
  const relFormatter = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
19
3
  const dayFormatter = new Intl.DateTimeFormat(locale, {
20
4
  hour: "numeric",
21
5
  minute: "numeric",
22
- second: showSeconds ? "numeric" : void 0
6
+ ...showSeconds && { second: "numeric" }
23
7
  });
24
8
  const weekFormatter = new Intl.DateTimeFormat(locale, {
25
9
  weekday: "short",
26
10
  hour: "numeric",
27
11
  minute: "numeric",
28
- second: showSeconds ? "numeric" : void 0
12
+ ...showSeconds && { second: "numeric" }
29
13
  });
30
14
  const fullFormatter = new Intl.DateTimeFormat(locale, {
31
15
  year: "numeric",
@@ -33,33 +17,43 @@ const formatTimeAgo = (timeAgoMs, locale, showSeconds = false, referenceDate = /
33
17
  day: "numeric",
34
18
  hour: "numeric",
35
19
  minute: "numeric",
36
- second: showSeconds ? "numeric" : void 0
20
+ ...showSeconds && { second: "numeric" }
37
21
  });
38
22
  const date = new Date(timeAgoMs);
39
- const secsInDay = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
40
- const secsInWeek = date.getDay() * 86400 + secsInDay;
41
23
  const secsAgo = Math.floor((referenceDate.getTime() - timeAgoMs) / 1e3);
42
24
  const minsAgo = Math.floor(secsAgo / 60);
25
+ const getStartOfDay = (offset) => {
26
+ const d = new Date(referenceDate);
27
+ d.setHours(0, 0, 0, 0);
28
+ d.setDate(d.getDate() + offset);
29
+ return d;
30
+ };
31
+ const startOfYesterday = getStartOfDay(-1);
32
+ const startOfToday = getStartOfDay(0);
33
+ const startOfTomorrow = getStartOfDay(1);
34
+ const startOfDayAfterTomorrow = getStartOfDay(2);
35
+ const secsInDay = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
36
+ const secsInWeek = date.getDay() * 86400 + secsInDay;
43
37
  switch (true) {
44
- case isDateInPeriod(timeAgoMs, "afterTomorrow", referenceDate):
38
+ case date >= startOfDayAfterTomorrow:
45
39
  return fullFormatter.format(date);
46
- case isDateInPeriod(timeAgoMs, "tomorrow", referenceDate):
40
+ case date >= startOfTomorrow:
47
41
  return `${relFormatter.format(1, "days")}, ${dayFormatter.format(date)}`;
48
42
  case minsAgo < -60:
49
43
  return `${relFormatter.format(0, "days")}, ${dayFormatter.format(date)}`;
50
44
  case minsAgo < -2:
51
45
  return relFormatter.format(-minsAgo, "minutes");
52
46
  case secsAgo < 0:
53
- return `${relFormatter.format(Math.abs(secsAgo), "seconds")}`;
47
+ return relFormatter.format(Math.abs(secsAgo), "seconds");
54
48
  case secsAgo < 20:
55
49
  return relFormatter.format(0, "seconds");
56
50
  case minsAgo < 2:
57
51
  return relFormatter.format(-secsAgo, "seconds");
58
52
  case minsAgo < 60:
59
53
  return relFormatter.format(-minsAgo, "minutes");
60
- case secsAgo < secsInDay:
54
+ case date >= startOfToday:
61
55
  return `${relFormatter.format(0, "days")}, ${dayFormatter.format(date)}`;
62
- case secsAgo < secsInDay + 86400:
56
+ case date >= startOfYesterday:
63
57
  return `${relFormatter.format(-1, "days")}, ${dayFormatter.format(date)}`;
64
58
  case secsAgo < secsInWeek:
65
59
  return weekFormatter.format(date);
@@ -102,7 +102,7 @@ const HvVerticalNavigationTreeView = forwardRef(function HvVerticalNavigationTre
102
102
  );
103
103
  const getChildrenIds = (id) => Object.keys(nodeMap.current).map((key) => {
104
104
  return nodeMap.current[key];
105
- }).filter((node) => node.parentId === id).sort((a, b) => a.index - b.index).map((child) => child.id);
105
+ }).filter((node) => node.parentId === id).toSorted((a, b) => a.index - b.index).map((child) => child.id);
106
106
  const getNavigableChildrenIds = useCallback(
107
107
  (id) => {
108
108
  let childrenIds = getChildrenIds(id);
@@ -134,7 +134,8 @@ const { staticClasses, useClasses } = createClasses(
134
134
  marginLeft: "auto"
135
135
  },
136
136
  [`&& .${staticClasses$1.root}`]: {
137
- fontSize: "15px"
137
+ fontSize: "15px",
138
+ borderColor: "transparent"
138
139
  }
139
140
  }
140
141
  }
@@ -3,7 +3,9 @@ import useMediaQuery from "@mui/material/useMediaQuery";
3
3
  import { theme } from "@hitachivantara/uikit-styles";
4
4
  const useWidth = () => {
5
5
  const muiTheme = useTheme();
6
- const keys = Object.keys(theme.breakpoints.values).reverse();
6
+ const keys = Object.keys(
7
+ theme.breakpoints.values
8
+ ).toReversed();
7
9
  return keys.reduce((output, key) => {
8
10
  const matches = useMediaQuery(muiTheme.breakpoints.up(key));
9
11
  return !output && matches ? key : output;
package/dist/index.d.ts CHANGED
@@ -1707,6 +1707,8 @@ export declare interface HvBreadCrumbProps extends HvBaseProps<HTMLDivElement, "
1707
1707
  onClick?: (event: React.MouseEvent<HTMLElement>, data: any) => void;
1708
1708
  /** Props passed down to the DropDownMenu sub-menu component. */
1709
1709
  dropDownMenuProps?: Partial<HvDropDownMenuProps>;
1710
+ /** Separator element between breadcrumb items. */
1711
+ separator?: React.ReactNode;
1710
1712
  /** A Jss Object used to override or extend the styles applied to the component. */
1711
1713
  classes?: HvBreadCrumbClasses;
1712
1714
  }
@@ -5980,7 +5982,7 @@ export declare interface HvTableHeaderProps extends Omit<React.ThHTMLAttributes<
5980
5982
  /** A Jss Object used to override or extend the styles applied to the component. */
5981
5983
  classes?: HvTableHeaderClasses;
5982
5984
  /** Extra props to be passed onto the sort button in the header. */
5983
- sortButtonProps?: HvButtonProps;
5985
+ sortButtonProps?: HvButtonBaseProps;
5984
5986
  }
5985
5987
 
5986
5988
  export declare type HvTableHeaderRenderer<D extends object = Record<string, unknown>> = Renderer<HvHeaderProps_2<D>>;
@@ -6099,7 +6101,7 @@ export declare interface HvTableRowProps extends HvBaseProps<HTMLTableRowElement
6099
6101
  }
6100
6102
 
6101
6103
  /**
6102
- * The `TableSection` component is a wrapper for the `Section` component that applies
6104
+ * The `HvTableSection` component is a wrapper for the `HvSection` component that applies
6103
6105
  * specific stylings for tables that follow the latest DS specifications.
6104
6106
  */
6105
6107
  export declare const HvTableSection: ForwardRefExoticComponent<HvTableSectionProps & RefAttributes<HTMLDivElement>>;