soltana-ui 0.1.0

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 (104) hide show
  1. package/README.md +158 -0
  2. package/dist/config/index.d.ts +3 -0
  3. package/dist/config/index.js +7 -0
  4. package/dist/config/register.d.ts +27 -0
  5. package/dist/config/stylesheet.d.ts +13 -0
  6. package/dist/config/types.d.ts +177 -0
  7. package/dist/config/types.js +7 -0
  8. package/dist/config/validation.d.ts +29 -0
  9. package/dist/config/validation.js +59 -0
  10. package/dist/enhancers/accordion.d.ts +19 -0
  11. package/dist/enhancers/carousel.d.ts +21 -0
  12. package/dist/enhancers/collapsible.d.ts +14 -0
  13. package/dist/enhancers/color-picker.d.ts +20 -0
  14. package/dist/enhancers/combobox.d.ts +17 -0
  15. package/dist/enhancers/context-menu.d.ts +19 -0
  16. package/dist/enhancers/date-picker.d.ts +8 -0
  17. package/dist/enhancers/drawer.d.ts +11 -0
  18. package/dist/enhancers/dropdown.d.ts +17 -0
  19. package/dist/enhancers/hover-card.d.ts +15 -0
  20. package/dist/enhancers/index.d.ts +42 -0
  21. package/dist/enhancers/modal.d.ts +16 -0
  22. package/dist/enhancers/scroll-area.d.ts +14 -0
  23. package/dist/enhancers/tabs.d.ts +26 -0
  24. package/dist/enhancers/test-helpers.d.ts +20 -0
  25. package/dist/enhancers/test-utils.d.ts +10 -0
  26. package/dist/enhancers/toast.d.ts +24 -0
  27. package/dist/enhancers/tooltip.d.ts +15 -0
  28. package/dist/enhancers/tree.d.ts +24 -0
  29. package/dist/enhancers/utils/click-away.d.ts +7 -0
  30. package/dist/enhancers/utils/create-overlay-enhancer.d.ts +14 -0
  31. package/dist/enhancers/utils/focus-trap.d.ts +9 -0
  32. package/dist/enhancers/utils/generate-id.d.ts +6 -0
  33. package/dist/enhancers/utils/keyboard-nav.d.ts +21 -0
  34. package/dist/enhancers/utils/position.d.ts +30 -0
  35. package/dist/fonts/index.d.ts +20 -0
  36. package/dist/index.d.ts +9 -0
  37. package/dist/init.d.ts +16 -0
  38. package/dist/plugins/index.d.ts +2 -0
  39. package/dist/plugins/index.js +1 -0
  40. package/dist/plugins/postcss-soltana-treeshake.d.ts +10 -0
  41. package/dist/plugins/postcss-soltana-treeshake.js +149 -0
  42. package/dist/plugins/types.d.ts +9 -0
  43. package/dist/plugins/types.js +4 -0
  44. package/dist/soltana-ui.css +1 -0
  45. package/dist/soltana-ui.js +1702 -0
  46. package/dist/soltana-ui.umd.cjs +1 -0
  47. package/package.json +90 -0
  48. package/src/styles/_variables.scss +348 -0
  49. package/src/styles/base/_accessibility.scss +146 -0
  50. package/src/styles/base/_index.scss +12 -0
  51. package/src/styles/base/_register.scss +84 -0
  52. package/src/styles/base/_relief-system.scss +53 -0
  53. package/src/styles/base/_scrollbar.scss +40 -0
  54. package/src/styles/base/_transitions.scss +75 -0
  55. package/src/styles/base/_typography.scss +442 -0
  56. package/src/styles/components/_alert-dialogs.scss +75 -0
  57. package/src/styles/components/_badges.scss +215 -0
  58. package/src/styles/components/_buttons.scss +293 -0
  59. package/src/styles/components/_callouts.scss +99 -0
  60. package/src/styles/components/_cards.scss +97 -0
  61. package/src/styles/components/_carousels.scss +108 -0
  62. package/src/styles/components/_closes.scss +63 -0
  63. package/src/styles/components/_code.scss +75 -0
  64. package/src/styles/components/_collapsibles.scss +61 -0
  65. package/src/styles/components/_color-pickers.scss +211 -0
  66. package/src/styles/components/_comboboxes.scss +88 -0
  67. package/src/styles/components/_context-menus.scss +82 -0
  68. package/src/styles/components/_date-pickers.scss +165 -0
  69. package/src/styles/components/_feedback.scss +354 -0
  70. package/src/styles/components/_figures.scss +52 -0
  71. package/src/styles/components/_heros.scss +83 -0
  72. package/src/styles/components/_hover-cards.scss +55 -0
  73. package/src/styles/components/_images.scss +71 -0
  74. package/src/styles/components/_index.scss +41 -0
  75. package/src/styles/components/_indicators.scss +403 -0
  76. package/src/styles/components/_inputs.scss +409 -0
  77. package/src/styles/components/_layouts.scss +139 -0
  78. package/src/styles/components/_lists.scss +135 -0
  79. package/src/styles/components/_menus.scss +195 -0
  80. package/src/styles/components/_navigation.scss +325 -0
  81. package/src/styles/components/_overlays.scss +233 -0
  82. package/src/styles/components/_scroll-areas.scss +53 -0
  83. package/src/styles/components/_segmented-controls.scss +75 -0
  84. package/src/styles/components/_tables.scss +137 -0
  85. package/src/styles/components/_toasts.scss +111 -0
  86. package/src/styles/components/_toggles.scss +57 -0
  87. package/src/styles/components/_trees.scss +123 -0
  88. package/src/styles/decorative/_classical.scss +196 -0
  89. package/src/styles/decorative/_index.scss +7 -0
  90. package/src/styles/finishes/_index.scss +55 -0
  91. package/src/styles/index.scss +30 -0
  92. package/src/styles/reliefs/_index.scss +66 -0
  93. package/src/styles/reliefs/_neumorphic-tables.scss +92 -0
  94. package/src/styles/themes/_dark.scss +130 -0
  95. package/src/styles/themes/_index.scss +3 -0
  96. package/src/styles/themes/_light.scss +122 -0
  97. package/src/styles/themes/_sepia.scss +121 -0
  98. package/src/styles/utilities/_index.scss +13 -0
  99. package/src/styles/utilities/_layout.scss +100 -0
  100. package/src/styles/utilities/_mixins.scss +410 -0
  101. package/src/styles/utilities/_responsive.scss +46 -0
  102. package/src/styles/utilities/_sizing.scss +62 -0
  103. package/src/styles/utilities/_spacing.scss +12 -0
  104. package/src/styles/utilities/_visual.scss +436 -0
