@freeappstore/sdk 0.15.9 → 0.16.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.
package/README.md CHANGED
@@ -282,3 +282,19 @@ https://freeappstore.online/skills.md
282
282
  ## License
283
283
 
284
284
  MIT.
285
+
286
+ ## Tailwind styling (SDK 0.16+)
287
+
288
+ React UI requires Tailwind 4. SDK styles are compiled by your app; they are no
289
+ longer injected at runtime. In `web/src/index.css`, after the Tailwind import, add:
290
+
291
+ ```css
292
+ @source "../node_modules/@freeappstore/sdk/dist";
293
+ @source "../../node_modules/@freeappstore/sdk/dist";
294
+ ```
295
+
296
+ Paths are relative to the stylesheet and cover web-local and root-hoisted installs.
297
+ Also add the token `@theme inline` mapping and animation keyframes from
298
+ [the styling guide](https://github.com/freeappstore-online/platform/blob/main/docs/ui.md#styling).
299
+ Both official templates include the complete setup. Floating UI uses opaque
300
+ `--popover` (default `var(--paper)`); `--panel` is opaque and glass is opt-in.
package/dist/logger.d.ts CHANGED
@@ -35,7 +35,7 @@ export interface BuildMeta {
35
35
  viewport: string;
36
36
  theme?: string | undefined;
37
37
  }
38
- export declare const SDK_VERSION = "0.15.8";
38
+ export declare const SDK_VERSION = "0.16.0";
39
39
  export declare class Logger {
40
40
  private readonly appId;
41
41
  private readonly apiBase;
package/dist/logger.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Must track package.json version — bumped on release. Guarded by version.test.ts
2
2
  // so a forgotten bump fails CI instead of silently misattributing telemetry.
3
- export const SDK_VERSION = '0.15.8';
3
+ export const SDK_VERSION = '0.16.0';
4
4
  const MEMORY_LIMIT = 200;
5
5
  const STORAGE_LIMIT = 500;
6
6
  const STORAGE_KEY_PREFIX = 'fas_logs:';
@@ -9,15 +9,17 @@ export interface BadgeProps {
9
9
  children: ReactNode;
10
10
  variant?: 'default' | 'accent' | 'success' | 'warning' | 'danger';
11
11
  style?: CSSProperties;
12
+ className?: string;
12
13
  }
13
- export declare function Badge({ children, variant, style: extraStyle }: BadgeProps): import("react").JSX.Element;
14
+ export declare function Badge({ children, variant, style: extraStyle, className }: BadgeProps): import("react").JSX.Element;
14
15
  export interface CardProps {
15
16
  children: ReactNode;
16
17
  onClick?: () => void;
17
18
  padding?: string;
18
19
  style?: CSSProperties;
20
+ className?: string;
19
21
  }
20
- export declare function Card({ children, onClick, padding, style: extraStyle }: CardProps): import("react").JSX.Element;
22
+ export declare function Card({ children, onClick, padding, style: extraStyle, className, }: CardProps): import("react").JSX.Element;
21
23
  export interface TabsProps {
22
24
  tabs: Array<{
23
25
  key: string;
@@ -26,8 +28,9 @@ export interface TabsProps {
26
28
  active: string;
27
29
  onChange: (key: string) => void;
28
30
  style?: CSSProperties;
31
+ className?: string;
29
32
  }
30
- export declare function Tabs({ tabs, active, onChange, style: extraStyle }: TabsProps): import("react").JSX.Element;
33
+ export declare function Tabs({ tabs, active, onChange, style: extraStyle, className }: TabsProps): import("react").JSX.Element;
31
34
  export interface ModalProps {
32
35
  open: boolean;
33
36
  onClose: () => void;
@@ -81,8 +84,9 @@ export interface SearchInputProps {
81
84
  onChange: (value: string) => void;
82
85
  placeholder?: string;
83
86
  style?: CSSProperties;
87
+ className?: string;
84
88
  }
85
- export declare function SearchInput({ value, onChange, placeholder, style: extraStyle, }: SearchInputProps): import("react").JSX.Element;
89
+ export declare function SearchInput({ value, onChange, placeholder, style: extraStyle, className, }: SearchInputProps): import("react").JSX.Element;
86
90
  export interface ListRowProps {
87
91
  icon?: ReactNode;
88
92
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/ui/components.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/ui/components.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,OAAO,CAAC,EAAE,IAAS,EAAE,KAAuB,EAAE,EAAE,YAAY,+BAQ3E;AAMD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAClE,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAmB,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,UAAU,+BAyBhG;AAMD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,OAAO,EACP,OAAgB,EAChB,KAAK,EAAE,UAAU,EACjB,SAAS,GACV,EAAE,SAAS,+BA6BX;AAMD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,+BAyCvF;AAMD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAeD;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,KAAK,EACL,SAAS,EACT,aAAoB,EACpB,QAAc,GACf,EAAE,UAAU,sCAsHZ;AAMD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,KAAK,EACL,OAAO,EACP,YAAwB,EACxB,OAAmB,EACnB,aAAoB,GACrB,EAAE,kBAAkB,+BA0CpB;AAMD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe,+BAW3E;AAMD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,GAAS,EACT,KAAuB,EACvB,MAAU,EACV,KAAK,GACN,EAAE,gBAAgB,+BAkBlB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAyB,EACzB,KAAK,EAAE,UAAU,EACjB,SAAS,GACV,EAAE,gBAAgB,+BA8BlB;AAMD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,YAAY,+BAoCjF;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AACD,UAAU,kBAAkB;IAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,qBAAa,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACzE,KAAK,EAAE,kBAAkB,CAAmB;IACrD,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB;IAGxD,MAAM;CAahB;AAMD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,YAAY,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,cAAc,sCAsE9E;AAMD,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,sCA8B3C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAiBvC;AAED,wBAAgB,SAAS,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,cAAc,+BAgCjF"}
@@ -1,104 +1,87 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Component, useEffect, useId, useRef, useState, } from 'react';
3
- // Inject keyframes once
4
- if (typeof document !== 'undefined' && !document.getElementById('fas-ui-keyframes')) {
5
- const style = document.createElement('style');
6
- style.id = 'fas-ui-keyframes';
7
- style.textContent =
8
- '@keyframes fas-spin{to{transform:rotate(360deg)}}@keyframes fas-fade-in{from{opacity:0}to{opacity:1}}@keyframes fas-slide-up{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}';
9
- document.head.appendChild(style);
10
- }
11
3
  export function Spinner({ size = 24, color = 'var(--accent)' }) {
12
- return (_jsx("div", { style: {
13
- width: size,
14
- height: size,
15
- border: '2px solid var(--line)',
16
- borderTopColor: color,
17
- borderRadius: '50%',
18
- animation: 'fas-spin 0.6s linear infinite',
19
- } }));
4
+ return (_jsx("div", { className: "border-2 border-line rounded-full motion-safe:animate-spin",
5
+ // Dynamic: Spinner size and color come from caller props.
6
+ style: { width: size, height: size, borderTopColor: color } }));
20
7
  }
21
- const badgeColors = {
22
- default: {
23
- bg: 'var(--panel)',
24
- color: 'var(--muted)',
25
- border: 'var(--line)',
26
- },
27
- accent: {
28
- bg: 'var(--accent-soft)',
29
- color: 'var(--accent)',
30
- border: 'var(--accent)',
31
- },
32
- success: {
33
- bg: 'var(--success-soft, #f0fdf4)',
34
- color: 'var(--success, #16a34a)',
35
- border: '#86efac',
36
- },
37
- warning: {
38
- bg: 'var(--warning-soft, #fefce8)',
39
- color: 'var(--warning, #ca8a04)',
40
- border: '#fde047',
41
- },
42
- danger: { bg: 'var(--danger-soft, #fef2f2)', color: 'var(--danger, #dc2626)', border: '#fecaca' },
8
+ const badgeClasses = {
9
+ default: 'bg-panel text-muted border-line',
10
+ accent: 'bg-accent-soft text-accent border-accent',
11
+ success: 'bg-success-soft text-success border-success',
12
+ warning: 'bg-warning-soft text-warning border-warning',
13
+ danger: 'bg-danger-soft text-danger border-danger',
43
14
  };
44
- export function Badge({ children, variant = 'default', style: extraStyle }) {
45
- const c = badgeColors[variant] ?? badgeColors.default;
46
- return (_jsx("span", { style: {
47
- display: 'inline-flex',
48
- alignItems: 'center',
49
- gap: '0.25rem',
50
- padding: '0.15rem 0.5rem',
51
- borderRadius: '9999px',
52
- fontSize: '0.75rem',
53
- fontWeight: 600,
54
- lineHeight: 1.4,
55
- background: c.bg,
56
- color: c.color,
57
- border: `1px solid ${c.border}`,
58
- ...extraStyle,
59
- }, children: children }));
15
+ export function Badge({ children, variant = 'default', style: extraStyle, className }) {
16
+ const palette = badgeClasses[variant];
17
+ return (_jsx("span", { className: [
18
+ 'inline-flex',
19
+ 'items-center',
20
+ 'gap-1',
21
+ 'p-[0.15rem_0.5rem]',
22
+ 'rounded-full',
23
+ 'text-[0.75rem]',
24
+ 'font-semibold',
25
+ 'leading-[1.4]',
26
+ 'border',
27
+ palette,
28
+ className,
29
+ ]
30
+ .filter(Boolean)
31
+ .join(' '),
32
+ // Dynamic: Caller-supplied appearance remains supported for compatibility; prefer className.
33
+ style: { ...extraStyle }, children: children }));
60
34
  }
61
- export function Card({ children, onClick, padding = '1rem', style: extraStyle }) {
35
+ export function Card({ children, onClick, padding = '1rem', style: extraStyle, className, }) {
62
36
  const interactive = !!onClick;
63
37
  const Tag = interactive ? 'button' : 'div';
64
- return (_jsx(Tag, { onClick: onClick, style: {
65
- display: 'block',
66
- width: '100%',
67
- textAlign: 'left',
68
- padding,
69
- borderRadius: 'var(--radius, 0.75rem)',
70
- border: '1px solid var(--line)',
71
- background: 'var(--panel)',
72
- cursor: interactive ? 'pointer' : undefined,
73
- fontFamily: 'inherit',
74
- fontSize: 'inherit',
75
- color: 'inherit',
76
- transition: 'border-color 0.15s',
77
- ...(interactive ? { outline: 'none' } : {}),
78
- ...extraStyle,
79
- }, children: children }));
38
+ return (_jsx(Tag, { onClick: onClick, className: [
39
+ 'block',
40
+ 'w-full',
41
+ 'text-left',
42
+ 'rounded',
43
+ 'border border-line',
44
+ 'bg-panel',
45
+ interactive ? 'cursor-pointer' : '',
46
+ 'font-[inherit]',
47
+ 'text-[inherit]',
48
+ 'text-inherit',
49
+ 'transition-colors duration-150',
50
+ 'focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2',
51
+ className,
52
+ ]
53
+ .filter(Boolean)
54
+ .join(' '),
55
+ // Dynamic: Card padding and appearance come from caller props.
56
+ style: { padding: padding, ...extraStyle }, children: children }));
80
57
  }
81
- export function Tabs({ tabs, active, onChange, style: extraStyle }) {
82
- return (_jsx("div", { style: {
83
- display: 'inline-flex',
84
- gap: '0.25rem',
85
- padding: '0.25rem',
86
- borderRadius: '9999px',
87
- border: '1px solid var(--line)',
88
- background: 'var(--panel)',
89
- ...extraStyle,
90
- }, children: tabs.map((tab) => (_jsx("button", { onClick: () => onChange(tab.key), style: {
91
- padding: '0.35rem 0.85rem',
92
- borderRadius: '9999px',
93
- border: 'none',
94
- fontSize: '0.8rem',
95
- fontWeight: 600,
96
- cursor: 'pointer',
97
- fontFamily: 'inherit',
98
- transition: 'all 0.15s',
99
- background: active === tab.key ? 'var(--ink)' : 'transparent',
100
- color: active === tab.key ? 'var(--panel)' : 'var(--muted)',
101
- }, children: tab.label }, tab.key))) }));
58
+ export function Tabs({ tabs, active, onChange, style: extraStyle, className }) {
59
+ return (_jsx("div", { className: [
60
+ 'inline-flex',
61
+ 'gap-1',
62
+ 'p-1',
63
+ 'rounded-full',
64
+ 'border border-line',
65
+ 'bg-panel',
66
+ className,
67
+ ]
68
+ .filter(Boolean)
69
+ .join(' '),
70
+ // Dynamic: Caller-supplied appearance remains supported for compatibility; prefer className.
71
+ style: { ...extraStyle }, children: tabs.map((tab) => (_jsx("button", { onClick: () => onChange(tab.key), className: [
72
+ 'p-[0.35rem_0.85rem]',
73
+ 'rounded-full',
74
+ 'border-0',
75
+ 'text-[0.8rem]',
76
+ 'font-semibold',
77
+ 'cursor-pointer',
78
+ 'font-[inherit]',
79
+ 'transition-all duration-150',
80
+ active === tab.key ? 'bg-ink' : 'bg-transparent',
81
+ active === tab.key ? 'text-panel' : 'text-muted',
82
+ ]
83
+ .filter(Boolean)
84
+ .join(' '), children: tab.label }, tab.key))) }));
102
85
  }
103
86
  const FOCUSABLE = 'a[href], area[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), iframe, [contenteditable="true"], [tabindex]:not([tabindex="-1"])';
104
87
  /** Focusable elements inside `root`, in tab order, skipping hidden ones. */
@@ -199,153 +182,62 @@ export function Modal({ open, onClose, children, title, ariaLabel, closeOnEscape
199
182
  }, [open]);
200
183
  if (!open)
201
184
  return null;
202
- return (_jsx("div", { onClick: onClose, style: {
203
- position: 'fixed',
204
- inset: 0,
205
- zIndex: 999,
206
- background: 'rgba(0,0,0,0.5)',
207
- backdropFilter: 'blur(4px)',
208
- display: 'flex',
209
- alignItems: 'center',
210
- justifyContent: 'center',
211
- padding: '1rem',
212
- animation: 'fas-fade-in 0.15s',
213
- }, children: _jsxs("div", { ref: dialogRef, role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": title ? undefined : ariaLabel, tabIndex: -1, onClick: (e) => e.stopPropagation(), style: {
214
- outline: 'none',
215
- background: 'var(--panel)',
216
- border: '1px solid var(--line)',
217
- borderRadius: 'var(--radius-lg, var(--radius, 0.75rem))',
218
- maxWidth,
219
- width: '100%',
220
- maxHeight: '85dvh',
221
- overflow: 'auto',
222
- animation: 'fas-slide-up 0.2s',
223
- }, children: [title && (_jsxs("div", { style: {
224
- display: 'flex',
225
- alignItems: 'center',
226
- justifyContent: 'space-between',
227
- padding: '1rem 1.25rem',
228
- borderBottom: '1px solid var(--line)',
229
- }, children: [_jsx("h2", { id: titleId, style: { margin: 0, fontSize: '1rem', fontWeight: 700, color: 'var(--ink)' }, children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", style: {
230
- background: 'none',
231
- border: 'none',
232
- cursor: 'pointer',
233
- padding: '0.25rem',
234
- color: 'var(--muted)',
235
- fontSize: '1.25rem',
236
- lineHeight: 1,
237
- fontFamily: 'inherit',
238
- }, children: "\u00D7" })] })), _jsx("div", { ref: contentRef, style: { padding: '1.25rem' }, children: children })] }) }));
185
+ return (_jsx("div", { onClick: onClose, className: "fixed inset-0 z-[999] bg-scrim backdrop-blur-[4px] flex items-center justify-center p-4 motion-safe:animate-sdk-fade-in", children: _jsxs("div", { ref: dialogRef, role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": title ? undefined : ariaLabel, tabIndex: -1, onClick: (e) => e.stopPropagation(), className: "outline-none bg-popover border border-line rounded-lg w-full max-h-[85dvh] overflow-auto motion-safe:animate-sdk-slide-up",
186
+ // Dynamic: Dialog maximum width comes from the caller prop.
187
+ style: { maxWidth: maxWidth }, children: [title && (_jsxs("div", { className: "flex items-center justify-between p-[1rem_1.25rem] border-b border-line", children: [_jsx("h2", { id: titleId, className: "m-0 text-[1rem] font-bold text-ink", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "bg-transparent border-0 cursor-pointer p-1 text-muted text-[1.25rem] leading-[1] font-[inherit]", children: "\u00D7" })] })), _jsx("div", { ref: contentRef, className: "p-5", children: children })] }) }));
239
188
  }
240
189
  export function ConfirmDialog({ open, onConfirm, onCancel, title, message, confirmLabel = 'Confirm', variant = 'default', closeOnEscape = true, }) {
241
190
  const isDanger = variant === 'danger';
242
191
  return (
243
192
  // Focus starts on Cancel (the first button), the safe choice for a destructive confirm.
244
- _jsxs(Modal, { open: open, onClose: onCancel, title: title, maxWidth: 400, closeOnEscape: closeOnEscape, children: [_jsx("p", { style: { fontSize: '0.9rem', color: 'var(--muted)', margin: '0 0 1.25rem' }, children: message }), _jsxs("div", { style: { display: 'flex', gap: '0.5rem', justifyContent: 'flex-end' }, children: [_jsx("button", { type: "button", onClick: onCancel, style: {
245
- padding: '0.5rem 1rem',
246
- borderRadius: 'var(--radius-sm, 0.5rem)',
247
- border: '1px solid var(--line)',
248
- background: 'transparent',
249
- color: 'var(--ink)',
250
- fontSize: '0.85rem',
251
- fontWeight: 600,
252
- cursor: 'pointer',
253
- fontFamily: 'inherit',
254
- }, children: "Cancel" }), _jsx("button", { type: "button", onClick: onConfirm, style: {
255
- padding: '0.5rem 1rem',
256
- borderRadius: 'var(--radius-sm, 0.5rem)',
257
- border: 'none',
258
- fontSize: '0.85rem',
259
- fontWeight: 600,
260
- cursor: 'pointer',
261
- fontFamily: 'inherit',
262
- background: isDanger ? 'var(--danger, #dc2626)' : 'var(--accent)',
263
- color: '#fff',
264
- }, children: confirmLabel })] })] }));
193
+ _jsxs(Modal, { open: open, onClose: onCancel, title: title, maxWidth: 400, closeOnEscape: closeOnEscape, children: [_jsx("p", { className: "text-[0.9rem] text-muted m-[0_0_1.25rem]", children: message }), _jsxs("div", { className: "flex gap-2 justify-end", children: [_jsx("button", { type: "button", onClick: onCancel, className: "p-[0.5rem_1rem] rounded-sm border border-line bg-transparent text-ink text-[0.85rem] font-semibold cursor-pointer font-[inherit]", children: "Cancel" }), _jsx("button", { type: "button", onClick: onConfirm, className: [
194
+ 'p-[0.5rem_1rem]',
195
+ 'rounded-sm',
196
+ 'border-0',
197
+ 'text-[0.85rem]',
198
+ 'font-semibold',
199
+ 'cursor-pointer',
200
+ 'font-[inherit]',
201
+ isDanger ? 'bg-danger' : 'bg-accent',
202
+ 'text-white',
203
+ ]
204
+ .filter(Boolean)
205
+ .join(' '), children: confirmLabel })] })] }));
265
206
  }
266
207
  export function EmptyState({ icon, title, message, action }) {
267
- return (_jsxs("div", { style: { textAlign: 'center', padding: '3rem 1.5rem' }, children: [icon && (_jsx("div", { style: { marginBottom: '0.75rem', color: 'var(--muted)', fontSize: '2rem' }, children: icon })), title && (_jsx("div", { style: {
268
- fontSize: '1rem',
269
- fontWeight: 700,
270
- color: 'var(--ink)',
271
- marginBottom: '0.35rem',
272
- }, children: title })), _jsx("p", { style: {
273
- fontSize: '0.85rem',
274
- color: 'var(--muted)',
275
- margin: '0 0 1rem',
276
- maxWidth: 320,
277
- marginInline: 'auto',
278
- }, children: message }), action] }));
208
+ return (_jsxs("div", { className: "text-center p-[3rem_1.5rem]", children: [icon && _jsx("div", { className: "mb-3 text-muted text-[2rem]", children: icon }), title && _jsx("div", { className: "text-[1rem] font-bold text-ink mb-[0.35rem]", children: title }), _jsx("p", { className: "text-[0.85rem] text-muted m-[0_0_1rem] max-w-80 [margin-inline:auto]", children: message }), action] }));
279
209
  }
280
210
  export function ProgressBar({ value, max = 100, color = 'var(--accent)', height = 8, label, }) {
281
211
  const pct = Math.min(100, Math.max(0, (value / max) * 100));
282
- return (_jsxs("div", { children: [label && (_jsx("div", { style: {
283
- fontSize: '0.75rem',
284
- fontWeight: 600,
285
- color: 'var(--muted)',
286
- marginBottom: '0.35rem',
287
- }, children: label })), _jsx("div", { style: {
288
- width: '100%',
289
- height,
290
- borderRadius: height,
291
- background: 'var(--line)',
292
- overflow: 'hidden',
293
- }, children: _jsx("div", { style: {
294
- width: `${pct}%`,
295
- height: '100%',
296
- borderRadius: height,
297
- background: color,
298
- transition: 'width 0.3s',
299
- } }) })] }));
212
+ return (_jsxs("div", { children: [label && _jsx("div", { className: "text-[0.75rem] font-semibold text-muted mb-[0.35rem]", children: label }), _jsx("div", { className: "w-full bg-line overflow-hidden",
213
+ // Dynamic: Track height and corner radius follow the caller height prop.
214
+ style: { height: height, borderRadius: height }, children: _jsx("div", { className: "h-full transition-[width] duration-300",
215
+ // Dynamic: Progress width is calculated from value/max; radius and color come from props.
216
+ style: { width: `${pct}%`, borderRadius: height, background: color } }) })] }));
300
217
  }
301
- export function SearchInput({ value, onChange, placeholder = 'Search...', style: extraStyle, }) {
302
- return (_jsxs("div", { style: { position: 'relative', ...extraStyle }, children: [_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "var(--muted)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: {
303
- position: 'absolute',
304
- left: 12,
305
- top: '50%',
306
- transform: 'translateY(-50%)',
307
- pointerEvents: 'none',
308
- }, children: [_jsx("circle", { cx: "11", cy: "11", r: "8" }), _jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })] }), _jsx("input", { type: "text", value: value, onChange: (e) => onChange(e.currentTarget.value), placeholder: placeholder, style: {
309
- width: '100%',
310
- padding: '0.5rem 0.75rem 0.5rem 2.25rem',
311
- borderRadius: '9999px',
312
- border: '1px solid var(--line)',
313
- background: 'var(--panel)',
314
- color: 'var(--ink)',
315
- fontSize: '0.85rem',
316
- fontFamily: 'inherit',
317
- outline: 'none',
318
- } })] }));
218
+ export function SearchInput({ value, onChange, placeholder = 'Search...', style: extraStyle, className, }) {
219
+ return (_jsxs("div", { className: ['relative', className].filter(Boolean).join(' '),
220
+ // Dynamic: Caller-supplied appearance remains supported for compatibility; prefer className.
221
+ style: { ...extraStyle }, children: [_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "var(--muted)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "absolute left-3 top-[50%] [transform:translateY(-50%)] [pointer-events:none]", children: [_jsx("circle", { cx: "11", cy: "11", r: "8" }), _jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })] }), _jsx("input", { type: "text", value: value, onChange: (e) => onChange(e.currentTarget.value), placeholder: placeholder, className: "w-full p-[0.5rem_0.75rem_0.5rem_2.25rem] rounded-full border border-line bg-panel text-ink text-[0.85rem] font-[inherit] outline-none" })] }));
319
222
  }
320
223
  export function ListRow({ icon, title, subtitle, trailing, onClick }) {
321
224
  const Tag = onClick ? 'button' : 'div';
322
- return (_jsxs(Tag, { onClick: onClick, style: {
323
- display: 'flex',
324
- alignItems: 'center',
325
- gap: '0.75rem',
326
- width: '100%',
327
- padding: '0.65rem 0.75rem',
328
- background: 'none',
329
- border: 'none',
330
- borderBottom: '1px solid var(--line)',
331
- textAlign: 'left',
332
- cursor: onClick ? 'pointer' : undefined,
333
- fontFamily: 'inherit',
334
- color: 'inherit',
335
- }, children: [icon && _jsx("div", { style: { flexShrink: 0, color: 'var(--muted)' }, children: icon }), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("div", { style: {
336
- fontSize: '0.9rem',
337
- fontWeight: 600,
338
- color: 'var(--ink)',
339
- overflow: 'hidden',
340
- textOverflow: 'ellipsis',
341
- whiteSpace: 'nowrap',
342
- }, children: title }), subtitle && (_jsx("div", { style: {
343
- fontSize: '0.75rem',
344
- color: 'var(--muted)',
345
- overflow: 'hidden',
346
- textOverflow: 'ellipsis',
347
- whiteSpace: 'nowrap',
348
- }, children: subtitle }))] }), trailing && _jsx("div", { style: { flexShrink: 0 }, children: trailing })] }));
225
+ return (_jsxs(Tag, { onClick: onClick, className: [
226
+ 'flex',
227
+ 'items-center',
228
+ 'gap-3',
229
+ 'w-full',
230
+ 'p-[0.65rem_0.75rem]',
231
+ 'bg-transparent',
232
+ 'border-0',
233
+ 'border-b border-line',
234
+ 'text-left',
235
+ onClick ? 'cursor-pointer' : '',
236
+ 'font-[inherit]',
237
+ 'text-inherit',
238
+ ]
239
+ .filter(Boolean)
240
+ .join(' '), children: [icon && _jsx("div", { className: "shrink-0 text-muted", children: icon }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "text-[0.9rem] font-semibold text-ink overflow-hidden [text-overflow:ellipsis] whitespace-nowrap", children: title }), subtitle && (_jsx("div", { className: "text-[0.75rem] text-muted overflow-hidden [text-overflow:ellipsis] whitespace-nowrap", children: subtitle }))] }), trailing && _jsx("div", { className: "shrink-0", children: trailing })] }));
349
241
  }
