tempest-react-sdk 0.25.0 → 0.26.1
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 +14 -1
- package/bin/lib/alias/collect.mjs +94 -0
- package/bin/lib/alias/collect.test.mjs +95 -0
- package/bin/lib/alias/discover.mjs +77 -0
- package/bin/lib/alias/discover.test.mjs +189 -0
- package/bin/lib/alias/index.mjs +88 -0
- package/bin/lib/alias/index.test.mjs +138 -0
- package/bin/lib/alias/rewrite-css.mjs +76 -0
- package/bin/lib/alias/rewrite-css.test.mjs +85 -0
- package/bin/lib/alias/rewrite.mjs +141 -0
- package/bin/lib/alias/rewrite.test.mjs +148 -0
- package/bin/lib/alias/specifier.mjs +49 -0
- package/bin/lib/alias/specifier.test.mjs +85 -0
- package/bin/lib/alias/tsconfig.mjs +116 -0
- package/bin/lib/alias/typescript.mjs +23 -0
- package/bin/lib/doctor/lucide.mjs +74 -0
- package/bin/lib/doctor/lucide.test.mjs +107 -0
- package/bin/lib/icons/generate.mjs +156 -0
- package/bin/lib/icons/generate.test.mjs +125 -0
- package/bin/tempest.mjs +174 -13
- package/dist/audio/use-audio.cjs +1 -1
- package/dist/audio/use-audio.cjs.map +1 -1
- package/dist/audio/use-audio.js +12 -12
- package/dist/audio/use-audio.js.map +1 -1
- package/dist/charts/palette.cjs +1 -1
- package/dist/charts/palette.cjs.map +1 -1
- package/dist/charts/palette.js +2 -2
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts.d.ts +5 -3
- package/dist/components/ClickOutside/ClickOutside.cjs +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.js +3 -1
- package/dist/components/ClickOutside/ClickOutside.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +21 -23
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/Kanban/Kanban.cjs +2 -0
- package/dist/components/Kanban/Kanban.cjs.map +1 -0
- package/dist/components/Kanban/Kanban.js +102 -0
- package/dist/components/Kanban/Kanban.js.map +1 -0
- package/dist/components/Kanban/Kanban.module.cjs +2 -0
- package/dist/components/Kanban/Kanban.module.cjs.map +1 -0
- package/dist/components/Kanban/Kanban.module.js +19 -0
- package/dist/components/Kanban/Kanban.module.js.map +1 -0
- package/dist/components/NotificationCenter/NotificationCenter.cjs +2 -0
- package/dist/components/NotificationCenter/NotificationCenter.cjs.map +1 -0
- package/dist/components/NotificationCenter/NotificationCenter.js +83 -0
- package/dist/components/NotificationCenter/NotificationCenter.js.map +1 -0
- package/dist/components/NotificationCenter/NotificationCenter.module.cjs +2 -0
- package/dist/components/NotificationCenter/NotificationCenter.module.cjs.map +1 -0
- package/dist/components/NotificationCenter/NotificationCenter.module.js +21 -0
- package/dist/components/NotificationCenter/NotificationCenter.module.js.map +1 -0
- package/dist/components/NotificationCenter/use-notification-inbox.cjs +2 -0
- package/dist/components/NotificationCenter/use-notification-inbox.cjs.map +1 -0
- package/dist/components/NotificationCenter/use-notification-inbox.js +63 -0
- package/dist/components/NotificationCenter/use-notification-inbox.js.map +1 -0
- package/dist/components/RefreshIndicator/RefreshIndicator.cjs +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.cjs.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.js +17 -17
- package/dist/components/RefreshIndicator/RefreshIndicator.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.cjs +1 -1
- package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.js +26 -20
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs +2 -0
- package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -0
- package/dist/components/VirtualTable/VirtualTable.js +116 -0
- package/dist/components/VirtualTable/VirtualTable.js.map +1 -0
- package/dist/components/VirtualTable/VirtualTable.module.cjs +2 -0
- package/dist/components/VirtualTable/VirtualTable.module.cjs.map +1 -0
- package/dist/components/VirtualTable/VirtualTable.module.js +20 -0
- package/dist/components/VirtualTable/VirtualTable.module.js.map +1 -0
- package/dist/components/Wizard/Wizard.cjs +1 -1
- package/dist/components/Wizard/Wizard.cjs.map +1 -1
- package/dist/components/Wizard/Wizard.js +53 -53
- package/dist/components/Wizard/Wizard.js.map +1 -1
- package/dist/geo/use-position-tracker.cjs +1 -1
- package/dist/geo/use-position-tracker.cjs.map +1 -1
- package/dist/geo/use-position-tracker.js +3 -1
- package/dist/geo/use-position-tracker.js.map +1 -1
- package/dist/hooks/use-async.cjs +1 -1
- package/dist/hooks/use-async.cjs.map +1 -1
- package/dist/hooks/use-async.js +3 -1
- package/dist/hooks/use-async.js.map +1 -1
- package/dist/hooks/use-click-outside.cjs +1 -1
- package/dist/hooks/use-click-outside.cjs.map +1 -1
- package/dist/hooks/use-click-outside.js +3 -1
- package/dist/hooks/use-click-outside.js.map +1 -1
- package/dist/hooks/use-deep-memo.cjs.map +1 -1
- package/dist/hooks/use-deep-memo.js.map +1 -1
- package/dist/hooks/use-event-listener.cjs +1 -1
- package/dist/hooks/use-event-listener.cjs.map +1 -1
- package/dist/hooks/use-event-listener.js +3 -1
- package/dist/hooks/use-event-listener.js.map +1 -1
- package/dist/hooks/use-interval.cjs +1 -1
- package/dist/hooks/use-interval.cjs.map +1 -1
- package/dist/hooks/use-interval.js +3 -1
- package/dist/hooks/use-interval.js.map +1 -1
- package/dist/hooks/use-is-first-render.cjs.map +1 -1
- package/dist/hooks/use-is-first-render.js.map +1 -1
- package/dist/hooks/use-long-press-handlers.cjs +1 -1
- package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
- package/dist/hooks/use-long-press-handlers.js +25 -23
- package/dist/hooks/use-long-press-handlers.js.map +1 -1
- package/dist/hooks/use-long-press.cjs +1 -1
- package/dist/hooks/use-long-press.cjs.map +1 -1
- package/dist/hooks/use-long-press.js +3 -1
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-online.cjs +1 -1
- package/dist/hooks/use-online.cjs.map +1 -1
- package/dist/hooks/use-online.js +6 -4
- package/dist/hooks/use-online.js.map +1 -1
- package/dist/hooks/use-previous.cjs.map +1 -1
- package/dist/hooks/use-previous.js.map +1 -1
- package/dist/hooks/use-service-worker-update.cjs +1 -1
- package/dist/hooks/use-service-worker-update.cjs.map +1 -1
- package/dist/hooks/use-service-worker-update.js +3 -1
- package/dist/hooks/use-service-worker-update.js.map +1 -1
- package/dist/hooks/use-sortable.cjs +2 -0
- package/dist/hooks/use-sortable.cjs.map +1 -0
- package/dist/hooks/use-sortable.js +169 -0
- package/dist/hooks/use-sortable.js.map +1 -0
- package/dist/hooks/use-stable-callback.cjs.map +1 -1
- package/dist/hooks/use-stable-callback.js.map +1 -1
- package/dist/hooks/use-timeout.cjs +1 -1
- package/dist/hooks/use-timeout.cjs.map +1 -1
- package/dist/hooks/use-timeout.js +3 -1
- package/dist/hooks/use-timeout.js.map +1 -1
- package/dist/icons/Icon.cjs +2 -0
- package/dist/icons/Icon.cjs.map +1 -0
- package/dist/icons/Icon.js +24 -0
- package/dist/icons/Icon.js.map +1 -0
- package/dist/icons/IconProvider.cjs +2 -0
- package/dist/icons/IconProvider.cjs.map +1 -0
- package/dist/icons/IconProvider.js +24 -0
- package/dist/icons/IconProvider.js.map +1 -0
- package/dist/icons/generated/aliases.cjs +2 -0
- package/dist/icons/generated/aliases.cjs.map +1 -0
- package/dist/icons/generated/aliases.js +255 -0
- package/dist/icons/generated/aliases.js.map +1 -0
- package/dist/icons/generated/icon-names.cjs +2 -0
- package/dist/icons/generated/icon-names.cjs.map +1 -0
- package/dist/icons/generated/icon-names.js +6 -0
- package/dist/icons/generated/icon-names.js.map +1 -0
- package/dist/icons/generated/loaders.cjs +2 -0
- package/dist/icons/generated/loaders.cjs.map +1 -0
- package/dist/icons/generated/loaders.js +32 -0
- package/dist/icons/generated/loaders.js.map +1 -0
- package/dist/icons/generated/shard-a.cjs +2 -0
- package/dist/icons/generated/shard-a.cjs.map +1 -0
- package/dist/icons/generated/shard-a.js +114 -0
- package/dist/icons/generated/shard-a.js.map +1 -0
- package/dist/icons/generated/shard-b.cjs +2 -0
- package/dist/icons/generated/shard-b.cjs.map +1 -0
- package/dist/icons/generated/shard-b.js +156 -0
- package/dist/icons/generated/shard-b.js.map +1 -0
- package/dist/icons/generated/shard-c.cjs +2 -0
- package/dist/icons/generated/shard-c.cjs.map +1 -0
- package/dist/icons/generated/shard-c.js +269 -0
- package/dist/icons/generated/shard-c.js.map +1 -0
- package/dist/icons/generated/shard-d.cjs +2 -0
- package/dist/icons/generated/shard-d.cjs.map +1 -0
- package/dist/icons/generated/shard-d.js +62 -0
- package/dist/icons/generated/shard-d.js.map +1 -0
- package/dist/icons/generated/shard-e.cjs +2 -0
- package/dist/icons/generated/shard-e.cjs.map +1 -0
- package/dist/icons/generated/shard-e.js +32 -0
- package/dist/icons/generated/shard-e.js.map +1 -0
- package/dist/icons/generated/shard-f.cjs +2 -0
- package/dist/icons/generated/shard-f.cjs.map +1 -0
- package/dist/icons/generated/shard-f.js +139 -0
- package/dist/icons/generated/shard-f.js.map +1 -0
- package/dist/icons/generated/shard-g.cjs +2 -0
- package/dist/icons/generated/shard-g.cjs.map +1 -0
- package/dist/icons/generated/shard-g.js +61 -0
- package/dist/icons/generated/shard-g.js.map +1 -0
- package/dist/icons/generated/shard-h.cjs +2 -0
- package/dist/icons/generated/shard-h.cjs.map +1 -0
- package/dist/icons/generated/shard-h.js +63 -0
- package/dist/icons/generated/shard-h.js.map +1 -0
- package/dist/icons/generated/shard-i.cjs +2 -0
- package/dist/icons/generated/shard-i.cjs.map +1 -0
- package/dist/icons/generated/shard-i.js +30 -0
- package/dist/icons/generated/shard-i.js.map +1 -0
- package/dist/icons/generated/shard-j.cjs +2 -0
- package/dist/icons/generated/shard-j.cjs.map +1 -0
- package/dist/icons/generated/shard-j.js +10 -0
- package/dist/icons/generated/shard-j.js.map +1 -0
- package/dist/icons/generated/shard-k.cjs +2 -0
- package/dist/icons/generated/shard-k.cjs.map +1 -0
- package/dist/icons/generated/shard-k.js +16 -0
- package/dist/icons/generated/shard-k.js.map +1 -0
- package/dist/icons/generated/shard-l.cjs +2 -0
- package/dist/icons/generated/shard-l.cjs.map +1 -0
- package/dist/icons/generated/shard-l.js +88 -0
- package/dist/icons/generated/shard-l.js.map +1 -0
- package/dist/icons/generated/shard-m.cjs +2 -0
- package/dist/icons/generated/shard-m.cjs.map +1 -0
- package/dist/icons/generated/shard-m.js +140 -0
- package/dist/icons/generated/shard-m.js.map +1 -0
- package/dist/icons/generated/shard-n.cjs +2 -0
- package/dist/icons/generated/shard-n.cjs.map +1 -0
- package/dist/icons/generated/shard-n.js +24 -0
- package/dist/icons/generated/shard-n.js.map +1 -0
- package/dist/icons/generated/shard-o.cjs +2 -0
- package/dist/icons/generated/shard-o.cjs.map +1 -0
- package/dist/icons/generated/shard-o.js +17 -0
- package/dist/icons/generated/shard-o.js.map +1 -0
- package/dist/icons/generated/shard-p.cjs +2 -0
- package/dist/icons/generated/shard-p.cjs.map +1 -0
- package/dist/icons/generated/shard-p.js +115 -0
- package/dist/icons/generated/shard-p.js.map +1 -0
- package/dist/icons/generated/shard-q.cjs +2 -0
- package/dist/icons/generated/shard-q.cjs.map +1 -0
- package/dist/icons/generated/shard-q.js +10 -0
- package/dist/icons/generated/shard-q.js.map +1 -0
- package/dist/icons/generated/shard-r.cjs +2 -0
- package/dist/icons/generated/shard-r.cjs.map +1 -0
- package/dist/icons/generated/shard-r.js +77 -0
- package/dist/icons/generated/shard-r.js.map +1 -0
- package/dist/icons/generated/shard-s.cjs +2 -0
- package/dist/icons/generated/shard-s.cjs.map +1 -0
- package/dist/icons/generated/shard-s.js +255 -0
- package/dist/icons/generated/shard-s.js.map +1 -0
- package/dist/icons/generated/shard-t.cjs +2 -0
- package/dist/icons/generated/shard-t.cjs.map +1 -0
- package/dist/icons/generated/shard-t.js +109 -0
- package/dist/icons/generated/shard-t.js.map +1 -0
- package/dist/icons/generated/shard-u.cjs +2 -0
- package/dist/icons/generated/shard-u.cjs.map +1 -0
- package/dist/icons/generated/shard-u.js +49 -0
- package/dist/icons/generated/shard-u.js.map +1 -0
- package/dist/icons/generated/shard-v.cjs +2 -0
- package/dist/icons/generated/shard-v.cjs.map +1 -0
- package/dist/icons/generated/shard-v.js +30 -0
- package/dist/icons/generated/shard-v.js.map +1 -0
- package/dist/icons/generated/shard-w.cjs +2 -0
- package/dist/icons/generated/shard-w.cjs.map +1 -0
- package/dist/icons/generated/shard-w.js +48 -0
- package/dist/icons/generated/shard-w.js.map +1 -0
- package/dist/icons/generated/shard-x.cjs +2 -0
- package/dist/icons/generated/shard-x.cjs.map +1 -0
- package/dist/icons/generated/shard-x.js +10 -0
- package/dist/icons/generated/shard-x.js.map +1 -0
- package/dist/icons/generated/shard-z.cjs +2 -0
- package/dist/icons/generated/shard-z.cjs.map +1 -0
- package/dist/icons/generated/shard-z.js +25 -0
- package/dist/icons/generated/shard-z.js.map +1 -0
- package/dist/icons/icon-context.cjs +2 -0
- package/dist/icons/icon-context.cjs.map +1 -0
- package/dist/icons/icon-context.js +13 -0
- package/dist/icons/icon-context.js.map +1 -0
- package/dist/icons/is-icon-name.cjs +2 -0
- package/dist/icons/is-icon-name.cjs.map +1 -0
- package/dist/icons/is-icon-name.js +10 -0
- package/dist/icons/is-icon-name.js.map +1 -0
- package/dist/icons/shard-cache.cjs +2 -0
- package/dist/icons/shard-cache.cjs.map +1 -0
- package/dist/icons/shard-cache.js +41 -0
- package/dist/icons/shard-cache.js.map +1 -0
- package/dist/icons/use-icon.cjs +2 -0
- package/dist/icons/use-icon.cjs.map +1 -0
- package/dist/icons/use-icon.js +20 -0
- package/dist/icons/use-icon.js.map +1 -0
- package/dist/icons-virtual.d.ts +22 -0
- package/dist/icons.cjs +1 -0
- package/dist/icons.d.ts +220 -0
- package/dist/icons.js +9 -0
- package/dist/offline/use-offline-sync.cjs +1 -1
- package/dist/offline/use-offline-sync.cjs.map +1 -1
- package/dist/offline/use-offline-sync.js +3 -1
- package/dist/offline/use-offline-sync.js.map +1 -1
- package/dist/push/use-push-subscription.cjs +1 -1
- package/dist/push/use-push-subscription.cjs.map +1 -1
- package/dist/push/use-push-subscription.js +3 -1
- package/dist/push/use-push-subscription.js.map +1 -1
- package/dist/sse/use-event-stream.cjs +1 -1
- package/dist/sse/use-event-stream.cjs.map +1 -1
- package/dist/sse/use-event-stream.js +3 -1
- package/dist/sse/use-event-stream.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +585 -3
- package/dist/tempest-react-sdk.js +189 -183
- package/dist/theme/ThemeProvider.cjs +1 -1
- package/dist/theme/ThemeProvider.cjs.map +1 -1
- package/dist/theme/ThemeProvider.js +6 -2
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/color.cjs +1 -1
- package/dist/theme/color.cjs.map +1 -1
- package/dist/theme/color.js +77 -46
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/create-theme.cjs +1 -1
- package/dist/theme/create-theme.cjs.map +1 -1
- package/dist/theme/create-theme.js +9 -3
- package/dist/theme/create-theme.js.map +1 -1
- package/dist/utils/compare-values.cjs +2 -0
- package/dist/utils/compare-values.cjs.map +1 -0
- package/dist/utils/compare-values.js +8 -0
- package/dist/utils/compare-values.js.map +1 -0
- package/dist/vision/use-camera-stream.cjs +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-camera-stream.js +3 -1
- package/dist/vision/use-camera-stream.js.map +1 -1
- package/dist/vite/create-vite-config.cjs +1 -1
- package/dist/vite/create-vite-config.cjs.map +1 -1
- package/dist/vite/create-vite-config.js +30 -22
- package/dist/vite/create-vite-config.js.map +1 -1
- package/dist/vite/tempest-icons.cjs +9 -0
- package/dist/vite/tempest-icons.cjs.map +1 -0
- package/dist/vite/tempest-icons.js +99 -0
- package/dist/vite/tempest-icons.js.map +1 -0
- package/dist/vite.cjs +1 -1
- package/dist/vite.d.ts +79 -0
- package/dist/vite.js +6 -5
- package/dist/ws/use-web-socket.cjs +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js +3 -1
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +12 -3
- package/template/package.json +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
|
|
6
|
+
import { iconAliases, iconNames } from "@/icons";
|
|
7
|
+
|
|
8
|
+
import { generateRegistry, renderRegistry, scanIconSlugs } from "./generate.mjs";
|
|
9
|
+
|
|
10
|
+
const known = new Set(iconNames);
|
|
11
|
+
|
|
12
|
+
describe("scanIconSlugs", () => {
|
|
13
|
+
it("finds literal name props, braced or not", () => {
|
|
14
|
+
expect(
|
|
15
|
+
scanIconSlugs(`<Icon name="save" /><Icon name={"trash-2"} />`, known).sort(),
|
|
16
|
+
).toEqual(["save", "trash-2"]);
|
|
17
|
+
});
|
|
18
|
+
it("finds an object field", () => {
|
|
19
|
+
expect(scanIconSlugs(`{ name: "house" }`, known)).toEqual(["house"]);
|
|
20
|
+
});
|
|
21
|
+
it("ignores a name that is not a lucide slug", () => {
|
|
22
|
+
expect(scanIconSlugs(`<Field name="email" />`, known)).toEqual([]);
|
|
23
|
+
});
|
|
24
|
+
it("ignores a dynamic name", () => {
|
|
25
|
+
expect(scanIconSlugs(`<Icon name={row.icon} />`, known)).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe("renderRegistry", () => {
|
|
30
|
+
it("emits a createIconRegistry call with static imports", () => {
|
|
31
|
+
const out = renderRegistry(["save", "trash-2"], iconAliases);
|
|
32
|
+
expect(out).toContain(`import { createIconRegistry } from "tempest-react-sdk/icons";`);
|
|
33
|
+
expect(out).toContain(`import { Save, Trash2 } from "lucide-react";`);
|
|
34
|
+
expect(out).toContain(` "save": Save,`);
|
|
35
|
+
});
|
|
36
|
+
it("imports the canonical component for an alias but keeps the alias key", () => {
|
|
37
|
+
const out = renderRegistry(["alert-circle"], iconAliases);
|
|
38
|
+
expect(out).toContain(`import { CircleAlert } from "lucide-react";`);
|
|
39
|
+
expect(out).toContain(` "alert-circle": CircleAlert,`);
|
|
40
|
+
});
|
|
41
|
+
it("emits an empty registry rather than an empty import", () => {
|
|
42
|
+
expect(renderRegistry([], iconAliases)).toContain("createIconRegistry({})");
|
|
43
|
+
});
|
|
44
|
+
it("is deterministic regardless of input order", () => {
|
|
45
|
+
expect(renderRegistry(["trash-2", "save"], iconAliases)).toBe(
|
|
46
|
+
renderRegistry(["save", "trash-2"], iconAliases),
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("generateRegistry", () => {
|
|
52
|
+
let root;
|
|
53
|
+
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
root = mkdtempSync(join(tmpdir(), "tempest-gen-icons-"));
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
afterEach(() => {
|
|
59
|
+
rmSync(root, { recursive: true, force: true });
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
/** Write a source file under the fixture root. */
|
|
63
|
+
function write(rel, contents) {
|
|
64
|
+
const path = join(root, rel);
|
|
65
|
+
mkdirSync(join(path, ".."), { recursive: true });
|
|
66
|
+
writeFileSync(path, contents);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
it("collects slugs across a nested tree", async () => {
|
|
70
|
+
write("pages/Home.tsx", `<Icon name="house" />`);
|
|
71
|
+
write("pages/admin/Users.tsx", `<Icon name="users" />`);
|
|
72
|
+
const { slugs, files } = await generateRegistry({ dir: root, known, aliases: iconAliases });
|
|
73
|
+
expect(slugs).toEqual(["house", "users"]);
|
|
74
|
+
expect(files).toBe(2);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("skips node_modules, dist and dot directories", async () => {
|
|
78
|
+
write("node_modules/dep/index.ts", `<Icon name="bug" />`);
|
|
79
|
+
write("dist/out.js", `<Icon name="bomb" />`);
|
|
80
|
+
write(".cache/x.ts", `<Icon name="box" />`);
|
|
81
|
+
write("App.tsx", `<Icon name="house" />`);
|
|
82
|
+
const { slugs } = await generateRegistry({ dir: root, known, aliases: iconAliases });
|
|
83
|
+
expect(slugs).toEqual(["house"]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("adds include slugs and drops invalid ones", async () => {
|
|
87
|
+
write("App.tsx", "");
|
|
88
|
+
const { slugs } = await generateRegistry({
|
|
89
|
+
dir: root,
|
|
90
|
+
known,
|
|
91
|
+
aliases: iconAliases,
|
|
92
|
+
include: ["rocket", "not-an-icon"],
|
|
93
|
+
});
|
|
94
|
+
expect(slugs).toEqual(["rocket"]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("yields an empty registry for a tree with no icons", async () => {
|
|
98
|
+
write("App.tsx", `export const App = () => null;`);
|
|
99
|
+
const { slugs, source } = await generateRegistry({
|
|
100
|
+
dir: root,
|
|
101
|
+
known,
|
|
102
|
+
aliases: iconAliases,
|
|
103
|
+
});
|
|
104
|
+
expect(slugs).toEqual([]);
|
|
105
|
+
expect(source).toContain("createIconRegistry({})");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("returns zero files for a directory that does not exist", async () => {
|
|
109
|
+
const { files, slugs } = await generateRegistry({
|
|
110
|
+
dir: join(root, "nope"),
|
|
111
|
+
known,
|
|
112
|
+
aliases: iconAliases,
|
|
113
|
+
});
|
|
114
|
+
expect(files).toBe(0);
|
|
115
|
+
expect(slugs).toEqual([]);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("renderRegistry — reserved names", () => {
|
|
120
|
+
it("aliases an export name that would shadow a restricted global", () => {
|
|
121
|
+
const out = renderRegistry(["infinity"], iconAliases);
|
|
122
|
+
expect(out).toContain(`import { Infinity as InfinityIcon } from "lucide-react";`);
|
|
123
|
+
expect(out).toContain(`"infinity": InfinityIcon,`);
|
|
124
|
+
});
|
|
125
|
+
});
|
package/bin/tempest.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// tempest doctor health-check the current project (à la flutter doctor)
|
|
5
5
|
// tempest lint [paths…] run ESLint (report only)
|
|
6
|
-
// tempest fix [paths…]
|
|
6
|
+
// tempest fix [paths…] alias imports (../ → @/) + ESLint --fix + Prettier
|
|
7
7
|
// tempest format [paths…] Prettier --write
|
|
8
8
|
// tempest --help | --version
|
|
9
9
|
import { spawnSync } from "node:child_process";
|
|
@@ -11,6 +11,11 @@ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
|
11
11
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
12
12
|
import { dirname, join, resolve } from "node:path";
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { aliasImports } from "./lib/alias/index.mjs";
|
|
15
|
+
import { loadTypeScript } from "./lib/alias/typescript.mjs";
|
|
16
|
+
import { readTsconfig } from "./lib/alias/tsconfig.mjs";
|
|
17
|
+
import { checkLucide } from "./lib/doctor/lucide.mjs";
|
|
18
|
+
import { generateRegistry, loadIconTables } from "./lib/icons/generate.mjs";
|
|
14
19
|
import { generate } from "./lib/openapi/generate.mjs";
|
|
15
20
|
import { loadSpec } from "./lib/openapi/load.mjs";
|
|
16
21
|
|
|
@@ -347,6 +352,21 @@ function doctor() {
|
|
|
347
352
|
"nested copy under tempest-react-sdk — run `npm dedupe` or align versions; two instances break hooks/context",
|
|
348
353
|
],
|
|
349
354
|
);
|
|
355
|
+
|
|
356
|
+
// lucide-react gets its own check: two copies of it do not break hooks the
|
|
357
|
+
// way a second React does, but they duplicate bytes and can leave the
|
|
358
|
+
// generated icon slug tables pointing at exports the older copy lacks.
|
|
359
|
+
const sdkPkg = readJSON(join(ROOT, "node_modules", "tempest-react-sdk", "package.json"));
|
|
360
|
+
checks.push(
|
|
361
|
+
...checkLucide({
|
|
362
|
+
appSpec: deps["lucide-react"] ? String(deps["lucide-react"]) : null,
|
|
363
|
+
sdkSpec: sdkPkg?.dependencies?.["lucide-react"]
|
|
364
|
+
? String(sdkPkg.dependencies["lucide-react"])
|
|
365
|
+
: null,
|
|
366
|
+
installedVersion: installedVersion("lucide-react"),
|
|
367
|
+
nestedCopy: nestedDupe("lucide-react"),
|
|
368
|
+
}),
|
|
369
|
+
);
|
|
350
370
|
}
|
|
351
371
|
|
|
352
372
|
// Declared-but-not-installed (package.json ↔ node_modules drift).
|
|
@@ -414,10 +434,10 @@ function doctor() {
|
|
|
414
434
|
}
|
|
415
435
|
|
|
416
436
|
// ── TypeScript ────────────────────────────────────────────────────────────
|
|
417
|
-
const tsc =
|
|
437
|
+
const tsc = readTsconfig({ root: ROOT, ts: loadTypeScript(ROOT) });
|
|
418
438
|
if (tsc) {
|
|
419
439
|
checks.push(["section", "TypeScript"]);
|
|
420
|
-
const co = tsc.compilerOptions
|
|
440
|
+
const co = tsc.compilerOptions;
|
|
421
441
|
checks.push(
|
|
422
442
|
co.paths?.["@/*"]
|
|
423
443
|
? ["ok", 'tsconfig "@/*" alias']
|
|
@@ -625,12 +645,93 @@ function requireBin(name) {
|
|
|
625
645
|
return bin;
|
|
626
646
|
}
|
|
627
647
|
|
|
628
|
-
|
|
629
|
-
|
|
648
|
+
/**
|
|
649
|
+
* Split argv into flags and positional paths.
|
|
650
|
+
*
|
|
651
|
+
* Needed because these commands used to hand `rest` straight through as their
|
|
652
|
+
* path list, so `tempest lint --max-warnings 0` counted the flag as a path and
|
|
653
|
+
* ESLint ran with a flag but no pattern. Flags are kept in order for forwarding.
|
|
654
|
+
*
|
|
655
|
+
* @param {string[]} args - The argv tail for the command.
|
|
656
|
+
* @returns {{ flags: string[], paths: string[] }}
|
|
657
|
+
*/
|
|
658
|
+
function splitArgs(args) {
|
|
659
|
+
const flags = [];
|
|
660
|
+
const paths = [];
|
|
661
|
+
for (const arg of args) (arg.startsWith("-") ? flags : paths).push(arg);
|
|
662
|
+
return { flags, paths };
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
function lint(args) {
|
|
666
|
+
const { flags, paths } = splitArgs(args);
|
|
667
|
+
return run(requireBin("eslint"), [...(paths.length ? paths : ["."]), ...flags]);
|
|
630
668
|
}
|
|
631
669
|
|
|
632
|
-
|
|
670
|
+
/** Flags `fix` owns itself; anything else is rejected rather than forwarded. */
|
|
671
|
+
const FIX_FLAGS = new Set(["--no-alias", "--dry-run"]);
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Print the alias pass result.
|
|
675
|
+
*
|
|
676
|
+
* @param {object} result - Return value of `aliasImports`.
|
|
677
|
+
* @param {boolean} dryRun - Whether the pass wrote anything.
|
|
678
|
+
* @returns {void}
|
|
679
|
+
*/
|
|
680
|
+
function reportAlias(result, dryRun) {
|
|
681
|
+
if (result.status === "no-typescript") {
|
|
682
|
+
console.log(
|
|
683
|
+
`${c.yellow}! typescript not installed — skipping alias pass${c.reset} ${c.dim}(npm i -D typescript)${c.reset}`,
|
|
684
|
+
);
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (result.status === "no-alias") {
|
|
688
|
+
console.log(
|
|
689
|
+
`${c.yellow}! no path alias found — skipping alias pass${c.reset} ${c.dim}add "paths": { "@/*": ["./src/*"] } to tsconfig.json${c.reset}`,
|
|
690
|
+
);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
for (const file of result.files) {
|
|
694
|
+
console.log(` ${file.path} ${c.dim}${file.changes.length}${c.reset}`);
|
|
695
|
+
if (dryRun) {
|
|
696
|
+
for (const ch of file.changes) {
|
|
697
|
+
console.log(` ${c.dim}${ch.line}:${c.reset} "${ch.from}" → "${ch.to}"`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
for (const err of result.errors) {
|
|
702
|
+
console.log(` ${c.red}✗ ${err.path}${c.reset} ${c.dim}${err.message}${c.reset}`);
|
|
703
|
+
}
|
|
704
|
+
if (!result.total) {
|
|
705
|
+
console.log(` ${c.dim}nothing to convert${c.reset}`);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
const verb = dryRun ? "would convert" : "converted";
|
|
709
|
+
console.log(
|
|
710
|
+
` ${c.green}✓${c.reset} ${verb} ${result.total} import(s) in ${result.files.length} file(s)`,
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
function fix(args) {
|
|
715
|
+
const { flags, paths } = splitArgs(args);
|
|
716
|
+
const unknown = flags.filter((f) => !FIX_FLAGS.has(f));
|
|
717
|
+
if (unknown.length) {
|
|
718
|
+
console.error(
|
|
719
|
+
`${c.red}✗ Unknown flag for fix: ${unknown.join(", ")}${c.reset} — supported: ${[...FIX_FLAGS].join(", ")}`,
|
|
720
|
+
);
|
|
721
|
+
return 1;
|
|
722
|
+
}
|
|
633
723
|
const targets = paths.length ? paths : ["."];
|
|
724
|
+
const dryRun = flags.includes("--dry-run");
|
|
725
|
+
|
|
726
|
+
let aliasStatus = 0;
|
|
727
|
+
if (!flags.includes("--no-alias")) {
|
|
728
|
+
console.log(`${c.dim}→ alias imports (../ → @/)${dryRun ? " [dry-run]" : ""}${c.reset}`);
|
|
729
|
+
const result = aliasImports({ root: ROOT, targets, dryRun });
|
|
730
|
+
reportAlias(result, dryRun);
|
|
731
|
+
aliasStatus = result.status === "error" ? 1 : 0;
|
|
732
|
+
}
|
|
733
|
+
if (dryRun) return aliasStatus;
|
|
734
|
+
|
|
634
735
|
console.log(`${c.dim}→ eslint --fix (sort imports · drop unused · tidy whitespace)${c.reset}`);
|
|
635
736
|
const eslintStatus = run(requireBin("eslint"), [...targets, "--fix"]);
|
|
636
737
|
const prettier = localBin("prettier");
|
|
@@ -641,11 +742,12 @@ function fix(paths) {
|
|
|
641
742
|
} else {
|
|
642
743
|
console.log(`${c.yellow}! prettier not installed — skipping format pass${c.reset}`);
|
|
643
744
|
}
|
|
644
|
-
return eslintStatus || prettierStatus;
|
|
745
|
+
return aliasStatus || eslintStatus || prettierStatus;
|
|
645
746
|
}
|
|
646
747
|
|
|
647
|
-
function format(
|
|
648
|
-
|
|
748
|
+
function format(args) {
|
|
749
|
+
const { flags, paths } = splitArgs(args);
|
|
750
|
+
return run(requireBin("prettier"), ["--write", ...(paths.length ? paths : ["."]), ...flags]);
|
|
649
751
|
}
|
|
650
752
|
|
|
651
753
|
// -------------------------------------------------------------- gen api ----
|
|
@@ -701,15 +803,67 @@ async function genApi(args) {
|
|
|
701
803
|
return 0;
|
|
702
804
|
}
|
|
703
805
|
|
|
806
|
+
// ------------------------------------------------------------ gen icons ----
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* `tempest gen icons [--out src/icons.generated.ts] [--dir src]` — write a static
|
|
810
|
+
* icon registry from the slugs the project's source mentions.
|
|
811
|
+
*
|
|
812
|
+
* The `tempestIcons()` Vite plugin does the same thing as a virtual module and
|
|
813
|
+
* needs no file; this exists for a project that is not on Vite, or that prefers a
|
|
814
|
+
* registry it can read and commit.
|
|
815
|
+
*/
|
|
816
|
+
async function genIcons(args) {
|
|
817
|
+
const outRel = parseOut(args, "src/icons.generated.ts");
|
|
818
|
+
const dirIndex = args.indexOf("--dir");
|
|
819
|
+
const dirRel = dirIndex >= 0 && args[dirIndex + 1] ? args[dirIndex + 1] : "src";
|
|
820
|
+
const dir = resolve(ROOT, dirRel);
|
|
821
|
+
|
|
822
|
+
let tables;
|
|
823
|
+
try {
|
|
824
|
+
tables = await loadIconTables(SELF_DIR);
|
|
825
|
+
} catch {
|
|
826
|
+
console.error(
|
|
827
|
+
`${c.red}✗ Could not read the icon tables from the installed SDK.${c.reset} Is tempest-react-sdk installed and built?`,
|
|
828
|
+
);
|
|
829
|
+
return 1;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
console.log(`${c.dim}→ scanning ${dirRel}${c.reset}`);
|
|
833
|
+
const { source, slugs, files } = await generateRegistry({
|
|
834
|
+
dir,
|
|
835
|
+
known: tables.known,
|
|
836
|
+
aliases: tables.aliases,
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
const dest = resolve(ROOT, outRel);
|
|
840
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
841
|
+
await writeFile(dest, source);
|
|
842
|
+
|
|
843
|
+
console.log(
|
|
844
|
+
`\n${c.green}✓ ${slugs.length} icon(s)${c.reset} from ${files} file(s) → ${c.bold}${outRel}${c.reset}`,
|
|
845
|
+
);
|
|
846
|
+
const prettier = localBin("prettier");
|
|
847
|
+
if (prettier) run(prettier, ["--write", outRel]);
|
|
848
|
+
console.log(`\n${c.dim}Wire it up:${c.reset}`);
|
|
849
|
+
console.log(` import { IconProvider } from "tempest-react-sdk/icons";`);
|
|
850
|
+
console.log(` import { icons } from "@/icons.generated";`);
|
|
851
|
+
console.log(` <IconProvider registry={icons}>…</IconProvider>`);
|
|
852
|
+
return 0;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const GEN_TARGETS = { api: genApi, icons: genIcons };
|
|
856
|
+
|
|
704
857
|
function gen(args) {
|
|
705
858
|
const what = args[0];
|
|
706
|
-
|
|
859
|
+
const target = GEN_TARGETS[what];
|
|
860
|
+
if (!target) {
|
|
707
861
|
console.error(
|
|
708
|
-
`${c.red}✗ Unknown gen target: ${what ?? "(none)"}${c.reset} —
|
|
862
|
+
`${c.red}✗ Unknown gen target: ${what ?? "(none)"}${c.reset} — supported: ${Object.keys(GEN_TARGETS).join(", ")}.`,
|
|
709
863
|
);
|
|
710
864
|
return 1;
|
|
711
865
|
}
|
|
712
|
-
return
|
|
866
|
+
return target(args.slice(1));
|
|
713
867
|
}
|
|
714
868
|
|
|
715
869
|
// ------------------------------------------------------------------ main ----
|
|
@@ -724,10 +878,17 @@ ${c.bold}Usage${c.reset}
|
|
|
724
878
|
${c.bold}Commands${c.reset}
|
|
725
879
|
${c.bold}doctor${c.reset} Health-check the current project
|
|
726
880
|
${c.bold}lint${c.reset} [paths] Run ESLint (report only)
|
|
727
|
-
${c.bold}fix${c.reset} [paths] ESLint --fix (sort imports, remove
|
|
881
|
+
${c.bold}fix${c.reset} [paths] Alias imports (../ → @/) + ESLint --fix (sort imports, remove
|
|
882
|
+
unused, tidy whitespace) + Prettier
|
|
728
883
|
${c.bold}format${c.reset} [paths] Prettier --write
|
|
729
884
|
${c.bold}gen api${c.reset} <src> Generate Zod schemas + types + service classes from an OpenAPI spec
|
|
730
885
|
(e.g. tempest gen api http://127.0.0.1:8000/openapi.json --out src/api)
|
|
886
|
+
${c.bold}gen icons${c.reset} Write a static icon registry from the slugs your source uses
|
|
887
|
+
(e.g. tempest gen icons --out src/icons.generated.ts --dir src)
|
|
888
|
+
|
|
889
|
+
${c.bold}fix options${c.reset}
|
|
890
|
+
--dry-run List the imports that would be rewritten; write nothing
|
|
891
|
+
--no-alias Skip the alias pass (ESLint + Prettier only)
|
|
731
892
|
|
|
732
893
|
${c.bold}Options${c.reset}
|
|
733
894
|
-h, --help Show this help
|
package/dist/audio/use-audio.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./audio-player.cjs");let t=require("react");function n(){let
|
|
1
|
+
const e=require("./audio-player.cjs");let t=require("react");function n(){let[n]=(0,t.useState)(()=>e.createAudioPlayer()),[r,i]=(0,t.useState)(!1);return(0,t.useEffect)(()=>()=>{n.stop()},[n]),{play:(0,t.useCallback)(async(e,t)=>{await n.play(e,t)&&i(!0)},[n]),stop:(0,t.useCallback)(()=>{n.stop()},[n]),unlocked:r}}exports.useAudio=n;
|
|
2
2
|
//# sourceMappingURL=use-audio.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-audio.cjs","names":[],"sources":["../../src/audio/use-audio.ts"],"sourcesContent":["import { useCallback, useEffect,
|
|
1
|
+
{"version":3,"file":"use-audio.cjs","names":[],"sources":["../../src/audio/use-audio.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { createAudioPlayer, type AudioPlayer, type PlayAudioOptions } from \"./audio-player\";\n\nexport interface UseAudioResult {\n /** Play `src` on the hook's private player. */\n play: (src: string, options?: PlayAudioOptions) => Promise<void>;\n /** Stop the current clip. */\n stop: () => void;\n /**\n * Whether the browser's autoplay policy has been satisfied. Becomes\n * `true` after the first successful `play()`.\n */\n unlocked: boolean;\n}\n\n/**\n * The player lives in a state initializer, not in a lazily-written ref: the\n * initializer runs exactly once and is not a side effect during render, which is\n * what the ref version was. The player identity never changes, so state holds it\n * fine and the value is non-null from the first render.\n *\n * Hook-managed audio player. Each component instance gets its own\n * {@link AudioPlayer}, so unmounting cleanly stops playback. Useful for\n * notification chimes, UI feedback sounds, and per-component soundtracks.\n */\nexport function useAudio(): UseAudioResult {\n const [player] = useState<AudioPlayer>(() => createAudioPlayer());\n const [unlocked, setUnlocked] = useState<boolean>(false);\n\n useEffect(() => {\n return () => {\n player.stop();\n };\n }, [player]);\n\n const play = useCallback(\n async (src: string, options?: PlayAudioOptions): Promise<void> => {\n const result = await player.play(src, options);\n if (result) setUnlocked(true);\n },\n [player],\n );\n\n const stop = useCallback((): void => {\n player.stop();\n }, [player]);\n\n return { play, stop, unlocked };\n}\n"],"mappings":"6DAyBA,SAAgB,GAA2B,CACvC,GAAM,CAAC,IAAA,EAAA,EAAA,SAAA,KAAsC,EAAA,kBAAkB,CAAC,EAC1D,CAAC,EAAU,IAAA,EAAA,EAAA,SAAA,CAAiC,EAAK,EAoBvD,OAlBA,EAAA,EAAA,UAAA,SACiB,CACT,EAAO,KAAK,CAChB,EACD,CAAC,CAAM,CAAC,EAcJ,CAAE,MAAA,EAAA,EAAA,YAAA,CAXL,MAAO,EAAa,IAA8C,CAE1D,MADiB,EAAO,KAAK,EAAK,CAAO,GACjC,EAAY,EAAI,CAChC,EACA,CAAC,CAAM,CAOF,EAAM,MAAA,EAAA,EAAA,YAAA,KAJsB,CACjC,EAAO,KAAK,CAChB,EAAG,CAAC,CAAM,CAEK,EAAM,UAAS,CAClC"}
|
package/dist/audio/use-audio.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { createAudioPlayer as e } from "./audio-player.js";
|
|
2
|
-
import { useCallback as t, useEffect as n,
|
|
2
|
+
import { useCallback as t, useEffect as n, useState as r } from "react";
|
|
3
3
|
//#region src/audio/use-audio.ts
|
|
4
|
-
function
|
|
5
|
-
let
|
|
6
|
-
return
|
|
7
|
-
|
|
8
|
-
}, []), {
|
|
4
|
+
function i() {
|
|
5
|
+
let [i] = r(() => e()), [a, o] = r(!1);
|
|
6
|
+
return n(() => () => {
|
|
7
|
+
i.stop();
|
|
8
|
+
}, [i]), {
|
|
9
9
|
play: t(async (e, t) => {
|
|
10
|
-
await
|
|
11
|
-
}, []),
|
|
10
|
+
await i.play(e, t) && o(!0);
|
|
11
|
+
}, [i]),
|
|
12
12
|
stop: t(() => {
|
|
13
|
-
|
|
14
|
-
}, []),
|
|
15
|
-
unlocked:
|
|
13
|
+
i.stop();
|
|
14
|
+
}, [i]),
|
|
15
|
+
unlocked: a
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
//#endregion
|
|
19
|
-
export {
|
|
19
|
+
export { i as useAudio };
|
|
20
20
|
|
|
21
21
|
//# sourceMappingURL=use-audio.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-audio.js","names":[],"sources":["../../src/audio/use-audio.ts"],"sourcesContent":["import { useCallback, useEffect,
|
|
1
|
+
{"version":3,"file":"use-audio.js","names":[],"sources":["../../src/audio/use-audio.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { createAudioPlayer, type AudioPlayer, type PlayAudioOptions } from \"./audio-player\";\n\nexport interface UseAudioResult {\n /** Play `src` on the hook's private player. */\n play: (src: string, options?: PlayAudioOptions) => Promise<void>;\n /** Stop the current clip. */\n stop: () => void;\n /**\n * Whether the browser's autoplay policy has been satisfied. Becomes\n * `true` after the first successful `play()`.\n */\n unlocked: boolean;\n}\n\n/**\n * The player lives in a state initializer, not in a lazily-written ref: the\n * initializer runs exactly once and is not a side effect during render, which is\n * what the ref version was. The player identity never changes, so state holds it\n * fine and the value is non-null from the first render.\n *\n * Hook-managed audio player. Each component instance gets its own\n * {@link AudioPlayer}, so unmounting cleanly stops playback. Useful for\n * notification chimes, UI feedback sounds, and per-component soundtracks.\n */\nexport function useAudio(): UseAudioResult {\n const [player] = useState<AudioPlayer>(() => createAudioPlayer());\n const [unlocked, setUnlocked] = useState<boolean>(false);\n\n useEffect(() => {\n return () => {\n player.stop();\n };\n }, [player]);\n\n const play = useCallback(\n async (src: string, options?: PlayAudioOptions): Promise<void> => {\n const result = await player.play(src, options);\n if (result) setUnlocked(true);\n },\n [player],\n );\n\n const stop = useCallback((): void => {\n player.stop();\n }, [player]);\n\n return { play, stop, unlocked };\n}\n"],"mappings":";;;AAyBA,SAAgB,IAA2B;CACvC,IAAM,CAAC,KAAU,QAA4B,EAAkB,CAAC,GAC1D,CAAC,GAAU,KAAe,EAAkB,EAAK;CAoBvD,OAlBA,cACiB;EACT,EAAO,KAAK;CAChB,GACD,CAAC,CAAM,CAAC,GAcJ;EAAE,MAZI,EACT,OAAO,GAAa,MAA8C;GAE9D,AAAI,MADiB,EAAO,KAAK,GAAK,CAAO,KACjC,EAAY,EAAI;EAChC,GACA,CAAC,CAAM,CAOF;EAAM,MAJF,QAAwB;GACjC,EAAO,KAAK;EAChB,GAAG,CAAC,CAAM,CAEK;EAAM;CAAS;AAClC"}
|
package/dist/charts/palette.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=[`#2563eb`,`#16a34a`,`#f59e0b`,`#7c3aed`,`#ec4899`,`#06b6d4`],t=8;function n(t){if(typeof window>`u`||typeof document>`u`)return e;let n=t??document.documentElement;if(!n)return e;let r=window.getComputedStyle(n),i=[];for(let e=1;e<=
|
|
1
|
+
var e=[`#2563eb`,`#16a34a`,`#f59e0b`,`#7c3aed`,`#ec4899`,`#06b6d4`],t=8;function n(t){if(typeof window>`u`||typeof document>`u`)return e;let n=t??document.documentElement;if(!n)return e;let r=window.getComputedStyle(n),i=[],a=Number.parseInt(r.getPropertyValue(`--tempest-chart-count`).trim(),10),o=Number.isFinite(a)&&a>0?Math.min(a,8):8;for(let e=1;e<=o;e+=1){let t=r.getPropertyValue(`--tempest-chart-${e}`).trim();if(!t)break;i.push(t)}return i.length>0?i:e}function r(e,t,n=e===`grid`?`#e4e7ec`:`#667085`){if(typeof window>`u`||typeof document>`u`)return n;let r=t??document.documentElement;return r&&window.getComputedStyle(r).getPropertyValue(`--tempest-chart-${e}`).trim()||n}exports.CHART_COLOR_TOKEN_COUNT=t,exports.DEFAULT_CHART_COLORS=e,exports.resolveChartChrome=r,exports.resolveChartColors=n;
|
|
2
2
|
//# sourceMappingURL=palette.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette.cjs","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n *
|
|
1
|
+
{"version":3,"file":"palette.cjs","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n * Respects `--tempest-chart-count` when the theme declares one (`createTheme`\n * writes it), so a six-color brand palette is read as six and not padded with the\n * SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at\n * the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is\n * resolvable.\n *\n * @param element - Element to resolve the tokens against. Default `<html>`; pass\n * a subtree root when a section carries a scoped theme.\n * @returns Literal color strings in cycle order.\n */\nexport function resolveChartColors(element?: Element | null): string[] {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return DEFAULT_CHART_COLORS;\n }\n\n const target = element ?? document.documentElement;\n if (!target) return DEFAULT_CHART_COLORS;\n\n const styles = window.getComputedStyle(target);\n const resolved: string[] = [];\n const declared = Number.parseInt(styles.getPropertyValue(\"--tempest-chart-count\").trim(), 10);\n const limit =\n Number.isFinite(declared) && declared > 0\n ? Math.min(declared, CHART_COLOR_TOKEN_COUNT)\n : CHART_COLOR_TOKEN_COUNT;\n\n for (let index = 1; index <= limit; index += 1) {\n const value = styles.getPropertyValue(`--tempest-chart-${index}`).trim();\n if (!value) break;\n resolved.push(value);\n }\n\n return resolved.length > 0 ? resolved : DEFAULT_CHART_COLORS;\n}\n\n/**\n * Read one piece of chart chrome (`--tempest-chart-grid` / `--tempest-chart-axis`).\n *\n * @param part - Which chrome token to read.\n * @param element - Element to resolve against. Default `<html>`.\n * @param fallback - Value returned when the token is unset.\n * @returns The resolved color, or `fallback`.\n */\nexport function resolveChartChrome(\n part: \"grid\" | \"axis\",\n element?: Element | null,\n fallback = part === \"grid\" ? \"#e4e7ec\" : \"#667085\",\n): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return fallback;\n const target = element ?? document.documentElement;\n if (!target) return fallback;\n const value = window\n .getComputedStyle(target)\n .getPropertyValue(`--tempest-chart-${part}`)\n .trim();\n return value || fallback;\n}\n"],"mappings":"AAmBA,IAAa,EAAiC,CAC1C,UACA,UACA,UACA,UACA,UACA,SACJ,EAGa,EAA0B,EAevC,SAAgB,EAAmB,EAAoC,CACnE,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IACrD,OAAO,EAGX,IAAM,EAAS,GAAW,SAAS,gBACnC,GAAI,CAAC,EAAQ,OAAO,EAEpB,IAAM,EAAS,OAAO,iBAAiB,CAAM,EACvC,EAAqB,CAAC,EACtB,EAAW,OAAO,SAAS,EAAO,iBAAiB,uBAAuB,CAAC,CAAC,KAAK,EAAG,EAAE,EACtF,EACF,OAAO,SAAS,CAAQ,GAAK,EAAW,EAClC,KAAK,IAAI,EAAA,CAAiC,EAAA,EAGpD,IAAK,IAAI,EAAQ,EAAG,GAAS,EAAO,GAAS,EAAG,CAC5C,IAAM,EAAQ,EAAO,iBAAiB,mBAAmB,GAAO,CAAC,CAAC,KAAK,EACvE,GAAI,CAAC,EAAO,MACZ,EAAS,KAAK,CAAK,CACvB,CAEA,OAAO,EAAS,OAAS,EAAI,EAAW,CAC5C,CAUA,SAAgB,EACZ,EACA,EACA,EAAW,IAAS,OAAS,UAAY,UACnC,CACN,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IAAa,OAAO,EAC7E,IAAM,EAAS,GAAW,SAAS,gBAMnC,OALK,GACS,OACT,iBAAiB,CAAM,CAAC,CACxB,iBAAiB,mBAAmB,GAAM,CAAC,CAC3C,KACE,GALa,CAMxB"}
|
package/dist/charts/palette.js
CHANGED
|
@@ -11,8 +11,8 @@ function n(t) {
|
|
|
11
11
|
if (typeof window > "u" || typeof document > "u") return e;
|
|
12
12
|
let n = t ?? document.documentElement;
|
|
13
13
|
if (!n) return e;
|
|
14
|
-
let r = window.getComputedStyle(n), i = [];
|
|
15
|
-
for (let e = 1; e <=
|
|
14
|
+
let r = window.getComputedStyle(n), i = [], a = Number.parseInt(r.getPropertyValue("--tempest-chart-count").trim(), 10), o = Number.isFinite(a) && a > 0 ? Math.min(a, 8) : 8;
|
|
15
|
+
for (let e = 1; e <= o; e += 1) {
|
|
16
16
|
let t = r.getPropertyValue(`--tempest-chart-${e}`).trim();
|
|
17
17
|
if (!t) break;
|
|
18
18
|
i.push(t);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette.js","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n *
|
|
1
|
+
{"version":3,"file":"palette.js","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n * Respects `--tempest-chart-count` when the theme declares one (`createTheme`\n * writes it), so a six-color brand palette is read as six and not padded with the\n * SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at\n * the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is\n * resolvable.\n *\n * @param element - Element to resolve the tokens against. Default `<html>`; pass\n * a subtree root when a section carries a scoped theme.\n * @returns Literal color strings in cycle order.\n */\nexport function resolveChartColors(element?: Element | null): string[] {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return DEFAULT_CHART_COLORS;\n }\n\n const target = element ?? document.documentElement;\n if (!target) return DEFAULT_CHART_COLORS;\n\n const styles = window.getComputedStyle(target);\n const resolved: string[] = [];\n const declared = Number.parseInt(styles.getPropertyValue(\"--tempest-chart-count\").trim(), 10);\n const limit =\n Number.isFinite(declared) && declared > 0\n ? Math.min(declared, CHART_COLOR_TOKEN_COUNT)\n : CHART_COLOR_TOKEN_COUNT;\n\n for (let index = 1; index <= limit; index += 1) {\n const value = styles.getPropertyValue(`--tempest-chart-${index}`).trim();\n if (!value) break;\n resolved.push(value);\n }\n\n return resolved.length > 0 ? resolved : DEFAULT_CHART_COLORS;\n}\n\n/**\n * Read one piece of chart chrome (`--tempest-chart-grid` / `--tempest-chart-axis`).\n *\n * @param part - Which chrome token to read.\n * @param element - Element to resolve against. Default `<html>`.\n * @param fallback - Value returned when the token is unset.\n * @returns The resolved color, or `fallback`.\n */\nexport function resolveChartChrome(\n part: \"grid\" | \"axis\",\n element?: Element | null,\n fallback = part === \"grid\" ? \"#e4e7ec\" : \"#667085\",\n): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return fallback;\n const target = element ?? document.documentElement;\n if (!target) return fallback;\n const value = window\n .getComputedStyle(target)\n .getPropertyValue(`--tempest-chart-${part}`)\n .trim();\n return value || fallback;\n}\n"],"mappings":";AAmBA,IAAa,IAAiC;CAC1C;CACA;CACA;CACA;CACA;CACA;AACJ,GAGa,IAA0B;AAevC,SAAgB,EAAmB,GAAoC;CACnE,IAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KACrD,OAAO;CAGX,IAAM,IAAS,KAAW,SAAS;CACnC,IAAI,CAAC,GAAQ,OAAO;CAEpB,IAAM,IAAS,OAAO,iBAAiB,CAAM,GACvC,IAAqB,CAAC,GACtB,IAAW,OAAO,SAAS,EAAO,iBAAiB,uBAAuB,CAAC,CAAC,KAAK,GAAG,EAAE,GACtF,IACF,OAAO,SAAS,CAAQ,KAAK,IAAW,IAClC,KAAK,IAAI,GAAA,CAAiC,IAAA;CAGpD,KAAK,IAAI,IAAQ,GAAG,KAAS,GAAO,KAAS,GAAG;EAC5C,IAAM,IAAQ,EAAO,iBAAiB,mBAAmB,GAAO,CAAC,CAAC,KAAK;EACvE,IAAI,CAAC,GAAO;EACZ,EAAS,KAAK,CAAK;CACvB;CAEA,OAAO,EAAS,SAAS,IAAI,IAAW;AAC5C;AAUA,SAAgB,EACZ,GACA,GACA,IAAW,MAAS,SAAS,YAAY,WACnC;CACN,IAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KAAa,OAAO;CAC7E,IAAM,IAAS,KAAW,SAAS;CAMnC,OALK,KACS,OACT,iBAAiB,CAAM,CAAC,CACxB,iBAAiB,mBAAmB,GAAM,CAAC,CAC3C,KACE,KALa;AAMxB"}
|
package/dist/charts.d.ts
CHANGED
|
@@ -153,9 +153,11 @@ export declare function resolveChartChrome(part: "grid" | "axis", element?: Elem
|
|
|
153
153
|
/**
|
|
154
154
|
* Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.
|
|
155
155
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
156
|
+
* Respects `--tempest-chart-count` when the theme declares one (`createTheme`
|
|
157
|
+
* writes it), so a six-color brand palette is read as six and not padded with the
|
|
158
|
+
* SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at
|
|
159
|
+
* the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is
|
|
160
|
+
* resolvable.
|
|
159
161
|
*
|
|
160
162
|
* @param element - Element to resolve the tokens against. Default `<html>`; pass
|
|
161
163
|
* a subtree root when a section carries a scoped theme.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require("react"),t=require("react/jsx-runtime");function n({onOutside:n,children:r,...i}){let a=(0,e.useRef)(null),o=(0,e.useRef)(n);return
|
|
1
|
+
let e=require("react"),t=require("react/jsx-runtime");function n({onOutside:n,children:r,...i}){let a=(0,e.useRef)(null),o=(0,e.useRef)(n);return(0,e.useEffect)(()=>{o.current=n},[n]),(0,e.useEffect)(()=>{if(typeof document>`u`)return;function e(e){let t=a.current,n=e.target;t&&n&&!t.contains(n)&&o.current(e)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[]),(0,t.jsx)(`div`,{ref:a,...i,children:r})}exports.ClickOutside=n;
|
|
2
2
|
//# sourceMappingURL=ClickOutside.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClickOutside.cjs","names":[],"sources":["../../../src/components/ClickOutside/ClickOutside.tsx"],"sourcesContent":["import { useEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface ClickOutsideProps extends HTMLAttributes<HTMLDivElement> {\n /** Called when a pointer event lands outside the wrapped subtree. */\n onOutside: (event: MouseEvent | TouchEvent) => void;\n /** Content wrapped by the outside-click boundary. */\n children: ReactNode;\n}\n\n/**\n * Wraps its children in a `<div>` and invokes `onOutside` whenever a\n * `mousedown` or `touchstart` event occurs outside that subtree.\n *\n * Useful for dismissing popovers, dropdowns and menus on outside interaction.\n * Listeners are attached to `document` on mount and removed on unmount.\n *\n * @param props - The click-outside props, plus any `<div>` attributes.\n * @returns The wrapper element containing the children.\n */\nexport function ClickOutside({ onOutside, children, ...props }: ClickOutsideProps): ReactNode {\n const ref = useRef<HTMLDivElement>(null);\n const handlerRef = useRef(onOutside);\n handlerRef.current = onOutside;\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n function handle(event: MouseEvent | TouchEvent): void {\n const node = ref.current;\n const target = event.target as Node | null;\n if (node && target && !node.contains(target)) {\n handlerRef.current(event);\n }\n }\n\n document.addEventListener(\"mousedown\", handle);\n document.addEventListener(\"touchstart\", handle);\n return () => {\n document.removeEventListener(\"mousedown\", handle);\n document.removeEventListener(\"touchstart\", handle);\n };\n }, []);\n\n return (\n <div ref={ref} {...props}>\n {children}\n </div>\n );\n}\n"],"mappings":"sDAmBA,SAAgB,EAAa,CAAE,YAAW,WAAU,GAAG,GAAuC,CAC1F,IAAM,GAAA,EAAA,EAAA,OAAA,CAA6B,IAAI,EACjC,GAAA,EAAA,EAAA,OAAA,CAAoB,CAAS,
|
|
1
|
+
{"version":3,"file":"ClickOutside.cjs","names":[],"sources":["../../../src/components/ClickOutside/ClickOutside.tsx"],"sourcesContent":["import { useEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface ClickOutsideProps extends HTMLAttributes<HTMLDivElement> {\n /** Called when a pointer event lands outside the wrapped subtree. */\n onOutside: (event: MouseEvent | TouchEvent) => void;\n /** Content wrapped by the outside-click boundary. */\n children: ReactNode;\n}\n\n/**\n * Wraps its children in a `<div>` and invokes `onOutside` whenever a\n * `mousedown` or `touchstart` event occurs outside that subtree.\n *\n * Useful for dismissing popovers, dropdowns and menus on outside interaction.\n * Listeners are attached to `document` on mount and removed on unmount.\n *\n * @param props - The click-outside props, plus any `<div>` attributes.\n * @returns The wrapper element containing the children.\n */\nexport function ClickOutside({ onOutside, children, ...props }: ClickOutsideProps): ReactNode {\n const ref = useRef<HTMLDivElement>(null);\n const handlerRef = useRef(onOutside);\n useEffect(() => {\n handlerRef.current = onOutside;\n }, [onOutside]);\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n function handle(event: MouseEvent | TouchEvent): void {\n const node = ref.current;\n const target = event.target as Node | null;\n if (node && target && !node.contains(target)) {\n handlerRef.current(event);\n }\n }\n\n document.addEventListener(\"mousedown\", handle);\n document.addEventListener(\"touchstart\", handle);\n return () => {\n document.removeEventListener(\"mousedown\", handle);\n document.removeEventListener(\"touchstart\", handle);\n };\n }, []);\n\n return (\n <div ref={ref} {...props}>\n {children}\n </div>\n );\n}\n"],"mappings":"sDAmBA,SAAgB,EAAa,CAAE,YAAW,WAAU,GAAG,GAAuC,CAC1F,IAAM,GAAA,EAAA,EAAA,OAAA,CAA6B,IAAI,EACjC,GAAA,EAAA,EAAA,OAAA,CAAoB,CAAS,EA0BnC,OAzBA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAW,QAAU,CACzB,EAAG,CAAC,CAAS,CAAC,GAEd,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,OAAO,SAAa,IACpB,OAGJ,SAAS,EAAO,EAAsC,CAClD,IAAM,EAAO,EAAI,QACX,EAAS,EAAM,OACjB,GAAQ,GAAU,CAAC,EAAK,SAAS,CAAM,GACvC,EAAW,QAAQ,CAAK,CAEhC,CAIA,OAFA,SAAS,iBAAiB,YAAa,CAAM,EAC7C,SAAS,iBAAiB,aAAc,CAAM,MACjC,CACT,SAAS,oBAAoB,YAAa,CAAM,EAChD,SAAS,oBAAoB,aAAc,CAAM,CACrD,CACJ,EAAG,CAAC,CAAC,GAGD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAU,MAAK,GAAI,EACd,UACA,CAAA,CAEb"}
|
|
@@ -3,7 +3,9 @@ import { jsx as n } from "react/jsx-runtime";
|
|
|
3
3
|
//#region src/components/ClickOutside/ClickOutside.tsx
|
|
4
4
|
function r({ onOutside: r, children: i, ...a }) {
|
|
5
5
|
let o = t(null), s = t(r);
|
|
6
|
-
return
|
|
6
|
+
return e(() => {
|
|
7
|
+
s.current = r;
|
|
8
|
+
}, [r]), e(() => {
|
|
7
9
|
if (typeof document > "u") return;
|
|
8
10
|
function e(e) {
|
|
9
11
|
let t = o.current, n = e.target;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClickOutside.js","names":[],"sources":["../../../src/components/ClickOutside/ClickOutside.tsx"],"sourcesContent":["import { useEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface ClickOutsideProps extends HTMLAttributes<HTMLDivElement> {\n /** Called when a pointer event lands outside the wrapped subtree. */\n onOutside: (event: MouseEvent | TouchEvent) => void;\n /** Content wrapped by the outside-click boundary. */\n children: ReactNode;\n}\n\n/**\n * Wraps its children in a `<div>` and invokes `onOutside` whenever a\n * `mousedown` or `touchstart` event occurs outside that subtree.\n *\n * Useful for dismissing popovers, dropdowns and menus on outside interaction.\n * Listeners are attached to `document` on mount and removed on unmount.\n *\n * @param props - The click-outside props, plus any `<div>` attributes.\n * @returns The wrapper element containing the children.\n */\nexport function ClickOutside({ onOutside, children, ...props }: ClickOutsideProps): ReactNode {\n const ref = useRef<HTMLDivElement>(null);\n const handlerRef = useRef(onOutside);\n handlerRef.current = onOutside;\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n function handle(event: MouseEvent | TouchEvent): void {\n const node = ref.current;\n const target = event.target as Node | null;\n if (node && target && !node.contains(target)) {\n handlerRef.current(event);\n }\n }\n\n document.addEventListener(\"mousedown\", handle);\n document.addEventListener(\"touchstart\", handle);\n return () => {\n document.removeEventListener(\"mousedown\", handle);\n document.removeEventListener(\"touchstart\", handle);\n };\n }, []);\n\n return (\n <div ref={ref} {...props}>\n {children}\n </div>\n );\n}\n"],"mappings":";;;AAmBA,SAAgB,EAAa,EAAE,cAAW,aAAU,GAAG,KAAuC;CAC1F,IAAM,IAAM,EAAuB,IAAI,GACjC,IAAa,EAAO,CAAS;
|
|
1
|
+
{"version":3,"file":"ClickOutside.js","names":[],"sources":["../../../src/components/ClickOutside/ClickOutside.tsx"],"sourcesContent":["import { useEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface ClickOutsideProps extends HTMLAttributes<HTMLDivElement> {\n /** Called when a pointer event lands outside the wrapped subtree. */\n onOutside: (event: MouseEvent | TouchEvent) => void;\n /** Content wrapped by the outside-click boundary. */\n children: ReactNode;\n}\n\n/**\n * Wraps its children in a `<div>` and invokes `onOutside` whenever a\n * `mousedown` or `touchstart` event occurs outside that subtree.\n *\n * Useful for dismissing popovers, dropdowns and menus on outside interaction.\n * Listeners are attached to `document` on mount and removed on unmount.\n *\n * @param props - The click-outside props, plus any `<div>` attributes.\n * @returns The wrapper element containing the children.\n */\nexport function ClickOutside({ onOutside, children, ...props }: ClickOutsideProps): ReactNode {\n const ref = useRef<HTMLDivElement>(null);\n const handlerRef = useRef(onOutside);\n useEffect(() => {\n handlerRef.current = onOutside;\n }, [onOutside]);\n\n useEffect(() => {\n if (typeof document === \"undefined\") {\n return;\n }\n\n function handle(event: MouseEvent | TouchEvent): void {\n const node = ref.current;\n const target = event.target as Node | null;\n if (node && target && !node.contains(target)) {\n handlerRef.current(event);\n }\n }\n\n document.addEventListener(\"mousedown\", handle);\n document.addEventListener(\"touchstart\", handle);\n return () => {\n document.removeEventListener(\"mousedown\", handle);\n document.removeEventListener(\"touchstart\", handle);\n };\n }, []);\n\n return (\n <div ref={ref} {...props}>\n {children}\n </div>\n );\n}\n"],"mappings":";;;AAmBA,SAAgB,EAAa,EAAE,cAAW,aAAU,GAAG,KAAuC;CAC1F,IAAM,IAAM,EAAuB,IAAI,GACjC,IAAa,EAAO,CAAS;CA0BnC,OAzBA,QAAgB;EACZ,EAAW,UAAU;CACzB,GAAG,CAAC,CAAS,CAAC,GAEd,QAAgB;EACZ,IAAI,OAAO,WAAa,KACpB;EAGJ,SAAS,EAAO,GAAsC;GAClD,IAAM,IAAO,EAAI,SACX,IAAS,EAAM;GACrB,AAAI,KAAQ,KAAU,CAAC,EAAK,SAAS,CAAM,KACvC,EAAW,QAAQ,CAAK;EAEhC;EAIA,OAFA,SAAS,iBAAiB,aAAa,CAAM,GAC7C,SAAS,iBAAiB,cAAc,CAAM,SACjC;GAET,AADA,SAAS,oBAAoB,aAAa,CAAM,GAChD,SAAS,oBAAoB,cAAc,CAAM;EACrD;CACJ,GAAG,CAAC,CAAC,GAGD,kBAAC,OAAD;EAAU;EAAK,GAAI;EACd;CACA,CAAA;AAEb"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../utils/cn.cjs"),t=require("../../hooks/use-pagination.cjs"),n=require("../Pagination/Pagination.cjs"),r=require("../SearchBar/SearchBar.cjs"),i=require("../Table/Table.cjs"),a=require("./DataTable.module.cjs");let
|
|
1
|
+
const e=require("../../utils/cn.cjs"),t=require("../../hooks/use-pagination.cjs"),n=require("../Pagination/Pagination.cjs"),r=require("../SearchBar/SearchBar.cjs"),i=require("../Table/Table.cjs"),a=require("../../utils/compare-values.cjs"),o=require("./DataTable.module.cjs");let s=require("react"),c=require("react/jsx-runtime");function l({data:l,columns:u,pageSize:d=10,searchable:f=!1,searchKeys:p,initialSort:m,rowKey:h=(e,t)=>t,emptyMessage:g,className:_,...v}){let[y,b]=(0,s.useState)(``),[x,S]=(0,s.useState)(m??null),{page:C,setPage:w}=t.usePagination(1,d),T=(0,s.useMemo)(()=>p&&p.length>0?p:u.filter(e=>{let t=l.find(t=>t[e.key]!=null),n=t?t[e.key]:void 0;return typeof n==`string`||typeof n==`number`}).map(e=>e.key),[p,u,l]),E=(0,s.useMemo)(()=>{let e=y.trim().toLowerCase();return!e||!f?l:l.filter(t=>T.some(n=>{let r=t[n];return r!=null&&String(r).toLowerCase().includes(e)}))},[l,y,f,T]),D=(0,s.useMemo)(()=>{if(!x)return E;let e=x.direction===`asc`?1:-1;return[...E].sort((t,n)=>a.compareValues(t[x.key],n[x.key])*e)},[E,x]),O=Math.max(1,Math.ceil(D.length/d));(0,s.useEffect)(()=>{C>O&&w(O)},[C,O,w]);let k=Math.min(C,O),A=(0,s.useMemo)(()=>{let e=(k-1)*d;return D.slice(e,e+d)},[D,k,d]);function j(e){S(t=>!t||t.key!==e?{key:e,direction:`asc`}:t.direction===`asc`?{key:e,direction:`desc`}:null)}let M=(0,s.useMemo)(()=>u.map(e=>{let t=x?.key===e.key?x?.direction===`asc`?` ▲`:` ▼`:``,n=e.sortable?(0,c.jsxs)(`button`,{type:`button`,className:o.default.sortButton,onClick:()=>j(e.key),"aria-label":`Ordenar por ${typeof e.header==`string`?e.header:String(e.key)}`,children:[e.header,(0,c.jsx)(`span`,{className:o.default.sortIndicator,"aria-hidden":!0,children:t})]}):e.header;return{key:String(e.key),header:n,align:e.align,priority:e.priority,width:e.width,render:e.render?t=>e.render(t):t=>t[e.key]??null}}),[u,x]);return(0,c.jsxs)(`div`,{className:e.cn(o.default.wrapper,_),...v,children:[f&&(0,c.jsx)(r.SearchBar,{value:y,onChange:e=>{b(e),w(1)},wrapperClassName:o.default.search}),(0,c.jsx)(i.Table,{columns:M,data:A,rowKey:(e,t)=>h(e,(k-1)*d+t),emptyMessage:g}),O>1&&(0,c.jsx)(n.Pagination,{page:k,totalPages:O,onPageChange:w,totalItems:D.length})]})}exports.DataTable=l;
|
|
2
2
|
//# sourceMappingURL=DataTable.cjs.map
|