@lowdefy/blocks-antd 5.0.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,73 @@ function getDarkModeIcon() {
28
28
  if (pref === 'light') return 'AiOutlineSun';
29
29
  return 'AiOutlineLaptop';
30
30
  }
31
- function renderNotifications({ blockId, classNames, styles, properties, events, Icon, Link, iconsColor }) {
31
+ function getDarkModeLabel() {
32
+ const pref = getDarkModePreference();
33
+ if (pref === 'dark') return 'Dark mode';
34
+ if (pref === 'light') return 'Light mode';
35
+ return 'System';
36
+ }
37
+ // Wraps a header action row for the expanded sider. Icon cell has a fixed
38
+ // basis so bell / avatar / sun share a vertical line regardless of their
39
+ // own intrinsic size; label fills the remaining width. Row gets a subtle
40
+ // hover background so it reads as interactive (matches menu items above).
41
+ const EXPANDED_ROW_BASE = {
42
+ display: 'flex',
43
+ alignItems: 'center',
44
+ gap: 12,
45
+ padding: '8px 12px',
46
+ width: '100%',
47
+ borderRadius: 6,
48
+ transition: 'background 0.15s'
49
+ };
50
+ const EXPANDED_ROW_BUTTON_RESET = {
51
+ background: 'transparent',
52
+ border: 'none',
53
+ textAlign: 'left',
54
+ font: 'inherit',
55
+ color: 'inherit'
56
+ };
57
+ function ExpandedRow({ children, label, className, style, onClick }) {
58
+ // `onClick` is only used when the row stands alone as the click target
59
+ // (e.g., dark-mode toggle). Notifications wraps this in a <Link> and
60
+ // profile wraps it in a <Dropdown> — in those cases interactivity comes
61
+ // from the parent, but the row should still hover-highlight.
62
+ const Tag = onClick ? 'button' : 'div';
63
+ const [hover, setHover] = React.useState(false);
64
+ const rowStyle = {
65
+ ...EXPANDED_ROW_BASE,
66
+ cursor: 'pointer',
67
+ ...onClick ? EXPANDED_ROW_BUTTON_RESET : null,
68
+ ...hover ? {
69
+ background: 'color-mix(in srgb, var(--ant-color-text) 6%, transparent)'
70
+ } : null,
71
+ ...style
72
+ };
73
+ return /*#__PURE__*/ React.createElement(Tag, {
74
+ type: onClick ? 'button' : undefined,
75
+ className: className,
76
+ style: rowStyle,
77
+ onClick: onClick,
78
+ onMouseEnter: ()=>setHover(true),
79
+ onMouseLeave: ()=>setHover(false)
80
+ }, /*#__PURE__*/ React.createElement("span", {
81
+ style: {
82
+ display: 'inline-flex',
83
+ alignItems: 'center',
84
+ justifyContent: 'center',
85
+ flex: '0 0 24px',
86
+ lineHeight: 1
87
+ }
88
+ }, children), /*#__PURE__*/ React.createElement("span", {
89
+ style: {
90
+ flex: 1,
91
+ minWidth: 0,
92
+ overflow: 'hidden',
93
+ textOverflow: 'ellipsis'
94
+ }
95
+ }, label));
96
+ }
97
+ function renderNotifications({ blockId, classNames, styles, properties, events, Icon, Link, iconsColor, expanded }) {
32
98
  if (type.isNone(properties.notifications)) return null;
33
99
  const notif = properties.notifications;
34
100
  const badge = /*#__PURE__*/ React.createElement(Badge, {
@@ -55,6 +121,26 @@ function renderNotifications({ blockId, classNames, styles, properties, events,
55
121
  }
56
122
  }));
57
123
  const link = notif.link;
124
+ if (expanded) {
125
+ const row = /*#__PURE__*/ React.createElement(ExpandedRow, {
126
+ className: classNames.notifications,
127
+ style: styles.notifications,
128
+ label: notif.title ?? 'Notifications'
129
+ }, badge);
130
+ if (link) {
131
+ return /*#__PURE__*/ React.createElement(Link, {
132
+ id: `${blockId}_notifications_link`,
133
+ pageId: link.pageId,
134
+ url: link.url,
135
+ newTab: link.newTab,
136
+ style: {
137
+ display: 'block',
138
+ color: 'inherit'
139
+ }
140
+ }, row);
141
+ }
142
+ return row;
143
+ }
58
144
  if (link) {
59
145
  return /*#__PURE__*/ React.createElement(Link, {
60
146
  id: `${blockId}_notifications_link`,
@@ -76,7 +162,7 @@ function renderNotifications({ blockId, classNames, styles, properties, events,
76
162
  }
77
163
  }, badge);
78
164
  }
79
- function renderProfile({ blockId, classNames, styles, properties, methods, events, Icon, Link, ShortcutBadge }) {
165
+ function renderProfile({ blockId, classNames, styles, properties, methods, events, Icon, Link, ShortcutBadge, expanded }) {
80
166
  if (type.isNone(properties.profile)) return null;
81
167
  const prof = properties.profile;
82
168
  const avatarProps = prof.avatar ?? {};
@@ -99,12 +185,17 @@ function renderProfile({ blockId, classNames, styles, properties, methods, event
99
185
  }
100
186
  })
101
187
  }, avatarProps.content);
188
+ const trigger = expanded ? /*#__PURE__*/ React.createElement(ExpandedRow, {
189
+ className: classNames.profile,
190
+ style: styles.profile,
191
+ label: prof.title ?? 'Profile'
192
+ }, avatar) : /*#__PURE__*/ React.createElement("div", {
193
+ className: classNames.profile,
194
+ style: styles.profile
195
+ }, avatar);
102
196
  const links = prof.links ?? [];
103
197
  if (links.length === 0) {
104
- return /*#__PURE__*/ React.createElement("div", {
105
- className: classNames.profile,
106
- style: styles.profile
107
- }, avatar);
198
+ return trigger;
108
199
  }
109
200
  const items = buildMenuItems({
110
201
  links,
@@ -119,10 +210,8 @@ function renderProfile({ blockId, classNames, styles, properties, methods, event
119
210
  });
120
211
  const linkMap = flattenLinks(links);
121
212
  return /*#__PURE__*/ React.createElement(Dropdown, {
122
- className: classNames.profile,
123
213
  style: {
124
- cursor: 'pointer',
125
- ...styles.profile
214
+ cursor: 'pointer'
126
215
  },
127
216
  menu: {
128
217
  items,
@@ -139,10 +228,11 @@ function renderProfile({ blockId, classNames, styles, properties, methods, event
139
228
  });
140
229
  }
141
230
  },
231
+ // Row-style trigger (expanded) expects click; small avatar (collapsed) uses hover.
142
232
  trigger: [
143
- prof.trigger ?? 'hover'
233
+ prof.trigger ?? (expanded ? 'click' : 'hover')
144
234
  ],
145
- placement: prof.placement ?? 'bottomRight',
235
+ placement: prof.placement ?? (expanded ? 'topRight' : 'bottomRight'),
146
236
  arrow: prof.arrow,
147
237
  popupClassName: classNames.profileMenu,
148
238
  popupStyle: styles.profileMenu,
@@ -152,20 +242,10 @@ function renderProfile({ blockId, classNames, styles, properties, methods, event
152
242
  open
153
243
  }
154
244
  })
155
- }, /*#__PURE__*/ React.createElement("div", null, avatar));
245
+ }, /*#__PURE__*/ React.createElement("div", null, trigger));
156
246
  }
