@kahitsan/ksui 0.38.2 → 0.39.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kahitsan/ksui",
3
- "version": "0.38.2",
3
+ "version": "0.39.0",
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",
@@ -43,6 +43,7 @@ import ExistingAttachmentTile, {
43
43
  import FormField from "../base/FormField";
44
44
  import DatePicker from "../base/DatePicker";
45
45
  import Button from "../base/Button";
46
+ import { injectCSS } from "../../utils/inject-css";
46
47
  import {
47
48
  type PendingFile,
48
49
  createPendingFile,
@@ -294,9 +295,12 @@ export interface TransactionFormProps {
294
295
  * For a caller that locks `category` to one value and never needs
295
296
  * EWT/sharing (e.g. a "record my own expense" surface). */
296
297
  simpleMode?: boolean;
298
+ layout?: "default" | "compact";
297
299
  }
298
300
 
299
301
  export default function TransactionForm(props: TransactionFormProps) {
302
+ injectCSS("ksui-transaction-form-compact", `.ks-transaction-compact{min-height:0;font-family:var(--ks-font-body,ui-sans-serif,system-ui,sans-serif)}.ks-transaction-compact-body{display:flex;flex-direction:column;min-height:0;overflow:auto;padding:1rem 1.25rem 1.5rem;gap:1rem}.ks-transaction-compact-body>div{width:100%;flex:0 0 auto}.ks-transaction-compact-body input[data-testid="transactions-form-amount"]{min-height:3.5rem;text-align:center;font-size:2rem}.ks-transaction-compact-body input[data-testid="transactions-form-description"]{background:transparent;border-color:var(--ks-border)}.ks-transaction-compact-body>div:has(input[data-testid="transactions-form-amount"])>label,.ks-transaction-compact-body>div:has(input[data-testid="transactions-form-description"])>label{display:none}.ks-transaction-compact-body>div:has(button[aria-label="Today"])>label{font-size:0;text-transform:uppercase;letter-spacing:.12em}.ks-transaction-compact-body>div:has(button[aria-label="Today"])>label:after{content:"TRANSACTION DATE";font-size:10px}.ks-transaction-compact-body [role="radiogroup"]{display:flex;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}.ks-transaction-compact-body [role="radiogroup"]::-webkit-scrollbar{display:none}.ks-transaction-compact-body [role="radio"]{min-width:8rem}.ks-transaction-compact-footer{flex:0 0 auto}`);
303
+ const compact = () => props.layout === "compact";
300
304
  const catConfig = () =>
301
305
  CATEGORY_FORM[props.category] || CATEGORY_FORM.expense;
302
306
  const [dragging, setDragging] = createSignal(false);
@@ -422,6 +426,7 @@ export default function TransactionForm(props: TransactionFormProps) {
422
426
  return (
423
427
  <div
424
428
  class="relative flex flex-col flex-1 min-h-0"
429
+ classList={{ "ks-transaction-compact": compact() }}
425
430
  onDragEnter={handleDragEnter}
426
431
  onDragLeave={handleDragLeave}
427
432
  onDragOver={handleDragOver}
@@ -455,7 +460,8 @@ export default function TransactionForm(props: TransactionFormProps) {
455
460
  }}
456
461
  class="flex flex-col flex-1 min-h-0"
457
462
  >
458
- <div class="flex-1 overflow-x-hidden overflow-y-auto px-5 sm:px-6 py-5 space-y-4">
463
+ <div class="flex-1 overflow-x-hidden overflow-y-auto px-5 sm:px-6 py-5 space-y-4"
464
+ classList={{ "ks-transaction-compact-body": compact() }}>
459
465
  <Show when={props.error}>
460
466
  <div
461
467
  class="rounded-lg border border-[color-mix(in_srgb,var(--ks-danger,#ef4444)_30%,transparent)] bg-[color-mix(in_srgb,var(--ks-danger,#ef4444)_10%,transparent)] px-3 py-2 text-sm text-[var(--ks-danger-fg,#f87171)]"
@@ -531,7 +537,7 @@ export default function TransactionForm(props: TransactionFormProps) {
531
537
  <Show
532
538
  when={!(props.category === "sale" && props.saleItems.length > 0)}
533
539
  >
534
- <FormField label="Amount *">
540
+ <FormField label={compact() ? "" : "Amount *"}>
535
541
  <div class="flex items-stretch gap-2 px-4 py-3 border bg-[color-mix(in_srgb,var(--ks-overlay-surface,#18181b)_60%,transparent)] border-[color-mix(in_srgb,var(--ks-border,rgba(39,39,42,0.5))_60%,transparent)] ks-hud-clip-button focus-within:border-[color-mix(in_srgb,var(--ks-focus-ring,#c9a961)_50%,transparent)] transition-colors">
536
542
  <span class="self-center text-3xl font-bold text-[var(--ks-fg-subtle,#71717a)] tabular-nums">
537
543
 
@@ -598,7 +604,7 @@ export default function TransactionForm(props: TransactionFormProps) {
598
604
  </Show>
599
605
  </Show>
600
606
 
601
- <FormField label="Date *">
607
+ <FormField label={compact() ? "TRANSACTION DATE" : "Date *"}>
602
608
  <DatePicker
603
609
  value={props.date}
604
610
  onChange={(d: string | null) => d && props.setDate(d)}
@@ -629,7 +635,7 @@ export default function TransactionForm(props: TransactionFormProps) {
629
635
  </div>
630
636
  </Show>
631
637
 
632
- <FormField label="Description *">
638
+ <FormField label={compact() ? "" : "Description *"}>
633
639
  <input
634
640
  type="text"
635
641
  data-testid="transactions-form-description"
@@ -673,14 +679,19 @@ export default function TransactionForm(props: TransactionFormProps) {
673
679
  }}
674
680
  />
675
681
  </FormField>
676
- <FormField label="Receipt / Ref #">
682
+ <FormField label={props.category === "sale" ? "Invoice ID" : "Receipt / Ref #"}>
677
683
  <input
678
684
  type="text"
679
685
  value={props.refNumber}
680
686
  onInput={(e) => props.setRefNumber(e.currentTarget.value)}
681
687
  class="w-full bg-[color-mix(in_srgb,var(--ks-overlay-surface,#18181b)_60%,transparent)] border border-[color-mix(in_srgb,var(--ks-border,rgba(39,39,42,0.5))_60%,transparent)] px-3 py-3 text-sm text-[var(--ks-fg,#ffffff)] ks-hud-clip-button focus:outline-none focus:border-[color-mix(in_srgb,var(--ks-focus-ring,#c9a961)_50%,transparent)]"
682
- placeholder="OR#, SI#, or ref number"
688
+ placeholder={props.category === "sale" ? "Auto-assigned; enter to override" : "OR#, SI#, or ref number"}
683
689
  />
690
+ <Show when={props.category === "sale"}>
691
+ <p class="mt-1 text-[10px] text-[var(--ks-fg-subtle,#71717a)]">
692
+ Leave blank for automatic numbering. Backdated sales can use a custom ID.
693
+ </p>
694
+ </Show>
684
695
  </FormField>
685
696
  </div>
686
697
  </Show>
@@ -894,9 +905,7 @@ export default function TransactionForm(props: TransactionFormProps) {
894
905
  }
895
906
  class="text-xs text-[var(--ks-fg-subtle,#71717a)] hover:text-[var(--ks-accent,#fbbf24)] px-3 py-1.5 transition-colors cursor-pointer"
896
907
  >
897
- {viewMode() === "default"
898
- ? "Show advanced fields"
899
- : "Hide advanced fields"}
908
+ {compact() ? (viewMode() === "default" ? "More details" : "Less details") : (viewMode() === "default" ? "Show advanced fields" : "Hide advanced fields")}
900
909
  </button>
901
910
  </div>
902
911
 
@@ -924,7 +933,8 @@ export default function TransactionForm(props: TransactionFormProps) {
924
933
  </Show>
925
934
  </div>
926
935
 
927
- <div class="px-5 sm:px-6 py-4 border-t border-[color-mix(in_srgb,var(--ks-border,rgba(39,39,42,0.5))_60%,transparent)] bg-[var(--ks-bg,#0a0a0a)] flex flex-col-reverse sm:flex-row sm:items-center sm:justify-between gap-3 shrink-0">
936
+ <div class="px-5 sm:px-6 py-4 border-t border-[color-mix(in_srgb,var(--ks-border,rgba(39,39,42,0.5))_60%,transparent)] bg-[var(--ks-bg,#0a0a0a)] flex flex-col-reverse sm:flex-row sm:items-center sm:justify-between gap-3 shrink-0"
937
+ classList={{ "ks-transaction-compact-footer": compact() }}>
928
938
  <div class="text-xs text-[var(--ks-fg-subtle,#71717a)]">
929
939
  <span class="text-[var(--ks-fg-subtle,#71717a)]">Will record as </span>
930
940
  <span