pendentive 0.1.1
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/LICENSE +13 -0
- package/README.md +88 -0
- package/dist/components/avatar/Avatar.d.ts +26 -0
- package/dist/components/badge/Badge.d.ts +25 -0
- package/dist/components/button/Button.d.ts +51 -0
- package/dist/components/button/ButtonGroup.d.ts +36 -0
- package/dist/components/checkbox/Checkbox.d.ts +34 -0
- package/dist/components/command/Command.d.ts +59 -0
- package/dist/components/data/List.d.ts +40 -0
- package/dist/components/data/Table.d.ts +37 -0
- package/dist/components/data/Tree.d.ts +36 -0
- package/dist/components/feedback/Alert.d.ts +29 -0
- package/dist/components/feedback/ProgressBar.d.ts +32 -0
- package/dist/components/feedback/Skeleton.d.ts +20 -0
- package/dist/components/feedback/Spinner.d.ts +20 -0
- package/dist/components/feedback/Toast.d.ts +30 -0
- package/dist/components/field/ColorField.d.ts +33 -0
- package/dist/components/field/NumberField.d.ts +42 -0
- package/dist/components/field/TextArea.d.ts +35 -0
- package/dist/components/field/TextField.d.ts +39 -0
- package/dist/components/field/shared.d.ts +9 -0
- package/dist/components/field/textInput.css.d.ts +5 -0
- package/dist/components/hovercard/HoverCard.d.ts +35 -0
- package/dist/components/input/ChipInput.d.ts +31 -0
- package/dist/components/input/DatePicker.d.ts +66 -0
- package/dist/components/input/FileDropzone.d.ts +26 -0
- package/dist/components/layout/Card.d.ts +24 -0
- package/dist/components/layout/Section.d.ts +33 -0
- package/dist/components/layout/Separator.d.ts +18 -0
- package/dist/components/misc/ModeCard.d.ts +35 -0
- package/dist/components/navigation/Accordion.d.ts +42 -0
- package/dist/components/navigation/Breadcrumb.d.ts +25 -0
- package/dist/components/navigation/Pagination.d.ts +30 -0
- package/dist/components/navigation/Tabs.d.ts +38 -0
- package/dist/components/overlay/AlertDialog.d.ts +37 -0
- package/dist/components/overlay/ContextMenu.d.ts +19 -0
- package/dist/components/overlay/Dialog.d.ts +38 -0
- package/dist/components/overlay/Drawer.d.ts +40 -0
- package/dist/components/overlay/DropdownMenu.d.ts +55 -0
- package/dist/components/overlay/Popover.d.ts +33 -0
- package/dist/components/radio/RadioGroup.d.ts +37 -0
- package/dist/components/select/Combobox.d.ts +42 -0
- package/dist/components/select/Select.d.ts +48 -0
- package/dist/components/slider/RangeSlider.d.ts +43 -0
- package/dist/components/slider/Slider.d.ts +41 -0
- package/dist/components/switch/Switch.d.ts +35 -0
- package/dist/components/toggle/Toggle.d.ts +39 -0
- package/dist/components/toggle/ToggleGroup.d.ts +47 -0
- package/dist/components/tooltip/Tooltip.d.ts +22 -0
- package/dist/core/classNames.d.ts +6 -0
- package/dist/core/content.d.ts +2 -0
- package/dist/core/controller.d.ts +34 -0
- package/dist/core/dom.d.ts +14 -0
- package/dist/core/overlay.d.ts +14 -0
- package/dist/core/styleInjector.d.ts +12 -0
- package/dist/core/theme.d.ts +18 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/index.cjs +4054 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +3934 -0
- package/dist/index.js.map +1 -0
- package/dist/linteau.global.js +397 -0
- package/dist/linteau.global.js.map +7 -0
- package/dist/styles/tokens.d.ts +33 -0
- package/dist/svg/Icon.d.ts +19 -0
- package/dist/svg/create-icon.d.ts +13 -0
- package/dist/svg/icons/alertTriangle.d.ts +1 -0
- package/dist/svg/icons/bell.d.ts +1 -0
- package/dist/svg/icons/calendar.d.ts +1 -0
- package/dist/svg/icons/check.d.ts +1 -0
- package/dist/svg/icons/chevronDown.d.ts +1 -0
- package/dist/svg/icons/chevronLeft.d.ts +1 -0
- package/dist/svg/icons/chevronRight.d.ts +1 -0
- package/dist/svg/icons/chevronUp.d.ts +1 -0
- package/dist/svg/icons/circle.d.ts +1 -0
- package/dist/svg/icons/copy.d.ts +1 -0
- package/dist/svg/icons/download.d.ts +1 -0
- package/dist/svg/icons/edit.d.ts +1 -0
- package/dist/svg/icons/externalLink.d.ts +1 -0
- package/dist/svg/icons/eye.d.ts +1 -0
- package/dist/svg/icons/eyeOff.d.ts +1 -0
- package/dist/svg/icons/filter.d.ts +1 -0
- package/dist/svg/icons/heart.d.ts +1 -0
- package/dist/svg/icons/home.d.ts +1 -0
- package/dist/svg/icons/index.d.ts +54 -0
- package/dist/svg/icons/info.d.ts +1 -0
- package/dist/svg/icons/link.d.ts +1 -0
- package/dist/svg/icons/loader.d.ts +1 -0
- package/dist/svg/icons/lock.d.ts +1 -0
- package/dist/svg/icons/mail.d.ts +1 -0
- package/dist/svg/icons/menu.d.ts +1 -0
- package/dist/svg/icons/minus.d.ts +1 -0
- package/dist/svg/icons/moon.d.ts +1 -0
- package/dist/svg/icons/moreHorizontal.d.ts +1 -0
- package/dist/svg/icons/phone.d.ts +1 -0
- package/dist/svg/icons/plus.d.ts +1 -0
- package/dist/svg/icons/refreshCw.d.ts +1 -0
- package/dist/svg/icons/search.d.ts +1 -0
- package/dist/svg/icons/settings.d.ts +1 -0
- package/dist/svg/icons/star.d.ts +1 -0
- package/dist/svg/icons/sun.d.ts +1 -0
- package/dist/svg/icons/trash.d.ts +1 -0
- package/dist/svg/icons/upload.d.ts +1 -0
- package/dist/svg/icons/user.d.ts +1 -0
- package/dist/svg/icons/x.d.ts +1 -0
- package/dist/svg/index.cjs +380 -0
- package/dist/svg/index.cjs.map +1 -0
- package/dist/svg/index.d.ts +4 -0
- package/dist/svg/index.js +352 -0
- package/dist/svg/index.js.map +1 -0
- package/dist/svg/types.d.ts +26 -0
- package/package.json +81 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
2
|
+
Version 2, December 2004
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 Nolly
|
|
5
|
+
|
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
|
7
|
+
copies of this license document, and changing it is allowed as long
|
|
8
|
+
as the name is changed.
|
|
9
|
+
|
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
12
|
+
|
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Pendentive
|
|
2
|
+
|
|
3
|
+
A self-sufficient UI component library with **zero dependencies**, no Tailwind, no CSS framework, and no build step required by consumers. Every component is a real, fully-typed DOM element with attached controller methods -- append it, control it, destroy it.
|
|
4
|
+
|
|
5
|
+
Works in:
|
|
6
|
+
- The browser, via a single `<script>` tag (`dist/pendentive.global.js`, global `window.Pendentive`)
|
|
7
|
+
- Node.js and Bun, as an ESM/CJS package (`import { Button } from 'pendentive'`)
|
|
8
|
+
- TypeScript and plain JavaScript, with full `.d.ts` types shipped
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install pendentive
|
|
14
|
+
# or
|
|
15
|
+
bun add pendentive
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Browser (no build step)
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<script src="./pendentive.global.js"></script>
|
|
22
|
+
<script>
|
|
23
|
+
const button = Pendentive.Button('Save', { variant: 'default' })
|
|
24
|
+
document.body.append(button)
|
|
25
|
+
</script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Node / Bun / bundlers
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { Button, Section, setTheme } from 'pendentive'
|
|
32
|
+
|
|
33
|
+
const button = Button('Save', {
|
|
34
|
+
variant: 'default',
|
|
35
|
+
onClick: () => console.log('saved')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
document.body.append(button)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
| Category | Components |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Buttons | Button, ButtonGroup |
|
|
46
|
+
| Layout | Section, Card, Separator |
|
|
47
|
+
| Form fields | TextField, TextArea, NumberField, ColorField |
|
|
48
|
+
| Selection controls | Checkbox, RadioGroup, Switch, Slider, RangeSlider, Select, Combobox |
|
|
49
|
+
| Specialized inputs | ChipInput, FileDropzone, DatePicker |
|
|
50
|
+
| Display | Badge, Avatar, ModeCard |
|
|
51
|
+
| Feedback | Spinner, ProgressBar, Skeleton, Toast, Alert |
|
|
52
|
+
| Overlays | Tooltip, Dialog, Drawer, Popover, DropdownMenu, ContextMenu |
|
|
53
|
+
| Navigation | Tabs, Accordion, Breadcrumb, Pagination |
|
|
54
|
+
| Data display | Table, List, Tree |
|
|
55
|
+
|
|
56
|
+
Every component ships its own CSS alongside its code -- import only what you use, and only that component's styles are ever injected.
|
|
57
|
+
|
|
58
|
+
## Styling
|
|
59
|
+
|
|
60
|
+
CSS is injected automatically at runtime -- nothing to import or link. Customize the whole design system through CSS custom properties (all prefixed `--pendentive-*` so they never collide with your own variables) or the `setTheme()` API:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { setTheme } from 'pendentive'
|
|
64
|
+
|
|
65
|
+
setTheme({ primary: 'oklch(0.7 0.2 250)', radius: '0.25rem' })
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Icons
|
|
69
|
+
|
|
70
|
+
Pendentive ships a built-in set of lucide-compatible icons, each a standalone, tree-shakeable component. Every `icon` prop across the library accepts any of: one of Pendentive's built-ins, a lucide-style icon-node array, raw SVG markup, an existing `SVGSVGElement`, a render function, or nothing at all.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { Icon, icons } from 'pendentive/svg'
|
|
74
|
+
|
|
75
|
+
const check = Icon(icons.check, 16)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Mix in your own icons (from a lucide clone or hand-rolled) freely -- they're fully interchangeable:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { icons } from 'pendentive/svg'
|
|
82
|
+
|
|
83
|
+
const allIcons = { ...icons, ...myLucideCloneIcons }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
WTFPL -- do what the fuck you want to.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Options accepted by the `Avatar` factory. */
|
|
2
|
+
export interface AvatarOptions {
|
|
3
|
+
/** Image URL. Falls back to `initials` if omitted or if the image fails to load. */
|
|
4
|
+
src?: string;
|
|
5
|
+
/** Accessible alt text for the image. */
|
|
6
|
+
alt?: string;
|
|
7
|
+
/** Fallback text (typically 1-2 letters) shown when there's no image. */
|
|
8
|
+
initials?: string;
|
|
9
|
+
/** Pixel diameter/side length. Defaults to `36`. */
|
|
10
|
+
size?: number;
|
|
11
|
+
/** Outline shape. Defaults to `'circle'`. */
|
|
12
|
+
shape?: 'circle' | 'square';
|
|
13
|
+
}
|
|
14
|
+
/** The runtime control surface attached to every `Avatar` element. */
|
|
15
|
+
export interface AvatarApi {
|
|
16
|
+
/** Replaces the image source, or falls back to initials if `undefined`. */
|
|
17
|
+
setSrc: (src: string | undefined) => void;
|
|
18
|
+
/** Detaches the avatar from the DOM. */
|
|
19
|
+
destroy: () => void;
|
|
20
|
+
}
|
|
21
|
+
/** An `Avatar` is a real `HTMLDivElement` extended with `AvatarApi`. */
|
|
22
|
+
export type AvatarElement = HTMLDivElement & AvatarApi;
|
|
23
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
24
|
+
export declare const avatarCss = "\n.linteau-avatar { display: inline-flex; align-items: center; justify-content: center; background: var(--linteau-secondary); color: var(--linteau-secondary-foreground); font-size: 12px; font-weight: 600; overflow: hidden; flex-shrink: 0 }\n.linteau-avatar-circle { border-radius: 50% }\n.linteau-avatar-square { border-radius: var(--linteau-radius-sm) }\n.linteau-avatar img { width: 100%; height: 100%; object-fit: cover }\n";
|
|
25
|
+
/** Creates a circular or square avatar with an automatic initials fallback. */
|
|
26
|
+
export declare function Avatar(options?: AvatarOptions): AvatarElement;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** Visual style of a `Badge`. */
|
|
3
|
+
export type BadgeVariant = 'default' | 'outline' | 'success' | 'warning' | 'destructive';
|
|
4
|
+
/** Options accepted by the `Badge` factory. */
|
|
5
|
+
export interface BadgeOptions {
|
|
6
|
+
/** Visual style. Defaults to `'default'`. */
|
|
7
|
+
variant?: BadgeVariant;
|
|
8
|
+
/** Optional icon rendered before the label. */
|
|
9
|
+
icon?: IconInput;
|
|
10
|
+
}
|
|
11
|
+
/** The runtime control surface attached to every `Badge` element. */
|
|
12
|
+
export interface BadgeApi {
|
|
13
|
+
/** Updates the visible label text. */
|
|
14
|
+
setLabel: (text: string) => void;
|
|
15
|
+
/** Swaps the visual variant, updating classes in place. */
|
|
16
|
+
setVariant: (variant: BadgeVariant) => void;
|
|
17
|
+
/** Detaches the badge from the DOM. */
|
|
18
|
+
destroy: () => void;
|
|
19
|
+
}
|
|
20
|
+
/** A `Badge` is a real `HTMLSpanElement` extended with `BadgeApi`. */
|
|
21
|
+
export type BadgeElement = HTMLSpanElement & BadgeApi;
|
|
22
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
23
|
+
export declare const badgeCss = "\n.linteau-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n line-height: 1.6;\n border: 1px solid transparent;\n}\n.linteau-badge-default { background: var(--linteau-secondary); color: var(--linteau-secondary-foreground) }\n.linteau-badge-outline { background: transparent; border-color: var(--linteau-border); color: var(--linteau-foreground) }\n.linteau-badge-success { background: var(--linteau-success); color: var(--linteau-success-foreground) }\n.linteau-badge-warning { background: var(--linteau-warning); color: var(--linteau-warning-foreground) }\n.linteau-badge-destructive { background: var(--linteau-destructive); color: var(--linteau-destructive-foreground) }\n";
|
|
24
|
+
/** Creates a small pill-shaped status/label indicator. */
|
|
25
|
+
export declare function Badge(text: string, options?: BadgeOptions): BadgeElement;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** Visual style of a `Button`. */
|
|
3
|
+
export type ButtonVariant = 'default' | 'outline' | 'ghost' | 'destructive';
|
|
4
|
+
/** Sizing preset of a `Button`. */
|
|
5
|
+
export type ButtonSize = 'sm' | 'default';
|
|
6
|
+
/** Options accepted by the `Button` factory. */
|
|
7
|
+
export interface ButtonOptions {
|
|
8
|
+
/** Visual style. Defaults to `'default'`. */
|
|
9
|
+
variant?: ButtonVariant;
|
|
10
|
+
/** Sizing preset. Defaults to `'default'`. */
|
|
11
|
+
size?: ButtonSize;
|
|
12
|
+
/** Optional icon, in any `IconInput` shape. */
|
|
13
|
+
icon?: IconInput;
|
|
14
|
+
/** Which side of the label the icon renders on. Defaults to `'start'`. */
|
|
15
|
+
iconPosition?: 'start' | 'end';
|
|
16
|
+
/** Disables the button and blocks click handling. Defaults to `false`. */
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
/** Stretches the button to 100% of its container's width. Defaults to `false`. */
|
|
19
|
+
fullWidth?: boolean;
|
|
20
|
+
/** Called on every click while the button is enabled. */
|
|
21
|
+
onClick?: (event: MouseEvent) => void;
|
|
22
|
+
}
|
|
23
|
+
/** The full runtime control surface attached to every `Button` element. */
|
|
24
|
+
export interface ButtonApi {
|
|
25
|
+
/** Updates the visible label text. */
|
|
26
|
+
setLabel: (text: string) => void;
|
|
27
|
+
/** Swaps the visual variant, updating classes in place. */
|
|
28
|
+
setVariant: (variant: ButtonVariant) => void;
|
|
29
|
+
/** Swaps the sizing preset, updating classes in place. */
|
|
30
|
+
setSize: (size: ButtonSize) => void;
|
|
31
|
+
/** Replaces the icon (or removes it if `icon` is `null`/`undefined`), optionally moving its position. */
|
|
32
|
+
setIcon: (icon: IconInput, position?: 'start' | 'end') => void;
|
|
33
|
+
/** Enables/disables the button. */
|
|
34
|
+
setDisabled: (disabled: boolean) => void;
|
|
35
|
+
/** Replaces the click handler (pass `undefined` to remove it). */
|
|
36
|
+
setOnClick: (handler: ((event: MouseEvent) => void) | undefined) => void;
|
|
37
|
+
/** Removes the click listener and detaches the button from the DOM. */
|
|
38
|
+
destroy: () => void;
|
|
39
|
+
}
|
|
40
|
+
/** A `Button` is a real `HTMLButtonElement` extended with `ButtonApi`. */
|
|
41
|
+
export type ButtonElement = HTMLButtonElement & ButtonApi;
|
|
42
|
+
/** This component's own CSS -- colocated so `Button.ts` is a single, self-contained, tree-shakeable unit. */
|
|
43
|
+
export declare const buttonCss = "\n.linteau-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n border-radius: var(--linteau-radius-sm);\n border: 1px solid transparent;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: background 120ms ease, border-color 120ms ease, transform 120ms ease, opacity 120ms ease;\n}\n.linteau-button-default { padding: 10px 14px }\n.linteau-button-sm { padding: 6px 10px; font-size: 12px }\n.linteau-button-full { width: 100% }\n.linteau-button:active { transform: scale(0.97) }\n.linteau-button:disabled { opacity: 0.5; cursor: not-allowed; transform: none }\n.linteau-button-default:not(.linteau-button-outline):not(.linteau-button-ghost):not(.linteau-button-destructive) {\n background: var(--linteau-primary);\n color: var(--linteau-primary-foreground);\n}\n.linteau-button-default:not(.linteau-button-outline):not(.linteau-button-ghost):not(.linteau-button-destructive):hover:not(:disabled) {\n filter: brightness(0.92);\n}\n.linteau-button-outline { background: transparent; border-color: var(--linteau-border); color: var(--linteau-foreground) }\n.linteau-button-outline:hover:not(:disabled) { background: var(--linteau-accent) }\n.linteau-button-ghost { background: transparent; color: var(--linteau-muted-foreground) }\n.linteau-button-ghost:hover:not(:disabled) { background: var(--linteau-accent); color: var(--linteau-foreground) }\n.linteau-button-destructive { background: var(--linteau-destructive); color: var(--linteau-destructive-foreground) }\n.linteau-button-destructive:hover:not(:disabled) { filter: brightness(0.92) }\n";
|
|
44
|
+
/**
|
|
45
|
+
* Creates a fully controllable, self-styled button.
|
|
46
|
+
*
|
|
47
|
+
* @param text - Initial label text.
|
|
48
|
+
* @param options - Configuration; every field is optional and can change later via the returned API.
|
|
49
|
+
* @returns The button element itself, extended with `ButtonApi` methods.
|
|
50
|
+
*/
|
|
51
|
+
export declare function Button(text: string, options?: ButtonOptions): ButtonElement;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** A single selectable item within a `ButtonGroup`. */
|
|
3
|
+
export interface ButtonGroupItem {
|
|
4
|
+
/** Visible label. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Unique value identifying this item. */
|
|
7
|
+
value: string;
|
|
8
|
+
/** Optional icon shown before the label. */
|
|
9
|
+
icon?: IconInput;
|
|
10
|
+
}
|
|
11
|
+
/** Options accepted by the `ButtonGroup` factory. */
|
|
12
|
+
export interface ButtonGroupOptions {
|
|
13
|
+
/** The items rendered as segments. */
|
|
14
|
+
items: ButtonGroupItem[];
|
|
15
|
+
/** Initially selected value (controlled if you keep calling `setValue`, uncontrolled otherwise). */
|
|
16
|
+
value?: string;
|
|
17
|
+
/** Called whenever the selection changes via user interaction. */
|
|
18
|
+
onChange?: (value: string) => void;
|
|
19
|
+
}
|
|
20
|
+
/** The runtime control surface attached to every `ButtonGroup` element. */
|
|
21
|
+
export interface ButtonGroupApi {
|
|
22
|
+
/** Returns the currently selected value, if any. */
|
|
23
|
+
getValue: () => string | undefined;
|
|
24
|
+
/** Programmatically selects a value (does not trigger `onChange`). */
|
|
25
|
+
setValue: (value: string) => void;
|
|
26
|
+
/** Replaces the full list of items, preserving selection where possible. */
|
|
27
|
+
setItems: (items: ButtonGroupItem[]) => void;
|
|
28
|
+
/** Detaches the group from the DOM and its internal listeners. */
|
|
29
|
+
destroy: () => void;
|
|
30
|
+
}
|
|
31
|
+
/** A `ButtonGroup` is a real `HTMLDivElement` extended with `ButtonGroupApi`. */
|
|
32
|
+
export type ButtonGroupElement = HTMLDivElement & ButtonGroupApi;
|
|
33
|
+
/** This component's own CSS. Depends on `.linteau-button`, which `Button()` registers itself the moment `ButtonGroup` renders its first segment. */
|
|
34
|
+
export declare const buttonGroupCss = "\n.linteau-button-group { display: inline-flex; border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-sm); overflow: hidden }\n.linteau-button-group .linteau-button { border-radius: 0; border: none; border-right: 1px solid var(--linteau-border); background: transparent; color: var(--linteau-muted-foreground) }\n.linteau-button-group .linteau-button:last-child { border-right: none }\n.linteau-button-group .linteau-button:hover:not(:disabled) { background: var(--linteau-accent) }\n.linteau-button-group .linteau-button-group-item-active { background: var(--linteau-primary); color: var(--linteau-primary-foreground) }\n";
|
|
35
|
+
/** Creates a segmented, single-select group of buttons -- useful for compact mode/tab-like pickers that don't need a full `Select`. */
|
|
36
|
+
export declare function ButtonGroup(options: ButtonGroupOptions): ButtonGroupElement;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Options accepted by the `Checkbox` factory. */
|
|
2
|
+
export interface CheckboxOptions {
|
|
3
|
+
/** Label rendered next to the box. */
|
|
4
|
+
label: string;
|
|
5
|
+
/** Controlled checked state. */
|
|
6
|
+
checked?: boolean;
|
|
7
|
+
/** Uncontrolled initial state, used only if `checked` is omitted. Defaults to `false`. */
|
|
8
|
+
defaultChecked?: boolean;
|
|
9
|
+
/** Renders a dash instead of a check mark, without affecting the boolean value. Defaults to `false`. */
|
|
10
|
+
indeterminate?: boolean;
|
|
11
|
+
/** Disables interaction. Defaults to `false`. */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Called whenever the user toggles the checkbox. */
|
|
14
|
+
onChange?: (checked: boolean) => void;
|
|
15
|
+
}
|
|
16
|
+
/** The runtime control surface attached to every `Checkbox` element. */
|
|
17
|
+
export interface CheckboxApi {
|
|
18
|
+
/** Returns the current checked state. */
|
|
19
|
+
getValue: () => boolean;
|
|
20
|
+
/** Programmatically sets the checked state (does not trigger `onChange`). */
|
|
21
|
+
setValue: (checked: boolean) => void;
|
|
22
|
+
/** Toggles the indeterminate visual state. */
|
|
23
|
+
setIndeterminate: (indeterminate: boolean) => void;
|
|
24
|
+
/** Enables/disables the checkbox. */
|
|
25
|
+
setDisabled: (disabled: boolean) => void;
|
|
26
|
+
/** Detaches the checkbox from the DOM and its internal listener. */
|
|
27
|
+
destroy: () => void;
|
|
28
|
+
}
|
|
29
|
+
/** A `Checkbox` is a real `HTMLDivElement` (the row) extended with `CheckboxApi`. */
|
|
30
|
+
export type CheckboxElement = HTMLDivElement & CheckboxApi;
|
|
31
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
32
|
+
export declare const checkboxCss = "\n.linteau-checkbox-row { display: flex; align-items: center; gap: 8px }\n.linteau-checkbox {\n width: 18px;\n height: 18px;\n border-radius: var(--linteau-radius-sm);\n border: 1px solid var(--linteau-border);\n background: var(--linteau-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--linteau-primary-foreground);\n}\n.linteau-checkbox:disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-checkbox.linteau-checked { background: var(--linteau-primary); border-color: var(--linteau-primary) }\n.linteau-checkbox svg { display: none }\n.linteau-checkbox.linteau-checked svg, .linteau-checkbox.linteau-indeterminate svg { display: block }\n";
|
|
33
|
+
/** Creates a labeled checkbox, supporting controlled/uncontrolled and indeterminate states. */
|
|
34
|
+
export declare function Checkbox(options: CheckboxOptions): CheckboxElement;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** A single selectable entry in a `Command` palette. */
|
|
3
|
+
export interface CommandItem {
|
|
4
|
+
/** Visible label. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Value passed to `onSelect` when this item is chosen. */
|
|
7
|
+
value: string;
|
|
8
|
+
/** Optional icon rendered before the label. */
|
|
9
|
+
icon?: IconInput;
|
|
10
|
+
/** Extra terms matched against the search query, alongside `label`. */
|
|
11
|
+
keywords?: string[];
|
|
12
|
+
/** Disables this item. Defaults to `false`. */
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** A labeled cluster of `CommandItem`s within the palette. */
|
|
16
|
+
export interface CommandGroup {
|
|
17
|
+
/** Optional heading shown above this group's items. */
|
|
18
|
+
heading?: string;
|
|
19
|
+
/** The items in this group. */
|
|
20
|
+
items: CommandItem[];
|
|
21
|
+
}
|
|
22
|
+
/** Options accepted by the `Command` factory. */
|
|
23
|
+
export interface CommandOptions {
|
|
24
|
+
/** The groups of selectable items. */
|
|
25
|
+
groups?: CommandGroup[];
|
|
26
|
+
/** Placeholder shown in the search input. Defaults to `'Type a command or search...'`. */
|
|
27
|
+
placeholder?: string;
|
|
28
|
+
/** Text shown when no items match the query. Defaults to `'No results found.'`. */
|
|
29
|
+
emptyText?: string;
|
|
30
|
+
/** Closes the palette after a selection is made. Defaults to `true`. */
|
|
31
|
+
closeOnSelect?: boolean;
|
|
32
|
+
/** Called when an enabled item is chosen. */
|
|
33
|
+
onSelect?: (value: string) => void;
|
|
34
|
+
}
|
|
35
|
+
/** The runtime control surface attached to every `Command` element. */
|
|
36
|
+
export interface CommandApi {
|
|
37
|
+
/** Opens the palette, locks scroll, and focuses the search input. */
|
|
38
|
+
open: () => void;
|
|
39
|
+
/** Closes the palette. */
|
|
40
|
+
close: () => void;
|
|
41
|
+
/** Toggles between open and closed. */
|
|
42
|
+
toggle: () => void;
|
|
43
|
+
/** Returns whether the palette is currently open. */
|
|
44
|
+
isOpen: () => boolean;
|
|
45
|
+
/** Replaces the full list of groups. */
|
|
46
|
+
setGroups: (groups: CommandGroup[]) => void;
|
|
47
|
+
/** Removes all listeners and detaches the palette from the DOM. */
|
|
48
|
+
destroy: () => void;
|
|
49
|
+
}
|
|
50
|
+
/** A `Command` is a real `HTMLDivElement` (the overlay) extended with `CommandApi`. */
|
|
51
|
+
export type CommandElement = HTMLDivElement & CommandApi;
|
|
52
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
53
|
+
export declare const commandCss = "\n.linteau-command-overlay { position: fixed; inset: 0; background: color-mix(in oklch, black 60%, transparent); display: flex; align-items: flex-start; justify-content: center; padding-top: 15vh; z-index: 1500; backdrop-filter: blur(4px) }\n.linteau-command-panel { width: min(560px, 92vw); max-height: 60vh; display: flex; flex-direction: column; background: var(--linteau-card); border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-lg); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); overflow: hidden }\n.linteau-command-input-wrap { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--linteau-border) }\n.linteau-command-input { flex: 1; background: transparent; border: none; outline: none; color: var(--linteau-foreground); font-size: 14px; font-family: inherit }\n.linteau-command-list { overflow-y: auto; padding: 6px; flex: 1 }\n.linteau-command-group-heading { padding: 6px 8px 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--linteau-muted-foreground) }\n.linteau-command-item { display: flex; align-items: center; gap: 8px; padding: 8px; border-radius: var(--linteau-radius-sm); font-size: 13px; color: var(--linteau-foreground); cursor: pointer }\n.linteau-command-item-highlighted { background: var(--linteau-accent) }\n.linteau-command-item-disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-command-empty { padding: 24px; text-align: center; font-size: 12px; color: var(--linteau-muted-foreground) }\n";
|
|
54
|
+
/**
|
|
55
|
+
* Creates a full-screen command palette: a search input backed by a live-filtered,
|
|
56
|
+
* grouped, keyboard-navigable list -- opened on demand (bind it to a keyboard shortcut
|
|
57
|
+
* like Cmd/Ctrl+K in your app).
|
|
58
|
+
*/
|
|
59
|
+
export declare function Command(options?: CommandOptions): CommandElement;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** A single row rendered inside a `List`. */
|
|
3
|
+
export interface ListItem {
|
|
4
|
+
/** Visible label. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Unique value identifying this row. */
|
|
7
|
+
value: string;
|
|
8
|
+
/** Optional icon rendered before the text. */
|
|
9
|
+
icon?: IconInput;
|
|
10
|
+
/** Optional secondary line under the label. */
|
|
11
|
+
description?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Options accepted by the `List` factory. */
|
|
14
|
+
export interface ListOptions {
|
|
15
|
+
/** The rows to render. */
|
|
16
|
+
items: ListItem[];
|
|
17
|
+
/** Enables single-select highlighting/interaction. Defaults to `true`. */
|
|
18
|
+
selectable?: boolean;
|
|
19
|
+
/** Controlled selected value. */
|
|
20
|
+
value?: string;
|
|
21
|
+
/** Called whenever the user selects a row (only when `selectable`). */
|
|
22
|
+
onChange?: (value: string) => void;
|
|
23
|
+
}
|
|
24
|
+
/** The runtime control surface attached to every `List` element. */
|
|
25
|
+
export interface ListApi {
|
|
26
|
+
/** Returns the currently selected value, if any. */
|
|
27
|
+
getValue: () => string | undefined;
|
|
28
|
+
/** Programmatically selects a value (does not trigger `onChange`). */
|
|
29
|
+
setValue: (value: string) => void;
|
|
30
|
+
/** Replaces the full list of rows. */
|
|
31
|
+
setItems: (items: ListItem[]) => void;
|
|
32
|
+
/** Detaches the list from the DOM and its internal listeners. */
|
|
33
|
+
destroy: () => void;
|
|
34
|
+
}
|
|
35
|
+
/** A `List` is a real `HTMLDivElement` extended with `ListApi`. */
|
|
36
|
+
export type ListElement = HTMLDivElement & ListApi;
|
|
37
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
38
|
+
export declare const listCss = "\n.linteau-list { display: flex; flex-direction: column; gap: 2px; width: 100% }\n.linteau-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--linteau-radius-sm); cursor: pointer }\n.linteau-list-item:hover { background: var(--linteau-accent) }\n.linteau-list-item-selected { background: var(--linteau-accent) }\n.linteau-list-item-text { display: flex; flex-direction: column }\n.linteau-list-item-label { font-size: 13px; color: var(--linteau-foreground) }\n.linteau-list-item-description { font-size: 11px; color: var(--linteau-muted-foreground) }\n";
|
|
39
|
+
/** Creates a vertical list of rows, optionally single-selectable. */
|
|
40
|
+
export declare function List(options: ListOptions): ListElement;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Sort direction used by `Table`. */
|
|
2
|
+
export type SortDirection = 'asc' | 'desc';
|
|
3
|
+
/** Definition of a single `Table` column. */
|
|
4
|
+
export interface TableColumn<TRow> {
|
|
5
|
+
/** Unique key, also used as the sort key passed to `onSortChange`. */
|
|
6
|
+
key: string;
|
|
7
|
+
/** Header label. */
|
|
8
|
+
header: string;
|
|
9
|
+
/** Allows this column's header to trigger sorting. Defaults to `false`. */
|
|
10
|
+
sortable?: boolean;
|
|
11
|
+
/** Custom cell renderer; defaults to reading `row[key]` as a string if omitted. */
|
|
12
|
+
render?: (row: TRow) => HTMLElement | string;
|
|
13
|
+
}
|
|
14
|
+
/** Options accepted by the `Table` factory. */
|
|
15
|
+
export interface TableOptions<TRow> {
|
|
16
|
+
/** Column definitions, in display order. */
|
|
17
|
+
columns: Array<TableColumn<TRow>>;
|
|
18
|
+
/** The rows to render. */
|
|
19
|
+
rows: TRow[];
|
|
20
|
+
/** Derives a stable string id for a row; used only internally for key stability. */
|
|
21
|
+
getRowId?: (row: TRow) => string;
|
|
22
|
+
/** Called when the user clicks a sortable header. */
|
|
23
|
+
onSortChange?: (key: string, direction: SortDirection) => void;
|
|
24
|
+
}
|
|
25
|
+
/** The runtime control surface attached to every `Table` element. */
|
|
26
|
+
export interface TableApi<TRow> {
|
|
27
|
+
/** Replaces the rows shown, re-rendering the body. */
|
|
28
|
+
setRows: (rows: TRow[]) => void;
|
|
29
|
+
/** Detaches the table from the DOM and its internal listeners. */
|
|
30
|
+
destroy: () => void;
|
|
31
|
+
}
|
|
32
|
+
/** A `Table` is a real `HTMLDivElement` (the scroll wrapper) extended with `TableApi`. */
|
|
33
|
+
export type TableElement<TRow> = HTMLDivElement & TableApi<TRow>;
|
|
34
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
35
|
+
export declare const tableCss = "\n.linteau-table-wrap { width: 100%; overflow-x: auto; border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-lg) }\n.linteau-table { width: 100%; border-collapse: collapse; font-size: 12px }\n.linteau-table th { text-align: left; padding: 10px 12px; background: var(--linteau-muted); color: var(--linteau-muted-foreground); font-weight: 600; border-bottom: 1px solid var(--linteau-border); cursor: default; white-space: nowrap }\n.linteau-table th.linteau-table-sortable { cursor: pointer; user-select: none }\n.linteau-table td { padding: 10px 12px; border-bottom: 1px solid var(--linteau-border); color: var(--linteau-foreground) }\n.linteau-table tr:last-child td { border-bottom: none }\n.linteau-table-sort-icon { display: inline-block; margin-left: 4px; vertical-align: middle }\n";
|
|
36
|
+
/** Creates a data table with optional click-to-sort headers and custom cell rendering. */
|
|
37
|
+
export declare function Table<TRow>(options: TableOptions<TRow>): TableElement<TRow>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** A single node in a `Tree`, optionally containing children. */
|
|
3
|
+
export interface TreeNode {
|
|
4
|
+
/** Visible label. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Unique value identifying this node. */
|
|
7
|
+
value: string;
|
|
8
|
+
/** Optional icon rendered before the label. */
|
|
9
|
+
icon?: IconInput;
|
|
10
|
+
/** Nested child nodes. */
|
|
11
|
+
children?: TreeNode[];
|
|
12
|
+
}
|
|
13
|
+
/** Options accepted by the `Tree` factory. */
|
|
14
|
+
export interface TreeOptions {
|
|
15
|
+
/** The root-level nodes to render. */
|
|
16
|
+
nodes: TreeNode[];
|
|
17
|
+
/** Values expanded by default. */
|
|
18
|
+
defaultExpanded?: string[];
|
|
19
|
+
/** Called when a leaf or branch node is clicked. */
|
|
20
|
+
onSelect?: (value: string) => void;
|
|
21
|
+
}
|
|
22
|
+
/** The runtime control surface attached to every `Tree` element. */
|
|
23
|
+
export interface TreeApi {
|
|
24
|
+
/** Expands every branch node. */
|
|
25
|
+
expandAll: () => void;
|
|
26
|
+
/** Collapses every branch node. */
|
|
27
|
+
collapseAll: () => void;
|
|
28
|
+
/** Detaches the tree from the DOM and its internal listeners. */
|
|
29
|
+
destroy: () => void;
|
|
30
|
+
}
|
|
31
|
+
/** A `Tree` is a real `HTMLDivElement` extended with `TreeApi`. */
|
|
32
|
+
export type TreeElement = HTMLDivElement & TreeApi;
|
|
33
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
34
|
+
export declare const treeCss = "\n.linteau-tree { display: flex; flex-direction: column; gap: 2px }\n.linteau-tree-row { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: var(--linteau-radius-sm); cursor: pointer; font-size: 12px }\n.linteau-tree-row:hover { background: var(--linteau-accent) }\n.linteau-tree-chevron { transition: transform 150ms ease }\n.linteau-tree-chevron.linteau-open { transform: rotate(90deg) }\n.linteau-tree-children { margin-left: 18px; display: flex; flex-direction: column; gap: 2px }\n.linteau-tree-children.linteau-collapsed { display: none }\n";
|
|
35
|
+
/** Creates a recursively nested, expandable tree of nodes. */
|
|
36
|
+
export declare function Tree(options: TreeOptions): TreeElement;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** Visual style of an `Alert`. */
|
|
3
|
+
export type AlertVariant = 'default' | 'success' | 'warning' | 'destructive';
|
|
4
|
+
/** Options accepted by the `Alert` factory. */
|
|
5
|
+
export interface AlertOptions {
|
|
6
|
+
/** Title shown above the description. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Visual style. Defaults to `'default'`. */
|
|
9
|
+
variant?: AlertVariant;
|
|
10
|
+
/** Optional icon; defaults to a sensible one per variant if omitted. */
|
|
11
|
+
icon?: IconInput;
|
|
12
|
+
/** Shows a close button. Defaults to `false`. */
|
|
13
|
+
dismissible?: boolean;
|
|
14
|
+
/** Called when the close button is clicked. */
|
|
15
|
+
onDismiss?: () => void;
|
|
16
|
+
}
|
|
17
|
+
/** The runtime control surface attached to every `Alert` element. */
|
|
18
|
+
export interface AlertApi {
|
|
19
|
+
/** Updates the description text. */
|
|
20
|
+
setDescription: (description: string) => void;
|
|
21
|
+
/** Detaches the alert from the DOM and its internal listener. */
|
|
22
|
+
destroy: () => void;
|
|
23
|
+
}
|
|
24
|
+
/** An `Alert` is a real `HTMLDivElement` extended with `AlertApi`. */
|
|
25
|
+
export type AlertElement = HTMLDivElement & AlertApi;
|
|
26
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
27
|
+
export declare const alertCss = "\n.linteau-alert { display: flex; gap: 10px; padding: 12px; border-radius: var(--linteau-radius-lg); border: 1px solid var(--linteau-border); background: var(--linteau-muted) }\n.linteau-alert-success { border-color: var(--linteau-success) }\n.linteau-alert-warning { border-color: var(--linteau-warning) }\n.linteau-alert-destructive { border-color: var(--linteau-destructive) }\n.linteau-alert-body { flex: 1 }\n.linteau-alert-title { font-size: 13px; font-weight: 600; margin-bottom: 2px }\n.linteau-alert-description { font-size: 12px; color: var(--linteau-muted-foreground) }\n.linteau-alert-close { background: transparent; border: none; color: var(--linteau-muted-foreground); cursor: pointer; display: flex; align-self: flex-start }\n";
|
|
28
|
+
/** Creates a static informational/status banner. */
|
|
29
|
+
export declare function Alert(description: string, options?: AlertOptions): AlertElement;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Options accepted by the `ProgressBar` factory. */
|
|
2
|
+
export interface ProgressBarOptions {
|
|
3
|
+
/** Title shown at the top of the overlay card. */
|
|
4
|
+
title?: string;
|
|
5
|
+
/** Initial progress percentage (0-100). Defaults to `0`. */
|
|
6
|
+
value?: number;
|
|
7
|
+
/** Whether the bar starts in indeterminate ("Working...") mode. Defaults to `false`. */
|
|
8
|
+
indeterminate?: boolean;
|
|
9
|
+
/** Whether the overlay is visible immediately. Defaults to `false`. */
|
|
10
|
+
visible?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** The runtime control surface attached to every `ProgressBar` element. */
|
|
13
|
+
export interface ProgressBarApi {
|
|
14
|
+
/** Sets the progress percentage (clamped 0-100) and optional custom label text. */
|
|
15
|
+
setValue: (percent: number, label?: string) => void;
|
|
16
|
+
/** Toggles indeterminate ("Working...") mode on or off. */
|
|
17
|
+
setIndeterminate: (indeterminate: boolean) => void;
|
|
18
|
+
/** Updates the overlay title text. */
|
|
19
|
+
setTitle: (title: string) => void;
|
|
20
|
+
/** Reveals the full-screen overlay. */
|
|
21
|
+
show: () => void;
|
|
22
|
+
/** Hides the full-screen overlay. */
|
|
23
|
+
hide: () => void;
|
|
24
|
+
/** Detaches the overlay from the DOM. */
|
|
25
|
+
destroy: () => void;
|
|
26
|
+
}
|
|
27
|
+
/** A `ProgressBar` is a real `HTMLDivElement` extended with `ProgressBarApi`. */
|
|
28
|
+
export type ProgressBarElement = HTMLDivElement & ProgressBarApi;
|
|
29
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
30
|
+
export declare const progressBarCss = "\n.linteau-progress-overlay { position: fixed; inset: 0; background: color-mix(in oklch, black 55%, transparent); display: flex; align-items: center; justify-content: center; z-index: 1000; backdrop-filter: blur(4px) }\n.linteau-progress-card { width: 280px; background: var(--linteau-card); border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-lg); padding: 20px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5) }\n.linteau-progress-title { font-size: 13px; font-weight: 600; margin-bottom: 12px; color: var(--linteau-foreground) }\n.linteau-progress-track { width: 100%; height: 8px; border-radius: 999px; background: var(--linteau-secondary); overflow: hidden; position: relative }\n.linteau-progress-fill { height: 100%; width: 0%; background: var(--linteau-primary); border-radius: 999px; transition: width 180ms ease }\n.linteau-progress-fill.linteau-indeterminate { width: 40% !important; animation: linteau-progress-slide 1.1s ease-in-out infinite }\n@keyframes linteau-progress-slide { 0% { transform: translateX(-100%) } 100% { transform: translateX(250%) } }\n.linteau-progress-percent { margin-top: 8px; font-size: 12px; color: var(--linteau-muted-foreground); text-align: right; font-variant-numeric: tabular-nums }\n";
|
|
31
|
+
/** Creates a full-screen progress overlay, ideal for long-running async operations. */
|
|
32
|
+
export declare function ProgressBar(options?: ProgressBarOptions): ProgressBarElement;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Options accepted by the `Skeleton` factory. */
|
|
2
|
+
export interface SkeletonOptions {
|
|
3
|
+
/** CSS width value or pixel number. Defaults to `'100%'`. */
|
|
4
|
+
width?: string | number;
|
|
5
|
+
/** CSS height value or pixel number. Defaults to `'1em'`. */
|
|
6
|
+
height?: string | number;
|
|
7
|
+
/** CSS border-radius value. Defaults to the theme's small radius. */
|
|
8
|
+
radius?: string;
|
|
9
|
+
}
|
|
10
|
+
/** The runtime control surface attached to every `Skeleton` element. */
|
|
11
|
+
export interface SkeletonApi {
|
|
12
|
+
/** Detaches the placeholder from the DOM. */
|
|
13
|
+
destroy: () => void;
|
|
14
|
+
}
|
|
15
|
+
/** A `Skeleton` is a real `HTMLDivElement` extended with `SkeletonApi`. */
|
|
16
|
+
export type SkeletonElement = HTMLDivElement & SkeletonApi;
|
|
17
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
18
|
+
export declare const skeletonCss = "\n.linteau-skeleton { background: linear-gradient(90deg, var(--linteau-secondary) 25%, var(--linteau-accent) 37%, var(--linteau-secondary) 63%); background-size: 400% 100%; animation: linteau-skeleton-shine 1.4s ease infinite; border-radius: var(--linteau-radius-sm) }\n@keyframes linteau-skeleton-shine { 0% { background-position: 100% 50% } 100% { background-position: 0 50% } }\n";
|
|
19
|
+
/** Creates an animated shimmering placeholder for content that's still loading. */
|
|
20
|
+
export declare function Skeleton(options?: SkeletonOptions): SkeletonElement;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Options accepted by the `Spinner` factory. */
|
|
2
|
+
export interface SpinnerOptions {
|
|
3
|
+
/** Pixel size of the spinner. Defaults to `16`. */
|
|
4
|
+
size?: number;
|
|
5
|
+
/** Stroke/text color. Defaults to `'currentColor'` via the icon's default. */
|
|
6
|
+
color?: string;
|
|
7
|
+
}
|
|
8
|
+
/** The runtime control surface attached to every `Spinner` element. */
|
|
9
|
+
export interface SpinnerApi {
|
|
10
|
+
/** Resizes the spinner in place. */
|
|
11
|
+
setSize: (size: number) => void;
|
|
12
|
+
/** Detaches the spinner from the DOM. */
|
|
13
|
+
destroy: () => void;
|
|
14
|
+
}
|
|
15
|
+
/** A `Spinner` is a real `SVGSVGElement` extended with `SpinnerApi`. */
|
|
16
|
+
export type SpinnerElement = SVGSVGElement & SpinnerApi;
|
|
17
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
18
|
+
export declare const spinnerCss = "\n.linteau-spinner { animation: linteau-spin 0.8s linear infinite; color: var(--linteau-muted-foreground) }\n@keyframes linteau-spin { to { transform: rotate(360deg) } }\n";
|
|
19
|
+
/** Creates a small, continuously rotating loading indicator. */
|
|
20
|
+
export declare function Spinner(options?: SpinnerOptions): SpinnerElement;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Visual style of a `Toast`. */
|
|
2
|
+
export type ToastVariant = 'default' | 'success' | 'warning' | 'destructive';
|
|
3
|
+
/** Options accepted by `ToastManager.show`. */
|
|
4
|
+
export interface ToastOptions {
|
|
5
|
+
/** Toast title. */
|
|
6
|
+
title?: string;
|
|
7
|
+
/** Supporting description text. */
|
|
8
|
+
description?: string;
|
|
9
|
+
/** Visual style. Defaults to `'default'`. */
|
|
10
|
+
variant?: ToastVariant;
|
|
11
|
+
/** Auto-dismiss delay in milliseconds. `0` disables auto-dismiss. Defaults to `4000`. */
|
|
12
|
+
duration?: number;
|
|
13
|
+
}
|
|
14
|
+
/** A stack-based toast notification manager. Lazily mounts its viewport to `document.body` on first use. */
|
|
15
|
+
export interface ToastManager {
|
|
16
|
+
/** Shows a new toast and returns its id (usable with `dismiss`). */
|
|
17
|
+
show: (options: ToastOptions) => string;
|
|
18
|
+
/** Dismisses a specific toast by id. */
|
|
19
|
+
dismiss: (id: string) => void;
|
|
20
|
+
/** Dismisses every visible toast. */
|
|
21
|
+
clear: () => void;
|
|
22
|
+
/** Removes the viewport entirely. */
|
|
23
|
+
destroy: () => void;
|
|
24
|
+
}
|
|
25
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
26
|
+
export declare const toastCss = "\n.linteau-toast-viewport { position: fixed; bottom: 16px; right: 16px; display: flex; flex-direction: column; gap: 8px; z-index: 1400; width: min(340px, 92vw) }\n.linteau-toast { display: flex; gap: 8px; background: var(--linteau-card); border: 1px solid var(--linteau-border); border-left: 3px solid var(--linteau-primary); border-radius: var(--linteau-radius-md); padding: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4) }\n.linteau-toast-success { border-left-color: var(--linteau-success) }\n.linteau-toast-warning { border-left-color: var(--linteau-warning) }\n.linteau-toast-destructive { border-left-color: var(--linteau-destructive) }\n.linteau-toast-body { flex: 1 }\n.linteau-toast-title { font-size: 12px; font-weight: 600 }\n.linteau-toast-description { font-size: 12px; color: var(--linteau-muted-foreground); margin-top: 2px }\n.linteau-toast-close { background: transparent; border: none; color: var(--linteau-muted-foreground); cursor: pointer; display: flex; align-self: flex-start }\n";
|
|
27
|
+
/** Creates an independent toast manager with its own viewport. Most apps only need the shared `toast` export below. */
|
|
28
|
+
export declare function createToastManager(): ToastManager;
|
|
29
|
+
/** A ready-to-use shared toast manager: `toast.show({ title: 'Saved' })`. */
|
|
30
|
+
export declare const toast: ToastManager;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IconInput } from '../../svg/types';
|
|
2
|
+
/** Options accepted by the `ColorField` factory. */
|
|
3
|
+
export interface ColorFieldOptions {
|
|
4
|
+
/** Label rendered before the swatch. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Optional icon rendered before the label. */
|
|
7
|
+
icon?: IconInput;
|
|
8
|
+
/** Controlled hex value. When provided together with `onChange`, you own the state. */
|
|
9
|
+
value?: string;
|
|
10
|
+
/** Uncontrolled initial value, used only if `value` is omitted. Defaults to `'#ffffff'`. */
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
/** Disables interaction. Defaults to `false`. */
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/** Called on every color change. */
|
|
15
|
+
onChange?: (value: string) => void;
|
|
16
|
+
}
|
|
17
|
+
/** The runtime control surface attached to every `ColorField` element. */
|
|
18
|
+
export interface ColorFieldApi {
|
|
19
|
+
/** Returns the current hex color string. */
|
|
20
|
+
getValue: () => string;
|
|
21
|
+
/** Programmatically sets the color (does not trigger `onChange`). */
|
|
22
|
+
setValue: (value: string) => void;
|
|
23
|
+
/** Enables/disables the control. */
|
|
24
|
+
setDisabled: (disabled: boolean) => void;
|
|
25
|
+
/** Detaches the field from the DOM and its internal listener. */
|
|
26
|
+
destroy: () => void;
|
|
27
|
+
}
|
|
28
|
+
/** A `ColorField` is a real `HTMLDivElement` (the field row) extended with `ColorFieldApi`. */
|
|
29
|
+
export type ColorFieldElement = HTMLDivElement & ColorFieldApi;
|
|
30
|
+
/** This component's own CSS, colocated and self-injected on first use. */
|
|
31
|
+
export declare const swatchCss = "\n.linteau-swatch { --linteau-swatch-color: #ffffff; width: 28px; height: 28px; border-radius: var(--linteau-radius-sm); background: var(--linteau-swatch-color); border: 1px solid var(--linteau-border); cursor: pointer; display: block; position: relative; overflow: hidden; transition: transform 120ms ease }\n.linteau-swatch:hover { transform: scale(1.06) }\n.linteau-swatch input[type='color'] { position: absolute; inset: 0; opacity: 0; cursor: pointer }\n";
|
|
32
|
+
/** Creates a labeled native color-picker swatch, supporting controlled and uncontrolled usage. */
|
|
33
|
+
export declare function ColorField(options: ColorFieldOptions): ColorFieldElement;
|