157
- function renderDarkModeToggle({ blockId, classNames, styles, methods, events, Icon, iconsColor }) {
158
- return /*#__PURE__*/ React.createElement("div", {
159
- className: classNames.darkModeToggle,
160
- style: {
161
- cursor: 'pointer',
162
- lineHeight: 1,
163
- ...styles.darkModeToggle
164
- },
165
- onClick: ()=>methods.triggerEvent({
166
- name: '__toggleDarkMode'
167
- })
168
- }, /*#__PURE__*/ React.createElement(Icon, {
247
+ function renderDarkModeToggle({ blockId, classNames, styles, methods, events, Icon, iconsColor, expanded }) {
248
+ const icon = /*#__PURE__*/ React.createElement(Icon, {
169
249
  blockId: `${blockId}_dark_mode_toggle_icon`,
170
250
  events: events,
171
251
  properties: {
@@ -177,9 +257,30 @@ function renderDarkModeToggle({ blockId, classNames, styles, methods, events, Ic
177
257
  color: iconsColor
178
258
  }
179
259
  }
180
- }));
260
+ });
261
+ if (expanded) {
262
+ return /*#__PURE__*/ React.createElement(ExpandedRow, {
263
+ className: classNames.darkModeToggle,
264
+ style: styles.darkModeToggle,
265
+ label: getDarkModeLabel(),
266
+ onClick: ()=>methods.triggerEvent({
267
+ name: '__toggleDarkMode'
268
+ })
269
+ }, icon);
270
+ }
271
+ return /*#__PURE__*/ React.createElement("div", {
272
+ className: classNames.darkModeToggle,
273
+ style: {
274
+ cursor: 'pointer',
275
+ lineHeight: 1,
276
+ ...styles.darkModeToggle
277
+ },
278
+ onClick: ()=>methods.triggerEvent({
279
+ name: '__toggleDarkMode'
280
+ })
281
+ }, icon);
181
282
  }
182
- function renderHeaderActions({ blockId, classNames = {}, styles = {}, properties, methods, events, components: { Icon, Link, ShortcutBadge }, iconsColor }) {
283
+ function renderHeaderActions({ blockId, classNames = {}, styles = {}, properties, methods, events, components: { Icon, Link, ShortcutBadge }, iconsColor, expanded = false }) {
183
284
  const hasNotifications = !type.isNone(properties.notifications);
184
285
  const hasProfile = !type.isNone(properties.profile);
185
286
  const hasDarkMode = properties.darkModeToggle;
@@ -194,10 +295,12 @@ function renderHeaderActions({ blockId, classNames = {}, styles = {}, properties
194
295
  Icon,
195
296
  Link,
196
297
  ShortcutBadge,
197
- iconsColor
298
+ iconsColor,
299
+ expanded
198
300
  };
301
+ const defaultClassName = expanded ? 'flex flex-col items-stretch gap-1 w-full' : 'flex items-center gap-4 ml-4';
199
302
  return /*#__PURE__*/ React.createElement("div", {
200
- className: classNames.headerActions ?? 'flex items-center gap-4 ml-4',
303
+ className: classNames.headerActions ?? defaultClassName,
201
304
  style: styles.headerActions
202
305
  }, hasNotifications && renderNotifications(ctx), hasProfile && renderProfile(ctx), hasDarkMode && renderDarkModeToggle(ctx));
203
306
  }
package/dist/blocks.js CHANGED
@@ -56,6 +56,7 @@ export { default as MultipleSelector } from './blocks/MultipleSelector/MultipleS
56
56
  export { default as Notification } from './blocks/Notification/Notification.js';
57
57
  export { default as NumberInput } from './blocks/NumberInput/NumberInput.js';
58
58
  export { default as PageHeaderMenu } from './blocks/PageHeaderMenu/PageHeaderMenu.js';
59
+ export { default as PageSidebarLayout } from './blocks/PageSidebarLayout/PageSidebarLayout.js';
59
60
  export { default as PageSiderMenu } from './blocks/PageSiderMenu/PageSiderMenu.js';
60
61
  export { default as Pagination } from './blocks/Pagination/Pagination.js';
61
62
  export { default as Paragraph } from './blocks/Paragraph/Paragraph.js';
package/dist/metas.js CHANGED
@@ -56,6 +56,7 @@ export { default as MultipleSelector } from './blocks/MultipleSelector/meta.js';
56
56
  export { default as Notification } from './blocks/Notification/meta.js';
57
57
  export { default as NumberInput } from './blocks/NumberInput/meta.js';
58
58
  export { default as PageHeaderMenu } from './blocks/PageHeaderMenu/meta.js';
59
+ export { default as PageSidebarLayout } from './blocks/PageSidebarLayout/meta.js';
59
60
  export { default as PageSiderMenu } from './blocks/PageSiderMenu/meta.js';
60
61
  export { default as Pagination } from './blocks/Pagination/meta.js';
61
62
  export { default as Paragraph } from './blocks/Paragraph/meta.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/blocks-antd",
3
- "version": "5.0.0",
3
+ "version": "5.2.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Lowdefy Ant Design Blocks",
6
6
  "homepage": "https://lowdefy.com",
@@ -45,12 +45,12 @@
45
45
  ],
46
46
  "dependencies": {
47
47
  "@ant-design/icons": "6.1.0",
48
- "@lowdefy/block-utils": "5.0.0",
49
- "@lowdefy/helpers": "5.0.0",
48
+ "@lowdefy/block-utils": "5.2.0",
49
+ "@lowdefy/helpers": "5.2.0",
50
50
  "@rc-component/motion": "1.3.1",
51
51
  "classnames": "2.3.2",
52
52
  "dayjs": "1.11.19",
53
- "minisearch": "^7.0.0"
53
+ "minisearch": "7.2.0"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "antd": ">=6",
@@ -58,9 +58,9 @@
58
58
  "react-dom": ">=18"
59
59
  },
60
60
  "devDependencies": {
61
- "@lowdefy/block-dev-e2e": "5.0.0",
62
- "@lowdefy/e2e-utils": "5.0.0",
63
- "@lowdefy/node-utils": "5.0.0",
61
+ "@lowdefy/block-dev-e2e": "5.2.0",
62
+ "@lowdefy/e2e-utils": "5.2.0",
63
+ "@lowdefy/node-utils": "5.2.0",
64
64
  "@playwright/test": "1.50.1",
65
65
  "@swc/cli": "0.8.0",
66
66
  "@swc/core": "1.15.18",