@close-by/clay 0.2.11 → 0.2.12

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.
@@ -39,9 +39,9 @@ const live = ui.state({ selectedId: null as string | null, rows: [] as Row[] });
39
39
 
40
40
  ui.auto(() => {
41
41
  ui.resizable(
42
- { orientation: 'horizontal', className: 'h-[calc(100vh-8rem)] w-full min-h-[24rem]' },
42
+ { orientation: 'horizontal', fill: 'viewport' },
43
43
  (r) => {
44
- r.panel({ defaultSize: 40, minSize: 28 }, () => {
44
+ r.panel({ defaultSize: 40, minSize: 28, className: 'min-h-0 overflow-hidden' }, () => {
45
45
  ui.auto(() => {
46
46
  for (const row of live.rows) {
47
47
  ui.button(row.id, {
@@ -54,11 +54,12 @@ ui.auto(() => {
54
54
  }
55
55
  });
56
56
  });
57
- r.panel({ defaultSize: 60, minSize: 36 }, () => {
57
+ r.handle();
58
+ r.panel({ defaultSize: 60, minSize: 36, className: 'min-h-0 overflow-hidden' }, () => {
58
59
  ui.auto(() => {
59
60
  const row = live.rows.find((x) => x.id === live.selectedId);
60
61
  if (!row) {
61
- ui.label('Select a row').classes('text-sm text-muted-foreground');
62
+ ui.empty({ title: 'Select a row', density: 'inline' });
62
63
  return;
63
64
  }
64
65
  // detail…
@@ -70,7 +71,7 @@ ui.auto(() => {
70
71
  });
71
72
  ```
72
73
 
73
- Keep **separate** `ui.auto` regions for list vs detail so selection updates do not remount the whole shell. Default panel sizes (`defaultSize` / `minSize`) are percentages.
74
+ Keep **separate** `ui.auto` regions for list vs detail so selection updates do not remount the whole shell. Default panel sizes (`defaultSize` / `minSize`) are percentages. Prefer `fill: 'parent' | 'viewport'` over viewport `calc` height utilities.
74
75
 
75
76
  ## Live feed rows (not `ui.list`)
76
77
 
@@ -163,7 +164,7 @@ For **`ui.dataTable`**, pass `showFilterChips: true` to surface active search +
163
164
  ```ts
164
165
  ui.auto(() => {
165
166
  if (live.loadingMore) {
166
- ui.label('Loading…').classes('text-xs text-muted-foreground p-2');
167
+ ui.label('Loading…', { tone: 'muted', size: 'xs' });
167
168
  return;
168
169
  }
169
170
  if (!live.hasMore) return;
@@ -183,6 +184,22 @@ ui.auto(() => {
183
184
 
184
185
  Alternative when you already wrap the list in **`ui.scrollArea`**: use `onNearEnd` on the scroll area (scroll-root is built-in). Prefer one pattern per surface — `viewportEnter` + `nearest-scroll` does **not** require `scrollArea`.
185
186
 
187
+ ## Fewer classes (ops density)
188
+
189
+ Prefer semantic props over Tailwind soup:
190
+
191
+ | Instead of… | Prefer… |
192
+ |-------------|---------|
193
+ | `.classes('text-sm text-muted-foreground')` | `ui.label(…, { tone: 'muted', size: 'sm' })` |
194
+ | Title + subtitle stacks | `ui.pageHeading('Orders', { description: '…' })` |
195
+ | `className: 'flex-row w-[10rem]'` on filters | `ui.select({ inline: true, width: 'sm', … })` |
196
+ | `ui.spinner({ className: 'h-3 w-3' })` | `ui.spinner({ size: 'xs' })` |
197
+ | Feed empty muted label | `ui.empty({ title: '…', density: 'inline' })` |
198
+ | `h-[calc(100%-7rem)]!` on resizable | `ui.resizable({ fill: 'parent' \| 'viewport' }, …)` |
199
+ | `className: 'items-end justify-between'` on rows | `ui.row({ align: 'end', justify: 'between' }, …)` |
200
+
201
+ `className` remains an escape hatch.
202
+
186
203
  ## Logs / traces — sensitive bodies
187
204
 
188
205
  Structured logs often contain API keys or partner tokens. Scrubbing is the **app’s** job; Clay can still reduce shoulder-surfing:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@close-by/clay",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "NiceGUI-like ui.* facade for Clay apps",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,10 +37,10 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@close-by/clay-compiler": "0.2.11",
41
- "@close-by/clay-core": "0.2.11",
42
- "@close-by/clay-components": "0.2.11",
43
- "@close-by/clay-server": "0.2.11",
40
+ "@close-by/clay-compiler": "0.2.12",
41
+ "@close-by/clay-core": "0.2.12",
42
+ "@close-by/clay-components": "0.2.12",
43
+ "@close-by/clay-server": "0.2.12",
44
44
  "@tailwindcss/cli": "^4.3.3",
45
45
  "tailwindcss": "^4.3.3"
46
46
  }
package/src/index.ts CHANGED
@@ -34,6 +34,7 @@ import {
34
34
  pagination as paginationFactory,
35
35
  filterBar as filterBarFactory,
36
36
  filterChips as filterChipsFactory,
37
+ pageHeading as pageHeadingFactory,
37
38
  numberField as numberFieldFactory,
38
39
  phoneInput as phoneInputFactory,
39
40
  field as fieldFactory,
@@ -120,7 +121,10 @@ import {
120
121
  type ButtonVariant,
121
122
  type ButtonSize,
122
123
  type LabelProps,
124
+ type LabelTone,
125
+ type LabelSize,
123
126
  type InputProps,
127
+ type FieldWidth,
124
128
  type CheckboxProps,
125
129
  type SwitchProps,
126
130
  type SelectProps,
@@ -144,6 +148,7 @@ import {
144
148
  type BadgeProps,
145
149
  type AlertProps,
146
150
  type SpinnerProps,
151
+ type SpinnerSize,
147
152
  type ProgressProps,
148
153
  type SeparatorProps,
149
154
  type IconProps,
@@ -157,6 +162,8 @@ import {
157
162
  type ButtonGroupProps,
158
163
  type ButtonGroupOrientation,
159
164
  type EmptyProps,
165
+ type EmptyDensity,
166
+ type PageHeadingProps,
160
167
  type PaginationProps,
161
168
  type FilterBarProps,
162
169
  type FilterChip,
@@ -253,6 +260,7 @@ import {
253
260
  type CommandMode,
254
261
  type CommandItemOptions,
255
262
  type ResizableProps,
263
+ type ResizableFill,
256
264
  type ResizableOrientation,
257
265
  type ResizablePanelProps,
258
266
  type ResizableHandleProps,
@@ -494,7 +502,10 @@ export type {
494
502
  ButtonVariant,
495
503
  ButtonSize,
496
504
  LabelProps,
505
+ LabelTone,
506
+ LabelSize,
497
507
  InputProps,
508
+ FieldWidth,
498
509
  CheckboxProps,
499
510
  BadgeProps,
500
511
  LinkProps,
@@ -555,6 +566,7 @@ export type {
555
566
  AvatarProps,
556
567
  SkeletonProps,
557
568
  SpinnerProps,
569
+ SpinnerSize,
558
570
  ProgressProps,
559
571
  SeparatorProps,
560
572
  IconProps,
@@ -931,6 +943,11 @@ export function empty(props: EmptyProps, footer?: () => void): Element {
931
943
  return emptyFactory(props, footer);
932
944
  }
933
945
 
946
+ /** Page title + optional description. Prefer over stacked muted labels. */
947
+ export function pageHeading(props: PageHeadingProps, trailing?: () => void): Element {
948
+ return pageHeadingFactory(props, trailing);
949
+ }
950
+
934
951
  /** Standalone pager. See {@link PaginationProps}. */
935
952
  export function pagination(props?: PaginationProps): Element {
936
953
  return paginationFactory(props);
@@ -1789,6 +1806,7 @@ export const ui = {
1789
1806
  feedList,
1790
1807
  buttonGroup,
1791
1808
  empty,
1809
+ pageHeading,
1792
1810
  pagination,
1793
1811
  filterBar,
1794
1812
  filterChips,