smartsell-ui-kit 0.0.3 → 0.0.5

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/README.md CHANGED
@@ -115,4 +115,27 @@ export default manifest;
115
115
  npm run typecheck
116
116
  npm run build
117
117
  npm publish
118
- ```
118
+ ```
119
+
120
+ ## Component preview workspace
121
+
122
+ The repository now includes a local Storybook workspace so you can inspect and interact with components before publishing the package.
123
+
124
+ - grouped sidebar navigation for buttons, surfaces, forms, and modals
125
+ - live Controls for component props such as size, tone, labels, states, and modal behaviors
126
+ - a mocked `SmartSellSDK` so theme-aware components render without depending on the main app runtime
127
+
128
+ Run it directly with npm:
129
+
130
+ ```bash
131
+ npm install
132
+ npm run storybook
133
+ ```
134
+
135
+ Run it in a container with hot reload:
136
+
137
+ ```bash
138
+ docker compose up --build
139
+ ```
140
+
141
+ The Storybook workspace is development-only. It is not part of the published package because `package.json` only ships `dist`, `README.md`, and `LICENSE`.
@@ -143,14 +143,26 @@ function StandardModal({
143
143
  closeOnBackdrop = true,
144
144
  closeOnEscape = true,
145
145
  hideCloseButton = false,
146
+ hideExpandButton = false,
147
+ maximized,
146
148
  contentStyle,
147
149
  theme
148
150
  }) {
149
151
  const modalTheme = useMemo(() => resolveTheme(theme), [theme]);
152
+ const [isMaximized, setIsMaximized] = useState(maximized != null ? maximized : false);
150
153
  const titleId = useMemo(
151
154
  () => `smartsell-modal-${String(title != null ? title : "dialog").toLowerCase().replace(/[^a-z0-9]+/g, "-")}`,
152
155
  [title]
153
156
  );
157
+ useEffect(() => {
158
+ if (typeof maximized === "boolean") {
159
+ setIsMaximized(maximized);
160
+ return;
161
+ }
162
+ if (isLikelyMobileViewport()) {
163
+ setIsMaximized(true);
164
+ }
165
+ }, [maximized]);
154
166
  useEffect(() => {
155
167
  if (!isOpen || typeof window === "undefined" || typeof document === "undefined") {
156
168
  return;
@@ -218,7 +230,7 @@ function StandardModal({
218
230
  display: "flex",
219
231
  alignItems: "center",
220
232
  justifyContent: "center",
221
- padding: 16,
233
+ padding: isMaximized ? 0 : 16,
222
234
  backgroundColor: modalTheme.overlay,
223
235
  backdropFilter: "blur(8px)"
224
236
  },
@@ -226,9 +238,14 @@ function StandardModal({
226
238
  "div",
227
239
  {
228
240
  style: {
229
- width: "min(100%, 100%)",
230
- maxWidth: normalizeWidth(maxWidth),
231
- borderRadius: 30,
241
+ position: "relative",
242
+ display: "flex",
243
+ flexDirection: "column",
244
+ width: isMaximized ? "100vw" : "min(100%, 100%)",
245
+ maxWidth: isMaximized ? "100vw" : normalizeWidth(maxWidth),
246
+ height: isMaximized ? "100vh" : void 0,
247
+ maxHeight: isMaximized ? "100vh" : "calc(100vh - 32px)",
248
+ borderRadius: isMaximized ? 0 : 30,
232
249
  border: `1px solid ${modalTheme.borderSoft}`,
233
250
  background: `linear-gradient(180deg, ${modalTheme.surfaceRaised}, ${modalTheme.colors.surface})`,
234
251
  boxShadow: `0 34px 80px ${withAlpha("#020617", 0.28)}`,
@@ -245,34 +262,69 @@ function StandardModal({
245
262
  alignItems: "flex-start",
246
263
  justifyContent: "space-between",
247
264
  gap: 16,
248
- padding: "24px 24px 0"
265
+ padding: "24px 24px 16px",
266
+ borderBottom: `1px solid ${withAlpha(modalTheme.colors.onSurface, 0.06)}`
249
267
  },
250
268
  children: [
251
269
  /* @__PURE__ */ jsx("div", { style: { flex: 1 }, children: header }),
252
- !hideCloseButton ? /* @__PURE__ */ jsx(
253
- "button",
254
- {
255
- "aria-label": "Close modal",
256
- type: "button",
257
- onClick: onClose,
258
- style: {
259
- height: 42,
260
- width: 42,
261
- borderRadius: 999,
262
- border: `1px solid ${modalTheme.borderSoft}`,
263
- backgroundColor: "transparent",
264
- color: modalTheme.colors.onSurface,
265
- cursor: "pointer",
266
- fontSize: 20,
267
- fontWeight: 700
268
- },
269
- children: "\xD7"
270
- }
271
- ) : null
270
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
271
+ !hideExpandButton ? /* @__PURE__ */ jsx(
272
+ "button",
273
+ {
274
+ "aria-label": isMaximized ? "Minimize modal" : "Maximize modal",
275
+ title: isMaximized ? "Minimize" : "Maximize",
276
+ type: "button",
277
+ onClick: () => setIsMaximized((current) => !current),
278
+ style: {
279
+ height: 42,
280
+ width: 42,
281
+ borderRadius: 999,
282
+ border: `1px solid ${modalTheme.borderSoft}`,
283
+ backgroundColor: "transparent",
284
+ color: modalTheme.colors.onSurface,
285
+ cursor: "pointer",
286
+ fontSize: 18,
287
+ fontWeight: 700
288
+ },
289
+ children: isMaximized ? "\u25A2" : "\u25A1"
290
+ }
291
+ ) : null,
292
+ !hideCloseButton ? /* @__PURE__ */ jsx(
293
+ "button",
294
+ {
295
+ "aria-label": "Close modal",
296
+ type: "button",
297
+ onClick: onClose,
298
+ style: {
299
+ height: 42,
300
+ width: 42,
301
+ borderRadius: 999,
302
+ border: `1px solid ${modalTheme.borderSoft}`,
303
+ backgroundColor: "transparent",
304
+ color: modalTheme.colors.onSurface,
305
+ cursor: "pointer",
306
+ fontSize: 20,
307
+ fontWeight: 700
308
+ },
309
+ children: "\xD7"
310
+ }
311
+ ) : null
312
+ ] })
272
313
  ]
273
314
  }
274
315
  ),
275
- /* @__PURE__ */ jsx("div", { style: { padding: 24 }, children }),
316
+ /* @__PURE__ */ jsx(
317
+ "div",
318
+ {
319
+ style: {
320
+ flex: 1,
321
+ minHeight: 0,
322
+ overflow: "auto",
323
+ padding: 24
324
+ },
325
+ children
326
+ }
327
+ ),
276
328
  footer ? /* @__PURE__ */ jsx(
277
329
  "div",
278
330
  {
@@ -280,7 +332,7 @@ function StandardModal({
280
332
  display: "flex",
281
333
  justifyContent: "flex-end",
282
334
  gap: 12,
283
- padding: "0 24px 24px",
335
+ padding: "16px 24px 24px",
284
336
  borderTop: `1px solid ${withAlpha(modalTheme.colors.onSurface, 0.06)}`
285
337
  },
286
338
  children: footer
@@ -579,4 +631,4 @@ function Modal(props) {
579
631
  export {
580
632
  Modal
581
633
  };
582
- //# sourceMappingURL=chunk-KZRGV5RH.js.map
634
+ //# sourceMappingURL=chunk-BI3QBKFG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Modal.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\nimport type { UiKitThemeTokens } from '../theme';\n\ntype LegacyButtonType = 'text' | 'outlined' | 'contained' | 'link';\n\ntype ModalThemeColors = {\n background: string;\n surface: string;\n onSurface: string;\n onBackground: string;\n primary: string;\n onPrimary: string;\n secondary: string;\n onSecondary: string;\n negative: string;\n warning: string;\n};\n\nexport interface ModalTheme {\n colors?: Partial<ModalThemeColors>;\n}\n\nexport type ModalThemeSource = ModalTheme | UiKitThemeTokens;\n\nexport interface LegacyModalAction {\n name: string;\n onClick: () => void;\n type?: LegacyButtonType;\n style?: CSSProperties;\n disable?: boolean;\n}\n\ninterface BaseModalProps {\n children?: ReactNode;\n theme?: ModalThemeSource;\n}\n\nexport interface StandardModalProps extends BaseModalProps {\n isOpen: boolean;\n onClose: () => void;\n children: ReactNode;\n footer?: ReactNode;\n title?: ReactNode;\n description?: ReactNode;\n headerContent?: ReactNode;\n maxWidth?: number | string;\n closeOnBackdrop?: boolean;\n closeOnEscape?: boolean;\n hideCloseButton?: boolean;\n hideExpandButton?: boolean;\n maximized?: boolean;\n contentStyle?: CSSProperties;\n}\n\nexport interface LegacyModalProps extends BaseModalProps {\n title: ReactNode;\n showModal: boolean;\n closeModal: () => void;\n action?: () => void;\n actionNameBtn?: string | undefined;\n hideActionButton?: boolean;\n cancelButton?: () => void;\n disableActionBtn?: boolean;\n isLoading?: boolean;\n onlyCloseButton?: boolean;\n hideCloseIcon?: boolean;\n style?: CSSProperties;\n bodyStyle?: CSSProperties;\n additionalActions?: LegacyModalAction[];\n maximized?: boolean;\n}\n\nexport type ModalProps = StandardModalProps | LegacyModalProps;\n\nconst defaultThemeColors: ModalThemeColors = {\n background: '#f8fafc',\n surface: '#ffffff',\n onSurface: '#0f172a',\n onBackground: '#0f172a',\n primary: '#0f766e',\n onPrimary: '#ffffff',\n secondary: '#1d4ed8',\n onSecondary: '#ffffff',\n negative: '#dc2626',\n warning: '#d97706',\n};\n\nconst withAlpha = (hex: string, alpha: number): string => {\n const normalized = hex.replace('#', '').trim();\n const value = normalized.length === 3\n ? normalized.split('').map((char) => char + char).join('')\n : normalized;\n\n const red = Number.parseInt(value.slice(0, 2), 16);\n const green = Number.parseInt(value.slice(2, 4), 16);\n const blue = Number.parseInt(value.slice(4, 6), 16);\n\n return `rgba(${red}, ${green}, ${blue}, ${alpha})`;\n};\n\nconst isUiKitThemeTokens = (theme?: ModalThemeSource): theme is UiKitThemeTokens => {\n return Boolean(theme && typeof theme === 'object' && 'theme' in theme);\n};\n\nconst resolveTheme = (theme?: ModalThemeSource) => {\n const colorOverrides = isUiKitThemeTokens(theme)\n ? theme.theme.colors\n : (theme?.colors ?? {});\n\n const colors: ModalThemeColors = {\n ...defaultThemeColors,\n ...colorOverrides,\n };\n\n return {\n colors,\n borderSoft: isUiKitThemeTokens(theme)\n ? theme.borderSoft\n : withAlpha(colors.onSurface, 0.1),\n borderStrong: isUiKitThemeTokens(theme)\n ? theme.borderStrong\n : withAlpha(colors.onSurface, 0.16),\n surfaceMuted: isUiKitThemeTokens(theme)\n ? theme.surfaceMuted\n : withAlpha(colors.onSurface, 0.04),\n surfaceRaised: isUiKitThemeTokens(theme)\n ? theme.surfaceRaised\n : withAlpha(colors.surface, 0.94),\n overlay: isUiKitThemeTokens(theme)\n ? theme.overlay\n : withAlpha('#030712', 0.62),\n mutedText: isUiKitThemeTokens(theme)\n ? theme.mutedText\n : withAlpha(colors.onSurface, 0.72),\n };\n};\n\nconst normalizeWidth = (maxWidth?: number | string): string | number => {\n if (typeof maxWidth === 'number') {\n return `${maxWidth}px`;\n }\n\n return maxWidth ?? '720px';\n};\n\nconst isLikelyMobileViewport = (): boolean => {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n return false;\n }\n\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n navigator.userAgent,\n );\n};\n\nconst isLegacyModalProps = (props: ModalProps): props is LegacyModalProps => {\n return 'showModal' in props;\n};\n\nfunction LegacyActionButton({\n label,\n onClick,\n disabled,\n type = 'contained',\n theme,\n style,\n}: {\n label: string;\n onClick: () => void;\n disabled: boolean;\n type?: LegacyButtonType;\n theme: ReturnType<typeof resolveTheme>;\n style?: CSSProperties;\n}) {\n const { colors } = theme;\n\n const buttonStyle: CSSProperties = {\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '0.4rem',\n padding: type === 'link' ? 0 : '1.3rem',\n boxSizing: 'border-box',\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontWeight: 700,\n fontSize: '1.3rem',\n margin: 0,\n textAlign: 'center',\n transition: '0.5s',\n opacity: disabled ? 0.5 : 1,\n filter: disabled ? 'saturate(0)' : undefined,\n };\n\n if (type === 'text') {\n buttonStyle.background = 'none';\n buttonStyle.border = '1px solid transparent';\n buttonStyle.color = colors.primary;\n buttonStyle.boxShadow = 'none';\n } else if (type === 'link') {\n buttonStyle.background = 'none';\n buttonStyle.border = 'none';\n buttonStyle.color = colors.primary;\n buttonStyle.boxShadow = 'none';\n } else if (type === 'outlined') {\n buttonStyle.background = 'none';\n buttonStyle.border = `2px solid ${colors.primary}`;\n buttonStyle.color = colors.primary;\n buttonStyle.boxShadow = `0 14px 28px ${withAlpha(colors.onSurface, 0.08)}`;\n } else {\n buttonStyle.background = colors.primary;\n buttonStyle.border = '1px solid transparent';\n buttonStyle.color = colors.onPrimary;\n buttonStyle.boxShadow = `0 14px 28px ${withAlpha(colors.primary, 0.22)}`;\n }\n\n return (\n <div\n style={{\n width: style?.width ?? (style?.maxWidth ? '100%' : 'max-content'),\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 5px',\n marginBottom: style?.marginBottom ?? 0,\n ...style,\n }}\n >\n <button\n type=\"button\"\n onClick={disabled ? undefined : onClick}\n disabled={disabled}\n style={buttonStyle}\n >\n {label}\n </button>\n </div>\n );\n}\n\nfunction StandardModal({\n isOpen,\n onClose,\n children,\n footer,\n title,\n description,\n headerContent,\n maxWidth,\n closeOnBackdrop = true,\n closeOnEscape = true,\n hideCloseButton = false,\n hideExpandButton = false,\n maximized,\n contentStyle,\n theme,\n}: StandardModalProps) {\n const modalTheme = useMemo(() => resolveTheme(theme), [theme]);\n const [isMaximized, setIsMaximized] = useState<boolean>(maximized ?? false);\n const titleId = useMemo(\n () => `smartsell-modal-${String(title ?? 'dialog').toLowerCase().replace(/[^a-z0-9]+/g, '-')}`,\n [title],\n );\n\n useEffect(() => {\n if (typeof maximized === 'boolean') {\n setIsMaximized(maximized);\n return;\n }\n\n if (isLikelyMobileViewport()) {\n setIsMaximized(true);\n }\n }, [maximized]);\n\n useEffect(() => {\n if (!isOpen || typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n\n const previousOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (closeOnEscape && event.key === 'Escape') {\n onClose();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.body.style.overflow = previousOverflow;\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [closeOnEscape, isOpen, onClose]);\n\n if (!isOpen) {\n return null;\n }\n\n const header = headerContent ?? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {title ? (\n <h2\n id={titleId}\n style={{\n margin: 0,\n color: modalTheme.colors.onSurface,\n fontSize: 30,\n fontWeight: 800,\n lineHeight: 1.1,\n }}\n >\n {title}\n </h2>\n ) : null}\n {description ? (\n <p\n style={{\n margin: 0,\n color: modalTheme.mutedText,\n fontSize: 15,\n lineHeight: 1.6,\n }}\n >\n {description}\n </p>\n ) : null}\n </div>\n );\n\n return (\n <div\n aria-label={headerContent ? (typeof title === 'string' ? title : 'Dialog') : undefined}\n aria-labelledby={headerContent ? undefined : title ? titleId : undefined}\n aria-modal=\"true\"\n role=\"dialog\"\n onMouseDown={(event) => {\n if (closeOnBackdrop && event.target === event.currentTarget) {\n onClose();\n }\n }}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 70,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: isMaximized ? 0 : 16,\n backgroundColor: modalTheme.overlay,\n backdropFilter: 'blur(8px)',\n }}\n >\n <div\n style={{\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n width: isMaximized ? '100vw' : 'min(100%, 100%)',\n maxWidth: isMaximized ? '100vw' : normalizeWidth(maxWidth),\n height: isMaximized ? '100vh' : undefined,\n maxHeight: isMaximized ? '100vh' : 'calc(100vh - 32px)',\n borderRadius: isMaximized ? 0 : 30,\n border: `1px solid ${modalTheme.borderSoft}`,\n background: `linear-gradient(180deg, ${modalTheme.surfaceRaised}, ${modalTheme.colors.surface})`,\n boxShadow: `0 34px 80px ${withAlpha('#020617', 0.28)}`,\n color: modalTheme.colors.onSurface,\n overflow: 'hidden',\n ...contentStyle,\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n gap: 16,\n padding: '24px 24px 16px',\n borderBottom: `1px solid ${withAlpha(modalTheme.colors.onSurface, 0.06)}`,\n }}\n >\n <div style={{ flex: 1 }}>{header}</div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n {!hideExpandButton ? (\n <button\n aria-label={isMaximized ? 'Minimize modal' : 'Maximize modal'}\n title={isMaximized ? 'Minimize' : 'Maximize'}\n type=\"button\"\n onClick={() => setIsMaximized((current) => !current)}\n style={{\n height: 42,\n width: 42,\n borderRadius: 999,\n border: `1px solid ${modalTheme.borderSoft}`,\n backgroundColor: 'transparent',\n color: modalTheme.colors.onSurface,\n cursor: 'pointer',\n fontSize: 18,\n fontWeight: 700,\n }}\n >\n {isMaximized ? '▢' : '□'}\n </button>\n ) : null}\n {!hideCloseButton ? (\n <button\n aria-label=\"Close modal\"\n type=\"button\"\n onClick={onClose}\n style={{\n height: 42,\n width: 42,\n borderRadius: 999,\n border: `1px solid ${modalTheme.borderSoft}`,\n backgroundColor: 'transparent',\n color: modalTheme.colors.onSurface,\n cursor: 'pointer',\n fontSize: 20,\n fontWeight: 700,\n }}\n >\n ×\n </button>\n ) : null}\n </div>\n </div>\n\n <div\n style={{\n flex: 1,\n minHeight: 0,\n overflow: 'auto',\n padding: 24,\n }}\n >\n {children}\n </div>\n\n {footer ? (\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 12,\n padding: '16px 24px 24px',\n borderTop: `1px solid ${withAlpha(modalTheme.colors.onSurface, 0.06)}`,\n }}\n >\n {footer}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction LegacyModal({\n title,\n showModal,\n closeModal,\n children,\n action,\n actionNameBtn,\n hideActionButton = false,\n cancelButton,\n disableActionBtn = false,\n isLoading = false,\n onlyCloseButton = false,\n hideCloseIcon = false,\n style,\n bodyStyle,\n additionalActions,\n maximized,\n theme,\n}: LegacyModalProps) {\n const modalTheme = useMemo(() => resolveTheme(theme), [theme]);\n const [isMaximized, setIsMaximized] = useState<boolean>(maximized ?? false);\n const resolvedAction = action ?? (() => null);\n\n useEffect(() => {\n if (maximized === undefined && isLikelyMobileViewport()) {\n setIsMaximized(true);\n }\n }, [maximized]);\n\n if (!showModal) {\n return null;\n }\n\n const actionButtons = () => {\n return (\n <>\n {additionalActions?.map((item) => (\n <LegacyActionButton\n key={item.name}\n label={item.name}\n onClick={item.onClick}\n type={item.type ?? 'contained'}\n style={item.style ?? { maxWidth: '150px' }}\n theme={modalTheme}\n disabled={item.disable ?? (disableActionBtn || isLoading)}\n />\n ))}\n\n {!hideActionButton ? (\n <LegacyActionButton\n label={actionNameBtn ?? 'Save'}\n onClick={resolvedAction}\n type=\"contained\"\n style={{ maxWidth: '100px' }}\n theme={modalTheme}\n disabled={disableActionBtn || isLoading}\n />\n ) : null}\n </>\n );\n };\n\n return (\n <div\n aria-labelledby=\"modal-title\"\n aria-modal=\"true\"\n role=\"dialog\"\n style={{\n background: `${modalTheme.colors.background}90`,\n backdropFilter: 'blur(2px)',\n width: '100%',\n height: '100%',\n position: 'fixed',\n zIndex: 999,\n top: 0,\n left: 0,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n boxSizing: 'border-box',\n }}\n >\n <div\n id={isLoading ? 'ldg1' : undefined}\n style={{\n position: isMaximized ? 'fixed' : 'relative',\n left: isMaximized ? 0 : undefined,\n top: isMaximized ? 0 : undefined,\n background: modalTheme.colors.background,\n display: 'flex',\n alignItems: 'center',\n flexDirection: 'column',\n borderRadius: '0.8rem',\n boxSizing: 'border-box',\n maxHeight: isMaximized ? '100vh' : '80vh',\n maxWidth: isMaximized ? '100vw' : '80vw',\n minWidth: isMaximized ? '100vw' : 300,\n minHeight: isMaximized ? '100vh' : undefined,\n width: isMaximized ? '100vw' : undefined,\n boxShadow: '0 24px 64px rgba(15, 23, 42, 0.18)',\n ...(isLoading ? { opacity: 0.5 } : null),\n ...style,\n }}\n >\n <div\n style={{\n background: modalTheme.colors.surface,\n color: modalTheme.colors.onSurface,\n position: 'absolute',\n top: 0,\n zIndex: 500,\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n height: '4rem',\n padding: '1rem',\n boxSizing: 'border-box',\n borderTopLeftRadius: '0.8rem',\n borderTopRightRadius: '0.8rem',\n borderBottom: `1px solid ${withAlpha(modalTheme.colors.onBackground, 0.1)}`,\n }}\n >\n <div id=\"modal-title\" style={{ fontWeight: 'bold', fontSize: '1.3rem' }}>\n {title}\n </div>\n <div\n id=\"modal-header-icons\"\n style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}\n >\n <button\n aria-label={isMaximized ? 'Minimize modal' : 'Maximize modal'}\n title={isMaximized ? 'Minimize' : 'Maximize'}\n type=\"button\"\n onClick={() => setIsMaximized((current) => !current)}\n style={{\n border: 'none',\n background: 'transparent',\n color: modalTheme.colors.onSurface,\n cursor: 'pointer',\n fontSize: 18,\n lineHeight: 1,\n padding: 0,\n }}\n >\n {isMaximized ? '▢' : '□'}\n </button>\n\n {!hideCloseIcon ? (\n <button\n aria-label=\"Close modal\"\n title=\"Close\"\n type=\"button\"\n onClick={isLoading ? undefined : closeModal}\n style={{\n border: 'none',\n background: 'transparent',\n color: modalTheme.colors.onSurface,\n cursor: isLoading ? 'not-allowed' : 'pointer',\n fontSize: 22,\n lineHeight: 1,\n padding: 0,\n opacity: isLoading ? 0.5 : 1,\n }}\n >\n ×\n </button>\n ) : null}\n </div>\n </div>\n\n <div\n style={{\n scrollbarWidth: 'thin',\n width: '100%',\n maxWidth: '100%',\n paddingTop: '4rem',\n paddingBottom: '4rem',\n overflow: 'auto',\n ...bodyStyle,\n }}\n >\n {children}\n </div>\n\n {onlyCloseButton ? (\n <div\n style={{\n background: modalTheme.colors.surface,\n color: modalTheme.colors.onSurface,\n position: 'absolute',\n bottom: 0,\n width: '100%',\n height: '4rem',\n padding: '0.5rem',\n borderTop: `1px solid ${withAlpha(modalTheme.colors.onBackground, 0.1)}`,\n boxSizing: 'border-box',\n borderBottomLeftRadius: '0.8rem',\n borderBottomRightRadius: '0.8rem',\n }}\n >\n <div\n className=\"buttons-footer\"\n style={{ flex: 1, display: 'flex', justifyContent: 'end' }}\n >\n <LegacyActionButton\n label=\"Close\"\n onClick={closeModal}\n theme={modalTheme}\n disabled={isLoading}\n />\n </div>\n </div>\n ) : (\n <div\n style={{\n background: modalTheme.colors.surface,\n color: modalTheme.colors.onSurface,\n position: 'absolute',\n bottom: 0,\n width: '100%',\n height: '4rem',\n padding: '0.5rem',\n borderTop: `1px solid ${withAlpha(modalTheme.colors.onBackground, 0.1)}`,\n boxSizing: 'border-box',\n borderBottomLeftRadius: '0.8rem',\n borderBottomRightRadius: '0.8rem',\n }}\n >\n {cancelButton ? (\n <div\n className=\"buttons-footer\"\n style={{ flex: 1, display: 'flex', justifyContent: 'end' }}\n >\n <LegacyActionButton\n label=\"Cancel\"\n onClick={cancelButton}\n type=\"text\"\n style={{ maxWidth: '100px' }}\n theme={modalTheme}\n disabled={false}\n />\n {actionButtons()}\n </div>\n ) : (\n <div\n className=\"buttons-footer\"\n style={{ flex: 1, display: 'flex', justifyContent: 'end' }}\n >\n {actionButtons()}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function Modal(props: ModalProps) {\n if (isLegacyModalProps(props)) {\n return <LegacyModal {...props} />;\n }\n\n return <StandardModal {...props} />;\n}"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  module.exports = __toCommonJS(index_exports);
35
35
 
36
36
  // src/components/Button.tsx
37
+ var import_react2 = require("react");
37
38
  var import_smartsell_sales_sdk2 = require("smartsell-sales-sdk");
38
39
 
39
40
  // src/theme.ts
@@ -78,9 +79,21 @@ function Button({
78
79
  disabled,
79
80
  style,
80
81
  type = "button",
82
+ onMouseEnter,
83
+ onMouseLeave,
84
+ onMouseDown,
85
+ onMouseUp,
86
+ onBlur,
87
+ onKeyDown,
88
+ onKeyUp,
89
+ onTouchStart,
90
+ onTouchEnd,
91
+ onTouchCancel,
81
92
  ...rest
82
93
  }) {
83
94
  const { theme } = useUiKitTheme(sdk);
95
+ const [isHovered, setIsHovered] = (0, import_react2.useState)(false);
96
+ const [isPressed, setIsPressed] = (0, import_react2.useState)(false);
84
97
  const palette = {
85
98
  primary: {
86
99
  background: theme.colors.primary,
@@ -120,12 +133,81 @@ function Button({
120
133
  color: tone === "neutral" ? palette.foreground : palette.background
121
134
  }
122
135
  };
136
+ const interactiveColor = tone === "neutral" ? palette.foreground : palette.background;
137
+ const isInteractive = !disabled;
138
+ const interactionStyles = {
139
+ solid: {
140
+ transform: isPressed ? "translateY(1px) scale(0.985)" : isHovered ? "translateY(-1px)" : "translateY(0)",
141
+ boxShadow: isPressed ? `0 8px 16px ${(0, import_smartsell_sales_sdk2.withAlpha)(palette.background, 0.2)}` : isHovered ? `0 18px 36px ${(0, import_smartsell_sales_sdk2.withAlpha)(palette.background, 0.26)}` : `0 14px 28px ${(0, import_smartsell_sales_sdk2.withAlpha)(palette.background, 0.18)}`,
142
+ filter: isPressed ? "brightness(0.95)" : isHovered ? "brightness(1.03)" : void 0
143
+ },
144
+ outline: {
145
+ transform: isPressed ? "translateY(1px) scale(0.985)" : isHovered ? "translateY(-1px)" : "translateY(0)",
146
+ backgroundColor: isPressed ? (0, import_smartsell_sales_sdk2.withAlpha)(interactiveColor, 0.14) : isHovered ? (0, import_smartsell_sales_sdk2.withAlpha)(interactiveColor, 0.08) : "transparent",
147
+ boxShadow: isPressed ? `0 6px 12px ${(0, import_smartsell_sales_sdk2.withAlpha)(theme.colors.onSurface, 0.08)}` : isHovered ? `0 12px 24px ${(0, import_smartsell_sales_sdk2.withAlpha)(theme.colors.onSurface, 0.08)}` : "none"
148
+ },
149
+ ghost: {
150
+ transform: isPressed ? "translateY(1px) scale(0.985)" : isHovered ? "translateY(-1px)" : "translateY(0)",
151
+ backgroundColor: isPressed ? (0, import_smartsell_sales_sdk2.withAlpha)(interactiveColor, 0.12) : isHovered ? (0, import_smartsell_sales_sdk2.withAlpha)(interactiveColor, 0.06) : "transparent",
152
+ boxShadow: "none"
153
+ }
154
+ };
123
155
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
124
156
  "button",
125
157
  {
126
158
  ...rest,
127
159
  type,
128
160
  disabled,
161
+ onMouseEnter: (event) => {
162
+ if (isInteractive) {
163
+ setIsHovered(true);
164
+ }
165
+ onMouseEnter == null ? void 0 : onMouseEnter(event);
166
+ },
167
+ onMouseLeave: (event) => {
168
+ setIsHovered(false);
169
+ setIsPressed(false);
170
+ onMouseLeave == null ? void 0 : onMouseLeave(event);
171
+ },
172
+ onMouseDown: (event) => {
173
+ if (isInteractive) {
174
+ setIsPressed(true);
175
+ }
176
+ onMouseDown == null ? void 0 : onMouseDown(event);
177
+ },
178
+ onMouseUp: (event) => {
179
+ setIsPressed(false);
180
+ onMouseUp == null ? void 0 : onMouseUp(event);
181
+ },
182
+ onBlur: (event) => {
183
+ setIsHovered(false);
184
+ setIsPressed(false);
185
+ onBlur == null ? void 0 : onBlur(event);
186
+ },
187
+ onKeyDown: (event) => {
188
+ if (isInteractive && (event.key === " " || event.key === "Enter")) {
189
+ setIsPressed(true);
190
+ }
191
+ onKeyDown == null ? void 0 : onKeyDown(event);
192
+ },
193
+ onKeyUp: (event) => {
194
+ setIsPressed(false);
195
+ onKeyUp == null ? void 0 : onKeyUp(event);
196
+ },
197
+ onTouchStart: (event) => {
198
+ if (isInteractive) {
199
+ setIsPressed(true);
200
+ }
201
+ onTouchStart == null ? void 0 : onTouchStart(event);
202
+ },
203
+ onTouchEnd: (event) => {
204
+ setIsPressed(false);
205
+ onTouchEnd == null ? void 0 : onTouchEnd(event);
206
+ },
207
+ onTouchCancel: (event) => {
208
+ setIsPressed(false);
209
+ onTouchCancel == null ? void 0 : onTouchCancel(event);
210
+ },
129
211
  style: {
130
212
  display: "inline-flex",
131
213
  alignItems: "center",
@@ -140,10 +222,10 @@ function Button({
140
222
  letterSpacing: "0.01em",
141
223
  lineHeight: 1,
142
224
  opacity: disabled ? 0.58 : 1,
143
- transition: "transform 160ms ease, opacity 160ms ease, background-color 160ms ease",
144
- boxShadow: variant === "solid" ? `0 14px 28px ${(0, import_smartsell_sales_sdk2.withAlpha)(palette.background, 0.18)}` : "none",
225
+ transition: "transform 140ms ease, opacity 160ms ease, background-color 160ms ease, box-shadow 160ms ease, filter 160ms ease",
145
226
  ...getSizeStyles(size),
146
227
  ...variantStyles[variant],
228
+ ...isInteractive ? interactionStyles[variant] : void 0,
147
229
  ...style
148
230
  },
149
231
  children: [
@@ -248,11 +330,11 @@ function Card({
248
330
  }
249
331
 
250
332
  // src/components/ComposableModal.tsx
251
- var import_react3 = require("react");
333
+ var import_react4 = require("react");
252
334
  var import_smartsell_sales_sdk4 = require("smartsell-sales-sdk");
253
335
 
254
336
  // src/components/Modal.tsx
255
- var import_react2 = require("react");
337
+ var import_react3 = require("react");
256
338
  var import_jsx_runtime3 = require("react/jsx-runtime");
257
339
  var defaultThemeColors = {
258
340
  background: "#f8fafc",
@@ -396,15 +478,27 @@ function StandardModal({
396
478
  closeOnBackdrop = true,
397
479
  closeOnEscape = true,
398
480
  hideCloseButton = false,
481
+ hideExpandButton = false,
482
+ maximized,
399
483
  contentStyle,
400
484
  theme
401
485
  }) {
402
- const modalTheme = (0, import_react2.useMemo)(() => resolveTheme(theme), [theme]);
403
- const titleId = (0, import_react2.useMemo)(
486
+ const modalTheme = (0, import_react3.useMemo)(() => resolveTheme(theme), [theme]);
487
+ const [isMaximized, setIsMaximized] = (0, import_react3.useState)(maximized != null ? maximized : false);
488
+ const titleId = (0, import_react3.useMemo)(
404
489
  () => `smartsell-modal-${String(title != null ? title : "dialog").toLowerCase().replace(/[^a-z0-9]+/g, "-")}`,
405
490
  [title]
406
491
  );
407
- (0, import_react2.useEffect)(() => {
492
+ (0, import_react3.useEffect)(() => {
493
+ if (typeof maximized === "boolean") {
494
+ setIsMaximized(maximized);
495
+ return;
496
+ }
497
+ if (isLikelyMobileViewport()) {
498
+ setIsMaximized(true);
499
+ }
500
+ }, [maximized]);
501
+ (0, import_react3.useEffect)(() => {
408
502
  if (!isOpen || typeof window === "undefined" || typeof document === "undefined") {
409
503
  return;
410
504
  }
@@ -471,7 +565,7 @@ function StandardModal({
471
565
  display: "flex",
472
566
  alignItems: "center",
473
567
  justifyContent: "center",
474
- padding: 16,
568
+ padding: isMaximized ? 0 : 16,
475
569
  backgroundColor: modalTheme.overlay,
476
570
  backdropFilter: "blur(8px)"
477
571
  },
@@ -479,9 +573,14 @@ function StandardModal({
479
573
  "div",
480
574
  {
481
575
  style: {
482
- width: "min(100%, 100%)",
483
- maxWidth: normalizeWidth(maxWidth),
484
- borderRadius: 30,
576
+ position: "relative",
577
+ display: "flex",
578
+ flexDirection: "column",
579
+ width: isMaximized ? "100vw" : "min(100%, 100%)",
580
+ maxWidth: isMaximized ? "100vw" : normalizeWidth(maxWidth),
581
+ height: isMaximized ? "100vh" : void 0,
582
+ maxHeight: isMaximized ? "100vh" : "calc(100vh - 32px)",
583
+ borderRadius: isMaximized ? 0 : 30,
485
584
  border: `1px solid ${modalTheme.borderSoft}`,
486
585
  background: `linear-gradient(180deg, ${modalTheme.surfaceRaised}, ${modalTheme.colors.surface})`,
487
586
  boxShadow: `0 34px 80px ${withAlpha4("#020617", 0.28)}`,
@@ -498,34 +597,69 @@ function StandardModal({
498
597
  alignItems: "flex-start",
499
598
  justifyContent: "space-between",
500
599
  gap: 16,
501
- padding: "24px 24px 0"
600
+ padding: "24px 24px 16px",
601
+ borderBottom: `1px solid ${withAlpha4(modalTheme.colors.onSurface, 0.06)}`
502
602
  },
503
603
  children: [
504
604
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { flex: 1 }, children: header }),
505
- !hideCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
506
- "button",
507
- {
508
- "aria-label": "Close modal",
509
- type: "button",
510
- onClick: onClose,
511
- style: {
512
- height: 42,
513
- width: 42,
514
- borderRadius: 999,
515
- border: `1px solid ${modalTheme.borderSoft}`,
516
- backgroundColor: "transparent",
517
- color: modalTheme.colors.onSurface,
518
- cursor: "pointer",
519
- fontSize: 20,
520
- fontWeight: 700
521
- },
522
- children: "\xD7"
523
- }
524
- ) : null
605
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
606
+ !hideExpandButton ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
607
+ "button",
608
+ {
609
+ "aria-label": isMaximized ? "Minimize modal" : "Maximize modal",
610
+ title: isMaximized ? "Minimize" : "Maximize",
611
+ type: "button",
612
+ onClick: () => setIsMaximized((current) => !current),
613
+ style: {
614
+ height: 42,
615
+ width: 42,
616
+ borderRadius: 999,
617
+ border: `1px solid ${modalTheme.borderSoft}`,
618
+ backgroundColor: "transparent",
619
+ color: modalTheme.colors.onSurface,
620
+ cursor: "pointer",
621
+ fontSize: 18,
622
+ fontWeight: 700
623
+ },
624
+ children: isMaximized ? "\u25A2" : "\u25A1"
625
+ }
626
+ ) : null,
627
+ !hideCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
628
+ "button",
629
+ {
630
+ "aria-label": "Close modal",
631
+ type: "button",
632
+ onClick: onClose,
633
+ style: {
634
+ height: 42,
635
+ width: 42,
636
+ borderRadius: 999,
637
+ border: `1px solid ${modalTheme.borderSoft}`,
638
+ backgroundColor: "transparent",
639
+ color: modalTheme.colors.onSurface,
640
+ cursor: "pointer",
641
+ fontSize: 20,
642
+ fontWeight: 700
643
+ },
644
+ children: "\xD7"
645
+ }
646
+ ) : null
647
+ ] })
525
648
  ]
526
649
  }
527
650
  ),
528
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { padding: 24 }, children }),
651
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
652
+ "div",
653
+ {
654
+ style: {
655
+ flex: 1,
656
+ minHeight: 0,
657
+ overflow: "auto",
658
+ padding: 24
659
+ },
660
+ children
661
+ }
662
+ ),
529
663
  footer ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
530
664
  "div",
531
665
  {
@@ -533,7 +667,7 @@ function StandardModal({
533
667
  display: "flex",
534
668
  justifyContent: "flex-end",
535
669
  gap: 12,
536
- padding: "0 24px 24px",
670
+ padding: "16px 24px 24px",
537
671
  borderTop: `1px solid ${withAlpha4(modalTheme.colors.onSurface, 0.06)}`
538
672
  },
539
673
  children: footer
@@ -564,10 +698,10 @@ function LegacyModal({
564
698
  maximized,
565
699
  theme
566
700
  }) {
567
- const modalTheme = (0, import_react2.useMemo)(() => resolveTheme(theme), [theme]);
568
- const [isMaximized, setIsMaximized] = (0, import_react2.useState)(maximized != null ? maximized : false);
701
+ const modalTheme = (0, import_react3.useMemo)(() => resolveTheme(theme), [theme]);
702
+ const [isMaximized, setIsMaximized] = (0, import_react3.useState)(maximized != null ? maximized : false);
569
703
  const resolvedAction = action != null ? action : (() => null);
570
- (0, import_react2.useEffect)(() => {
704
+ (0, import_react3.useEffect)(() => {
571
705
  if (maximized === void 0 && isLikelyMobileViewport()) {
572
706
  setIsMaximized(true);
573
707
  }
@@ -850,6 +984,8 @@ function ComposableModal({
850
984
  isBusy = false,
851
985
  closeOnBackdrop = true,
852
986
  closeOnEscape = true,
987
+ hideExpandButton = false,
988
+ maximized,
853
989
  hideDefaultFooter = false,
854
990
  maxWidth,
855
991
  headerFallback,
@@ -858,7 +994,7 @@ function ComposableModal({
858
994
  }) {
859
995
  const theme = useUiKitTheme(sdk);
860
996
  const slotIds = createModalSlotIds(slotBaseId);
861
- const context = (0, import_react3.useMemo)(
997
+ const context = (0, import_react4.useMemo)(
862
998
  () => ({
863
999
  title,
864
1000
  description,
@@ -916,6 +1052,8 @@ function ComposableModal({
916
1052
  footer: footerContent,
917
1053
  theme,
918
1054
  maxWidth,
1055
+ hideExpandButton,
1056
+ maximized,
919
1057
  closeOnBackdrop,
920
1058
  closeOnEscape,
921
1059
  children: bodyContent