@blockle/blocks-react 3.1.0 → 3.3.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 (135) hide show
  1. package/dist/components/display/Divider/divider.css.js +3 -3
  2. package/dist/components/display/Tag/Tag.d.ts +28 -0
  3. package/dist/components/display/Tag/Tag.d.ts.map +1 -0
  4. package/dist/components/display/Tag/Tag.js +46 -0
  5. package/dist/components/feedback/Alert/Alert.d.ts +15 -6
  6. package/dist/components/feedback/Alert/Alert.d.ts.map +1 -1
  7. package/dist/components/feedback/Alert/Alert.js +8 -37
  8. package/dist/components/feedback/Toast/ToastContext.d.ts +6 -0
  9. package/dist/components/feedback/Toast/ToastContext.d.ts.map +1 -1
  10. package/dist/components/feedback/Toast/ToastProvider.d.ts +6 -0
  11. package/dist/components/feedback/Toast/ToastProvider.d.ts.map +1 -1
  12. package/dist/components/feedback/Toast/ToastProvider.js +90 -29
  13. package/dist/components/feedback/Toast/useCountdowns.d.ts +14 -0
  14. package/dist/components/feedback/Toast/useCountdowns.d.ts.map +1 -0
  15. package/dist/components/feedback/Toast/useCountdowns.js +74 -0
  16. package/dist/components/form/Button/Button.d.ts +11 -3
  17. package/dist/components/form/Button/Button.d.ts.map +1 -1
  18. package/dist/components/form/Checkbox/Checkbox.d.ts.map +1 -1
  19. package/dist/components/form/Checkbox/Checkbox.js +7 -25
  20. package/dist/components/form/IconButton/IconButton.d.ts +29 -0
  21. package/dist/components/form/IconButton/IconButton.d.ts.map +1 -0
  22. package/dist/components/form/IconButton/IconButton.js +61 -0
  23. package/dist/components/form/Label/Label.d.ts +1 -1
  24. package/dist/components/form/Label/Label.d.ts.map +1 -1
  25. package/dist/components/form/NumericInput/NumericInput.d.ts +11 -1
  26. package/dist/components/form/NumericInput/NumericInput.d.ts.map +1 -1
  27. package/dist/components/form/NumericInput/NumericInput.js +52 -24
  28. package/dist/components/form/Select/Select.d.ts.map +1 -1
  29. package/dist/components/form/Select/Select.js +2 -23
  30. package/dist/components/form/Select/select.css.js +1 -1
  31. package/dist/components/form/Textarea/Textarea.css.d.ts +2 -0
  32. package/dist/components/form/Textarea/Textarea.css.d.ts.map +1 -1
  33. package/dist/components/form/Textarea/Textarea.css.js +17 -1
  34. package/dist/components/form/Textarea/Textarea.d.ts +11 -0
  35. package/dist/components/form/Textarea/Textarea.d.ts.map +1 -1
  36. package/dist/components/form/Textarea/Textarea.js +8 -2
  37. package/dist/components/layout/Inline/Inline.d.ts +11 -3
  38. package/dist/components/layout/Inline/Inline.d.ts.map +1 -1
  39. package/dist/components/layout/Inline/Inline.js +5 -3
  40. package/dist/components/layout/Stack/Stack.d.ts +12 -8
  41. package/dist/components/layout/Stack/Stack.d.ts.map +1 -1
  42. package/dist/components/layout/Stack/Stack.js +8 -4
  43. package/dist/components/navigation/Link/Link.d.ts +1 -1
  44. package/dist/components/navigation/Link/Link.d.ts.map +1 -1
  45. package/dist/components/navigation/Link/Link.js +2 -2
  46. package/dist/components/navigation/Tabs/Tab.d.ts +21 -0
  47. package/dist/components/navigation/Tabs/Tab.d.ts.map +1 -0
  48. package/dist/components/navigation/Tabs/Tab.js +138 -0
  49. package/dist/components/navigation/Tabs/TabIndicator.d.ts +6 -0
  50. package/dist/components/navigation/Tabs/TabIndicator.d.ts.map +1 -0
  51. package/dist/components/navigation/Tabs/TabIndicator.js +19 -0
  52. package/dist/components/navigation/Tabs/TabList.d.ts +10 -0
  53. package/dist/components/navigation/Tabs/TabList.d.ts.map +1 -0
  54. package/dist/components/navigation/Tabs/TabList.js +101 -0
  55. package/dist/components/navigation/Tabs/TabListContext.d.ts +13 -0
  56. package/dist/components/navigation/Tabs/TabListContext.d.ts.map +1 -0
  57. package/dist/components/navigation/Tabs/TabListContext.js +6 -0
  58. package/dist/components/navigation/Tabs/TabNav.d.ts +15 -0
  59. package/dist/components/navigation/Tabs/TabNav.d.ts.map +1 -0
  60. package/dist/components/navigation/Tabs/TabNav.js +44 -0
  61. package/dist/components/navigation/Tabs/TabPanel.d.ts +14 -0
  62. package/dist/components/navigation/Tabs/TabPanel.d.ts.map +1 -0
  63. package/dist/components/navigation/Tabs/TabPanel.js +31 -0
  64. package/dist/components/navigation/Tabs/Tabs.d.ts +13 -0
  65. package/dist/components/navigation/Tabs/Tabs.d.ts.map +1 -0
  66. package/dist/components/navigation/Tabs/Tabs.js +33 -0
  67. package/dist/components/navigation/Tabs/TabsContext.d.ts +13 -0
  68. package/dist/components/navigation/Tabs/TabsContext.d.ts.map +1 -0
  69. package/dist/components/navigation/Tabs/TabsContext.js +27 -0
  70. package/dist/components/navigation/Tabs/tabs.css.d.ts +7 -0
  71. package/dist/components/navigation/Tabs/tabs.css.d.ts.map +1 -0
  72. package/dist/components/navigation/Tabs/tabs.css.js +122 -0
  73. package/dist/components/overlay/Dialog/Dialog.d.ts +1 -1
  74. package/dist/components/overlay/Dialog/Dialog.d.ts.map +1 -1
  75. package/dist/components/overlay/Dialog/Dialog.js +9 -7
  76. package/dist/components/overlay/Drawer/Drawer.d.ts +1 -1
  77. package/dist/components/overlay/Drawer/Drawer.d.ts.map +1 -1
  78. package/dist/components/overlay/Drawer/Drawer.js +9 -7
  79. package/dist/components/overlay/Menu/Menu.d.ts +52 -0
  80. package/dist/components/overlay/Menu/Menu.d.ts.map +1 -0
  81. package/dist/components/overlay/Menu/Menu.js +273 -0
  82. package/dist/components/overlay/Menu/menu-utils.d.ts +33 -0
  83. package/dist/components/overlay/Menu/menu-utils.d.ts.map +1 -0
  84. package/dist/components/overlay/Menu/menu-utils.js +54 -0
  85. package/dist/components/overlay/Popover/Popover.d.ts +9 -0
  86. package/dist/components/overlay/Popover/Popover.d.ts.map +1 -1
  87. package/dist/components/overlay/Popover/Popover.js +70 -31
  88. package/dist/components/overlay/Popover/popover-utils.d.ts +32 -1
  89. package/dist/components/overlay/Popover/popover-utils.d.ts.map +1 -1
  90. package/dist/components/overlay/Popover/popover-utils.js +77 -22
  91. package/dist/components/overlay/modalOverlayStack.d.ts +8 -0
  92. package/dist/components/overlay/modalOverlayStack.d.ts.map +1 -0
  93. package/dist/components/overlay/modalOverlayStack.js +37 -0
  94. package/dist/components/overlay/useModalOverlay.d.ts +6 -14
  95. package/dist/components/overlay/useModalOverlay.d.ts.map +1 -1
  96. package/dist/components/overlay/useModalOverlay.js +8 -31
  97. package/dist/components/typography/Heading/Heading.d.ts +2 -1
  98. package/dist/components/typography/Heading/Heading.d.ts.map +1 -1
  99. package/dist/components/typography/Heading/Heading.js +9 -1
  100. package/dist/components/typography/Text/Text.d.ts +3 -2
  101. package/dist/components/typography/Text/Text.d.ts.map +1 -1
  102. package/dist/components/typography/Text/Text.js +9 -1
  103. package/dist/components/typography/textOverflow.css.d.ts +3 -0
  104. package/dist/components/typography/textOverflow.css.d.ts.map +1 -0
  105. package/dist/components/typography/textOverflow.css.js +32 -0
  106. package/dist/components/typography/textOverflow.d.ts +9 -0
  107. package/dist/components/typography/textOverflow.d.ts.map +1 -0
  108. package/dist/components/typography/textOverflow.js +10 -0
  109. package/dist/hooks/useModalDialog/useModalDialog.d.ts +5 -0
  110. package/dist/hooks/useModalDialog/useModalDialog.d.ts.map +1 -1
  111. package/dist/hooks/useModalDialog/useModalDialog.js +3 -2
  112. package/dist/hooks/usePreventBodyScroll/usePreventBodyScroll.d.ts +5 -0
  113. package/dist/hooks/usePreventBodyScroll/usePreventBodyScroll.d.ts.map +1 -1
  114. package/dist/hooks/usePreventBodyScroll/usePreventBodyScroll.js +31 -16
  115. package/dist/icons/icons.d.ts +8 -0
  116. package/dist/icons/icons.d.ts.map +1 -0
  117. package/dist/icons/icons.js +39 -0
  118. package/dist/index.d.ts +8 -0
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +16 -0
  121. package/dist/testUtils/browser/consumerStyles.css.d.ts +2 -0
  122. package/dist/testUtils/browser/consumerStyles.css.d.ts.map +1 -0
  123. package/dist/testUtils/browser/contrast.d.ts +6 -2
  124. package/dist/testUtils/browser/contrast.d.ts.map +1 -1
  125. package/dist/testUtils/browser/emulateNoAnchorPositioning.d.ts +8 -0
  126. package/dist/testUtils/browser/emulateNoAnchorPositioning.d.ts.map +1 -0
  127. package/dist/testUtils/browser/render.d.ts +6 -2
  128. package/dist/testUtils/browser/render.d.ts.map +1 -1
  129. package/dist/testUtils/browser/screenshot.d.ts +2 -0
  130. package/dist/testUtils/browser/screenshot.d.ts.map +1 -0
  131. package/dist/testUtils/testTheme.css.d.ts.map +1 -1
  132. package/package.json +2 -2
  133. package/dist/components/feedback/Alert/Alert.css.d.ts +0 -2
  134. package/dist/components/feedback/Alert/Alert.css.d.ts.map +0 -1
  135. package/dist/components/feedback/Alert/Alert.css.js +0 -15
