@columenlabs/lumen-ui 0.1.153 → 0.1.155
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/dist/index.d.ts +1 -1
- package/dist/lumen-drawer.d.ts +13 -2
- package/dist/lumen-drawer.js +3 -2
- package/dist/lumen-form.d.ts +3 -1
- package/dist/lumen-form.js +7 -5
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export { type CoverageBlock, type CoverageData, type CoverageFact, type Coverage
|
|
|
38
38
|
export { type CalendarFact, LumenCoverageCalendarMap, type LumenCoverageCalendarMapProps, } from './coverage-calendar-map.js';
|
|
39
39
|
export { DetailsTable, type DetailsTableProps, FactsTable } from './details-table.js';
|
|
40
40
|
export { DrawerSection, type DrawerSectionProps } from './drawer-section.js';
|
|
41
|
-
export { LumenDrawer, type LumenDrawerProps } from './lumen-drawer.js';
|
|
41
|
+
export { type DrawerAction, LumenDrawer, type LumenDrawerProps } from './lumen-drawer.js';
|
|
42
42
|
export { LumenCode, type LumenCodeProps, langOfPath } from './lumen-code.js';
|
|
43
43
|
export { LumenCodeEditor, type LumenCodeEditorProps, type LumenCodeLang, } from './lumen-code-editor.js';
|
|
44
44
|
export { RenameField, type RenameFieldProps } from './rename-field.js';
|
package/dist/lumen-drawer.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
+
import { type IconButtonProps } from './icon-button.js';
|
|
3
|
+
/**
|
|
4
|
+
* One of a drawer's actions, as data: the drawer draws it as an icon button with its name in the
|
|
5
|
+
* tooltip, so a drawer's actions are never text. Destructive ones go first, as the footer lists them.
|
|
6
|
+
*/
|
|
7
|
+
export type DrawerAction = Pick<IconButtonProps, 'icon' | 'label' | 'onClick' | 'busy' | 'disabled' | 'pressed' | 'to' | 'href'> & {
|
|
8
|
+
/** Delete, remove: drawn in the destructive colour. */
|
|
9
|
+
destructive?: boolean;
|
|
10
|
+
};
|
|
2
11
|
/** A drawer's width on desktop, as the resizable panel takes it ("32%", "320px"). */
|
|
3
12
|
type Size = `${number}%` | `${number}px`;
|
|
4
13
|
export interface LumenDrawerProps {
|
|
@@ -9,7 +18,9 @@ export interface LumenDrawerProps {
|
|
|
9
18
|
description?: ReactNode;
|
|
10
19
|
/** Stacked DrawerSections; the drawer pads and scrolls them. */
|
|
11
20
|
children: ReactNode;
|
|
12
|
-
/** The footer's actions, right-aligned
|
|
21
|
+
/** The footer's actions as data, right-aligned in order, before `footer`: always icons. */
|
|
22
|
+
actions?: readonly DrawerAction[];
|
|
23
|
+
/** Last in the footer, after `actions`: the `SaveButton`. No footer when this, `actions` and `footerStart` are left out. */
|
|
13
24
|
footer?: ReactNode;
|
|
14
25
|
/** Left side of the footer: a count or status line ("12 releases"). */
|
|
15
26
|
footerStart?: ReactNode;
|
|
@@ -34,5 +45,5 @@ export interface LumenDrawerProps {
|
|
|
34
45
|
* phone it shows only when there are actions, as the sheet's X closes it). With `dock` it sits beside
|
|
35
46
|
* the page on desktop instead (DockedDrawer), for a list whose rows each open it.
|
|
36
47
|
*/
|
|
37
|
-
export declare function LumenDrawer({ open, onClose, title, description, children, footer, footerStart, defaultSize, minSize, maxSize, dock, }: LumenDrawerProps): import("react").JSX.Element | null;
|
|
48
|
+
export declare function LumenDrawer({ open, onClose, title, description, children, actions, footer, footerStart, defaultSize, minSize, maxSize, dock, }: LumenDrawerProps): import("react").JSX.Element | null;
|
|
38
49
|
export {};
|
package/dist/lumen-drawer.js
CHANGED
|
@@ -21,7 +21,7 @@ const DrawerPanels = lazyPart(() => loadPanels().then((m) => m.DrawerPanels));
|
|
|
21
21
|
* phone it shows only when there are actions, as the sheet's X closes it). With `dock` it sits beside
|
|
22
22
|
* the page on desktop instead (DockedDrawer), for a list whose rows each open it.
|
|
23
23
|
*/
|
|
24
|
-
export function LumenDrawer({ open, onClose, title, description, children, footer, footerStart, defaultSize = '32%', minSize = '320px', maxSize = '60%', dock, }) {
|
|
24
|
+
export function LumenDrawer({ open, onClose, title, description, children, actions, footer, footerStart, defaultSize = '32%', minSize = '320px', maxSize = '60%', dock, }) {
|
|
25
25
|
const isMobile = useIsMobile();
|
|
26
26
|
const slot = useDockSlot();
|
|
27
27
|
// Fetched once the page is idle, so the first drawer opened on a desktop has its panels ready.
|
|
@@ -35,7 +35,8 @@ export function LumenDrawer({ open, onClose, title, description, children, foote
|
|
|
35
35
|
const body = _jsx("div", { className: "flex flex-col px-4 pb-4", children: children });
|
|
36
36
|
// A drawer with actions ends on a footer, styled like a dialog's: the body scrolls above it and
|
|
37
37
|
// ends on a clear edge. Without actions it has none: the header's × already closes it.
|
|
38
|
-
const
|
|
38
|
+
const acts = actions?.length ? actions : null;
|
|
39
|
+
const foot = (acts || footer || footerStart) && (_jsxs("footer", { "data-slot": "drawer-footer", className: "flex shrink-0 items-center gap-2 border-t bg-muted/50 px-4 py-2.5", children: [footerStart && (_jsx("div", { className: "min-w-0 flex-1 truncate text-muted-foreground text-xs", children: footerStart })), _jsxs("div", { className: "ml-auto flex items-center gap-2", children: [acts?.map(({ destructive, ...a }) => (_jsx(IconButton, { ...a, className: destructive ? 'text-destructive hover:text-destructive' : undefined }, a.label))), footer] })] }));
|
|
39
40
|
if (dock && !isMobile && slot)
|
|
40
41
|
return open
|
|
41
42
|
? createPortal(_jsx(DockedDrawer, { dock: dock, title: title, description: description, onClose: onClose, defaultSize: defaultSize, minSize: minSize, maxSize: maxSize, body: body, foot: foot }), slot)
|
package/dist/lumen-form.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ export interface LumenFormField {
|
|
|
9
9
|
/** `text` by default. `secret` hides what is typed; `select` and `multi` are LumenSelector. */
|
|
10
10
|
kind?: 'text' | 'secret' | 'number' | 'date' | 'textarea' | 'select' | 'multi';
|
|
11
11
|
required?: boolean;
|
|
12
|
-
/**
|
|
12
|
+
/** More about the field, behind an (i) beside its label (`InfoTip`). Most fields need none. */
|
|
13
|
+
info?: ReactNode;
|
|
14
|
+
/** @deprecated Use `info`: drawn the same way, as an (i) beside the label, never a line under the field. */
|
|
13
15
|
hint?: ReactNode;
|
|
14
16
|
placeholder?: string;
|
|
15
17
|
/** `select` and `multi`. */
|
package/dist/lumen-form.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// LumenForm:
|
|
3
|
-
// a list of fields in, a laid-out form out. Label,
|
|
3
|
+
// a list of fields in, a laid-out form out. Label, (i), input and error sit the same way in every
|
|
4
4
|
// app; each field's own check runs as the person types, and Save is LumenShell's SaveButton, which
|
|
5
5
|
// lists what stands in the way and takes the person to it. A secret already saved shows masked and
|
|
6
6
|
// is kept while its box stays empty. LumenForm only puts the kit's parts together.
|
|
7
|
+
import { XIcon } from 'lucide-react';
|
|
7
8
|
import { useId, useState } from 'react';
|
|
8
9
|
import { SaveButton } from './form-issues.js';
|
|
10
|
+
import { IconButton } from './icon-button.js';
|
|
11
|
+
import { InfoTip } from './info-tip.js';
|
|
9
12
|
import { LumenSelector } from './lumen-selector.js';
|
|
10
|
-
import {
|
|
11
|
-
import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from './ui/field.js';
|
|
13
|
+
import { Field, FieldError, FieldGroup, FieldLabel } from './ui/field.js';
|
|
12
14
|
import { Input } from './ui/input.js';
|
|
13
15
|
import { Textarea } from './ui/textarea.js';
|
|
14
16
|
const isEmpty = (v) => v === undefined || (Array.isArray(v) ? v.length === 0 : v.trim() === '');
|
|
@@ -76,6 +78,6 @@ export function LumenForm({ fields, initial, onSave, onCancel, saveLabel = 'Save
|
|
|
76
78
|
save();
|
|
77
79
|
}, children: [_jsx(FieldGroup, { children: fields.map((f) => {
|
|
78
80
|
const invalid = touched.has(f.id) && !!errors[f.id];
|
|
79
|
-
return (_jsxs(Field, { "data-invalid": invalid || undefined, children: [_jsxs(FieldLabel, { htmlFor: domId(f.id), children: [f.label, f.required && _jsx("span", { className: "font-normal text-muted-foreground", children: "required" })
|
|
80
|
-
}) }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t pt-3", children: [footer, _jsx("div", { className: "flex-1" }), onCancel &&
|
|
81
|
+
return (_jsxs(Field, { "data-invalid": invalid || undefined, children: [_jsxs(FieldLabel, { htmlFor: domId(f.id), children: [f.label, f.required && _jsx("span", { className: "font-normal text-muted-foreground", children: "required" }), (f.info ?? f.hint) && (_jsx(InfoTip, { label: `About ${f.label}`, children: f.info ?? f.hint }))] }), input(f), invalid && _jsx(FieldError, { children: errors[f.id] })] }, f.id));
|
|
82
|
+
}) }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t pt-3", children: [footer, _jsx("div", { className: "flex-1" }), onCancel && _jsx(IconButton, { type: "button", icon: XIcon, label: "Cancel", onClick: onCancel }), _jsx("span", { className: "contents", onClickCapture: touchAll, children: _jsx(SaveButton, { issues: issues, busy: busy, label: saveLabel, onSave: save }) })] })] }));
|
|
81
83
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@columenlabs/lumen-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.155",
|
|
4
4
|
"description": "Lumen: shared React components (frame, views, widgets, charts, drawers).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@codemirror/lang-javascript": "6.2.5",
|
|
50
50
|
"@codemirror/lang-json": "6.0.2",
|
|
51
51
|
"@codemirror/lang-sql": "6.10.0",
|
|
52
|
-
"@columenlabs/lumen-ui-types": "0.1.
|
|
52
|
+
"@columenlabs/lumen-ui-types": "0.1.155",
|
|
53
53
|
"@dnd-kit/core": "6.3.1",
|
|
54
54
|
"@dnd-kit/sortable": "10.0.0",
|
|
55
55
|
"@dnd-kit/utilities": "3.2.2",
|