@spatika/react 1.0.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/README.md +72 -0
- package/dist/composites/ActionBar.d.ts +7 -0
- package/dist/composites/ActionBar.d.ts.map +1 -0
- package/dist/composites/ActionBar.js +5 -0
- package/dist/composites/AmountInput.d.ts +10 -0
- package/dist/composites/AmountInput.d.ts.map +1 -0
- package/dist/composites/AmountInput.js +7 -0
- package/dist/composites/AppHeader.d.ts +25 -0
- package/dist/composites/AppHeader.d.ts.map +1 -0
- package/dist/composites/AppHeader.js +13 -0
- package/dist/composites/AppSidebar.d.ts +30 -0
- package/dist/composites/AppSidebar.d.ts.map +1 -0
- package/dist/composites/AppSidebar.js +15 -0
- package/dist/composites/BottomSheet.d.ts +36 -0
- package/dist/composites/BottomSheet.d.ts.map +1 -0
- package/dist/composites/BottomSheet.js +37 -0
- package/dist/composites/Breadcrumb.d.ts +10 -0
- package/dist/composites/Breadcrumb.d.ts.map +1 -0
- package/dist/composites/Breadcrumb.js +10 -0
- package/dist/composites/Callout.d.ts +8 -0
- package/dist/composites/Callout.d.ts.map +1 -0
- package/dist/composites/Callout.js +5 -0
- package/dist/composites/Card.d.ts +31 -0
- package/dist/composites/Card.d.ts.map +1 -0
- package/dist/composites/Card.js +33 -0
- package/dist/composites/Chip.d.ts +13 -0
- package/dist/composites/Chip.d.ts.map +1 -0
- package/dist/composites/Chip.js +59 -0
- package/dist/composites/ChipGroup.d.ts +23 -0
- package/dist/composites/ChipGroup.d.ts.map +1 -0
- package/dist/composites/ChipGroup.js +27 -0
- package/dist/composites/CommandSearchField.d.ts +27 -0
- package/dist/composites/CommandSearchField.d.ts.map +1 -0
- package/dist/composites/CommandSearchField.js +17 -0
- package/dist/composites/CoverHero.d.ts +51 -0
- package/dist/composites/CoverHero.d.ts.map +1 -0
- package/dist/composites/CoverHero.js +71 -0
- package/dist/composites/CoverPattern.d.ts +12 -0
- package/dist/composites/CoverPattern.d.ts.map +1 -0
- package/dist/composites/CoverPattern.js +14 -0
- package/dist/composites/DataTableToolbar.d.ts +13 -0
- package/dist/composites/DataTableToolbar.d.ts.map +1 -0
- package/dist/composites/DataTableToolbar.js +7 -0
- package/dist/composites/DividerLabel.d.ts +5 -0
- package/dist/composites/DividerLabel.d.ts.map +1 -0
- package/dist/composites/DividerLabel.js +5 -0
- package/dist/composites/EmptyState.d.ts +16 -0
- package/dist/composites/EmptyState.d.ts.map +1 -0
- package/dist/composites/EmptyState.js +10 -0
- package/dist/composites/EntityCard.d.ts +31 -0
- package/dist/composites/EntityCard.d.ts.map +1 -0
- package/dist/composites/EntityCard.js +21 -0
- package/dist/composites/EntityMediaCard.d.ts +25 -0
- package/dist/composites/EntityMediaCard.d.ts.map +1 -0
- package/dist/composites/EntityMediaCard.js +17 -0
- package/dist/composites/FilterSheet.d.ts +34 -0
- package/dist/composites/FilterSheet.d.ts.map +1 -0
- package/dist/composites/FilterSheet.js +36 -0
- package/dist/composites/FloatingPageChrome.d.ts +90 -0
- package/dist/composites/FloatingPageChrome.d.ts.map +1 -0
- package/dist/composites/FloatingPageChrome.js +67 -0
- package/dist/composites/FormField.d.ts +15 -0
- package/dist/composites/FormField.d.ts.map +1 -0
- package/dist/composites/FormField.js +9 -0
- package/dist/composites/GlassCard.d.ts +13 -0
- package/dist/composites/GlassCard.d.ts.map +1 -0
- package/dist/composites/GlassCard.js +32 -0
- package/dist/composites/HeaderIconButton.d.ts +13 -0
- package/dist/composites/HeaderIconButton.d.ts.map +1 -0
- package/dist/composites/HeaderIconButton.js +12 -0
- package/dist/composites/ListRow.d.ts +9 -0
- package/dist/composites/ListRow.d.ts.map +1 -0
- package/dist/composites/ListRow.js +6 -0
- package/dist/composites/MediaEntryCard.d.ts +25 -0
- package/dist/composites/MediaEntryCard.d.ts.map +1 -0
- package/dist/composites/MediaEntryCard.js +10 -0
- package/dist/composites/MobileTabBar.d.ts +33 -0
- package/dist/composites/MobileTabBar.d.ts.map +1 -0
- package/dist/composites/MobileTabBar.js +19 -0
- package/dist/composites/NotificationBell.d.ts +28 -0
- package/dist/composites/NotificationBell.d.ts.map +1 -0
- package/dist/composites/NotificationBell.js +25 -0
- package/dist/composites/PageHeader.d.ts +11 -0
- package/dist/composites/PageHeader.d.ts.map +1 -0
- package/dist/composites/PageHeader.js +6 -0
- package/dist/composites/PageShell.d.ts +12 -0
- package/dist/composites/PageShell.d.ts.map +1 -0
- package/dist/composites/PageShell.js +8 -0
- package/dist/composites/PageStickyHeader.d.ts +33 -0
- package/dist/composites/PageStickyHeader.d.ts.map +1 -0
- package/dist/composites/PageStickyHeader.js +19 -0
- package/dist/composites/Pagination.d.ts +7 -0
- package/dist/composites/Pagination.d.ts.map +1 -0
- package/dist/composites/Pagination.js +6 -0
- package/dist/composites/PhotoViewer.d.ts +18 -0
- package/dist/composites/PhotoViewer.d.ts.map +1 -0
- package/dist/composites/PhotoViewer.js +37 -0
- package/dist/composites/PinPad.d.ts +29 -0
- package/dist/composites/PinPad.d.ts.map +1 -0
- package/dist/composites/PinPad.js +58 -0
- package/dist/composites/ProfileHero.d.ts +34 -0
- package/dist/composites/ProfileHero.d.ts.map +1 -0
- package/dist/composites/ProfileHero.js +21 -0
- package/dist/composites/QuickFilterRail.d.ts +25 -0
- package/dist/composites/QuickFilterRail.d.ts.map +1 -0
- package/dist/composites/QuickFilterRail.js +18 -0
- package/dist/composites/QuickSettings.d.ts +27 -0
- package/dist/composites/QuickSettings.d.ts.map +1 -0
- package/dist/composites/QuickSettings.js +18 -0
- package/dist/composites/RichTextEditor.d.ts +13 -0
- package/dist/composites/RichTextEditor.d.ts.map +1 -0
- package/dist/composites/RichTextEditor.js +23 -0
- package/dist/composites/SearchField.d.ts +8 -0
- package/dist/composites/SearchField.d.ts.map +1 -0
- package/dist/composites/SearchField.js +8 -0
- package/dist/composites/SectionPanel.d.ts +16 -0
- package/dist/composites/SectionPanel.d.ts.map +1 -0
- package/dist/composites/SectionPanel.js +8 -0
- package/dist/composites/SegmentedControl.d.ts +17 -0
- package/dist/composites/SegmentedControl.d.ts.map +1 -0
- package/dist/composites/SegmentedControl.js +11 -0
- package/dist/composites/StatCard.d.ts +11 -0
- package/dist/composites/StatCard.d.ts.map +1 -0
- package/dist/composites/StatCard.js +6 -0
- package/dist/composites/StatusDot.d.ts +11 -0
- package/dist/composites/StatusDot.d.ts.map +1 -0
- package/dist/composites/StatusDot.js +23 -0
- package/dist/composites/SurfaceCard.d.ts +12 -0
- package/dist/composites/SurfaceCard.d.ts.map +1 -0
- package/dist/composites/SurfaceCard.js +24 -0
- package/dist/composites/Timeline.d.ts +19 -0
- package/dist/composites/Timeline.d.ts.map +1 -0
- package/dist/composites/Timeline.js +12 -0
- package/dist/composites/Toast.d.ts +26 -0
- package/dist/composites/Toast.d.ts.map +1 -0
- package/dist/composites/Toast.js +49 -0
- package/dist/composites/Toolbar.d.ts +6 -0
- package/dist/composites/Toolbar.d.ts.map +1 -0
- package/dist/composites/Toolbar.js +5 -0
- package/dist/composites/ViewFiltersPanel.d.ts +21 -0
- package/dist/composites/ViewFiltersPanel.d.ts.map +1 -0
- package/dist/composites/ViewFiltersPanel.js +11 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/lib/animations.d.ts +62 -0
- package/dist/lib/animations.d.ts.map +1 -0
- package/dist/lib/animations.js +37 -0
- package/dist/lib/avatar-utils.d.ts +10 -0
- package/dist/lib/avatar-utils.d.ts.map +1 -0
- package/dist/lib/avatar-utils.js +49 -0
- package/dist/lib/chips.d.ts +10 -0
- package/dist/lib/chips.d.ts.map +1 -0
- package/dist/lib/chips.js +30 -0
- package/dist/lib/cn.d.ts +4 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +6 -0
- package/dist/lib/compose-refs.d.ts +6 -0
- package/dist/lib/compose-refs.d.ts.map +1 -0
- package/dist/lib/compose-refs.js +17 -0
- package/dist/lib/cover-chrome.d.ts +9 -0
- package/dist/lib/cover-chrome.d.ts.map +1 -0
- package/dist/lib/cover-chrome.js +23 -0
- package/dist/lib/cover-pattern.d.ts +75 -0
- package/dist/lib/cover-pattern.d.ts.map +1 -0
- package/dist/lib/cover-pattern.js +135 -0
- package/dist/lib/overlay-stack.d.ts +23 -0
- package/dist/lib/overlay-stack.d.ts.map +1 -0
- package/dist/lib/overlay-stack.js +37 -0
- package/dist/lib/portal.d.ts +12 -0
- package/dist/lib/portal.d.ts.map +1 -0
- package/dist/lib/portal.js +12 -0
- package/dist/lib/slot.d.ts +12 -0
- package/dist/lib/slot.d.ts.map +1 -0
- package/dist/lib/slot.js +55 -0
- package/dist/lib/surfaces.d.ts +14 -0
- package/dist/lib/surfaces.d.ts.map +1 -0
- package/dist/lib/surfaces.js +18 -0
- package/dist/lib/themes.d.ts +16 -0
- package/dist/lib/themes.d.ts.map +1 -0
- package/dist/lib/themes.js +53 -0
- package/dist/lib/typography.d.ts +17 -0
- package/dist/lib/typography.d.ts.map +1 -0
- package/dist/lib/typography.js +16 -0
- package/dist/lib/use-controllable-state.d.ts +12 -0
- package/dist/lib/use-controllable-state.d.ts.map +1 -0
- package/dist/lib/use-controllable-state.js +20 -0
- package/dist/lib/use-cover-chrome-bleed.d.ts +9 -0
- package/dist/lib/use-cover-chrome-bleed.d.ts.map +1 -0
- package/dist/lib/use-cover-chrome-bleed.js +28 -0
- package/dist/lib/use-dismissable.d.ts +13 -0
- package/dist/lib/use-dismissable.d.ts.map +1 -0
- package/dist/lib/use-dismissable.js +33 -0
- package/dist/lib/use-floating-position.d.ts +27 -0
- package/dist/lib/use-floating-position.d.ts.map +1 -0
- package/dist/lib/use-floating-position.js +115 -0
- package/dist/lib/use-focus-trap.d.ts +7 -0
- package/dist/lib/use-focus-trap.d.ts.map +1 -0
- package/dist/lib/use-focus-trap.js +61 -0
- package/dist/lib/use-media-query.d.ts +5 -0
- package/dist/lib/use-media-query.d.ts.map +1 -0
- package/dist/lib/use-media-query.js +19 -0
- package/dist/primitives/Accordion.d.ts +24 -0
- package/dist/primitives/Accordion.d.ts.map +1 -0
- package/dist/primitives/Accordion.js +37 -0
- package/dist/primitives/Alert.d.ts +10 -0
- package/dist/primitives/Alert.d.ts.map +1 -0
- package/dist/primitives/Alert.js +25 -0
- package/dist/primitives/AlertDialog.d.ts +33 -0
- package/dist/primitives/AlertDialog.d.ts.map +1 -0
- package/dist/primitives/AlertDialog.js +96 -0
- package/dist/primitives/Avatar.d.ts +15 -0
- package/dist/primitives/Avatar.d.ts.map +1 -0
- package/dist/primitives/Avatar.js +52 -0
- package/dist/primitives/Badge.d.ts +12 -0
- package/dist/primitives/Badge.d.ts.map +1 -0
- package/dist/primitives/Badge.js +27 -0
- package/dist/primitives/Button.d.ts +14 -0
- package/dist/primitives/Button.d.ts.map +1 -0
- package/dist/primitives/Button.js +37 -0
- package/dist/primitives/Checkbox.d.ts +9 -0
- package/dist/primitives/Checkbox.d.ts.map +1 -0
- package/dist/primitives/Checkbox.js +22 -0
- package/dist/primitives/Command.d.ts +17 -0
- package/dist/primitives/Command.d.ts.map +1 -0
- package/dist/primitives/Command.js +33 -0
- package/dist/primitives/Dialog.d.ts +34 -0
- package/dist/primitives/Dialog.d.ts.map +1 -0
- package/dist/primitives/Dialog.js +96 -0
- package/dist/primitives/DropdownMenu.d.ts +65 -0
- package/dist/primitives/DropdownMenu.d.ts.map +1 -0
- package/dist/primitives/DropdownMenu.js +196 -0
- package/dist/primitives/Input.d.ts +4 -0
- package/dist/primitives/Input.d.ts.map +1 -0
- package/dist/primitives/Input.js +6 -0
- package/dist/primitives/Kbd.d.ts +4 -0
- package/dist/primitives/Kbd.d.ts.map +1 -0
- package/dist/primitives/Kbd.js +6 -0
- package/dist/primitives/Label.d.ts +4 -0
- package/dist/primitives/Label.d.ts.map +1 -0
- package/dist/primitives/Label.js +6 -0
- package/dist/primitives/NativeSelect.d.ts +7 -0
- package/dist/primitives/NativeSelect.d.ts.map +1 -0
- package/dist/primitives/NativeSelect.js +10 -0
- package/dist/primitives/Popover.d.ts +29 -0
- package/dist/primitives/Popover.d.ts.map +1 -0
- package/dist/primitives/Popover.js +95 -0
- package/dist/primitives/Progress.d.ts +8 -0
- package/dist/primitives/Progress.d.ts.map +1 -0
- package/dist/primitives/Progress.js +7 -0
- package/dist/primitives/RadioGroup.d.ts +13 -0
- package/dist/primitives/RadioGroup.d.ts.map +1 -0
- package/dist/primitives/RadioGroup.js +33 -0
- package/dist/primitives/Select.d.ts +33 -0
- package/dist/primitives/Select.d.ts.map +1 -0
- package/dist/primitives/Select.js +178 -0
- package/dist/primitives/Separator.d.ts +7 -0
- package/dist/primitives/Separator.d.ts.map +1 -0
- package/dist/primitives/Separator.js +6 -0
- package/dist/primitives/Sheet.d.ts +28 -0
- package/dist/primitives/Sheet.d.ts.map +1 -0
- package/dist/primitives/Sheet.js +96 -0
- package/dist/primitives/Skeleton.d.ts +4 -0
- package/dist/primitives/Skeleton.d.ts.map +1 -0
- package/dist/primitives/Skeleton.js +6 -0
- package/dist/primitives/Slider.d.ts +12 -0
- package/dist/primitives/Slider.d.ts.map +1 -0
- package/dist/primitives/Slider.js +23 -0
- package/dist/primitives/Spinner.d.ts +6 -0
- package/dist/primitives/Spinner.d.ts.map +1 -0
- package/dist/primitives/Spinner.js +7 -0
- package/dist/primitives/StarRating.d.ts +10 -0
- package/dist/primitives/StarRating.d.ts.map +1 -0
- package/dist/primitives/StarRating.js +11 -0
- package/dist/primitives/Switch.d.ts +8 -0
- package/dist/primitives/Switch.d.ts.map +1 -0
- package/dist/primitives/Switch.js +20 -0
- package/dist/primitives/Table.d.ts +13 -0
- package/dist/primitives/Table.d.ts.map +1 -0
- package/dist/primitives/Table.js +20 -0
- package/dist/primitives/Tabs.d.ts +17 -0
- package/dist/primitives/Tabs.d.ts.map +1 -0
- package/dist/primitives/Tabs.js +30 -0
- package/dist/primitives/Textarea.d.ts +4 -0
- package/dist/primitives/Textarea.d.ts.map +1 -0
- package/dist/primitives/Textarea.js +6 -0
- package/dist/primitives/Tooltip.d.ts +31 -0
- package/dist/primitives/Tooltip.d.ts.map +1 -0
- package/dist/primitives/Tooltip.js +94 -0
- package/dist/theme/OriginThemeProvider.d.ts +31 -0
- package/dist/theme/OriginThemeProvider.d.ts.map +1 -0
- package/dist/theme/OriginThemeProvider.js +37 -0
- package/dist/theme/SpatikaThemeProvider.d.ts +36 -0
- package/dist/theme/SpatikaThemeProvider.d.ts.map +1 -0
- package/dist/theme/SpatikaThemeProvider.js +38 -0
- package/package.json +58 -0
- package/src/composites/ActionBar.tsx +25 -0
- package/src/composites/AmountInput.tsx +40 -0
- package/src/composites/AppHeader.tsx +88 -0
- package/src/composites/AppSidebar.tsx +120 -0
- package/src/composites/BottomSheet.tsx +179 -0
- package/src/composites/Breadcrumb.tsx +42 -0
- package/src/composites/Callout.tsx +22 -0
- package/src/composites/Card.tsx +119 -0
- package/src/composites/Chip.tsx +87 -0
- package/src/composites/ChipGroup.component.test.tsx +31 -0
- package/src/composites/ChipGroup.test.ts +16 -0
- package/src/composites/ChipGroup.tsx +86 -0
- package/src/composites/CommandSearchField.tsx +124 -0
- package/src/composites/CoverHero.tsx +359 -0
- package/src/composites/CoverPattern.tsx +90 -0
- package/src/composites/DataTableToolbar.tsx +48 -0
- package/src/composites/DividerLabel.tsx +22 -0
- package/src/composites/EmptyState.tsx +55 -0
- package/src/composites/EntityCard.tsx +100 -0
- package/src/composites/EntityMediaCard.tsx +118 -0
- package/src/composites/FilterSheet.tsx +178 -0
- package/src/composites/FloatingPageChrome.tsx +294 -0
- package/src/composites/FormField.tsx +44 -0
- package/src/composites/GlassCard.tsx +47 -0
- package/src/composites/HeaderIconButton.tsx +49 -0
- package/src/composites/ListRow.tsx +29 -0
- package/src/composites/MediaEntryCard.tsx +95 -0
- package/src/composites/MobileTabBar.tsx +130 -0
- package/src/composites/NotificationBell.tsx +164 -0
- package/src/composites/PageHeader.tsx +27 -0
- package/src/composites/PageShell.tsx +20 -0
- package/src/composites/PageStickyHeader.tsx +157 -0
- package/src/composites/Pagination.tsx +41 -0
- package/src/composites/PhotoViewer.tsx +142 -0
- package/src/composites/PinPad.tsx +163 -0
- package/src/composites/ProfileHero.tsx +163 -0
- package/src/composites/QuickFilterRail.tsx +92 -0
- package/src/composites/QuickSettings.tsx +120 -0
- package/src/composites/RichTextEditor.tsx +103 -0
- package/src/composites/SearchField.tsx +38 -0
- package/src/composites/SectionPanel.tsx +59 -0
- package/src/composites/SegmentedControl.tsx +62 -0
- package/src/composites/StatCard.tsx +26 -0
- package/src/composites/StatusDot.tsx +40 -0
- package/src/composites/SurfaceCard.tsx +44 -0
- package/src/composites/Timeline.tsx +70 -0
- package/src/composites/Toast.tsx +135 -0
- package/src/composites/Toolbar.tsx +19 -0
- package/src/composites/ViewFiltersPanel.tsx +82 -0
- package/src/composites/chrome.test.tsx +170 -0
- package/src/composites/smoke.test.tsx +49 -0
- package/src/index.ts +355 -0
- package/src/lib/animations.ts +47 -0
- package/src/lib/avatar-utils.ts +52 -0
- package/src/lib/chips.ts +58 -0
- package/src/lib/cn.test.ts +16 -0
- package/src/lib/cn.ts +7 -0
- package/src/lib/compose-refs.ts +21 -0
- package/src/lib/cover-chrome.ts +31 -0
- package/src/lib/cover-pattern.ts +242 -0
- package/src/lib/overlay-stack.ts +44 -0
- package/src/lib/portal.tsx +21 -0
- package/src/lib/slot.tsx +69 -0
- package/src/lib/surfaces.ts +57 -0
- package/src/lib/themes.test.ts +73 -0
- package/src/lib/themes.ts +59 -0
- package/src/lib/tokens.test.ts +52 -0
- package/src/lib/typography.ts +27 -0
- package/src/lib/use-controllable-state.ts +38 -0
- package/src/lib/use-cover-chrome-bleed.ts +33 -0
- package/src/lib/use-dismissable.ts +49 -0
- package/src/lib/use-floating-position.ts +168 -0
- package/src/lib/use-focus-trap.ts +73 -0
- package/src/lib/use-media-query.ts +22 -0
- package/src/primitives/Accordion.tsx +114 -0
- package/src/primitives/Alert.tsx +57 -0
- package/src/primitives/AlertDialog.tsx +270 -0
- package/src/primitives/Avatar.tsx +140 -0
- package/src/primitives/Badge.test.tsx +15 -0
- package/src/primitives/Badge.tsx +43 -0
- package/src/primitives/Button.test.tsx +37 -0
- package/src/primitives/Button.tsx +58 -0
- package/src/primitives/Checkbox.tsx +75 -0
- package/src/primitives/Command.tsx +175 -0
- package/src/primitives/Dialog.tsx +241 -0
- package/src/primitives/DropdownMenu.tsx +552 -0
- package/src/primitives/Input.test.tsx +22 -0
- package/src/primitives/Input.tsx +22 -0
- package/src/primitives/Kbd.tsx +17 -0
- package/src/primitives/Label.tsx +20 -0
- package/src/primitives/NativeSelect.tsx +22 -0
- package/src/primitives/Popover.tsx +209 -0
- package/src/primitives/Progress.tsx +31 -0
- package/src/primitives/RadioGroup.tsx +116 -0
- package/src/primitives/Select.tsx +409 -0
- package/src/primitives/Separator.tsx +30 -0
- package/src/primitives/Sheet.tsx +265 -0
- package/src/primitives/Skeleton.tsx +16 -0
- package/src/primitives/Slider.tsx +97 -0
- package/src/primitives/Spinner.tsx +21 -0
- package/src/primitives/StarRating.tsx +53 -0
- package/src/primitives/Switch.tsx +68 -0
- package/src/primitives/Table.tsx +134 -0
- package/src/primitives/Tabs.tsx +97 -0
- package/src/primitives/Textarea.tsx +20 -0
- package/src/primitives/Tooltip.tsx +193 -0
- package/src/primitives/smoke.test.tsx +34 -0
- package/src/test/setup.ts +1 -0
- package/src/theme/SpatikaThemeProvider.test.tsx +82 -0
- package/src/theme/SpatikaThemeProvider.tsx +112 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { cn } from "./cn";
|
|
2
|
+
/** Floating glass pill sitting on a generated / photo cover. */
|
|
3
|
+
export function coverFloatingShellClass(_ink, className) {
|
|
4
|
+
return cn("cover-floating-shell", className);
|
|
5
|
+
}
|
|
6
|
+
export function coverFloatingIconClass(ink) {
|
|
7
|
+
return ink === "light"
|
|
8
|
+
? "text-white/90 hover:bg-white/20 hover:text-white"
|
|
9
|
+
: "text-zinc-800 hover:bg-zinc-950/[0.08] hover:text-zinc-950";
|
|
10
|
+
}
|
|
11
|
+
export function coverPlateClass(ink) {
|
|
12
|
+
return ink === "light"
|
|
13
|
+
? "border border-white/18 bg-black/40 backdrop-blur-[24px] backdrop-saturate-150 shadow-[0_8px_36px_rgba(0,0,0,0.45),inset_0_1px_0_rgba(255,255,255,0.18)]"
|
|
14
|
+
: "border border-white/60 bg-white/55 backdrop-blur-[20px] backdrop-saturate-150 shadow-[0_8px_32px_rgba(0,0,0,0.08),inset_0_1px_0_rgba(255,255,255,0.8)]";
|
|
15
|
+
}
|
|
16
|
+
export function coverTitleClass(ink) {
|
|
17
|
+
return ink === "light"
|
|
18
|
+
? "text-white [text-shadow:0_1px_10px_rgba(0,0,0,0.4)]"
|
|
19
|
+
: "text-zinc-950";
|
|
20
|
+
}
|
|
21
|
+
export function coverMutedClass(ink) {
|
|
22
|
+
return ink === "light" ? "text-white/70" : "text-zinc-600";
|
|
23
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeded cover scenes for profile / story heroes.
|
|
3
|
+
* Compact kit set — journalD ships a larger catalog; kinds here keep the same
|
|
4
|
+
* contract (palette, headerInk, chromeInk, layered SVG geometry).
|
|
5
|
+
*/
|
|
6
|
+
export declare const COVER_PATTERN_KINDS: readonly ["mountains", "aurora", "ocean", "meadow", "dusk", "lake"];
|
|
7
|
+
export type CoverPatternKind = (typeof COVER_PATTERN_KINDS)[number];
|
|
8
|
+
export type CoverPatternInput = {
|
|
9
|
+
seed: string;
|
|
10
|
+
hue: number;
|
|
11
|
+
secondaryHue?: number;
|
|
12
|
+
tertiaryHue?: number;
|
|
13
|
+
dark?: boolean;
|
|
14
|
+
warm?: boolean;
|
|
15
|
+
kind?: CoverPatternKind | null;
|
|
16
|
+
};
|
|
17
|
+
export type CoverNaturePalette = {
|
|
18
|
+
skyTop: string;
|
|
19
|
+
skyBottom: string;
|
|
20
|
+
far: string;
|
|
21
|
+
mid: string;
|
|
22
|
+
near: string;
|
|
23
|
+
accent: string;
|
|
24
|
+
water: string;
|
|
25
|
+
highlight: string;
|
|
26
|
+
star: string;
|
|
27
|
+
};
|
|
28
|
+
export type CoverCircle = {
|
|
29
|
+
cx: number;
|
|
30
|
+
cy: number;
|
|
31
|
+
r: number;
|
|
32
|
+
fill: string;
|
|
33
|
+
opacity?: number;
|
|
34
|
+
};
|
|
35
|
+
export type CoverEllipse = {
|
|
36
|
+
cx: number;
|
|
37
|
+
cy: number;
|
|
38
|
+
rx: number;
|
|
39
|
+
ry: number;
|
|
40
|
+
fill?: string;
|
|
41
|
+
opacity?: number;
|
|
42
|
+
};
|
|
43
|
+
export type CoverPath = {
|
|
44
|
+
d: string;
|
|
45
|
+
fill?: string;
|
|
46
|
+
opacity?: number;
|
|
47
|
+
};
|
|
48
|
+
export type CoverPolygon = {
|
|
49
|
+
points: string;
|
|
50
|
+
fill: string;
|
|
51
|
+
opacity?: number;
|
|
52
|
+
};
|
|
53
|
+
/** `light` = white-ish text on a dark scene; `dark` = near-black text on a pale scene. */
|
|
54
|
+
export type CoverHeaderInk = "light" | "dark";
|
|
55
|
+
export type CoverScene = {
|
|
56
|
+
kind: CoverPatternKind;
|
|
57
|
+
palette: CoverNaturePalette;
|
|
58
|
+
uid: string;
|
|
59
|
+
skyStyle: {
|
|
60
|
+
backgroundColor: string;
|
|
61
|
+
backgroundImage: string;
|
|
62
|
+
};
|
|
63
|
+
headerInk: CoverHeaderInk;
|
|
64
|
+
chromeInk: CoverHeaderInk;
|
|
65
|
+
polygons: CoverPolygon[];
|
|
66
|
+
paths: CoverPath[];
|
|
67
|
+
ellipses: CoverEllipse[];
|
|
68
|
+
circles: CoverCircle[];
|
|
69
|
+
};
|
|
70
|
+
export type CoverPattern = CoverScene;
|
|
71
|
+
export declare function isCoverPatternKind(value: string | null | undefined): value is CoverPatternKind;
|
|
72
|
+
export declare function getCoverPattern(input: CoverPatternInput): CoverScene;
|
|
73
|
+
export declare function getCoverPatternStyle(input: CoverPatternInput): CoverScene["skyStyle"];
|
|
74
|
+
export declare function getCoverPatternKind(input: CoverPatternInput): CoverPatternKind;
|
|
75
|
+
//# sourceMappingURL=cover-pattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cover-pattern.d.ts","sourceRoot":"","sources":["../../src/lib/cover-pattern.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,mBAAmB,qEAOtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AAgCtC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAE9F;AA0FD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,UAAU,CAyBpE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAAC,CAErF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,gBAAgB,CAE9E"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeded cover scenes for profile / story heroes.
|
|
3
|
+
* Compact kit set — journalD ships a larger catalog; kinds here keep the same
|
|
4
|
+
* contract (palette, headerInk, chromeInk, layered SVG geometry).
|
|
5
|
+
*/
|
|
6
|
+
export const COVER_PATTERN_KINDS = [
|
|
7
|
+
"mountains",
|
|
8
|
+
"aurora",
|
|
9
|
+
"ocean",
|
|
10
|
+
"meadow",
|
|
11
|
+
"dusk",
|
|
12
|
+
"lake",
|
|
13
|
+
];
|
|
14
|
+
const VW = 1600;
|
|
15
|
+
const VH = 420;
|
|
16
|
+
function hashSeed(value) {
|
|
17
|
+
let hash = 2166136261;
|
|
18
|
+
const source = value || "User";
|
|
19
|
+
for (let i = 0; i < source.length; i++) {
|
|
20
|
+
hash ^= source.charCodeAt(i);
|
|
21
|
+
hash = Math.imul(hash, 16777619);
|
|
22
|
+
}
|
|
23
|
+
return hash >>> 0;
|
|
24
|
+
}
|
|
25
|
+
function wrapHue(hue) {
|
|
26
|
+
return ((hue % 360) + 360) % 360;
|
|
27
|
+
}
|
|
28
|
+
function pick(hash, salt, modulo) {
|
|
29
|
+
return (hash + salt * 2654435761) % modulo;
|
|
30
|
+
}
|
|
31
|
+
function hsl(h, s, l) {
|
|
32
|
+
return `hsl(${Math.round(wrapHue(h))} ${Math.round(s)}% ${Math.round(l)}%)`;
|
|
33
|
+
}
|
|
34
|
+
function parseHslL(color) {
|
|
35
|
+
const match = color.match(/hsl\(\s*[\d.]+\s+[\d.]+%\s+([\d.]+)%\s*\)/i);
|
|
36
|
+
return match ? Number(match[1]) : null;
|
|
37
|
+
}
|
|
38
|
+
export function isCoverPatternKind(value) {
|
|
39
|
+
return Boolean(value && COVER_PATTERN_KINDS.includes(value));
|
|
40
|
+
}
|
|
41
|
+
function buildPalette(kind, hue, secondary, dark) {
|
|
42
|
+
const skyL = dark ? 14 : kind === "dusk" || kind === "aurora" ? 28 : 78;
|
|
43
|
+
const landL = dark ? 18 : 42;
|
|
44
|
+
const shift = kind === "ocean" || kind === "lake" ? 18 : 0;
|
|
45
|
+
return {
|
|
46
|
+
skyTop: hsl(hue + (kind === "aurora" ? 40 : 8), dark ? 38 : 52, skyL + (dark ? 0 : 8)),
|
|
47
|
+
skyBottom: hsl(hue + shift, dark ? 32 : 48, skyL - 8),
|
|
48
|
+
far: hsl(secondary, 28, landL + 12),
|
|
49
|
+
mid: hsl(hue + 12, 34, landL),
|
|
50
|
+
near: hsl(hue - 8, 38, landL - 8),
|
|
51
|
+
accent: hsl(hue + 48, 62, dark ? 58 : 52),
|
|
52
|
+
water: hsl(hue + 18 + shift, 42, dark ? 28 : 48),
|
|
53
|
+
highlight: hsl(hue + 20, 70, dark ? 72 : 88),
|
|
54
|
+
star: hsl(hue, 20, 96),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function getCoverHeaderInk(palette) {
|
|
58
|
+
const samples = [palette.near, palette.mid, palette.skyBottom];
|
|
59
|
+
const luma = samples.reduce((sum, color) => sum + (parseHslL(color) ?? 50), 0) / samples.length;
|
|
60
|
+
return luma < 36 ? "light" : "dark";
|
|
61
|
+
}
|
|
62
|
+
function getCoverChromeInk(palette) {
|
|
63
|
+
const luma = parseHslL(palette.skyTop);
|
|
64
|
+
return (luma ?? 50) < 42 ? "light" : "dark";
|
|
65
|
+
}
|
|
66
|
+
function ridge(y, amp, phase, fill) {
|
|
67
|
+
const steps = 8;
|
|
68
|
+
let d = `M0 ${VH} L0 ${y}`;
|
|
69
|
+
for (let i = 1; i <= steps; i++) {
|
|
70
|
+
const x = (VW / steps) * i;
|
|
71
|
+
const wave = Math.sin((i + phase) * 0.9) * amp;
|
|
72
|
+
d += ` L${x} ${y + wave}`;
|
|
73
|
+
}
|
|
74
|
+
d += ` L${VW} ${VH} Z`;
|
|
75
|
+
return { d, fill };
|
|
76
|
+
}
|
|
77
|
+
function buildScene(kind, hash, palette) {
|
|
78
|
+
const sunX = 220 + pick(hash, 3, 1100);
|
|
79
|
+
const sunY = kind === "dusk" ? 90 : 70;
|
|
80
|
+
const sunR = kind === "aurora" ? 28 : 46;
|
|
81
|
+
const paths = [
|
|
82
|
+
ridge(250, 28, pick(hash, 5, 6), palette.far),
|
|
83
|
+
ridge(290, 36, pick(hash, 7, 6), palette.mid),
|
|
84
|
+
ridge(340, 22, pick(hash, 9, 6), palette.near),
|
|
85
|
+
];
|
|
86
|
+
const circles = [
|
|
87
|
+
{ cx: sunX, cy: sunY, r: sunR, fill: palette.highlight, opacity: 0.9 },
|
|
88
|
+
];
|
|
89
|
+
const ellipses = [];
|
|
90
|
+
if (kind === "ocean" || kind === "lake") {
|
|
91
|
+
paths.push({
|
|
92
|
+
d: `M0 310 Q400 280 800 320 T${VW} 300 L${VW} ${VH} L0 ${VH} Z`,
|
|
93
|
+
fill: palette.water,
|
|
94
|
+
opacity: 0.85,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if (kind === "aurora") {
|
|
98
|
+
ellipses.push({ cx: 480, cy: 90, rx: 340, ry: 48, fill: palette.accent, opacity: 0.35 }, { cx: 980, cy: 70, rx: 280, ry: 36, fill: palette.highlight, opacity: 0.28 });
|
|
99
|
+
}
|
|
100
|
+
if (kind === "meadow") {
|
|
101
|
+
circles.push({ cx: 180, cy: 360, r: 14, fill: palette.accent, opacity: 0.7 }, { cx: 420, cy: 380, r: 10, fill: palette.highlight, opacity: 0.65 }, { cx: 1280, cy: 350, r: 12, fill: palette.accent, opacity: 0.6 });
|
|
102
|
+
}
|
|
103
|
+
return { polygons: [], paths, ellipses, circles };
|
|
104
|
+
}
|
|
105
|
+
export function getCoverPattern(input) {
|
|
106
|
+
const seed = input.seed || "User";
|
|
107
|
+
const hash = hashSeed(seed);
|
|
108
|
+
const kind = isCoverPatternKind(input.kind)
|
|
109
|
+
? input.kind
|
|
110
|
+
: COVER_PATTERN_KINDS[pick(hash, 1, COVER_PATTERN_KINDS.length)];
|
|
111
|
+
const dark = Boolean(input.dark);
|
|
112
|
+
const warmth = input.warm ? 8 : 0;
|
|
113
|
+
const hue = wrapHue(input.hue + warmth);
|
|
114
|
+
const secondary = wrapHue((input.secondaryHue ?? input.hue + 28) + warmth);
|
|
115
|
+
const palette = buildPalette(kind, hue, secondary, dark);
|
|
116
|
+
const drawn = buildScene(kind, hash, palette);
|
|
117
|
+
return {
|
|
118
|
+
kind,
|
|
119
|
+
palette,
|
|
120
|
+
uid: `n${hash.toString(36)}-${kind}`,
|
|
121
|
+
headerInk: getCoverHeaderInk(palette),
|
|
122
|
+
chromeInk: getCoverChromeInk(palette),
|
|
123
|
+
skyStyle: {
|
|
124
|
+
backgroundColor: palette.skyBottom,
|
|
125
|
+
backgroundImage: `linear-gradient(180deg, ${palette.skyTop} 0%, ${palette.skyBottom} 72%)`,
|
|
126
|
+
},
|
|
127
|
+
...drawn,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export function getCoverPatternStyle(input) {
|
|
131
|
+
return getCoverPattern(input).skyStyle;
|
|
132
|
+
}
|
|
133
|
+
export function getCoverPatternKind(input) {
|
|
134
|
+
return getCoverPattern(input).kind;
|
|
135
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Stacking layers for portaled UI.
|
|
4
|
+
*
|
|
5
|
+
* App shells (e.g. journalD fullscreen story editor) often use z-index ~9999.
|
|
6
|
+
* Floating menus sit just above that; modal dialogs sit above menus.
|
|
7
|
+
*/
|
|
8
|
+
export declare const OVERLAY_Z_INDEX: {
|
|
9
|
+
/** Popovers / selects that are not competing with fullscreen editors. */
|
|
10
|
+
readonly popover: 90;
|
|
11
|
+
/** Dropdown menus (including menus opened inside fullscreen editors). */
|
|
12
|
+
readonly menu: 10000;
|
|
13
|
+
/** Modal overlays + dialog/sheet/alert content. */
|
|
14
|
+
readonly modal: 11000;
|
|
15
|
+
};
|
|
16
|
+
/** Inline styles that beat consumer `.glass { position: relative }` rules. */
|
|
17
|
+
export declare function fixedLayerStyle(zIndex: number, extra?: React.CSSProperties): React.CSSProperties;
|
|
18
|
+
/**
|
|
19
|
+
* Radix-compatible synthetic event for menu `onSelect`.
|
|
20
|
+
* Callers use `event.preventDefault()` to keep the menu open.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createSelectEvent(): Event;
|
|
23
|
+
//# sourceMappingURL=overlay-stack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay-stack.d.ts","sourceRoot":"","sources":["../../src/lib/overlay-stack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,eAAe;IAC1B,yEAAyE;;IAEzE,yEAAyE;;IAEzE,mDAAmD;;CAE3C,CAAC;AAEX,8EAA8E;AAC9E,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,GAC1B,KAAK,CAAC,aAAa,CAMrB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,CAUzC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stacking layers for portaled UI.
|
|
3
|
+
*
|
|
4
|
+
* App shells (e.g. journalD fullscreen story editor) often use z-index ~9999.
|
|
5
|
+
* Floating menus sit just above that; modal dialogs sit above menus.
|
|
6
|
+
*/
|
|
7
|
+
export const OVERLAY_Z_INDEX = {
|
|
8
|
+
/** Popovers / selects that are not competing with fullscreen editors. */
|
|
9
|
+
popover: 90,
|
|
10
|
+
/** Dropdown menus (including menus opened inside fullscreen editors). */
|
|
11
|
+
menu: 10000,
|
|
12
|
+
/** Modal overlays + dialog/sheet/alert content. */
|
|
13
|
+
modal: 11000,
|
|
14
|
+
};
|
|
15
|
+
/** Inline styles that beat consumer `.glass { position: relative }` rules. */
|
|
16
|
+
export function fixedLayerStyle(zIndex, extra) {
|
|
17
|
+
return {
|
|
18
|
+
position: "fixed",
|
|
19
|
+
zIndex,
|
|
20
|
+
...extra,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Radix-compatible synthetic event for menu `onSelect`.
|
|
25
|
+
* Callers use `event.preventDefault()` to keep the menu open.
|
|
26
|
+
*/
|
|
27
|
+
export function createSelectEvent() {
|
|
28
|
+
let prevented = false;
|
|
29
|
+
return {
|
|
30
|
+
preventDefault() {
|
|
31
|
+
prevented = true;
|
|
32
|
+
},
|
|
33
|
+
get defaultPrevented() {
|
|
34
|
+
return prevented;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type PortalProps = {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
container?: HTMLElement | null;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Renders children into `document.body` (or a provided container) via React portal.
|
|
8
|
+
* Mounts synchronously on the client so floating content can be measured in the
|
|
9
|
+
* same layout pass (avoids width=0 positioning flashes).
|
|
10
|
+
*/
|
|
11
|
+
export declare function Portal({ children, container }: PortalProps): React.ReactPortal | null;
|
|
12
|
+
//# sourceMappingURL=portal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../src/lib/portal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,WAAW,4BAO1D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createPortal } from "react-dom";
|
|
2
|
+
/**
|
|
3
|
+
* Renders children into `document.body` (or a provided container) via React portal.
|
|
4
|
+
* Mounts synchronously on the client so floating content can be measured in the
|
|
5
|
+
* same layout pass (avoids width=0 positioning flashes).
|
|
6
|
+
*/
|
|
7
|
+
export function Portal({ children, container }) {
|
|
8
|
+
const target = container ?? (typeof document !== "undefined" ? document.body : null);
|
|
9
|
+
if (!target)
|
|
10
|
+
return null;
|
|
11
|
+
return createPortal(children, target);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type SlotProps = React.HTMLAttributes<HTMLElement> & {
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Renders as its single React element child, merging Slot props onto that child.
|
|
7
|
+
* Used for `asChild` composition on Button, Badge, and overlay triggers.
|
|
8
|
+
*/
|
|
9
|
+
export declare const Slot: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
} & React.RefAttributes<HTMLElement>>;
|
|
12
|
+
//# sourceMappingURL=slot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot.d.ts","sourceRoot":"","sources":["../../src/lib/slot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAyC/B,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG;IAC1D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,IAAI;eAPJ,KAAK,CAAC,SAAS;qCAyB3B,CAAC"}
|
package/dist/lib/slot.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { composeRefs } from "./compose-refs";
|
|
3
|
+
/**
|
|
4
|
+
* Merges two prop objects, composing event handlers and classNames,
|
|
5
|
+
* and merging style objects. Used by Slot for asChild composition.
|
|
6
|
+
*/
|
|
7
|
+
function mergeProps(slotProps, childProps) {
|
|
8
|
+
const override = { ...childProps };
|
|
9
|
+
for (const propName of Object.keys(slotProps)) {
|
|
10
|
+
const slotValue = slotProps[propName];
|
|
11
|
+
const childValue = childProps[propName];
|
|
12
|
+
const isHandler = /^on[A-Z]/.test(propName);
|
|
13
|
+
if (isHandler) {
|
|
14
|
+
if (slotValue && childValue) {
|
|
15
|
+
override[propName] = (...args) => {
|
|
16
|
+
childValue(...args);
|
|
17
|
+
slotValue(...args);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
else if (slotValue) {
|
|
21
|
+
override[propName] = slotValue;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (propName === "style") {
|
|
25
|
+
override[propName] = {
|
|
26
|
+
...(slotValue || {}),
|
|
27
|
+
...(childValue || {}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
else if (propName === "className") {
|
|
31
|
+
override[propName] = [slotValue, childValue].filter(Boolean).join(" ");
|
|
32
|
+
}
|
|
33
|
+
else if (childValue === undefined) {
|
|
34
|
+
override[propName] = slotValue;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return override;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Renders as its single React element child, merging Slot props onto that child.
|
|
41
|
+
* Used for `asChild` composition on Button, Badge, and overlay triggers.
|
|
42
|
+
*/
|
|
43
|
+
export const Slot = React.forwardRef(({ children, ...props }, forwardedRef) => {
|
|
44
|
+
if (!React.isValidElement(children)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const child = children;
|
|
48
|
+
const childProps = (child.props ?? {});
|
|
49
|
+
const merged = mergeProps(props, childProps);
|
|
50
|
+
return React.cloneElement(child, {
|
|
51
|
+
...merged,
|
|
52
|
+
ref: composeRefs(forwardedRef, child.ref),
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
Slot.displayName = "Slot";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const surfaceRadiusCard = "rounded-[var(--radius-card)]";
|
|
2
|
+
export declare const surfaceRadiusControl = "rounded-[var(--radius-control)]";
|
|
3
|
+
export declare const surfaceRadiusPill = "rounded-[var(--radius-pill)]";
|
|
4
|
+
/** Soft profile-style card radius (squarish). */
|
|
5
|
+
export declare const surfaceRadiusProfile = "rounded-lg";
|
|
6
|
+
/** Primary elevated card (About / hero panels). */
|
|
7
|
+
export declare const surfacePrimaryClass: string;
|
|
8
|
+
/** Quieter secondary card. */
|
|
9
|
+
export declare const surfaceSecondaryClass: string;
|
|
10
|
+
/** Detail glass card with soft elevation. */
|
|
11
|
+
export declare const surfaceDetailClass: string;
|
|
12
|
+
/** Minimal dashed supporting strip. */
|
|
13
|
+
export declare const surfaceTertiaryClass: string;
|
|
14
|
+
//# sourceMappingURL=surfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../../src/lib/surfaces.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAChE,eAAO,MAAM,oBAAoB,oCAAoC,CAAC;AACtE,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAEhE,iDAAiD;AACjD,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,mDAAmD;AACnD,eAAO,MAAM,mBAAmB,QAS/B,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,qBAAqB,QAQjC,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,kBAAkB,QAS9B,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,oBAAoB,QAOhC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surface / card hierarchy class recipes.
|
|
3
|
+
* Use with GlassCard or SurfaceCard rather than copying Tailwind strings.
|
|
4
|
+
*/
|
|
5
|
+
import { cn } from "./cn";
|
|
6
|
+
export const surfaceRadiusCard = "rounded-[var(--radius-card)]";
|
|
7
|
+
export const surfaceRadiusControl = "rounded-[var(--radius-control)]";
|
|
8
|
+
export const surfaceRadiusPill = "rounded-[var(--radius-pill)]";
|
|
9
|
+
/** Soft profile-style card radius (squarish). */
|
|
10
|
+
export const surfaceRadiusProfile = "rounded-lg";
|
|
11
|
+
/** Primary elevated card (About / hero panels). */
|
|
12
|
+
export const surfacePrimaryClass = cn("relative h-full overflow-hidden", surfaceRadiusProfile, "border border-border/20", "bg-gradient-to-br from-card via-card to-primary/[0.06] dark:from-card/95 dark:via-card/90 dark:to-primary/[0.08]", "p-3.5 sm:p-5 lg:p-6", "shadow-[0_18px_40px_-24px_rgba(0,0,0,0.35)] dark:shadow-[0_22px_48px_-20px_rgba(0,0,0,0.65)]", "ring-1 ring-inset ring-white/25 dark:ring-white/8", "backdrop-blur-xl");
|
|
13
|
+
/** Quieter secondary card. */
|
|
14
|
+
export const surfaceSecondaryClass = cn("relative h-full overflow-hidden", surfaceRadiusProfile, "border border-border/20", "bg-muted/25 dark:bg-muted/15", "p-3 sm:p-3.5 lg:p-4", "shadow-none", "backdrop-blur-md");
|
|
15
|
+
/** Detail glass card with soft elevation. */
|
|
16
|
+
export const surfaceDetailClass = cn("relative h-full overflow-hidden", surfaceRadiusProfile, "border border-border/25", "bg-card/95 dark:bg-card/80", "p-3 sm:p-4 lg:p-5", "shadow-[0_10px_28px_-18px_rgba(0,0,0,0.28)] dark:shadow-[0_14px_32px_-16px_rgba(0,0,0,0.55)]", "ring-1 ring-inset ring-white/40 dark:ring-white/8", "backdrop-blur-xl");
|
|
17
|
+
/** Minimal dashed supporting strip. */
|
|
18
|
+
export const surfaceTertiaryClass = cn("relative overflow-hidden", surfaceRadiusProfile, "border border-dashed border-border/30", "bg-transparent dark:bg-muted/5", "p-3 sm:p-3.5", "shadow-none");
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Supported theme identifiers applied as classes on a root element. */
|
|
2
|
+
export declare const THEME_IDS: readonly ["mukta", "neelam", "usha", "sandhya"];
|
|
3
|
+
export type ThemeId = (typeof THEME_IDS)[number];
|
|
4
|
+
export declare const DEFAULT_THEME: ThemeId;
|
|
5
|
+
/** Default `localStorage` key used by the docs site and `SpatikaThemeProvider`. */
|
|
6
|
+
export declare const SPATIKA_THEME_STORAGE_KEY = "spk-theme";
|
|
7
|
+
export declare const THEME_LABELS: Record<ThemeId, string>;
|
|
8
|
+
export declare function isThemeId(value: unknown): value is ThemeId;
|
|
9
|
+
export declare function isDarkTheme(theme: ThemeId): boolean;
|
|
10
|
+
/** Read a persisted theme. Returns `null` when missing or invalid. */
|
|
11
|
+
export declare function readStoredTheme(storageKey?: string | false): ThemeId | null;
|
|
12
|
+
/** Persist a theme. No-op when `storageKey` is unset. */
|
|
13
|
+
export declare function writeStoredTheme(storageKey: string | false | undefined, theme: ThemeId): void;
|
|
14
|
+
/** Apply a theme class to an element (defaults to `<html>`). */
|
|
15
|
+
export declare function applyTheme(theme: ThemeId, target?: HTMLElement | null): void;
|
|
16
|
+
//# sourceMappingURL=themes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,SAAS,iDAAkD,CAAC;AAEzE,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,OAAiB,CAAC;AAE9C,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAKhD,CAAC;AAIF,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEnD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,CAQ3E;AAED,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAO7F;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,QASrE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Supported theme identifiers applied as classes on a root element. */
|
|
2
|
+
export const THEME_IDS = ["mukta", "neelam", "usha", "sandhya"];
|
|
3
|
+
export const DEFAULT_THEME = "mukta";
|
|
4
|
+
/** Default `localStorage` key used by the docs site and `SpatikaThemeProvider`. */
|
|
5
|
+
export const SPATIKA_THEME_STORAGE_KEY = "spk-theme";
|
|
6
|
+
export const THEME_LABELS = {
|
|
7
|
+
mukta: "Mukta",
|
|
8
|
+
neelam: "Neelam",
|
|
9
|
+
usha: "Usha",
|
|
10
|
+
sandhya: "Sandhya",
|
|
11
|
+
};
|
|
12
|
+
const THEME_CLASS_LIST = ["neelam", "usha", "sandhya"];
|
|
13
|
+
export function isThemeId(value) {
|
|
14
|
+
return typeof value === "string" && THEME_IDS.includes(value);
|
|
15
|
+
}
|
|
16
|
+
export function isDarkTheme(theme) {
|
|
17
|
+
return theme === "neelam" || theme === "sandhya";
|
|
18
|
+
}
|
|
19
|
+
/** Read a persisted theme. Returns `null` when missing or invalid. */
|
|
20
|
+
export function readStoredTheme(storageKey) {
|
|
21
|
+
if (!storageKey || typeof window === "undefined")
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
const value = window.localStorage.getItem(storageKey);
|
|
25
|
+
return isThemeId(value) ? value : null;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Persist a theme. No-op when `storageKey` is unset. */
|
|
32
|
+
export function writeStoredTheme(storageKey, theme) {
|
|
33
|
+
if (!storageKey || typeof window === "undefined")
|
|
34
|
+
return;
|
|
35
|
+
try {
|
|
36
|
+
window.localStorage.setItem(storageKey, theme);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Private mode / quota — keep the in-memory theme.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Apply a theme class to an element (defaults to `<html>`). */
|
|
43
|
+
export function applyTheme(theme, target) {
|
|
44
|
+
if (typeof document === "undefined")
|
|
45
|
+
return;
|
|
46
|
+
const root = target ?? document.documentElement;
|
|
47
|
+
root.classList.remove(...THEME_CLASS_LIST);
|
|
48
|
+
if (theme !== DEFAULT_THEME) {
|
|
49
|
+
root.classList.add(theme);
|
|
50
|
+
}
|
|
51
|
+
root.setAttribute("data-spk-theme", theme);
|
|
52
|
+
root.style.colorScheme = isDarkTheme(theme) ? "dark" : "light";
|
|
53
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named typography roles for the Spatika design language.
|
|
3
|
+
* Prefer these over ad-hoc text-[10px] font-black uppercase strings.
|
|
4
|
+
*/
|
|
5
|
+
/** Uppercase micro-label (section kickers, chip group titles). */
|
|
6
|
+
export declare const typographyEyebrow = "text-[10px] font-black uppercase tracking-widest text-muted-foreground/70";
|
|
7
|
+
/** Slightly stronger eyebrow for page bands. */
|
|
8
|
+
export declare const typographyBandEyebrow = "text-[10px] font-black uppercase tracking-[0.2em] text-muted-foreground/55";
|
|
9
|
+
/** Compact card / filter section title. */
|
|
10
|
+
export declare const typographySectionLabel = "text-[10px] font-black uppercase tracking-widest text-muted-foreground";
|
|
11
|
+
/** Primary page title treatment (pairs with .app-title CSS when preferred). */
|
|
12
|
+
export declare const typographyPageTitle = "text-2xl font-black tracking-tight text-foreground sm:text-3xl";
|
|
13
|
+
/** Supporting copy under titles. */
|
|
14
|
+
export declare const typographyPageSubtitle = "text-sm font-medium leading-relaxed text-muted-foreground";
|
|
15
|
+
/** Dense body used in admin / settings panels. */
|
|
16
|
+
export declare const typographyBodyDense = "text-sm font-medium leading-snug text-foreground";
|
|
17
|
+
//# sourceMappingURL=typography.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../src/lib/typography.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,8EAC+C,CAAC;AAE9E,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,+EAC4C,CAAC;AAE/E,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,2EACuC,CAAC;AAE3E,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,mEACkC,CAAC;AAEnE,oCAAoC;AACpC,eAAO,MAAM,sBAAsB,8DAC0B,CAAC;AAE9D,kDAAkD;AAClD,eAAO,MAAM,mBAAmB,qDAAqD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named typography roles for the Spatika design language.
|
|
3
|
+
* Prefer these over ad-hoc text-[10px] font-black uppercase strings.
|
|
4
|
+
*/
|
|
5
|
+
/** Uppercase micro-label (section kickers, chip group titles). */
|
|
6
|
+
export const typographyEyebrow = "text-[10px] font-black uppercase tracking-widest text-muted-foreground/70";
|
|
7
|
+
/** Slightly stronger eyebrow for page bands. */
|
|
8
|
+
export const typographyBandEyebrow = "text-[10px] font-black uppercase tracking-[0.2em] text-muted-foreground/55";
|
|
9
|
+
/** Compact card / filter section title. */
|
|
10
|
+
export const typographySectionLabel = "text-[10px] font-black uppercase tracking-widest text-muted-foreground";
|
|
11
|
+
/** Primary page title treatment (pairs with .app-title CSS when preferred). */
|
|
12
|
+
export const typographyPageTitle = "text-2xl font-black tracking-tight text-foreground sm:text-3xl";
|
|
13
|
+
/** Supporting copy under titles. */
|
|
14
|
+
export const typographyPageSubtitle = "text-sm font-medium leading-relaxed text-muted-foreground";
|
|
15
|
+
/** Dense body used in admin / settings panels. */
|
|
16
|
+
export const typographyBodyDense = "text-sm font-medium leading-snug text-foreground";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type UseControllableStateParams<T> = {
|
|
2
|
+
prop?: T;
|
|
3
|
+
defaultProp?: T;
|
|
4
|
+
onChange?: (value: T) => void;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Controlled/uncontrolled state helper (Radix-style).
|
|
8
|
+
* When `prop` is provided the state is controlled; otherwise it uses local state.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useControllableState<T>({ prop, defaultProp, onChange, }: UseControllableStateParams<T>): [T | undefined, (value: T | ((prev: T | undefined) => T)) => void];
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=use-controllable-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-controllable-state.d.ts","sourceRoot":"","sources":["../../src/lib/use-controllable-state.ts"],"names":[],"mappings":"AAEA,KAAK,0BAA0B,CAAC,CAAC,IAAI;IACnC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,EACtC,IAAI,EACJ,WAAW,EACX,QAAQ,GACT,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAqBpG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Controlled/uncontrolled state helper (Radix-style).
|
|
4
|
+
* When `prop` is provided the state is controlled; otherwise it uses local state.
|
|
5
|
+
*/
|
|
6
|
+
export function useControllableState({ prop, defaultProp, onChange, }) {
|
|
7
|
+
const [uncontrolled, setUncontrolled] = React.useState(defaultProp);
|
|
8
|
+
const isControlled = prop !== undefined;
|
|
9
|
+
const value = isControlled ? prop : uncontrolled;
|
|
10
|
+
const setValue = React.useCallback((next) => {
|
|
11
|
+
const resolved = typeof next === "function"
|
|
12
|
+
? next(value)
|
|
13
|
+
: next;
|
|
14
|
+
if (!isControlled) {
|
|
15
|
+
setUncontrolled(resolved);
|
|
16
|
+
}
|
|
17
|
+
onChange?.(resolved);
|
|
18
|
+
}, [isControlled, onChange, value]);
|
|
19
|
+
return [value, setValue];
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Foreground ink the app chrome should use while it floats over a cover surface. */
|
|
2
|
+
export type CoverChromeInk = "light" | "dark";
|
|
3
|
+
/**
|
|
4
|
+
* Tells the fixed app header to go transparent so a page cover (profile hero,
|
|
5
|
+
* story hero, …) can paint through it. Cleared on unmount and whenever the
|
|
6
|
+
* cover has scrolled away.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useCoverChromeBleed(active: boolean, ink: CoverChromeInk): void;
|
|
9
|
+
//# sourceMappingURL=use-cover-chrome-bleed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-cover-chrome-bleed.d.ts","sourceRoot":"","sources":["../../src/lib/use-cover-chrome-bleed.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAsB9E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useLayoutEffect } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Tells the fixed app header to go transparent so a page cover (profile hero,
|
|
4
|
+
* story hero, …) can paint through it. Cleared on unmount and whenever the
|
|
5
|
+
* cover has scrolled away.
|
|
6
|
+
*/
|
|
7
|
+
export function useCoverChromeBleed(active, ink) {
|
|
8
|
+
useLayoutEffect(() => {
|
|
9
|
+
const root = document.documentElement;
|
|
10
|
+
if (!active) {
|
|
11
|
+
root.removeAttribute("data-cover-chrome-bleed");
|
|
12
|
+
root.removeAttribute("data-cover-chrome-ink");
|
|
13
|
+
root.removeAttribute("data-profile-cover-bleed");
|
|
14
|
+
root.removeAttribute("data-profile-cover-ink");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
root.setAttribute("data-cover-chrome-bleed", "true");
|
|
18
|
+
root.setAttribute("data-cover-chrome-ink", ink);
|
|
19
|
+
root.setAttribute("data-profile-cover-bleed", "true");
|
|
20
|
+
root.setAttribute("data-profile-cover-ink", ink);
|
|
21
|
+
return () => {
|
|
22
|
+
root.removeAttribute("data-cover-chrome-bleed");
|
|
23
|
+
root.removeAttribute("data-cover-chrome-ink");
|
|
24
|
+
root.removeAttribute("data-profile-cover-bleed");
|
|
25
|
+
root.removeAttribute("data-profile-cover-ink");
|
|
26
|
+
};
|
|
27
|
+
}, [active, ink]);
|
|
28
|
+
}
|