@atom-learning/components 9.0.0 → 10.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion/Accordion.js +1 -1
- package/dist/components/accordion/AccordionContent.js +1 -1
- package/dist/components/accordion/AccordionItem.js +1 -1
- package/dist/components/accordion/AccordionTrigger.js +2 -2
- package/dist/components/action-icon/ActionIcon.js +1 -1
- package/dist/components/alert-dialog/Alert.d.ts +3 -0
- package/dist/components/alert-dialog/Alert.js +7 -0
- package/dist/components/alert-dialog/Alert.js.map +1 -0
- package/dist/components/alert-dialog/AlertDialog.context.js +9 -6
- package/dist/components/alert-dialog/AlertDialog.context.js.map +1 -1
- package/dist/components/alert-dialog/alert-context/AlertDialog.js +1 -1
- package/dist/components/alert-dialog/alert-context/reducer.js +1 -5
- package/dist/components/alert-dialog/alert-context/reducer.js.map +1 -1
- package/dist/components/alert-dialog/alert-context/types.d.ts +1 -2
- package/dist/components/avatar/Avatar.js +5 -6
- package/dist/components/avatar/Avatar.js.map +1 -1
- package/dist/components/avatar/AvatarIcon.js +2 -2
- package/dist/components/avatar/AvatarIcon.js.map +1 -1
- package/dist/components/avatar/AvatarInitial.js +2 -2
- package/dist/components/avatar/AvatarInitial.js.map +1 -1
- package/dist/components/badge/Badge.context.js +12 -13
- package/dist/components/badge/Badge.context.js.map +1 -1
- package/dist/components/badge/Badge.js +4 -3
- package/dist/components/badge/Badge.js.map +1 -1
- package/dist/components/badge/BadgeText.js +3 -3
- package/dist/components/badge/BadgeText.js.map +1 -1
- package/dist/components/banner/Banner.context.js +13 -14
- package/dist/components/banner/Banner.context.js.map +1 -1
- package/dist/components/banner/banner-regular/BannerRegularActions.js +2 -8
- package/dist/components/banner/banner-regular/BannerRegularActions.js.map +1 -1
- package/dist/components/banner/banner-regular/BannerRegularButton.js +2 -2
- package/dist/components/banner/banner-regular/BannerRegularButton.js.map +1 -1
- package/dist/components/banner/banner-regular/BannerRegularDismiss.js +1 -1
- package/dist/components/banner/banner-regular/BannerRegularDismiss.js.map +1 -1
- package/dist/components/banner/banner-slim/BannerSlimButton.js +2 -2
- package/dist/components/banner/banner-slim/BannerSlimButton.js.map +1 -1
- package/dist/components/banner/banner-slim/BannerSlimContainer.js +4 -13
- package/dist/components/banner/banner-slim/BannerSlimContainer.js.map +1 -1
- package/dist/components/calendar/Calendar.d.ts +1 -1
- package/dist/components/calendar/Calendar.js +6 -4
- package/dist/components/calendar/Calendar.js.map +1 -1
- package/dist/components/carousel/Carousel.js +2 -2
- package/dist/components/carousel/Carousel.js.map +1 -1
- package/dist/components/carousel/CarouselSlide.js +1 -1
- package/dist/components/carousel/CarouselSlide.js.map +1 -1
- package/dist/components/carousel/CarouselSlider.js +1 -1
- package/dist/components/carousel/CarouselSlider.js.map +1 -1
- package/dist/components/checkbox/Checkbox.js +2 -2
- package/dist/components/checkbox/Checkbox.js.map +1 -1
- package/dist/components/checkbox-field/CheckboxField.js +7 -3
- package/dist/components/checkbox-field/CheckboxField.js.map +1 -1
- package/dist/components/checkbox-group/CheckboxGroup.d.ts +1 -1
- package/dist/components/checkbox-group/CheckboxGroupAllItem.js +2 -2
- package/dist/components/checkbox-group/CheckboxGroupAllItem.js.map +1 -1
- package/dist/components/checkbox-group/CheckboxGroupChecked.context.js +13 -14
- package/dist/components/checkbox-group/CheckboxGroupChecked.context.js.map +1 -1
- package/dist/components/checkbox-group/CheckboxGroupItem.js +2 -2
- package/dist/components/checkbox-group/CheckboxGroupItem.js.map +1 -1
- package/dist/components/checkbox-group/CheckboxGroupMounted.context.js +6 -7
- package/dist/components/checkbox-group/CheckboxGroupMounted.context.js.map +1 -1
- package/dist/components/chip/Chip.js +4 -5
- package/dist/components/chip/Chip.js.map +1 -1
- package/dist/components/create-password-field/CreatePasswordField.js +1 -1
- package/dist/components/create-password-field/CreatePasswordField.js.map +1 -1
- package/dist/components/data-table/DataTable.context.js +43 -26
- package/dist/components/data-table/DataTable.context.js.map +1 -1
- package/dist/components/data-table/DataTable.types.d.ts +1 -0
- package/dist/components/data-table/DataTable.types.js.map +1 -1
- package/dist/components/data-table/DataTableBulkActionsFloating.js +3 -7
- package/dist/components/data-table/DataTableBulkActionsFloating.js.map +1 -1
- package/dist/components/data-table/DataTableGlobalFilter.js +16 -8
- package/dist/components/data-table/DataTableGlobalFilter.js.map +1 -1
- package/dist/components/data-table/DataTableHead.js +5 -14
- package/dist/components/data-table/DataTableHead.js.map +1 -1
- package/dist/components/data-table/DataTableHeaderCell.js +1 -1
- package/dist/components/data-table/DataTableRowSelectionCheckbox.js +1 -0
- package/dist/components/data-table/DataTableRowSelectionCheckbox.js.map +1 -1
- package/dist/components/data-table/DataTableSelectAllRowsCheckbox.js +2 -1
- package/dist/components/data-table/DataTableSelectAllRowsCheckbox.js.map +1 -1
- package/dist/components/data-table/DataTableTable.js +8 -6
- package/dist/components/data-table/DataTableTable.js.map +1 -1
- package/dist/components/data-table/drag-and-drop/DragAndDropTable.js +1 -1
- package/dist/components/data-table/drag-and-drop/DragAndDropTable.js.map +1 -1
- package/dist/components/data-table/pagination/Pagination.js +3 -2
- package/dist/components/data-table/pagination/Pagination.js.map +1 -1
- package/dist/components/data-table/usePagination.d.ts +1 -0
- package/dist/components/data-table/usePagination.js +7 -2
- package/dist/components/data-table/usePagination.js.map +1 -1
- package/dist/components/date-input/DateInput.js +4 -3
- package/dist/components/date-input/DateInput.js.map +1 -1
- package/dist/components/dismissible/DismissibleRoot.js +15 -16
- package/dist/components/dismissible/DismissibleRoot.js.map +1 -1
- package/dist/components/dismissible/DismissibleTrigger.js +1 -1
- package/dist/components/dismissible/DismissibleTrigger.js.map +1 -1
- package/dist/components/dismissible-group/DismissibleGroupItem.js +1 -1
- package/dist/components/dismissible-group/DismissibleGroupItem.js.map +1 -1
- package/dist/components/dismissible-group/DismissibleGroupRoot.js +5 -6
- package/dist/components/dismissible-group/DismissibleGroupRoot.js.map +1 -1
- package/dist/components/drawer/Drawer.context.js +2 -3
- package/dist/components/drawer/Drawer.context.js.map +1 -1
- package/dist/components/drawer/DrawerContent.js +1 -1
- package/dist/components/drawer/DrawerContent.js.map +1 -1
- package/dist/components/empty-state/EmptyState.context.js +2 -3
- package/dist/components/empty-state/EmptyState.context.js.map +1 -1
- package/dist/components/empty-state/EmptyStateBody.js +1 -1
- package/dist/components/empty-state/EmptyStateBody.js.map +1 -1
- package/dist/components/empty-state/EmptyStateImage.js +1 -1
- package/dist/components/empty-state/EmptyStateImage.js.map +1 -1
- package/dist/components/empty-state/EmptyStateTitle.js +1 -1
- package/dist/components/empty-state/EmptyStateTitle.js.map +1 -1
- package/dist/components/file-drop/FileDrop.js +3 -3
- package/dist/components/file-drop/FileDrop.js.map +1 -1
- package/dist/components/file-drop/useFileDrop.js +1 -1
- package/dist/components/file-drop/useFileDrop.js.map +1 -1
- package/dist/components/file-input/FileInput.js +1 -1
- package/dist/components/form/Form.js +7 -6
- package/dist/components/form/Form.js.map +1 -1
- package/dist/components/form/useFormCustomContext.js +1 -1
- package/dist/components/form/useFormCustomContext.js.map +1 -1
- package/dist/components/index.d.ts +1 -3
- package/dist/components/inline-message/InlineMessage.js +1 -1
- package/dist/components/input/Input.js +2 -2
- package/dist/components/input/Input.js.map +1 -1
- package/dist/components/keyboard-shortcut/KeyboardShortcut.js +10 -7
- package/dist/components/keyboard-shortcut/KeyboardShortcut.js.map +1 -1
- package/dist/components/markdown-content/MarkdownContent.d.ts +1 -1
- package/dist/components/markdown-content/MarkdownContent.js +9 -9
- package/dist/components/markdown-content/MarkdownContent.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownEmphasis.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownEmphasis.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownHeading.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownHeading.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownLink.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownLink.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownList.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownList.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownListItem.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownListItem.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownParagraph.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownParagraph.js.map +1 -1
- package/dist/components/markdown-content/components/MarkdownStrong.d.ts +2 -2
- package/dist/components/markdown-content/components/MarkdownStrong.js.map +1 -1
- package/dist/components/navigation/NavigationMenu.context.js +1 -1
- package/dist/components/navigation/NavigationMenu.context.js.map +1 -1
- package/dist/components/navigation/NavigationMenu.js +8 -7
- package/dist/components/navigation/NavigationMenu.js.map +1 -1
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordion.d.ts +2 -2
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordion.js +3 -3
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordion.js.map +1 -1
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordionContent.js +1 -1
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordionContent.js.map +1 -1
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordionTrigger.js +1 -1
- package/dist/components/navigation-menu-vertical/NavigationMenuVerticalAccordionTrigger.js.map +1 -1
- package/dist/components/number-input/NumberInput.js +15 -16
- package/dist/components/number-input/NumberInput.js.map +1 -1
- package/dist/components/number-input-field/NumberInputField.js +7 -3
- package/dist/components/number-input-field/NumberInputField.js.map +1 -1
- package/dist/components/pagination/Pagination.context.js +29 -22
- package/dist/components/pagination/Pagination.context.js.map +1 -1
- package/dist/components/pagination/usePagination.js +1 -1
- package/dist/components/pagination/usePagination.js.map +1 -1
- package/dist/components/password-input/PasswordInput.js +1 -2
- package/dist/components/password-input/PasswordInput.js.map +1 -1
- package/dist/components/radio-button-field/RadioButtonField.js +7 -3
- package/dist/components/radio-button-field/RadioButtonField.js.map +1 -1
- package/dist/components/search-input/SearchInput.js +7 -11
- package/dist/components/search-input/SearchInput.js.map +1 -1
- package/dist/components/section-message/SectionMessage.context.js +15 -16
- package/dist/components/section-message/SectionMessage.context.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlBadge.js +1 -1
- package/dist/components/segmented-control/SegmentedControlBadge.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlDescription.js +1 -1
- package/dist/components/segmented-control/SegmentedControlDescription.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlHeading.js +1 -1
- package/dist/components/segmented-control/SegmentedControlHeading.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlIcon.js +1 -1
- package/dist/components/segmented-control/SegmentedControlIcon.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlItem.js +1 -1
- package/dist/components/segmented-control/SegmentedControlItem.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlItemList.js +20 -14
- package/dist/components/segmented-control/SegmentedControlItemList.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControlRoot.js +14 -18
- package/dist/components/segmented-control/SegmentedControlRoot.js.map +1 -1
- package/dist/components/select-menu/SelectMenu.context.js +1 -1
- package/dist/components/select-menu/SelectMenu.context.js.map +1 -1
- package/dist/components/select-menu/SelectMenu.js +18 -12
- package/dist/components/select-menu/SelectMenu.js.map +1 -1
- package/dist/components/side-bar/SideBar.context.js +1 -1
- package/dist/components/side-bar/SideBar.context.js.map +1 -1
- package/dist/components/side-bar/SideBar.js +2 -2
- package/dist/components/side-bar/SideBar.js.map +1 -1
- package/dist/components/slider-field/SliderField.js +8 -3
- package/dist/components/slider-field/SliderField.js.map +1 -1
- package/dist/components/sortable/SortableRoot.js +5 -3
- package/dist/components/sortable/SortableRoot.js.map +1 -1
- package/dist/components/stepper/Stepper.context.js +38 -30
- package/dist/components/stepper/Stepper.context.js.map +1 -1
- package/dist/components/tabs/TabsTriggerList.js +1 -1
- package/dist/components/toast/Toast.context.js +1 -1
- package/dist/components/toast/Toast.context.js.map +1 -1
- package/dist/components/toast/ToastProvider.js +1 -1
- package/dist/components/toast/ToastProvider.js.map +1 -1
- package/dist/components/tree/TreeCollapsible.d.ts +2 -2
- package/dist/components/tree/TreeCollapsible.js +3 -3
- package/dist/components/tree/TreeCollapsible.js.map +1 -1
- package/dist/components/tree/TreeCollapsibleContent.js +1 -1
- package/dist/components/tree/TreeCollapsibleContent.js.map +1 -1
- package/dist/components/tree/TreeCollapsibleTrigger.js +1 -1
- package/dist/components/tree/TreeCollapsibleTrigger.js.map +1 -1
- package/dist/docgen.json +1 -1
- package/dist/index.cjs.js +1299 -1244
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +7 -7
- package/dist/styled.js +5 -1
- package/dist/styled.js.map +1 -1
- package/dist/utilities/hooks/useCallbackRef.d.ts +3 -3
- package/dist/utilities/hooks/useCallbackRef.js +4 -1
- package/dist/utilities/hooks/useCallbackRef.js.map +1 -1
- package/dist/utilities/hooks/useResizeObserver.js +13 -3
- package/dist/utilities/hooks/useResizeObserver.js.map +1 -1
- package/dist/utilities/hooks/useScrollPosition.js +22 -17
- package/dist/utilities/hooks/useScrollPosition.js.map +1 -1
- package/dist/utilities/hooks/useWindowScrollPosition.js +19 -15
- package/dist/utilities/hooks/useWindowScrollPosition.js.map +1 -1
- package/dist/utilities/uri/index.js +1 -6
- package/dist/utilities/uri/index.js.map +1 -1
- package/package.json +39 -35
- package/dist/components/index.js +0 -102
- package/dist/components/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Theme, cn, createTheme, styled } from "./styled.js";
|
|
2
|
+
import { ColorScheme } from "./experiments/color-scheme/ColorScheme.js";
|
|
3
|
+
import { Icon } from "./components/icon/Icon.js";
|
|
4
|
+
import { Accordion } from "./components/accordion/Accordion.js";
|
|
5
|
+
import { Tooltip } from "./components/tooltip/Tooltip.js";
|
|
6
|
+
import { ActionIcon } from "./components/action-icon/ActionIcon.js";
|
|
7
|
+
import { AlertDialog } from "./components/alert-dialog/AlertDialog.js";
|
|
2
8
|
import { Loader } from "./components/loader/Loader.js";
|
|
3
9
|
import { Button, StyledButton } from "./components/button/Button.js";
|
|
4
10
|
import { Heading } from "./components/heading/Heading.js";
|
|
5
11
|
import { Text } from "./components/text/Text.js";
|
|
6
|
-
import { AlertDialog } from "./components/alert-dialog/AlertDialog.js";
|
|
7
|
-
import { Icon } from "./components/icon/Icon.js";
|
|
8
12
|
import { useAlert } from "./components/alert-dialog/AlertDialog.context.js";
|
|
9
|
-
import {
|
|
10
|
-
import { Accordion } from "./components/accordion/Accordion.js";
|
|
11
|
-
import { Tooltip } from "./components/tooltip/Tooltip.js";
|
|
12
|
-
import { ActionIcon } from "./components/action-icon/ActionIcon.js";
|
|
13
|
+
import { Alert } from "./components/alert-dialog/Alert.js";
|
|
13
14
|
import { Link, StyledLink } from "./components/link/Link.js";
|
|
14
15
|
import { Image } from "./components/image/Image.js";
|
|
15
16
|
import { Avatar } from "./components/avatar/Avatar.js";
|
|
@@ -96,5 +97,4 @@ import { KeyboardShortcut } from "./components/keyboard-shortcut/index.js";
|
|
|
96
97
|
import { SegmentedControl } from "./components/segmented-control/SegmentedControl.js";
|
|
97
98
|
import { FileDrop } from "./components/file-drop/FileDrop.js";
|
|
98
99
|
import { useFileDrop } from "./components/file-drop/useFileDrop.js";
|
|
99
|
-
import { Alert } from "./components/index.js";
|
|
100
100
|
export { Accordion, ActionIcon, Alert, AlertDialog, Avatar, Badge, BannerRegular, BannerSlim, Button, Carousel, Checkbox, CheckboxField, CheckboxGroup, CheckboxTree, Chip, ChipDismissibleGroup, ChipGroup, ChipToggleGroup, ColorScheme, Combobox, CreatePasswordField, DataTable, DateField, DateInput, Dialog, Dismissible, DismissibleGroup, Divider, Drawer, DropdownMenu, EmptyState, FieldWrapper, FileDrop, FileInput, Form, Heading, Icon, Image, InlineFieldWrapper, InlineMessage, Input, InputBackground, InputField, InputText, KeyboardShortcut, Label, Link, List, Loader, MarkdownContent, NavigationMenu, NavigationMenuVertical, NotificationBadge, NumberInput, NumberInputField, Pagination, PasswordField, PasswordInput, Popover, ProgressBar, RadioButton, RadioButtonField, RadioButtonGroup, RadioCard, RadioCardGroup, SearchField, SearchInput, SectionMessage, SegmentedControl, Select, SelectField, SelectMenu, SelectMenuField, SideBar, skeleton_loader_exports as Skeleton, Slider, SliderField, sortable_exports as Sortable, Spacer, Stepper, StyledButton, StyledLink, Switch, Table, Tabs, Text, Textarea, TextareaField, Theme, Tile, TileInteractive, TileToggleGroup, Toast, ToggleGroup, Tooltip, TopBar, Tree, Video, cn, createTheme, styled, toast, useAlert, useCarousel, useDataTable, useFileDrop, useSidebarState };
|
package/dist/styled.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { composeRefs } from "@radix-ui/react-compose-refs";
|
|
2
3
|
import clsx from "clsx";
|
|
3
4
|
import { extendTailwindMerge } from "tailwind-merge";
|
|
4
5
|
import { defaultConfig, tv } from "tailwind-variants";
|
|
@@ -111,7 +112,10 @@ function styled(el, styles, options) {
|
|
|
111
112
|
as: props.as || element.props.as,
|
|
112
113
|
className: finalClassName
|
|
113
114
|
};
|
|
114
|
-
if (ref)
|
|
115
|
+
if (ref) {
|
|
116
|
+
const existingRef = element.props.ref;
|
|
117
|
+
cloneProps.ref = existingRef ? composeRefs(existingRef, ref) : ref;
|
|
118
|
+
}
|
|
115
119
|
return React.cloneElement(element, cloneProps);
|
|
116
120
|
}
|
|
117
121
|
throw Error("Something is wrong");
|
package/dist/styled.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styled.js","names":[],"sources":["../src/styled.tsx"],"sourcesContent":["import clsx, { type ClassValue } from 'clsx'\nimport React, { type ElementType, type ReactElement } from 'react'\nimport { extendTailwindMerge } from 'tailwind-merge'\nimport { defaultConfig, tv } from 'tailwind-variants'\n\ndefaultConfig.twMerge = false\n\nconst isArbitraryNumber = (value: string) =>\n /^\\[[\\d.]+\\]$/.test(value) || !Number.isNaN(Number(value))\n\nconst twMerge = extendTailwindMerge<\n 'capsize' | 'capsize-before' | 'capsize-after'\n>({\n extend: {\n classGroups: {\n capsize: [{ capsize: ['none', isArbitraryNumber] }],\n 'capsize-before': [{ 'capsize-before': [isArbitraryNumber] }],\n 'capsize-after': [{ 'capsize-after': [isArbitraryNumber] }]\n },\n conflictingClassGroups: {\n capsize: ['capsize-before', 'capsize-after'],\n 'capsize-before': ['capsize'],\n 'capsize-after': ['capsize']\n }\n }\n})\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs))\n\ntype Breakpoint = '@initial' | '@sm' | '@md' | '@lg' | '@xl'\n\nexport const Theme = ({\n children,\n theme\n}: React.PropsWithChildren<{ theme?: Record<string, string> }>) => (\n <div className=\"contents\" style={theme}>\n {children}\n </div>\n)\n\nexport const createTheme = (config: Record<string, Record<string, string>>) =>\n Object.fromEntries(\n Object.values(config).flatMap((tokens) =>\n Object.entries(tokens).map(([token, value]) => [`--${token}`, value])\n )\n )\n\n// ---------------------------------------------------------------------------\n// Local typing for styled()\n// ---------------------------------------------------------------------------\n\n// Responsive variant prop: either a single value or a per-breakpoint map\n// Each breakpoint can have a different value from the union type V\ntype ResponsiveVariant<V extends string | number | boolean> =\n | V\n | Partial<Record<Breakpoint, V>>\n\n// Helpers to derive value type from variant config keys\ntype Keys<V> = keyof V\ntype StringKeys<V> = Extract<Keys<V>, string>\ntype NumberKeys<V> = Extract<Keys<V>, number>\n// Booleans are represented as string keys \"true\"/\"false\" in our VariantConfig,\n// so we only need to detect those in StringKeys.\ntype BooleanKeys<V> = Extract<StringKeys<V>, 'true' | 'false'>\n\ntype HasBoolLikeKeys<V> =\n BooleanKeys<V> extends never\n ? Extract<StringKeys<V>, 'true' | 'false'> extends never\n ? false\n : true\n : true\n\n// If a variant's keys are boolean-like, expose the prop as boolean.\n// If it has numeric keys, allow those numbers and their string forms.\n// Otherwise use a string union of the keys.\ntype VariantValueType<V> =\n HasBoolLikeKeys<V> extends true\n ? boolean\n : [NumberKeys<V>] extends [never]\n ? StringKeys<V>\n : NumberKeys<V> | `${NumberKeys<V>}`\n\n// Shape of the `variants` section passed to styled()\ntype VariantConfig = Record<string, Record<string | number, string | string[]>>\n\n// Options for styled() function\ntype StyledOptions = {\n enableResponsiveVariants?: boolean\n enablePolymorphism?: boolean\n}\n\n// Helper to check if responsive variants are enabled\ntype AreResponsiveVariantsEnabled<O> = O extends {\n enableResponsiveVariants: true\n}\n ? true\n : false\n\n// Props derived from a `variants` config\n// If enableResponsiveVariants is true, all variants support responsive values\n// If enableResponsiveVariants is not provided or false, variants do not support responsive values\ntype VariantProps<\n V extends VariantConfig | undefined,\n R extends boolean = false\n> = V extends VariantConfig\n ? R extends true\n ? {\n [K in keyof V]?: ResponsiveVariant<VariantValueType<V[K]>>\n }\n : {\n [K in keyof V]?: VariantValueType<V[K]>\n }\n : unknown\n\n// Typed config for our styled helper.\n// We intentionally *don't* rely on tailwind-variants' TS types here;\n// we only care about enough structure to derive props.\ntype StyledConfig<V extends VariantConfig | undefined = undefined> = {\n base?: string | string[]\n variants?: V\n compoundVariants?: Array<\n {\n class?: string | string[]\n } & (V extends VariantConfig\n ? {\n [K in keyof V]?: VariantValueType<V[K]> | VariantValueType<V[K]>[]\n }\n : Record<string, never>)\n >\n defaultVariants?: V extends VariantConfig\n ? { [K in keyof V]?: VariantValueType<V[K]> }\n : Record<string, never>\n}\n\n// Props of the default element. `as` is typed `never` so JSX usage with `as`\n// can only resolve through the generic polymorphic signature — signatures\n// built from this can never accept calls the generic one would reject.\ntype DefaultElementProps<\n TDefaultElement extends ElementType,\n OwnProps\n> = OwnProps & { as?: never } & Omit<\n React.ComponentPropsWithRef<TDefaultElement>,\n keyof OwnProps | 'as'\n >\n\n// Polymorphic component type: `as` prop narrows accepted props and ref type.\n//\n// The non-generic default-element signature appears twice on purpose. Tooling\n// that inspects call signatures disagrees on which one to read: props-table\n// generation (react-docgen-typescript) reads the FIRST, while type-level\n// inference (React.ComponentProps and friends) reads the LAST. If either\n// tool lands on the generic signature instead, TAs erases to its ElementType\n// constraint and the props collapse to `any` (docgen then also loses every\n// element-specific prop, e.g. Radix's asChild).\nexport interface PolymorphicComponent<\n TDefaultElement extends ElementType,\n OwnProps\n> {\n (\n props: DefaultElementProps<TDefaultElement, OwnProps>\n ): React.ReactElement | null\n <TAs extends ElementType = TDefaultElement>(\n props: OwnProps & { as?: TAs } & Omit<\n React.ComponentPropsWithRef<TAs>,\n keyof OwnProps | 'as'\n >\n ): React.ReactElement | null\n (\n props: DefaultElementProps<TDefaultElement, OwnProps>\n ): React.ReactElement | null\n displayName?: string\n __isStyledComponent?: boolean\n /**\n * Phantom brand (never present at runtime) that carries this component's own\n * props so a wrapping styled() can recover them via {@link BaseOwnProps}.\n * Optional so plain function casts to this interface stay assignable; nominal\n * enough that foreign polymorphic components (Reach, Radix) don't match it.\n */\n readonly __ownProps?: OwnProps\n}\n\n// Non-polymorphic component type: no `as` prop. Single concrete call\n// signature, so React.ComponentProps and react-docgen-typescript both read\n// it directly — no sandwich needed.\nexport interface StyledComponent<\n TDefaultElement extends ElementType,\n OwnProps\n> {\n (\n props: OwnProps &\n Omit<React.ComponentPropsWithRef<TDefaultElement>, keyof OwnProps | 'as'>\n ): React.ReactElement | null\n displayName?: string\n __isStyledComponent?: boolean\n}\n\ntype PolymorphicElementProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E\n} & Omit<React.ComponentPropsWithRef<E>, keyof OwnProps | 'as'>\n\n// When styled() wraps one of our own polymorphic components (rather than a host\n// string), that component's own props (variants + custom props) are part of the\n// styled component's identity and must persist regardless of `as`. Without this\n// they live only in the default element's `ComponentPropsWithRef` and get\n// dropped by the generic `as` signature, which keys element props off the `as`\n// target. Recover them via the `__ownProps` phantom brand — matching on that\n// field (rather than the call signatures) means foreign polymorphic components\n// (Reach, Radix) and host strings don't match and instead contribute `unknown`,\n// the intersection identity, so their attributes still swap with `as`.\ntype BaseOwnProps<T> = T extends { readonly __ownProps?: infer OwnProps }\n ? unknown extends OwnProps\n ? unknown\n : OwnProps\n : unknown\n\n/**\n * Extract the props a styled component accepts, optionally for a specific\n * `as` element. `React.ComponentProps<typeof Box>` only describes the default\n * element (with `as` unusable); use this to retarget or to build wrappers\n * that re-expose polymorphism:\n *\n * ```tsx\n * type AnchorBoxProps = StyledComponentProps<typeof Box, 'a'> // href, anchor ref…\n * ```\n */\nexport type StyledComponentProps<C, TAs extends ElementType = never> =\n C extends PolymorphicComponent<\n infer TDefault extends ElementType,\n infer OwnProps\n >\n ? PolymorphicElementProps<[TAs] extends [never] ? TDefault : TAs, OwnProps>\n : C extends ElementType\n ? React.ComponentPropsWithRef<[TAs] extends [never] ? C : TAs>\n : never\n\n// Function overloads for better type inference\n\n// enablePolymorphism: false — no `as` prop\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>,\n options: { enablePolymorphism: false; enableResponsiveVariants: true }\n): StyledComponent<TElement, VariantProps<V, true>>\n\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>,\n options: { enablePolymorphism: false }\n): StyledComponent<TElement, VariantProps<V, false>>\n\n// enablePolymorphism: true (default) — `as` prop available\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>,\n options: { enableResponsiveVariants: true }\n): PolymorphicComponent<\n TElement,\n VariantProps<V, true> & BaseOwnProps<TElement>\n>\n\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>\n): PolymorphicComponent<\n TElement,\n VariantProps<V, false> & BaseOwnProps<TElement>\n>\n\n// Implementation\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined,\n O extends StyledOptions | undefined = undefined\n>(el: TElement, styles: StyledConfig<V>, options?: O) {\n const variantKeys = Object.keys(styles.variants || {})\n const enableResponsiveVariants = options?.enableResponsiveVariants === true\n const tvFn = tv(styles as any)\n\n type ResponsiveVariantsEnabled = AreResponsiveVariantsEnabled<O>\n type VariantPropsType = VariantProps<V, ResponsiveVariantsEnabled>\n type BaseProps = React.ComponentPropsWithRef<TElement>\n // Extract variant keys to omit from BaseProps so variant props override native HTML attributes\n type VariantKeys = V extends VariantConfig ? keyof V : never\n type StyledProps = Omit<BaseProps, VariantKeys> &\n VariantPropsType & {\n as?: ElementType\n ref?: React.Ref<React.ComponentRef<TElement>>\n className?: string\n /** @internal wrapper classes passed between nested styled components */\n __wrapperClasses?: string\n }\n\n const Comp = (props: StyledProps) => {\n const { ref, ...propsWithoutRef } = props\n const additionalStyles = enableResponsiveVariants\n ? variantKeys\n .map((variantKey) => {\n const responsiveVariantConfig:\n | Record<Breakpoint, string | number>\n | undefined = props[variantKey]\n const variantStyles: Record<string, string | string[]> =\n styles.variants![variantKey]\n\n if (\n typeof responsiveVariantConfig === 'object' &&\n responsiveVariantConfig &&\n !Array.isArray(responsiveVariantConfig)\n ) {\n return Object.entries(responsiveVariantConfig).flatMap(\n ([key, val]) => {\n const valStr = String(val)\n const styleArr: string | string[] =\n variantStyles && variantStyles[valStr]\n\n if (styleArr && Array.isArray(styleArr)) {\n return styleArr.flatMap((cls: string) => {\n if (key === '@initial') return cls\n return `${key.replace('@', '')}:${cls}`\n })\n }\n return []\n }\n )\n }\n\n return []\n })\n .flat()\n : []\n\n // Filter out variant props that don't belong to this component before calling tvFn\n // This prevents tailwind-variants from processing props meant for wrapped components\n // Only pass props that are in this component's variant keys\n // For boolean variants, only include them if the value is explicitly true or false (not null/undefined)\n // Note: tailwind-variants treats null as \"no variant\" but undefined/missing as \"apply false variant\"\n // So we need to convert undefined to null for boolean variants to prevent default behavior\n const propsForTv =\n variantKeys.length > 0\n ? Object.fromEntries(\n Object.entries(props as Record<string, unknown>)\n .filter(([key]) => variantKeys.includes(key))\n .map(([key, value]) => {\n // Check if this is a boolean variant (has both 'true' and 'false' keys)\n const variantConfig = styles.variants?.[key]\n if (\n variantConfig &&\n 'true' in variantConfig &&\n 'false' in variantConfig\n ) {\n // For boolean variants, only include if value is explicitly true or false\n // Convert undefined to null to prevent tailwind-variants from applying false variant\n if (value === true || value === false) {\n return [key, value]\n }\n // For null/undefined, pass null to prevent tailwind-variants from applying defaults\n // This ensures that when a boolean prop is explicitly null/undefined, no variant is applied\n return [key, null]\n }\n // For non-boolean variants, pass value as-is (including null/undefined)\n return [key, value]\n })\n )\n : {}\n\n const cls = tvFn(propsForTv)\n\n const filteredProps = Object.fromEntries(\n Object.entries(props).filter(\n ([key]) =>\n !variantKeys.includes(key) &&\n key !== 'as' &&\n key !== '__wrapperClasses'\n )\n )\n\n const mergedClassName = clsx(cls, additionalStyles).trim()\n const propsClassName = props.className\n // Check for wrapper classes passed from a parent styled component\n const wrapperClasses = props.__wrapperClasses\n\n if (\n typeof el === 'string' ||\n typeof el === 'function' ||\n (el && typeof el === 'object')\n ) {\n const elementType = el as ElementType\n\n // If el is a host string ('div', 'span', etc.) we must not pass variant props to the DOM.\n if (typeof el === 'string') {\n const { className: _, ...restFilteredProps } = filteredProps as any\n // Merge order: wrapper classes (lowest priority) < component classes < user's className (highest priority)\n // This ensures variant classes from this component override base classes from wrapper\n // IMPORTANT: When propsClassName exists (could be from asChild), we need to ensure child's classes win\n // over parent classes, but user's className should still have highest priority.\n // Strategy: Only apply special merge when wrapperClasses exist (nested styled component scenario).\n // For regular cases (no wrapperClasses), use standard merge order so user's className has highest priority.\n const finalClassName =\n wrapperClasses && propsClassName\n ? twMerge(mergedClassName, wrapperClasses, propsClassName) // wrapper overrides base, user className wins\n : wrapperClasses\n ? twMerge(mergedClassName, wrapperClasses) // wrapper overrides base\n : propsClassName\n ? (() => {\n // When propsClassName comes from asChild (Radix), we want this component's classes to win\n // When propsClassName is a regular className prop, the user's className should win (highest priority)\n // We can detect asChild scenario by checking if propsClassName contains classes that look like they came from a parent component\n // (e.g., data attribute variants like data-[state=closed]:rounded-sm)\n // If it does, treat it as asChild and let component classes win. Otherwise, let user's className win.\n const hasDataAttributeVariants = propsClassName\n .split(' ')\n .some((cls) => /^data-\\[state=[^\\]]+\\]:/.test(cls))\n\n if (hasDataAttributeVariants) {\n // This is likely from asChild - component's classes should win\n return twMerge(propsClassName, mergedClassName)\n } else {\n // Regular className prop - user's className should win (highest priority)\n return twMerge(mergedClassName, propsClassName)\n }\n })()\n : twMerge(mergedClassName) // Always merge mergedClassName to resolve conflicts within it (e.g., bg-[unset] vs bg-(--base))\n\n return React.createElement(props.as || elementType, {\n ...restFilteredProps,\n ref,\n className: finalClassName\n })\n }\n\n // If el is a function component (including forwardRef), pass ALL props through\n // (the wrapped component may expect variant props), but ensure className and ref are forwarded.\n // We need to pass all props (not filteredProps) because the underlying component may have its own variants\n //\n // For className merging with wrapped styled components:\n // Solution: Pass wrapper's classes via __wrapperClasses prop for styled components to merge correctly.\n // For regular function components, merge wrapper classes with our classes and pass as className.\n // This ensures:\n // - Styled components can merge: wrapper classes < wrapped component classes < user's className\n // - Regular components get merged classes directly and don't receive __wrapperClasses\n // Filter out variant props and __wrapperClasses from props passed to function components\n // This prevents them from ending up in the DOM.\n // Note: We filter out variant props that belong to THIS component. Variant props that belong to\n // the wrapped component will be passed through (they're not in variantKeys), and the wrapped\n // component will filter them if it's a styled component.\n // Note: 'as' prop is filtered from filteredProps to prevent it from going to DOM for string elements,\n // but we add it back for function components since they need it for polymorphism.\n const { className: _, ...restFilteredProps } = filteredProps as any\n const asProp = props.as // Extract 'as' prop separately\n // Note: __wrapperClasses is already filtered out in filteredProps, so restFilteredProps doesn't include it\n\n // For styled components: Pass wrapper classes via __wrapperClasses so they can merge correctly.\n // Styled components extract __wrapperClasses from props (before filteredProps) and filter it in filteredProps.\n // For regular function components: We merge wrapper classes into className, but also pass __wrapperClasses\n // which they may spread. To prevent it in DOM, we need to ensure it's filtered, but we can't control that.\n // However, styled components that wrap regular components will filter __wrapperClasses in their filteredProps.\n if (wrapperClasses) {\n // We have wrapper classes from parent - this is a nested styled component scenario\n // Merge order: wrapper classes (base) < this component's classes (variants) < user's className\n // This ensures variant classes override base classes via twMerge\n // IMPORTANT: When propsClassName exists (could be from asChild), we need to ensure this component's classes win.\n // Strategy: Merge wrapperClasses with propsClassName first, then merge with mergedClassName last.\n // This ensures: wrapperClasses < propsClassName < mergedClassName (this component's classes win)\n // This is critical when propsClassName contains parent classes from asChild merge.\n const finalClassName = propsClassName\n ? twMerge(wrapperClasses, propsClassName, mergedClassName) // This component's classes win by being merged last\n : twMerge(wrapperClasses, mergedClassName)\n\n // Check if the wrapped component is a styled component\n // React.forwardRef components are objects, not functions\n const isStyledComponent =\n (typeof elementType === 'function' ||\n typeof elementType === 'object') &&\n elementType !== null &&\n (elementType as any).__isStyledComponent === true\n\n const propsForComponent: any = {\n ...restFilteredProps, // Base props (filters THIS component's variant props, __wrapperClasses, 'as')\n ...(asProp ? { as: asProp } : {}), // Add 'as' prop back for function components (polymorphic support)\n // Note: We don't add variant props back - they're already filtered by filteredProps.\n ref\n }\n\n if (isStyledComponent) {\n // Wrapped component is a styled component - pass __wrapperClasses so variant classes win\n // IMPORTANT: When propsClassName exists (could be from asChild), it may contain both parent and child classes.\n // We should NOT merge propsClassName with mergedClassName here, because that would remove child classes.\n // Instead, pass propsClassName as-is (or merge only wrapperClasses with mergedClassName) so the child\n // can merge its own classes last. The child will merge: twMerge(__wrapperClasses, propsClassName, child's mergedClassName).\n // This ensures child's classes win by being merged last.\n // Merge wrapperClasses with mergedClassName to create the wrapper classes for the child\n const combinedWrapperClasses = twMerge(\n wrapperClasses,\n mergedClassName\n )\n propsForComponent.__wrapperClasses = combinedWrapperClasses\n propsForComponent.className = propsClassName || undefined\n } else {\n // Wrapped component is not a styled component - merge wrapper classes into className\n // and don't pass __wrapperClasses (it would end up in DOM)\n propsForComponent.className = finalClassName\n }\n return React.createElement(elementType, propsForComponent)\n } else {\n // No wrapper classes from parent - we're top-level\n // For function components: Pass __wrapperClasses so styled components can merge correctly.\n // Styled components extract __wrapperClasses from their props (before filteredProps) and filter it in filteredProps.\n // Regular function components will receive __wrapperClasses but should filter it out themselves.\n // We also merge wrapper classes into className for regular function components.\n // Note: We pass __wrapperClasses in props (not filteredProps) so styled components can access it,\n // but styled components filter it in their filteredProps so it won't go to DOM.\n // Regular function components that spread all props will pass __wrapperClasses to DOM, which is a problem.\n // But we can't distinguish them, so we rely on styled components filtering it.\n // Check if the wrapped component is a styled component\n // elementType is the component itself (e.g., Inner when Outer extends Inner)\n // React.forwardRef components are objects, not functions, but we can still check the flag\n const isStyledComponent =\n (typeof elementType === 'function' ||\n typeof elementType === 'object') &&\n elementType !== null &&\n (elementType as any).__isStyledComponent === true\n\n const propsForComponent: any = {\n ...restFilteredProps, // Filters out __wrapperClasses, variant props, 'as'\n ...(asProp ? { as: asProp } : {}),\n ref\n }\n\n if (isStyledComponent) {\n // Styled component - pass wrapper classes via __wrapperClasses so variant classes can take precedence\n // IMPORTANT: When propsClassName exists, we need to distinguish between:\n // 1. User's className (should win - highest priority)\n // 2. className from asChild/parent component (component's classes should win)\n // We detect asChild by checking for data attribute variants (e.g., data-[state=closed]:rounded-sm)\n const hasDataAttributeVariants = propsClassName\n ? propsClassName\n .split(' ')\n .some((cls) => /^data-\\[state=[^\\]]+\\]:/.test(cls))\n : false\n\n const mergedPropsAndComponent = propsClassName\n ? hasDataAttributeVariants\n ? // This is likely from asChild - component's classes should win\n twMerge(propsClassName, mergedClassName)\n : // Regular user className - user's className should win (highest priority)\n twMerge(mergedClassName, propsClassName)\n : mergedClassName\n propsForComponent.__wrapperClasses = mergedClassName\n propsForComponent.className = mergedPropsAndComponent || undefined\n } else {\n // Regular function component - merge wrapper classes into className\n // Standard merge order: component classes < user's className (highest priority)\n propsForComponent.className = twMerge(mergedClassName, propsClassName)\n }\n return React.createElement(elementType, propsForComponent)\n }\n }\n\n if (React.isValidElement(el)) {\n const element = el as ReactElement<unknown>\n // Merge existing element className, incoming filteredProps.className and our computed class\n const existingClass = (element.props as any).className\n const incomingClass = (filteredProps as any).className\n const finalClassName = cn(\n existingClass,\n incomingClass,\n mergedClassName\n ).trim()\n\n const cloneProps: any = {\n // ...element.props,\n ...filteredProps,\n as: props.as || (element.props as { as?: ElementType }).as,\n className: finalClassName\n }\n\n // Forward the ref if provided\n if (ref) {\n cloneProps.ref = ref\n }\n\n return React.cloneElement(element, cloneProps)\n }\n\n throw Error('Something is wrong')\n }\n\n // Mark the component as a styled component so we can detect it later\n ;(Comp as any).__isStyledComponent = true\n\n // Name the component for DevTools and error component stacks — without\n // this every styled component reads as the inner function name, \"Comp\"\n const baseName =\n typeof el === 'string'\n ? el\n : (el as any).displayName || (el as any).name || 'Component'\n Comp.displayName = baseName.startsWith('styled.')\n ? baseName\n : `styled.${baseName}`\n\n return Comp\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"styled.js","names":[],"sources":["../src/styled.tsx"],"sourcesContent":["// composeRefs must propagate ref-callback cleanup returns per the React 19\n// contract — the ref composition across the library (here and in the input /\n// badge / segmented-control components) relies on cleanups firing on detach.\n// @radix-ui/react-compose-refs@1.1.x is verified to do this.\nimport { composeRefs } from '@radix-ui/react-compose-refs'\nimport clsx, { type ClassValue } from 'clsx'\nimport React, { type ElementType, type ReactElement } from 'react'\nimport { extendTailwindMerge } from 'tailwind-merge'\nimport { defaultConfig, tv } from 'tailwind-variants'\n\ndefaultConfig.twMerge = false\n\nconst isArbitraryNumber = (value: string) =>\n /^\\[[\\d.]+\\]$/.test(value) || !Number.isNaN(Number(value))\n\nconst twMerge = extendTailwindMerge<\n 'capsize' | 'capsize-before' | 'capsize-after'\n>({\n extend: {\n classGroups: {\n capsize: [{ capsize: ['none', isArbitraryNumber] }],\n 'capsize-before': [{ 'capsize-before': [isArbitraryNumber] }],\n 'capsize-after': [{ 'capsize-after': [isArbitraryNumber] }]\n },\n conflictingClassGroups: {\n capsize: ['capsize-before', 'capsize-after'],\n 'capsize-before': ['capsize'],\n 'capsize-after': ['capsize']\n }\n }\n})\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs))\n\ntype Breakpoint = '@initial' | '@sm' | '@md' | '@lg' | '@xl'\n\nexport const Theme = ({\n children,\n theme\n}: React.PropsWithChildren<{ theme?: Record<string, string> }>) => (\n <div className=\"contents\" style={theme}>\n {children}\n </div>\n)\n\nexport const createTheme = (config: Record<string, Record<string, string>>) =>\n Object.fromEntries(\n Object.values(config).flatMap((tokens) =>\n Object.entries(tokens).map(([token, value]) => [`--${token}`, value])\n )\n )\n\n// ---------------------------------------------------------------------------\n// Local typing for styled()\n// ---------------------------------------------------------------------------\n\n// Responsive variant prop: either a single value or a per-breakpoint map\n// Each breakpoint can have a different value from the union type V\ntype ResponsiveVariant<V extends string | number | boolean> =\n | V\n | Partial<Record<Breakpoint, V>>\n\n// Helpers to derive value type from variant config keys\ntype Keys<V> = keyof V\ntype StringKeys<V> = Extract<Keys<V>, string>\ntype NumberKeys<V> = Extract<Keys<V>, number>\n// Booleans are represented as string keys \"true\"/\"false\" in our VariantConfig,\n// so we only need to detect those in StringKeys.\ntype BooleanKeys<V> = Extract<StringKeys<V>, 'true' | 'false'>\n\ntype HasBoolLikeKeys<V> =\n BooleanKeys<V> extends never\n ? Extract<StringKeys<V>, 'true' | 'false'> extends never\n ? false\n : true\n : true\n\n// If a variant's keys are boolean-like, expose the prop as boolean.\n// If it has numeric keys, allow those numbers and their string forms.\n// Otherwise use a string union of the keys.\ntype VariantValueType<V> =\n HasBoolLikeKeys<V> extends true\n ? boolean\n : [NumberKeys<V>] extends [never]\n ? StringKeys<V>\n : NumberKeys<V> | `${NumberKeys<V>}`\n\n// Shape of the `variants` section passed to styled()\ntype VariantConfig = Record<string, Record<string | number, string | string[]>>\n\n// Options for styled() function\ntype StyledOptions = {\n enableResponsiveVariants?: boolean\n enablePolymorphism?: boolean\n}\n\n// Helper to check if responsive variants are enabled\ntype AreResponsiveVariantsEnabled<O> = O extends {\n enableResponsiveVariants: true\n}\n ? true\n : false\n\n// Props derived from a `variants` config\n// If enableResponsiveVariants is true, all variants support responsive values\n// If enableResponsiveVariants is not provided or false, variants do not support responsive values\ntype VariantProps<\n V extends VariantConfig | undefined,\n R extends boolean = false\n> = V extends VariantConfig\n ? R extends true\n ? {\n [K in keyof V]?: ResponsiveVariant<VariantValueType<V[K]>>\n }\n : {\n [K in keyof V]?: VariantValueType<V[K]>\n }\n : unknown\n\n// Typed config for our styled helper.\n// We intentionally *don't* rely on tailwind-variants' TS types here;\n// we only care about enough structure to derive props.\ntype StyledConfig<V extends VariantConfig | undefined = undefined> = {\n base?: string | string[]\n variants?: V\n compoundVariants?: Array<\n {\n class?: string | string[]\n } & (V extends VariantConfig\n ? {\n [K in keyof V]?: VariantValueType<V[K]> | VariantValueType<V[K]>[]\n }\n : Record<string, never>)\n >\n defaultVariants?: V extends VariantConfig\n ? { [K in keyof V]?: VariantValueType<V[K]> }\n : Record<string, never>\n}\n\n// Props of the default element. `as` is typed `never` so JSX usage with `as`\n// can only resolve through the generic polymorphic signature — signatures\n// built from this can never accept calls the generic one would reject.\ntype DefaultElementProps<\n TDefaultElement extends ElementType,\n OwnProps\n> = OwnProps & { as?: never } & Omit<\n React.ComponentPropsWithRef<TDefaultElement>,\n keyof OwnProps | 'as'\n >\n\n// Polymorphic component type: `as` prop narrows accepted props and ref type.\n//\n// The non-generic default-element signature appears twice on purpose. Tooling\n// that inspects call signatures disagrees on which one to read: props-table\n// generation (react-docgen-typescript) reads the FIRST, while type-level\n// inference (React.ComponentProps and friends) reads the LAST. If either\n// tool lands on the generic signature instead, TAs erases to its ElementType\n// constraint and the props collapse to `any` (docgen then also loses every\n// element-specific prop, e.g. Radix's asChild).\nexport interface PolymorphicComponent<\n TDefaultElement extends ElementType,\n OwnProps\n> {\n (\n props: DefaultElementProps<TDefaultElement, OwnProps>\n ): React.ReactElement | null\n <TAs extends ElementType = TDefaultElement>(\n props: OwnProps & { as?: TAs } & Omit<\n React.ComponentPropsWithRef<TAs>,\n keyof OwnProps | 'as'\n >\n ): React.ReactElement | null\n (\n props: DefaultElementProps<TDefaultElement, OwnProps>\n ): React.ReactElement | null\n displayName?: string\n __isStyledComponent?: boolean\n /**\n * Phantom brand (never present at runtime) that carries this component's own\n * props so a wrapping styled() can recover them via {@link BaseOwnProps}.\n * Optional so plain function casts to this interface stay assignable; nominal\n * enough that foreign polymorphic components (Reach, Radix) don't match it.\n */\n readonly __ownProps?: OwnProps\n}\n\n// Non-polymorphic component type: no `as` prop. Single concrete call\n// signature, so React.ComponentProps and react-docgen-typescript both read\n// it directly — no sandwich needed.\nexport interface StyledComponent<\n TDefaultElement extends ElementType,\n OwnProps\n> {\n (\n props: OwnProps &\n Omit<React.ComponentPropsWithRef<TDefaultElement>, keyof OwnProps | 'as'>\n ): React.ReactElement | null\n displayName?: string\n __isStyledComponent?: boolean\n}\n\ntype PolymorphicElementProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E\n} & Omit<React.ComponentPropsWithRef<E>, keyof OwnProps | 'as'>\n\n// When styled() wraps one of our own polymorphic components (rather than a host\n// string), that component's own props (variants + custom props) are part of the\n// styled component's identity and must persist regardless of `as`. Without this\n// they live only in the default element's `ComponentPropsWithRef` and get\n// dropped by the generic `as` signature, which keys element props off the `as`\n// target. Recover them via the `__ownProps` phantom brand — matching on that\n// field (rather than the call signatures) means foreign polymorphic components\n// (Reach, Radix) and host strings don't match and instead contribute `unknown`,\n// the intersection identity, so their attributes still swap with `as`.\ntype BaseOwnProps<T> = T extends { readonly __ownProps?: infer OwnProps }\n ? unknown extends OwnProps\n ? unknown\n : OwnProps\n : unknown\n\n/**\n * Extract the props a styled component accepts, optionally for a specific\n * `as` element. `React.ComponentProps<typeof Box>` only describes the default\n * element (with `as` unusable); use this to retarget or to build wrappers\n * that re-expose polymorphism:\n *\n * ```tsx\n * type AnchorBoxProps = StyledComponentProps<typeof Box, 'a'> // href, anchor ref…\n * ```\n */\nexport type StyledComponentProps<C, TAs extends ElementType = never> =\n C extends PolymorphicComponent<\n infer TDefault extends ElementType,\n infer OwnProps\n >\n ? PolymorphicElementProps<[TAs] extends [never] ? TDefault : TAs, OwnProps>\n : C extends ElementType\n ? React.ComponentPropsWithRef<[TAs] extends [never] ? C : TAs>\n : never\n\n// Function overloads for better type inference\n\n// enablePolymorphism: false — no `as` prop\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>,\n options: { enablePolymorphism: false; enableResponsiveVariants: true }\n): StyledComponent<TElement, VariantProps<V, true>>\n\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>,\n options: { enablePolymorphism: false }\n): StyledComponent<TElement, VariantProps<V, false>>\n\n// enablePolymorphism: true (default) — `as` prop available\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>,\n options: { enableResponsiveVariants: true }\n): PolymorphicComponent<\n TElement,\n VariantProps<V, true> & BaseOwnProps<TElement>\n>\n\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined\n>(\n el: TElement,\n styles: StyledConfig<V>\n): PolymorphicComponent<\n TElement,\n VariantProps<V, false> & BaseOwnProps<TElement>\n>\n\n// Implementation\nexport function styled<\n TElement extends ElementType,\n V extends VariantConfig | undefined = undefined,\n O extends StyledOptions | undefined = undefined\n>(el: TElement, styles: StyledConfig<V>, options?: O) {\n const variantKeys = Object.keys(styles.variants || {})\n const enableResponsiveVariants = options?.enableResponsiveVariants === true\n const tvFn = tv(styles as any)\n\n type ResponsiveVariantsEnabled = AreResponsiveVariantsEnabled<O>\n type VariantPropsType = VariantProps<V, ResponsiveVariantsEnabled>\n type BaseProps = React.ComponentPropsWithRef<TElement>\n // Extract variant keys to omit from BaseProps so variant props override native HTML attributes\n type VariantKeys = V extends VariantConfig ? keyof V : never\n type StyledProps = Omit<BaseProps, VariantKeys> &\n VariantPropsType & {\n as?: ElementType\n ref?: React.Ref<React.ComponentRef<TElement>>\n className?: string\n /** @internal wrapper classes passed between nested styled components */\n __wrapperClasses?: string\n }\n\n const Comp = (props: StyledProps) => {\n const { ref, ...propsWithoutRef } = props\n const additionalStyles = enableResponsiveVariants\n ? variantKeys\n .map((variantKey) => {\n const responsiveVariantConfig:\n | Record<Breakpoint, string | number>\n | undefined = props[variantKey]\n const variantStyles: Record<string, string | string[]> =\n styles.variants![variantKey]\n\n if (\n typeof responsiveVariantConfig === 'object' &&\n responsiveVariantConfig &&\n !Array.isArray(responsiveVariantConfig)\n ) {\n return Object.entries(responsiveVariantConfig).flatMap(\n ([key, val]) => {\n const valStr = String(val)\n const styleArr: string | string[] =\n variantStyles && variantStyles[valStr]\n\n if (styleArr && Array.isArray(styleArr)) {\n return styleArr.flatMap((cls: string) => {\n if (key === '@initial') return cls\n return `${key.replace('@', '')}:${cls}`\n })\n }\n return []\n }\n )\n }\n\n return []\n })\n .flat()\n : []\n\n // Filter out variant props that don't belong to this component before calling tvFn\n // This prevents tailwind-variants from processing props meant for wrapped components\n // Only pass props that are in this component's variant keys\n // For boolean variants, only include them if the value is explicitly true or false (not null/undefined)\n // Note: tailwind-variants treats null as \"no variant\" but undefined/missing as \"apply false variant\"\n // So we need to convert undefined to null for boolean variants to prevent default behavior\n const propsForTv =\n variantKeys.length > 0\n ? Object.fromEntries(\n Object.entries(props as Record<string, unknown>)\n .filter(([key]) => variantKeys.includes(key))\n .map(([key, value]) => {\n // Check if this is a boolean variant (has both 'true' and 'false' keys)\n const variantConfig = styles.variants?.[key]\n if (\n variantConfig &&\n 'true' in variantConfig &&\n 'false' in variantConfig\n ) {\n // For boolean variants, only include if value is explicitly true or false\n // Convert undefined to null to prevent tailwind-variants from applying false variant\n if (value === true || value === false) {\n return [key, value]\n }\n // For null/undefined, pass null to prevent tailwind-variants from applying defaults\n // This ensures that when a boolean prop is explicitly null/undefined, no variant is applied\n return [key, null]\n }\n // For non-boolean variants, pass value as-is (including null/undefined)\n return [key, value]\n })\n )\n : {}\n\n const cls = tvFn(propsForTv)\n\n const filteredProps = Object.fromEntries(\n Object.entries(props).filter(\n ([key]) =>\n !variantKeys.includes(key) &&\n key !== 'as' &&\n key !== '__wrapperClasses'\n )\n )\n\n const mergedClassName = clsx(cls, additionalStyles).trim()\n const propsClassName = props.className\n // Check for wrapper classes passed from a parent styled component\n const wrapperClasses = props.__wrapperClasses\n\n if (\n typeof el === 'string' ||\n typeof el === 'function' ||\n (el && typeof el === 'object')\n ) {\n const elementType = el as ElementType\n\n // If el is a host string ('div', 'span', etc.) we must not pass variant props to the DOM.\n if (typeof el === 'string') {\n const { className: _, ...restFilteredProps } = filteredProps as any\n // Merge order: wrapper classes (lowest priority) < component classes < user's className (highest priority)\n // This ensures variant classes from this component override base classes from wrapper\n // IMPORTANT: When propsClassName exists (could be from asChild), we need to ensure child's classes win\n // over parent classes, but user's className should still have highest priority.\n // Strategy: Only apply special merge when wrapperClasses exist (nested styled component scenario).\n // For regular cases (no wrapperClasses), use standard merge order so user's className has highest priority.\n const finalClassName =\n wrapperClasses && propsClassName\n ? twMerge(mergedClassName, wrapperClasses, propsClassName) // wrapper overrides base, user className wins\n : wrapperClasses\n ? twMerge(mergedClassName, wrapperClasses) // wrapper overrides base\n : propsClassName\n ? (() => {\n // When propsClassName comes from asChild (Radix), we want this component's classes to win\n // When propsClassName is a regular className prop, the user's className should win (highest priority)\n // We can detect asChild scenario by checking if propsClassName contains classes that look like they came from a parent component\n // (e.g., data attribute variants like data-[state=closed]:rounded-sm)\n // If it does, treat it as asChild and let component classes win. Otherwise, let user's className win.\n const hasDataAttributeVariants = propsClassName\n .split(' ')\n .some((cls) => /^data-\\[state=[^\\]]+\\]:/.test(cls))\n\n if (hasDataAttributeVariants) {\n // This is likely from asChild - component's classes should win\n return twMerge(propsClassName, mergedClassName)\n } else {\n // Regular className prop - user's className should win (highest priority)\n return twMerge(mergedClassName, propsClassName)\n }\n })()\n : twMerge(mergedClassName) // Always merge mergedClassName to resolve conflicts within it (e.g., bg-[unset] vs bg-(--base))\n\n return React.createElement(props.as || elementType, {\n ...restFilteredProps,\n ref,\n className: finalClassName\n })\n }\n\n // If el is a function component (or other component object), pass ALL props through\n // (the wrapped component may expect variant props), but ensure className and ref are forwarded.\n // We need to pass all props (not filteredProps) because the underlying component may have its own variants\n //\n // For className merging with wrapped styled components:\n // Solution: Pass wrapper's classes via __wrapperClasses prop for styled components to merge correctly.\n // For regular function components, merge wrapper classes with our classes and pass as className.\n // This ensures:\n // - Styled components can merge: wrapper classes < wrapped component classes < user's className\n // - Regular components get merged classes directly and don't receive __wrapperClasses\n // Filter out variant props and __wrapperClasses from props passed to function components\n // This prevents them from ending up in the DOM.\n // Note: We filter out variant props that belong to THIS component. Variant props that belong to\n // the wrapped component will be passed through (they're not in variantKeys), and the wrapped\n // component will filter them if it's a styled component.\n // Note: 'as' prop is filtered from filteredProps to prevent it from going to DOM for string elements,\n // but we add it back for function components since they need it for polymorphism.\n const { className: _, ...restFilteredProps } = filteredProps as any\n const asProp = props.as // Extract 'as' prop separately\n // Note: __wrapperClasses is already filtered out in filteredProps, so restFilteredProps doesn't include it\n\n // For styled components: Pass wrapper classes via __wrapperClasses so they can merge correctly.\n // Styled components extract __wrapperClasses from props (before filteredProps) and filter it in filteredProps.\n // For regular function components: We merge wrapper classes into className, but also pass __wrapperClasses\n // which they may spread. To prevent it in DOM, we need to ensure it's filtered, but we can't control that.\n // However, styled components that wrap regular components will filter __wrapperClasses in their filteredProps.\n if (wrapperClasses) {\n // We have wrapper classes from parent - this is a nested styled component scenario\n // Merge order: wrapper classes (base) < this component's classes (variants) < user's className\n // This ensures variant classes override base classes via twMerge\n // IMPORTANT: When propsClassName exists (could be from asChild), we need to ensure this component's classes win.\n // Strategy: Merge wrapperClasses with propsClassName first, then merge with mergedClassName last.\n // This ensures: wrapperClasses < propsClassName < mergedClassName (this component's classes win)\n // This is critical when propsClassName contains parent classes from asChild merge.\n const finalClassName = propsClassName\n ? twMerge(wrapperClasses, propsClassName, mergedClassName) // This component's classes win by being merged last\n : twMerge(wrapperClasses, mergedClassName)\n\n // Check if the wrapped component is a styled component. Component\n // types can be objects, not just functions (e.g. React.memo, lazy)\n const isStyledComponent =\n (typeof elementType === 'function' ||\n typeof elementType === 'object') &&\n elementType !== null &&\n (elementType as any).__isStyledComponent === true\n\n const propsForComponent: any = {\n ...restFilteredProps, // Base props (filters THIS component's variant props, __wrapperClasses, 'as')\n ...(asProp ? { as: asProp } : {}), // Add 'as' prop back for function components (polymorphic support)\n // Note: We don't add variant props back - they're already filtered by filteredProps.\n ref\n }\n\n if (isStyledComponent) {\n // Wrapped component is a styled component - pass __wrapperClasses so variant classes win\n // IMPORTANT: When propsClassName exists (could be from asChild), it may contain both parent and child classes.\n // We should NOT merge propsClassName with mergedClassName here, because that would remove child classes.\n // Instead, pass propsClassName as-is (or merge only wrapperClasses with mergedClassName) so the child\n // can merge its own classes last. The child will merge: twMerge(__wrapperClasses, propsClassName, child's mergedClassName).\n // This ensures child's classes win by being merged last.\n // Merge wrapperClasses with mergedClassName to create the wrapper classes for the child\n const combinedWrapperClasses = twMerge(\n wrapperClasses,\n mergedClassName\n )\n propsForComponent.__wrapperClasses = combinedWrapperClasses\n propsForComponent.className = propsClassName || undefined\n } else {\n // Wrapped component is not a styled component - merge wrapper classes into className\n // and don't pass __wrapperClasses (it would end up in DOM)\n propsForComponent.className = finalClassName\n }\n return React.createElement(elementType, propsForComponent)\n } else {\n // No wrapper classes from parent - we're top-level\n // For function components: Pass __wrapperClasses so styled components can merge correctly.\n // Styled components extract __wrapperClasses from their props (before filteredProps) and filter it in filteredProps.\n // Regular function components will receive __wrapperClasses but should filter it out themselves.\n // We also merge wrapper classes into className for regular function components.\n // Note: We pass __wrapperClasses in props (not filteredProps) so styled components can access it,\n // but styled components filter it in their filteredProps so it won't go to DOM.\n // Regular function components that spread all props will pass __wrapperClasses to DOM, which is a problem.\n // But we can't distinguish them, so we rely on styled components filtering it.\n // Check if the wrapped component is a styled component\n // elementType is the component itself (e.g., Inner when Outer extends Inner)\n // Component types can be objects, not just functions, but we can still check the flag\n const isStyledComponent =\n (typeof elementType === 'function' ||\n typeof elementType === 'object') &&\n elementType !== null &&\n (elementType as any).__isStyledComponent === true\n\n const propsForComponent: any = {\n ...restFilteredProps, // Filters out __wrapperClasses, variant props, 'as'\n ...(asProp ? { as: asProp } : {}),\n ref\n }\n\n if (isStyledComponent) {\n // Styled component - pass wrapper classes via __wrapperClasses so variant classes can take precedence\n // IMPORTANT: When propsClassName exists, we need to distinguish between:\n // 1. User's className (should win - highest priority)\n // 2. className from asChild/parent component (component's classes should win)\n // We detect asChild by checking for data attribute variants (e.g., data-[state=closed]:rounded-sm)\n const hasDataAttributeVariants = propsClassName\n ? propsClassName\n .split(' ')\n .some((cls) => /^data-\\[state=[^\\]]+\\]:/.test(cls))\n : false\n\n const mergedPropsAndComponent = propsClassName\n ? hasDataAttributeVariants\n ? // This is likely from asChild - component's classes should win\n twMerge(propsClassName, mergedClassName)\n : // Regular user className - user's className should win (highest priority)\n twMerge(mergedClassName, propsClassName)\n : mergedClassName\n propsForComponent.__wrapperClasses = mergedClassName\n propsForComponent.className = mergedPropsAndComponent || undefined\n } else {\n // Regular function component - merge wrapper classes into className\n // Standard merge order: component classes < user's className (highest priority)\n propsForComponent.className = twMerge(mergedClassName, propsClassName)\n }\n return React.createElement(elementType, propsForComponent)\n }\n }\n\n if (React.isValidElement(el)) {\n const element = el as ReactElement<unknown>\n // Merge existing element className, incoming filteredProps.className and our computed class\n const existingClass = (element.props as any).className\n const incomingClass = (filteredProps as any).className\n const finalClassName = cn(\n existingClass,\n incomingClass,\n mergedClassName\n ).trim()\n\n const cloneProps: any = {\n // ...element.props,\n ...filteredProps,\n as: props.as || (element.props as { as?: ElementType }).as,\n className: finalClassName\n }\n\n // Forward the ref if provided, composed with any ref the element\n // already carries — overwriting it would silently detach the original.\n if (ref) {\n const existingRef = (element.props as { ref?: React.Ref<unknown> }).ref\n cloneProps.ref = existingRef ? composeRefs(existingRef, ref) : ref\n }\n\n return React.cloneElement(element, cloneProps)\n }\n\n throw Error('Something is wrong')\n }\n\n // Mark the component as a styled component so we can detect it later\n ;(Comp as any).__isStyledComponent = true\n\n // Name the component for DevTools and error component stacks — without\n // this every styled component reads as the inner function name, \"Comp\"\n const baseName =\n typeof el === 'string'\n ? el\n : (el as any).displayName || (el as any).name || 'Component'\n Comp.displayName = baseName.startsWith('styled.')\n ? baseName\n : `styled.${baseName}`\n\n return Comp\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export declare const useCallbackRef: () => [
|
|
3
|
-
React.
|
|
4
|
-
(
|
|
3
|
+
React.RefObject<HTMLElement | null>,
|
|
4
|
+
(el: HTMLElement | null) => void | (() => void)
|
|
5
5
|
];
|
|
6
6
|
export declare const useCallbackRefState: () => [
|
|
7
7
|
HTMLElement | null,
|
|
8
|
-
(
|
|
8
|
+
(el: HTMLElement | null) => void
|
|
9
9
|
];
|
|
@@ -3,7 +3,10 @@ import * as React$1 from "react";
|
|
|
3
3
|
var useCallbackRef = () => {
|
|
4
4
|
const elRef = React$1.useRef(null);
|
|
5
5
|
return [elRef, React$1.useCallback((el) => {
|
|
6
|
-
|
|
6
|
+
elRef.current = el;
|
|
7
|
+
return () => {
|
|
8
|
+
elRef.current = null;
|
|
9
|
+
};
|
|
7
10
|
}, [])];
|
|
8
11
|
};
|
|
9
12
|
var useCallbackRefState = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCallbackRef.js","names":[],"sources":["../../../src/utilities/hooks/useCallbackRef.ts"],"sourcesContent":["import * as React from 'react'\n\nexport const useCallbackRef: () => [\n React.
|
|
1
|
+
{"version":3,"file":"useCallbackRef.js","names":[],"sources":["../../../src/utilities/hooks/useCallbackRef.ts"],"sourcesContent":["import * as React from 'react'\n\nexport const useCallbackRef: () => [\n React.RefObject<HTMLElement | null>,\n (el: HTMLElement | null) => void | (() => void)\n] = () => {\n const elRef = React.useRef<HTMLElement | null>(null)\n\n // React 19 ref-callback cleanup: the ref must be cleared on detach, or it\n // retains the unmounted DOM node — stale reads and a memory leak.\n const setElRefCallback = React.useCallback((el: HTMLElement | null) => {\n elRef.current = el\n return () => {\n elRef.current = null\n }\n }, [])\n\n return [elRef, setElRefCallback]\n}\n\nexport const useCallbackRefState: () => [\n HTMLElement | null,\n (el: HTMLElement | null) => void\n] = () => {\n const [elRef, setElRef] = React.useState<HTMLElement | null>(null)\n const hasElement = React.useRef(false)\n\n const setElRefCallback = React.useCallback((el: HTMLElement | null) => {\n // Commit the attached node to state exactly once — the first time one\n // becomes available — and never again. Under React 19 concurrent rendering\n // with heavy CPU contention, renders get interrupted and re-run, so the DOM\n // node attached via the callback ref churns: React commits and replaces the\n // node, firing this callback with a fresh identity each time. The previous\n // `prev === el ? prev : el` guard couldn't catch that — a new identity is\n // never `=== prev` — so every churn scheduled another render, which churned\n // the node again: an unbounded \"Maximum update depth exceeded\" loop.\n //\n // A one-shot setState makes the returned element reference stable and the\n // loop structurally impossible (later invocations are no-ops). All consumers\n // attach this to a single, always-mounted element, so the first node is the\n // node — there is no element swap to miss.\n //\n // NOTE: re-verified against React 19 ref-callback cleanups (2026-07): a\n // cleanup-based attach/detach setState rewrite still loops — the regression\n // test in useCallbackRef.test.tsx fails with \"Maximum update depth\n // exceeded\". Cleanups don't help when every render mints a new node.\n if (el && !hasElement.current) {\n hasElement.current = true\n setElRef(el)\n }\n }, [])\n\n return [elRef, setElRefCallback]\n}\n"],"mappings":";;AAEA,IAAa,uBAGH;CACR,MAAM,QAAQ,QAAM,OAA2B,IAAI;CAWnD,OAAO,CAAC,OAPiB,QAAM,aAAa,OAA2B;EACrE,MAAM,UAAU;EAChB,aAAa;GACX,MAAM,UAAU;EAClB;CACF,GAAG,CAAC,CAEW,CAAgB;AACjC;AAEA,IAAa,4BAGH;CACR,MAAM,CAAC,OAAO,YAAY,QAAM,SAA6B,IAAI;CACjE,MAAM,aAAa,QAAM,OAAO,KAAK;CA2BrC,OAAO,CAAC,OAzBiB,QAAM,aAAa,OAA2B;EAmBrE,IAAI,MAAM,CAAC,WAAW,SAAS;GAC7B,WAAW,UAAU;GACrB,SAAS,EAAE;EACb;CACF,GAAG,CAAC,CAEW,CAAgB;AACjC"}
|
|
@@ -13,13 +13,23 @@ var useResizeObserver = ({ delay = 500, elements, onResize }) => {
|
|
|
13
13
|
React$1.useLayoutEffect(() => {
|
|
14
14
|
onResizeRef.current = onResize;
|
|
15
15
|
});
|
|
16
|
-
const observer = React$1.
|
|
16
|
+
const [observer, setObserver] = React$1.useState(null);
|
|
17
17
|
React$1.useEffect(() => {
|
|
18
|
+
const debouncedOnResize = debounce(delay, (entries) => onResizeRef.current(entries));
|
|
19
|
+
const resizeObserver = createResizeObserver(debouncedOnResize);
|
|
20
|
+
setObserver(resizeObserver);
|
|
21
|
+
return () => {
|
|
22
|
+
debouncedOnResize.cancel();
|
|
23
|
+
resizeObserver?.disconnect();
|
|
24
|
+
};
|
|
25
|
+
}, [delay]);
|
|
26
|
+
React$1.useEffect(() => {
|
|
27
|
+
if (!observer) return;
|
|
18
28
|
elements.forEach((element) => {
|
|
19
|
-
if (element) observer
|
|
29
|
+
if (element) observer.observe(element);
|
|
20
30
|
});
|
|
21
31
|
return () => {
|
|
22
|
-
elements.forEach((element) => element && observer
|
|
32
|
+
elements.forEach((element) => element && observer.unobserve(element));
|
|
23
33
|
};
|
|
24
34
|
}, [observer, elements]);
|
|
25
35
|
return observer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useResizeObserver.js","names":[],"sources":["../../../src/utilities/hooks/useResizeObserver.ts"],"sourcesContent":["import * as React from 'react'\nimport { debounce } from 'throttle-debounce'\n\ntype UseResizeObserverOptions = {\n elements: (HTMLElement | undefined | null)[]\n onResize: (entries: ResizeObserverEntry[]) => void\n delay?: number\n}\n\ntype UseResizeObserverOutput = ResizeObserver | null\n\nconst createResizeObserver = (\n callback: (entries: ResizeObserverEntry[]) => void\n) => {\n try {\n return new ResizeObserver(callback)\n } catch {\n return null\n }\n}\n\nexport const useResizeObserver = ({\n delay = 500,\n elements,\n onResize\n}: UseResizeObserverOptions): UseResizeObserverOutput => {\n // Keep the latest `onResize` in a ref so the observer is only recreated when\n // `delay` changes. Otherwise a callback whose identity changes on render (e.g.\n // `useSize`'s `handleResize`, which depends on `element`) would recreate and\n // re-subscribe the observer, and `ResizeObserver` fires its initial callback\n // on every `observe()` — a measure → setState → re-render → re-subscribe loop\n // that surfaces as \"Maximum update depth exceeded\".\n const onResizeRef = React.useRef(onResize)\n React.useLayoutEffect(() => {\n onResizeRef.current = onResize\n })\n\n const observer = React.
|
|
1
|
+
{"version":3,"file":"useResizeObserver.js","names":[],"sources":["../../../src/utilities/hooks/useResizeObserver.ts"],"sourcesContent":["import * as React from 'react'\nimport { debounce } from 'throttle-debounce'\n\ntype UseResizeObserverOptions = {\n elements: (HTMLElement | undefined | null)[]\n onResize: (entries: ResizeObserverEntry[]) => void\n delay?: number\n}\n\ntype UseResizeObserverOutput = ResizeObserver | null\n\nconst createResizeObserver = (\n callback: (entries: ResizeObserverEntry[]) => void\n) => {\n try {\n return new ResizeObserver(callback)\n } catch {\n return null\n }\n}\n\nexport const useResizeObserver = ({\n delay = 500,\n elements,\n onResize\n}: UseResizeObserverOptions): UseResizeObserverOutput => {\n // Keep the latest `onResize` in a ref so the observer is only recreated when\n // `delay` changes. Otherwise a callback whose identity changes on render (e.g.\n // `useSize`'s `handleResize`, which depends on `element`) would recreate and\n // re-subscribe the observer, and `ResizeObserver` fires its initial callback\n // on every `observe()` — a measure → setState → re-render → re-subscribe loop\n // that surfaces as \"Maximum update depth exceeded\".\n const onResizeRef = React.useRef(onResize)\n React.useLayoutEffect(() => {\n onResizeRef.current = onResize\n })\n\n // The observer is an OS-backed resource, so it must be created inside an\n // effect — created during render it would leak whenever React discards a\n // render (StrictMode, interrupted renders). The debounced callback is\n // cancelled on cleanup so no trailing invocation fires after the observer\n // is gone.\n const [observer, setObserver] = React.useState<ResizeObserver | null>(null)\n\n React.useEffect(() => {\n const debouncedOnResize = debounce(\n delay,\n (entries: ResizeObserverEntry[]) => onResizeRef.current(entries)\n )\n const resizeObserver = createResizeObserver(debouncedOnResize)\n setObserver(resizeObserver)\n\n return () => {\n debouncedOnResize.cancel()\n resizeObserver?.disconnect()\n }\n }, [delay])\n\n React.useEffect(() => {\n if (!observer) return\n\n elements.forEach((element) => {\n if (element) observer.observe(element)\n })\n\n return () => {\n elements.forEach((element) => element && observer.unobserve(element))\n }\n }, [observer, elements])\n\n return observer\n}\n"],"mappings":";;;AAWA,IAAM,wBACJ,aACG;CACH,IAAI;EACF,OAAO,IAAI,eAAe,QAAQ;CACpC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,IAAa,qBAAqB,EAChC,QAAQ,KACR,UACA,eACuD;CAOvD,MAAM,cAAc,QAAM,OAAO,QAAQ;CACzC,QAAM,sBAAsB;EAC1B,YAAY,UAAU;CACxB,CAAC;CAOD,MAAM,CAAC,UAAU,eAAe,QAAM,SAAgC,IAAI;CAE1E,QAAM,gBAAgB;EACpB,MAAM,oBAAoB,SACxB,QACC,YAAmC,YAAY,QAAQ,OAAO,CACjE;EACA,MAAM,iBAAiB,qBAAqB,iBAAiB;EAC7D,YAAY,cAAc;EAE1B,aAAa;GACX,kBAAkB,OAAO;GACzB,gBAAgB,WAAW;EAC7B;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,QAAM,gBAAgB;EACpB,IAAI,CAAC,UAAU;EAEf,SAAS,SAAS,YAAY;GAC5B,IAAI,SAAS,SAAS,QAAQ,OAAO;EACvC,CAAC;EAED,aAAa;GACX,SAAS,SAAS,YAAY,WAAW,SAAS,UAAU,OAAO,CAAC;EACtE;CACF,GAAG,CAAC,UAAU,QAAQ,CAAC;CAEvB,OAAO;AACT"}
|
|
@@ -1,30 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
2
2
|
import { debounce, throttle } from "throttle-debounce";
|
|
3
3
|
//#region src/utilities/hooks/useScrollPosition.ts
|
|
4
|
+
var NO_ELEMENT_SNAPSHOT = {
|
|
5
|
+
left: 0,
|
|
6
|
+
top: 0
|
|
7
|
+
};
|
|
4
8
|
var useScrollPosition = ({ element, delay = 500, delayMethod = "throttle" }) => {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const delayMethodFn = useMemo(() => delayMethod === "debounce" ? debounce : throttle, [delayMethod]);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
if (!element) return;
|
|
12
|
-
const handleScroll = delayMethodFn(delay, () => {
|
|
13
|
-
setScrollPosition((prev) => prev.left === element.scrollLeft && prev.top === element.scrollTop ? prev : {
|
|
14
|
-
left: element.scrollLeft,
|
|
15
|
-
top: element.scrollTop
|
|
16
|
-
});
|
|
17
|
-
});
|
|
9
|
+
const snapshotRef = useRef(null);
|
|
10
|
+
const subscribe = useCallback((onStoreChange) => {
|
|
11
|
+
if (!element) return () => void 0;
|
|
12
|
+
const handleScroll = (delayMethod === "debounce" ? debounce : throttle)(delay, onStoreChange);
|
|
18
13
|
element.addEventListener("scroll", handleScroll);
|
|
19
14
|
return () => {
|
|
15
|
+
handleScroll.cancel();
|
|
20
16
|
element.removeEventListener("scroll", handleScroll);
|
|
21
17
|
};
|
|
22
18
|
}, [
|
|
23
19
|
element,
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
delay,
|
|
21
|
+
delayMethod
|
|
26
22
|
]);
|
|
27
|
-
|
|
23
|
+
const getSnapshot = () => {
|
|
24
|
+
if (!element) return NO_ELEMENT_SNAPSHOT;
|
|
25
|
+
const prev = snapshotRef.current;
|
|
26
|
+
if (!prev || prev.left !== element.scrollLeft || prev.top !== element.scrollTop) snapshotRef.current = {
|
|
27
|
+
left: element.scrollLeft,
|
|
28
|
+
top: element.scrollTop
|
|
29
|
+
};
|
|
30
|
+
return snapshotRef.current;
|
|
31
|
+
};
|
|
32
|
+
return useSyncExternalStore(subscribe, getSnapshot, () => NO_ELEMENT_SNAPSHOT);
|
|
28
33
|
};
|
|
29
34
|
//#endregion
|
|
30
35
|
export { useScrollPosition };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScrollPosition.js","names":[],"sources":["../../../src/utilities/hooks/useScrollPosition.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useScrollPosition.js","names":[],"sources":["../../../src/utilities/hooks/useScrollPosition.ts"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from 'react'\nimport { debounce, throttle } from 'throttle-debounce'\n\ntype UseScrollPositionOptions = {\n element?: HTMLElement | null\n delay?: number\n delayMethod?: 'throttle' | 'debounce'\n}\n\ntype UseScrollPositionOutput = {\n left: number\n top: number\n}\n\nconst NO_ELEMENT_SNAPSHOT: UseScrollPositionOutput = { left: 0, top: 0 }\n\n// useSyncExternalStore rather than event-listener + setState: the position is\n// correct from the very first render (an already-scrolled element must not\n// report {0,0} until its next scroll event), the trailing throttle/debounce\n// invocation is cancelled on unsubscribe (no state updates after unmount),\n// and reads can't tear under concurrent rendering.\nexport const useScrollPosition = ({\n element,\n delay = 500,\n delayMethod = 'throttle'\n}: UseScrollPositionOptions): UseScrollPositionOutput => {\n const snapshotRef = useRef<UseScrollPositionOutput | null>(null)\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (!element) return () => undefined\n\n const delayMethodFn = delayMethod === 'debounce' ? debounce : throttle\n const handleScroll = delayMethodFn(delay, onStoreChange)\n\n element.addEventListener('scroll', handleScroll)\n\n return () => {\n handleScroll.cancel()\n element.removeEventListener('scroll', handleScroll)\n }\n },\n [element, delay, delayMethod]\n )\n\n // Snapshots must be referentially stable between store changes, so cache\n // the object and only replace it when the underlying values move.\n const getSnapshot = () => {\n if (!element) return NO_ELEMENT_SNAPSHOT\n\n const prev = snapshotRef.current\n if (\n !prev ||\n prev.left !== element.scrollLeft ||\n prev.top !== element.scrollTop\n ) {\n snapshotRef.current = {\n left: element.scrollLeft,\n top: element.scrollTop\n }\n }\n return snapshotRef.current as UseScrollPositionOutput\n }\n\n return useSyncExternalStore(subscribe, getSnapshot, () => NO_ELEMENT_SNAPSHOT)\n}\n"],"mappings":";;;AAcA,IAAM,sBAA+C;CAAE,MAAM;CAAG,KAAK;AAAE;AAOvE,IAAa,qBAAqB,EAChC,SACA,QAAQ,KACR,cAAc,iBACyC;CACvD,MAAM,cAAc,OAAuC,IAAI;CAE/D,MAAM,YAAY,aACf,kBAA8B;EAC7B,IAAI,CAAC,SAAS,aAAa,KAAA;EAG3B,MAAM,gBADgB,gBAAgB,aAAa,WAAW,SAAA,CAC3B,OAAO,aAAa;EAEvD,QAAQ,iBAAiB,UAAU,YAAY;EAE/C,aAAa;GACX,aAAa,OAAO;GACpB,QAAQ,oBAAoB,UAAU,YAAY;EACpD;CACF,GACA;EAAC;EAAS;EAAO;CAAW,CAC9B;CAIA,MAAM,oBAAoB;EACxB,IAAI,CAAC,SAAS,OAAO;EAErB,MAAM,OAAO,YAAY;EACzB,IACE,CAAC,QACD,KAAK,SAAS,QAAQ,cACtB,KAAK,QAAQ,QAAQ,WAErB,YAAY,UAAU;GACpB,MAAM,QAAQ;GACd,KAAK,QAAQ;EACf;EAEF,OAAO,YAAY;CACrB;CAEA,OAAO,qBAAqB,WAAW,mBAAmB,mBAAmB;AAC/E"}
|
|
@@ -1,25 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
2
2
|
import { debounce, throttle } from "throttle-debounce";
|
|
3
3
|
//#region src/utilities/hooks/useWindowScrollPosition.ts
|
|
4
|
+
var SERVER_SNAPSHOT = {
|
|
5
|
+
x: 0,
|
|
6
|
+
y: 0
|
|
7
|
+
};
|
|
4
8
|
var useWindowScrollPosition = ({ delay = 500, delayMethod = "throttle" } = {}) => {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
});
|
|
9
|
-
const delayMethodFn = useMemo(() => delayMethod === "debounce" ? debounce : throttle, [delayMethod]);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
const handleScroll = delayMethodFn(delay, () => {
|
|
12
|
-
setScrollPosition({
|
|
13
|
-
x: window.scrollX,
|
|
14
|
-
y: window.scrollY
|
|
15
|
-
});
|
|
16
|
-
});
|
|
9
|
+
const snapshotRef = useRef(null);
|
|
10
|
+
const subscribe = useCallback((onStoreChange) => {
|
|
11
|
+
const handleScroll = (delayMethod === "debounce" ? debounce : throttle)(delay, onStoreChange);
|
|
17
12
|
window.addEventListener("scroll", handleScroll);
|
|
18
13
|
return () => {
|
|
14
|
+
handleScroll.cancel();
|
|
19
15
|
window.removeEventListener("scroll", handleScroll);
|
|
20
16
|
};
|
|
21
|
-
}, [
|
|
22
|
-
|
|
17
|
+
}, [delay, delayMethod]);
|
|
18
|
+
const getSnapshot = () => {
|
|
19
|
+
const prev = snapshotRef.current;
|
|
20
|
+
if (!prev || prev.x !== window.scrollX || prev.y !== window.scrollY) snapshotRef.current = {
|
|
21
|
+
x: window.scrollX,
|
|
22
|
+
y: window.scrollY
|
|
23
|
+
};
|
|
24
|
+
return snapshotRef.current;
|
|
25
|
+
};
|
|
26
|
+
return useSyncExternalStore(subscribe, getSnapshot, () => SERVER_SNAPSHOT);
|
|
23
27
|
};
|
|
24
28
|
//#endregion
|
|
25
29
|
export { useWindowScrollPosition };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWindowScrollPosition.js","names":[],"sources":["../../../src/utilities/hooks/useWindowScrollPosition.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useWindowScrollPosition.js","names":[],"sources":["../../../src/utilities/hooks/useWindowScrollPosition.ts"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from 'react'\nimport { debounce, throttle } from 'throttle-debounce'\n\ntype UseWindowScrollPositionOptions = {\n delay?: number\n delayMethod?: 'throttle' | 'debounce'\n}\n\ntype UseWindowScrollPositionOutput = {\n x: number\n y: number\n}\n\nconst SERVER_SNAPSHOT: UseWindowScrollPositionOutput = { x: 0, y: 0 }\n\n// useSyncExternalStore rather than event-listener + setState: the position is\n// correct from the very first render (a mid-page mount must not report {0,0}\n// until the first scroll event), the trailing throttle/debounce invocation is\n// cancelled on unsubscribe (no state updates after unmount), and reads can't\n// tear under concurrent rendering.\nexport const useWindowScrollPosition = ({\n delay = 500,\n delayMethod = 'throttle'\n}: UseWindowScrollPositionOptions = {}): UseWindowScrollPositionOutput => {\n const snapshotRef = useRef<UseWindowScrollPositionOutput | null>(null)\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n const delayMethodFn = delayMethod === 'debounce' ? debounce : throttle\n const handleScroll = delayMethodFn(delay, onStoreChange)\n\n window.addEventListener('scroll', handleScroll)\n\n return () => {\n handleScroll.cancel()\n window.removeEventListener('scroll', handleScroll)\n }\n },\n [delay, delayMethod]\n )\n\n // Snapshots must be referentially stable between store changes, so cache\n // the object and only replace it when the underlying values move.\n const getSnapshot = () => {\n const prev = snapshotRef.current\n if (!prev || prev.x !== window.scrollX || prev.y !== window.scrollY) {\n snapshotRef.current = { x: window.scrollX, y: window.scrollY }\n }\n return snapshotRef.current as UseWindowScrollPositionOutput\n }\n\n return useSyncExternalStore(subscribe, getSnapshot, () => SERVER_SNAPSHOT)\n}\n"],"mappings":";;;AAaA,IAAM,kBAAiD;CAAE,GAAG;CAAG,GAAG;AAAE;AAOpE,IAAa,2BAA2B,EACtC,QAAQ,KACR,cAAc,eACoB,CAAC,MAAqC;CACxE,MAAM,cAAc,OAA6C,IAAI;CAErE,MAAM,YAAY,aACf,kBAA8B;EAE7B,MAAM,gBADgB,gBAAgB,aAAa,WAAW,SAAA,CAC3B,OAAO,aAAa;EAEvD,OAAO,iBAAiB,UAAU,YAAY;EAE9C,aAAa;GACX,aAAa,OAAO;GACpB,OAAO,oBAAoB,UAAU,YAAY;EACnD;CACF,GACA,CAAC,OAAO,WAAW,CACrB;CAIA,MAAM,oBAAoB;EACxB,MAAM,OAAO,YAAY;EACzB,IAAI,CAAC,QAAQ,KAAK,MAAM,OAAO,WAAW,KAAK,MAAM,OAAO,SAC1D,YAAY,UAAU;GAAE,GAAG,OAAO;GAAS,GAAG,OAAO;EAAQ;EAE/D,OAAO,YAAY;CACrB;CAEA,OAAO,qBAAqB,WAAW,mBAAmB,eAAe;AAC3E"}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
//#region src/utilities/uri/index.ts
|
|
2
|
-
var isExternalUrl = (url) =>
|
|
3
|
-
if (!url) return false;
|
|
4
|
-
const isAbsoluteUrl = /^https?:\/\//.test(url);
|
|
5
|
-
if (typeof window === "undefined") return isAbsoluteUrl;
|
|
6
|
-
return isAbsoluteUrl && new URL(url).origin !== window.location.origin;
|
|
7
|
-
};
|
|
2
|
+
var isExternalUrl = (url) => !!url && /^https?:\/\//.test(url);
|
|
8
3
|
var getExternalAnchorProps = (url) => isExternalUrl(url) ? {
|
|
9
4
|
target: "_blank",
|
|
10
5
|
rel: "noopener noreferrer"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utilities/uri/index.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utilities/uri/index.ts"],"sourcesContent":["// Deliberately syntactic (no window.location.origin comparison): the check\n// must give the same answer on server and client, or an SSR'd same-origin\n// absolute link renders target=\"_blank\" markup that the client would not.\n// Consumers wanting same-tab navigation should pass relative URLs.\nexport const isExternalUrl = (url?: string) => !!url && /^https?:\\/\\//.test(url)\n\nexport const getExternalAnchorProps = (url?: string) =>\n isExternalUrl(url) ? { target: '_blank', rel: 'noopener noreferrer' } : {}\n"],"mappings":";AAIA,IAAa,iBAAiB,QAAiB,CAAC,CAAC,OAAO,eAAe,KAAK,GAAG;AAE/E,IAAa,0BAA0B,QACrC,cAAc,GAAG,IAAI;CAAE,QAAQ;CAAU,KAAK;AAAsB,IAAI,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atom-learning/components",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://github.com/Atom-Learning/components#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"validate": "node ./scripts/validate.mjs",
|
|
69
69
|
"validate:linting": "oxlint src/ --quiet",
|
|
70
70
|
"validate:size": "size-limit",
|
|
71
|
+
"validate:barrel": "node ./scripts/validate-barrel.mjs",
|
|
71
72
|
"validate:types": "tsgo --noEmit",
|
|
72
73
|
"validate:ssr": "node ./scripts/validate-ssr.mjs",
|
|
73
74
|
"validate:public-api": "node ./scripts/api-snapshot.mjs",
|
|
@@ -79,24 +80,24 @@
|
|
|
79
80
|
"@dnd-kit/modifiers": "^6.0.0",
|
|
80
81
|
"@dnd-kit/sortable": "^7.0.1",
|
|
81
82
|
"@dnd-kit/utilities": "^3.2.0",
|
|
82
|
-
"@
|
|
83
|
-
"@radix-ui/react-
|
|
84
|
-
"@radix-ui/react-
|
|
85
|
-
"@radix-ui/react-
|
|
86
|
-
"@radix-ui/react-
|
|
87
|
-
"@radix-ui/react-dialog": "^1.1.
|
|
88
|
-
"@radix-ui/react-dropdown-menu": "^2.1.
|
|
89
|
-
"@radix-ui/react-navigation-menu": "^1.2.
|
|
90
|
-
"@radix-ui/react-popover": "^1.1.
|
|
91
|
-
"@radix-ui/react-progress": "^1.1.
|
|
92
|
-
"@radix-ui/react-radio-group": "^1.
|
|
93
|
-
"@radix-ui/react-select": "^2.
|
|
94
|
-
"@radix-ui/react-slider": "^1.
|
|
95
|
-
"@radix-ui/react-slot": "^1.
|
|
96
|
-
"@radix-ui/react-switch": "^1.
|
|
97
|
-
"@radix-ui/react-tabs": "^1.1.
|
|
98
|
-
"@radix-ui/react-toggle-group": "^1.1.
|
|
99
|
-
"@radix-ui/react-tooltip": "^1.
|
|
83
|
+
"@radix-ui/react-accordion": "^1.2.16",
|
|
84
|
+
"@radix-ui/react-alert-dialog": "^1.1.19",
|
|
85
|
+
"@radix-ui/react-checkbox": "^1.3.7",
|
|
86
|
+
"@radix-ui/react-collapsible": "^1.1.16",
|
|
87
|
+
"@radix-ui/react-compose-refs": "^1.1.3",
|
|
88
|
+
"@radix-ui/react-dialog": "^1.1.19",
|
|
89
|
+
"@radix-ui/react-dropdown-menu": "^2.1.20",
|
|
90
|
+
"@radix-ui/react-navigation-menu": "^1.2.18",
|
|
91
|
+
"@radix-ui/react-popover": "^1.1.19",
|
|
92
|
+
"@radix-ui/react-progress": "^1.1.12",
|
|
93
|
+
"@radix-ui/react-radio-group": "^1.4.3",
|
|
94
|
+
"@radix-ui/react-select": "^2.3.3",
|
|
95
|
+
"@radix-ui/react-slider": "^1.4.3",
|
|
96
|
+
"@radix-ui/react-slot": "^1.3.0",
|
|
97
|
+
"@radix-ui/react-switch": "^1.3.3",
|
|
98
|
+
"@radix-ui/react-tabs": "^1.1.17",
|
|
99
|
+
"@radix-ui/react-toggle-group": "^1.1.15",
|
|
100
|
+
"@radix-ui/react-tooltip": "^1.2.12",
|
|
100
101
|
"@reach/combobox": "^0.16.1",
|
|
101
102
|
"@tailwindcss/vite": "^4.3.1",
|
|
102
103
|
"@tanstack/react-table": "^8.5.11",
|
|
@@ -107,9 +108,9 @@
|
|
|
107
108
|
"embla-carousel-react": "^8.0.0",
|
|
108
109
|
"glob": "^7.1.6",
|
|
109
110
|
"invariant": "^2.2.4",
|
|
110
|
-
"mdast-util-directive": "1.0
|
|
111
|
-
"mdast-util-from-markdown": "0.
|
|
112
|
-
"micromark-extension-directive": "
|
|
111
|
+
"mdast-util-directive": "^3.1.0",
|
|
112
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
113
|
+
"micromark-extension-directive": "^4.0.0",
|
|
113
114
|
"minimatch": "^10.0.0",
|
|
114
115
|
"prop-types": "^15.8.1",
|
|
115
116
|
"react-aria": "^3.36.0",
|
|
@@ -122,36 +123,34 @@
|
|
|
122
123
|
"tailwindcss": "^4.3.1",
|
|
123
124
|
"tailwindcss-safe-area": "^1.3.0",
|
|
124
125
|
"throttle-debounce": "^3.0.1",
|
|
125
|
-
"ts-morph": "^
|
|
126
|
-
"uid": "^2.0.0",
|
|
126
|
+
"ts-morph": "^28.0.0",
|
|
127
127
|
"use-deep-compare-effect": "^1.8.1"
|
|
128
128
|
},
|
|
129
129
|
"devDependencies": {
|
|
130
130
|
"@atom-learning/icons": "1.24.0",
|
|
131
131
|
"@atom-learning/theme": "^6.0.0",
|
|
132
|
-
"@commitlint/cli": "^
|
|
133
|
-
"@commitlint/config-conventional": "^
|
|
134
|
-
"@radix-ui/react-id": "^1.1.
|
|
132
|
+
"@commitlint/cli": "^21.2.1",
|
|
133
|
+
"@commitlint/config-conventional": "^21.2.0",
|
|
134
|
+
"@radix-ui/react-id": "^1.1.2",
|
|
135
135
|
"@semantic-release/changelog": "^6.0.3",
|
|
136
136
|
"@semantic-release/exec": "^7.0.0",
|
|
137
137
|
"@semantic-release/github": "^12.0.6",
|
|
138
138
|
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
139
|
-
"@size-limit/preset-small-lib": "^12.0
|
|
139
|
+
"@size-limit/preset-small-lib": "^12.1.0",
|
|
140
140
|
"@testing-library/dom": "^10.4.1",
|
|
141
141
|
"@testing-library/jest-dom": "^6.9.1",
|
|
142
142
|
"@testing-library/react": "^16.3.2",
|
|
143
143
|
"@testing-library/user-event": "^14.6.1",
|
|
144
|
-
"@types/mdast": "^
|
|
144
|
+
"@types/mdast": "^4.0.0",
|
|
145
145
|
"@types/node": "20.6.0",
|
|
146
146
|
"@types/prop-types": "^15",
|
|
147
147
|
"@types/react": "^19.0.0",
|
|
148
148
|
"@types/react-dom": "^19.0.0",
|
|
149
149
|
"@typescript/native-preview": "^7.0.0-dev.20260313.1",
|
|
150
150
|
"@vitejs/plugin-react": "^6.0.1",
|
|
151
|
-
"@vitest/browser-playwright": "^4.1.
|
|
152
|
-
"@vitest/coverage-v8": "^4.1.
|
|
153
|
-
"@vitest/ui": "^4.1.
|
|
154
|
-
"alias-hq": "^5.3.0",
|
|
151
|
+
"@vitest/browser-playwright": "^4.1.10",
|
|
152
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
153
|
+
"@vitest/ui": "^4.1.10",
|
|
155
154
|
"axe-core": "^4.11.1",
|
|
156
155
|
"change-case": "^4.1.2",
|
|
157
156
|
"chokidar": "^3.5.1",
|
|
@@ -169,10 +168,10 @@
|
|
|
169
168
|
"react-dom": "^19.0.0",
|
|
170
169
|
"semantic-release": "^25.0.0",
|
|
171
170
|
"semantic-release-slack-bot": "^4.0.2",
|
|
172
|
-
"size-limit": "^12.0
|
|
171
|
+
"size-limit": "^12.1.0",
|
|
173
172
|
"tsnapi": "^0.1.1",
|
|
174
173
|
"vite": "^8.0.0",
|
|
175
|
-
"vitest": "^4.1.
|
|
174
|
+
"vitest": "^4.1.10",
|
|
176
175
|
"yargs": "^16.2.0"
|
|
177
176
|
},
|
|
178
177
|
"peerDependencies": {
|
|
@@ -244,6 +243,11 @@
|
|
|
244
243
|
"limit": "25kb",
|
|
245
244
|
"path": "dist/index.js",
|
|
246
245
|
"import": "{ useAlert, Alert }"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"limit": "50kb",
|
|
249
|
+
"path": "dist/index.js",
|
|
250
|
+
"import": "{ MarkdownContent }"
|
|
247
251
|
}
|
|
248
252
|
]
|
|
249
253
|
}
|