@ifc-lite/viewer 1.1.6 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/LICENSE +373 -0
  2. package/dist/apple-touch-icon.png +0 -0
  3. package/dist/assets/Arrow.dom-B0e15b_b.js +20 -0
  4. package/dist/assets/arrow2-bb-jcVEo.js +2 -0
  5. package/dist/assets/arrow2_bg-4Y7xYo54.wasm +0 -0
  6. package/dist/assets/arrow2_bg-BlXl-cSQ.js +1 -0
  7. package/dist/assets/arrow2_bg-BoXCojjR.wasm +0 -0
  8. package/dist/assets/desktop-cache-oPzaWXYE.js +1 -0
  9. package/dist/assets/event-DIOks52T.js +1 -0
  10. package/dist/assets/ifc-cache-BAN4vcd4.js +1 -0
  11. package/dist/assets/ifc-lite_bg-C6kblxf9.wasm +0 -0
  12. package/dist/assets/index-Dgd6vzw_.js +65252 -0
  13. package/dist/assets/index-v3mcCUPN.css +1 -0
  14. package/dist/assets/native-bridge-Ci7NLjlZ.js +111 -0
  15. package/dist/assets/wasm-bridge-Dc82YpdZ.js +1 -0
  16. package/dist/favicon-16x16-cropped.png +0 -0
  17. package/dist/favicon-16x16.png +0 -0
  18. package/dist/favicon-192x192-cropped.png +0 -0
  19. package/dist/favicon-192x192.png +0 -0
  20. package/dist/favicon-32x32-cropped.png +0 -0
  21. package/dist/favicon-32x32.png +0 -0
  22. package/dist/favicon-48x48-cropped.png +0 -0
  23. package/dist/favicon-48x48.png +0 -0
  24. package/dist/favicon-512x512-cropped.png +0 -0
  25. package/dist/favicon-512x512.png +0 -0
  26. package/dist/favicon-64x64-cropped.png +0 -0
  27. package/dist/favicon-64x64.png +0 -0
  28. package/dist/favicon-96x96-cropped.png +0 -0
  29. package/dist/favicon-96x96.png +0 -0
  30. package/dist/favicon-square-512.png +0 -0
  31. package/dist/favicon.ico +0 -0
  32. package/dist/favicon.png +0 -0
  33. package/dist/favicon.svg +3 -0
  34. package/dist/index.html +44 -0
  35. package/dist/logo.png +0 -0
  36. package/dist/manifest.json +48 -0
  37. package/index.html +33 -2
  38. package/package.json +34 -17
  39. package/public/apple-touch-icon.png +0 -0
  40. package/public/favicon-16x16-cropped.png +0 -0
  41. package/public/favicon-16x16.png +0 -0
  42. package/public/favicon-192x192-cropped.png +0 -0
  43. package/public/favicon-192x192.png +0 -0
  44. package/public/favicon-32x32-cropped.png +0 -0
  45. package/public/favicon-32x32.png +0 -0
  46. package/public/favicon-48x48-cropped.png +0 -0
  47. package/public/favicon-48x48.png +0 -0
  48. package/public/favicon-512x512-cropped.png +0 -0
  49. package/public/favicon-512x512.png +0 -0
  50. package/public/favicon-64x64-cropped.png +0 -0
  51. package/public/favicon-64x64.png +0 -0
  52. package/public/favicon-96x96-cropped.png +0 -0
  53. package/public/favicon-96x96.png +0 -0
  54. package/public/favicon-square-512.png +0 -0
  55. package/public/favicon.ico +0 -0
  56. package/public/favicon.png +0 -0
  57. package/public/favicon.svg +3 -0
  58. package/public/logo.png +0 -0
  59. package/public/manifest.json +48 -0
  60. package/src/App.tsx +2 -0
  61. package/src/components/ui/alert.tsx +62 -0
  62. package/src/components/ui/badge.tsx +39 -0
  63. package/src/components/ui/dialog.tsx +120 -0
  64. package/src/components/ui/label.tsx +27 -0
  65. package/src/components/ui/select.tsx +151 -0
  66. package/src/components/ui/switch.tsx +30 -0
  67. package/src/components/ui/table.tsx +120 -0
  68. package/src/components/ui/tabs.tsx +1 -1
  69. package/src/components/viewer/BCFPanel.tsx +1164 -0
  70. package/src/components/viewer/BulkPropertyEditor.tsx +875 -0
  71. package/src/components/viewer/DataConnector.tsx +840 -0
  72. package/src/components/viewer/DrawingSettingsPanel.tsx +536 -0
  73. package/src/components/viewer/EntityContextMenu.tsx +45 -17
  74. package/src/components/viewer/ExportChangesButton.tsx +195 -0
  75. package/src/components/viewer/ExportDialog.tsx +402 -0
  76. package/src/components/viewer/HierarchyPanel.tsx +1132 -218
  77. package/src/components/viewer/IDSPanel.tsx +661 -0
  78. package/src/components/viewer/KeyboardShortcutsDialog.tsx +245 -39
  79. package/src/components/viewer/MainToolbar.tsx +418 -94
  80. package/src/components/viewer/PropertiesPanel.tsx +1355 -91
  81. package/src/components/viewer/PropertyEditor.tsx +611 -0
  82. package/src/components/viewer/Section2DPanel.tsx +3313 -0
  83. package/src/components/viewer/SheetSetupPanel.tsx +502 -0
  84. package/src/components/viewer/StatusBar.tsx +27 -16
  85. package/src/components/viewer/TitleBlockEditor.tsx +437 -0
  86. package/src/components/viewer/ToolOverlays.tsx +935 -127
  87. package/src/components/viewer/ViewerLayout.tsx +40 -11
  88. package/src/components/viewer/Viewport.tsx +1276 -336
  89. package/src/components/viewer/ViewportContainer.tsx +554 -18
  90. package/src/components/viewer/ViewportOverlays.tsx +24 -7
  91. package/src/hooks/useBCF.ts +504 -0
  92. package/src/hooks/useIDS.ts +1065 -0
  93. package/src/hooks/useIfc.ts +1534 -205
  94. package/src/hooks/useIfcCache.ts +279 -0
  95. package/src/hooks/useKeyboardShortcuts.ts +50 -8
  96. package/src/hooks/useModelSelection.ts +61 -0
  97. package/src/hooks/useViewerSelectors.ts +218 -0
  98. package/src/hooks/useWebGPU.ts +80 -0
  99. package/src/index.css +265 -27
  100. package/src/lib/platform.ts +23 -0
  101. package/src/services/cacheService.ts +142 -0
  102. package/src/services/desktop-cache.ts +143 -0
  103. package/src/services/fs-cache.ts +212 -0
  104. package/src/services/ifc-cache.ts +14 -6
  105. package/src/store/constants.ts +85 -0
  106. package/src/store/index.ts +214 -0
  107. package/src/store/slices/bcfSlice.ts +372 -0
  108. package/src/store/slices/cameraSlice.ts +63 -0
  109. package/src/store/slices/dataSlice.test.ts +226 -0
  110. package/src/store/slices/dataSlice.ts +112 -0
  111. package/src/store/slices/drawing2DSlice.ts +340 -0
  112. package/src/store/slices/hoverSlice.ts +40 -0
  113. package/src/store/slices/idsSlice.ts +310 -0
  114. package/src/store/slices/loadingSlice.ts +33 -0
  115. package/src/store/slices/measurementSlice.test.ts +217 -0
  116. package/src/store/slices/measurementSlice.ts +293 -0
  117. package/src/store/slices/modelSlice.test.ts +271 -0
  118. package/src/store/slices/modelSlice.ts +211 -0
  119. package/src/store/slices/mutationSlice.ts +502 -0
  120. package/src/store/slices/sectionSlice.test.ts +125 -0
  121. package/src/store/slices/sectionSlice.ts +58 -0
  122. package/src/store/slices/selectionSlice.test.ts +286 -0
  123. package/src/store/slices/selectionSlice.ts +263 -0
  124. package/src/store/slices/sheetSlice.ts +565 -0
  125. package/src/store/slices/uiSlice.ts +58 -0
  126. package/src/store/slices/visibilitySlice.test.ts +304 -0
  127. package/src/store/slices/visibilitySlice.ts +277 -0
  128. package/src/store/types.test.ts +135 -0
  129. package/src/store/types.ts +248 -0
  130. package/src/store.ts +40 -515
  131. package/src/utils/ifcConfig.ts +82 -0
  132. package/src/utils/localParsingUtils.ts +287 -0
  133. package/src/utils/serverDataModel.ts +783 -0
  134. package/src/utils/spatialHierarchy.ts +283 -0
  135. package/src/utils/viewportUtils.ts +334 -0
  136. package/src/vite-env.d.ts +23 -0
  137. package/src/webgpu-types.d.ts +128 -0
  138. package/src-tauri/Cargo.toml +29 -0
  139. package/src-tauri/build.rs +7 -0
  140. package/src-tauri/capabilities/default.json +18 -0
  141. package/src-tauri/icons/128x128.png +0 -0
  142. package/src-tauri/icons/128x128@2x.png +0 -0
  143. package/src-tauri/icons/32x32.png +0 -0
  144. package/src-tauri/icons/Square107x107Logo.png +0 -0
  145. package/src-tauri/icons/Square142x142Logo.png +0 -0
  146. package/src-tauri/icons/Square150x150Logo.png +0 -0
  147. package/src-tauri/icons/Square284x284Logo.png +0 -0
  148. package/src-tauri/icons/Square30x30Logo.png +0 -0
  149. package/src-tauri/icons/Square310x310Logo.png +0 -0
  150. package/src-tauri/icons/Square44x44Logo.png +0 -0
  151. package/src-tauri/icons/Square71x71Logo.png +0 -0
  152. package/src-tauri/icons/Square89x89Logo.png +0 -0
  153. package/src-tauri/icons/StoreLogo.png +0 -0
  154. package/src-tauri/icons/icon.icns +0 -0
  155. package/src-tauri/icons/icon.ico +0 -0
  156. package/src-tauri/icons/icon.png +0 -0
  157. package/src-tauri/src/lib.rs +21 -0
  158. package/src-tauri/src/main.rs +10 -0
  159. package/src-tauri/tauri.conf.json +39 -0
  160. package/vite.config.ts +174 -26
  161. package/public/ifc-lite_bg.wasm +0 -0
  162. package/public/web-ifc.wasm +0 -0
  163. package/src/components/Viewport.tsx +0 -723
  164. package/src/components/viewer/BoxSelectionOverlay.tsx +0 -53