@@ -0,0 +1,15 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ export declare const HOVER_CARD_SELECTOR = "[data-sol-hover-card]";
3
+ /**
4
+ * Enhance all `[data-sol-hover-card]` elements with hover-triggered
5
+ * floating card behavior.
6
+ *
7
+ * Expected structure:
8
+ * ```html
9
+ * <div data-sol-hover-card class="hover-card">
10
+ * <span class="hover-card-trigger">Hover me</span>
11
+ * <div class="hover-card-content">Rich content</div>
12
+ * </div>
13
+ * ```
14
+ */
15
+ export declare function initHoverCards(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,42 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ import { initModals } from './modal.js';
3
+ import { initTabs } from './tabs.js';
4
+ import { initTooltips } from './tooltip.js';
5
+ import { initAccordions } from './accordion.js';
6
+ import { initDropdowns } from './dropdown.js';
7
+ import { initDrawers } from './drawer.js';
8
+ import { initToasts, showToast, dismissToast } from './toast.js';
9
+ import { initCollapsibles } from './collapsible.js';
10
+ import { initComboboxes } from './combobox.js';
11
+ import { initHoverCards } from './hover-card.js';
12
+ import { initContextMenus } from './context-menu.js';
13
+ import { initCarousels } from './carousel.js';
14
+ import { initScrollAreas } from './scroll-area.js';
15
+ import { initDatePickers } from './date-picker.js';
16
+ import { initColorPickers } from './color-picker.js';
17
+ import { initTrees } from './tree.js';
18
+ export { initModals, initTabs, initTooltips };
19
+ export { initAccordions, initDropdowns, initDrawers, initToasts };
20
+ export { showToast, dismissToast };
21
+ export { initCollapsibles, initComboboxes, initHoverCards };
22
+ export { initContextMenus, initCarousels, initScrollAreas };
23
+ export { initDatePickers, initColorPickers, initTrees };
24
+ export { MODAL_SELECTOR, MODAL_OPEN_SELECTOR } from './modal.js';
25
+ export { TABS_SELECTOR } from './tabs.js';
26
+ export { TOOLTIP_SELECTOR } from './tooltip.js';
27
+ export { ACCORDION_SELECTOR } from './accordion.js';
28
+ export { DROPDOWN_SELECTOR } from './dropdown.js';
29
+ export { DRAWER_SELECTOR, DRAWER_OPEN_SELECTOR } from './drawer.js';
30
+ export { TOAST_CONTAINER_SELECTOR } from './toast.js';
31
+ export { COLLAPSIBLE_SELECTOR } from './collapsible.js';
32
+ export { COMBOBOX_SELECTOR } from './combobox.js';
33
+ export { HOVER_CARD_SELECTOR } from './hover-card.js';
34
+ export { CONTEXT_MENU_SELECTOR } from './context-menu.js';
35
+ export { CAROUSEL_SELECTOR } from './carousel.js';
36
+ export { SCROLL_AREA_SELECTOR } from './scroll-area.js';
37
+ export { DATE_PICKER_SELECTOR } from './date-picker.js';
38
+ export { COLOR_PICKER_SELECTOR } from './color-picker.js';
39
+ export { TREE_SELECTOR } from './tree.js';
40
+ export type { ToastOptions, ToastType, ToastPosition } from './toast.js';
41
+ /** Initialize all enhancers. Call after DOM content is loaded. */
42
+ export declare function initAll(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,16 @@
1
+ export declare const MODAL_SELECTOR = "[data-sol-modal]";
2
+ export declare const MODAL_OPEN_SELECTOR = "[data-modal-open]";
3
+ /**
4
+ * Enhance all `[data-sol-modal]` elements with open/close, focus trapping,
5
+ * Escape key, and backdrop click behavior.
6
+ *
7
+ * Open triggers: elements with `[data-modal-open="<modal-id>"]`.
8
+ * Close triggers: elements with `[data-modal-close]` inside the modal.
9
+ * Adds the `.sol-modal-open` class to `document.body` while any modal is open
10
+ * to prevent background scrolling.
11
+ *
12
+ * @param options - Optional scoping and selector overrides.
13
+ * @returns Cleanup handle — call `destroy()` to remove all listeners.
14
+ * Re-calling `initModals()` implicitly cleans up previous listeners.
15
+ */
16
+ export declare const initModals: (options?: import('../index.js').EnhancerOptions) => import('../index.js').EnhancerCleanup;
@@ -0,0 +1,14 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ export declare const SCROLL_AREA_SELECTOR = "[data-sol-scroll-area]";
3
+ /**
4
+ * Enhance all `[data-sol-scroll-area]` elements with auto-hiding
5
+ * scrollbar visibility on scroll.
6
+ *
7
+ * Expected structure:
8
+ * ```html
9
+ * <div data-sol-scroll-area class="scroll-area" style="max-height: 20rem;">
10
+ * <!-- Scrollable content -->
11
+ * </div>
12
+ * ```
13
+ */
14
+ export declare function initScrollAreas(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,26 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ export declare const TABS_SELECTOR = "[data-sol-tabs]";
3
+ /**
4
+ * Enhance all `[data-sol-tabs]` elements with tab switching, keyboard
5
+ * navigation, and ARIA attributes.
6
+ *
7
+ * Expected structure:
8
+ * ```html
9
+ * <div data-sol-tabs>
10
+ * <div role="tablist">
11
+ * <button role="tab" aria-selected="true">Tab 1</button>
12
+ * <button role="tab">Tab 2</button>
13
+ * </div>
14
+ * <div role="tabpanel">Panel 1</div>
15
+ * <div role="tabpanel" hidden>Panel 2</div>
16
+ * </div>
17
+ * ```
18
+ *
19
+ * Mutates each tab container by setting `id`, `aria-controls`, and
20
+ * `aria-labelledby` attributes on tabs and panels.
21
+ *
22
+ * @param options - Optional scoping and selector overrides.
23
+ * @returns Cleanup handle — call `destroy()` to remove all listeners.
24
+ * Re-calling `initTabs()` implicitly cleans up previous listeners.
25
+ */
26
+ export declare function initTabs(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,20 @@
1
+ import { vi } from 'vitest';
2
+ import { EnhancerCleanup } from '../config/types.js';
3
+ /**
4
+ * Verifies that re-calling an enhancer init function does not duplicate listeners.
5
+ * Tests the singleton behavior pattern used across all enhancers.
6
+ *
7
+ * @param initFn - The enhancer init function to test (e.g., initTabs, initModals)
8
+ * @param setupDOM - Callback to create the necessary DOM structure and return the trigger element
9
+ * @param verify - Callback to verify the expected behavior after triggering
10
+ */
11
+ export declare function testSingletonBehavior(initFn: () => EnhancerCleanup, setupDOM: () => HTMLElement, verify: (trigger: HTMLElement) => void): void;
12
+ /**
13
+ * Mocks getBoundingClientRect on an HTML element with default positioning values.
14
+ * Useful for tests that require element dimensions and positioning (e.g., tooltips, popovers).
15
+ *
16
+ * @param element - The element to mock getBoundingClientRect on
17
+ * @param overrides - Optional partial DOMRect properties to override defaults
18
+ * @returns The vitest spy instance
19
+ */
20
+ export declare function mockBoundingClientRect(element: HTMLElement, overrides?: Partial<DOMRect>): ReturnType<typeof vi.spyOn>;
@@ -0,0 +1,10 @@
1
+ type InitFn = (opts?: {
2
+ root?: Element;
3
+ }) => {
4
+ destroy: () => void;
5
+ };
6
+ export declare function testDestroyPreventsInteraction(init: InitFn, createDOM: () => HTMLElement, triggerAction: (el: HTMLElement) => void, verifyInactive: (el: HTMLElement) => void): void;
7
+ export declare function testIdempotentInit(init: InitFn, createDOM: () => HTMLElement, act: (el: HTMLElement) => void): void;
8
+ export declare function testNoMatchGraceful(init: InitFn): void;
9
+ export declare function testCustomRoot(init: InitFn, setupInRoot: (root: HTMLElement) => void, verify: (root: HTMLElement) => void): void;
10
+ export {};
@@ -0,0 +1,24 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ export declare const TOAST_CONTAINER_SELECTOR = "[data-sol-toast-container]";
3
+ export type ToastType = 'success' | 'warning' | 'error' | 'info';
4
+ export type ToastPosition = 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center';
5
+ export interface ToastOptions {
6
+ message: string;
7
+ type?: ToastType;
8
+ duration?: number;
9
+ position?: ToastPosition;
10
+ }
11
+ /**
12
+ * Programmatically show a toast notification.
13
+ * Creates DOM, animates in, and auto-dismisses after `duration` ms (default 5000).
14
+ */
15
+ export declare function showToast(opts: ToastOptions): HTMLElement;
16
+ /**
17
+ * Dismiss a specific toast element.
18
+ */
19
+ export declare function dismissToast(toast: HTMLElement): void;
20
+ /**
21
+ * Enhance all `[data-sol-toast-container]` elements with ARIA attributes
22
+ * and close button behavior on existing toasts.
23
+ */
24
+ export declare function initToasts(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,15 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ export declare const TOOLTIP_SELECTOR = "[data-sol-tooltip]";
3
+ /**
4
+ * Enhance all `[data-sol-tooltip]` elements with positioned tooltips.
5
+ *
6
+ * Attaches mouseenter/focus listeners that show a tooltip, and
7
+ * mouseleave/blur/Escape listeners that hide it. Creates a single shared
8
+ * tooltip element appended to `document.body`.
9
+ *
10
+ * @param options - Optional scoping and selector overrides.
11
+ * @returns Cleanup handle — call `destroy()` to remove all listeners and the
12
+ * tooltip element. Re-calling `initTooltips()` implicitly cleans up
13
+ * previous listeners.
14
+ */
15
+ export declare function initTooltips(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,24 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../config/types.js';
2
+ export declare const TREE_SELECTOR = "[data-sol-tree]";
3
+ /**
4
+ * Enhance all `[data-sol-tree]` elements with expand/collapse and
5
+ * keyboard navigation behavior.
6
+ *
7
+ * Expected structure:
8
+ * ```html
9
+ * <div data-sol-tree class="tree" role="tree">
10
+ * <div class="tree-branch tree-node" role="treeitem">
11
+ * <div class="tree-node-content">
12
+ * <button class="tree-toggle"></button>
13
+ * Folder
14
+ * </div>
15
+ * <div class="tree-children">
16
+ * <div class="tree-leaf tree-node" role="treeitem">
17
+ * <div class="tree-node-content">File</div>
18
+ * </div>
19
+ * </div>
20
+ * </div>
21
+ * </div>
22
+ * ```
23
+ */
24
+ export declare function initTrees(options?: EnhancerOptions): EnhancerCleanup;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Register a callback that fires when a click occurs outside `element`.
3
+ * Uses the provided `AbortSignal` for cleanup — no manual teardown needed.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare function onClickAway(element: HTMLElement, callback: () => void, signal: AbortSignal): void;
@@ -0,0 +1,14 @@
1
+ import { EnhancerCleanup, EnhancerOptions } from '../../config/types.js';
2
+ interface OverlayConfig {
3
+ overlaySelector: string;
4
+ openTriggerAttr: string;
5
+ closeTriggerAttr: string;
6
+ bodyOpenClass: string;
7
+ contentSelector: string;
8
+ childElementsToActivate: string[];
9
+ checkOverlayAsBackdrop: boolean;
10
+ backdropSelector: string;
11
+ setupAria?: (overlay: HTMLElement) => void;
12
+ }
13
+ export declare function createOverlayEnhancer(config: OverlayConfig): (options?: EnhancerOptions) => EnhancerCleanup;
14
+ export {};
@@ -0,0 +1,9 @@
1
+ declare const FOCUSABLE: string;
2
+ /**
3
+ * Trap Tab/Shift+Tab focus within a container element.
4
+ * Call from a `keydown` handler when `e.key === 'Tab'`.
5
+ *
6
+ * @internal
7
+ */
8
+ export declare function trapFocus(container: HTMLElement, event: KeyboardEvent): void;
9
+ export { FOCUSABLE };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generate a short random ID string suitable for ARIA `id` attributes.
3
+ *
4
+ * @internal
5
+ */
6
+ export declare function generateId(): string;
@@ -0,0 +1,21 @@
1
+ /** @internal */
2
+ export interface KeyboardNavOptions {
3
+ /** Container element holding the navigable items. */
4
+ container: HTMLElement;
5
+ /** CSS selector for individual navigable items within the container. */
6
+ itemSelector: string;
7
+ /** Navigation direction supported by the component. */
8
+ orientation: 'vertical' | 'horizontal' | 'both';
9
+ /** Wrap from last item to first (and vice versa). Defaults to true. */
10
+ wrap?: boolean;
11
+ /** Callback invoked when an item is activated (Enter/Space). */
12
+ onActivate?: (item: HTMLElement) => void;
13
+ }
14
+ /**
15
+ * Handle a keydown event for arrow-key navigation within a list of items.
16
+ * Manages `aria-activedescendant`-style focus by calling `focus()` on
17
+ * the target item. Returns true if the event was handled.
18
+ *
19
+ * @internal
20
+ */
21
+ export declare function handleKeyboardNav(options: KeyboardNavOptions, event: KeyboardEvent): boolean;
@@ -0,0 +1,30 @@
1
+ export type Placement = 'top' | 'bottom' | 'left' | 'right';
2
+ export interface PositionOptions {
3
+ /** Anchor element or fixed coordinates (e.g. for context menus). */
4
+ anchor: HTMLElement | {
5
+ x: number;
6
+ y: number;
7
+ };
8
+ /** Floating element to position. */
9
+ floating: HTMLElement;
10
+ /** Preferred placement relative to the anchor. */
11
+ placement: Placement;
12
+ /** Gap between anchor and floating element in pixels. */
13
+ gap?: number;
14
+ /** Minimum distance from viewport edges in pixels. */
15
+ viewportPadding?: number;
16
+ /** Auto-flip to opposite side when clipped by viewport. */
17
+ flip?: boolean;
18
+ }
19
+ export interface PositionResult {
20
+ top: number;
21
+ left: number;
22
+ }
23
+ /**
24
+ * Compute absolute position for a floating element relative to an anchor.
25
+ * Supports viewport clamping and optional flip when the preferred placement
26
+ * would be clipped.
27
+ *
28
+ * @internal
29
+ */
30
+ export declare function computePosition(options: PositionOptions): PositionResult;
@@ -0,0 +1,20 @@
1
+ export declare const DEFAULT_FONT_URL: string;
2
+ /**
3
+ * Inject a font stylesheet (and optional preconnect hints) into `<head>`.
4
+ *
5
+ * Idempotent: only the first call injects elements; subsequent calls are
6
+ * no-ops. The internal loaded flag is reset when `destroy()` is called on
7
+ * the Soltana instance, allowing re-initialization.
8
+ *
9
+ * @param url - Font CSS URL. Defaults to the bundled Google Fonts URL
10
+ * containing Cinzel, Cinzel Decorative, Raleway, and JetBrains
11
+ * Mono. When the URL
12
+ * points to `fonts.googleapis.com`, preconnect links are also
13
+ * injected automatically.
14
+ */
15
+ export declare function loadSoltanaFonts(url?: string): void;
16
+ /**
17
+ * Remove injected font elements and reset loaded flag. Called by destroy().
18
+ * @internal
19
+ */
20
+ export declare function _resetFontLoader(): void;
@@ -0,0 +1,9 @@
1
+ export { initSoltana, DEFAULT_STATE } from './init.js';
2
+ export { BUILT_IN_THEMES, BUILT_IN_RELIEFS, BUILT_IN_FINISHES } from './config/index.js';
3
+ /** Advanced exports for runtime validation, testing, and custom integrations. */
4
+ export { VALID_THEMES, VALID_RELIEFS, VALID_FINISHES } from './config/index.js';
5
+ export type { SoltanaConfig, SoltanaInitOptions, SoltanaInstance, SoltanaChangeDetail, EnhancerCleanup, EnhancerOptions, Theme, Relief, Finish, BuiltInTheme, BuiltInRelief, BuiltInFinish, TierName, SoltanaChangeType, ThemeSeed, RegisterThemeOptions, RegisterReliefOptions, RegisterFinishOptions, TierRegistration, } from './config/index.js';
6
+ export { initModals, initTabs, initTooltips, initAccordions, initDropdowns, initDrawers, initToasts, showToast, dismissToast, initCollapsibles, initComboboxes, initHoverCards, initContextMenus, initCarousels, initScrollAreas, initDatePickers, initColorPickers, initTrees, initAll, MODAL_SELECTOR, MODAL_OPEN_SELECTOR, TABS_SELECTOR, TOOLTIP_SELECTOR, ACCORDION_SELECTOR, DROPDOWN_SELECTOR, DRAWER_SELECTOR, DRAWER_OPEN_SELECTOR, TOAST_CONTAINER_SELECTOR, COLLAPSIBLE_SELECTOR, COMBOBOX_SELECTOR, HOVER_CARD_SELECTOR, CONTEXT_MENU_SELECTOR, CAROUSEL_SELECTOR, SCROLL_AREA_SELECTOR, DATE_PICKER_SELECTOR, COLOR_PICKER_SELECTOR, TREE_SELECTOR, } from './enhancers/index.js';
7
+ export type { ToastOptions, ToastType, ToastPosition } from './enhancers/index.js';
8
+ export { loadSoltanaFonts, DEFAULT_FONT_URL } from './fonts/index.js';
9
+ export declare const version: string;
package/dist/init.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { SoltanaConfig, SoltanaInitOptions, SoltanaInstance } from './config/types.js';
2
+ /**
3
+ * Default tier configuration used when no overrides are provided.
4
+ *
5
+ * - `theme: 'auto'` resolves to `'dark'` or `'light'` via `prefers-color-scheme`.
6
+ * - `relief: 'flat'` is the minimal baseline (no shadow effects).
7
+ * - `finish: 'matte'` is the zero-effect baseline (no blur, sheen, or tint).
8
+ *
9
+ * All built-in tier combinations (3 themes + auto resolver, 4 reliefs, 4 finishes) are valid.
10
+ */
11
+ export declare const DEFAULT_STATE: Readonly<SoltanaConfig>;
12
+ /**
13
+ * Initialize the Soltana design system.
14
+ * Sets data attributes on <html> to activate SCSS theme/relief/finish selectors.
15
+ */
16
+ export declare function initSoltana(userConfig?: Partial<SoltanaConfig & SoltanaInitOptions>): SoltanaInstance;
@@ -0,0 +1,2 @@
1
+ export { default as soltanaTreeshake } from './postcss-soltana-treeshake.js';
2
+ export type { SoltanaTreeshakeOptions, TierConfig } from './types.js';
@@ -0,0 +1 @@
1
+ export { default as soltanaTreeshake } from './postcss-soltana-treeshake.js';
@@ -0,0 +1,10 @@
1
+ import type { Plugin } from 'postcss';
2
+ import type { SoltanaTreeshakeOptions } from './types.js';
3
+ /**
4
+ * PostCSS plugin that strips CSS rules referencing excluded tier values.
5
+ */
6
+ declare function soltanaTreeshake(options?: SoltanaTreeshakeOptions): Plugin;
7
+ declare namespace soltanaTreeshake {
8
+ var postcss: true;
9
+ }
10
+ export default soltanaTreeshake;
@@ -0,0 +1,149 @@
1
+ // ---------------------------------------------------------------------------
2
+ // PostCSS Soltana Tree-Shake Plugin
3
+ // ---------------------------------------------------------------------------
4
+ // Strips CSS rules referencing excluded built-in tier values from the compiled
5
+ // output. Only explicitly excluded built-in values are removed — custom tier
6
+ // values and non-tier selectors are never touched.
7
+ // ---------------------------------------------------------------------------
8
+ import { BUILT_IN_THEMES, BUILT_IN_RELIEFS, BUILT_IN_FINISHES } from '../config/index.js';
9
+ const BUILT_IN = {
10
+ theme: BUILT_IN_THEMES,
11
+ relief: BUILT_IN_RELIEFS,
12
+ finish: BUILT_IN_FINISHES,
13
+ };
14
+ // Maps plural config keys to singular tier names used in selectors
15
+ const TIER_KEY_MAP = {
16
+ themes: 'theme',
17
+ reliefs: 'relief',
18
+ finishes: 'finish',
19
+ };
20
+ // Matches [data-tier='value'] in a selector fragment (global for all occurrences)
21
+ const DATA_ATTR_RE = /\[data-(theme|relief|finish)='([^']+)'\]/g;
22
+ // Matches .tier-value in a selector fragment
23
+ const CLASS_RE = /\.(theme|relief|finish)-([\w-]+)/;
24
+ // Matches [data-tier='value'] that appears inside :not()
25
+ const NEGATED_ATTR_RE = /:not\([^)]*\[data-(theme|relief|finish)='[^']+'\][^)]*\)/g;
26
+ function isTierConfig(value) {
27
+ if (typeof value !== 'object' || value === null)
28
+ return false;
29
+ const obj = value;
30
+ if ('include' in obj && !Array.isArray(obj.include))
31
+ return false;
32
+ if ('exclude' in obj && !Array.isArray(obj.exclude))
33
+ return false;
34
+ return true;
35
+ }
36
+ /**
37
+ * Compute the set of tier values to exclude from output.
38
+ */
39
+ function buildExcludeSet(options) {
40
+ const excludes = new Map();
41
+ for (const [pluralKey, value] of Object.entries(options)) {
42
+ const tier = TIER_KEY_MAP[pluralKey];
43
+ if (!tier || !(tier in BUILT_IN))
44
+ continue;
45
+ if (!isTierConfig(value))
46
+ continue;
47
+ const tierConfig = value;
48
+ const builtIn = BUILT_IN[tier];
49
+ if (tierConfig.include && tierConfig.exclude) {
50
+ console.warn(`[soltana] Tier "${tier}" specifies both include and exclude; exclude will be ignored`);
51
+ }
52
+ let excluded;
53
+ const builtInSet = new Set(builtIn);
54
+ if (tierConfig.include) {
55
+ // Warn on unrecognized include values
56
+ for (const v of tierConfig.include) {
57
+ if (!builtInSet.has(v)) {
58
+ console.warn(`[soltana] Treeshake: include value "${v}" is not a built-in ${tier}`);
59
+ }
60
+ }
61
+ // Exclude everything built-in that isn't in the include list
62
+ const included = new Set(tierConfig.include);
63
+ excluded = builtIn.filter((v) => !included.has(v));
64
+ }
65
+ else if (tierConfig.exclude) {
66
+ // Warn on unrecognized exclude values
67
+ for (const v of tierConfig.exclude) {
68
+ if (!builtInSet.has(v)) {
69
+ console.warn(`[soltana] Treeshake: exclude value "${v}" is not a built-in ${tier}`);
70
+ }
71
+ }
72
+ // Exclude only explicitly listed values (intersected with built-in)
73
+ excluded = tierConfig.exclude.filter((v) => builtInSet.has(v));
74
+ }
75
+ else {
76
+ continue;
77
+ }
78
+ if (excluded.length > 0) {
79
+ excludes.set(tier, new Set(excluded));
80
+ }
81
+ }
82
+ return excludes;
83
+ }
84
+ /**
85
+ * Extract all tier + value pairs from a single selector fragment.
86
+ * Returns an empty array for neutral selectors (no tier reference).
87
+ * Ignores tier references inside :not() — those are negations, not positive matches.
88
+ */
89
+ function extractTierRefs(fragment) {
90
+ const stripped = fragment.replace(NEGATED_ATTR_RE, '');
91
+ const refs = [];
92
+ DATA_ATTR_RE.lastIndex = 0;
93
+ let match;
94
+ while ((match = DATA_ATTR_RE.exec(stripped)) !== null) {
95
+ refs.push({ tier: match[1], value: match[2] });
96
+ }
97
+ const classMatch = CLASS_RE.exec(stripped);
98
+ if (classMatch) {
99
+ refs.push({ tier: classMatch[1], value: classMatch[2] });
100
+ }
101
+ return refs;
102
+ }
103
+ /**
104
+ * Determine whether a selector fragment should be excluded.
105
+ * A fragment is excluded if any of its tier references targets an excluded value.
106
+ */
107
+ function isExcluded(fragment, excludes) {
108
+ const refs = extractTierRefs(fragment);
109
+ if (refs.length === 0)
110
+ return false; // Neutral selector — never excluded
111
+ return refs.some((ref) => {
112
+ const tierExcludes = excludes.get(ref.tier);
113
+ return tierExcludes?.has(ref.value) ?? false;
114
+ });
115
+ }
116
+ /**
117
+ * PostCSS plugin that strips CSS rules referencing excluded tier values.
118
+ */
119
+ function soltanaTreeshake(options = {}) {
120
+ const excludes = buildExcludeSet(options);
121
+ return {
122
+ postcssPlugin: 'postcss-soltana-treeshake',
123
+ Once(root) {
124
+ if (excludes.size === 0)
125
+ return;
126
+ root.walkRules((rule) => {
127
+ // Never touch @keyframes children
128
+ if (rule.parent && 'name' in rule.parent && rule.parent.name === 'keyframes') {
129
+ return;
130
+ }
131
+ const fragments = rule.selectors;
132
+ const kept = [];
133
+ for (const fragment of fragments) {
134
+ if (!isExcluded(fragment, excludes)) {
135
+ kept.push(fragment);
136
+ }
137
+ }
138
+ if (kept.length === 0) {
139
+ rule.remove();
140
+ }
141
+ else if (kept.length < fragments.length) {
142
+ rule.selectors = kept;
143
+ }
144
+ });
145
+ },
146
+ };
147
+ }
148
+ soltanaTreeshake.postcss = true;
149
+ export default soltanaTreeshake;
@@ -0,0 +1,9 @@
1
+ export interface TierConfig {
2
+ include?: string[];
3
+ exclude?: string[];
4
+ }
5
+ export interface SoltanaTreeshakeOptions {
6
+ themes?: TierConfig;
7
+ reliefs?: TierConfig;
8
+ finishes?: TierConfig;
9
+ }
@@ -0,0 +1,4 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Soltana Build Plugin Types
3
+ // ---------------------------------------------------------------------------
4
+ export {};