diff --git a/packages/apollo-wind/src/index.ts b/packages/apollo-wind/src/index.ts index 12d90f7d3..ed1367784 100644 --- a/packages/apollo-wind/src/index.ts +++ b/packages/apollo-wind/src/index.ts @@ -2,93 +2,105 @@ // @uipath/apollo-wind - Public API Exports // ============================================================================= +export type { + AdapterRequest, + AdapterResponse, + DataAdapter, +} from './components/forms/data-fetcher'; +export { + DataFetcher, + DataSourceBuilder, + DataTransformers, + FetchAdapter, +} from './components/forms/data-fetcher'; +export { FormFieldRenderer } from './components/forms/field-renderer'; +export { FormDesigner } from './components/forms/form-designer'; +export { + analyticsPlugin, + auditPlugin, + autoSavePlugin, + formattingPlugin, + validationPlugin, + workflowPlugin, +} from './components/forms/form-plugins'; +export type { + CustomFieldComponentProps, + DataSource, + FieldCondition, + FieldMetadata, + FieldOption, + FieldRule, + FieldType, + FormAction, + FormContext, + FormPlugin, + FormSchema, + FormSection, + FormStep, +} from './components/forms/form-schema'; +export { + hasMinMaxStep, + hasOptions, + isCustomField, + isFileField, +} from './components/forms/form-schema'; +export { FormStateViewer } from './components/forms/form-state-viewer'; // ----------------------------------------------------------------------------- -// Utilities +// Metadata Forms System // ----------------------------------------------------------------------------- -export { cn } from './lib/utils'; - +export { MetadataForm } from './components/forms/metadata-form'; +export { + ExpressionBuilder, + RuleBuilder, + RulesEngine, +} from './components/forms/rules-engine'; // ----------------------------------------------------------------------------- -// Layout Components +// Utility Components // ----------------------------------------------------------------------------- -export { Row } from './components/ui/layout/row'; -export type { RowProps } from './components/ui/layout/row'; - -export { Column } from './components/ui/layout/column'; -export type { ColumnProps } from './components/ui/layout/column'; - -export { Grid } from './components/ui/layout/grid'; -export type { GridProps } from './components/ui/layout/grid'; - +export { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from './components/ui/accordion'; +export { Alert, AlertDescription, AlertTitle } from './components/ui/alert'; +export { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogOverlay, + AlertDialogPortal, + AlertDialogTitle, + AlertDialogTrigger, +} from './components/ui/alert-dialog'; +export { AspectRatio } from './components/ui/aspect-ratio'; +export { Avatar, AvatarFallback, AvatarImage } from './components/ui/avatar'; +export type { BadgeProps } from './components/ui/badge'; +export { Badge, badgeVariants } from './components/ui/badge'; +export { + Breadcrumb, + BreadcrumbEllipsis, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from './components/ui/breadcrumb'; +export type { ButtonProps } from './components/ui/button'; // ----------------------------------------------------------------------------- // Button Components // ----------------------------------------------------------------------------- export { Button, buttonVariants } from './components/ui/button'; -export type { ButtonProps } from './components/ui/button'; - export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, } from './components/ui/button-group'; - -export { Toggle, toggleVariants } from './components/ui/toggle'; - -export { ToggleGroup, ToggleGroupItem } from './components/ui/toggle-group'; - -// ----------------------------------------------------------------------------- -// Form Input Components -// ----------------------------------------------------------------------------- -export { Input } from './components/ui/input'; -export type { InputProps } from './components/ui/input'; - -export { Textarea } from './components/ui/textarea'; -export type { TextareaProps } from './components/ui/textarea'; - -export { Label } from './components/ui/label'; -export type { LabelProps } from './components/ui/label'; - -export { Checkbox } from './components/ui/checkbox'; -export type { CheckboxProps } from './components/ui/checkbox'; - -export { RadioGroup, RadioGroupItem } from './components/ui/radio-group'; - -export { Switch } from './components/ui/switch'; - -export { Slider } from './components/ui/slider'; - -export { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectScrollDownButton, - SelectScrollUpButton, - SelectSeparator, - SelectTrigger, - SelectValue, -} from './components/ui/select'; - -export { Combobox } from './components/ui/combobox'; - -export { MultiSelect } from './components/ui/multi-select'; -export type { MultiSelectProps } from './components/ui/multi-select'; - -export { Search, SearchWithSuggestions } from './components/ui/search'; -export type { - SearchProps, - SearchWithSuggestionsProps, -} from './components/ui/search'; - export { Calendar } from './components/ui/calendar'; - -export { DatePicker } from './components/ui/date-picker'; - -export { DateTimePicker } from './components/ui/datetime-picker'; -export type { DateTimePickerProps } from './components/ui/datetime-picker'; - -export { FileUpload } from './components/ui/file-upload'; - // ----------------------------------------------------------------------------- // Data Display Components // ----------------------------------------------------------------------------- @@ -100,65 +112,53 @@ export { CardHeader, CardTitle, } from './components/ui/card'; - -export { StatsCard } from './components/ui/stats-card'; -export type { StatsCardProps } from './components/ui/stats-card'; - -export { Badge, badgeVariants } from './components/ui/badge'; -export type { BadgeProps } from './components/ui/badge'; - -export { CodeBlock } from './components/ui/code-block'; +export type { CheckboxProps } from './components/ui/checkbox'; +export { Checkbox } from './components/ui/checkbox'; export type { CodeBlockProps } from './components/ui/code-block'; - -export { Avatar, AvatarFallback, AvatarImage } from './components/ui/avatar'; - +export { CodeBlock } from './components/ui/code-block'; export { - Table, - TableBody, - TableCaption, - TableCell, - TableFooter, - TableHead, - TableHeader, - TableRow, -} from './components/ui/table'; - + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from './components/ui/collapsible'; +export { Combobox } from './components/ui/combobox'; +export { + Command, + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, + CommandShortcut, +} from './components/ui/command'; +export { + ContextMenu, + ContextMenuCheckboxItem, + ContextMenuContent, + ContextMenuGroup, + ContextMenuItem, + ContextMenuLabel, + ContextMenuPortal, + ContextMenuRadioGroup, + ContextMenuRadioItem, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuTrigger, +} from './components/ui/context-menu'; +export type { DataTableProps } from './components/ui/data-table'; export { DataTable, DataTableColumnHeader, DataTableSelectColumn, } from './components/ui/data-table'; -export type { DataTableProps } from './components/ui/data-table'; - -export { - EditableCell, - createEditableColumn, -} from './components/ui/editable-cell'; -export type { - EditableCellMeta, - EditableCellType, -} from './components/ui/editable-cell'; - -export { Progress } from './components/ui/progress'; - -export { Skeleton } from './components/ui/skeleton'; - -export { Spinner, spinnerVariants } from './components/ui/spinner'; -export type { SpinnerProps } from './components/ui/spinner'; - -export { EmptyState } from './components/ui/empty-state'; -export type { EmptyStateProps } from './components/ui/empty-state'; - -export { default as TreeView } from './components/ui/tree-view'; -export type { - TreeViewItem, - TreeViewItemAction, - TreeViewIconMap, - TreeViewMenuItem, - TreeViewProps, - TreeViewSelectionMode, -} from './components/ui/tree-view'; - +export { DatePicker } from './components/ui/date-picker'; +export type { DateTimePickerProps } from './components/ui/datetime-picker'; +export { DateTimePicker } from './components/ui/datetime-picker'; // ----------------------------------------------------------------------------- // Feedback & Overlay Components // ----------------------------------------------------------------------------- @@ -174,90 +174,9 @@ export { DialogTitle, DialogTrigger, } from './components/ui/dialog'; - -export { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogOverlay, - AlertDialogPortal, - AlertDialogTitle, - AlertDialogTrigger, -} from './components/ui/alert-dialog'; - -export { - Sheet, - SheetClose, - SheetContent, - SheetDescription, - SheetFooter, - SheetHeader, - SheetOverlay, - SheetPortal, - SheetTitle, - SheetTrigger, -} from './components/ui/sheet'; - -export { - Popover, - PopoverAnchor, - PopoverContent, - PopoverTrigger, -} from './components/ui/popover'; - -export { - Tooltip, - TooltipContent, - TooltipPortal, - TooltipProvider, - TooltipTrigger, -} from './components/ui/tooltip'; - -export { - HoverCard, - HoverCardContent, - HoverCardTrigger, -} from './components/ui/hover-card'; - -export { Alert, AlertDescription, AlertTitle } from './components/ui/alert'; - -export { toast, Toaster } from './components/ui/sonner'; - -// ----------------------------------------------------------------------------- -// Navigation Components -// ----------------------------------------------------------------------------- -export { Tabs, TabsContent, TabsList, TabsTrigger } from './components/ui/tabs'; - -export { - Breadcrumb, - BreadcrumbEllipsis, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, -} from './components/ui/breadcrumb'; - -export { - Pagination, - PaginationContent, - PaginationEllipsis, - PaginationItem, - PaginationLink, - PaginationNext, - PaginationPrevious, -} from './components/ui/pagination'; - -export { Stepper } from './components/ui/stepper'; -export type { Step, StepperProps } from './components/ui/stepper'; - -// ----------------------------------------------------------------------------- -// Menu Components -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// Menu Components +// ----------------------------------------------------------------------------- export { DropdownMenu, DropdownMenuCheckboxItem, @@ -275,119 +194,143 @@ export { DropdownMenuSubTrigger, DropdownMenuTrigger, } from './components/ui/dropdown-menu'; - +export type { + EditableCellMeta, + EditableCellType, +} from './components/ui/editable-cell'; export { - ContextMenu, - ContextMenuCheckboxItem, - ContextMenuContent, - ContextMenuGroup, - ContextMenuItem, - ContextMenuLabel, - ContextMenuPortal, - ContextMenuRadioGroup, - ContextMenuRadioItem, - ContextMenuSeparator, - ContextMenuShortcut, - ContextMenuSub, - ContextMenuSubContent, - ContextMenuSubTrigger, - ContextMenuTrigger, -} from './components/ui/context-menu'; - + createEditableColumn, + EditableCell, +} from './components/ui/editable-cell'; +export type { EmptyStateProps } from './components/ui/empty-state'; +export { EmptyState } from './components/ui/empty-state'; +export { FileUpload } from './components/ui/file-upload'; export { - Command, - CommandDialog, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - CommandSeparator, - CommandShortcut, -} from './components/ui/command'; - + HoverCard, + HoverCardContent, + HoverCardTrigger, +} from './components/ui/hover-card'; +export type { InputProps } from './components/ui/input'; // ----------------------------------------------------------------------------- -// Utility Components +// Form Input Components // ----------------------------------------------------------------------------- +export { Input } from './components/ui/input'; +export type { LabelProps } from './components/ui/label'; +export { Label } from './components/ui/label'; +export type { ColumnProps } from './components/ui/layout/column'; +export { Column } from './components/ui/layout/column'; +export type { GridProps } from './components/ui/layout/grid'; +export { Grid } from './components/ui/layout/grid'; +export type { RowProps } from './components/ui/layout/row'; +// ----------------------------------------------------------------------------- +// Layout Components +// ----------------------------------------------------------------------------- +export { Row } from './components/ui/layout/row'; +export type { MultiSelectProps } from './components/ui/multi-select'; +export { MultiSelect } from './components/ui/multi-select'; export { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from './components/ui/accordion'; - + Pagination, + PaginationContent, + PaginationEllipsis, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from './components/ui/pagination'; export { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from './components/ui/collapsible'; - -export { ScrollArea, ScrollBar } from './components/ui/scroll-area'; - -export { Separator } from './components/ui/separator'; - + Popover, + PopoverAnchor, + PopoverContent, + PopoverTrigger, +} from './components/ui/popover'; +export { Progress } from './components/ui/progress'; +export { RadioGroup, RadioGroupItem } from './components/ui/radio-group'; export { ResizableHandle, ResizablePanel, ResizablePanelGroup, } from './components/ui/resizable'; - -export { AspectRatio } from './components/ui/aspect-ratio'; - -// ----------------------------------------------------------------------------- -// Metadata Forms System -// ----------------------------------------------------------------------------- -export { MetadataForm } from './components/forms/metadata-form'; -export { FormFieldRenderer } from './components/forms/field-renderer'; -export { FormDesigner } from './components/forms/form-designer'; -export { FormStateViewer } from './components/forms/form-state-viewer'; - +export { ScrollArea, ScrollBar } from './components/ui/scroll-area'; +export type { + SearchProps, + SearchWithSuggestionsProps, +} from './components/ui/search'; +export { Search, SearchWithSuggestions } from './components/ui/search'; export { - RulesEngine, - RuleBuilder, - ExpressionBuilder, -} from './components/forms/rules-engine'; - + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, +} from './components/ui/select'; +export { Separator } from './components/ui/separator'; export { - DataFetcher, - DataSourceBuilder, - DataTransformers, - FetchAdapter, -} from './components/forms/data-fetcher'; -export type { - DataAdapter, - AdapterRequest, - AdapterResponse, -} from './components/forms/data-fetcher'; - + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetOverlay, + SheetPortal, + SheetTitle, + SheetTrigger, +} from './components/ui/sheet'; +export { Skeleton } from './components/ui/skeleton'; +export { Slider } from './components/ui/slider'; +export { Toaster, toast } from './components/ui/sonner'; +export type { SpinnerProps } from './components/ui/spinner'; +export { Spinner, spinnerVariants } from './components/ui/spinner'; +export type { StatsCardProps } from './components/ui/stats-card'; +export { StatsCard } from './components/ui/stats-card'; +export type { Step, StepperProps } from './components/ui/stepper'; +export { Stepper } from './components/ui/stepper'; +export { Switch } from './components/ui/switch'; export { - analyticsPlugin, - autoSavePlugin, - validationPlugin, - workflowPlugin, - auditPlugin, - formattingPlugin, -} from './components/forms/form-plugins'; - + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from './components/ui/table'; +// ----------------------------------------------------------------------------- +// Navigation Components +// ----------------------------------------------------------------------------- +export { Tabs, TabsContent, TabsList, TabsTrigger } from './components/ui/tabs'; +export type { TextareaProps } from './components/ui/textarea'; +export { Textarea } from './components/ui/textarea'; +export { Toggle, toggleVariants } from './components/ui/toggle'; +export { ToggleGroup, ToggleGroupItem } from './components/ui/toggle-group'; +export { + Tooltip, + TooltipContent, + TooltipPortal, + TooltipProvider, + TooltipTrigger, +} from './components/ui/tooltip'; export type { - FormSchema, - FormSection, - FormStep, - FieldMetadata, - FieldType, - FieldCondition, - FieldRule, - DataSource, - FormContext, - FormPlugin, - FormAction, - CustomFieldComponentProps, - FieldOption, -} from './components/forms/form-schema'; - + TreeViewIconMap, + TreeViewItem, + TreeViewItemAction, + TreeViewMenuItem, + TreeViewProps, + TreeViewSelectionMode, +} from './components/ui/tree-view'; +export { default as TreeView } from './components/ui/tree-view'; export { - hasOptions, - hasMinMaxStep, - isFileField, - isCustomField, -} from './components/forms/form-schema'; + hasApolloWindCss, + injectTailwindIntoShadowRoot, + TAILWIND_INJECT_ATTR, +} from './lib/shadow-dom-css'; +// ----------------------------------------------------------------------------- +// Utilities +// ----------------------------------------------------------------------------- +export { cn } from './lib/utils'; diff --git a/packages/apollo-wind/src/lib/index.ts b/packages/apollo-wind/src/lib/index.ts index e85b6f5ae..781cbf766 100644 --- a/packages/apollo-wind/src/lib/index.ts +++ b/packages/apollo-wind/src/lib/index.ts @@ -1 +1,6 @@ -export { cn, get, deepEqual } from './utils'; +export { + hasApolloWindCss, + injectTailwindIntoShadowRoot, + TAILWIND_INJECT_ATTR, +} from './shadow-dom-css'; +export { cn, deepEqual, get } from './utils'; diff --git a/packages/apollo-wind/src/lib/register-shadow-dom-properties.test.ts b/packages/apollo-wind/src/lib/register-shadow-dom-properties.test.ts new file mode 100644 index 000000000..67379420d --- /dev/null +++ b/packages/apollo-wind/src/lib/register-shadow-dom-properties.test.ts @@ -0,0 +1,58 @@ +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { registerCssPropertyRules } from './register-shadow-dom-properties'; + +const SELECTOR = 'style[data-tw-property-rules]'; + +const SAMPLE_CSS = ` +@layer base { .border { border-style: var(--tw-border-style); border-width: 1px; } } +@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid} +@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000} +@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0} +.bg-popover { background-color: var(--popover); } +`; + +beforeEach(() => { + document.querySelectorAll(SELECTOR).forEach((el) => { el.remove(); }); +}); + +afterEach(() => { + document.querySelectorAll(SELECTOR).forEach((el) => { el.remove(); }); +}); + +describe('registerCssPropertyRules', () => { + it('extracts @property rules from CSS and injects them into document.head', () => { + registerCssPropertyRules(SAMPLE_CSS); + + const style = document.querySelector(SELECTOR); + expect(style).not.toBeNull(); + + const text = style?.textContent ?? ''; + expect(text).toContain('@property --tw-border-style'); + expect(text).toContain('@property --tw-shadow'); + expect(text).toContain('@property --tw-translate-x'); + }); + + it('does not include non-@property rules', () => { + registerCssPropertyRules(SAMPLE_CSS); + + const text = document.querySelector(SELECTOR)?.textContent ?? ''; + expect(text).not.toContain('.border'); + expect(text).not.toContain('.bg-popover'); + expect(text).not.toContain('@layer'); + }); + + it('injects only one style element when called multiple times', () => { + registerCssPropertyRules(SAMPLE_CSS); + registerCssPropertyRules(SAMPLE_CSS); + registerCssPropertyRules(SAMPLE_CSS); + + const elements = document.querySelectorAll(SELECTOR); + expect(elements).toHaveLength(1); + }); + + it('does nothing when CSS has no @property rules', () => { + registerCssPropertyRules('.flex { display: flex; }'); + + expect(document.querySelector(SELECTOR)).toBeNull(); + }); +}); diff --git a/packages/apollo-wind/src/lib/register-shadow-dom-properties.ts b/packages/apollo-wind/src/lib/register-shadow-dom-properties.ts new file mode 100644 index 000000000..79848a6d2 --- /dev/null +++ b/packages/apollo-wind/src/lib/register-shadow-dom-properties.ts @@ -0,0 +1,44 @@ +/** + * Extract `@property` at-rules from a CSS string and inject them into + * `document.head` so they register at the global scope. + * + * Browsers silently ignore `@property` rules inside shadow DOM `