Binary file
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "IFClite Viewer",
3
+ "short_name": "IFClite",
4
+ "description": "High-performance web viewer for IFC files",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#1a1b26",
8
+ "theme_color": "#7aa2f7",
9
+ "icons": [
10
+ {
11
+ "src": "/favicon-16x16-cropped.png",
12
+ "sizes": "16x16",
13
+ "type": "image/png"
14
+ },
15
+ {
16
+ "src": "/favicon-32x32-cropped.png",
17
+ "sizes": "32x32",
18
+ "type": "image/png"
19
+ },
20
+ {
21
+ "src": "/favicon-48x48-cropped.png",
22
+ "sizes": "48x48",
23
+ "type": "image/png"
24
+ },
25
+ {
26
+ "src": "/favicon-96x96-cropped.png",
27
+ "sizes": "96x96",
28
+ "type": "image/png"
29
+ },
30
+ {
31
+ "src": "/favicon-192x192-cropped.png",
32
+ "sizes": "192x192",
33
+ "type": "image/png",
34
+ "purpose": "any maskable"
35
+ },
36
+ {
37
+ "src": "/favicon-512x512-cropped.png",
38
+ "sizes": "512x512",
39
+ "type": "image/png",
40
+ "purpose": "any maskable"
41
+ },
42
+ {
43
+ "src": "/apple-touch-icon.png",
44
+ "sizes": "180x180",
45
+ "type": "image/png"
46
+ }
47
+ ]
48
+ }
package/src/App.tsx CHANGED
@@ -11,3 +11,5 @@ import { ViewerLayout } from './components/viewer/ViewerLayout';
11
11
  export function App() {
12
12
  return <ViewerLayout />;
13
13
  }
