@kahitsan/ksui 0.11.0 → 0.13.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
@@ -38,6 +38,25 @@ voucher and payment account pickers, the attachment tiles) call a backend that
38
38
  answers certain requests, so they shine inside an app built the KahitSan way, but
39
39
  they degrade gracefully without one. Each component page says what it needs.
40
40
 
41
+ Some components (Button, DataTable, DatePicker, etc.) use Tailwind utility
42
+ classes internally. To ensure these classes are included in your CSS output,
43
+ add the ksui Tailwind plugin to your project:
44
+
45
+ ```js
46
+ // tailwind.config.js (v3)
47
+ module.exports = {
48
+ plugins: [require("@kahitsan/ksui/tailwind")],
49
+ }
50
+ ```
51
+
52
+ ```css
53
+ /* app.css (v4) */
54
+ @plugin "@kahitsan/ksui/tailwind";
55
+ ```
56
+
57
+ Without the plugin, Tailwind may purge the utility classes ksui components use,
58
+ causing missing backgrounds or borders.
59
+
41
60
  ## What is inside
42
61
 
43
62
  The package is organized into three kinds of exports:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kahitsan/ksui",
3
- "version": "0.11.0",
3
+ "version": "0.13.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",
@@ -17,10 +17,18 @@
17
17
  "types": "./src/components/*.tsx",
18
18
  "development": "./src/components/*.tsx",
19
19
  "import": "./src/components/*.tsx"
20
- }
20
+ },
21
+ "./utils/*": {
22
+ "solid": "./src/utils/*.ts",
23
+ "types": "./src/utils/*.ts",
24
+ "development": "./src/utils/*.ts",
25
+ "import": "./src/utils/*.ts"
26
+ },
27
+ "./tailwind": "./tailwind.js"
21
28
  },
22
29
  "files": [
23
- "src"
30
+ "src",
31
+ "tailwind.js"
24
32
  ],
25
33
  "scripts": {
26
34
  "typecheck": "tsc --noEmit",
@@ -32,7 +40,13 @@
32
40
  "lucide-solid": "^1.7.0"
33
41
  },
34
42
  "peerDependencies": {
35
- "solid-js": "^1.9.0"
43
+ "solid-js": "^1.9.0",
44
+ "tailwindcss": ">=3.0.0"
45
+ },
46
+ "peerDependenciesMeta": {
47
+ "tailwindcss": {
48
+ "optional": true
49
+ }
36
50
  },
