@close-by/clay 0.2.2 → 0.2.4

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,15 +1,17 @@
1
1
  {
2
2
  "name": "@close-by/clay",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "NiceGUI-like ui.* facade for Clay apps",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "src/index.ts",
8
8
  "exports": {
9
- ".": "./src/index.ts"
9
+ ".": "./src/index.ts",
10
+ "./page-tsconfig": "./page-tsconfig.json"
10
11
  },
11
12
  "files": [
12
13
  "src",
14
+ "page-tsconfig.json",
13
15
  "README.md",
14
16
  "LICENSE",
15
17
  "!src/**/*.test.ts",
@@ -25,9 +27,10 @@
25
27
  "access": "public"
26
28
  },
27
29
  "dependencies": {
28
- "@close-by/clay-core": "0.2.2",
29
- "@close-by/clay-components": "0.2.2",
30
- "@close-by/clay-server": "0.2.2",
30
+ "@close-by/clay-compiler": "0.2.4",
31
+ "@close-by/clay-core": "0.2.4",
32
+ "@close-by/clay-components": "0.2.4",
33
+ "@close-by/clay-server": "0.2.4",
31
34
  "@tailwindcss/cli": "^4.3.3",
32
35
  "tailwindcss": "^4.3.3"
33
36
  }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "compilerOptions": {
4
+ "lib": ["ESNext"],
5
+ "types": ["bun-types"],
6
+ "target": "ESNext",
7
+ "module": "Preserve",
8
+ "moduleResolution": "bundler",
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "noEmit": true,
12
+ "verbatimModuleSyntax": true
13
+ }
14
+ }
package/src/index.ts CHANGED
@@ -22,6 +22,8 @@ import {
22
22
  progress as progressFactory,
23
23
  separator as separatorFactory,
24
24
  icon as iconFactory,
25
+ iconText as iconTextFactory,
26
+ statusDot as statusDotFactory,
25
27
  stat as statFactory,
26
28
  dataTable as dataTableFactory,
27
29
  areaChart as areaChartFactory,
@@ -52,6 +54,7 @@ import {
52
54
  command as commandFactory,
53
55
  resizable as resizableFactory,
54
56
  scrollArea as scrollAreaFactory,
57
+ viewportEnter as viewportEnterFactory,
55
58
  keybind as keybindFactory,
56
59
  kbd as kbdFactory,
57
60
  sheet as sheetFactory,
@@ -66,6 +69,7 @@ import {
66
69
  markdown as markdownFactory,
67
70
  html as htmlFactory,
68
71
  image as imageFactory,
72
+ iframe as iframeFactory,
69
73
  upload as uploadFactory,
70
74
  rating as ratingFactory,
71
75
  colorPicker as colorPickerFactory,
@@ -109,6 +113,10 @@ import {
109
113
  type ProgressProps,
110
114
  type SeparatorProps,
111
115
  type IconProps,
116
+ type IconTextProps,
117
+ type IconSlotProps,
118
+ type StatusDotProps,
119
+ type StatusDotColor,
112
120
  type StatItem,
113
121
  type DataTableProps,
114
122
  type DataTableAction,
@@ -175,6 +183,7 @@ import {
175
183
  type ResizablePanelProps,
176
184
  type ResizableHandleProps,
177
185
  type ScrollAreaProps,
186
+ type ViewportEnterProps,
178
187
  type KeybindProps,
179
188
  type KbdProps,
180
189
  type BreadcrumbItem,
@@ -200,6 +209,8 @@ import {
200
209
  type MarkdownProps,
201
210
  type HtmlProps,
202
211
  type ImageProps,
212
+ type IframeProps,
213
+ type ViewportEnterProps,
203
214
  type UploadProps,
204
215
  type UploadVariant,
205
216
  type UploadedFile,
@@ -474,6 +485,8 @@ export type {
474
485
  MarkdownProps,
475
486
  HtmlProps,
476
487
  ImageProps,
488
+ IframeProps,
489
+ ViewportEnterProps,
477
490
  UploadProps,
478
491
  UploadVariant,
479
492
  UploadedFile,
@@ -617,7 +630,10 @@ export function label(text?: string | (() => string), props?: Omit<LabelProps, '
617
630
  }
618
631
 
619
632
  /** Clickable button. Prefer `ui.button`. See {@link ButtonProps}. */
620
- export function button(text?: string, props?: Omit<ButtonProps, 'text'>): Element {
633
+ export function button(
634
+ text?: string | (() => string),
635
+ props?: Omit<ButtonProps, 'text'>,
636
+ ): Element {
621
637
  return buttonFactory(text, props);
622
638
  }
623
639
 
@@ -706,8 +722,11 @@ export function externalLink(
706
722
  }
707
723
 
708
724
  /** Small status badge. Prefer `ui.badge`. See {@link BadgeProps}. */
709
- export function badge(text?: string, props?: Omit<BadgeProps, 'text'>): Element {
710
- return badgeFactory(text, props);
725
+ export function badge(
726
+ text?: string | (() => string) | BadgeProps,
727
+ props?: Omit<BadgeProps, 'text'>,
728
+ ): Element {
729
+ return badgeFactory(text as Parameters<typeof badgeFactory>[0], props);
711
730
  }
712
731
 
713
732
  /**
@@ -759,6 +778,19 @@ export function icon(name: string, props?: Omit<IconProps, 'name'>): Element {
759
778
  return iconFactory(name, props);
760
779
  }
761
780
 
781
+ /** Inline icon + text (replaces manual `ui.row` + `ui.icon` + `ui.label`). See {@link IconTextProps}. */
782
+ export function iconText(
783
+ text?: string | (() => string),
784
+ props?: Omit<IconTextProps, 'text'>,
785
+ ): Element {
786
+ return iconTextFactory(text, props);
787
+ }
788
+
789
+ /** Status dot (or icon) + label for feeds and tables. See {@link StatusDotProps}. */
790
+ export function statusDot(props?: StatusDotProps): Element {
791
+ return statusDotFactory(props);
792
+ }
793
+
762
794
  /** Render markdown to HTML. Prefer `ui.markdown`. See {@link MarkdownProps}. */
763
795
  export function markdown(text?: string, props?: MarkdownProps): Element {
764
796
  return markdownFactory(text, props);
@@ -774,6 +806,11 @@ export function image(src: string, props?: ImageProps): Element {
774
806
  return imageFactory(src, props);
775
807
  }
776
808
 
809
+ /** Iframe embed. Prefer `ui.iframe`. See {@link IframeProps}. */
810
+ export function iframe(src: string, props?: IframeProps): Element {
811
+ return iframeFactory(src, props);
812
+ }
813
+
777
814
  /** File upload control (`POST /upload`). Prefer `ui.upload`. See {@link UploadProps}. */
778
815
  export function upload(props?: UploadProps): Element {
779
816
  return uploadFactory(props);
@@ -1115,6 +1152,23 @@ export function scrollArea(a: any, b?: any): Element {
1115
1152
  return scrollAreaFactory(a, b);
1116
1153
  }
1117
1154
 
1155
+ /**
1156
+ * Observe when children enter the viewport (IntersectionObserver).
1157
+ * Prefer `ui.viewportEnter`. See {@link ViewportEnterProps}.
1158
+ *
1159
+ * @example
1160
+ * ```ts
1161
+ * ui.viewportEnter({ onEnter: () => void loadMore(), once: true }, () => {
1162
+ * ui.label('Lazy section');
1163
+ * });
1164
+ * ```
1165
+ */
1166
+ export function viewportEnter(fn: () => void, props?: ViewportEnterProps): Element;
1167
+ export function viewportEnter(props: ViewportEnterProps, fn: () => void): Element;
1168
+ export function viewportEnter(a: any, b?: any): Element {
1169
+ return viewportEnterFactory(a, b);
1170
+ }
1171
+
1118
1172
  /**
1119
1173
  * Headless keyboard chord listener. Prefer `ui.keybind`. See {@link KeybindProps}.
1120
1174
  *
@@ -1485,6 +1539,7 @@ export const ui = {
1485
1539
  markdown,
1486
1540
  html,
1487
1541
  image,
1542
+ iframe,
1488
1543
  upload,
1489
1544
  rating,
1490
1545
  colorPicker,
@@ -1533,6 +1588,7 @@ export const ui = {
1533
1588
  command,
1534
1589
  resizable,
1535
1590
  scrollArea,
1591
+ viewportEnter,
1536
1592
  keybind,
1537
1593
  kbd,
1538
1594
  breadcrumb,
package/src/pages.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { fileURLToPath, pathToFileURL } from 'url';
2
2
  import { join } from 'path';
3
+ import { readFile } from 'fs/promises';
3
4
  import {
4
5
  clearPages,
5
6
  getRegisteredPaths,
6
7
  type PageFn,
7
8
  } from '@close-by/clay-core';
9
+ import { warnClayPageIssues } from '@close-by/clay-compiler';
8
10
  import type { AppNavItem } from '@close-by/clay-components';
9
11
 
10
12
  /**
@@ -26,6 +28,15 @@ export async function importFresh(absPath: string): Promise<unknown> {
26
28
  return import(href);
27
29
  }
28
30
 
31
+ async function warnPageModuleIfNeeded(absPath: string): Promise<void> {
32
+ try {
33
+ const text = await readFile(absPath, 'utf8');
34
+ warnClayPageIssues(text, absPath);
35
+ } catch {
36
+ // unreadable — import will surface the error
37
+ }
38
+ }
39
+
29
40
  /**
30
41
  * Optional metadata for a registered page — used by `navFromPages` / `loadPages`.
31
42
  * Export as `pageMeta` from a page module, or pass via `attachPageMeta`.
@@ -108,6 +119,7 @@ export async function loadPages(dir: string | URL): Promise<string[]> {
108
119
  for (const relative of files) {
109
120
  const fullPath = join(absDir, relative);
110
121
  const pathsBefore = new Set(getRegisteredPaths());
122
+ await warnPageModuleIfNeeded(fullPath);
111
123
  const mod = (await importFresh(fullPath)) as { pageMeta?: PageMeta };
112
124
  const added = getRegisteredPaths().filter((p) => !pathsBefore.has(p));
113
125
  if (added.length === 1 && mod.pageMeta) {