14
+
15
+ export default App;
@@ -0,0 +1,62 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import { cva, type VariantProps } from 'class-variance-authority';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const alertVariants = cva(
10
+ 'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7',
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default: 'bg-background text-foreground',
15
+ destructive:
16
+ 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ variant: 'default',
21
+ },
22
+ }
23
+ );
24
+
25
+ const Alert = React.forwardRef<
26
+ HTMLDivElement,
27
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
28
+ >(({ className, variant, ...props }, ref) => (
29
+ <div
30
+ ref={ref}
31
+ role="alert"
32
+ className={cn(alertVariants({ variant }), className)}
33
+ {...props}
34
+ />
35
+ ));
36
+ Alert.displayName = 'Alert';
37
+
38
+ const AlertTitle = React.forwardRef<
39
+ HTMLParagraphElement,
40
+ React.HTMLAttributes<HTMLHeadingElement>
41
+ >(({ className, ...props }, ref) => (
42
+ <h5
43
+ ref={ref}
44
+ className={cn('mb-1 font-medium leading-none tracking-tight', className)}
45
+ {...props}
46
+ />
47
+ ));
48
+ AlertTitle.displayName = 'AlertTitle';
49
+
50
+ const AlertDescription = React.forwardRef<
51
+ HTMLParagraphElement,
52
+ React.HTMLAttributes<HTMLParagraphElement>
53
+ >(({ className, ...props }, ref) => (
54
+ <div
55
+ ref={ref}
56
+ className={cn('text-sm [&_p]:leading-relaxed', className)}
57
+ {...props}
58
+ />
59
+ ));
60
+ AlertDescription.displayName = 'AlertDescription';
61
+
62
+ export { Alert, AlertTitle, AlertDescription };
@@ -0,0 +1,39 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import { cva, type VariantProps } from 'class-variance-authority';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const badgeVariants = cva(
10
+ 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default:
15
+ 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
16
+ secondary:
17
+ 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
18
+ destructive:
19
+ 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',
20
+ outline: 'text-foreground',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: 'default',
25
+ },
26
+ }
27
+ );
28
+
29
+ export interface BadgeProps
30
+ extends React.HTMLAttributes<HTMLDivElement>,
31
+ VariantProps<typeof badgeVariants> {}
32
+
33
+ function Badge({ className, variant, ...props }: BadgeProps) {
34
+ return (
35
+ <div className={cn(badgeVariants({ variant }), className)} {...props} />
36
+ );
37
+ }
38
+
39
+ export { Badge, badgeVariants };
@@ -0,0 +1,120 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
7
+ import { X } from 'lucide-react';
8
+ import { cn } from '@/lib/utils';
9
+
10
+ const Dialog = DialogPrimitive.Root;
11
+ const DialogTrigger = DialogPrimitive.Trigger;
12
+ const DialogPortal = DialogPrimitive.Portal;
13
+ const DialogClose = DialogPrimitive.Close;
14
+
15
+ const DialogOverlay = React.forwardRef<
16
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => (
19
+ <DialogPrimitive.Overlay
20
+ ref={ref}
21
+ className={cn(
22
+ 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ ));
28
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
29
+
30
+ const DialogContent = React.forwardRef<
31
+ React.ElementRef<typeof DialogPrimitive.Content>,
32
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
33
+ >(({ className, children, ...props }, ref) => (
34
+ <DialogPortal>
35
+ <DialogOverlay />
36
+ <DialogPrimitive.Content
37
+ ref={ref}
38
+ className={cn(
39
+ 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
40
+ className
41
+ )}
42
+ {...props}
43
+ >
44
+ {children}
45
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
46
+ <X className="h-4 w-4" />
47
+ <span className="sr-only">Close</span>
48
+ </DialogPrimitive.Close>
49
+ </DialogPrimitive.Content>
50
+ </DialogPortal>
51
+ ));
52
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
53
+
54
+ const DialogHeader = ({
55
+ className,
56
+ ...props
57
+ }: React.HTMLAttributes<HTMLDivElement>) => (
58
+ <div
59
+ className={cn(
60
+ 'flex flex-col space-y-1.5 text-center sm:text-left',
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ );
66
+ DialogHeader.displayName = 'DialogHeader';
67
+
68
+ const DialogFooter = ({
69
+ className,
70
+ ...props
71
+ }: React.HTMLAttributes<HTMLDivElement>) => (
72
+ <div
73
+ className={cn(
74
+ 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
75
+ className
76
+ )}
77
+ {...props}
78
+ />
79
+ );
80
+ DialogFooter.displayName = 'DialogFooter';
81
+
82
+ const DialogTitle = React.forwardRef<
83
+ React.ElementRef<typeof DialogPrimitive.Title>,
84
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
85
+ >(({ className, ...props }, ref) => (
86
+ <DialogPrimitive.Title
87
+ ref={ref}
88
+ className={cn(
89
+ 'text-lg font-semibold leading-none tracking-tight',
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ ));
95
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
96
+
97
+ const DialogDescription = React.forwardRef<
98
+ React.ElementRef<typeof DialogPrimitive.Description>,
99
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
100
+ >(({ className, ...props }, ref) => (
101
+ <DialogPrimitive.Description
102
+ ref={ref}
103
+ className={cn('text-sm text-muted-foreground', className)}
104
+ {...props}
105
+ />
106
+ ));
107
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
108
+
109
+ export {
110
+ Dialog,
111
+ DialogPortal,
112
+ DialogOverlay,
113
+ DialogTrigger,
114
+ DialogClose,
115
+ DialogContent,
116
+ DialogHeader,
117
+ DialogFooter,
118
+ DialogTitle,
119
+ DialogDescription,
120
+ };
@@ -0,0 +1,27 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import * as LabelPrimitive from '@radix-ui/react-label';
7
+ import { cva, type VariantProps } from 'class-variance-authority';
8
+ import { cn } from '@/lib/utils';
9
+
10
+ const labelVariants = cva(
11
+ 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
12
+ );
13
+
14
+ const Label = React.forwardRef<
15
+ React.ElementRef<typeof LabelPrimitive.Root>,
16
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
17
+ VariantProps<typeof labelVariants>
18
+ >(({ className, ...props }, ref) => (
19
+ <LabelPrimitive.Root
20
+ ref={ref}
21
+ className={cn(labelVariants(), className)}
22
+ {...props}
23
+ />
24
+ ));
25
+ Label.displayName = LabelPrimitive.Root.displayName;
26
+
27
+ export { Label };
@@ -0,0 +1,151 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import * as SelectPrimitive from '@radix-ui/react-select';
7
+ import { Check, ChevronDown, ChevronUp } from 'lucide-react';
8
+ import { cn } from '@/lib/utils';
9
+
10
+ const Select = SelectPrimitive.Root;
11
+ const SelectGroup = SelectPrimitive.Group;
12
+ const SelectValue = SelectPrimitive.Value;
13
+
14
+ const SelectTrigger = React.forwardRef<
15
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
16
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
17
+ >(({ className, children, ...props }, ref) => (
18
+ <SelectPrimitive.Trigger
19
+ ref={ref}
20
+ className={cn(
21
+ 'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
22
+ className
23
+ )}
24
+ {...props}
25
+ >
26
+ {children}
27
+ <SelectPrimitive.Icon asChild>
28
+ <ChevronDown className="h-4 w-4 opacity-50" />
29
+ </SelectPrimitive.Icon>
30
+ </SelectPrimitive.Trigger>
31
+ ));
32
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
33
+
34
+ const SelectScrollUpButton = React.forwardRef<
35
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
36
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
37
+ >(({ className, ...props }, ref) => (
38
+ <SelectPrimitive.ScrollUpButton
39
+ ref={ref}
40
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
41
+ {...props}
42
+ >
43
+ <ChevronUp className="h-4 w-4" />
44
+ </SelectPrimitive.ScrollUpButton>
45
+ ));
46
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
47
+
48
+ const SelectScrollDownButton = React.forwardRef<
49
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
50
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
51
+ >(({ className, ...props }, ref) => (
52
+ <SelectPrimitive.ScrollDownButton
53
+ ref={ref}
54
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
55
+ {...props}
56
+ >
57
+ <ChevronDown className="h-4 w-4" />
58
+ </SelectPrimitive.ScrollDownButton>
59
+ ));
60
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
61
+
62
+ const SelectContent = React.forwardRef<
63
+ React.ElementRef<typeof SelectPrimitive.Content>,
64
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
65
+ >(({ className, children, position = 'popper', ...props }, ref) => (
66
+ <SelectPrimitive.Portal>
67
+ <SelectPrimitive.Content
68
+ ref={ref}
69
+ className={cn(
70
+ 'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
71
+ position === 'popper' &&
72
+ 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
73
+ className
74
+ )}
75
+ position={position}
76
+ {...props}
77
+ >
78
+ <SelectScrollUpButton />
79
+ <SelectPrimitive.Viewport
80
+ className={cn(
81
+ 'p-1',
82
+ position === 'popper' &&
83
+ 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'
84
+ )}
85
+ >
86
+ {children}
87
+ </SelectPrimitive.Viewport>
88
+ <SelectScrollDownButton />
89
+ </SelectPrimitive.Content>
90
+ </SelectPrimitive.Portal>
91
+ ));
92
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
93
+
94
+ const SelectLabel = React.forwardRef<
95
+ React.ElementRef<typeof SelectPrimitive.Label>,
96
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
97
+ >(({ className, ...props }, ref) => (
98
+ <SelectPrimitive.Label
99
+ ref={ref}
100
+ className={cn('px-2 py-1.5 text-sm font-semibold', className)}
101
+ {...props}
102
+ />
103
+ ));
104
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
105
+
106
+ const SelectItem = React.forwardRef<
107
+ React.ElementRef<typeof SelectPrimitive.Item>,
108
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
109
+ >(({ className, children, ...props }, ref) => (
110
+ <SelectPrimitive.Item
111
+ ref={ref}
112
+ className={cn(
113
+ 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
114
+ className
115
+ )}
116
+ {...props}
117
+ >
118
+ <span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
119
+ <SelectPrimitive.ItemIndicator>
120
+ <Check className="h-4 w-4" />
121
+ </SelectPrimitive.ItemIndicator>
122
+ </span>
123
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
124
+ </SelectPrimitive.Item>
125
+ ));
126
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
127
+
128
+ const SelectSeparator = React.forwardRef<
129
+ React.ElementRef<typeof SelectPrimitive.Separator>,
130
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
131
+ >(({ className, ...props }, ref) => (
132
+ <SelectPrimitive.Separator
133
+ ref={ref}
134
+ className={cn('-mx-1 my-1 h-px bg-muted', className)}
135
+ {...props}
136
+ />
137
+ ));
138
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
139
+
140
+ export {
141
+ Select,
142
+ SelectGroup,
143
+ SelectValue,
144
+ SelectTrigger,
145
+ SelectContent,
146
+ SelectLabel,
147
+ SelectItem,
148
+ SelectSeparator,
149
+ SelectScrollUpButton,
150
+ SelectScrollDownButton,
151
+ };
@@ -0,0 +1,30 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const Switch = React.forwardRef<
10
+ React.ElementRef<typeof SwitchPrimitives.Root>,
11
+ React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
12
+ >(({ className, ...props }, ref) => (
13
+ <SwitchPrimitives.Root
14
+ className={cn(
15
+ 'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
16
+ className
17
+ )}
18
+ {...props}
19
+ ref={ref}
20
+ >
21
+ <SwitchPrimitives.Thumb
22
+ className={cn(
23
+ 'pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0'
24
+ )}
25
+ />
26
+ </SwitchPrimitives.Root>
27
+ ));
28
+ Switch.displayName = SwitchPrimitives.Root.displayName;
29
+
30
+ export { Switch };
@@ -0,0 +1,120 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const Table = React.forwardRef<
6
+ HTMLTableElement,
7
+ React.HTMLAttributes<HTMLTableElement>
8
+ >(({ className, ...props }, ref) => (
9
+ <div className="relative w-full overflow-auto">
10
+ <table
11
+ ref={ref}
12
+ className={cn("w-full caption-bottom text-sm", className)}
13
+ {...props}
14
+ />
15
+ </div>
16
+ ))
17
+ Table.displayName = "Table"
18
+
19
+ const TableHeader = React.forwardRef<
20
+ HTMLTableSectionElement,
21
+ React.HTMLAttributes<HTMLTableSectionElement>
22
+ >(({ className, ...props }, ref) => (
23
+ <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
24
+ ))
25
+ TableHeader.displayName = "TableHeader"
26
+
27
+ const TableBody = React.forwardRef<
28
+ HTMLTableSectionElement,
29
+ React.HTMLAttributes<HTMLTableSectionElement>
30
+ >(({ className, ...props }, ref) => (
31
+ <tbody
32
+ ref={ref}
33
+ className={cn("[&_tr:last-child]:border-0", className)}
34
+ {...props}
35
+ />
36
+ ))
37
+ TableBody.displayName = "TableBody"
38
+
39
+ const TableFooter = React.forwardRef<
40
+ HTMLTableSectionElement,
41
+ React.HTMLAttributes<HTMLTableSectionElement>
42
+ >(({ className, ...props }, ref) => (
43
+ <tfoot
44
+ ref={ref}
45
+ className={cn(
46
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
47
+ className
48
+ )}
49
+ {...props}
50
+ />
51
+ ))
52
+ TableFooter.displayName = "TableFooter"
53
+
54
+ const TableRow = React.forwardRef<
55
+ HTMLTableRowElement,
56
+ React.HTMLAttributes<HTMLTableRowElement>
57
+ >(({ className, ...props }, ref) => (
58
+ <tr
59
+ ref={ref}
60
+ className={cn(
61
+ "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
62
+ className
63
+ )}
64
+ {...props}
65
+ />
66
+ ))
67
+ TableRow.displayName = "TableRow"
68
+
69
+ const TableHead = React.forwardRef<
70
+ HTMLTableCellElement,
71
+ React.ThHTMLAttributes<HTMLTableCellElement>
72
+ >(({ className, ...props }, ref) => (
73
+ <th
74
+ ref={ref}
75
+ className={cn(
76
+ "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ ))
82
+ TableHead.displayName = "TableHead"
83
+
84
+ const TableCell = React.forwardRef<
85
+ HTMLTableCellElement,
86
+ React.TdHTMLAttributes<HTMLTableCellElement>
87
+ >(({ className, ...props }, ref) => (
88
+ <td
89
+ ref={ref}
90
+ className={cn(
91
+ "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
92
+ className
93
+ )}
94
+ {...props}
95
+ />
96
+ ))
97
+ TableCell.displayName = "TableCell"
98
+
99
+ const TableCaption = React.forwardRef<
100
+ HTMLTableCaptionElement,
101
+ React.HTMLAttributes<HTMLTableCaptionElement>
102
+ >(({ className, ...props }, ref) => (
103
+ <caption
104
+ ref={ref}
105
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
106
+ {...props}
107
+ />
108
+ ))
109
+ TableCaption.displayName = "TableCaption"
110
+
111
+ export {
112
+ Table,
113
+ TableHeader,
114
+ TableBody,
115
+ TableFooter,
116
+ TableHead,
117
+ TableRow,
118
+ TableCell,
119
+ TableCaption,
120
+ }
@@ -30,7 +30,7 @@ const TabsTrigger = React.forwardRef<
30
30
  <TabsPrimitive.Trigger
31
31
  ref={ref}
32
32
  className={cn(
33
- 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
33
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
34
34
  className
35
35
  )}
36
36
  {...props}