37
51
  "devDependencies": {
38
52
  "@changesets/cli": "^2.31.0",
@@ -11,13 +11,20 @@
11
11
  // names. Surface / border / accent colors read from CSS custom properties
12
12
  // (`--ksui-dt-*`) with the host's dark zinc + amber values as fallbacks, so a
13
13
  // consumer can retint without forking. The component depends only on solid-js +
14
- // lucide-solid (plus ksui's own utils); the host's `~/components/ui/DatePicker`
15
- // dependency is replaced by a self-contained native `<input type="date">` so
16
- // the library carries no host primitive.
14
+ // lucide-solid plus ksui's own DatePicker the same self-contained calendar
15
+ // popover the host DataTable used for its date filter (single + range), so the
16
+ // library carries no host primitive and no native `<input type="date">`.
17
17
  //
18
18
  // The public type surface (DataTableRow / DataTableColumn / FetchResult /
19
19
  // FetchParams / DataTableProps) mirrors the kernel's `@kserp/host-ui` ambient
20
20
  // contract EXACTLY, so a caller written against host-ui works unchanged here.
21
+ //
22
+ // Composition note: the date filter renders ksui's own `DatePicker` (a sibling
23
+ // base component) instead of a native `<input type="date">`, mirroring how the
24
+ // host DataTable wired its DatePicker. Importing one base into another technically
25
+ // makes this a composite under CONTRIBUTING's base/composite split; it stays in
26
+ // `base/` (and is re-exported as base) to preserve its existing import path —
27
+ // the only ksui dependency is DatePicker, itself a self-contained primitive.
21
28
 
22
29
  import {
23
30
  batch,
@@ -38,6 +45,7 @@ import ChevronRight from "lucide-solid/icons/chevron-right";
38
45
  import ChevronDown from "lucide-solid/icons/chevron-down";
39
46
  import ChevronUp from "lucide-solid/icons/chevron-up";
40
47
  import ChevronsUpDown from "lucide-solid/icons/chevrons-up-down";
48
+ import DatePicker from "./DatePicker";
41
49
 
42
50
  // ---------------------------------------------------------------------------
43
51
  // Injected CSS
@@ -61,10 +69,11 @@ const STYLE_ID = "ksui-datatable-style";
61
69
  // --ksui-dt-radius outer card / control corner radius (0.5rem)
62
70
  // --ksui-dt-border card / header / footer / control border (zinc-800/50, rgba(39,39,42,0.5))
63
71
  // --ksui-dt-row-border row divider + expansion-row top border (zinc-800/30, rgba(39,39,42,0.3))
64
- // --ksui-dt-control-bg filter button / menu / date input / select / search / show-more bg (zinc-900, #18181b)
72
+ // --ksui-dt-control-bg filter button / menu / select / search / show-more bg (zinc-900, #18181b)
73
+ // (the date filter is the ksui DatePicker; it reads the same vars)
65
74
  // --ksui-dt-fg primary text: row/search text (zinc-200, #e4e4e7)
66
75
  // --ksui-dt-fg-strong hover-to-full-contrast text on controls/pager (white, #ffffff)
67
- // --ksui-dt-text secondary text: filter btn / select / date input / pager nums+arrows (zinc-400, #a1a1aa)
76
+ // --ksui-dt-text secondary text: filter btn / select / pager nums+arrows (zinc-400, #a1a1aa)
68
77
  // --ksui-dt-text-strong show-more label + sortable-header hover (zinc-300, #d4d4d8)
69
78
  // --ksui-dt-muted header th / search icon+placeholder / empty / info text (zinc-500, #71717a)
70
79
  // --ksui-dt-faint sort caret / per-row date separator / pager ellipsis (zinc-600, #52525b)
@@ -88,8 +97,6 @@ const DATATABLE_CSS = `
88
97
  .ksui-datatable-filter-toggle{display:inline-flex;cursor:pointer;align-items:center;gap:0.5rem;border-radius:0.5rem;border:1px solid var(--ksui-dt-border,rgba(39,39,42,0.5));background:var(--ksui-dt-control-bg,#18181b);padding:0.5rem 0.75rem;font-size:0.75rem;line-height:1rem;color:var(--ksui-dt-text,#a1a1aa);transition:color 0.15s ease;}
89
98
  .ksui-datatable-filter-toggle:hover{color:var(--ksui-dt-fg-strong,#ffffff);}
90
99
  .ksui-datatable-filter-menu{position:absolute;left:0;top:100%;z-index:50;margin-top:0.5rem;border-radius:0.5rem;border:1px solid var(--ksui-dt-border,rgba(39,39,42,0.5));background:var(--ksui-dt-control-bg,#18181b);padding:0.75rem;box-shadow:0 20px 25px -5px rgba(0,0,0,0.4),0 8px 10px -6px rgba(0,0,0,0.4);}
91
- .ksui-datatable-date-input{border-radius:0.375rem;border:1px solid var(--ksui-dt-border,rgba(39,39,42,0.5));background:var(--ksui-dt-control-bg,#18181b);padding:0.5rem;font-size:0.75rem;line-height:1rem;color:var(--ksui-dt-text,#a1a1aa);color-scheme:dark;}
92
- .ksui-datatable-date-sep{font-size:0.75rem;color:var(--ksui-dt-faint,#52525b);}
93
100
  .ksui-datatable-select{border-radius:0.375rem;border:1px solid var(--ksui-dt-border,rgba(39,39,42,0.5));background:var(--ksui-dt-control-bg,#18181b);padding:0.5rem;font-size:0.75rem;line-height:1rem;color:var(--ksui-dt-text,#a1a1aa);}
94
101
  .ksui-datatable-search-wrap{position:relative;}
95
102
  .ksui-datatable-search-icon{position:absolute;left:0.75rem;top:50%;transform:translateY(-50%);color:var(--ksui-dt-muted,#71717a);pointer-events:none;}
@@ -711,30 +718,13 @@ export function DataTable<T extends DataTableRow>(props: DataTableProps<T>): JSX
711
718
  {/* Right side: date filter + per-page + search */}
712
719
  <div class="ksui-datatable-controls">
713
720
  <Show when={props.dateField && !props.dateRangeMode}>
714
- <input
715
- type="date"
716
- class="ksui-datatable-date-input"
717
- value={dateFilter() ?? ""}
718
- onChange={(e) => handleDateFilter(e.currentTarget.value || null)}
719
- />
721
+ <DatePicker value={dateFilter()} onChange={handleDateFilter} />
720
722
  </Show>
721
723
  <Show when={props.dateField && props.dateRangeMode}>
722
- <input
723
- type="date"
724
- class="ksui-datatable-date-input"
725
- value={dateFrom() ?? ""}
726
- onChange={(e) =>
727
- handleDateRangeFilter({ start: e.currentTarget.value || null, end: dateTo() })
728
- }
729
- />
730
- <span class="ksui-datatable-date-sep">to</span>
731
- <input
732
- type="date"
733
- class="ksui-datatable-date-input"
734
- value={dateTo() ?? ""}
735
- onChange={(e) =>
736
- handleDateRangeFilter({ start: dateFrom(), end: e.currentTarget.value || null })
737
- }
724
+ <DatePicker
725
+ range={true}
726
+ value={{ start: dateFrom(), end: dateTo() }}
727
+ onChange={handleDateRangeFilter}
738
728
  />
739
729
  </Show>
740
730
  <Show when={paging() && lengthMenu().length > 1}>