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.
Files changed (113) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +88 -0
  3. package/dist/components/avatar/Avatar.d.ts +26 -0
  4. package/dist/components/badge/Badge.d.ts +25 -0
  5. package/dist/components/button/Button.d.ts +51 -0
  6. package/dist/components/button/ButtonGroup.d.ts +36 -0
  7. package/dist/components/checkbox/Checkbox.d.ts +34 -0
  8. package/dist/components/command/Command.d.ts +59 -0
  9. package/dist/components/data/List.d.ts +40 -0
  10. package/dist/components/data/Table.d.ts +37 -0
  11. package/dist/components/data/Tree.d.ts +36 -0
  12. package/dist/components/feedback/Alert.d.ts +29 -0
  13. package/dist/components/feedback/ProgressBar.d.ts +32 -0
  14. package/dist/components/feedback/Skeleton.d.ts +20 -0
  15. package/dist/components/feedback/Spinner.d.ts +20 -0
  16. package/dist/components/feedback/Toast.d.ts +30 -0
  17. package/dist/components/field/ColorField.d.ts +33 -0
  18. package/dist/components/field/NumberField.d.ts +42 -0
  19. package/dist/components/field/TextArea.d.ts +35 -0
  20. package/dist/components/field/TextField.d.ts +39 -0
  21. package/dist/components/field/shared.d.ts +9 -0
  22. package/dist/components/field/textInput.css.d.ts +5 -0
  23. package/dist/components/hovercard/HoverCard.d.ts +35 -0
  24. package/dist/components/input/ChipInput.d.ts +31 -0
  25. package/dist/components/input/DatePicker.d.ts +66 -0
  26. package/dist/components/input/FileDropzone.d.ts +26 -0
  27. package/dist/components/layout/Card.d.ts +24 -0
  28. package/dist/components/layout/Section.d.ts +33 -0
  29. package/dist/components/layout/Separator.d.ts +18 -0
  30. package/dist/components/misc/ModeCard.d.ts +35 -0
  31. package/dist/components/navigation/Accordion.d.ts +42 -0
  32. package/dist/components/navigation/Breadcrumb.d.ts +25 -0
  33. package/dist/components/navigation/Pagination.d.ts +30 -0
  34. package/dist/components/navigation/Tabs.d.ts +38 -0
  35. package/dist/components/overlay/AlertDialog.d.ts +37 -0
  36. package/dist/components/overlay/ContextMenu.d.ts +19 -0
  37. package/dist/components/overlay/Dialog.d.ts +38 -0
  38. package/dist/components/overlay/Drawer.d.ts +40 -0
  39. package/dist/components/overlay/DropdownMenu.d.ts +55 -0
  40. package/dist/components/overlay/Popover.d.ts +33 -0
  41. package/dist/components/radio/RadioGroup.d.ts +37 -0
  42. package/dist/components/select/Combobox.d.ts +42 -0
  43. package/dist/components/select/Select.d.ts +48 -0
  44. package/dist/components/slider/RangeSlider.d.ts +43 -0
  45. package/dist/components/slider/Slider.d.ts +41 -0
  46. package/dist/components/switch/Switch.d.ts +35 -0
  47. package/dist/components/toggle/Toggle.d.ts +39 -0
  48. package/dist/components/toggle/ToggleGroup.d.ts +47 -0
  49. package/dist/components/tooltip/Tooltip.d.ts +22 -0
  50. package/dist/core/classNames.d.ts +6 -0
  51. package/dist/core/content.d.ts +2 -0
  52. package/dist/core/controller.d.ts +34 -0
  53. package/dist/core/dom.d.ts +14 -0
  54. package/dist/core/overlay.d.ts +14 -0
  55. package/dist/core/styleInjector.d.ts +12 -0
  56. package/dist/core/theme.d.ts +18 -0
  57. package/dist/core/types.d.ts +10 -0
  58. package/dist/index.cjs +4054 -0
  59. package/dist/index.cjs.map +1 -0
  60. package/dist/index.d.ts +62 -0
  61. package/dist/index.js +3934 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/linteau.global.js +397 -0
  64. package/dist/linteau.global.js.map +7 -0
  65. package/dist/styles/tokens.d.ts +33 -0
  66. package/dist/svg/Icon.d.ts +19 -0
  67. package/dist/svg/create-icon.d.ts +13 -0
  68. package/dist/svg/icons/alertTriangle.d.ts +1 -0
  69. package/dist/svg/icons/bell.d.ts +1 -0
  70. package/dist/svg/icons/calendar.d.ts +1 -0
  71. package/dist/svg/icons/check.d.ts +1 -0
  72. package/dist/svg/icons/chevronDown.d.ts +1 -0
  73. package/dist/svg/icons/chevronLeft.d.ts +1 -0
  74. package/dist/svg/icons/chevronRight.d.ts +1 -0
  75. package/dist/svg/icons/chevronUp.d.ts +1 -0
  76. package/dist/svg/icons/circle.d.ts +1 -0
  77. package/dist/svg/icons/copy.d.ts +1 -0
  78. package/dist/svg/icons/download.d.ts +1 -0
  79. package/dist/svg/icons/edit.d.ts +1 -0
  80. package/dist/svg/icons/externalLink.d.ts +1 -0
  81. package/dist/svg/icons/eye.d.ts +1 -0
  82. package/dist/svg/icons/eyeOff.d.ts +1 -0
  83. package/dist/svg/icons/filter.d.ts +1 -0
  84. package/dist/svg/icons/heart.d.ts +1 -0
  85. package/dist/svg/icons/home.d.ts +1 -0
  86. package/dist/svg/icons/index.d.ts +54 -0
  87. package/dist/svg/icons/info.d.ts +1 -0
  88. package/dist/svg/icons/link.d.ts +1 -0
  89. package/dist/svg/icons/loader.d.ts +1 -0
  90. package/dist/svg/icons/lock.d.ts +1 -0
  91. package/dist/svg/icons/mail.d.ts +1 -0
  92. package/dist/svg/icons/menu.d.ts +1 -0
  93. package/dist/svg/icons/minus.d.ts +1 -0
  94. package/dist/svg/icons/moon.d.ts +1 -0
  95. package/dist/svg/icons/moreHorizontal.d.ts +1 -0
  96. package/dist/svg/icons/phone.d.ts +1 -0
  97. package/dist/svg/icons/plus.d.ts +1 -0
  98. package/dist/svg/icons/refreshCw.d.ts +1 -0
  99. package/dist/svg/icons/search.d.ts +1 -0
  100. package/dist/svg/icons/settings.d.ts +1 -0
  101. package/dist/svg/icons/star.d.ts +1 -0
  102. package/dist/svg/icons/sun.d.ts +1 -0
  103. package/dist/svg/icons/trash.d.ts +1 -0
  104. package/dist/svg/icons/upload.d.ts +1 -0
  105. package/dist/svg/icons/user.d.ts +1 -0
  106. package/dist/svg/icons/x.d.ts +1 -0
  107. package/dist/svg/index.cjs +380 -0
  108. package/dist/svg/index.cjs.map +1 -0
  109. package/dist/svg/index.d.ts +4 -0
  110. package/dist/svg/index.js +352 -0
  111. package/dist/svg/index.js.map +1 -0
  112. package/dist/svg/types.d.ts +26 -0
  113. package/package.json +81 -0
