@happyvertical/smrt-ui 0.30.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.
- package/AGENTS.md +50 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/dist/actions/__tests__/ripple.test.js +28 -0
- package/dist/actions/permission.d.ts +34 -0
- package/dist/actions/permission.d.ts.map +1 -0
- package/dist/actions/permission.js +70 -0
- package/dist/actions/ripple.d.ts +7 -0
- package/dist/actions/ripple.d.ts.map +1 -0
- package/dist/actions/ripple.js +65 -0
- package/dist/components/calendar/Calendar.svelte +520 -0
- package/dist/components/calendar/Calendar.svelte.d.ts +17 -0
- package/dist/components/calendar/Calendar.svelte.d.ts.map +1 -0
- package/dist/components/calendar/DayView.svelte +389 -0
- package/dist/components/calendar/DayView.svelte.d.ts +13 -0
- package/dist/components/calendar/DayView.svelte.d.ts.map +1 -0
- package/dist/components/calendar/index.d.ts +6 -0
- package/dist/components/calendar/index.d.ts.map +1 -0
- package/dist/components/calendar/index.js +5 -0
- package/dist/components/chat/MessageBubble.svelte +126 -0
- package/dist/components/chat/MessageBubble.svelte.d.ts +30 -0
- package/dist/components/chat/MessageBubble.svelte.d.ts.map +1 -0
- package/dist/components/chat/ReactionPicker.svelte +89 -0
- package/dist/components/chat/ReactionPicker.svelte.d.ts +19 -0
- package/dist/components/chat/ReactionPicker.svelte.d.ts.map +1 -0
- package/dist/components/chat/TypingIndicator.svelte +90 -0
- package/dist/components/chat/TypingIndicator.svelte.d.ts +17 -0
- package/dist/components/chat/TypingIndicator.svelte.d.ts.map +1 -0
- package/dist/components/chat/__tests__/chat-primitives.test.js +67 -0
- package/dist/components/chat/index.d.ts +10 -0
- package/dist/components/chat/index.d.ts.map +1 -0
- package/dist/components/chat/index.js +9 -0
- package/dist/components/data/DataTable.svelte +519 -0
- package/dist/components/data/DataTable.svelte.d.ts +49 -0
- package/dist/components/data/DataTable.svelte.d.ts.map +1 -0
- package/dist/components/data/__tests__/DataTable.test.js +48 -0
- package/dist/components/data/__tests__/data-table-helpers.test.js +36 -0
- package/dist/components/data/index.d.ts +6 -0
- package/dist/components/data/index.d.ts.map +1 -0
- package/dist/components/data/index.js +5 -0
- package/dist/components/data/types.d.ts +104 -0
- package/dist/components/data/types.d.ts.map +1 -0
- package/dist/components/data/types.js +45 -0
- package/dist/components/display/ConfidenceBadge.svelte +142 -0
- package/dist/components/display/ConfidenceBadge.svelte.d.ts +25 -0
- package/dist/components/display/ConfidenceBadge.svelte.d.ts.map +1 -0
- package/dist/components/display/CurrencyDisplay.svelte +106 -0
- package/dist/components/display/CurrencyDisplay.svelte.d.ts +30 -0
- package/dist/components/display/CurrencyDisplay.svelte.d.ts.map +1 -0
- package/dist/components/display/DateDisplay.svelte +122 -0
- package/dist/components/display/DateDisplay.svelte.d.ts +24 -0
- package/dist/components/display/DateDisplay.svelte.d.ts.map +1 -0
- package/dist/components/display/Icon.svelte +77 -0
- package/dist/components/display/Icon.svelte.d.ts +28 -0
- package/dist/components/display/Icon.svelte.d.ts.map +1 -0
- package/dist/components/display/StatusBadge.svelte +256 -0
- package/dist/components/display/StatusBadge.svelte.d.ts +24 -0
- package/dist/components/display/StatusBadge.svelte.d.ts.map +1 -0
- package/dist/components/display/__tests__/ConfidenceBadge.test.js +96 -0
- package/dist/components/display/__tests__/CurrencyDisplay.test.js +114 -0
- package/dist/components/display/__tests__/DateDisplay.test.js +114 -0
- package/dist/components/display/__tests__/Icon.test.js +93 -0
- package/dist/components/display/__tests__/StatusBadge.test.js +98 -0
- package/dist/components/display/index.d.ts +10 -0
- package/dist/components/display/index.d.ts.map +1 -0
- package/dist/components/display/index.js +9 -0
- package/dist/components/display/types.d.ts +5 -0
- package/dist/components/display/types.d.ts.map +1 -0
- package/dist/components/display/types.js +4 -0
- package/dist/components/feedback/ConfirmDialog.svelte +226 -0
- package/dist/components/feedback/ConfirmDialog.svelte.d.ts +25 -0
- package/dist/components/feedback/ConfirmDialog.svelte.d.ts.map +1 -0
- package/dist/components/feedback/LoadingOverlay.svelte +281 -0
- package/dist/components/feedback/LoadingOverlay.svelte.d.ts +31 -0
- package/dist/components/feedback/LoadingOverlay.svelte.d.ts.map +1 -0
- package/dist/components/feedback/Modal.svelte +393 -0
- package/dist/components/feedback/Modal.svelte.d.ts +46 -0
- package/dist/components/feedback/Modal.svelte.d.ts.map +1 -0
- package/dist/components/feedback/ProgressBar.svelte +162 -0
- package/dist/components/feedback/ProgressBar.svelte.d.ts +21 -0
- package/dist/components/feedback/ProgressBar.svelte.d.ts.map +1 -0
- package/dist/components/feedback/__tests__/ConfirmDialog.test.js +111 -0
- package/dist/components/feedback/__tests__/LoadingOverlay.test.js +99 -0
- package/dist/components/feedback/__tests__/Modal.test.js +72 -0
- package/dist/components/feedback/__tests__/ProgressBar.test.js +89 -0
- package/dist/components/feedback/index.d.ts +8 -0
- package/dist/components/feedback/index.d.ts.map +1 -0
- package/dist/components/feedback/index.js +10 -0
- package/dist/components/layout/Container.svelte +53 -0
- package/dist/components/layout/Container.svelte.d.ts +11 -0
- package/dist/components/layout/Container.svelte.d.ts.map +1 -0
- package/dist/components/layout/EmptyState.svelte +187 -0
- package/dist/components/layout/EmptyState.svelte.d.ts +28 -0
- package/dist/components/layout/EmptyState.svelte.d.ts.map +1 -0
- package/dist/components/layout/Footer.svelte +63 -0
- package/dist/components/layout/Footer.svelte.d.ts +8 -0
- package/dist/components/layout/Footer.svelte.d.ts.map +1 -0
- package/dist/components/layout/Grid.svelte +241 -0
- package/dist/components/layout/Grid.svelte.d.ts +56 -0
- package/dist/components/layout/Grid.svelte.d.ts.map +1 -0
- package/dist/components/layout/Header.svelte +86 -0
- package/dist/components/layout/Header.svelte.d.ts +9 -0
- package/dist/components/layout/Header.svelte.d.ts.map +1 -0
- package/dist/components/layout/Masthead.svelte +219 -0
- package/dist/components/layout/Masthead.svelte.d.ts +13 -0
- package/dist/components/layout/Masthead.svelte.d.ts.map +1 -0
- package/dist/components/layout/PageHeader.svelte +131 -0
- package/dist/components/layout/PageHeader.svelte.d.ts +26 -0
- package/dist/components/layout/PageHeader.svelte.d.ts.map +1 -0
- package/dist/components/layout/SummaryCard.svelte +203 -0
- package/dist/components/layout/SummaryCard.svelte.d.ts +20 -0
- package/dist/components/layout/SummaryCard.svelte.d.ts.map +1 -0
- package/dist/components/layout/__tests__/Container.test.js +62 -0
- package/dist/components/layout/__tests__/EmptyState.test.js +83 -0
- package/dist/components/layout/__tests__/Footer.test.js +50 -0
- package/dist/components/layout/__tests__/Grid.test.js +121 -0
- package/dist/components/layout/__tests__/Header.test.js +48 -0
- package/dist/components/layout/__tests__/Masthead.test.js +93 -0
- package/dist/components/layout/__tests__/PageHeader.test.js +80 -0
- package/dist/components/layout/__tests__/SummaryCard.test.js +82 -0
- package/dist/components/layout/index.d.ts +12 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +11 -0
- package/dist/components/memberships/MembershipCard.svelte +163 -0
- package/dist/components/memberships/MembershipCard.svelte.d.ts +12 -0
- package/dist/components/memberships/MembershipCard.svelte.d.ts.map +1 -0
- package/dist/components/memberships/MembershipList.svelte +98 -0
- package/dist/components/memberships/MembershipList.svelte.d.ts +19 -0
- package/dist/components/memberships/MembershipList.svelte.d.ts.map +1 -0
- package/dist/components/nav/FilterChips.svelte +152 -0
- package/dist/components/nav/FilterChips.svelte.d.ts +19 -0
- package/dist/components/nav/FilterChips.svelte.d.ts.map +1 -0
- package/dist/components/nav/Tabs.svelte +252 -0
- package/dist/components/nav/Tabs.svelte.d.ts +34 -0
- package/dist/components/nav/Tabs.svelte.d.ts.map +1 -0
- package/dist/components/nav/__tests__/FilterChips.test.js +94 -0
- package/dist/components/nav/__tests__/Tabs.test.js +128 -0
- package/dist/components/nav/index.d.ts +7 -0
- package/dist/components/nav/index.d.ts.map +1 -0
- package/dist/components/nav/index.js +6 -0
- package/dist/components/nav/types.d.ts +24 -0
- package/dist/components/nav/types.d.ts.map +1 -0
- package/dist/components/nav/types.js +4 -0
- package/dist/components/permissions/PermissionCheck.svelte +45 -0
- package/dist/components/permissions/PermissionCheck.svelte.d.ts +19 -0
- package/dist/components/permissions/PermissionCheck.svelte.d.ts.map +1 -0
- package/dist/components/roles/RoleBadge.svelte +84 -0
- package/dist/components/roles/RoleBadge.svelte.d.ts +13 -0
- package/dist/components/roles/RoleBadge.svelte.d.ts.map +1 -0
- package/dist/components/roles/RoleSelector.svelte +216 -0
- package/dist/components/roles/RoleSelector.svelte.d.ts +13 -0
- package/dist/components/roles/RoleSelector.svelte.d.ts.map +1 -0
- package/dist/components/theme/ThemeProvider.svelte +71 -0
- package/dist/components/theme/ThemeProvider.svelte.d.ts +10 -0
- package/dist/components/theme/ThemeProvider.svelte.d.ts.map +1 -0
- package/dist/components/theme/context.svelte.d.ts +15 -0
- package/dist/components/theme/context.svelte.d.ts.map +1 -0
- package/dist/components/theme/context.svelte.js +42 -0
- package/dist/components/theme/index.d.ts +3 -0
- package/dist/components/theme/index.d.ts.map +1 -0
- package/dist/components/theme/index.js +2 -0
- package/dist/components/ui/Avatar.svelte +167 -0
- package/dist/components/ui/Avatar.svelte.d.ts +26 -0
- package/dist/components/ui/Avatar.svelte.d.ts.map +1 -0
- package/dist/components/ui/Badge.svelte +70 -0
- package/dist/components/ui/Badge.svelte.d.ts +12 -0
- package/dist/components/ui/Badge.svelte.d.ts.map +1 -0
- package/dist/components/ui/Button.svelte +226 -0
- package/dist/components/ui/Button.svelte.d.ts +28 -0
- package/dist/components/ui/Button.svelte.d.ts.map +1 -0
- package/dist/components/ui/Card.svelte +122 -0
- package/dist/components/ui/Card.svelte.d.ts +15 -0
- package/dist/components/ui/Card.svelte.d.ts.map +1 -0
- package/dist/components/ui/Chip.svelte +167 -0
- package/dist/components/ui/Chip.svelte.d.ts +33 -0
- package/dist/components/ui/Chip.svelte.d.ts.map +1 -0
- package/dist/components/ui/Dropdown.svelte +250 -0
- package/dist/components/ui/Dropdown.svelte.d.ts +20 -0
- package/dist/components/ui/Dropdown.svelte.d.ts.map +1 -0
- package/dist/components/ui/Pagination.svelte +294 -0
- package/dist/components/ui/Pagination.svelte.d.ts +21 -0
- package/dist/components/ui/Pagination.svelte.d.ts.map +1 -0
- package/dist/components/ui/Skeleton.svelte +113 -0
- package/dist/components/ui/Skeleton.svelte.d.ts +24 -0
- package/dist/components/ui/Skeleton.svelte.d.ts.map +1 -0
- package/dist/components/ui/Tooltip.svelte +120 -0
- package/dist/components/ui/Tooltip.svelte.d.ts +24 -0
- package/dist/components/ui/Tooltip.svelte.d.ts.map +1 -0
- package/dist/components/ui/Tree.svelte +209 -0
- package/dist/components/ui/Tree.svelte.d.ts +17 -0
- package/dist/components/ui/Tree.svelte.d.ts.map +1 -0
- package/dist/components/ui/__tests__/Badge.test.js +76 -0
- package/dist/components/ui/__tests__/Button.test.js +69 -0
- package/dist/components/ui/__tests__/Card.test.js +103 -0
- package/dist/components/ui/__tests__/Pagination.test.js +99 -0
- package/dist/components/ui/__tests__/gap-primitives-interactive.test.js +112 -0
- package/dist/components/ui/__tests__/gap-primitives.test.js +84 -0
- package/dist/components/ui/index.d.ts +14 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +18 -0
- package/dist/i18n/Trans.svelte +29 -0
- package/dist/i18n/Trans.svelte.d.ts +24 -0
- package/dist/i18n/Trans.svelte.d.ts.map +1 -0
- package/dist/i18n/__tests__/i18n.test.js +74 -0
- package/dist/i18n/__tests__/render-parity.spec.js +37 -0
- package/dist/i18n/context.svelte.d.ts +43 -0
- package/dist/i18n/context.svelte.d.ts.map +1 -0
- package/dist/i18n/context.svelte.js +69 -0
- package/dist/i18n/index.d.ts +17 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +24 -0
- package/dist/i18n/registry.d.ts +44 -0
- package/dist/i18n/registry.d.ts.map +1 -0
- package/dist/i18n/registry.js +60 -0
- package/dist/i18n/render.d.ts +22 -0
- package/dist/i18n/render.d.ts.map +1 -0
- package/dist/i18n/render.js +44 -0
- package/dist/i18n/strings.d.ts +7 -0
- package/dist/i18n/strings.d.ts.map +1 -0
- package/dist/i18n/strings.js +19 -0
- package/dist/i18n/strings.ui.d.ts +34 -0
- package/dist/i18n/strings.ui.d.ts.map +1 -0
- package/dist/i18n/strings.ui.js +44 -0
- package/dist/i18n/use-i18n.d.ts +20 -0
- package/dist/i18n/use-i18n.d.ts.map +1 -0
- package/dist/i18n/use-i18n.js +21 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/registry/index.d.ts +6 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +4 -0
- package/dist/registry/module-registry.d.ts +58 -0
- package/dist/registry/module-registry.d.ts.map +1 -0
- package/dist/registry/module-registry.js +94 -0
- package/dist/styles/index.d.ts +4 -0
- package/dist/styles/index.d.ts.map +1 -0
- package/dist/styles/index.js +6 -0
- package/dist/styles/tokens.css +76 -0
- package/dist/test-support/a11y.d.ts +16 -0
- package/dist/test-support/a11y.d.ts.map +1 -0
- package/dist/test-support/a11y.js +32 -0
- package/dist/test-support/setup.d.ts +11 -0
- package/dist/test-support/setup.d.ts.map +1 -0
- package/dist/test-support/setup.js +33 -0
- package/dist/theme/ThemeProvider.svelte +207 -0
- package/dist/theme/ThemeProvider.svelte.d.ts +22 -0
- package/dist/theme/ThemeProvider.svelte.d.ts.map +1 -0
- package/dist/theme/context.d.ts +49 -0
- package/dist/theme/context.d.ts.map +1 -0
- package/dist/theme/context.js +32 -0
- package/dist/theme/index.d.ts +7 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +9 -0
- package/dist/theme/tokens.d.ts +309 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/theme/tokens.js +418 -0
- package/dist/themes/CUSTOM_THEME_GUIDE.md +341 -0
- package/dist/themes/README.md +675 -0
- package/dist/themes/ThemeProvider.svelte +275 -0
- package/dist/themes/ThemeProvider.svelte.d.ts +24 -0
- package/dist/themes/ThemeProvider.svelte.d.ts.map +1 -0
- package/dist/themes/__tests__/css-generator.test.js +32 -0
- package/dist/themes/__tests__/registry.test.js +43 -0
- package/dist/themes/__tests__/token-aliases.test.js +176 -0
- package/dist/themes/components/ColorSchemeToggle.svelte +205 -0
- package/dist/themes/components/ColorSchemeToggle.svelte.d.ts +14 -0
- package/dist/themes/components/ColorSchemeToggle.svelte.d.ts.map +1 -0
- package/dist/themes/components/ThemeSwitcher.svelte +188 -0
- package/dist/themes/components/ThemeSwitcher.svelte.d.ts +14 -0
- package/dist/themes/components/ThemeSwitcher.svelte.d.ts.map +1 -0
- package/dist/themes/components/index.d.ts +8 -0
- package/dist/themes/components/index.d.ts.map +1 -0
- package/dist/themes/components/index.js +7 -0
- package/dist/themes/context.svelte.d.ts +30 -0
- package/dist/themes/context.svelte.d.ts.map +1 -0
- package/dist/themes/context.svelte.js +42 -0
- package/dist/themes/create-theme.d.ts +99 -0
- package/dist/themes/create-theme.d.ts.map +1 -0
- package/dist/themes/create-theme.js +389 -0
- package/dist/themes/css-generator.d.ts +44 -0
- package/dist/themes/css-generator.d.ts.map +1 -0
- package/dist/themes/css-generator.js +226 -0
- package/dist/themes/glass/index.d.ts +14 -0
- package/dist/themes/glass/index.d.ts.map +1 -0
- package/dist/themes/glass/index.js +286 -0
- package/dist/themes/index.d.ts +31 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +37 -0
- package/dist/themes/material/index.d.ts +13 -0
- package/dist/themes/material/index.d.ts.map +1 -0
- package/dist/themes/material/index.js +269 -0
- package/dist/themes/registry.d.ts +64 -0
- package/dist/themes/registry.d.ts.map +1 -0
- package/dist/themes/registry.js +122 -0
- package/dist/themes/shared.d.ts +78 -0
- package/dist/themes/shared.d.ts.map +1 -0
- package/dist/themes/shared.js +179 -0
- package/dist/themes/studio/index.d.ts +14 -0
- package/dist/themes/studio/index.d.ts.map +1 -0
- package/dist/themes/studio/index.js +270 -0
- package/dist/themes/styles/all.css +12 -0
- package/dist/themes/styles/glass.css +432 -0
- package/dist/themes/styles/index.d.ts +22 -0
- package/dist/themes/styles/index.d.ts.map +1 -0
- package/dist/themes/styles/index.js +23 -0
- package/dist/themes/styles/material.css +364 -0
- package/dist/themes/styles/studio.css +416 -0
- package/dist/themes/types.d.ts +273 -0
- package/dist/themes/types.d.ts.map +1 -0
- package/dist/themes/types.js +15 -0
- package/dist/types-generic.d.ts +75 -0
- package/dist/types-generic.d.ts.map +1 -0
- package/dist/types-generic.js +1 -0
- package/dist/utils/forms/__tests__/formatters.test.js +27 -0
- package/dist/utils/forms/formatters.d.ts +14 -0
- package/dist/utils/forms/formatters.d.ts.map +1 -0
- package/dist/utils/forms/formatters.js +77 -0
- package/dist/utils/import-optional.d.ts +5 -0
- package/dist/utils/import-optional.d.ts.map +1 -0
- package/dist/utils/import-optional.js +7 -0
- package/dist/utils/theme/__tests__/color.test.js +72 -0
- package/dist/utils/theme/__tests__/typography.test.js +11 -0
- package/dist/utils/theme/color.d.ts +70 -0
- package/dist/utils/theme/color.d.ts.map +1 -0
- package/dist/utils/theme/color.js +221 -0
- package/dist/utils/theme/typography.d.ts +27 -0
- package/dist/utils/theme/typography.d.ts.map +1 -0
- package/dist/utils/theme/typography.js +30 -0
- package/package.json +143 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getThemeContext } from '../context.svelte.js';
|
|
3
|
+
import type { ColorScheme } from '../types.js';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Show labels with icons */
|
|
7
|
+
showLabels?: boolean;
|
|
8
|
+
/** Button variant: 'switch' | 'buttons' | 'segmented' */
|
|
9
|
+
variant?: 'switch' | 'buttons' | 'segmented';
|
|
10
|
+
/** Additional CSS class */
|
|
11
|
+
class?: string;
|
|
12
|
+
/** Accessible label */
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
showLabels = true,
|
|
18
|
+
variant = 'switch',
|
|
19
|
+
class: className = '',
|
|
20
|
+
ariaLabel = 'Toggle color scheme',
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
const context = getThemeContext();
|
|
24
|
+
|
|
25
|
+
function setScheme(scheme: ColorScheme) {
|
|
26
|
+
context.setColorScheme(scheme);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function toggle() {
|
|
30
|
+
context.toggleColorScheme();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Icons
|
|
34
|
+
const icons = {
|
|
35
|
+
light: '☀️',
|
|
36
|
+
dark: '🌙',
|
|
37
|
+
system: '💻',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const labels = {
|
|
41
|
+
light: 'Light',
|
|
42
|
+
dark: 'Dark',
|
|
43
|
+
system: 'System',
|
|
44
|
+
};
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<div class="smrt-color-scheme-toggle {variant} {className}">
|
|
48
|
+
{#if variant === 'switch'}
|
|
49
|
+
<button
|
|
50
|
+
class="smrt-color-scheme-toggle__switch"
|
|
51
|
+
onclick={toggle}
|
|
52
|
+
type="button"
|
|
53
|
+
aria-label={ariaLabel}
|
|
54
|
+
title={labels[context.state.resolvedScheme]}
|
|
55
|
+
>
|
|
56
|
+
{#if context.state.isDark}
|
|
57
|
+
<span class="smrt-color-scheme-toggle__icon">{icons.dark}</span>
|
|
58
|
+
{:else}
|
|
59
|
+
<span class="smrt-color-scheme-toggle__icon">{icons.light}</span>
|
|
60
|
+
{/if}
|
|
61
|
+
{#if showLabels}
|
|
62
|
+
<span class="smrt-color-scheme-toggle__label">
|
|
63
|
+
{labels[context.state.resolvedScheme]}
|
|
64
|
+
</span>
|
|
65
|
+
{/if}
|
|
66
|
+
</button>
|
|
67
|
+
|
|
68
|
+
{:else if variant === 'buttons'}
|
|
69
|
+
<div class="smrt-color-scheme-toggle__buttons">
|
|
70
|
+
{#each ['light', 'dark', 'system'] as scheme}
|
|
71
|
+
<button
|
|
72
|
+
class="smrt-color-scheme-toggle__button"
|
|
73
|
+
class:active={context.state.colorScheme === scheme}
|
|
74
|
+
onclick={() => setScheme(scheme as ColorScheme)}
|
|
75
|
+
type="button"
|
|
76
|
+
>
|
|
77
|
+
<span class="smrt-color-scheme-toggle__icon">{icons[scheme as keyof typeof icons]}</span>
|
|
78
|
+
{#if showLabels}
|
|
79
|
+
<span class="smrt-color-scheme-toggle__label">
|
|
80
|
+
{labels[scheme as keyof typeof labels]}
|
|
81
|
+
</span>
|
|
82
|
+
{/if}
|
|
83
|
+
</button>
|
|
84
|
+
{/each}
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
{:else if variant === 'segmented'}
|
|
88
|
+
<div class="smrt-color-scheme-toggle__segmented" role="radiogroup" aria-label={ariaLabel}>
|
|
89
|
+
{#each ['light', 'dark', 'system'] as scheme}
|
|
90
|
+
<button
|
|
91
|
+
class="smrt-color-scheme-toggle__segment"
|
|
92
|
+
class:active={context.state.colorScheme === scheme}
|
|
93
|
+
onclick={() => setScheme(scheme as ColorScheme)}
|
|
94
|
+
type="button"
|
|
95
|
+
role="radio"
|
|
96
|
+
aria-checked={context.state.colorScheme === scheme}
|
|
97
|
+
>
|
|
98
|
+
<span class="smrt-color-scheme-toggle__icon">
|
|
99
|
+
{icons[scheme as keyof typeof icons]}
|
|
100
|
+
</span>
|
|
101
|
+
{#if showLabels}
|
|
102
|
+
<span class="smrt-color-scheme-toggle__label">
|
|
103
|
+
{labels[scheme as keyof typeof labels]}
|
|
104
|
+
</span>
|
|
105
|
+
{/if}
|
|
106
|
+
</button>
|
|
107
|
+
{/each}
|
|
108
|
+
</div>
|
|
109
|
+
{/if}
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<style>
|
|
113
|
+
.smrt-color-scheme-toggle {
|
|
114
|
+
display: inline-flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.smrt-color-scheme-toggle__switch {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
122
|
+
padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
|
|
123
|
+
border: 1px solid var(--smrt-color-outline, #ccc);
|
|
124
|
+
border-radius: var(--smrt-radius-full, 9999px);
|
|
125
|
+
background: var(--smrt-color-surface-container-low, #f5f5f5);
|
|
126
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
127
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
128
|
+
cursor: pointer;
|
|
129
|
+
transition: all 200ms ease;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.smrt-color-scheme-toggle__switch:hover {
|
|
133
|
+
background: var(--smrt-color-surface-container, #eee);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.smrt-color-scheme-toggle__buttons {
|
|
137
|
+
display: flex;
|
|
138
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.smrt-color-scheme-toggle__button {
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
145
|
+
padding: var(--smrt-spacing-1_5, 0.375rem) var(--smrt-spacing-3, 0.75rem);
|
|
146
|
+
border: 1px solid var(--smrt-color-outline, #ccc);
|
|
147
|
+
border-radius: var(--smrt-radius-md, 0.5rem);
|
|
148
|
+
background: var(--smrt-color-surface-container-low, #f5f5f5);
|
|
149
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
150
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
151
|
+
cursor: pointer;
|
|
152
|
+
transition: all 200ms ease;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.smrt-color-scheme-toggle__button:hover {
|
|
156
|
+
background: var(--smrt-color-surface-container, #eee);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.smrt-color-scheme-toggle__button.active {
|
|
160
|
+
background: var(--smrt-color-primary-container, #e3f2fd);
|
|
161
|
+
color: var(--smrt-color-on-primary-container, #1565c0);
|
|
162
|
+
border-color: var(--smrt-color-primary, #2196f3);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.smrt-color-scheme-toggle__segmented {
|
|
166
|
+
display: inline-flex;
|
|
167
|
+
background: var(--smrt-color-surface-container-lowest, #fafafa);
|
|
168
|
+
border: 1px solid var(--smrt-color-outline, #ccc);
|
|
169
|
+
border-radius: var(--smrt-radius-lg, 0.75rem);
|
|
170
|
+
padding: var(--smrt-spacing-0_5, 0.125rem);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.smrt-color-scheme-toggle__segment {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
177
|
+
padding: var(--smrt-spacing-1_5, 0.375rem) var(--smrt-spacing-3, 0.75rem);
|
|
178
|
+
border: none;
|
|
179
|
+
border-radius: var(--smrt-radius-md, 0.5rem);
|
|
180
|
+
background: transparent;
|
|
181
|
+
color: var(--smrt-color-on-surface-variant, #666);
|
|
182
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
transition: all 200ms ease;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.smrt-color-scheme-toggle__segment:hover {
|
|
188
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.smrt-color-scheme-toggle__segment.active {
|
|
192
|
+
background: var(--smrt-color-surface, white);
|
|
193
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
194
|
+
box-shadow: var(--smrt-elevation-1, 0 1px 2px rgba(0,0,0,0.1));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.smrt-color-scheme-toggle__icon {
|
|
198
|
+
font-size: var(--smrt-typography-body-large-size, 1rem);
|
|
199
|
+
line-height: 1;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.smrt-color-scheme-toggle__label {
|
|
203
|
+
font-size: inherit;
|
|
204
|
+
}
|
|
205
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** Show labels with icons */
|
|
3
|
+
showLabels?: boolean;
|
|
4
|
+
/** Button variant: 'switch' | 'buttons' | 'segmented' */
|
|
5
|
+
variant?: 'switch' | 'buttons' | 'segmented';
|
|
6
|
+
/** Additional CSS class */
|
|
7
|
+
class?: string;
|
|
8
|
+
/** Accessible label */
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const ColorSchemeToggle: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type ColorSchemeToggle = ReturnType<typeof ColorSchemeToggle>;
|
|
13
|
+
export default ColorSchemeToggle;
|
|
14
|
+
//# sourceMappingURL=ColorSchemeToggle.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorSchemeToggle.svelte.d.ts","sourceRoot":"","sources":["../../../src/themes/components/ColorSchemeToggle.svelte.ts"],"names":[],"mappings":"AAOA,UAAU,KAAK;IACb,6BAA6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IAC7C,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwFD,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getThemeContext } from '../context.svelte.js';
|
|
3
|
+
import { getThemeOptions } from '../registry.js';
|
|
4
|
+
import type { ThemePreset } from '../types.js';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
/** Custom label text */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Show icons for each theme */
|
|
10
|
+
showIcons?: boolean;
|
|
11
|
+
/** Button variant: 'select' | 'buttons' | 'segmented' */
|
|
12
|
+
variant?: 'select' | 'buttons' | 'segmented';
|
|
13
|
+
/** Additional CSS class */
|
|
14
|
+
class?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
label = 'Theme',
|
|
19
|
+
showIcons = true,
|
|
20
|
+
variant = 'select',
|
|
21
|
+
class: className = '',
|
|
22
|
+
}: Props = $props();
|
|
23
|
+
|
|
24
|
+
const context = getThemeContext();
|
|
25
|
+
const options = getThemeOptions();
|
|
26
|
+
|
|
27
|
+
function handleChange(event: Event) {
|
|
28
|
+
const select = event.target as HTMLSelectElement;
|
|
29
|
+
context.setPreset(select.value as ThemePreset);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function handlePresetClick(preset: ThemePreset) {
|
|
33
|
+
context.setPreset(preset);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Icons for each theme
|
|
37
|
+
const themeIcons: Record<ThemePreset, string> = {
|
|
38
|
+
material: '🔷',
|
|
39
|
+
glass: '💎',
|
|
40
|
+
studio: '◻️',
|
|
41
|
+
};
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<div class="smrt-theme-switcher {variant} {className}">
|
|
45
|
+
{#if label}
|
|
46
|
+
<span class="smrt-theme-switcher__label">{label}</span>
|
|
47
|
+
{/if}
|
|
48
|
+
|
|
49
|
+
{#if variant === 'select'}
|
|
50
|
+
<select
|
|
51
|
+
class="smrt-theme-switcher__select"
|
|
52
|
+
value={context.state.preset}
|
|
53
|
+
onchange={handleChange}
|
|
54
|
+
>
|
|
55
|
+
{#each options as option}
|
|
56
|
+
<option value={option.value}>
|
|
57
|
+
{#if showIcons}{themeIcons[option.value]} {/if}
|
|
58
|
+
{option.label}
|
|
59
|
+
</option>
|
|
60
|
+
{/each}
|
|
61
|
+
</select>
|
|
62
|
+
|
|
63
|
+
{:else if variant === 'buttons'}
|
|
64
|
+
<div class="smrt-theme-switcher__buttons">
|
|
65
|
+
{#each options as option}
|
|
66
|
+
<button
|
|
67
|
+
class="smrt-theme-switcher__button"
|
|
68
|
+
class:active={context.state.preset === option.value}
|
|
69
|
+
onclick={() => handlePresetClick(option.value)}
|
|
70
|
+
type="button"
|
|
71
|
+
>
|
|
72
|
+
{#if showIcons}
|
|
73
|
+
<span class="smrt-theme-switcher__icon">{themeIcons[option.value]}</span>
|
|
74
|
+
{/if}
|
|
75
|
+
<span class="smrt-theme-switcher__text">{option.label}</span>
|
|
76
|
+
</button>
|
|
77
|
+
{/each}
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
{:else if variant === 'segmented'}
|
|
81
|
+
<div class="smrt-theme-switcher__segmented" role="radiogroup">
|
|
82
|
+
{#each options as option}
|
|
83
|
+
<button
|
|
84
|
+
class="smrt-theme-switcher__segment"
|
|
85
|
+
class:active={context.state.preset === option.value}
|
|
86
|
+
onclick={() => handlePresetClick(option.value)}
|
|
87
|
+
type="button"
|
|
88
|
+
role="radio"
|
|
89
|
+
aria-checked={context.state.preset === option.value}
|
|
90
|
+
>
|
|
91
|
+
{#if showIcons}
|
|
92
|
+
<span class="smrt-theme-switcher__icon">{themeIcons[option.value]}</span>
|
|
93
|
+
{/if}
|
|
94
|
+
<span class="smrt-theme-switcher__text">{option.label}</span>
|
|
95
|
+
</button>
|
|
96
|
+
{/each}
|
|
97
|
+
</div>
|
|
98
|
+
{/if}
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<style>
|
|
102
|
+
.smrt-theme-switcher {
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.smrt-theme-switcher__label {
|
|
109
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
110
|
+
font-weight: var(--smrt-typography-body-medium-weight, 400);
|
|
111
|
+
color: var(--smrt-color-on-surface-variant, inherit);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.smrt-theme-switcher__select {
|
|
115
|
+
padding: var(--smrt-spacing-1_5, 0.375rem) var(--smrt-spacing-3, 0.75rem);
|
|
116
|
+
border-radius: var(--smrt-radius-md, 0.5rem);
|
|
117
|
+
border: 1px solid var(--smrt-color-outline, #ccc);
|
|
118
|
+
background: var(--smrt-color-surface, white);
|
|
119
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
120
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
121
|
+
cursor: pointer;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.smrt-theme-switcher__buttons {
|
|
125
|
+
display: flex;
|
|
126
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.smrt-theme-switcher__button {
|
|
130
|
+
display: flex;
|
|
131
|
+
align-items: center;
|
|
132
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
133
|
+
padding: var(--smrt-spacing-1_5, 0.375rem) var(--smrt-spacing-3, 0.75rem);
|
|
134
|
+
border: 1px solid var(--smrt-color-outline, #ccc);
|
|
135
|
+
border-radius: var(--smrt-radius-md, 0.5rem);
|
|
136
|
+
background: var(--smrt-color-surface-container-low, #f5f5f5);
|
|
137
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
138
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
transition: all 200ms ease;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.smrt-theme-switcher__button:hover {
|
|
144
|
+
background: var(--smrt-color-surface-container, #eee);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.smrt-theme-switcher__button.active {
|
|
148
|
+
background: var(--smrt-color-primary-container, #e3f2fd);
|
|
149
|
+
color: var(--smrt-color-on-primary-container, #1565c0);
|
|
150
|
+
border-color: var(--smrt-color-primary, #2196f3);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.smrt-theme-switcher__segmented {
|
|
154
|
+
display: inline-flex;
|
|
155
|
+
background: var(--smrt-color-surface-container-lowest, #fafafa);
|
|
156
|
+
border: 1px solid var(--smrt-color-outline, #ccc);
|
|
157
|
+
border-radius: var(--smrt-radius-lg, 0.75rem);
|
|
158
|
+
padding: var(--smrt-spacing-0_5, 0.125rem);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.smrt-theme-switcher__segment {
|
|
162
|
+
display: flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
165
|
+
padding: var(--smrt-spacing-1_5, 0.375rem) var(--smrt-spacing-3, 0.75rem);
|
|
166
|
+
border: none;
|
|
167
|
+
border-radius: var(--smrt-radius-md, 0.5rem);
|
|
168
|
+
background: transparent;
|
|
169
|
+
color: var(--smrt-color-on-surface-variant, #666);
|
|
170
|
+
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
transition: all 200ms ease;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.smrt-theme-switcher__segment:hover {
|
|
176
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.smrt-theme-switcher__segment.active {
|
|
180
|
+
background: var(--smrt-color-surface, white);
|
|
181
|
+
color: var(--smrt-color-on-surface, inherit);
|
|
182
|
+
box-shadow: var(--smrt-elevation-1, 0 1px 2px rgba(0,0,0,0.1));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.smrt-theme-switcher__icon {
|
|
186
|
+
font-size: var(--smrt-typography-body-large-size, 1rem);
|
|
187
|
+
}
|
|
188
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** Custom label text */
|
|
3
|
+
label?: string;
|
|
4
|
+
/** Show icons for each theme */
|
|
5
|
+
showIcons?: boolean;
|
|
6
|
+
/** Button variant: 'select' | 'buttons' | 'segmented' */
|
|
7
|
+
variant?: 'select' | 'buttons' | 'segmented';
|
|
8
|
+
/** Additional CSS class */
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const ThemeSwitcher: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type ThemeSwitcher = ReturnType<typeof ThemeSwitcher>;
|
|
13
|
+
export default ThemeSwitcher;
|
|
14
|
+
//# sourceMappingURL=ThemeSwitcher.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeSwitcher.svelte.d.ts","sourceRoot":"","sources":["../../../src/themes/components/ThemeSwitcher.svelte.ts"],"names":[],"mappings":"AAQA,UAAU,KAAK;IACb,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yDAAyD;IACzD,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IAC7C,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA+ED,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Components
|
|
3
|
+
*
|
|
4
|
+
* UI components for theme selection and configuration.
|
|
5
|
+
*/
|
|
6
|
+
export { default as ColorSchemeToggle } from './ColorSchemeToggle.svelte';
|
|
7
|
+
export { default as ThemeSwitcher } from './ThemeSwitcher.svelte';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Context
|
|
3
|
+
*
|
|
4
|
+
* Svelte 5 runes-based context for theme state management.
|
|
5
|
+
* Provides reactive theme state and methods to all child components.
|
|
6
|
+
*/
|
|
7
|
+
import type { ColorScheme, ThemeConfig, ThemeContext, ThemePreset } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Set the theme context in the component tree
|
|
10
|
+
* @param context - Theme context object
|
|
11
|
+
*/
|
|
12
|
+
export declare function setThemeContext(context: ThemeContext): void;
|
|
13
|
+
/**
|
|
14
|
+
* Get the theme context from the component tree
|
|
15
|
+
* @returns Theme context
|
|
16
|
+
* @throws Error if called outside of ThemeProvider
|
|
17
|
+
*/
|
|
18
|
+
export declare function getThemeContext(): ThemeContext;
|
|
19
|
+
/**
|
|
20
|
+
* Try to get the theme context without throwing
|
|
21
|
+
* @returns Theme context or null if not available
|
|
22
|
+
*/
|
|
23
|
+
export declare function tryGetThemeContext(): ThemeContext | null;
|
|
24
|
+
/**
|
|
25
|
+
* Check if theme context is available
|
|
26
|
+
* @returns True if inside ThemeProvider
|
|
27
|
+
*/
|
|
28
|
+
export declare function hasThemeContext(): boolean;
|
|
29
|
+
export type { ThemeContext, ThemePreset, ColorScheme, ThemeConfig };
|
|
30
|
+
//# sourceMappingURL=context.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.svelte.d.ts","sourceRoot":"","sources":["../../src/themes/context.svelte.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACZ,MAAM,YAAY,CAAC;AAKpB;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAU9C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,GAAG,IAAI,CAExD;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAGD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Context
|
|
3
|
+
*
|
|
4
|
+
* Svelte 5 runes-based context for theme state management.
|
|
5
|
+
* Provides reactive theme state and methods to all child components.
|
|
6
|
+
*/
|
|
7
|
+
import { getContext, setContext } from 'svelte';
|
|
8
|
+
/** Context key symbol */
|
|
9
|
+
const THEME_CONTEXT_KEY = Symbol('smrt-theme-context');
|
|
10
|
+
/**
|
|
11
|
+
* Set the theme context in the component tree
|
|
12
|
+
* @param context - Theme context object
|
|
13
|
+
*/
|
|
14
|
+
export function setThemeContext(context) {
|
|
15
|
+
setContext(THEME_CONTEXT_KEY, context);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the theme context from the component tree
|
|
19
|
+
* @returns Theme context
|
|
20
|
+
* @throws Error if called outside of ThemeProvider
|
|
21
|
+
*/
|
|
22
|
+
export function getThemeContext() {
|
|
23
|
+
const context = getContext(THEME_CONTEXT_KEY);
|
|
24
|
+
if (!context) {
|
|
25
|
+
throw new Error('Theme context not found. Make sure to wrap your app with <ThemeProvider> from @smrt/svelte/themes');
|
|
26
|
+
}
|
|
27
|
+
return context;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Try to get the theme context without throwing
|
|
31
|
+
* @returns Theme context or null if not available
|
|
32
|
+
*/
|
|
33
|
+
export function tryGetThemeContext() {
|
|
34
|
+
return getContext(THEME_CONTEXT_KEY) ?? null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if theme context is available
|
|
38
|
+
* @returns True if inside ThemeProvider
|
|
39
|
+
*/
|
|
40
|
+
export function hasThemeContext() {
|
|
41
|
+
return !!tryGetThemeContext();
|
|
42
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Theme Utilities
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for creating custom themes that match the SMRT theme system.
|
|
5
|
+
*/
|
|
6
|
+
import type { ColorPalette, EasingScale, ElevationScale, GlassEffects, Theme, ThemePreset, TypographyScale } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Options for creating a custom theme
|
|
9
|
+
*/
|
|
10
|
+
export interface CreateThemeOptions {
|
|
11
|
+
/** Theme identifier (must be unique) */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Display name */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Light mode color palette */
|
|
16
|
+
light: Partial<ColorPalette> & Pick<ColorPalette, 'primary' | 'background'>;
|
|
17
|
+
/** Dark mode color palette (optional, will be auto-generated if not provided) */
|
|
18
|
+
dark?: Partial<ColorPalette>;
|
|
19
|
+
/** Typography scale (optional, defaults to Material) */
|
|
20
|
+
typography?: Partial<TypographyScale>;
|
|
21
|
+
/** Elevation shadows (optional) */
|
|
22
|
+
elevation?: Partial<ElevationScale>;
|
|
23
|
+
/** Custom easing curves (optional) */
|
|
24
|
+
easing?: Partial<EasingScale>;
|
|
25
|
+
/** Glass effects (optional) */
|
|
26
|
+
glass?: GlassEffects;
|
|
27
|
+
/** Font family */
|
|
28
|
+
fontFamily?: string;
|
|
29
|
+
/** Base theme to extend (copies all tokens as starting point) */
|
|
30
|
+
extend?: ThemePreset;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a custom theme
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { createTheme, registerTheme } from '@happyvertical/smrt-ui/themes';
|
|
38
|
+
*
|
|
39
|
+
* const myTheme = createTheme({
|
|
40
|
+
* id: 'brand',
|
|
41
|
+
* name: 'Brand Theme',
|
|
42
|
+
* light: {
|
|
43
|
+
* primary: '#ff6b35',
|
|
44
|
+
* background: '#fafafa',
|
|
45
|
+
* surface: '#ffffff',
|
|
46
|
+
* },
|
|
47
|
+
* dark: {
|
|
48
|
+
* primary: '#ff8c5a',
|
|
49
|
+
* background: '#0a0a0a',
|
|
50
|
+
* surface: '#1a1a1a',
|
|
51
|
+
* },
|
|
52
|
+
* fontFamily: 'Inter, sans-serif',
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* registerTheme(myTheme);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function createTheme(options: CreateThemeOptions): Theme;
|
|
59
|
+
/**
|
|
60
|
+
* Preload the theme registry for extension support
|
|
61
|
+
* Call this before createTheme if using the extend option
|
|
62
|
+
*/
|
|
63
|
+
export declare function preloadThemeRegistry(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Register a custom theme for use with ThemeProvider
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* import { createTheme, registerTheme } from '@happyvertical/smrt-ui/themes';
|
|
70
|
+
*
|
|
71
|
+
* const customTheme = createTheme({ id: 'brand', name: 'Brand', ... });
|
|
72
|
+
* registerTheme(customTheme);
|
|
73
|
+
*
|
|
74
|
+
* // Now use in your app
|
|
75
|
+
* <ThemeProvider preset="brand" />
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function registerTheme(theme: Theme): void;
|
|
79
|
+
/**
|
|
80
|
+
* Get a registered custom theme
|
|
81
|
+
*/
|
|
82
|
+
export declare function getRegisteredTheme(_id: string): Theme | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Check if a theme is registered
|
|
85
|
+
* Note: This is async due to ESM dynamic import requirements
|
|
86
|
+
*/
|
|
87
|
+
export declare function isThemeRegistered(id: string): Promise<boolean>;
|
|
88
|
+
/**
|
|
89
|
+
* Create a simple theme from just a primary color
|
|
90
|
+
* Auto-generates all other colors
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const brandTheme = createThemeFromColor('#ff6b35', 'brand', 'Brand Theme');
|
|
95
|
+
* registerTheme(brandTheme);
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function createThemeFromColor(primaryColor: string, id: string, name: string, options?: Omit<CreateThemeOptions, 'id' | 'name' | 'light'>): Theme;
|
|
99
|
+
//# sourceMappingURL=create-theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-theme.d.ts","sourceRoot":"","sources":["../../src/themes/create-theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,cAAc,EACd,YAAY,EACZ,KAAK,EACL,WAAW,EACX,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,YAAY,CAAC,CAAC;IAC5E,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7B,wDAAwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACtC,mCAAmC;IACnC,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACpC,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,+BAA+B;IAC/B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAsPD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,KAAK,CAkD9D;AAkBD;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1D;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAIjE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,GAC1D,KAAK,CAWP"}
|