@svelte-atoms/core 1.0.0-alpha.23 → 1.0.0-alpha.25
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/README.md +645 -645
- package/dist/components/accordion/accordion-root.svelte.d.ts +2 -2
- package/dist/components/alert/alert-actions.svelte.d.ts +1 -0
- package/dist/components/alert/alert-close-button.svelte.d.ts +1 -0
- package/dist/components/alert/alert-content.svelte.d.ts +1 -0
- package/dist/components/atom/html-atom.svelte +151 -4
- package/dist/components/atom/html-atom.svelte.d.ts +4 -2
- package/dist/components/atom/types.d.ts +7 -0
- package/dist/components/button/button.stories.svelte +57 -17
- package/dist/components/button/button.stories.svelte.d.ts +6 -14
- package/dist/components/checkbox/checkbox.svelte.d.ts +1 -1
- package/dist/components/combobox/combobox-root.svelte.d.ts +2 -2
- package/dist/components/datagrid/datagrid.stories.svelte +75 -75
- package/dist/components/drawer/drawer-backdrop.svelte.d.ts +1 -0
- package/dist/components/icon/icon.svelte.d.ts +1 -0
- package/dist/components/input/input-placeholder.svelte +56 -56
- package/dist/components/input/input-placeholder.svelte.d.ts +1 -0
- package/dist/components/input/input-root.svelte +79 -79
- package/dist/components/input/input-root.svelte.d.ts +1 -0
- package/dist/components/input/input-value.svelte +113 -113
- package/dist/components/input/input-value.svelte.d.ts +1 -1
- package/dist/components/input/input.stories.svelte +38 -38
- package/dist/components/label/label.svelte.d.ts +1 -0
- package/dist/components/layer/layer-inner.svelte.d.ts +1 -0
- package/dist/components/layer/layer-root.svelte.d.ts +1 -0
- package/dist/components/popover/popover-arrow.svelte.d.ts +1 -0
- package/dist/components/portal/portal-inner.svelte.d.ts +1 -0
- package/dist/components/portal/portal-root.svelte.d.ts +1 -0
- package/dist/components/portal/teleport.svelte.d.ts +1 -0
- package/dist/components/radio/radio.svelte.d.ts +2 -2
- package/dist/components/root/root.svelte +121 -103
- package/dist/components/root/root.svelte.d.ts +1 -0
- package/dist/components/stack/stack-root.svelte.d.ts +1 -0
- package/dist/components/toast/toast-description.svelte.d.ts +1 -0
- package/dist/components/toast/toast-root.svelte.d.ts +1 -0
- package/dist/components/toast/toast-title.svelte.d.ts +1 -0
- package/dist/components/tree/tree-header.svelte.d.ts +1 -0
- package/dist/context/preset.svelte.d.ts +3 -0
- package/dist/runes/index.d.ts +3 -0
- package/dist/runes/index.js +3 -0
- package/dist/runes/reduced-motion.svelte.d.ts +23 -0
- package/dist/runes/reduced-motion.svelte.js +41 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/variant.d.ts +213 -0
- package/dist/utils/variant.js +137 -0
- package/llm/composition.md +395 -0
- package/llm/crafting.md +838 -0
- package/llm/motion.md +970 -0
- package/llm/philosophy.md +23 -0
- package/llm/preset-variant-integration.md +516 -0
- package/llm/preset.md +383 -0
- package/llm/styling.md +216 -0
- package/llm/usage.md +46 -0
- package/llm/variants.md +712 -0
- package/package.json +2 -1
|
@@ -14,7 +14,7 @@ declare function $$render<B extends Base = Base>(): {
|
|
|
14
14
|
checkedContent?: any;
|
|
15
15
|
} & Record<string, any>;
|
|
16
16
|
exports: {};
|
|
17
|
-
bindings: "
|
|
17
|
+
bindings: "value" | "group";
|
|
18
18
|
slots: {};
|
|
19
19
|
events: {};
|
|
20
20
|
};
|
|
@@ -22,7 +22,7 @@ declare class __sveltets_Render<B extends Base = Base> {
|
|
|
22
22
|
props(): ReturnType<typeof $$render<B>>['props'];
|
|
23
23
|
events(): ReturnType<typeof $$render<B>>['events'];
|
|
24
24
|
slots(): ReturnType<typeof $$render<B>>['slots'];
|
|
25
|
-
bindings(): "
|
|
25
|
+
bindings(): "value" | "group";
|
|
26
26
|
exports(): {};
|
|
27
27
|
}
|
|
28
28
|
interface $$IsomorphicComponent {
|
|
@@ -1,103 +1,121 @@
|
|
|
1
|
-
<script module lang="ts">
|
|
2
|
-
export type RootPortals = 'root.l0' | 'root.l1' | 'root.l2' | 'root.l3';
|
|
3
|
-
</script>
|
|
4
|
-
|
|
5
|
-
<script lang="ts">
|
|
6
|
-
import { cn, defineState, defineProperty } from '../../utils';
|
|
7
|
-
import { RootBond, RootBondState, type RootStateProps } from './bond.svelte';
|
|
8
|
-
import { Portal, ActivePortal, Portals } from '../portal';
|
|
9
|
-
import { Stack } from '../stack';
|
|
10
|
-
import { HtmlAtom } from '../atom';
|
|
11
|
-
import { HtmlElement, MathmlElement, SvgElement } from '../element';
|
|
12
|
-
|
|
13
|
-
let {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<Portal.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export type RootPortals = 'root.l0' | 'root.l1' | 'root.l2' | 'root.l3';
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { cn, defineState, defineProperty } from '../../utils';
|
|
7
|
+
import { RootBond, RootBondState, type RootStateProps } from './bond.svelte';
|
|
8
|
+
import { Portal, ActivePortal, Portals } from '../portal';
|
|
9
|
+
import { Stack } from '../stack';
|
|
10
|
+
import { HtmlAtom } from '../atom';
|
|
11
|
+
import { HtmlElement, MathmlElement, SvgElement } from '../element';
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
class: klass = '',
|
|
15
|
+
base = undefined,
|
|
16
|
+
children = undefined,
|
|
17
|
+
portals = undefined,
|
|
18
|
+
...restProps
|
|
19
|
+
} = $props();
|
|
20
|
+
|
|
21
|
+
let html: typeof HtmlElement | undefined = HtmlElement;
|
|
22
|
+
let svg: typeof SvgElement | undefined = undefined;
|
|
23
|
+
let mathml: typeof MathmlElement | undefined = undefined;
|
|
24
|
+
|
|
25
|
+
type Renderers = {
|
|
26
|
+
html?: typeof HtmlElement;
|
|
27
|
+
svg?: typeof SvgElement;
|
|
28
|
+
mathml?: typeof MathmlElement;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const renderers = defineState<Renderers>([
|
|
32
|
+
defineProperty('html', () => {
|
|
33
|
+
if (!html) {
|
|
34
|
+
import('../element/html-element.svelte').then((mod) => {
|
|
35
|
+
html = mod.default;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return html;
|
|
40
|
+
}),
|
|
41
|
+
defineProperty('svg', () => {
|
|
42
|
+
if (!svg) {
|
|
43
|
+
import('../element/svg-element.svelte').then((mod) => {
|
|
44
|
+
svg = mod.default;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return svg;
|
|
49
|
+
}),
|
|
50
|
+
defineProperty('mathml', () => {
|
|
51
|
+
if (!mathml) {
|
|
52
|
+
import('../element/mathml-element.svelte').then((mod) => {
|
|
53
|
+
mathml = mod.default;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return mathml;
|
|
58
|
+
})
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
const bondProps = defineState<RootStateProps>([defineProperty('renderers', () => renderers)]);
|
|
62
|
+
|
|
63
|
+
const bondState = new RootBondState(() => bondProps);
|
|
64
|
+
const bond = new RootBond(bondState).share();
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<Portals id="root">
|
|
68
|
+
<HtmlAtom
|
|
69
|
+
{@attach (node) => {
|
|
70
|
+
bond.rootElement = node;
|
|
71
|
+
}}
|
|
72
|
+
{base}
|
|
73
|
+
preset="root"
|
|
74
|
+
class={cn(
|
|
75
|
+
'atom-root bg-background text-foreground relative flex w-full flex-1 flex-col items-start font-sans',
|
|
76
|
+
'$preset',
|
|
77
|
+
klass
|
|
78
|
+
)}
|
|
79
|
+
{...restProps}
|
|
80
|
+
>
|
|
81
|
+
{#if portals}
|
|
82
|
+
{@render portals?.()}
|
|
83
|
+
{:else}
|
|
84
|
+
<Portal.Outer
|
|
85
|
+
base={Stack.Item}
|
|
86
|
+
id="root.l0"
|
|
87
|
+
class="pointer-events-none absolute inset-0 z-10 overflow-hidden"
|
|
88
|
+
>
|
|
89
|
+
<Portal.Inner />
|
|
90
|
+
</Portal.Outer>
|
|
91
|
+
|
|
92
|
+
<Portal.Outer
|
|
93
|
+
base={Stack.Item}
|
|
94
|
+
id="root.l1"
|
|
95
|
+
class="pointer-events-none absolute inset-0 z-10 overflow-hidden"
|
|
96
|
+
>
|
|
97
|
+
<Portal.Inner />
|
|
98
|
+
</Portal.Outer>
|
|
99
|
+
|
|
100
|
+
<Portal.Outer
|
|
101
|
+
base={Stack.Item}
|
|
102
|
+
id="root.l2"
|
|
103
|
+
class="pointer-events-none absolute inset-0 z-10 overflow-hidden"
|
|
104
|
+
>
|
|
105
|
+
<Portal.Inner />
|
|
106
|
+
</Portal.Outer>
|
|
107
|
+
|
|
108
|
+
<Portal.Outer
|
|
109
|
+
base={Stack.Item}
|
|
110
|
+
id="root.l3"
|
|
111
|
+
class="pointer-events-none absolute inset-0 z-10 overflow-hidden"
|
|
112
|
+
>
|
|
113
|
+
<Portal.Inner />
|
|
114
|
+
</Portal.Outer>
|
|
115
|
+
{/if}
|
|
116
|
+
|
|
117
|
+
<ActivePortal id="root.l0">
|
|
118
|
+
{@render children?.()}
|
|
119
|
+
</ActivePortal>
|
|
120
|
+
</HtmlAtom>
|
|
121
|
+
</Portals>
|
|
@@ -18,6 +18,7 @@ declare function $$render<E extends keyof HTMLElementTagNameMap = 'div', B exten
|
|
|
18
18
|
bond?: import("../..").Bond;
|
|
19
19
|
base?: B | undefined;
|
|
20
20
|
preset?: import("../..").ModuleName | (string & {});
|
|
21
|
+
variants?: import("../..").VariantDefinition<any> | ((bond: import("../..").Bond, variantProps: Record<string, any>) => Record<string, any>);
|
|
21
22
|
} & HTMLAttributes<ElementType<E>>;
|
|
22
23
|
exports: {};
|
|
23
24
|
bindings: "";
|
|
@@ -25,6 +25,7 @@ declare function $$render<T extends keyof HTMLElementTagNameMap>(): {
|
|
|
25
25
|
bond?: import("../..").Bond;
|
|
26
26
|
base?: import("../atom").ComponentBase | import("../atom").SnippetBase | undefined;
|
|
27
27
|
preset?: import("../..").ModuleName | (string & {});
|
|
28
|
+
variants?: import("../..").VariantDefinition<any> | ((bond: import("../..").Bond, variantProps: Record<string, any>) => Record<string, any>);
|
|
28
29
|
} & {
|
|
29
30
|
as?: T | undefined;
|
|
30
31
|
children?: Snippet<[{
|
|
@@ -30,6 +30,7 @@ declare function $$render<T extends keyof HTMLElementTagNameMap>(): {
|
|
|
30
30
|
bond?: import("../..").Bond;
|
|
31
31
|
base?: import("../atom").ComponentBase | import("../atom").SnippetBase | undefined;
|
|
32
32
|
preset?: import("../..").ModuleName | (string & {});
|
|
33
|
+
variants?: import("../../utils").VariantDefinition<any> | ((bond: import("../..").Bond, variantProps: Record<string, any>) => Record<string, any>);
|
|
33
34
|
} & {
|
|
34
35
|
as?: T | undefined;
|
|
35
36
|
open?: boolean;
|
|
@@ -26,6 +26,7 @@ declare function $$render<T extends keyof HTMLElementTagNameMap>(): {
|
|
|
26
26
|
bond?: import("../..").Bond;
|
|
27
27
|
base?: import("../atom").ComponentBase | import("../atom").SnippetBase | undefined;
|
|
28
28
|
preset?: import("../..").ModuleName | (string & {});
|
|
29
|
+
variants?: import("../..").VariantDefinition<any> | ((bond: import("../..").Bond, variantProps: Record<string, any>) => Record<string, any>);
|
|
29
30
|
} & {
|
|
30
31
|
as?: T | undefined;
|
|
31
32
|
class?: string;
|
|
@@ -27,6 +27,7 @@ declare function $$render<E extends keyof HTMLElementTagNameMap = 'div', B exten
|
|
|
27
27
|
bond?: import("../..").Bond;
|
|
28
28
|
base?: B | undefined;
|
|
29
29
|
preset?: import("../..").ModuleName | (string & {});
|
|
30
|
+
variants?: import("../..").VariantDefinition<any> | ((bond: import("../..").Bond, variantProps: Record<string, any>) => Record<string, any>);
|
|
30
31
|
} & {
|
|
31
32
|
class?: string;
|
|
32
33
|
open?: boolean;
|
|
@@ -7,6 +7,9 @@ export type PresetEntryRecord = {
|
|
|
7
7
|
class?: ClassValue;
|
|
8
8
|
as?: string;
|
|
9
9
|
base?: Base;
|
|
10
|
+
variants?: Record<string, Record<string, any>>;
|
|
11
|
+
compounds?: Array<Record<string, any>>;
|
|
12
|
+
defaults?: Record<string, any>;
|
|
10
13
|
};
|
|
11
14
|
export type PresetEntry = (this: Bond | undefined | null, bond: Bond | undefined | null, ...args: any[]) => PresetEntryRecord;
|
|
12
15
|
export type Preset = Record<PresetModuleName, PresetEntry>;
|
package/dist/runes/index.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export { colorScheme, type ColorScheme } from './color-scheme.svelte';
|
|
2
|
+
export { reducedMotion } from './reduced-motion.svelte';
|
|
3
|
+
export { container } from './container.svelte';
|
|
4
|
+
export { type Viewport, viewport } from './viewport.svelte';
|
|
2
5
|
export { mounted } from './lifecycles.svelte';
|
package/dist/runes/index.js
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A rune that tracks the user's motion preferences via the `prefers-reduced-motion` media query.
|
|
3
|
+
*
|
|
4
|
+
* @returns An object with a `current` getter that returns `true` if the user prefers reduced motion, `false` otherwise.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <script>
|
|
9
|
+
* import { reducedMotion } from '@svelte-atoms/core';
|
|
10
|
+
*
|
|
11
|
+
* const motion = reducedMotion();
|
|
12
|
+
* </script>
|
|
13
|
+
*
|
|
14
|
+
* {#if motion.current}
|
|
15
|
+
* <div>Animations disabled</div>
|
|
16
|
+
* {:else}
|
|
17
|
+
* <div class="animated">Animations enabled</div>
|
|
18
|
+
* {/if}
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function reducedMotion(): {
|
|
22
|
+
readonly current: boolean;
|
|
23
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A rune that tracks the user's motion preferences via the `prefers-reduced-motion` media query.
|
|
3
|
+
*
|
|
4
|
+
* @returns An object with a `current` getter that returns `true` if the user prefers reduced motion, `false` otherwise.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <script>
|
|
9
|
+
* import { reducedMotion } from '@svelte-atoms/core';
|
|
10
|
+
*
|
|
11
|
+
* const motion = reducedMotion();
|
|
12
|
+
* </script>
|
|
13
|
+
*
|
|
14
|
+
* {#if motion.current}
|
|
15
|
+
* <div>Animations disabled</div>
|
|
16
|
+
* {:else}
|
|
17
|
+
* <div class="animated">Animations enabled</div>
|
|
18
|
+
* {/if}
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function reducedMotion() {
|
|
22
|
+
let prefersReduced = $state(false);
|
|
23
|
+
$effect(() => {
|
|
24
|
+
if (typeof window === 'undefined')
|
|
25
|
+
return;
|
|
26
|
+
const handleChange = (ev) => {
|
|
27
|
+
prefersReduced = ev.matches;
|
|
28
|
+
};
|
|
29
|
+
const media = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
30
|
+
media.addEventListener('change', handleChange);
|
|
31
|
+
prefersReduced = media.matches;
|
|
32
|
+
return () => {
|
|
33
|
+
media.removeEventListener('change', handleChange);
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
get current() {
|
|
38
|
+
return prefersReduced;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { type StateDefiner, defineProperty, defineState } from './state';
|
|
2
|
+
export { defineVariants, type VariantDefinition, type VariantProps, type VariantValue, type ExtractVariants, type VariantPropsType } from './variant';
|
|
2
3
|
import type { ClassValue as SvelteClassValue } from 'svelte/elements';
|
|
3
4
|
export type ClassValueFunction = <T = unknown>(bond: T, ...args: unknown[]) => SvelteClassValue;
|
|
4
5
|
export type ClassValue = SvelteClassValue | ClassValueFunction | undefined;
|
package/dist/utils/index.js
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variant System for @svelte-atoms/core
|
|
3
|
+
*
|
|
4
|
+
* A simple, single-function approach to defining component variants.
|
|
5
|
+
* Define variants once, use everywhere with full type safety and bond state access.
|
|
6
|
+
*
|
|
7
|
+
* Goals:
|
|
8
|
+
* 1. Single function returns all variants for a component
|
|
9
|
+
* 2. Access internal component state (via bond) for reactive variants
|
|
10
|
+
* 3. Return both classes AND other attributes (aria, data, etc.)
|
|
11
|
+
* 4. Type-safe with autocompletion
|
|
12
|
+
* 5. No context, no complexity
|
|
13
|
+
*/
|
|
14
|
+
import type { ClassValue } from 'svelte/elements';
|
|
15
|
+
import type { Bond } from '../shared';
|
|
16
|
+
/**
|
|
17
|
+
* Variant value can be a static value or a function that receives bond
|
|
18
|
+
*/
|
|
19
|
+
export type VariantValue<T = any> = T | ((bond?: Bond | null) => T);
|
|
20
|
+
/**
|
|
21
|
+
* Variant definition - maps variant keys to their possible values
|
|
22
|
+
* Each value can return classes and/or attributes
|
|
23
|
+
*/
|
|
24
|
+
export type VariantDefinition<V extends Record<string, Record<string, any>>> = {
|
|
25
|
+
/** Base classes applied to all variants */
|
|
26
|
+
class?: ClassValue;
|
|
27
|
+
/** Variant definitions - each key maps to possible values */
|
|
28
|
+
variants: V;
|
|
29
|
+
/** Compound variants - apply when multiple conditions match */
|
|
30
|
+
compounds?: Array<Partial<{
|
|
31
|
+
[K in keyof V]: keyof V[K];
|
|
32
|
+
}> & {
|
|
33
|
+
class?: ClassValue;
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
}>;
|
|
36
|
+
/** Default values for variants */
|
|
37
|
+
defaults?: Partial<{
|
|
38
|
+
[K in keyof V]: keyof V[K];
|
|
39
|
+
}>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Props type for variant function
|
|
43
|
+
*/
|
|
44
|
+
export type VariantProps<V extends Record<string, Record<string, any>>> = Partial<{
|
|
45
|
+
[K in keyof V]: keyof V[K];
|
|
46
|
+
}> & {
|
|
47
|
+
bond?: Bond | null;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Define variants for a component
|
|
51
|
+
* Returns a function that takes variant props and returns classes + attributes
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* // Option 1: Static config (no bond access needed)
|
|
56
|
+
* const buttonVariants = defineVariants({
|
|
57
|
+
* class: 'rounded-md font-medium transition-colors',
|
|
58
|
+
* variants: {
|
|
59
|
+
* variant: {
|
|
60
|
+
* primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
61
|
+
* secondary: 'bg-gray-500 text-white hover:bg-gray-600'
|
|
62
|
+
* },
|
|
63
|
+
* size: {
|
|
64
|
+
* sm: 'px-2 py-1 text-sm',
|
|
65
|
+
* md: 'px-4 py-2 text-base',
|
|
66
|
+
* lg: 'px-6 py-3 text-lg'
|
|
67
|
+
* }
|
|
68
|
+
* },
|
|
69
|
+
* compounds: [
|
|
70
|
+
* {
|
|
71
|
+
* variant: 'primary',
|
|
72
|
+
* size: 'lg',
|
|
73
|
+
* class: 'shadow-lg'
|
|
74
|
+
* }
|
|
75
|
+
* ],
|
|
76
|
+
* defaults: {
|
|
77
|
+
* variant: 'primary',
|
|
78
|
+
* size: 'md'
|
|
79
|
+
* }
|
|
80
|
+
* });
|
|
81
|
+
*
|
|
82
|
+
* // Option 2: Dynamic config (with bond access)
|
|
83
|
+
* const buttonVariants = defineVariants((bond) => ({
|
|
84
|
+
* class: 'rounded-md font-medium transition-colors',
|
|
85
|
+
* variants: {
|
|
86
|
+
* variant: {
|
|
87
|
+
* primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
88
|
+
* secondary: 'bg-gray-500 text-white hover:bg-gray-600',
|
|
89
|
+
* danger: bond?.state?.disabled
|
|
90
|
+
* ? 'bg-red-300 text-white'
|
|
91
|
+
* : 'bg-red-500 text-white hover:bg-red-600'
|
|
92
|
+
* },
|
|
93
|
+
* size: {
|
|
94
|
+
* sm: 'px-2 py-1 text-sm',
|
|
95
|
+
* md: 'px-4 py-2 text-base',
|
|
96
|
+
* lg: 'px-6 py-3 text-lg'
|
|
97
|
+
* }
|
|
98
|
+
* },
|
|
99
|
+
* compounds: [
|
|
100
|
+
* {
|
|
101
|
+
* variant: 'primary',
|
|
102
|
+
* size: 'lg',
|
|
103
|
+
* class: 'shadow-lg'
|
|
104
|
+
* }
|
|
105
|
+
* ],
|
|
106
|
+
* defaults: {
|
|
107
|
+
* variant: 'primary',
|
|
108
|
+
* size: 'md'
|
|
109
|
+
* }
|
|
110
|
+
* }));
|
|
111
|
+
*
|
|
112
|
+
* // Usage in component:
|
|
113
|
+
* const props = buttonVariants({ variant: 'primary', size: 'lg', bond });
|
|
114
|
+
* // Returns: { class: '...' }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function defineVariants<V extends Record<string, Record<string, any>>>(config: VariantDefinition<V> | ((bond?: Bond | null) => VariantDefinition<V>)): (bond: Bond, props?: VariantProps<V>) => Record<string, any>;
|
|
118
|
+
/**
|
|
119
|
+
* Example 1: Simple button variants (static config)
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* const buttonVariants = defineVariants({
|
|
123
|
+
* class: 'rounded-md font-medium transition-colors focus:outline-none focus:ring-2',
|
|
124
|
+
* variants: {
|
|
125
|
+
* variant: {
|
|
126
|
+
* primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
127
|
+
* secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
|
|
128
|
+
* ghost: 'hover:bg-gray-100'
|
|
129
|
+
* },
|
|
130
|
+
* size: {
|
|
131
|
+
* sm: 'px-2 py-1 text-sm',
|
|
132
|
+
* md: 'px-4 py-2',
|
|
133
|
+
* lg: 'px-6 py-3 text-lg'
|
|
134
|
+
* }
|
|
135
|
+
* },
|
|
136
|
+
* defaultVariants: {
|
|
137
|
+
* variant: 'primary',
|
|
138
|
+
* size: 'md'
|
|
139
|
+
* }
|
|
140
|
+
* });
|
|
141
|
+
*
|
|
142
|
+
* // In component:
|
|
143
|
+
* let { variant, size, ...rest } = $props();
|
|
144
|
+
* const variantProps = buttonVariants({ variant, size });
|
|
145
|
+
*
|
|
146
|
+
* <button class={variantProps.class} {...rest}>Click me</button>
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
/**
|
|
150
|
+
* Example 2: Reactive variants with bond state (function-based config)
|
|
151
|
+
*
|
|
152
|
+
* ```ts
|
|
153
|
+
* const buttonVariants = defineVariants((bond) => ({
|
|
154
|
+
* class: 'rounded-md font-medium transition-colors',
|
|
155
|
+
* variants: {
|
|
156
|
+
* variant: {
|
|
157
|
+
* primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
158
|
+
* secondary: 'bg-gray-500 text-white hover:bg-gray-600',
|
|
159
|
+
* // Access bond in the config function itself
|
|
160
|
+
* danger: bond?.state?.disabled
|
|
161
|
+
* ? 'bg-red-300 text-white'
|
|
162
|
+
* : 'bg-red-500 text-white hover:bg-red-600'
|
|
163
|
+
* },
|
|
164
|
+
* size: {
|
|
165
|
+
* sm: 'px-2 py-1 text-sm',
|
|
166
|
+
* md: 'px-4 py-2',
|
|
167
|
+
* lg: 'px-6 py-3 text-lg'
|
|
168
|
+
* }
|
|
169
|
+
* },
|
|
170
|
+
* defaults: {
|
|
171
|
+
* variant: 'primary',
|
|
172
|
+
* size: 'md'
|
|
173
|
+
* }
|
|
174
|
+
* }));
|
|
175
|
+
*
|
|
176
|
+
* // In component:
|
|
177
|
+
* const bond = ButtonBond.get();
|
|
178
|
+
* const variantProps = buttonVariants({ variant: 'danger', size: 'md', bond });
|
|
179
|
+
*
|
|
180
|
+
* <button class={variantProps.class}>Click me</button>
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
/**
|
|
184
|
+
* Example 3: Accordion with per-variant bond access
|
|
185
|
+
*
|
|
186
|
+
* ```ts
|
|
187
|
+
* const accordionVariants = defineVariants({
|
|
188
|
+
* class: 'border rounded-md transition-all',
|
|
189
|
+
* variants: {
|
|
190
|
+
* state: {
|
|
191
|
+
* // Each variant can also be a function receiving bond
|
|
192
|
+
* open: (bond) => ({
|
|
193
|
+
* class: bond?.state?.isOpen ? 'bg-blue-50 border-blue-200' : 'bg-white',
|
|
194
|
+
* 'aria-expanded': bond?.state?.isOpen,
|
|
195
|
+
* 'data-state': bond?.state?.isOpen ? 'open' : 'closed'
|
|
196
|
+
* }),
|
|
197
|
+
* disabled: (bond) => ({
|
|
198
|
+
* class: bond?.state?.disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer',
|
|
199
|
+
* 'aria-disabled': bond?.state?.disabled
|
|
200
|
+
* })
|
|
201
|
+
* }
|
|
202
|
+
* }
|
|
203
|
+
* });
|
|
204
|
+
*
|
|
205
|
+
* // In component:
|
|
206
|
+
* const bond = AccordionBond.get();
|
|
207
|
+
* const variantProps = accordionVariants({ state: 'open', bond });
|
|
208
|
+
*
|
|
209
|
+
* <div {...variantProps}>Content</div>
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export type ExtractVariants<T extends (...args: any[]) => any> = Parameters<T>[0];
|
|
213
|
+
export type VariantPropsType<T> = T extends VariantDefinition<infer V> ? VariantProps<V> : Record<string, any>;
|