350
242
  export class ErrorBoundary extends Component {
351
243
  state = { error: null };
@@ -354,7 +246,7 @@ export class ErrorBoundary extends Component {
354
246
  }
355
247
  render() {
356
248
  if (this.state.error) {
357
- return (this.props.fallback ?? (_jsxs("div", { style: { padding: '2rem', textAlign: 'center' }, children: [_jsx("p", { style: { color: 'var(--danger, #dc2626)', fontWeight: 700, marginBottom: '0.5rem' }, children: "Something went wrong" }), _jsx("p", { style: { color: 'var(--muted)', fontSize: '0.85rem' }, children: this.state.error.message })] })));
249
+ return (this.props.fallback ?? (_jsxs("div", { className: "p-8 text-center", children: [_jsx("p", { className: "text-danger font-bold mb-2", children: "Something went wrong" }), _jsx("p", { className: "text-muted text-[0.85rem]", children: this.state.error.message })] })));
358
250
  }
359
251
  return this.props.children;
360
252
  }
@@ -398,32 +290,8 @@ export function BuildInfo({ version, commit, buildDate, extra }) {
398
290
  };
399
291
  if (!v && !sha && !date)
400
292
  return null;
401
- return (_jsxs(_Fragment, { children: [_jsx("div", { onClick: handleClick, style: {
402
- position: 'fixed',
403
- bottom: 8,
404
- right: 8,
405
- width: 24,
406
- height: 24,
407
- zIndex: 9999,
408
- cursor: 'default',
409
- opacity: 0,
410
- }, "aria-hidden": "true" }), visible && (_jsxs("div", { onClick: () => setVisible(false), style: {
411
- position: 'fixed',
412
- bottom: 8,
413
- right: 8,
414
- zIndex: 9999,
415
- background: 'rgba(0,0,0,0.85)',
416
- color: '#e5e5e5',
417
- padding: '0.5rem 0.75rem',
418
- borderRadius: '0.5rem',
419
- fontSize: '0.7rem',
420
- fontFamily: 'monospace',
421
- lineHeight: 1.6,
422
- maxWidth: 280,
423
- cursor: 'pointer',
424
- animation: 'fas-fade-in 0.15s',
425
- }, children: [v && (_jsxs("div", { children: [_jsx("span", { style: { color: '#94a3b8' }, children: "version " }), v] })), sha && (_jsxs("div", { children: [_jsx("span", { style: { color: '#94a3b8' }, children: "commit " }), sha.slice(0, 7)] })), date && (_jsxs("div", { children: [_jsx("span", { style: { color: '#94a3b8' }, children: "built " }), new Date(date).toLocaleString()] })), extra &&
426
- Object.entries(extra).map(([k, val]) => (_jsxs("div", { children: [_jsx("span", { style: { color: '#94a3b8' }, children: k.padEnd(8) }), val] }, k))), _jsx("div", { style: { color: 'var(--muted)', marginTop: '0.25rem', fontSize: '0.6rem' }, children: "tap to dismiss" })] }))] }));
293
+ return (_jsxs(_Fragment, { children: [_jsx("div", { onClick: handleClick, className: "fixed bottom-2 right-2 w-6 h-6 z-[9999] cursor-default opacity-[0]", "aria-hidden": "true" }), visible && (_jsxs("div", { onClick: () => setVisible(false), className: "fixed bottom-2 right-2 z-[9999] bg-popover text-ink border border-line shadow-lg p-[0.5rem_0.75rem] rounded-[0.5rem] text-[0.7rem] font-mono leading-[1.6] max-w-70 cursor-pointer motion-safe:animate-sdk-fade-in", children: [v && (_jsxs("div", { children: [_jsx("span", { className: "text-muted", children: "version " }), v] })), sha && (_jsxs("div", { children: [_jsx("span", { className: "text-muted", children: "commit " }), sha.slice(0, 7)] })), date && (_jsxs("div", { children: [_jsx("span", { className: "text-muted", children: "built " }), new Date(date).toLocaleString()] })), extra &&
294
+ Object.entries(extra).map(([k, val]) => (_jsxs("div", { children: [_jsx("span", { className: "text-muted", children: k.padEnd(8) }), val] }, k))), _jsx("div", { className: "text-muted mt-1 text-[0.6rem]", children: "tap to dismiss" })] }))] }));
427
295
  }
