@urbicon-ui/blocks 6.1.8 → 6.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/dist/components/AreaChart/AreaChart.svelte +2 -6
- package/dist/components/BarChart/BarChart.svelte +2 -6
- package/dist/components/Calendar/Calendar.svelte +12 -10
- package/dist/components/Calendar/calendar.variants.d.ts +2 -1
- package/dist/components/Calendar/index.d.ts +2 -2
- package/dist/components/CommandPalette/CommandPalette.svelte +106 -39
- package/dist/components/CommandPalette/commandPalette.variants.d.ts +3 -7
- package/dist/components/CommandPalette/commandPalette.variants.js +0 -1
- package/dist/components/CommandPalette/index.d.ts +2 -2
- package/dist/components/CompositionBar/CompositionBar.svelte +12 -15
- package/dist/components/CompositionBar/composition-bar.variants.d.ts +3 -1
- package/dist/components/CompositionBar/index.d.ts +2 -2
- package/dist/components/DonutChart/DonutChart.svelte +2 -6
- package/dist/components/EmptyState/EmptyState.svelte +8 -9
- package/dist/components/EmptyState/emptyState.variants.d.ts +3 -1
- package/dist/components/EmptyState/index.d.ts +3 -3
- package/dist/components/FileUpload/FileUpload.svelte +17 -17
- package/dist/components/FileUpload/fileUpload.variants.d.ts +3 -11
- package/dist/components/FileUpload/fileUpload.variants.js +0 -5
- package/dist/components/FileUpload/index.d.ts +4 -3
- package/dist/components/Guide/Guide.svelte +5 -8
- package/dist/components/Guide/GuideArticle.svelte +5 -8
- package/dist/components/Guide/GuideBeacon.svelte +5 -8
- package/dist/components/Guide/GuideHint.svelte +5 -8
- package/dist/components/Guide/GuideMarker.svelte +5 -8
- package/dist/components/Guide/GuideMention.svelte +5 -8
- package/dist/components/Guide/GuidePanel.svelte +5 -8
- package/dist/components/Guide/guide.variants.d.ts +9 -1
- package/dist/components/Guide/index.d.ts +12 -9
- package/dist/components/LineChart/LineChart.svelte +2 -6
- package/dist/components/Planner/Planner.svelte +7 -10
- package/dist/components/Planner/index.d.ts +4 -4
- package/dist/components/Planner/planner.variants.d.ts +3 -1
- package/dist/components/Sankey/Sankey.svelte +8 -9
- package/dist/components/Sankey/index.d.ts +2 -2
- package/dist/components/Sankey/sankey.variants.d.ts +3 -1
- package/dist/components/SidebarLayout/SidebarLayout.svelte +17 -17
- package/dist/components/SidebarLayout/index.d.ts +8 -2
- package/dist/components/SidebarLayout/sidebar-layout.variants.d.ts +3 -1
- package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte +30 -38
- package/dist/components/ThemeSwitcher/index.d.ts +6 -4
- package/dist/components/ThemeSwitcher/themeSwitcher.variants.d.ts +3 -1
- package/dist/primitives/Accordion/Accordion.svelte +7 -9
- package/dist/primitives/Accordion/AccordionItem.svelte +8 -20
- package/dist/primitives/Accordion/accordion.variants.d.ts +3 -1
- package/dist/primitives/Accordion/index.d.ts +6 -6
- package/dist/primitives/Alert/Alert.svelte +7 -21
- package/dist/primitives/Alert/alert.variants.d.ts +3 -1
- package/dist/primitives/Alert/index.d.ts +3 -3
- package/dist/primitives/Avatar/Avatar.svelte +17 -20
- package/dist/primitives/Avatar/avatar.variants.d.ts +3 -1
- package/dist/primitives/Avatar/index.d.ts +3 -3
- package/dist/primitives/Badge/Badge.svelte +20 -23
- package/dist/primitives/Badge/badge.variants.d.ts +3 -1
- package/dist/primitives/Badge/index.d.ts +2 -2
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +30 -32
- package/dist/primitives/Breadcrumb/breadcrumb.variants.d.ts +3 -1
- package/dist/primitives/Breadcrumb/index.d.ts +2 -2
- package/dist/primitives/Button/Button.svelte +21 -21
- package/dist/primitives/Button/button.variants.d.ts +3 -1
- package/dist/primitives/Button/index.d.ts +3 -3
- package/dist/primitives/ButtonGroup/ButtonGroup.svelte +15 -14
- package/dist/primitives/ButtonGroup/buttongroup.variants.d.ts +3 -1
- package/dist/primitives/ButtonGroup/index.d.ts +3 -2
- package/dist/primitives/Card/Card.svelte +15 -18
- package/dist/primitives/Card/card.variants.d.ts +3 -1
- package/dist/primitives/Card/index.d.ts +3 -3
- package/dist/primitives/Checkbox/Checkbox.svelte +20 -20
- package/dist/primitives/Checkbox/checkbox.variants.d.ts +3 -1
- package/dist/primitives/Checkbox/index.d.ts +7 -3
- package/dist/primitives/Collapsible/Collapsible.svelte +30 -30
- package/dist/primitives/Collapsible/collapsible.variants.d.ts +3 -1
- package/dist/primitives/Collapsible/index.d.ts +3 -3
- package/dist/primitives/Combobox/Combobox.svelte +20 -31
- package/dist/primitives/Combobox/combobox.variants.d.ts +3 -1
- package/dist/primitives/Combobox/index.d.ts +5 -3
- package/dist/primitives/Dialog/Dialog.svelte +7 -10
- package/dist/primitives/Dialog/dialog.variants.d.ts +3 -1
- package/dist/primitives/Dialog/index.d.ts +2 -2
- package/dist/primitives/Drawer/Drawer.svelte +7 -10
- package/dist/primitives/Drawer/drawer.variants.d.ts +3 -1
- package/dist/primitives/Drawer/index.d.ts +2 -2
- package/dist/primitives/Input/Input.svelte +54 -30
- package/dist/primitives/Input/index.d.ts +7 -3
- package/dist/primitives/Input/input.variants.d.ts +3 -1
- package/dist/primitives/Menu/Menu.svelte +23 -23
- package/dist/primitives/Menu/index.d.ts +4 -1
- package/dist/primitives/Menu/menu.variants.d.ts +3 -1
- package/dist/primitives/Pagination/Pagination.svelte +18 -16
- package/dist/primitives/Pagination/index.d.ts +2 -2
- package/dist/primitives/Pagination/pagination.variants.d.ts +3 -1
- package/dist/primitives/Popover/Popover.svelte +2 -6
- package/dist/primitives/Progress/Progress.svelte +17 -17
- package/dist/primitives/Progress/index.d.ts +8 -3
- package/dist/primitives/Progress/progress.variants.d.ts +3 -1
- package/dist/primitives/RadioGroup/RadioGroup.svelte +16 -16
- package/dist/primitives/RadioGroup/RadioItem.svelte +19 -19
- package/dist/primitives/RadioGroup/index.d.ts +3 -3
- package/dist/primitives/RadioGroup/radioGroup.variants.d.ts +4 -1
- package/dist/primitives/SegmentGroup/SegmentGroup.svelte +14 -11
- package/dist/primitives/SegmentGroup/SegmentItem.svelte +12 -11
- package/dist/primitives/SegmentGroup/index.d.ts +3 -3
- package/dist/primitives/SegmentGroup/segmentgroup.variants.d.ts +3 -1
- package/dist/primitives/Select/Select.svelte +31 -22
- package/dist/primitives/Select/index.d.ts +8 -3
- package/dist/primitives/Select/select.variants.d.ts +3 -1
- package/dist/primitives/Separator/Separator.svelte +2 -6
- package/dist/primitives/Sidebar/Sidebar.svelte +6 -9
- package/dist/primitives/Sidebar/index.d.ts +2 -2
- package/dist/primitives/Sidebar/sidebar.variants.d.ts +3 -1
- package/dist/primitives/Skeleton/Skeleton.svelte +7 -9
- package/dist/primitives/Skeleton/index.d.ts +3 -3
- package/dist/primitives/Skeleton/skeleton.variants.d.ts +3 -1
- package/dist/primitives/Skeleton/skeleton.variants.js +5 -6
- package/dist/primitives/Slider/Slider.svelte +19 -19
- package/dist/primitives/Slider/index.d.ts +8 -3
- package/dist/primitives/Slider/slider.variants.d.ts +3 -1
- package/dist/primitives/Spinner/Spinner.svelte +7 -9
- package/dist/primitives/Spinner/index.d.ts +5 -3
- package/dist/primitives/Spinner/spinner.variants.d.ts +3 -1
- package/dist/primitives/Stepper/Stepper.svelte +13 -18
- package/dist/primitives/Stepper/StepperStep.svelte +18 -19
- package/dist/primitives/Stepper/index.d.ts +5 -5
- package/dist/primitives/Stepper/stepper.variants.d.ts +3 -1
- package/dist/primitives/Tab/Tab.svelte +14 -17
- package/dist/primitives/Tab/TabItem.svelte +18 -19
- package/dist/primitives/Tab/TabPanel.svelte +10 -13
- package/dist/primitives/Tab/index.d.ts +7 -7
- package/dist/primitives/Tab/tab.variants.d.ts +3 -1
- package/dist/primitives/Textarea/Textarea.svelte +23 -23
- package/dist/primitives/Textarea/index.d.ts +7 -3
- package/dist/primitives/Textarea/textarea.variants.d.ts +3 -1
- package/dist/primitives/Toast/Toaster.svelte +5 -6
- package/dist/primitives/Toast/index.d.ts +2 -2
- package/dist/primitives/Toast/toast.variants.d.ts +3 -1
- package/dist/primitives/Toggle/Toggle.svelte +19 -19
- package/dist/primitives/Toggle/index.d.ts +7 -3
- package/dist/primitives/Toggle/toggle.variants.d.ts +3 -1
- package/dist/primitives/Toolbar/Toolbar.svelte +7 -9
- package/dist/primitives/Toolbar/index.d.ts +4 -3
- package/dist/primitives/Toolbar/toolbar.variants.d.ts +3 -1
- package/dist/primitives/Tooltip/Tooltip.svelte +7 -9
- package/dist/primitives/Tooltip/index.d.ts +2 -2
- package/dist/primitives/Tooltip/tooltip.variants.d.ts +3 -1
- package/dist/provider/blocks-context.d.ts +45 -0
- package/dist/provider/blocks-context.js +57 -0
- package/dist/provider/index.d.ts +1 -1
- package/dist/provider/index.js +1 -1
- package/dist/style/semantic.css +5 -0
- package/dist/utils/variants.d.ts +32 -0
- package/dist/utils/variants.js +26 -1
- package/package.json +3 -3
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { mintRegistry } from '../..';
|
|
3
|
-
import { getBlocksConfig,
|
|
3
|
+
import { getBlocksConfig, resolveSlotClasses } from '../../provider';
|
|
4
4
|
import { useFormField, getTierContext } from '../../utils';
|
|
5
5
|
import type { TextareaProps } from './index';
|
|
6
|
-
import { textareaVariants } from './textarea.variants';
|
|
6
|
+
import { textareaVariants, type TextareaVariants } from './textarea.variants';
|
|
7
7
|
|
|
8
8
|
let {
|
|
9
9
|
label,
|
|
@@ -36,13 +36,6 @@
|
|
|
36
36
|
|
|
37
37
|
const blocksConfig = getBlocksConfig();
|
|
38
38
|
const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
|
|
39
|
-
const slotClasses = $derived(
|
|
40
|
-
mergeSlotClasses(
|
|
41
|
-
blocksConfig?.defaults?.Textarea?.slotClasses,
|
|
42
|
-
resolvePresetSlotClasses(blocksConfig?.presets, 'Textarea', preset),
|
|
43
|
-
slotClassesProp
|
|
44
|
-
)
|
|
45
|
-
);
|
|
46
39
|
|
|
47
40
|
let textareaRef = $state<HTMLTextAreaElement>();
|
|
48
41
|
|
|
@@ -66,20 +59,27 @@
|
|
|
66
59
|
|
|
67
60
|
const showFooter = $derived(!!error || !!helper || (showCounter && maxlength));
|
|
68
61
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
62
|
+
// Variant props feed both the tv() style computation and the slot-class
|
|
63
|
+
// cascade — extracted into one derived so `resolveSlotClasses` can match
|
|
64
|
+
// conditional `overrides` against the textarea's active variants.
|
|
65
|
+
const variantProps: TextareaVariants = $derived({
|
|
66
|
+
tier: effectiveTier,
|
|
67
|
+
variant,
|
|
68
|
+
size,
|
|
69
|
+
intent,
|
|
70
|
+
autoResize: autoResize || undefined,
|
|
71
|
+
disabled: disabled || undefined,
|
|
72
|
+
readonly: readonly || undefined,
|
|
73
|
+
error: !!error || undefined,
|
|
74
|
+
required: required || undefined,
|
|
75
|
+
messageType: error ? 'error' : 'helper',
|
|
76
|
+
counterState
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const styles = $derived(textareaVariants(variantProps));
|
|
80
|
+
|
|
81
|
+
const slotClasses = $derived(
|
|
82
|
+
resolveSlotClasses(blocksConfig, 'Textarea', preset, variantProps, slotClassesProp)
|
|
83
83
|
);
|
|
84
84
|
|
|
85
85
|
const lineHeight = $derived(size === 'sm' ? 20 : size === 'lg' ? 28 : 24);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
2
2
|
import type { MintProp } from '../../mint';
|
|
3
|
-
import type { TextareaVariants } from './textarea.variants';
|
|
3
|
+
import type { TextareaSlots, TextareaVariants } from './textarea.variants';
|
|
4
4
|
/**
|
|
5
5
|
* @description Multi-line text input with auto-resize, character counter, and validation states.
|
|
6
6
|
* Shares the same variant/intent/size system as Input for visual consistency.
|
|
@@ -59,8 +59,12 @@ export interface TextareaProps extends Omit<TextareaVariants, 'error' | 'counter
|
|
|
59
59
|
class?: string;
|
|
60
60
|
/** Remove all default tv() classes. Only user-provided classes apply. */
|
|
61
61
|
unstyled?: boolean;
|
|
62
|
-
/**
|
|
63
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Per-slot class overrides merged with tv() styles. Slots: wrapper (root —
|
|
64
|
+
* what `class` also targets) | base (the `<textarea>` element) | label |
|
|
65
|
+
* footer | message | counter.
|
|
66
|
+
*/
|
|
67
|
+
slotClasses?: Partial<Record<TextareaSlots, string>>;
|
|
64
68
|
/**
|
|
65
69
|
* Apply a named preset registered via `<BlocksProvider presets={{ Textarea: {...} }}>`.
|
|
66
70
|
* Prefer this over `class` overrides when the requested look falls outside the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VariantProps } from '../../utils/variants';
|
|
1
|
+
import { type SlotNames, type VariantProps } from '../../utils/variants';
|
|
2
2
|
export declare const textareaVariants: (props?: import("../../utils/variants").TVProps<{
|
|
3
3
|
tier: {
|
|
4
4
|
modify: {
|
|
@@ -191,3 +191,5 @@ export declare const textareaVariants: (props?: import("../../utils/variants").T
|
|
|
191
191
|
}) | undefined) => string;
|
|
192
192
|
};
|
|
193
193
|
export type TextareaVariants = VariantProps<typeof textareaVariants>;
|
|
194
|
+
/** Slot names derived from the `tv()` config above — single source of truth for `slotClasses`. */
|
|
195
|
+
export type TextareaSlots = SlotNames<typeof textareaVariants>;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import SuccessCircleIconDefault from '../../icons/SuccessCircleIcon.svelte';
|
|
11
11
|
import WarningTriangleIconDefault from '../../icons/WarningTriangleIcon.svelte';
|
|
12
12
|
import DangerCircleIconDefault from '../../icons/DangerCircleIcon.svelte';
|
|
13
|
-
import { getBlocksConfig,
|
|
13
|
+
import { getBlocksConfig, resolveSlotClasses } from '../../provider';
|
|
14
14
|
import type { ToastProps } from './index';
|
|
15
15
|
|
|
16
16
|
const bt = useBlocksI18n();
|
|
@@ -38,12 +38,11 @@
|
|
|
38
38
|
|
|
39
39
|
const blocksConfig = getBlocksConfig();
|
|
40
40
|
const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
|
|
41
|
+
// Component-level slot-class cascade. Per-toast `intent` is NOT part of
|
|
42
|
+
// activeProps — it is applied per row in the `slot(key, intent)` helper via
|
|
43
|
+
// its own `toastVariants({ placement, intent })` call (see below).
|
|
41
44
|
const slotClasses = $derived(
|
|
42
|
-
|
|
43
|
-
blocksConfig?.defaults?.Toaster?.slotClasses,
|
|
44
|
-
resolvePresetSlotClasses(blocksConfig?.presets, 'Toaster', preset),
|
|
45
|
-
slotClassesProp
|
|
46
|
-
)
|
|
45
|
+
resolveSlotClasses(blocksConfig, 'Toaster', preset, { placement }, slotClassesProp)
|
|
47
46
|
);
|
|
48
47
|
|
|
49
48
|
$effect(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
-
import type { ToastPlacement } from './toast.variants';
|
|
2
|
+
import type { ToasterSlots, ToastPlacement } from './toast.variants';
|
|
3
3
|
/**
|
|
4
4
|
* Canonical intents accepted by the toaster. Use as a runtime list when
|
|
5
5
|
* building dispatchers (e.g. `toaster[intent]?.(title, opts)`); use
|
|
@@ -82,7 +82,7 @@ export interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'childr
|
|
|
82
82
|
/** Strip all default tv classes. Use with `slotClasses` for a fully custom look. */
|
|
83
83
|
unstyled?: boolean;
|
|
84
84
|
/** Per-slot class overrides merged with (or replacing, when `unstyled`) the default styles. */
|
|
85
|
-
slotClasses?: Partial<Record<
|
|
85
|
+
slotClasses?: Partial<Record<ToasterSlots, string>>;
|
|
86
86
|
/**
|
|
87
87
|
* Apply a named preset registered via `<BlocksProvider presets={{ Toaster: {...} }}>`.
|
|
88
88
|
* Prefer this over `class` overrides when the requested look falls outside the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VariantProps } from '../../utils/variants';
|
|
1
|
+
import { type SlotNames, type VariantProps } from '../../utils/variants';
|
|
2
2
|
export declare const toastVariants: (props?: import("../../utils/variants").TVProps<{
|
|
3
3
|
intent: {
|
|
4
4
|
primary: {
|
|
@@ -111,4 +111,6 @@ export declare const toastVariants: (props?: import("../../utils/variants").TVPr
|
|
|
111
111
|
}) | undefined) => string;
|
|
112
112
|
};
|
|
113
113
|
export type ToastVariants = VariantProps<typeof toastVariants>;
|
|
114
|
+
/** Slot names derived from the tv() config — single source of truth for slotClasses. */
|
|
115
|
+
export type ToasterSlots = SlotNames<typeof toastVariants>;
|
|
114
116
|
export type ToastPlacement = 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useBlocksI18n, mintRegistry } from '../..';
|
|
3
|
-
import { getBlocksConfig,
|
|
3
|
+
import { getBlocksConfig, resolveSlotClasses } from '../../provider';
|
|
4
4
|
import { getTierContext, useFormField } from '../../utils';
|
|
5
|
-
import { toggleVariants } from './toggle.variants';
|
|
5
|
+
import { toggleVariants, type ToggleVariants } from './toggle.variants';
|
|
6
6
|
import type { ToggleProps } from './index';
|
|
7
7
|
|
|
8
8
|
const bt = useBlocksI18n();
|
|
@@ -42,13 +42,6 @@
|
|
|
42
42
|
|
|
43
43
|
const blocksConfig = getBlocksConfig();
|
|
44
44
|
const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
|
|
45
|
-
const slotClasses = $derived(
|
|
46
|
-
mergeSlotClasses(
|
|
47
|
-
blocksConfig?.defaults?.Toggle?.slotClasses,
|
|
48
|
-
resolvePresetSlotClasses(blocksConfig?.presets, 'Toggle', preset),
|
|
49
|
-
slotClassesProp
|
|
50
|
-
)
|
|
51
|
-
);
|
|
52
45
|
|
|
53
46
|
let rootEl = $state<HTMLElement>();
|
|
54
47
|
|
|
@@ -58,16 +51,23 @@
|
|
|
58
51
|
const tierCtx = getTierContext();
|
|
59
52
|
const effectiveTier = $derived(tier ?? tierCtx?.tier ?? 'commit');
|
|
60
53
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
54
|
+
// Variant props feed both the tv() style computation and the slot-class
|
|
55
|
+
// cascade — extracted into one derived so `resolveSlotClasses` can match
|
|
56
|
+
// conditional `overrides` against the toggle's active variants.
|
|
57
|
+
const variantProps: ToggleVariants = $derived({
|
|
58
|
+
tier: effectiveTier,
|
|
59
|
+
size,
|
|
60
|
+
intent,
|
|
61
|
+
appearance,
|
|
62
|
+
checked,
|
|
63
|
+
disabled,
|
|
64
|
+
withBorder
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const styles = $derived(toggleVariants(variantProps));
|
|
68
|
+
|
|
69
|
+
const slotClasses = $derived(
|
|
70
|
+
resolveSlotClasses(blocksConfig, 'Toggle', preset, variantProps, slotClassesProp)
|
|
71
71
|
);
|
|
72
72
|
|
|
73
73
|
const dataState = $derived(checked ? 'checked' : 'unchecked');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
2
|
import type { MintProp } from '../../mint';
|
|
3
3
|
import type { InteractiveTier } from '../../utils';
|
|
4
|
-
import type { ToggleVariants } from './toggle.variants';
|
|
4
|
+
import type { ToggleSlots, ToggleVariants } from './toggle.variants';
|
|
5
5
|
/**
|
|
6
6
|
* @description Accessible switch control for boolean on/off states.
|
|
7
7
|
* Built on a hidden native input with semantic intents and Mint micro-interactions.
|
|
@@ -43,8 +43,12 @@ export interface ToggleProps extends Omit<ToggleVariants, 'checked'>, Omit<HTMLI
|
|
|
43
43
|
class?: string;
|
|
44
44
|
/** Strip all default tailwind-variants classes. Use with `slotClasses` for a fully custom look. The track exposes `data-state` for conditional styling. */
|
|
45
45
|
unstyled?: boolean;
|
|
46
|
-
/**
|
|
47
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Per-slot class overrides merged with (or replacing, when `unstyled`) the
|
|
48
|
+
* default styles. Slots: wrapper (root — what `class` also targets) | control
|
|
49
|
+
* (the `<label>` wrapping the input) | track | thumb | label | message.
|
|
50
|
+
*/
|
|
51
|
+
slotClasses?: Partial<Record<ToggleSlots, string>>;
|
|
48
52
|
/**
|
|
49
53
|
* Apply a named preset registered via `<BlocksProvider presets={{ Toggle: {...} }}>`.
|
|
50
54
|
* Prefer this over `class` overrides when the requested look falls outside the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VariantProps } from '../../utils/variants';
|
|
1
|
+
import { type SlotNames, type VariantProps } from '../../utils/variants';
|
|
2
2
|
export declare const toggleVariants: (props?: import("../../utils/variants").TVProps<{
|
|
3
3
|
tier: {
|
|
4
4
|
commit: {
|
|
@@ -132,3 +132,5 @@ export declare const toggleVariants: (props?: import("../../utils/variants").TVP
|
|
|
132
132
|
}) | undefined) => string;
|
|
133
133
|
};
|
|
134
134
|
export type ToggleVariants = VariantProps<typeof toggleVariants>;
|
|
135
|
+
/** Slot names derived from the `tv()` config above — single source of truth for `slotClasses`. */
|
|
136
|
+
export type ToggleSlots = SlotNames<typeof toggleVariants>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { toolbarVariants } from './toolbar.variants';
|
|
2
|
+
import { toolbarVariants, type ToolbarVariants } from './toolbar.variants';
|
|
3
3
|
import type { ToolbarProps } from './index';
|
|
4
|
-
import { getBlocksConfig,
|
|
4
|
+
import { getBlocksConfig, resolveSlotClasses } from '../../provider';
|
|
5
5
|
import { setTierContext } from '../../utils/tier-context';
|
|
6
6
|
|
|
7
7
|
let {
|
|
@@ -30,15 +30,13 @@
|
|
|
30
30
|
|
|
31
31
|
const blocksConfig = getBlocksConfig();
|
|
32
32
|
const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
|
|
33
|
+
|
|
34
|
+
const variantProps: ToolbarVariants = $derived({ variant, orientation, gap, padding });
|
|
35
|
+
const styles = $derived(toolbarVariants(variantProps));
|
|
36
|
+
|
|
33
37
|
const slotClasses = $derived(
|
|
34
|
-
|
|
35
|
-
blocksConfig?.defaults?.Toolbar?.slotClasses,
|
|
36
|
-
resolvePresetSlotClasses(blocksConfig?.presets, 'Toolbar', preset),
|
|
37
|
-
slotClassesProp
|
|
38
|
-
)
|
|
38
|
+
resolveSlotClasses(blocksConfig, 'Toolbar', preset, variantProps, slotClassesProp)
|
|
39
39
|
);
|
|
40
|
-
|
|
41
|
-
const styles = $derived(toolbarVariants({ variant, orientation, gap, padding }));
|
|
42
40
|
</script>
|
|
43
41
|
|
|
44
42
|
<div
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import type { InteractiveTier } from '../../utils';
|
|
4
|
-
import type { ToolbarVariants } from './toolbar.variants';
|
|
4
|
+
import type { ToolbarSlots, ToolbarVariants } from './toolbar.variants';
|
|
5
5
|
/**
|
|
6
6
|
* Props interface for Toolbar component
|
|
7
7
|
*
|
|
@@ -54,8 +54,9 @@ export interface ToolbarProps extends ToolbarVariants, Omit<HTMLAttributes<HTMLD
|
|
|
54
54
|
tier?: InteractiveTier;
|
|
55
55
|
/** Remove all default tv() classes. Combine with `slotClasses` to restyle from scratch. */
|
|
56
56
|
unstyled?: boolean;
|
|
57
|
-
/** Per-slot class overrides merged with (or replacing when `unstyled`) the default classes.
|
|
58
|
-
|
|
57
|
+
/** Per-slot class overrides merged with (or replacing when `unstyled`) the default classes.
|
|
58
|
+
* Slots: base */
|
|
59
|
+
slotClasses?: Partial<Record<ToolbarSlots, string>>;
|
|
59
60
|
/**
|
|
60
61
|
* Apply a named preset registered via `<BlocksProvider presets={{ Toolbar: {...} }}>`.
|
|
61
62
|
* Prefer this over `class` overrides when the requested look falls outside the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VariantProps } from '../../utils/variants';
|
|
1
|
+
import { type SlotNames, type VariantProps } from '../../utils/variants';
|
|
2
2
|
export declare const toolbarVariants: (props?: import("../../utils/variants").TVProps<{
|
|
3
3
|
variant: {
|
|
4
4
|
quiet: {
|
|
@@ -68,3 +68,5 @@ export declare const toolbarVariants: (props?: import("../../utils/variants").TV
|
|
|
68
68
|
}) | undefined) => string;
|
|
69
69
|
};
|
|
70
70
|
export type ToolbarVariants = VariantProps<typeof toolbarVariants>;
|
|
71
|
+
/** Slot names derived from the tv() config — single source of truth for slotClasses. */
|
|
72
|
+
export type ToolbarSlots = SlotNames<typeof toolbarVariants>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { tooltipVariants } from './tooltip.variants';
|
|
3
|
+
import type { VariantProps } from '../../utils/variants';
|
|
3
4
|
import type { TooltipProps } from './index';
|
|
4
|
-
import { getBlocksConfig,
|
|
5
|
+
import { getBlocksConfig, resolveSlotClasses } from '../../provider';
|
|
5
6
|
import {
|
|
6
7
|
computePosition,
|
|
7
8
|
autoUpdate,
|
|
@@ -31,13 +32,6 @@
|
|
|
31
32
|
|
|
32
33
|
const blocksConfig = getBlocksConfig();
|
|
33
34
|
const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
|
|
34
|
-
const slotClasses = $derived(
|
|
35
|
-
mergeSlotClasses(
|
|
36
|
-
blocksConfig?.defaults?.Tooltip?.slotClasses,
|
|
37
|
-
resolvePresetSlotClasses(blocksConfig?.presets, 'Tooltip', preset),
|
|
38
|
-
slotClassesProp
|
|
39
|
-
)
|
|
40
|
-
);
|
|
41
35
|
|
|
42
36
|
let visible = $state(false);
|
|
43
37
|
let triggerElement = $state<HTMLElement>();
|
|
@@ -48,7 +42,11 @@
|
|
|
48
42
|
const propsId = $props.id();
|
|
49
43
|
const tooltipId = `tooltip-${propsId}`;
|
|
50
44
|
|
|
51
|
-
const
|
|
45
|
+
const variantProps: VariantProps<typeof tooltipVariants> = $derived({ visible, intent, size });
|
|
46
|
+
const styles = $derived(tooltipVariants(variantProps));
|
|
47
|
+
const slotClasses = $derived(
|
|
48
|
+
resolveSlotClasses(blocksConfig, 'Tooltip', preset, variantProps, slotClassesProp)
|
|
49
|
+
);
|
|
52
50
|
|
|
53
51
|
let showTimeout: number;
|
|
54
52
|
let hideTimeout: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import type { Placement } from '../../utils/floating';
|
|
4
|
-
import type { TooltipVariants } from './tooltip.variants';
|
|
4
|
+
import type { TooltipSlots, TooltipVariants } from './tooltip.variants';
|
|
5
5
|
/**
|
|
6
6
|
* @description Contextual overlay that displays brief, supplementary text on hover or focus.
|
|
7
7
|
* Built with Floating UI for precise positioning and accessibility support.
|
|
@@ -43,7 +43,7 @@ export interface TooltipProps extends TooltipVariants, Omit<HTMLAttributes<HTMLD
|
|
|
43
43
|
/** Remove default tv classes; only consumer classes apply. */
|
|
44
44
|
unstyled?: boolean;
|
|
45
45
|
/** Per-slot class overrides merged with (or replacing, when unstyled) tv styles. */
|
|
46
|
-
slotClasses?: Partial<Record<
|
|
46
|
+
slotClasses?: Partial<Record<TooltipSlots, string>>;
|
|
47
47
|
/**
|
|
48
48
|
* Apply a named preset registered via `<BlocksProvider presets={{ Tooltip: {...} }}>`.
|
|
49
49
|
* Prefer this over `class` overrides when the requested look falls outside the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VariantProps } from '../../utils/variants';
|
|
1
|
+
import { type SlotNames, type VariantProps } from '../../utils/variants';
|
|
2
2
|
export declare const tooltipVariants: (props?: import("../../utils/variants").TVProps<{
|
|
3
3
|
visible: {
|
|
4
4
|
true: {
|
|
@@ -61,3 +61,5 @@ export declare const tooltipVariants: (props?: import("../../utils/variants").TV
|
|
|
61
61
|
}) | undefined) => string;
|
|
62
62
|
};
|
|
63
63
|
export type TooltipVariants = Omit<VariantProps<typeof tooltipVariants>, 'visible'>;
|
|
64
|
+
/** Slot names derived from the `tv()` config above — single source of truth for `slotClasses`. */
|
|
65
|
+
export type TooltipSlots = SlotNames<typeof tooltipVariants>;
|
|
@@ -1,5 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A prop-conditional style rule. Its non-`class` keys are matched against a
|
|
3
|
+
* component's active variant props — exactly like a `tv()` compoundVariant
|
|
4
|
+
* (`string` = equality, `string[]` = "one of"). On a match, the `class`
|
|
5
|
+
* record (slot → classes) is merged into the slot-class cascade. Additive:
|
|
6
|
+
* every matching rule contributes; later sources win per Tailwind bucket.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* { variant: 'outlined', class: { base: 'border' } } // 1px border only on outlined
|
|
10
|
+
*/
|
|
11
|
+
export interface ConditionalOverride {
|
|
12
|
+
/** Per-slot classes applied when the prop conditions match. */
|
|
13
|
+
class: Record<string, string>;
|
|
14
|
+
/** Prop conditions: prop name → required value (or one of several). */
|
|
15
|
+
[propCondition: string]: string | string[] | Record<string, string> | undefined;
|
|
16
|
+
}
|
|
1
17
|
export interface ComponentDefaults {
|
|
2
18
|
slotClasses?: Record<string, string>;
|
|
19
|
+
/**
|
|
20
|
+
* Prop-conditional style rules, applied after unconditional `slotClasses`
|
|
21
|
+
* (so they win per bucket) but before instance-level `slotClasses` / `class`.
|
|
22
|
+
* Use for surgical per-variant tweaks the unconditional `slotClasses` cannot
|
|
23
|
+
* express, e.g. `overrides: [{ variant: 'outlined', class: { base: 'border' } }]`.
|
|
24
|
+
*/
|
|
25
|
+
overrides?: ConditionalOverride[];
|
|
3
26
|
}
|
|
4
27
|
/**
|
|
5
28
|
* A preset is a named, project-defined visual style for a component.
|
|
@@ -12,6 +35,8 @@ export interface ComponentDefaults {
|
|
|
12
35
|
*/
|
|
13
36
|
export interface ComponentPreset {
|
|
14
37
|
slotClasses?: Record<string, string>;
|
|
38
|
+
/** Prop-conditional rules scoped to this preset (see {@link ConditionalOverride}). */
|
|
39
|
+
overrides?: ConditionalOverride[];
|
|
15
40
|
}
|
|
16
41
|
/** Map of component name → preset name → preset definition. */
|
|
17
42
|
export type PresetMap = Record<string, Record<string, ComponentPreset>>;
|
|
@@ -30,3 +55,23 @@ export declare function mergeSlotClasses(...sources: (Record<string, string> | u
|
|
|
30
55
|
* is used but not registered, so missing presets are discoverable.
|
|
31
56
|
*/
|
|
32
57
|
export declare function resolvePresetSlotClasses(presets: PresetMap | undefined, component: string, presetName: string | undefined): Record<string, string> | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Collect the per-slot classes of every `overrides` entry whose prop
|
|
60
|
+
* conditions match `activeProps`. Returns `undefined` when there are no
|
|
61
|
+
* overrides or none match. Multiple matches merge additively, in order.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveOverrideSlotClasses(overrides: ConditionalOverride[] | undefined, activeProps: Record<string, unknown>): Record<string, string> | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the full slot-class cascade for a component instance, honoring
|
|
66
|
+
* conditional `overrides` from both provider defaults and the active preset.
|
|
67
|
+
*
|
|
68
|
+
* Precedence (weak → strong), conflict-resolved per slot so a later source
|
|
69
|
+
* wins within the same Tailwind bucket:
|
|
70
|
+
*
|
|
71
|
+
* defaults.slotClasses → defaults.overrides[match]
|
|
72
|
+
* → preset.slotClasses → preset.overrides[match] → instance.slotClasses
|
|
73
|
+
*
|
|
74
|
+
* The result is handed to the component's `tv()` slot fn as the `class`
|
|
75
|
+
* override, where it additionally strips conflicting library classes.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveSlotClasses(config: BlocksConfig | undefined, component: string, preset: string | undefined, activeProps: Record<string, unknown>, instanceSlotClasses: Record<string, string> | undefined): Record<string, string>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createOptionalContext } from '../utils/optional-context';
|
|
2
|
+
import { matchesCompound, resolveClassChain } from '../utils/variants';
|
|
2
3
|
// BlocksProvider is optional — components must work without one.
|
|
3
4
|
const [getBlocksConfig, setBlocksConfig] = createOptionalContext();
|
|
4
5
|
export { getBlocksConfig, setBlocksConfig };
|
|
@@ -34,3 +35,59 @@ export function resolvePresetSlotClasses(presets, component, presetName) {
|
|
|
34
35
|
}
|
|
35
36
|
return preset.slotClasses;
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Collect the per-slot classes of every `overrides` entry whose prop
|
|
40
|
+
* conditions match `activeProps`. Returns `undefined` when there are no
|
|
41
|
+
* overrides or none match. Multiple matches merge additively, in order.
|
|
42
|
+
*/
|
|
43
|
+
export function resolveOverrideSlotClasses(overrides, activeProps) {
|
|
44
|
+
if (!overrides || overrides.length === 0)
|
|
45
|
+
return undefined;
|
|
46
|
+
let result;
|
|
47
|
+
for (const entry of overrides) {
|
|
48
|
+
if (!matchesCompound(entry, activeProps))
|
|
49
|
+
continue;
|
|
50
|
+
result ??= {};
|
|
51
|
+
for (const [slot, value] of Object.entries(entry.class)) {
|
|
52
|
+
if (!value)
|
|
53
|
+
continue;
|
|
54
|
+
result[slot] = result[slot] ? `${result[slot]} ${value}` : value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolve the full slot-class cascade for a component instance, honoring
|
|
61
|
+
* conditional `overrides` from both provider defaults and the active preset.
|
|
62
|
+
*
|
|
63
|
+
* Precedence (weak → strong), conflict-resolved per slot so a later source
|
|
64
|
+
* wins within the same Tailwind bucket:
|
|
65
|
+
*
|
|
66
|
+
* defaults.slotClasses → defaults.overrides[match]
|
|
67
|
+
* → preset.slotClasses → preset.overrides[match] → instance.slotClasses
|
|
68
|
+
*
|
|
69
|
+
* The result is handed to the component's `tv()` slot fn as the `class`
|
|
70
|
+
* override, where it additionally strips conflicting library classes.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveSlotClasses(config, component, preset, activeProps, instanceSlotClasses) {
|
|
73
|
+
const defaults = config?.defaults?.[component];
|
|
74
|
+
const presetDef = preset ? config?.presets?.[component]?.[preset] : undefined;
|
|
75
|
+
const sources = [
|
|
76
|
+
defaults?.slotClasses,
|
|
77
|
+
resolveOverrideSlotClasses(defaults?.overrides, activeProps),
|
|
78
|
+
resolvePresetSlotClasses(config?.presets, component, preset),
|
|
79
|
+
resolveOverrideSlotClasses(presetDef?.overrides, activeProps),
|
|
80
|
+
instanceSlotClasses
|
|
81
|
+
];
|
|
82
|
+
const result = {};
|
|
83
|
+
for (const source of sources) {
|
|
84
|
+
if (!source)
|
|
85
|
+
continue;
|
|
86
|
+
for (const [slot, value] of Object.entries(source)) {
|
|
87
|
+
if (!value)
|
|
88
|
+
continue;
|
|
89
|
+
result[slot] = result[slot] ? resolveClassChain(result[slot], value) : value;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
package/dist/provider/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as BlocksProvider } from './BlocksProvider.svelte';
|
|
2
|
-
export { type BlocksConfig, type ComponentDefaults, type ComponentPreset, getBlocksConfig, mergeSlotClasses, type PresetMap, resolvePresetSlotClasses } from './blocks-context';
|
|
2
|
+
export { type BlocksConfig, type ComponentDefaults, type ComponentPreset, type ConditionalOverride, getBlocksConfig, mergeSlotClasses, type PresetMap, resolveOverrideSlotClasses, resolvePresetSlotClasses, resolveSlotClasses } from './blocks-context';
|
package/dist/provider/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as BlocksProvider } from './BlocksProvider.svelte';
|
|
2
|
-
export { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from './blocks-context';
|
|
2
|
+
export { getBlocksConfig, mergeSlotClasses, resolveOverrideSlotClasses, resolvePresetSlotClasses, resolveSlotClasses } from './blocks-context';
|
package/dist/style/semantic.css
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
--color-surface-selected: light-dark(var(--color-primary-50), var(--color-primary-900));
|
|
39
39
|
--color-surface-subtle: light-dark(var(--color-neutral-50), var(--color-neutral-800));
|
|
40
40
|
--color-surface-inverted: light-dark(var(--color-neutral-900), var(--color-neutral-100));
|
|
41
|
+
/* Skeleton wave-shimmer highlight (Skeleton animation="wave"). A translucent
|
|
42
|
+
white glint that sweeps across `surface-interactive`; lower alpha in dark
|
|
43
|
+
mode so it reads as a subtle sheen, not a flash. light-dark() keeps it
|
|
44
|
+
mode-aware so the wave needs no `dark:` override. */
|
|
45
|
+
--color-skeleton-shimmer: light-dark(oklch(1 0 0 / 0.5), oklch(1 0 0 / 0.1));
|
|
41
46
|
|
|
42
47
|
/* === TEXT ===
|
|
43
48
|
tertiary/quaternary shifted darker (light) so informative text on
|
package/dist/utils/variants.d.ts
CHANGED
|
@@ -16,6 +16,23 @@ type CompoundVariant<V extends Record<string, Record<string, unknown>>> = {
|
|
|
16
16
|
};
|
|
17
17
|
export type TVProps<V extends Record<string, Record<string, unknown>>> = VariantPropsMap<V> & TVClassOverrides;
|
|
18
18
|
export type VariantProps<T extends (...args: never[]) => unknown> = Omit<Exclude<Parameters<T>[0], undefined>, 'class' | 'className'>;
|
|
19
|
+
/**
|
|
20
|
+
* Extracts the slot-name union from a slotted `tv()` config function — the
|
|
21
|
+
* companion to {@link VariantProps}. The slot-mode overload returns
|
|
22
|
+
* `(props?) => { [K in keyof S]: SlotFn }`, so `keyof ReturnType<T>` is exactly
|
|
23
|
+
* the set of slot names a component declares in `tv({ slots: … })`.
|
|
24
|
+
*
|
|
25
|
+
* Use it to type a component's `slotClasses` prop from the single source of
|
|
26
|
+
* truth (its `*.variants.ts`) instead of hand-maintaining a parallel union
|
|
27
|
+
* that silently drifts when a slot is added or renamed:
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // button.variants.ts
|
|
31
|
+
* export type ButtonSlots = SlotNames<typeof buttonVariants>; // 'base' | 'content' | 'spinner'
|
|
32
|
+
* // index.ts
|
|
33
|
+
* slotClasses?: Partial<Record<ButtonSlots, string>>;
|
|
34
|
+
*/
|
|
35
|
+
export type SlotNames<T extends (...args: never[]) => unknown> = keyof ReturnType<T> & string;
|
|
19
36
|
/**
|
|
20
37
|
* Concatenate class inputs into a single string. Accepts strings, nested
|
|
21
38
|
* arrays, and falsy values (filtered out). Trims and joins with single
|
|
@@ -27,6 +44,21 @@ export type VariantProps<T extends (...args: never[]) => unknown> = Omit<Exclude
|
|
|
27
44
|
* pass. See `docs/ARCHITECTURE.md` "tv() engine — explicit trade-offs".
|
|
28
45
|
*/
|
|
29
46
|
export declare function cx(...inputs: ClassInput[]): string;
|
|
47
|
+
/**
|
|
48
|
+
* Merge class strings with the same Tailwind conflict resolution `tv()`
|
|
49
|
+
* applies between stages: a later source's classes strip any earlier class
|
|
50
|
+
* that shares their conflict bucket, so the last source wins per bucket.
|
|
51
|
+
* Within a single source, order is preserved and conflicts fall through to
|
|
52
|
+
* the CSS cascade. Falsy / empty sources are skipped.
|
|
53
|
+
*
|
|
54
|
+
* Reuses `tokenize` + `stripConflicts`. Powers the BlocksProvider slot-class
|
|
55
|
+
* cascade (`resolveSlotClasses`) so a conditional `overrides` entry
|
|
56
|
+
* deterministically defeats an unconditional `slotClasses` entry in the same
|
|
57
|
+
* bucket — instead of emitting both and leaving the winner to stylesheet
|
|
58
|
+
* order.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveClassChain(...sources: (string | null | undefined)[]): string;
|
|
61
|
+
export declare function matchesCompound(compound: Record<string, unknown>, effectiveProps: Record<string, unknown>): boolean;
|
|
30
62
|
export declare function tv<V extends Record<string, Record<string, unknown>> = {}>(config: {
|
|
31
63
|
base?: string | string[];
|
|
32
64
|
variants?: V;
|
package/dist/utils/variants.js
CHANGED
|
@@ -317,6 +317,31 @@ function tokenize(value) {
|
|
|
317
317
|
return [];
|
|
318
318
|
return value.split(/\s+/).filter(Boolean);
|
|
319
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Merge class strings with the same Tailwind conflict resolution `tv()`
|
|
322
|
+
* applies between stages: a later source's classes strip any earlier class
|
|
323
|
+
* that shares their conflict bucket, so the last source wins per bucket.
|
|
324
|
+
* Within a single source, order is preserved and conflicts fall through to
|
|
325
|
+
* the CSS cascade. Falsy / empty sources are skipped.
|
|
326
|
+
*
|
|
327
|
+
* Reuses `tokenize` + `stripConflicts`. Powers the BlocksProvider slot-class
|
|
328
|
+
* cascade (`resolveSlotClasses`) so a conditional `overrides` entry
|
|
329
|
+
* deterministically defeats an unconditional `slotClasses` entry in the same
|
|
330
|
+
* bucket — instead of emitting both and leaving the winner to stylesheet
|
|
331
|
+
* order.
|
|
332
|
+
*/
|
|
333
|
+
export function resolveClassChain(...sources) {
|
|
334
|
+
let acc = [];
|
|
335
|
+
for (const source of sources) {
|
|
336
|
+
if (!source)
|
|
337
|
+
continue;
|
|
338
|
+
const tokens = tokenize(source);
|
|
339
|
+
if (tokens.length === 0)
|
|
340
|
+
continue;
|
|
341
|
+
acc = [...stripConflicts(acc, tokens), ...tokens];
|
|
342
|
+
}
|
|
343
|
+
return acc.join(' ');
|
|
344
|
+
}
|
|
320
345
|
// ─── Internal Helpers ────────────────────────────────────────────────────────
|
|
321
346
|
function falsyToString(value) {
|
|
322
347
|
if (value === false)
|
|
@@ -337,7 +362,7 @@ function stripUndefined(obj) {
|
|
|
337
362
|
}
|
|
338
363
|
return result;
|
|
339
364
|
}
|
|
340
|
-
function matchesCompound(compound, effectiveProps) {
|
|
365
|
+
export function matchesCompound(compound, effectiveProps) {
|
|
341
366
|
for (const key of Object.keys(compound)) {
|
|
342
367
|
if (key === 'class' || key === 'className')
|
|
343
368
|
continue;
|