@@ -7,23 +7,24 @@ import { useComponentStyles } from "../../../hooks/useComponentStyles/useCompone
7
7
  import { useIsomorphicLayoutEffect } from "../../../hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";
8
8
  import { useKeyboard } from "../../../hooks/useKeyboard/useKeyboard.js";
9
9
  import { Box } from "../../layout/Box/Box.js";
10
- import { getPopoverPosition } from "./popover-utils.js";
10
+ import { getPopoverLayout } from "./popover-utils.js";
11
11
  const Popover = ({
12
12
  anchorElement,
13
13
  children,
14
14
  className,
15
+ limitHeight = false,
15
16
  onRequestClose,
16
17
  open,
17
18
  placement: placementProp,
18
19
  position,
19
20
  ref,
20
- sticky,
21
+ sticky: _sticky,
21
22
  style,
22
23
  ...restProps
23
24
  }) => {
24
25
  const placement = placementProp ?? position ?? "top";
25
26
  const popoverRef = useRef(null);
26
- const [popoverPosition, setPopoverPosition] = useState({ x: 0, y: 0 });
27
+ const [layout, setLayout] = useState({ x: 0, y: 0 });
27
28
  const [visible, setVisible] = useState(open);
28
29
  const popoverClassName = useComponentStyles("popover", { root: true }, false);
29
30
  const onEscape = useCallback(
@@ -50,8 +51,9 @@ const Popover = ({
50
51
  return;
51
52
  }
52
53
  element.showPopover();
53
- const [x, y] = getPopoverPosition(placement, anchorElement, popoverRef);
54
- setPopoverPosition({ x, y });
54
+ setLayout(
55
+ getPopoverLayout(placement, anchorElement, popoverRef, limitHeight)
56
+ );
55
57
  } else if (open) {
56
58
  setVisible(true);
57
59
  } else {
@@ -71,36 +73,70 @@ const Popover = ({
71
73
  }
72
74
  }, [open, visible]);
73
75
  useEffect(() => {
74
- if (open) {
75
- const [x, y] = getPopoverPosition(placement, anchorElement, popoverRef);
76
- setPopoverPosition({ x, y });
77
- }
78
- }, [open, anchorElement, placement]);
79
- useEffect(() => {
80
- if (!open || !sticky) {
76
+ if (!open || !visible) {
81
77
  return;
82
78
  }
83
- function updatePopoverPosition() {
84
- const [x, y] = getPopoverPosition(placement, anchorElement, popoverRef);
85
- setPopoverPosition((prev) => {
86
- if (prev.x === x && prev.y === y) {
79
+ let frame = 0;
80
+ function updateLayout() {
81
+ frame = 0;
82
+ if (!popoverRef.current) {
83
+ return;
84
+ }
85
+ const next = getPopoverLayout(
86
+ placement,
87
+ anchorElement,
88
+ popoverRef,
89
+ limitHeight
90
+ );
91
+ setLayout((prev) => {
92
+ if (prev.x === next.x && prev.y === next.y && prev.maxWidth === next.maxWidth && prev.maxHeight === next.maxHeight) {
87
93
  return prev;
88
94
  }
89
- return { x, y };
95
+ return next;
90
96
  });
91
97
  }
92
- window.addEventListener("resize", updatePopoverPosition);
93
- window.addEventListener("scroll", updatePopoverPosition);
98
+ function scheduleLayoutUpdate() {
99
+ if (!frame) {
100
+ frame = requestAnimationFrame(updateLayout);
101
+ }
102
+ }
103
+ function onScroll(event) {
104
+ if (event.target instanceof Node && popoverRef.current?.contains(event.target)) {
105
+ return;
106
+ }
107
+ scheduleLayoutUpdate();
108
+ }
109
+ updateLayout();
110
+ const { visualViewport } = window;
111
+ const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(scheduleLayoutUpdate);
112
+ if (anchorElement.current) {
113
+ observer?.observe(anchorElement.current);
114
+ }
115
+ if (popoverRef.current) {
116
+ observer?.observe(popoverRef.current);
117
+ }
118
+ window.addEventListener("resize", scheduleLayoutUpdate);
119
+ document.addEventListener("scroll", onScroll, {
120
+ capture: true,
121
+ passive: true
122
+ });
123
+ visualViewport?.addEventListener("resize", scheduleLayoutUpdate);
94
124
  return () => {
95
- window.removeEventListener("resize", updatePopoverPosition);
96
- window.removeEventListener("scroll", updatePopoverPosition);
125
+ cancelAnimationFrame(frame);
126
+ observer?.disconnect();
127
+ window.removeEventListener("resize", scheduleLayoutUpdate);
128
+ document.removeEventListener("scroll", onScroll, { capture: true });
129
+ visualViewport?.removeEventListener("resize", scheduleLayoutUpdate);
97
130
  };
98
- }, [placement, anchorElement, open, sticky]);
99
- const onAnimationEnd = useCallback(() => {
100
- if (!open) {
101
- setVisible(false);
102
- }
103
- }, [open]);
131
+ }, [open, visible, placement, anchorElement, limitHeight]);
132
+ const onClosingEnd = useCallback(
133
+ (event) => {
134
+ if (!open && event.target === event.currentTarget) {
135
+ setVisible(false);
136
+ }
137
+ },
138
+ [open]
139
+ );
104
140
  if (!visible) {
105
141
  return null;
106
142
  }
@@ -112,12 +148,15 @@ const Popover = ({
112
148
  popover: "manual",
113
149
  className: classnames(popoverClassName, className),
114
150
  position: "absolute",
115
- onAnimationEnd,
116
- onTransitionEnd: onAnimationEnd,
151
+ onAnimationEnd: onClosingEnd,
152
+ onTransitionEnd: onClosingEnd,
153
+ onTransitionCancel: onClosingEnd,
117
154
  style: {
118
155
  ...style,
119
- left: popoverPosition.x,
120
- top: popoverPosition.y
156
+ left: layout.x,
157
+ top: layout.y,
158
+ maxWidth: layout.maxWidth,
159
+ maxHeight: layout.maxHeight
121
160
  },
122
161
  ...restProps,
123
162
  children
@@ -35,6 +35,37 @@ export type ComputePopoverPositionOptions = {
35
35
  * Returns the popover's `left` and `top`, relative to the document
36
36
  */
37
37
  export declare function computePopoverPosition({ placement, anchor, popover, viewport, }: ComputePopoverPositionOptions): PopoverPositions;
38
- export declare function getPopoverPosition(placement: PopoverPlacement, anchorRef: React.RefObject<HTMLElement | null>, popoverRef: React.RefObject<HTMLElement | null>): PopoverPositions;
38
+ /**
39
+ * Returns the most height the popover's border box can take on the side it
40
+ * opens on, keeping it VIEWPORT_PADDING inside the viewport
41
+ */
42
+ export declare function computeAvailableHeight({ placement, anchor, popover, viewport, }: ComputePopoverPositionOptions): number;
43
+ /**
44
+ * Returns the most width the popover's border box can take, keeping it
45
+ * VIEWPORT_PADDING inside the viewport on both sides
46
+ */
47
+ export declare function computeAvailableWidth(viewport: ComputePopoverPositionOptions['viewport']): number;
48
+ export type PopoverLayout = {
49
+ x: number;
50
+ y: number;
51
+ /**
52
+ * The popover's `max-width`: the viewport's width, VIEWPORT_PADDING inside
53
+ * both edges. It follows the popover's `box-sizing`, so padding and border
54
+ * fit too.
55
+ */
56
+ maxWidth?: number;
57
+ /**
58
+ * The popover's `max-height`, when it is limited to the room it has. It
59
+ * follows the popover's `box-sizing`, so padding and border fit too.
60
+ */
61
+ maxHeight?: number;
62
+ };
63
+ /**
64
+ * Measures the anchor and popover and returns where to put the popover. A
65
+ * popover wider than the viewport is capped to it, and placed by its capped
66
+ * width. With `limitHeight`, a popover taller than the room on its side is
67
+ * capped to that room, and placed by its capped height.
68
+ */
69
+ export declare function getPopoverLayout(placement: PopoverPlacement, anchorRef: React.RefObject<HTMLElement | null>, popoverRef: React.RefObject<HTMLElement | null>, limitHeight?: boolean): PopoverLayout;
39
70
  export {};
40
71
  //# sourceMappingURL=popover-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover-utils.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Popover/popover-utils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAEtD,KAAK,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD,KAAK,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnC,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,WAAW,IAAI,WAAW,EAAE,CAAC;AAE7E,KAAK,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,KAAK,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,gBAAgB,CAAC;IAC5B,wDAAwD;IACxD,MAAM,EAAE,IAAI,CAAC;IACb,kEAAkE;IAClE,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/E,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE,6BAA6B,GAAG,gBAAgB,CAyClD;AAoED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAC9C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAC9C,gBAAgB,CAyClB"}
1
+ {"version":3,"file":"popover-utils.d.ts","sourceRoot":"","sources":["../../../../src/components/overlay/Popover/popover-utils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAEtD,KAAK,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD,KAAK,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnC,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,WAAW,IAAI,WAAW,EAAE,CAAC;AAE7E,KAAK,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,KAAK,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,gBAAgB,CAAC;IAC5B,wDAAwD;IACxD,MAAM,EAAE,IAAI,CAAC;IACb,kEAAkE;IAClE,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/E,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE,6BAA6B,GAAG,gBAAgB,CAgDlD;AA0CD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE,6BAA6B,GAAG,MAAM,CAgBxC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,6BAA6B,CAAC,UAAU,CAAC,GAClD,MAAM,CAER;AAyCD,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAC9C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAC/C,WAAW,UAAQ,GAClB,aAAa,CAyFf"}
@@ -11,7 +11,11 @@ function computePopoverPosition({
11
11
  let left;
12
12
  let top;
13
13
  if (side === "top" || side === "bottom") {
14
- top = side === "top" ? anchor.top - margin.bottom - popover.height : anchor.top + anchor.height + margin.top;
14
+ top = holdInViewport(
15
+ side === "top" ? anchor.top - margin.bottom - popover.height : anchor.top + anchor.height + margin.top,
16
+ popover.height,
17
+ viewport.height
18
+ );
15
19
  left = alignOnCrossAxis(
16
20
  edge,
17
21
  anchor.left,
@@ -20,7 +24,11 @@ function computePopoverPosition({
20
24
  viewport.width
21
25
  );
22
26
  } else {
23
- left = side === "left" ? anchor.left - margin.right - popover.width : anchor.left + anchor.width + margin.left;
27
+ left = holdInViewport(
28
+ side === "left" ? anchor.left - margin.right - popover.width : anchor.left + anchor.width + margin.left,
29
+ popover.width,
30
+ viewport.width
31
+ );
24
32
  top = alignOnCrossAxis(
25
33
  edge,
26
34
  anchor.top,
@@ -56,6 +64,25 @@ function flipSide(side, anchor, popover, viewport) {
56
64
  }
57
65
  return side;
58
66
  }
67
+ function computeAvailableHeight({
68
+ placement,
69
+ anchor,
70
+ popover,
71
+ viewport
72
+ }) {
73
+ const [preferredSide] = placement.split("-");
74
+ const side = flipSide(preferredSide, anchor, popover, viewport);
75
+ let available = viewport.height - VIEWPORT_PADDING * 2;
76
+ if (side === "top") {
77
+ available = anchor.top - popover.margin.bottom - VIEWPORT_PADDING;
78
+ } else if (side === "bottom") {
79
+ available = viewport.height - VIEWPORT_PADDING - (anchor.top + anchor.height) - popover.margin.top;
80
+ }
81
+ return Math.max(0, available);
82
+ }
83
+ function computeAvailableWidth(viewport) {
84
+ return Math.max(0, viewport.width - VIEWPORT_PADDING * 2);
85
+ }
59
86
  function alignOnCrossAxis(edge, anchorStart, anchorSize, popoverSize, viewportSize) {
60
87
  let start = anchorStart + (anchorSize - popoverSize) / 2;
61
88
  if (edge === "start") {
@@ -63,46 +90,74 @@ function alignOnCrossAxis(edge, anchorStart, anchorSize, popoverSize, viewportSi
63
90
  } else if (edge === "end") {
64
91
  start = anchorStart + anchorSize - popoverSize;
65
92
  }
93
+ return holdInViewport(start, popoverSize, viewportSize);
94
+ }
95
+ function holdInViewport(start, popoverSize, viewportSize) {
66
96
  const max = viewportSize - VIEWPORT_PADDING - popoverSize;
67
97
  return Math.max(VIEWPORT_PADDING, Math.min(start, max));
68
98
  }
69
- function getPopoverPosition(placement, anchorRef, popoverRef) {
99
+ function getPopoverLayout(placement, anchorRef, popoverRef, limitHeight = false) {
70
100
  if (!anchorRef.current || !popoverRef.current) {
71
- return [0, 0];
101
+ return { x: 0, y: 0 };
72
102
  }
103
+ const element = popoverRef.current;
73
104
  const anchorRect = anchorRef.current.getBoundingClientRect();
74
- const popoverRect = popoverRef.current.getBoundingClientRect();
75
- const popoverStyles = getComputedStyle(popoverRef.current);
76
- const [width, height] = getOriginalElementSize(
105
+ const popoverRect = element.getBoundingClientRect();
106
+ const popoverStyles = getComputedStyle(element);
107
+ const [measuredWidth, measuredHeight] = getOriginalElementSize(
77
108
  popoverStyles,
78
109
  popoverRect.width,
79
110
  popoverRect.height
80
111
  );
112
+ const style = (property) => cssValueToNumber(popoverStyles.getPropertyValue(property));
113
+ const borderY = style("border-top-width") + style("border-bottom-width");
114
+ const isContentBox = popoverStyles.boxSizing === "content-box";
115
+ const height = limitHeight ? Math.max(measuredHeight, element.scrollHeight + borderY) : measuredHeight;
81
116
  const { documentElement } = document;
82
- return computePopoverPosition({
117
+ const viewport = {
118
+ width: documentElement.clientWidth,
119
+ height: documentElement.clientHeight,
120
+ scrollX: documentElement.scrollLeft,
121
+ scrollY: documentElement.scrollTop
122
+ };
123
+ const availableWidth = computeAvailableWidth(viewport);
124
+ const options = {
83
125
  placement,
84
126
  anchor: anchorRect,
85
127
  popover: {
86
- width,
128
+ width: Math.min(measuredWidth, availableWidth),
87
129
  height,
88
130
  margin: {
89
- top: cssValueToNumber(popoverStyles.getPropertyValue("margin-top")),
90
- right: cssValueToNumber(popoverStyles.getPropertyValue("margin-right")),
91
- bottom: cssValueToNumber(
92
- popoverStyles.getPropertyValue("margin-bottom")
93
- ),
94
- left: cssValueToNumber(popoverStyles.getPropertyValue("margin-left"))
131
+ top: style("margin-top"),
132
+ right: style("margin-right"),
133
+ bottom: style("margin-bottom"),
134
+ left: style("margin-left")
95
135
  }
96
136
  },
97
- viewport: {
98
- width: documentElement.clientWidth,
99
- height: documentElement.clientHeight,
100
- scrollX: documentElement.scrollLeft,
101
- scrollY: documentElement.scrollTop
102
- }
137
+ viewport
138
+ };
139
+ const paddingAndBorderX = isContentBox ? style("padding-left") + style("padding-right") + style("border-left-width") + style("border-right-width") : 0;
140
+ const maxWidth = Math.max(0, availableWidth - paddingAndBorderX);
141
+ if (!limitHeight) {
142
+ const [x2, y2] = computePopoverPosition(options);
143
+ return { x: x2, y: y2, maxWidth };
144
+ }
145
+ const availableHeight = computeAvailableHeight(options);
146
+ const [x, y] = computePopoverPosition({
147
+ ...options,
148
+ popover: { ...options.popover, height: Math.min(height, availableHeight) }
103
149
  });
150
+ const paddingAndBorderY = isContentBox ? style("padding-top") + style("padding-bottom") + borderY : 0;
151
+ return {
152
+ x,
153
+ y,
154
+ maxWidth,
155
+ maxHeight: Math.max(0, availableHeight - paddingAndBorderY)
156
+ };
104
157
  }
105
158
  export {
159
+ computeAvailableHeight,
160
+ computeAvailableWidth,
106
161
  computePopoverPosition,
107
- getPopoverPosition
162
+ getPopoverLayout
108
163
  };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Puts a modal overlay on the stack of open ones while `open` is true, and
3
+ * returns whether it is the top one: the one opened last, wherever it is
4
+ * mounted. Like the browser's top layer, which shows each modal dialog above
5
+ * the ones shown before it, the order does not follow the React tree.
6
+ */
7
+ export declare const useIsTopModalOverlay: (open: boolean) => boolean;
8
+ //# sourceMappingURL=modalOverlayStack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modalOverlayStack.d.ts","sourceRoot":"","sources":["../../../src/components/overlay/modalOverlayStack.ts"],"names":[],"mappings":"AA8BA;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,OAAO,KAAG,OAoBpD,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { useState, useSyncExternalStore } from "react";
3
+ import { useIsomorphicLayoutEffect } from "../../hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js";
4
+ let stack = [];
5
+ const listeners = /* @__PURE__ */ new Set();
6
+ const setStack = (next) => {
7
+ stack = next;
8
+ for (const listener of listeners) {
9
+ listener();
10
+ }
11
+ };
12
+ const subscribe = (listener) => {
13
+ listeners.add(listener);
14
+ return () => {
15
+ listeners.delete(listener);
16
+ };
17
+ };
18
+ const useIsTopModalOverlay = (open) => {
19
+ const [token] = useState(() => ({}));
20
+ useIsomorphicLayoutEffect(() => {
21
+ if (!open) {
22
+ return;
23
+ }
24
+ setStack([...stack, token]);
25
+ return () => {
26
+ setStack(stack.filter((item) => item !== token));
27
+ };
28
+ }, [open, token]);
29
+ return useSyncExternalStore(
30
+ subscribe,
31
+ () => stack.at(-1) === token,
32
+ () => false
33
+ );
34
+ };
35
+ export {
36
+ useIsTopModalOverlay
37
+ };
@@ -1,9 +1,4 @@
1
1
  import { RequestCloseReason } from './requestCloseReason.js';
2
- type DialogContextValue = {
3
- setEnabled: (active: boolean) => void;
4
- };
5
- export declare const DialogContext: import('react').Context<DialogContextValue | undefined>;
6
- export declare const useNestedDialog: (open: boolean) => boolean;
7
2
  type UseDialogCloseRequestsOptions = {
8
3
  enabled: boolean;
9
4
  onRequestClose: (reason: RequestCloseReason) => void;
@@ -19,17 +14,14 @@ type UseModalOverlayOptions = Omit<UseDialogCloseRequestsOptions, 'enabled'> & {
19
14
  * closed, the body does not scroll, and an Escape, close request or click
20
15
  * outside requests to close.
21
16
  *
22
- * While a nested Dialog or Drawer is open, the outer one ignores Escape and
23
- * clicks outside, and leaves the body scroll lock to the outermost one.
24
- * Provide `contextValue` through DialogContext to the dialog's content.
17
+ * Only the modal overlay opened last handles Escape and clicks outside, so a
18
+ * click in a Dialog or Drawer does not close the ones below it, whether it is
19
+ * nested in them or mounted elsewhere.
25
20
  */
26
21
  export declare const useModalOverlay: (dialogRef: React.RefObject<HTMLDialogElement | null>, { open, onRequestClose, ...handlers }: UseModalOverlayOptions) => {
27
- contextValue: DialogContextValue;
28
- closeRequestProps: {
29
- onKeyDown: (event: React.KeyboardEvent<HTMLDialogElement>) => void;
30
- onKeyDownCapture: (event: React.KeyboardEvent<HTMLDialogElement>) => void;
31
- onCancel: (event: React.SyntheticEvent<HTMLDialogElement>) => void;
32
- };
22
+ onKeyDown: (event: React.KeyboardEvent<HTMLDialogElement>) => void;
23
+ onKeyDownCapture: (event: React.KeyboardEvent<HTMLDialogElement>) => void;
24
+ onCancel: (event: React.SyntheticEvent<HTMLDialogElement>) => void;
33
25
  };
34
26
  export {};
35
27
  //# sourceMappingURL=useModalOverlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useModalOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/overlay/useModalOverlay.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,KAAK,kBAAkB,GAAG;IACxB,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,aAAa,yDAEzB,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,MAAM,OAAO,KAAG,OAgB/C,CAAC;AAEF,KAAK,6BAA6B,GAAG;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAC1D,gBAAgB,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;CACvD,CAAC;AA6EF,KAAK,sBAAsB,GAAG,IAAI,CAAC,6BAA6B,EAAE,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EACpD,uCAAuC,sBAAsB;;;2BA/D/B,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC;kCAR3D,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC;0BA2BlB,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC;;CAqErE,CAAC"}
1
+ {"version":3,"file":"useModalOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/overlay/useModalOverlay.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,KAAK,6BAA6B,GAAG;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAC1D,gBAAgB,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;CACvD,CAAC;AA6EF,KAAK,sBAAsB,GAAG,IAAI,CAAC,6BAA6B,EAAE,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EACpD,uCAAuC,sBAAsB;uBA/D/B,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC;8BAR3D,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC;sBA2BlB,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC;CA2DrE,CAAC"}
@@ -1,24 +1,9 @@
1
1
  "use client";
2
- import { useState, createContext, useContext, useEffect, useRef } from "react";
2
+ import { useRef } from "react";
3
3
  import { useClickOutside } from "../../hooks/useClickOutside/useClickOutside.js";
4
4
  import { usePreventBodyScroll } from "../../hooks/usePreventBodyScroll/usePreventBodyScroll.js";
5
5
  import { useRestoreFocus } from "../../hooks/useRestoreFocus/useRestoreFocus.js";
6
- const DialogContext = createContext(
7
- void 0
8
- );
9
- const useNestedDialog = (open) => {
10
- const parentDialog = useContext(DialogContext);
11
- useEffect(() => {
12
- if (!parentDialog || !open) {
13
- return;
14
- }
15
- parentDialog.setEnabled(false);
16
- return () => {
17
- parentDialog.setEnabled(true);
18
- };
19
- }, [parentDialog, open]);
20
- return !!parentDialog;
21
- };
6
+ import { useIsTopModalOverlay } from "./modalOverlayStack.js";
22
7
  const useDialogCloseRequests = ({
23
8
  enabled,
24
9
  onRequestClose,
@@ -63,23 +48,15 @@ const useDialogCloseRequests = ({
63
48
  };
64
49
  };
65
50
  const useModalOverlay = (dialogRef, { open, onRequestClose, ...handlers }) => {
66
- const [enabled, setEnabled] = useState(true);
67
- const [contextValue] = useState(() => ({ setEnabled }));
68
51
  useRestoreFocus(open);
69
- const isNested = useNestedDialog(open);
70
- usePreventBodyScroll(open && !isNested);
52
+ usePreventBodyScroll(open);
53
+ const isTop = useIsTopModalOverlay(open);
54
+ const enabled = open && isTop;
71
55
  useClickOutside(dialogRef, () => onRequestClose("outside-click"), {
72
- enabled: open && enabled
73
- });
74
- const closeRequestProps = useDialogCloseRequests({
75
- enabled: open && enabled,
76
- onRequestClose,
77
- ...handlers
56
+ enabled
78
57
  });
79
- return { contextValue, closeRequestProps };
58
+ return useDialogCloseRequests({ enabled, onRequestClose, ...handlers });
80
59
  };
81
60
  export {
82
- DialogContext,
83
- useModalOverlay,
84
- useNestedDialog
61
+ useModalOverlay
85
62
  };
@@ -1,10 +1,11 @@
1
1
  import { HTMLElementProps, MarginAtoms, PaddingAtoms, TextAtoms } from '@blockle/blocks-core';
2
2
  import { TextColor } from '../textColor.js';
3
+ import { TextOverflowProps } from '../textOverflow.js';
3
4
  export type HeadingProps = {
4
5
  className?: string;
5
6
  /** A text Color role, which follows the Color mode, or a fixed Palette color. */
6
7
  color?: TextColor;
7
8
  level?: 1 | 2 | 3 | 4 | 5 | 6;
8
- } & HTMLElementProps<HTMLHeadingElement> & Omit<TextAtoms, 'color'> & MarginAtoms & PaddingAtoms;
9
+ } & TextOverflowProps & HTMLElementProps<HTMLHeadingElement> & Omit<TextAtoms, 'color'> & MarginAtoms & PaddingAtoms;
9
10
  export declare const Heading: React.FC<HeadingProps>;
10
11
  //# sourceMappingURL=Heading.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/Heading/Heading.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAGhE,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC/B,GAAG,gBAAgB,CAAC,kBAAkB,CAAC,GACtC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GACxB,WAAW,GACX,YAAY,CAAC;AAEf,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAuB1C,CAAC"}
1
+ {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/Heading/Heading.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,oBAAoB,CAAC;AAG5B,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC/B,GAAG,iBAAiB,GACnB,gBAAgB,CAAC,kBAAkB,CAAC,GACpC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GACxB,WAAW,GACX,YAAY,CAAC;AAEf,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA8B1C,CAAC"}
@@ -3,11 +3,14 @@ import { jsx } from "react/jsx-runtime";
3
3
  import { classnames } from "@blockle/blocks-core";
4
4
  import { useComponentStyles } from "../../../hooks/useComponentStyles/useComponentStyles.js";
5
5
  import { Box } from "../../layout/Box/Box.js";
6
+ import { textOverflowClassName } from "../textOverflow.js";
6
7
  import { heading } from "./heading.css.js";
7
8
  const Heading = ({
8
9
  className,
9
10
  color,
10
11
  level = 1,
12
+ lineClamp,
13
+ truncate,
11
14
  children,
12
15
  ...restProps
13
16
  }) => {
@@ -20,7 +23,12 @@ const Heading = ({
20
23
  Box,
21
24
  {
22
25
  asChild: true,
23
- className: classnames(heading, themeClassName, className),
26
+ className: classnames(
27
+ heading,
28
+ themeClassName,
29
+ textOverflowClassName("Heading", { lineClamp, truncate }),
30
+ className
31
+ ),
24
32
  color,
25
33
  ...restProps,
26
34
  children: /* @__PURE__ */ jsx(Tag, { children })
@@ -1,6 +1,7 @@
1
1
  import { HTMLElementProps, MarginAtoms, PaddingAtoms, TextAtoms } from '@blockle/blocks-core';
2
2
  import { default as React } from 'react';
3
3
  import { TextColor } from '../textColor.js';
4
+ import { TextOverflowProps } from '../textOverflow.js';
4
5
  type Tags = 'cite' | 'code' | 'del' | 'em' | 'ins' | 'kbd' | 'label' | 'mark' | 'p' | 'q' | 's' | 'small' | 'span' | 'strong' | 'sub' | 'sup';
5
6
  export type TextProps<Tag extends Tags = 'span'> = {
6
7
  asChild?: boolean;
@@ -9,7 +10,7 @@ export type TextProps<Tag extends Tags = 'span'> = {
9
10
  tag?: Tag;
10
11
  /** A text Color role, which follows the Color mode, or a fixed Palette color. */
11
12
  color?: TextColor;
12
- } & Omit<HTMLElementProps<HTMLSpanElement>, 'children' | 'ref'> & Omit<TextAtoms, 'color'> & MarginAtoms & PaddingAtoms;
13
- export declare const Text: <T extends Tags = "span">({ asChild, children, className, color, ref, tag, ...restProps }: TextProps<T>) => import("react/jsx-runtime").JSX.Element;
13
+ } & TextOverflowProps & Omit<HTMLElementProps<HTMLSpanElement>, 'children' | 'ref'> & Omit<TextAtoms, 'color'> & MarginAtoms & PaddingAtoms;
14
+ export declare const Text: <T extends Tags = "span">({ asChild, children, className, color, lineClamp, ref, tag, truncate, ...restProps }: TextProps<T>) => import("react/jsx-runtime").JSX.Element;
14
15
  export {};
15
16
  //# sourceMappingURL=Text.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Text.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/Text/Text.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAGhE,KAAK,IAAI,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,IAAI,GACJ,KAAK,GACL,KAAK,GACL,OAAO,GACP,MAAM,GACN,GAAG,GACH,GAAG,GACH,GAAG,GACH,OAAO,GACP,MAAM,GACN,QAAQ,GACR,KAAK,GACL,KAAK,CAAC;AAEV,MAAM,MAAM,SAAS,CAAC,GAAG,SAAS,IAAI,GAAG,MAAM,IAAI;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,iFAAiF;IACjF,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,GAC7D,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GACxB,WAAW,GACX,YAAY,CAAC;AAEf,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,IAAI,GAAG,MAAM,EAAE,iEAQ3C,SAAS,CAAC,CAAC,CAAC,4CAsBd,CAAC"}
1
+ {"version":3,"file":"Text.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/Text/Text.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,oBAAoB,CAAC;AAG5B,KAAK,IAAI,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,IAAI,GACJ,KAAK,GACL,KAAK,GACL,OAAO,GACP,MAAM,GACN,GAAG,GACH,GAAG,GACH,GAAG,GACH,OAAO,GACP,MAAM,GACN,QAAQ,GACR,KAAK,GACL,KAAK,CAAC;AAEV,MAAM,MAAM,SAAS,CAAC,GAAG,SAAS,IAAI,GAAG,MAAM,IAAI;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,iFAAiF;IACjF,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,GAAG,iBAAiB,GACnB,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,GAC3D,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GACxB,WAAW,GACX,YAAY,CAAC;AAEf,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,IAAI,GAAG,MAAM,EAAE,sFAU3C,SAAS,CAAC,CAAC,CAAC,4CA2Bd,CAAC"}
@@ -3,14 +3,17 @@ import { jsx } from "react/jsx-runtime";
3
3
  import { classnames } from "@blockle/blocks-core";
4
4
  import { useComponentStyles } from "../../../hooks/useComponentStyles/useComponentStyles.js";
5
5
  import { Box } from "../../layout/Box/Box.js";
6
+ import { textOverflowClassName } from "../textOverflow.js";
6
7
  import { text } from "./text.css.js";
7
8
  const Text = ({
8
9
  asChild,
9
10
  children,
10
11
  className,
11
12
  color,
13
+ lineClamp,
12
14
  ref,
13
15
  tag,
16
+ truncate,
14
17
  ...restProps
15
18
  }) => {
16
19
  const Component = tag ?? "span";
@@ -22,7 +25,12 @@ const Text = ({
22
25
  Box,
23
26
  {
24
27
  asChild: true,
25
- className: classnames(text, themeClassName, className),
28
+ className: classnames(
29
+ text,
30
+ themeClassName,
31
+ textOverflowClassName("Text", { lineClamp, truncate }),
32
+ className
33
+ ),
26
34
  color,
27
35
  ...restProps,
28
36
  children: asChild ? children : (
@@ -0,0 +1,3 @@
1
+ export declare const lineClamp: Record<1 | 2 | 3 | 4 | 5, string>;
2
+ export declare const truncate: string;
3
+ //# sourceMappingURL=textOverflow.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textOverflow.css.d.ts","sourceRoot":"","sources":["../../../src/components/typography/textOverflow.css.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,SAAS,mCAYrB,CAAC;AAEF,eAAO,MAAM,QAAQ,QASnB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { setFileScope, endFileScope } from "@vanilla-extract/css/fileScope";
2
+ import { layers } from "@blockle/blocks-core";
3
+ import { styleVariants, style } from "@vanilla-extract/css";
4
+ setFileScope("src/components/typography/textOverflow.css.ts", "@blockle/blocks-react");
5
+ const lineClamp = styleVariants(
6
+ { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5 },
7
+ (lines) => ({
8
+ "@layer": {
9
+ [layers.molecule]: {
10
+ display: "-webkit-box",
11
+ WebkitBoxOrient: "vertical",
12
+ WebkitLineClamp: lines,
13
+ overflow: "hidden"
14
+ }
15
+ }
16
+ })
17
+ );
18
+ const truncate = style({
19
+ "@layer": {
20
+ [layers.molecule]: {
21
+ display: "block",
22
+ overflow: "hidden",
23
+ textOverflow: "ellipsis",
24
+ whiteSpace: "nowrap"
25
+ }
26
+ }
27
+ });
28
+ endFileScope();
29
+ export {
30
+ lineClamp,
31
+ truncate
32
+ };