@datlv-trustshop/shopify-inapp-components 0.2.6 → 0.2.8

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.
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import { BannerItem } from "../types";
3
3
  export interface TopBannerProps {
4
4
  className?: string;
5
+ open?: boolean;
5
6
  onClose?: () => void;
6
7
  onAction?: (banner: BannerItem) => void;
7
8
  closable?: boolean;
@@ -1,12 +1,24 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useContext } from "react";
3
3
  import { Banner, Button, Text, BlockStack, InlineStack, } from "@shopify/polaris";
4
4
  import { ExternalIcon } from "@shopify/polaris-icons";
5
5
  import { useTopBanner } from "../hooks/useBanner";
6
6
  import { DashboardContext } from "../provider/DashboardProvider";
7
7
  const BANNER_MIN_HEIGHT = 100;
8
- const TopBannerSkeleton = ({ className }) => {
9
- return (_jsxs("div", { className: className, style: { width: "100%" }, children: [_jsxs("div", { style: {
8
+ const TopBannerSkeleton = ({ className, visible }) => {
9
+ // When not visible, return zero-space container
10
+ if (!visible) {
11
+ return (_jsx("div", { className: className, style: {
12
+ width: "100%",
13
+ height: 0,
14
+ overflow: "hidden",
15
+ position: "absolute",
16
+ pointerEvents: "none",
17
+ }, "aria-hidden": "true" }));
18
+ }
19
+ return (_jsxs("div", { className: className, style: {
20
+ width: "100%",
21
+ }, children: [_jsxs("div", { style: {
10
22
  minHeight: `${BANNER_MIN_HEIGHT}px`,
11
23
  padding: "16px",
12
24
  borderRadius: "8px",
@@ -49,7 +61,7 @@ const TopBannerSkeleton = ({ className }) => {
49
61
  }
50
62
  ` })] }));
51
63
  };
52
- export const TopBanner = ({ className = "", onClose, onAction, closable = true, renderBanner, }) => {
64
+ export const TopBanner = ({ className = "", open = true, onClose, onAction, closable = true, renderBanner, }) => {
53
65
  const context = useContext(DashboardContext);
54
66
  const isInitialized = context?.isInitialized ?? false;
55
67
  const isLoading = context?.state?.loading ?? true;
@@ -94,25 +106,55 @@ export const TopBanner = ({ className = "", onClose, onAction, closable = true,
94
106
  onAction?.(banner);
95
107
  }
96
108
  };
97
- if (!dismissChecked) {
98
- return _jsx(TopBannerSkeleton, { className: className });
99
- }
100
- if (isDismissed) {
101
- // Banner was dismissed, don't show anything
102
- return null;
103
- }
104
- if (!isInitialized || isLoading) {
105
- return _jsx(TopBannerSkeleton, { className: className });
109
+ const shouldShow = open && !isDismissed;
110
+ const showSkeleton = shouldShow && (!dismissChecked || !isInitialized || isLoading);
111
+ const showBanner = shouldShow && dismissChecked && isInitialized && !isLoading && banner;
112
+ // Always render skeleton during loading, but control visibility
113
+ if (!dismissChecked || !isInitialized || isLoading) {
114
+ return _jsx(TopBannerSkeleton, { className: className, visible: showSkeleton });
106
115
  }
116
+ // No banner data available - render invisible container to maintain mount
107
117
  if (!banner) {
108
- return null;
118
+ return (_jsx("div", { className: className, style: {
119
+ width: "100%",
120
+ height: 0,
121
+ overflow: "hidden",
122
+ position: "absolute",
123
+ pointerEvents: "none",
124
+ }, "aria-hidden": "true" }));
109
125
  }
126
+ // Custom render function with visibility control
110
127
  if (renderBanner) {
111
- return (_jsx(_Fragment, { children: renderBanner(banner, {
128
+ // When not showing, render zero-space container
129
+ if (!showBanner) {
130
+ return (_jsx("div", { className: className, style: {
131
+ width: "100%",
132
+ height: 0,
133
+ overflow: "hidden",
134
+ position: "absolute",
135
+ pointerEvents: "none",
136
+ }, "aria-hidden": "true" }));
137
+ }
138
+ return (_jsx("div", { style: {
139
+ opacity: 1,
140
+ visibility: "visible",
141
+ transition: "opacity 0.3s ease",
142
+ }, children: renderBanner(banner, {
112
143
  onClose: handleClose,
113
144
  onAction: handleAction,
114
145
  }) }));
115
146
  }
147
+ // Default banner render with visibility control
148
+ // When not showing, render zero-space container
149
+ if (!showBanner) {
150
+ return (_jsx("div", { className: className, style: {
151
+ width: "100%",
152
+ height: 0,
153
+ overflow: "hidden",
154
+ position: "absolute",
155
+ pointerEvents: "none",
156
+ }, "aria-hidden": "true" }));
157
+ }
116
158
  return (_jsx("div", { className: className, style: {
117
159
  width: "100%",
118
160
  minHeight: `${BANNER_MIN_HEIGHT}px`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datlv-trustshop/shopify-inapp-components",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "private": false,
5
5
  "description": "React TypeScript components for Shopify in-app dashboard content",
6
6
  "main": "dist/index.js",