@@ -0,0 +1,38 @@
1
+ /** Options accepted by the `Dialog` factory. */
2
+ export interface DialogOptions {
3
+ /** Title shown in the header. */
4
+ title?: string;
5
+ /** Initial body content. */
6
+ content?: HTMLElement | string;
7
+ /** Footer action elements (e.g. Buttons), right-aligned. */
8
+ actions?: HTMLElement[];
9
+ /** Closes the dialog when the backdrop is clicked. Defaults to `true`. */
10
+ closeOnBackdrop?: boolean;
11
+ /** Closes the dialog on Escape. Defaults to `true`. */
12
+ closeOnEscape?: boolean;
13
+ /** Called whenever the open state changes. */
14
+ onOpenChange?: (open: boolean) => void;
15
+ }
16
+ /** The runtime control surface attached to every `Dialog` element. */
17
+ export interface DialogApi {
18
+ /** The scrollable body container -- set once via `content`, or update later with `setContent`. */
19
+ body: HTMLElement;
20
+ /** Opens the dialog: locks scroll, binds Escape. */
21
+ open: () => void;
22
+ /** Closes the dialog. */
23
+ close: () => void;
24
+ /** Returns whether the dialog is currently open. */
25
+ isOpen: () => boolean;
26
+ /** Updates the header title text. */
27
+ setTitle: (title: string) => void;
28
+ /** Replaces the body content. */
29
+ setContent: (content: HTMLElement | string) => void;
30
+ /** Removes all listeners/subscriptions and detaches the dialog from the DOM. */
31
+ destroy: () => void;
32
+ }
33
+ /** A `Dialog` is a real `HTMLDivElement` (the overlay) extended with `DialogApi`. */
34
+ export type DialogElement = HTMLDivElement & DialogApi;
35
+ /** This component's own CSS, colocated and self-injected on first use. */
36
+ export declare const dialogCss = "\n.linteau-dialog-overlay { position: fixed; inset: 0; background: color-mix(in oklch, black 60%, transparent); display: flex; align-items: center; justify-content: center; z-index: 1000; backdrop-filter: blur(4px) }\n.linteau-dialog-panel { width: min(480px, 92vw); max-height: 86vh; 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-dialog-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--linteau-border) }\n.linteau-dialog-title { font-size: 14px; font-weight: 600 }\n.linteau-dialog-close { background: transparent; border: none; color: var(--linteau-muted-foreground); cursor: pointer; display: flex; padding: 4px; border-radius: var(--linteau-radius-sm) }\n.linteau-dialog-close:hover { background: var(--linteau-accent); color: var(--linteau-foreground) }\n.linteau-dialog-body { padding: 16px; overflow-y: auto }\n.linteau-dialog-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--linteau-border) }\n";
37
+ /** Creates a centered modal dialog with a backdrop, focus-safe scroll lock, and Escape-to-close. */
38
+ export declare function Dialog(options?: DialogOptions): DialogElement;
@@ -0,0 +1,40 @@
1
+ /** Which edge of the screen a `Drawer` slides in from. */
2
+ export type DrawerSide = 'left' | 'right' | 'top' | 'bottom';
3
+ /** Options accepted by the `Drawer` factory. */
4
+ export interface DrawerOptions {
5
+ /** Which edge to slide in from. Defaults to `'right'`. */
6
+ side?: DrawerSide;
7
+ /** Title shown in the header. */
8
+ title?: string;
9
+ /** Initial body content. */
10
+ content?: HTMLElement | string;
11
+ /** Closes the drawer when the backdrop is clicked. Defaults to `true`. */
12
+ closeOnBackdrop?: boolean;
13
+ /** Closes the drawer on Escape. Defaults to `true`. */
14
+ closeOnEscape?: boolean;
15
+ /** Called whenever the open state changes. */
16
+ onOpenChange?: (open: boolean) => void;
17
+ }
18
+ /** The runtime control surface attached to every `Drawer` element. */
19
+ export interface DrawerApi {
20
+ /** The scrollable body container. */
21
+ body: HTMLElement;
22
+ /** Opens the drawer. */
23
+ open: () => void;
24
+ /** Closes the drawer. */
25
+ close: () => void;
26
+ /** Returns whether the drawer is currently open. */
27
+ isOpen: () => boolean;
28
+ /** Updates the header title text. */
29
+ setTitle: (title: string) => void;
30
+ /** Replaces the body content. */
31
+ setContent: (content: HTMLElement | string) => void;
32
+ /** Removes all listeners/subscriptions and detaches the drawer from the DOM. */
33
+ destroy: () => void;
34
+ }
35
+ /** A `Drawer` is a real `HTMLDivElement` (the overlay) extended with `DrawerApi`. */
36
+ export type DrawerElement = HTMLDivElement & DrawerApi;
37
+ /** This component's own CSS, colocated and self-injected on first use. */
38
+ export declare const drawerCss = "\n.linteau-drawer-overlay { position: fixed; inset: 0; background: color-mix(in oklch, black 55%, transparent); z-index: 1000 }\n.linteau-drawer-panel { position: fixed; background: var(--linteau-card); border: 1px solid var(--linteau-border); display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); transition: transform 200ms ease }\n.linteau-drawer-right { top: 0; right: 0; bottom: 0; width: min(360px, 90vw); transform: translateX(0) }\n.linteau-drawer-left { top: 0; left: 0; bottom: 0; width: min(360px, 90vw); transform: translateX(0) }\n.linteau-drawer-top { top: 0; left: 0; right: 0; height: min(320px, 80vh); transform: translateY(0) }\n.linteau-drawer-bottom { bottom: 0; left: 0; right: 0; height: min(320px, 80vh); transform: translateY(0) }\n.linteau-drawer-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--linteau-border) }\n.linteau-drawer-title { font-size: 14px; font-weight: 600 }\n.linteau-drawer-close { background: transparent; border: none; color: var(--linteau-muted-foreground); cursor: pointer; display: flex; padding: 4px; border-radius: var(--linteau-radius-sm) }\n.linteau-drawer-body { padding: 16px; overflow-y: auto; flex: 1 }\n";
39
+ /** Creates a slide-in panel anchored to a screen edge, ideal for side navigation or contextual forms. */
40
+ export declare function Drawer(options?: DrawerOptions): DrawerElement;
@@ -0,0 +1,55 @@
1
+ import type { FloatingPlacement } from '../../core/overlay';
2
+ import type { IconInput } from '../../svg/types';
3
+ /** A single actionable entry in a `DropdownMenu`/`ContextMenu`. */
4
+ export interface MenuItem {
5
+ /** Visible label. */
6
+ label: string;
7
+ /** Value passed to `onSelect` when this item is chosen. */
8
+ value: string;
9
+ /** Optional icon rendered before the label. */
10
+ icon?: IconInput;
11
+ /** Disables this item. Defaults to `false`. */
12
+ disabled?: boolean;
13
+ /** Renders the item in the destructive color. Defaults to `false`. */
14
+ destructive?: boolean;
15
+ }
16
+ /** A visual divider between menu items. */
17
+ export interface MenuSeparator {
18
+ separator: true;
19
+ }
20
+ /** A single entry rendered by a menu -- either a selectable item or a separator. */
21
+ export type MenuEntry = MenuItem | MenuSeparator;
22
+ /** Renders `entries` into `container`, wiring up click handling. Shared by `DropdownMenu` and `ContextMenu`. */
23
+ export declare function renderMenuEntries(container: HTMLElement, entries: MenuEntry[], onSelect: (value: string) => void, onAfterSelect: () => void): void;
24
+ /** Options accepted by the `DropdownMenu` factory. */
25
+ export interface DropdownMenuOptions {
26
+ /** The element the menu is anchored to and toggled by. */
27
+ anchor: HTMLElement;
28
+ /** The menu's items/separators. */
29
+ items: MenuEntry[];
30
+ /** Side of the anchor the menu appears on. Defaults to `'bottom'`. */
31
+ placement?: FloatingPlacement;
32
+ /** Called when an enabled item is chosen. */
33
+ onSelect?: (value: string) => void;
34
+ }
35
+ /** The runtime control surface attached to every `DropdownMenu` element. */
36
+ export interface DropdownMenuApi {
37
+ /** Opens the menu. */
38
+ open: () => void;
39
+ /** Closes the menu. */
40
+ close: () => void;
41
+ /** Toggles between open and closed. */
42
+ toggle: () => void;
43
+ /** Returns whether the menu is currently open. */
44
+ isOpen: () => boolean;
45
+ /** Replaces the full list of items/separators. */
46
+ setItems: (items: MenuEntry[]) => void;
47
+ /** Removes all listeners and detaches the menu from the DOM. */
48
+ destroy: () => void;
49
+ }
50
+ /** A `DropdownMenu` is a real `HTMLDivElement` (the floating menu) extended with `DropdownMenuApi`. */
51
+ export type DropdownMenuElement = HTMLDivElement & DropdownMenuApi;
52
+ /** This component's own CSS. Reused by `ContextMenu` under the same `menu` key, so it's only ever injected once. */
53
+ export declare const menuCss = "\n.linteau-menu { position: fixed; z-index: 1200; min-width: 160px; background: var(--linteau-card); border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-md); padding: 4px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4) }\n.linteau-menu-item { display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: var(--linteau-radius-sm); font-size: 12px; color: var(--linteau-foreground); cursor: pointer }\n.linteau-menu-item:hover:not(.linteau-menu-item-disabled) { background: var(--linteau-accent) }\n.linteau-menu-item-disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-menu-item-destructive { color: var(--linteau-destructive) }\n.linteau-menu-separator { height: 1px; background: var(--linteau-border); margin: 4px 0 }\n";
54
+ /** Creates a floating action menu anchored to another element, toggled by clicking that anchor. */
55
+ export declare function DropdownMenu(options: DropdownMenuOptions): DropdownMenuElement;
@@ -0,0 +1,33 @@
1
+ import type { FloatingPlacement } from '../../core/overlay';
2
+ /** Options accepted by the `Popover` factory. */
3
+ export interface PopoverOptions {
4
+ /** The element the popover is anchored to and toggled by. */
5
+ anchor: HTMLElement;
6
+ /** Initial panel content. */
7
+ content: HTMLElement | string;
8
+ /** Side of the anchor the panel appears on. Defaults to `'bottom'`. */
9
+ placement?: FloatingPlacement;
10
+ /** Closes the popover when clicking outside it. Defaults to `true`. */
11
+ closeOnClickOutside?: boolean;
12
+ }
13
+ /** The runtime control surface attached to every `Popover` element. */
14
+ export interface PopoverApi {
15
+ /** Opens the popover and positions it against its anchor. */
16
+ open: () => void;
17
+ /** Closes the popover. */
18
+ close: () => void;
19
+ /** Toggles between open and closed. */
20
+ toggle: () => void;
21
+ /** Returns whether the popover is currently open. */
22
+ isOpen: () => boolean;
23
+ /** Replaces the panel content. */
24
+ setContent: (content: HTMLElement | string) => void;
25
+ /** Removes all listeners and detaches the popover from the DOM. */
26
+ destroy: () => void;
27
+ }
28
+ /** A `Popover` is a real `HTMLDivElement` (the floating panel) extended with `PopoverApi`. */
29
+ export type PopoverElement = HTMLDivElement & PopoverApi;
30
+ /** This component's own CSS, colocated and self-injected on first use. */
31
+ export declare const popoverCss = "\n.linteau-popover { position: fixed; z-index: 1200; background: var(--linteau-card); border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-md); padding: 10px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4) }\n";
32
+ /** Creates a floating panel anchored to another element, toggled by clicking that anchor. */
33
+ export declare function Popover(options: PopoverOptions): PopoverElement;
@@ -0,0 +1,37 @@
1
+ /** A single selectable option within a `RadioGroup`. */
2
+ export interface RadioOptionItem {
3
+ /** Visible label. */
4
+ label: string;
5
+ /** Unique value identifying this option. */
6
+ value: string;
7
+ /** Disables just this option. Defaults to `false`. */
8
+ disabled?: boolean;
9
+ }
10
+ /** Options accepted by the `RadioGroup` factory. */
11
+ export interface RadioGroupOptions {
12
+ /** The list of selectable options. */
13
+ items: RadioOptionItem[];
14
+ /** Controlled value. */
15
+ value?: string;
16
+ /** Uncontrolled initial value, used only if `value` is omitted. */
17
+ defaultValue?: string;
18
+ /** Disables every option. Defaults to `false`. */
19
+ disabled?: boolean;
20
+ /** Called whenever the user picks a new option. */
21
+ onChange?: (value: string) => void;
22
+ }
23
+ /** The runtime control surface attached to every `RadioGroup` element. */
24
+ export interface RadioGroupApi {
25
+ /** Returns the currently selected value, if any. */
26
+ getValue: () => string | undefined;
27
+ /** Programmatically selects a value (does not trigger `onChange`). */
28
+ setValue: (value: string) => void;
29
+ /** Detaches the group from the DOM and its internal listeners. */
30
+ destroy: () => void;
31
+ }
32
+ /** A `RadioGroup` is a real `HTMLDivElement` extended with `RadioGroupApi`. */
33
+ export type RadioGroupElement = HTMLDivElement & RadioGroupApi;
34
+ /** This component's own CSS, colocated and self-injected on first use. */
35
+ export declare const radioCss = "\n.linteau-radio-group { display: flex; flex-direction: column; gap: 8px }\n.linteau-radio-row { display: flex; align-items: center; gap: 8px; cursor: pointer }\n.linteau-radio-row.linteau-disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-radio { width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--linteau-border); background: var(--linteau-secondary); display: flex; align-items: center; justify-content: center; flex-shrink: 0 }\n.linteau-radio.linteau-checked { border-color: var(--linteau-primary) }\n.linteau-radio-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--linteau-primary); opacity: 0; transition: opacity 100ms ease }\n.linteau-radio.linteau-checked .linteau-radio-dot { opacity: 1 }\n";
36
+ /** Creates a single-select group of radio rows. */
37
+ export declare function RadioGroup(options: RadioGroupOptions): RadioGroupElement;
@@ -0,0 +1,42 @@
1
+ import type { IconInput } from '../../svg/types';
2
+ import type { SelectOptionItem } from './Select';
3
+ /** Options accepted by the `Combobox` factory. */
4
+ export interface ComboboxOptions {
5
+ /** Label rendered above the field. */
6
+ label: string;
7
+ /** Optional icon rendered before the label. */
8
+ icon?: IconInput;
9
+ /** The list of selectable options, filtered live against the typed text. */
10
+ options: SelectOptionItem[];
11
+ /** Controlled value. */
12
+ value?: string;
13
+ /** Uncontrolled initial value, used only if `value` is omitted. */
14
+ defaultValue?: string;
15
+ /** Placeholder shown when nothing is typed/selected. */
16
+ placeholder?: string;
17
+ /** Disables the field. Defaults to `false`. */
18
+ disabled?: boolean;
19
+ /** Called whenever the user selects an option. */
20
+ onChange?: (value: string) => void;
21
+ }
22
+ /** The runtime control surface attached to every `Combobox` element. */
23
+ export interface ComboboxApi {
24
+ /** Returns the currently selected value. */
25
+ getValue: () => string;
26
+ /** Programmatically selects a value (does not trigger `onChange`). */
27
+ setValue: (value: string) => void;
28
+ /** Replaces the full list of options. */
29
+ setOptions: (options: SelectOptionItem[]) => void;
30
+ /** Opens the suggestion list. */
31
+ open: () => void;
32
+ /** Closes the suggestion list. */
33
+ close: () => void;
34
+ /** Detaches the field from the DOM and its internal listeners. */
35
+ destroy: () => void;
36
+ }
37
+ /** A `Combobox` is a real `HTMLDivElement` (the field wrapper) extended with `ComboboxApi`. */
38
+ export type ComboboxElement = HTMLDivElement & ComboboxApi;
39
+ /** This component's own CSS. Reused by `DatePicker` under the same `combobox` key, so it's only ever injected once. */
40
+ export declare const comboboxCss = "\n.linteau-combobox { position: relative; display: flex; align-items: center }\n.linteau-combobox-input { padding-right: 28px }\n.linteau-combobox-chevron { position: absolute; right: 8px; pointer-events: none; color: var(--linteau-muted-foreground) }\n.linteau-combobox-list { position: fixed; z-index: 1200; min-width: 180px; max-height: 220px; overflow-y: auto; background: var(--linteau-card); border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-md); padding: 4px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4) }\n.linteau-combobox-option { padding: 6px 8px; border-radius: var(--linteau-radius-sm); font-size: 12px; cursor: pointer; color: var(--linteau-foreground) }\n.linteau-combobox-option-highlighted, .linteau-combobox-option:hover { background: var(--linteau-accent) }\n";
41
+ /** Creates a filterable, type-to-search select -- a text input backed by a live-filtered dropdown of options. */
42
+ export declare function Combobox(options: ComboboxOptions): ComboboxElement;
@@ -0,0 +1,48 @@
1
+ import type { IconInput } from '../../svg/types';
2
+ /** A single option rendered inside a `Select`. */
3
+ export interface SelectOptionItem {
4
+ /** Visible label. */
5
+ label: string;
6
+ /** Underlying value. */
7
+ value: string;
8
+ /** Disables just this option. Defaults to `false`. */
9
+ disabled?: boolean;
10
+ }
11
+ /** Options accepted by the `Select` factory. */
12
+ export interface SelectOptions {
13
+ /** Label rendered before the dropdown. */
14
+ label: string;
15
+ /** Optional icon rendered before the label. */
16
+ icon?: IconInput;
17
+ /** The list of selectable options. */
18
+ options: SelectOptionItem[];
19
+ /** Controlled value. When provided together with `onChange`, you own the state. */
20
+ value?: string;
21
+ /** Uncontrolled initial value, used only if `value` is omitted. */
22
+ defaultValue?: string;
23
+ /** Placeholder shown when no value is selected (renders as a disabled first option). */
24
+ placeholder?: string;
25
+ /** Disables the whole control. Defaults to `false`. */
26
+ disabled?: boolean;
27
+ /** Called whenever the user picks a new option. */
28
+ onChange?: (value: string) => void;
29
+ }
30
+ /** The runtime control surface attached to every `Select` element. */
31
+ export interface SelectApi {
32
+ /** Returns the currently selected value. */
33
+ getValue: () => string;
34
+ /** Programmatically selects a value (does not trigger `onChange`). */
35
+ setValue: (value: string) => void;
36
+ /** Replaces the full list of options, preserving selection where possible. */
37
+ setOptions: (options: SelectOptionItem[]) => void;
38
+ /** Enables/disables the control. */
39
+ setDisabled: (disabled: boolean) => void;
40
+ /** Detaches the select from the DOM and its internal listener. */
41
+ destroy: () => void;
42
+ }
43
+ /** A `Select` is a real `HTMLDivElement` (the field row) extended with `SelectApi`. */
44
+ export type SelectElement = HTMLDivElement & SelectApi;
45
+ /** This component's own CSS, colocated and self-injected on first use. */
46
+ export declare const selectCss = "\n.linteau-select-wrap { position: relative }\n.linteau-select { appearance: none; background: var(--linteau-secondary); color: var(--linteau-foreground); border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-sm); padding: 6px 28px 6px 10px; font-size: 12px; font-family: inherit; cursor: pointer; transition: border-color 120ms ease }\n.linteau-select:disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-select:focus { outline: none; border-color: var(--linteau-ring); box-shadow: 0 0 0 2px color-mix(in oklch, var(--linteau-ring) 20%, transparent) }\n.linteau-select-chevron { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); pointer-events: none }\n";
47
+ /** Creates a labeled native select dropdown, restyled to match the design system. */
48
+ export declare function Select(options: SelectOptions): SelectElement;
@@ -0,0 +1,43 @@
1
+ import type { IconInput } from '../../svg/types';
2
+ /** A `[low, high]` numeric pair. */
3
+ export type RangeValue = [number, number];
4
+ /** Options accepted by the `RangeSlider` factory. */
5
+ export interface RangeSliderOptions {
6
+ /** Label rendered above the track. */
7
+ label: string;
8
+ /** Optional icon rendered before the label. */
9
+ icon?: IconInput;
10
+ /** Minimum value. */
11
+ min: number;
12
+ /** Maximum value. */
13
+ max: number;
14
+ /** Step increment. */
15
+ step: number;
16
+ /** Controlled `[low, high]` value. */
17
+ value?: RangeValue;
18
+ /** Uncontrolled initial `[low, high]` value, used only if `value` is omitted. */
19
+ defaultValue?: RangeValue;
20
+ /** Disables both thumbs. Defaults to `false`. */
21
+ disabled?: boolean;
22
+ /** Formats each displayed bound. Defaults to `String(value)`. */
23
+ format?: (value: number) => string;
24
+ /** Called on every change with the new `[low, high]` pair. */
25
+ onChange?: (value: RangeValue) => void;
26
+ }
27
+ /** The runtime control surface attached to every `RangeSlider` element. */
28
+ export interface RangeSliderApi {
29
+ /** Returns the current `[low, high]` value. */
30
+ getValue: () => RangeValue;
31
+ /** Programmatically sets the value (does not trigger `onChange`). */
32
+ setValue: (value: RangeValue) => void;
33
+ /** Enables/disables both thumbs. */
34
+ setDisabled: (disabled: boolean) => void;
35
+ /** Detaches the slider from the DOM and its internal listeners. */
36
+ destroy: () => void;
37
+ }
38
+ /** A `RangeSlider` is a real `HTMLDivElement` (the field wrapper) extended with `RangeSliderApi`. */
39
+ export type RangeSliderElement = HTMLDivElement & RangeSliderApi;
40
+ /** This component's own CSS. Depends on `.linteau-slider` (registered via the imported `sliderCss`) for its thumbs. */
41
+ export declare const rangeSliderCss = "\n.linteau-range-track { position: relative; height: 20px; display: flex; align-items: center }\n.linteau-range-track::before { content: ''; position: absolute; left: 0; right: 0; height: 6px; border-radius: 999px; background: var(--linteau-secondary) }\n.linteau-range-track::after { content: ''; position: absolute; height: 6px; border-radius: 999px; background: var(--linteau-primary); left: var(--linteau-range-low, 0%); right: calc(100% - var(--linteau-range-high, 100%)) }\n.linteau-range-input { position: absolute; left: 0; right: 0; width: 100%; height: 20px; background: transparent; pointer-events: none; margin: 0 }\n.linteau-range-input::-webkit-slider-thumb { pointer-events: auto }\n.linteau-range-input::-moz-range-thumb { pointer-events: auto }\n";
42
+ /** Creates a labeled dual-thumb range slider, supporting controlled and uncontrolled usage. */
43
+ export declare function RangeSlider(options: RangeSliderOptions): RangeSliderElement;
@@ -0,0 +1,41 @@
1
+ import type { IconInput } from '../../svg/types';
2
+ /** Options accepted by the `Slider` factory. */
3
+ export interface SliderOptions {
4
+ /** Label rendered above the track. */
5
+ label: string;
6
+ /** Optional icon rendered before the label. */
7
+ icon?: IconInput;
8
+ /** Minimum value. */
9
+ min: number;
10
+ /** Maximum value. */
11
+ max: number;
12
+ /** Step increment. */
13
+ step: number;
14
+ /** Controlled value. When provided together with `onChange`, you own the state. */
15
+ value?: number;
16
+ /** Uncontrolled initial value, used only if `value` is omitted. */
17
+ defaultValue?: number;
18
+ /** Disables interaction. Defaults to `false`. */
19
+ disabled?: boolean;
20
+ /** Formats the displayed value string. Defaults to `String(value)`. */
21
+ format?: (value: number) => string;
22
+ /** Called on every input event with the new numeric value. */
23
+ onChange?: (value: number) => void;
24
+ }
25
+ /** The runtime control surface attached to every `Slider` element. */
26
+ export interface SliderApi {
27
+ /** Returns the current numeric value. */
28
+ getValue: () => number;
29
+ /** Programmatically sets the value (does not trigger `onChange`, clamped to `[min, max]`). */
30
+ setValue: (value: number) => void;
31
+ /** Enables/disables the slider. */
32
+ setDisabled: (disabled: boolean) => void;
33
+ /** Detaches the slider from the DOM and its internal listener. */
34
+ destroy: () => void;
35
+ }
36
+ /** A `Slider` is a real `HTMLDivElement` (the field wrapper) extended with `SliderApi`. */
37
+ export type SliderElement = HTMLDivElement & SliderApi;
38
+ /** This component's own CSS, colocated and self-injected on first use. */
39
+ export declare const sliderCss = "\n.linteau-slider { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; border-radius: 999px; background: linear-gradient(to right, var(--linteau-primary) 0%, var(--linteau-primary) var(--linteau-fill, 0%), var(--linteau-secondary) var(--linteau-fill, 0%), var(--linteau-secondary) 100%); outline: none; transition: background 120ms ease }\n.linteau-slider:disabled { opacity: 0.5 }\n.linteau-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: var(--linteau-primary); border: 2px solid var(--linteau-card); box-shadow: 0 0 0 1px var(--linteau-border); cursor: pointer; transition: transform 120ms ease }\n.linteau-slider::-webkit-slider-thumb:hover { transform: scale(1.15) }\n.linteau-slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--linteau-primary); border: 2px solid var(--linteau-card); cursor: pointer }\n";
40
+ /** Creates a labeled range slider with a live value readout, supporting controlled and uncontrolled usage. */
41
+ export declare function Slider(options: SliderOptions): SliderElement;
@@ -0,0 +1,35 @@
1
+ import type { IconInput } from '../../svg/types';
2
+ /** Options accepted by the `Switch` factory. */
3
+ export interface SwitchOptions {
4
+ /** Label rendered next to the toggle. */
5
+ label: string;
6
+ /** Optional icon rendered before the label. */
7
+ icon?: IconInput;
8
+ /** Controlled checked state. When provided together with `onChange`, you own the state. */
9
+ checked?: boolean;
10
+ /** Uncontrolled initial state, used only if `checked` is omitted. Defaults to `false`. */
11
+ defaultChecked?: boolean;
12
+ /** Disables interaction. Defaults to `false`. */
13
+ disabled?: boolean;
14
+ /** Called whenever the user toggles the switch. */
15
+ onChange?: (checked: boolean) => void;
16
+ }
17
+ /** The runtime control surface attached to every `Switch` element. */
18
+ export interface SwitchApi {
19
+ /** Returns the current checked state. */
20
+ getValue: () => boolean;
21
+ /** Programmatically sets the checked state (does not trigger `onChange`). */
22
+ setValue: (checked: boolean) => void;
23
+ /** Updates the label text. */
24
+ setLabel: (label: string) => void;
25
+ /** Enables/disables the switch. */
26
+ setDisabled: (disabled: boolean) => void;
27
+ /** Detaches the switch from the DOM and its internal listener. */
28
+ destroy: () => void;
29
+ }
30
+ /** A `Switch` is a real `HTMLDivElement` (the row) extended with `SwitchApi`. */
31
+ export type SwitchElement = HTMLDivElement & SwitchApi;
32
+ /** This component's own CSS, colocated and self-injected on first use. */
33
+ export declare const switchCss = "\n.linteau-switch-row { display: flex; align-items: center; justify-content: space-between }\n.linteau-switch { width: 38px; height: 22px; border-radius: 999px; background: var(--linteau-secondary); border: 1px solid var(--linteau-border); padding: 2px; cursor: pointer; display: flex; align-items: center; transition: background 150ms ease }\n.linteau-switch:disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-switch.linteau-checked { background: var(--linteau-primary) }\n.linteau-switch-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--linteau-card); transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1); transform: translateX(0) }\n.linteau-switch.linteau-checked .linteau-switch-thumb { transform: translateX(16px); background: var(--linteau-primary-foreground) }\n";
34
+ /** Creates a labeled on/off toggle, supporting both controlled and uncontrolled usage. */
35
+ export declare function Switch(options: SwitchOptions): SwitchElement;
@@ -0,0 +1,39 @@
1
+ import type { IconInput } from '../../svg/types';
2
+ /** Visual style of a `Toggle`. */
3
+ export type ToggleVariant = 'default' | 'outline';
4
+ /** Sizing preset of a `Toggle`. */
5
+ export type ToggleSize = 'sm' | 'default';
6
+ /** Options accepted by the `Toggle` factory. */
7
+ export interface ToggleOptions {
8
+ /** Visual style. Defaults to `'default'`. */
9
+ variant?: ToggleVariant;
10
+ /** Sizing preset. Defaults to `'default'`. */
11
+ size?: ToggleSize;
12
+ /** Optional icon rendered before the label. */
13
+ icon?: IconInput;
14
+ /** Controlled pressed state. When provided together with `onPressedChange`, you own the state. */
15
+ pressed?: boolean;
16
+ /** Uncontrolled initial pressed state, used only if `pressed` is omitted. Defaults to `false`. */
17
+ defaultPressed?: boolean;
18
+ /** Disables interaction. Defaults to `false`. */
19
+ disabled?: boolean;
20
+ /** Called whenever the user toggles the button. */
21
+ onPressedChange?: (pressed: boolean) => void;
22
+ }
23
+ /** The runtime control surface attached to every `Toggle` element. */
24
+ export interface ToggleApi {
25
+ /** Returns the current pressed state. */
26
+ getPressed: () => boolean;
27
+ /** Programmatically sets the pressed state (does not trigger `onPressedChange`). */
28
+ setPressed: (pressed: boolean) => void;
29
+ /** Enables/disables the toggle. */
30
+ setDisabled: (disabled: boolean) => void;
31
+ /** Detaches the toggle from the DOM and its internal listener. */
32
+ destroy: () => void;
33
+ }
34
+ /** A `Toggle` is a real `HTMLButtonElement` extended with `ToggleApi`. */
35
+ export type ToggleElement = HTMLButtonElement & ToggleApi;
36
+ /** This component's own CSS, colocated and self-injected on first use. */
37
+ export declare const toggleCss = "\n.linteau-toggle {\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 background: transparent;\n color: var(--linteau-muted-foreground);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: background 120ms ease, color 120ms ease, border-color 120ms ease;\n}\n.linteau-toggle-default { padding: 8px 12px }\n.linteau-toggle-sm { padding: 5px 8px; font-size: 12px }\n.linteau-toggle:hover:not(:disabled) { background: var(--linteau-accent); color: var(--linteau-foreground) }\n.linteau-toggle:disabled { opacity: 0.5; cursor: not-allowed }\n.linteau-toggle-outline { border-color: var(--linteau-border) }\n.linteau-toggle.linteau-pressed { background: var(--linteau-accent); color: var(--linteau-foreground) }\n";
38
+ /** Creates a single pressable toggle button -- a two-state control (like a checkbox rendered as a button), useful for toolbar options (bold, italic, view modes). */
39
+ export declare function Toggle(text: string, options?: ToggleOptions): ToggleElement;
@@ -0,0 +1,47 @@
1
+ import type { ToggleSize, ToggleVariant } from './Toggle';
2
+ import type { IconInput } from '../../svg/types';
3
+ /** A single item within a `ToggleGroup`. */
4
+ export interface ToggleGroupItem {
5
+ /** Visible label. */
6
+ label: string;
7
+ /** Unique value identifying this item. */
8
+ value: string;
9
+ /** Optional icon shown before the label. */
10
+ icon?: IconInput;
11
+ /** Disables just this item. Defaults to `false`. */
12
+ disabled?: boolean;
13
+ }
14
+ /** Options accepted by the `ToggleGroup` factory. */
15
+ export interface ToggleGroupOptions {
16
+ /** The items rendered as toggles. */
17
+ items: ToggleGroupItem[];
18
+ /** `'single'` allows one selected item at a time; `'multiple'` allows several. Defaults to `'single'`. */
19
+ type?: 'single' | 'multiple';
20
+ /** Controlled selected value(s) -- a `string` in `'single'` mode, a `string[]` in `'multiple'` mode. */
21
+ value?: string | string[];
22
+ /** Uncontrolled initial value(s), used only if `value` is omitted. */
23
+ defaultValue?: string | string[];
24
+ /** Visual style applied to every item. Defaults to `'outline'`. */
25
+ variant?: ToggleVariant;
26
+ /** Sizing preset applied to every item. Defaults to `'default'`. */
27
+ size?: ToggleSize;
28
+ /** Disables every item. Defaults to `false`. */
29
+ disabled?: boolean;
30
+ /** Called whenever the selection changes via user interaction. */
31
+ onChange?: (value: string | string[]) => void;
32
+ }
33
+ /** The runtime control surface attached to every `ToggleGroup` element. */
34
+ export interface ToggleGroupApi {
35
+ /** Returns the current selected value(s). */
36
+ getValue: () => string | string[];
37
+ /** Programmatically sets the selected value(s) (does not trigger `onChange`). */
38
+ setValue: (value: string | string[]) => void;
39
+ /** Detaches the group from the DOM and its internal listeners. */
40
+ destroy: () => void;
41
+ }
42
+ /** A `ToggleGroup` is a real `HTMLDivElement` extended with `ToggleGroupApi`. */
43
+ export type ToggleGroupElement = HTMLDivElement & ToggleGroupApi;
44
+ /** This component's own CSS. Depends on `.linteau-toggle`, which `Toggle()` registers itself the moment `ToggleGroup` renders its first item. */
45
+ export declare const toggleGroupCss = "\n.linteau-toggle-group { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--linteau-border); border-radius: var(--linteau-radius-sm) }\n";
46
+ /** Creates a group of toggle buttons supporting single- or multiple-selection, useful for view/alignment/format pickers. */
47
+ export declare function ToggleGroup(options: ToggleGroupOptions): ToggleGroupElement;
@@ -0,0 +1,22 @@
1
+ import type { FloatingPlacement } from '../../core/overlay';
2
+ import type { Destroyable } from '../../core/types';
3
+ /** Options accepted by the `Tooltip` factory. */
4
+ export interface TooltipOptions {
5
+ /** Side of the anchor the tooltip appears on. Defaults to `'top'`. */
6
+ placement?: FloatingPlacement;
7
+ /** Milliseconds to wait before showing, after hover/focus starts. Defaults to `200`. */
8
+ delay?: number;
9
+ }
10
+ /**
11
+ * The runtime control surface returned by `Tooltip`. Unlike most components, this is a
12
+ * plain controller -- not an element -- because it attaches behavior to an existing anchor
13
+ * rather than creating a new one to place in your layout.
14
+ */
15
+ export interface TooltipApi extends Destroyable {
16
+ /** Updates the tooltip's text content. */
17
+ setContent: (content: string) => void;
18
+ }
19
+ /** This component's own CSS, colocated and self-injected on first use. */
20
+ export declare const tooltipCss = "\n.linteau-tooltip { position: fixed; z-index: 1300; background: var(--linteau-foreground); color: var(--linteau-background); font-size: 11px; font-weight: 500; padding: 5px 8px; border-radius: var(--linteau-radius-sm); pointer-events: none; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3) }\n";
21
+ /** Attaches a floating text tooltip to `anchor`, shown on hover/focus. */
22
+ export declare function Tooltip(anchor: HTMLElement, content: string, options?: TooltipOptions): TooltipApi;
@@ -0,0 +1,6 @@
1
+ /** Every class name Linteau generates starts with this prefix, so it can never collide with a consumer's own CSS. */
2
+ export declare const PREFIX: 'linteau-';
3
+ /** Prefixes a class-name fragment with the library namespace, e.g. `px('button')` -> `'linteau-button'`. */
4
+ export declare function px(part: string): string;
5
+ /** Joins class-name fragments, dropping any falsy value. Handy for conditional classes. */
6
+ export declare function cx(...parts: Array<string | false | null | undefined>): string;
@@ -0,0 +1,2 @@
1
+ /** Replaces `target`'s children with either an appended element or plain text. Shared by every component with a "content" slot. */
2
+ export declare function fillContent(target: HTMLElement, content: HTMLElement | string): void;
@@ -0,0 +1,34 @@
1
+ /** A listener function subscribed to a single event of type `T`. */
2
+ export type Listener<T> = (payload: T) => void;
3
+ /** A minimal, fully-typed event emitter used internally by stateful components. */
4
+ export interface Emitter<TEvents extends Record<string, unknown>> {
5
+ /** Subscribes to an event, returning an unsubscribe function. */
6
+ on<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): () => void;
7
+ /** Removes a previously-subscribed listener. */
8
+ off<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): void;
9
+ /** Synchronously notifies every listener subscribed to `event`. */
10
+ emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void;
11
+ /** Removes every listener for every event. */
12
+ clear: () => void;
13
+ }
14
+ /** Creates a standalone, strongly-typed event emitter. */
15
+ export declare function createEmitter<TEvents extends Record<string, unknown>>(): Emitter<TEvents>;
16
+ /**
17
+ * Merges a strongly-typed controller API onto a real DOM element, producing
18
+ * a single value that IS a valid Node (append it anywhere) AND a fully
19
+ * controllable component instance (no wrapper object required).
20
+ *
21
+ * This is the pattern every Linteau component factory returns through.
22
+ *
23
+ * @typeParam TElement - The native element type being extended, e.g. `HTMLButtonElement`.
24
+ * @typeParam TApi - The extra methods/properties to attach.
25
+ * @param element - The native element instance created by the component.
26
+ * @param api - The controller methods/properties to merge onto the element.
27
+ * @returns The same element instance, typed as `TElement & TApi`.
28
+ */
29
+ export declare function attachController<TElement extends HTMLElement, TApi extends object>(element: TElement, api: TApi): TElement & TApi;
30
+ /** A small helper for collecting and running teardown callbacks in `destroy()` implementations. */
31
+ export declare function createCleanup(): {
32
+ add: (fn: () => void) => void;
33
+ run: () => void;
34
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * True when running in an environment with a real `document`/`window`
3
+ * (browser, or Node/Bun with a DOM shim like `happy-dom`/`linkedom`).
4
+ */
5
+ export declare function isBrowser(): boolean;
6
+ /**
7
+ * Guards a component factory against being called without a DOM, throwing
8
+ * one clear, actionable error instead of a cryptic `ReferenceError`.
9
+ *
10
+ * @param componentName - Name shown in the thrown error, e.g. `'Button'`.
11
+ */
12
+ export declare function assertDom(componentName: string): void;
13
+ /** Tiny `document.createElement` wrapper that also applies an initial class name. */
14
+ export declare function el<K extends keyof HTMLElementTagNameMap>(tag: K, className?: string): HTMLElementTagNameMap[K];
@@ -0,0 +1,14 @@
1
+ /** Placement of a floating element relative to its anchor. */
2
+ export type FloatingPlacement = 'top' | 'bottom' | 'left' | 'right';
3
+ /**
4
+ * Calls `callback` when a mouse press lands outside every element in `targets`.
5
+ * Accepts one or more elements so a floating panel and its anchor can both be excluded.
6
+ * @returns An unsubscribe function.
7
+ */
8
+ export declare function onClickOutside(targets: HTMLElement | HTMLElement[], callback: () => void): () => void;
9
+ /** Calls `callback` whenever the Escape key is pressed. @returns An unsubscribe function. */
10
+ export declare function onEscapeKey(callback: () => void): () => void;
11
+ /** Locks page scroll (used by modal-like overlays). @returns A function that restores the previous overflow value. */
12
+ export declare function lockBodyScroll(): () => void;
13
+ /** Positions `floating` next to `anchor`, clamped to stay inside the viewport. */
14
+ export declare function positionFloating(anchor: HTMLElement, floating: HTMLElement, placement?: FloatingPlacement, gap?: number): void;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Injects a single CSS block exactly once, keyed by `key`. Safe to call from every
3
+ * instance of every component -- the second and later calls for the same key are no-ops.
4
+ *
5
+ * Each component factory calls this with its own colocated CSS string right after
6
+ * `assertDom`, so consumers never import or link any CSS file themselves -- and an app
7
+ * that only imports `Button` never pays for `Dialog`'s or `Table`'s styles.
8
+ *
9
+ * @param key - A stable identifier for this CSS block (typically the component name). Shared blocks (e.g. field-base) reuse the same key across multiple components to dedupe.
10
+ * @param css - The raw CSS text to inject.
11
+ */
12
+ export declare function ensureComponentStyles(key: string, css: string): void;