@kahitsan/ksui 0.47.1 → 0.47.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kahitsan/ksui",
3
- "version": "0.47.1",
3
+ "version": "0.47.2",
4
4
  "description": "ksui is a standalone set of SolidJS UI components for KahitSan/Hilinga and any SolidJS app. Published to the public npm registry and consumed as a normal dependency. Ships source under a `solid` export condition so the consumer's vite-plugin-solid compiles it with only solid-js externalized; it depends on nothing but solid-js + lucide-solid and injects its own CSS.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -2,7 +2,8 @@
2
2
  // and address, offers inputs when they are missing, and warns when withholding
3
3
  // is on but no TIN is known.
4
4
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
- import { render, fireEvent, waitFor } from "@solidjs/testing-library";
5
+ import { render, fireEvent, waitFor, screen } from "@solidjs/testing-library";
6
+ import { createSignal } from "solid-js";
6
7
  import TransactionForm, { type TransactionFormProps } from "./TransactionForm";
7
8
  import { isValidTin } from "./payee-tin";
8
9
 
@@ -225,4 +226,51 @@ describe("TransactionForm payee tax ID", () => {
225
226
  await Promise.resolve();
226
227
  expect(queryByTestId("form-payee-tin-input")).toBeNull();
227
228
  });
229
+
230
+ it("shows the newly picked payee's tax ID when switching payees", async () => {
231
+ const payees = [
232
+ { id: 1, name: "Alpha Mart", kind: "vendor", tin: "123-456-789-00043", address: "1 Main St" },
233
+ { id: 2, name: "Beta Shop", kind: "vendor", tin: null, address: null },
234
+ ];
235
+ vi.stubGlobal(
236
+ "fetch",
237
+ vi.fn(async (url: string) => {
238
+ const one = /\/api\/payees\/(\d+)/.exec(String(url));
239
+ const body = one ? payees.find((p) => p.id === Number(one[1])) : { data: payees };
240
+ return new Response(JSON.stringify(body), { status: 200 });
241
+ }),
242
+ );
243
+ const [payee, setPayee] = createSignal("");
244
+ const [payeeId, setPayeeId] = createSignal<number | null>(null);
245
+ const { findByTestId, queryByTestId } = render(() => (
246
+ <TransactionForm
247
+ {...tinProps({
248
+ get payee() {
249
+ return payee();
250
+ },
251
+ setPayee,
252
+ get payeeId() {
253
+ return payeeId();
254
+ },
255
+ setPayeeId,
256
+ })}
257
+ />
258
+ ));
259
+ const pick = async (id: number) => {
260
+ fireEvent.click(await screen.findByTestId("form-payee-picker-trigger"));
261
+ fireEvent.input(await screen.findByTestId("form-payee-picker-input"), { target: { value: "a" } });
262
+ fireEvent.click(await screen.findByTestId(`form-payee-picker-result-${id}`));
263
+ };
264
+
265
+ await pick(1);
266
+ expect((await findByTestId("form-payee-tin-readonly")).textContent).toContain("123-456-789-00043");
267
+
268
+ await pick(2);
269
+ await findByTestId("form-payee-tin-input");
270
+ expect(queryByTestId("form-payee-tin-readonly")).toBeNull();
271
+
272
+ await pick(1);
273
+ expect((await findByTestId("form-payee-tin-readonly")).textContent).toContain("123-456-789-00043");
274
+ expect(queryByTestId("form-payee-tin-input")).toBeNull();
275
+ });
228
276
  });
@@ -7,7 +7,7 @@
7
7
  // advanced-fields toggle entirely, for a caller that locks `category` to one
8
8
  // value and never needs EWT/sharing (e.g. a "record my own expense" surface).
9
9
 
10
- import { createEffect, createSignal, Show, For } from "solid-js";
10
+ import { batch, createEffect, createSignal, Show, For } from "solid-js";
11
11
  import X from "lucide-solid/icons/x";
12
12
  import Upload from "lucide-solid/icons/upload";
13
13
  import FileIcon from "lucide-solid/icons/file";
@@ -788,13 +788,16 @@ export default function TransactionForm(props: TransactionFormProps) {
788
788
  icon={Store}
789
789
  noun="payee"
790
790
  placeholder={catConfig().payeePlaceholder!}
791
- onChange={(p) => {
792
- setSelectedPayee(p);
793
- props.setPayee(p ? p.name : "");
794
- props.setPayeeId(p ? p.id : null);
795
- props.setPayeeTin?.("");
796
- props.setPayeeAddress?.("");
797
- }}
791
+ onChange={(p) =>
792
+ // One batch so the sync effect never sees the new name with the old id.
793
+ batch(() => {
794
+ setSelectedPayee(p);
795
+ props.setPayee(p ? p.name : "");
796
+ props.setPayeeId(p ? p.id : null);
797
+ props.setPayeeTin?.("");
798
+ props.setPayeeAddress?.("");
799
+ })
800
+ }
798
801
  />
799
802
  </FormField>
800
803
  <FormField label={props.category === "sale" ? "Invoice ID" : "Receipt / Ref #"}>