@drawnagency/primitives 0.1.20 → 0.1.21

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.
@@ -1 +1 @@
1
- {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,sBAAsB,CAAC;AAkC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAqkBP"}
1
+ {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,sBAAsB,CAAC;AAkC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAskBP"}
@@ -3,6 +3,7 @@ interface BuildStatusResult {
3
3
  state: BuildState;
4
4
  deployUrl: string | null;
5
5
  startTracking: () => void;
6
+ dismiss: () => void;
6
7
  }
7
8
  export declare function useBuildStatus(): BuildStatusResult;
8
9
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAS1D,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAID,wBAAgB,cAAc,IAAI,iBAAiB,CA0FlD"}
1
+ {"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAS1D,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAKD,wBAAgB,cAAc,IAAI,iBAAiB,CAsGlD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawnagency/primitives",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -47,7 +47,7 @@ import { SplitButton } from "../shared/SplitButton";
47
47
  import { IconButton } from "../shared/IconButton";
48
48
  import { SegmentedControl } from "../shared/SegmentedControl";
49
49
  import { SettingsIcon } from "../shared/icons";
50
- import { ImageIcon } from "lucide-react";
50
+ import { ImageIcon, X } from "lucide-react";
51
51
  import { ErrorBoundary } from "../shared/ErrorBoundary";
52
52
 
53
53
  export { useMediaLibrary } from "./MediaLibraryContext";
@@ -585,6 +585,7 @@ export default function EditorShell({
585
585
  }}
586
586
  processingItems={mediaPipeline.processingItems}
587
587
  buildState={buildStatus.state}
588
+ onBuildDismiss={buildStatus.dismiss}
588
589
  />
589
590
 
590
591
  <EditorContent
@@ -871,29 +872,51 @@ function GlobalModal() {
871
872
  );
872
873
  }
873
874
 
875
+ function LoadingEllipsis() {
876
+ const [dots, setDots] = useState(0);
877
+ useEffect(() => {
878
+ const id = setInterval(() => setDots((d) => (d + 1) % 4), 400);
879
+ return () => clearInterval(id);
880
+ }, []);
881
+ return <>{".".repeat(dots)}</>;
882
+ }
883
+
874
884
  function StatusText({
875
885
  publishAction,
876
886
  publishFeedback,
877
887
  buildState,
888
+ onDismiss,
878
889
  }: {
879
890
  publishAction: "idle" | "saving" | "publishing";
880
891
  publishFeedback: string | null;
881
892
  buildState: "idle" | "building" | "ready" | "error";
893
+ onDismiss: () => void;
882
894
  }) {
883
895
  if (publishAction === "saving") {
884
- return <span className="text-xs font-medium text-base-content/60">Saving changes...</span>;
885
- }
886
- if (publishAction === "publishing") {
887
- return <span className="text-xs font-medium text-base-content/60">Publishing...</span>;
896
+ return <span className="text-xs font-medium text-base-content/60">Saving changes<LoadingEllipsis /></span>;
888
897
  }
889
- if (buildState === "building") {
890
- return <span className="text-xs font-medium text-orange-600">Publishing...</span>;
898
+ if (publishAction === "publishing" || buildState === "building") {
899
+ return <span className="text-xs font-medium text-base-content/60">Publishing<LoadingEllipsis /></span>;
891
900
  }
892
901
  if (buildState === "ready") {
893
- return <span className="text-xs font-medium text-green-600">Published</span>;
902
+ return (
903
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-green-600">
904
+ <button type="button" onClick={onDismiss} className="text-base-content/30 hover:text-base-content/60 cursor-pointer" aria-label="Dismiss">
905
+ <X size={12} />
906
+ </button>
907
+ Published
908
+ </span>
909
+ );
894
910
  }
895
911
  if (buildState === "error") {
896
- return <span className="text-xs font-medium text-red-600">Publish failed</span>;
912
+ return (
913
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-red-600">
914
+ <button type="button" onClick={onDismiss} className="text-base-content/30 hover:text-base-content/60 cursor-pointer" aria-label="Dismiss">
915
+ <X size={12} />
916
+ </button>
917
+ Publish failed
918
+ </span>
919
+ );
897
920
  }
898
921
  if (publishFeedback) {
899
922
  return (
@@ -921,6 +944,7 @@ function EditorToolbar({
921
944
  onMediaClick,
922
945
  processingItems,
923
946
  buildState,
947
+ onBuildDismiss,
924
948
  }: {
925
949
  buttonState: "synced" | "publish" | "saveAndPublish";
926
950
  localChangesExist: boolean;
@@ -934,6 +958,7 @@ function EditorToolbar({
934
958
  onMediaClick: () => void;
935
959
  processingItems: QueueItem[];
936
960
  buildState: "idle" | "building" | "ready" | "error";
961
+ onBuildDismiss: () => void;
937
962
  }) {
938
963
  const { isEditMode, viewBranch, setViewBranch, toggleEditMode } = useEditorContext();
939
964
 
@@ -981,6 +1006,7 @@ function EditorToolbar({
981
1006
  publishAction={publishAction}
982
1007
  publishFeedback={publishFeedback}
983
1008
  buildState={buildState}
1009
+ onDismiss={onBuildDismiss}
984
1010
  />
985
1011
  </div>
986
1012
  <div className="flex items-center justify-end gap-2">
@@ -13,14 +13,17 @@ interface BuildStatusResult {
13
13
  state: BuildState;
14
14
  deployUrl: string | null;
15
15
  startTracking: () => void;
16
+ dismiss: () => void;
16
17
  }
17
18
 
18
19
  const POLL_INTERVAL = 5000;
20
+ const AUTO_CLEAR_DELAY = 5000;
19
21
 
20
22
  export function useBuildStatus(): BuildStatusResult {
21
23
  const [state, setState] = useState<BuildState>("idle");
22
24
  const [deployUrl, setDeployUrl] = useState<string | null>(null);
23
25
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
26
+ const clearRef = useRef<ReturnType<typeof setTimeout> | null>(null);
24
27
  const isPolling = useRef(false);
25
28
 
26
29
  const stopPolling = useCallback(() => {
@@ -63,6 +66,9 @@ export function useBuildStatus(): BuildStatusResult {
63
66
 
64
67
  if (data.state === "ready" || data.state === "error") {
65
68
  stopPolling();
69
+ if (data.state === "ready") {
70
+ clearRef.current = setTimeout(() => setState("idle"), AUTO_CLEAR_DELAY);
71
+ }
66
72
  }
67
73
  },
68
74
  [stopPolling],
@@ -97,14 +103,22 @@ export function useBuildStatus(): BuildStatusResult {
97
103
  return () => {
98
104
  cancelled = true;
99
105
  stopPolling();
106
+ if (clearRef.current) clearTimeout(clearRef.current);
100
107
  };
101
108
  }, [fetchStatus, handleStatusUpdate, startPolling, stopPolling]);
102
109
 
103
110
  const startTracking = useCallback(() => {
111
+ if (clearRef.current) { clearTimeout(clearRef.current); clearRef.current = null; }
104
112
  setState("building");
105
113
  setDeployUrl(null);
106
114
  startPolling();
107
115
  }, [startPolling]);
108
116
 
109
- return { state, deployUrl, startTracking };
117
+ const dismiss = useCallback(() => {
118
+ if (clearRef.current) { clearTimeout(clearRef.current); clearRef.current = null; }
119
+ setState("idle");
120
+ stopPolling();
121
+ }, [stopPolling]);
122
+
123
+ return { state, deployUrl, startTracking, dismiss };
110
124
  }