428
296
  /**
429
297
  * Fixed bottom footer for PWA standalone mode. Shows "Part of FreeAppStore"
@@ -453,27 +321,7 @@ export function Footer({ text }) {
453
321
  }, []);
454
322
  if (!isStandalone)
455
323
  return null;
456
- return (_jsx("footer", { style: {
457
- position: 'fixed',
458
- left: 0,
459
- right: 0,
460
- bottom: 0,
461
- zIndex: 900,
462
- textAlign: 'center',
463
- background: 'var(--panel)',
464
- borderTop: '1px solid var(--line)',
465
- paddingTop: '0.5rem',
466
- paddingBottom: 'calc(0.5rem + env(safe-area-inset-bottom, 0px))',
467
- backdropFilter: 'blur(20px)',
468
- WebkitBackdropFilter: 'blur(20px)',
469
- }, children: _jsx("a", { href: "https://freeappstore.online", target: "_blank", rel: "noopener noreferrer", style: {
470
- fontSize: '0.65rem',
471
- fontWeight: 600,
472
- letterSpacing: '0.05em',
473
- textTransform: 'uppercase',
474
- color: 'var(--muted)',
475
- textDecoration: 'none',
476
- }, children: text ?? 'Part of FreeAppStore' }) }));
324
+ return (_jsx("footer", { className: "fixed left-0 right-0 bottom-0 z-[900] text-center bg-panel border-t border-line pt-2 pb-[calc(0.5rem_+_env(safe-area-inset-bottom,_0px))] backdrop-blur-[20px]", children: _jsx("a", { href: "https://freeappstore.online", target: "_blank", rel: "noopener noreferrer", className: "text-[0.65rem] font-semibold tracking-[0.05em] uppercase text-muted no-underline", children: text ?? 'Part of FreeAppStore' }) }));
477
325
  }
478
326
  /**
479
327
  * Returns true when the app is running in PWA standalone mode (installed
@@ -499,34 +347,6 @@ export function KeyPrompt({ app, provider, providerName, message }) {
499
347
  const name = providerName ?? provider;
500
348
  const msg = message ??
501
349
  `This app uses ${name} and needs your API key. Your key is stored securely on the FreeAppStore platform and is never visible to the app.`;
502
- return (_jsxs("div", { style: {
503
- background: 'var(--panel)',
504
- border: '1px solid var(--line)',
505
- borderRadius: 'var(--radius, 0.75rem)',
506
- padding: '1.5rem',
507
- maxWidth: 420,
508
- margin: '2rem auto',
509
- textAlign: 'center',
510
- }, children: [_jsx("div", { style: { fontSize: '1.5rem', marginBottom: '0.5rem' }, children: _jsx("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "var(--muted)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { display: 'inline-block', verticalAlign: 'middle' }, children: _jsx("path", { d: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" }) }) }), _jsxs("div", { style: {
511
- fontSize: '1rem',
512
- fontWeight: 700,
513
- color: 'var(--ink)',
514
- marginBottom: '0.5rem',
515
- }, children: [name, " API key required"] }), _jsx("p", { style: {
516
- fontSize: '0.85rem',
517
- color: 'var(--muted)',
518
- margin: '0 0 1rem',
519
- lineHeight: 1.5,
520
- }, children: msg }), _jsxs("button", { onClick: () => app.keys.manage(provider), style: {
521
- background: 'var(--accent)',
522
- color: '#fff',
523
- border: 'none',
524
- padding: '0.6rem 1.5rem',
525
- borderRadius: 'var(--radius, 0.75rem)',
526
- fontSize: '0.9rem',
527
- fontWeight: 700,
528
- cursor: 'pointer',
529
- fontFamily: 'inherit',
530
- }, children: ["Configure ", name, " key"] })] }));
350
+ return (_jsxs("div", { className: "bg-panel border border-line rounded p-6 max-w-105 m-[2rem_auto] text-center", children: [_jsx("div", { className: "text-[1.5rem] mb-2", children: _jsx("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "var(--muted)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "inline-block align-middle", children: _jsx("path", { d: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" }) }) }), _jsxs("div", { className: "text-[1rem] font-bold text-ink mb-2", children: [name, " API key required"] }), _jsx("p", { className: "text-[0.85rem] text-muted m-[0_0_1rem] leading-[1.5]", children: msg }), _jsxs("button", { onClick: () => app.keys.manage(provider), className: "bg-accent text-white border-0 p-[0.6rem_1.5rem] rounded text-[0.9rem] font-bold cursor-pointer font-[inherit]", children: ["Configure ", name, " key"] })] }));
531
351
  }
532
352
  //# sourceMappingURL=components.js.map