@rebasepro/ui 0.17.3 → 0.18.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.
Files changed (127) hide show
  1. package/README.md +4 -0
  2. package/dist/components/MultiSelect.d.ts +10 -0
  3. package/dist/index.es.js +2 -1
  4. package/dist/index.es.js.map +1 -1
  5. package/package.json +32 -23
  6. package/src/components/Alert.tsx +0 -118
  7. package/src/components/Autocomplete.tsx +0 -93
  8. package/src/components/Avatar.tsx +0 -73
  9. package/src/components/Badge.tsx +0 -44
  10. package/src/components/BooleanSwitch.tsx +0 -116
  11. package/src/components/BooleanSwitchWithLabel.tsx +0 -120
  12. package/src/components/Button.tsx +0 -110
  13. package/src/components/Card.tsx +0 -43
  14. package/src/components/CenteredView.tsx +0 -35
  15. package/src/components/Checkbox.tsx +0 -129
  16. package/src/components/Chip.tsx +0 -131
  17. package/src/components/CircularProgress.tsx +0 -53
  18. package/src/components/CircularProgressCenter.tsx +0 -27
  19. package/src/components/Collapse.tsx +0 -66
  20. package/src/components/ColorPicker.tsx +0 -140
  21. package/src/components/Container.tsx +0 -51
  22. package/src/components/DateTimeField.tsx +0 -363
  23. package/src/components/DebouncedTextField.tsx +0 -76
  24. package/src/components/Dialog.tsx +0 -159
  25. package/src/components/DialogActions.tsx +0 -29
  26. package/src/components/DialogContent.tsx +0 -27
  27. package/src/components/DialogTitle.tsx +0 -41
  28. package/src/components/ErrorBoundary.tsx +0 -236
  29. package/src/components/ExpandablePanel.tsx +0 -130
  30. package/src/components/FileUpload.tsx +0 -103
  31. package/src/components/FilterChip.tsx +0 -89
  32. package/src/components/IconButton.tsx +0 -101
  33. package/src/components/InfoLabel.tsx +0 -23
  34. package/src/components/InputLabel.tsx +0 -40
  35. package/src/components/Label.tsx +0 -32
  36. package/src/components/LoadingButton.tsx +0 -32
  37. package/src/components/Markdown.tsx +0 -55
  38. package/src/components/Menu.tsx +0 -114
  39. package/src/components/Menubar.tsx +0 -355
  40. package/src/components/MultiSelect.tsx +0 -433
  41. package/src/components/Paper.tsx +0 -23
  42. package/src/components/Popover.tsx +0 -162
  43. package/src/components/RadioGroup.tsx +0 -74
  44. package/src/components/ResizablePanels.tsx +0 -189
  45. package/src/components/SearchBar.tsx +0 -136
  46. package/src/components/Select.tsx +0 -326
  47. package/src/components/Separator.tsx +0 -28
  48. package/src/components/Sheet.tsx +0 -135
  49. package/src/components/Skeleton.tsx +0 -54
  50. package/src/components/Slider.tsx +0 -110
  51. package/src/components/Table.tsx +0 -178
  52. package/src/components/Tabs.tsx +0 -185
  53. package/src/components/TextField.tsx +0 -270
  54. package/src/components/TextareaAutosize.tsx +0 -368
  55. package/src/components/ToggleButtonGroup.tsx +0 -69
  56. package/src/components/Tooltip.tsx +0 -153
  57. package/src/components/Typography.tsx +0 -132
  58. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +0 -90
  59. package/src/components/VirtualTable/VirtualTable.tsx +0 -700
  60. package/src/components/VirtualTable/VirtualTableCell.tsx +0 -59
  61. package/src/components/VirtualTable/VirtualTableHeader.tsx +0 -327
  62. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +0 -250
  63. package/src/components/VirtualTable/VirtualTableProps.tsx +0 -339
  64. package/src/components/VirtualTable/VirtualTableRow.tsx +0 -51
  65. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +0 -44
  66. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +0 -89
  67. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +0 -71
  68. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +0 -107
  69. package/src/components/VirtualTable/fields/VirtualTableSwitch.tsx +0 -28
  70. package/src/components/VirtualTable/index.tsx +0 -10
  71. package/src/components/VirtualTable/selection/SelectionContext.tsx +0 -36
  72. package/src/components/VirtualTable/selection/SelectionStore.ts +0 -54
  73. package/src/components/VirtualTable/types.tsx +0 -47
  74. package/src/components/common/SelectInputLabel.tsx +0 -23
  75. package/src/components/index.tsx +0 -62
  76. package/src/hooks/PortalContainerContext.tsx +0 -50
  77. package/src/hooks/index.ts +0 -7
  78. package/src/hooks/useDebounceCallback.tsx +0 -21
  79. package/src/hooks/useDebounceValue.tsx +0 -20
  80. package/src/hooks/useDebouncedCallback.ts +0 -39
  81. package/src/hooks/useInjectStyles.tsx +0 -31
  82. package/src/hooks/useOutsideAlerter.tsx +0 -46
  83. package/src/icons/GitHubIcon.tsx +0 -21
  84. package/src/icons/HandleIcon.tsx +0 -23
  85. package/src/icons/Icon.tsx +0 -33
  86. package/src/icons/LucideIconByName.tsx +0 -117
  87. package/src/icons/cool_icon_keys.ts +0 -12
  88. package/src/icons/icon_keys.ts +0 -1936
  89. package/src/icons/index.ts +0 -179
  90. package/src/index.css +0 -169
  91. package/src/index.ts +0 -47
  92. package/src/scripts/fixIconSizes.cjs +0 -92
  93. package/src/scripts/fixIconSizesToConst.cjs +0 -106
  94. package/src/scripts/generateIconKeys.ts +0 -41
  95. package/src/scripts/generateIcons.ts +0 -4
  96. package/src/scripts/saveIconFiles.ts +0 -89
  97. package/src/styles.ts +0 -141
  98. package/src/theme.css +0 -168
  99. package/src/util/chip_colors.ts +0 -242
  100. package/src/util/cls.ts +0 -8
  101. package/src/util/debounce.ts +0 -28
  102. package/src/util/hash.ts +0 -11
  103. package/src/util/index.ts +0 -4
  104. package/src/util/key_to_icon_component.ts +0 -11
  105. package/src/util/lazy_chunk.ts +0 -101
  106. package/src/views/CardView.tsx +0 -281
  107. package/src/views/CollectionView/CollectionCardView.tsx +0 -265
  108. package/src/views/CollectionView/CollectionKanbanView.tsx +0 -246
  109. package/src/views/CollectionView/CollectionListView.tsx +0 -240
  110. package/src/views/CollectionView/CollectionTableView.tsx +0 -229
  111. package/src/views/CollectionView/CollectionView.tsx +0 -450
  112. package/src/views/CollectionView/CollectionViewToolbar.tsx +0 -242
  113. package/src/views/CollectionView/CollectionViewTypes.ts +0 -181
  114. package/src/views/CollectionView/DefaultCellRenderer.tsx +0 -404
  115. package/src/views/CollectionView/index.ts +0 -39
  116. package/src/views/CollectionView/resolveTitleProperty.ts +0 -52
  117. package/src/views/CollectionView/utils.ts +0 -14
  118. package/src/views/Kanban/Board.tsx +0 -384
  119. package/src/views/Kanban/BoardColumn.tsx +0 -138
  120. package/src/views/Kanban/BoardColumnTitle.tsx +0 -47
  121. package/src/views/Kanban/BoardSortableList.tsx +0 -182
  122. package/src/views/Kanban/board_types.ts +0 -80
  123. package/src/views/Kanban/index.tsx +0 -5
  124. package/src/views/Kanban/placement.ts +0 -62
  125. package/src/views/KanbanView.tsx +0 -32
  126. package/src/views/ListView.tsx +0 -296
  127. package/src/views/index.ts +0 -5
@@ -1,28 +0,0 @@
1
- import React, { useEffect } from "react";
2
- import { BooleanSwitch } from "../../BooleanSwitch";
3
-
4
- export function VirtualTableSwitch(props: {
5
- error?: Error;
6
- internalValue?: boolean;
7
- focused: boolean;
8
- disabled: boolean;
9
- updateValue: (newValue: (boolean | null)) => void;
10
- }) {
11
- const { internalValue, updateValue, focused } = props;
12
- const ref = React.useRef<HTMLButtonElement>(null);
13
-
14
- useEffect(() => {
15
- if (ref.current && focused) {
16
- ref.current.focus({ preventScroll: true });
17
- }
18
- }, [focused, ref]);
19
-
20
- return (
21
- <BooleanSwitch
22
- ref={ref}
23
- size={"small"}
24
- value={Boolean(internalValue)}
25
- onValueChange={updateValue}
26
- />
27
- );
28
- }
@@ -1,10 +0,0 @@
1
- export { VirtualTable } from "./VirtualTable";
2
- export * from "./VirtualTableProps";
3
- export type { FilterFormFieldProps } from "./VirtualTableHeader";
4
- export * from "./selection/SelectionStore";
5
- export * from "./selection/SelectionContext";
6
- export * from "./fields/VirtualTableInput";
7
- export * from "./fields/VirtualTableNumberInput";
8
- export * from "./fields/VirtualTableSwitch";
9
- export * from "./fields/VirtualTableDateField";
10
- export * from "./fields/VirtualTableSelect";
@@ -1,36 +0,0 @@
1
- import React, { createContext, useContext } from "react";
2
- import { VirtualTableSelectionStore, SelectedCell } from "./SelectionStore";
3
-
4
- export interface VirtualTableSelectionContextProps<T extends SelectedCell = SelectedCell> {
5
- selectionStore: VirtualTableSelectionStore<T>;
6
- select: (cell: T | undefined) => void;
7
- }
8
-
9
- const SelectionContext = createContext<VirtualTableSelectionContextProps<any> | null>(null);
10
-
11
- export const VirtualTableSelectionProvider = <T extends SelectedCell = SelectedCell>({
12
- store,
13
- children
14
- }: {
15
- store: VirtualTableSelectionStore<T>;
16
- children: React.ReactNode;
17
- }) => {
18
- const value = React.useMemo(() => ({
19
- selectionStore: store,
20
- select: store.select
21
- }), [store]);
22
-
23
- return (
24
- <SelectionContext.Provider value={value}>
25
- {children}
26
- </SelectionContext.Provider>
27
- );
28
- };
29
-
30
- export const useVirtualTableSelection = <T extends SelectedCell = SelectedCell>() => {
31
- const context = useContext(SelectionContext);
32
- if (!context) {
33
- throw new Error("useVirtualTableSelection must be used within a VirtualTableSelectionProvider");
34
- }
35
- return context as VirtualTableSelectionContextProps<T>;
36
- };
@@ -1,54 +0,0 @@
1
- import { useSyncExternalStore, useCallback, useRef } from "react";
2
-
3
- export interface SelectedCell {
4
- columnKey: string;
5
- id: string | number;
6
- cellRect?: DOMRect;
7
- width?: number;
8
- height?: number;
9
- }
10
-
11
- export function createVirtualTableSelectionStore<T extends SelectedCell = SelectedCell>() {
12
- let selectedCell: T | undefined = undefined;
13
- const listeners = new Set<() => void>();
14
-
15
- function getEntity(): T | undefined {
16
- return selectedCell;
17
- }
18
-
19
- function subscribe(listener: () => void): () => void {
20
- listeners.add(listener);
21
- return () => listeners.delete(listener);
22
- }
23
-
24
- function select(cell: T | undefined) {
25
- selectedCell = cell;
26
- listeners.forEach(l => l());
27
- }
28
-
29
- return {
30
- getEntity,
31
- subscribe,
32
- select
33
- };
34
- }
35
-
36
- export type VirtualTableSelectionStore<T extends SelectedCell = SelectedCell> = ReturnType<typeof createVirtualTableSelectionStore<T>>;
37
-
38
- export function useVirtualTableCellSelected<T extends SelectedCell = SelectedCell>(
39
- store: VirtualTableSelectionStore<T>,
40
- columnKey: string,
41
- id: string | number
42
- ): boolean {
43
- const selectorRef = useRef({ columnKey, id });
44
- selectorRef.current = { columnKey, id };
45
-
46
- const getEntity = useCallback(() => {
47
- const cell = store.getEntity();
48
- if (!cell) return false;
49
- const s = selectorRef.current;
50
- return cell.columnKey === s.columnKey && cell.id === s.id;
51
- }, [store]);
52
-
53
- return useSyncExternalStore(store.subscribe, getEntity, getEntity);
54
- }
@@ -1,47 +0,0 @@
1
- import React from "react";
2
- import {
3
- CellRendererParams,
4
- OnRowClickParams,
5
- OnVirtualTableColumnResizeParams,
6
- VirtualTableColumn,
7
- VirtualTableFilterValues,
8
- VirtualTableWhereFilterOp
9
- } from "./VirtualTableProps";
10
- import { FilterFormFieldProps } from "./VirtualTableHeader";
11
-
12
- export type VirtualTableRowProps<T extends Record<string, unknown>> = {
13
- style: React.CSSProperties,
14
- rowHeight: number,
15
- rowData: T;
16
- rowIndex: number;
17
- onRowClick?: (props: OnRowClickParams<Record<string, unknown>>) => void;
18
- children: React.ReactNode[];
19
- columns: VirtualTableColumn[];
20
- hoverRow?: boolean;
21
- rowClassName?: (rowData: T) => string | undefined;
22
- };
23
-
24
- export type VirtualTableContextProps<T> = {
25
- data?: T[];
26
- rowHeight?: number,
27
- headerHeight?: number,
28
- columns: VirtualTableColumn[];
29
- cellRenderer: React.ComponentType<CellRendererParams<T>>;
30
- /** Each sorted column's direction and its rank in the sort, keyed by column. */
31
- sortIndex: Map<string, { direction: "asc" | "desc"; position: number }>;
32
- filter?: VirtualTableFilterValues<string>;
33
- onRowClick?: (props: OnRowClickParams<Record<string, unknown>>) => void;
34
- onColumnSort: (key: string, additive?: boolean) => void;
35
- onColumnResize: (params: OnVirtualTableColumnResizeParams) => void;
36
- onColumnResizeEnd: (params: OnVirtualTableColumnResizeParams) => void;
37
- onFilterUpdate: (column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, unknown]) => void;
38
- customView?: React.ReactNode,
39
- hoverRow: boolean;
40
- createFilterField?: (props: FilterFormFieldProps<unknown>) => React.ReactNode;
41
- rowClassName?: (rowData: T) => string | undefined;
42
- endAdornment?: React.ReactNode;
43
- AddColumnComponent?: React.ComponentType;
44
- onColumnsOrderChange?: (columns: VirtualTableColumn[]) => void;
45
- draggingColumnId?: string | null;
46
- extraData?: unknown;
47
- };
@@ -1,23 +0,0 @@
1
- import React from "react";
2
- import { cls } from "../../util";
3
-
4
- /**
5
- * The label above a Select or MultiSelect.
6
- *
7
- * It used `text-surface-accent-500` — a SURFACE scale, borrowed for type. The
8
- * label above a TextField has always used `text-text-secondary`, and the two are
9
- * the same role, so a form mixing the components showed two different label
10
- * colours: `#64748b` blue-grey over a Select, `#757575` neutral over a TextField.
11
- * Measured side by side on /debug/ui, which is where it is most obvious, because
12
- * the reference puts them in adjacent columns.
13
- *
14
- * The text tokens are also the tuned ones: `--color-surface-500` was moved to
15
- * #797979 precisely so muted type clears AA on both grounds. The slate scale
16
- * carries no such guarantee — it is for surfaces.
17
- */
18
- export function SelectInputLabel({ children, error }: { children: React.ReactNode, error?: boolean }) {
19
- return <div className={cls("text-sm font-medium ml-3.5 mb-1",
20
- error ? "text-red-600 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark")}>
21
- {children}
22
- </div>;
23
- }
@@ -1,62 +0,0 @@
1
- // ./common/SelectInputLabel is internal — Select and MultiSelect render it for
2
- // a string `label`. Pass a ReactNode `label` to override it.
3
- export * from "./Autocomplete";
4
- export * from "./Alert";
5
- export * from "./Avatar";
6
- export * from "./BooleanSwitch";
7
- export * from "./BooleanSwitchWithLabel";
8
- export * from "./Button";
9
- export * from "./Card";
10
- export * from "./CenteredView";
11
- export * from "./Container";
12
- export * from "./Collapse";
13
- export * from "./CircularProgress";
14
- export * from "./CircularProgressCenter";
15
- export * from "./ErrorBoundary";
16
- export * from "./Checkbox";
17
- export * from "./Chip";
18
- export * from "./ColorPicker";
19
- export * from "./DateTimeField";
20
- export * from "./Dialog";
21
- export * from "./DialogActions";
22
- export * from "./DialogContent";
23
- export * from "./DialogTitle";
24
- export * from "./ExpandablePanel";
25
- export * from "./FileUpload";
26
- export * from "./FilterChip";
27
- export * from "./IconButton";
28
- export * from "./InputLabel";
29
- export * from "./InfoLabel";
30
- export * from "./Label";
31
- export * from "./LoadingButton";
32
- export * from "./Markdown";
33
- export * from "./Menu";
34
- export * from "./Menubar";
35
- export * from "./MultiSelect";
36
- export * from "./Paper";
37
- export * from "./RadioGroup";
38
- export * from "./ResizablePanels";
39
- export * from "./SearchBar";
40
- export * from "./Select";
41
- export * from "./Separator";
42
- export * from "./Slider";
43
- export * from "./Sheet";
44
- export * from "./TextareaAutosize";
45
- export * from "./TextField";
46
- export * from "./Tooltip";
47
- export * from "./Typography";
48
- export * from "./Tabs";
49
- export * from "./Table";
50
- export * from "./Popover";
51
- export * from "./Badge";
52
- export * from "./DebouncedTextField";
53
- export * from "./Skeleton";
54
- export * from "./ToggleButtonGroup";
55
- export * from "./VirtualTable";
56
-
57
- // Re-exported Radix primitives — consume these from @rebasepro/ui instead of
58
- // adding direct @radix-ui/* deps to every sub-package.
59
- import * as Portal from "@radix-ui/react-portal";
60
- import * as PopoverPrimitive from "@radix-ui/react-popover";
61
- export { Portal, PopoverPrimitive };
62
- export { Slot } from "@radix-ui/react-slot";
@@ -1,50 +0,0 @@
1
- "use client";
2
- import React, { createContext, useContext, useMemo } from "react";
3
-
4
- export interface PortalContainerContextType {
5
- container: HTMLElement | null;
6
- }
7
-
8
- const PortalContainerContext = createContext<PortalContainerContextType | undefined>(undefined);
9
-
10
- export interface PortalContainerProviderProps {
11
- container: HTMLElement | null;
12
- children: React.ReactNode;
13
- }
14
-
15
- /**
16
- * Provider component that sets the portal container for all descendants.
17
- * This can be used at any level of the tree to specify where portals should be attached.
18
- *
19
- * @example
20
- * ```tsx
21
- * const containerRef = useRef<HTMLDivElement>(null);
22
- *
23
- * <div ref={containerRef}>
24
- * <PortalContainerProvider container={containerRef.current}>
25
- * <YourComponents />
26
- * </PortalContainerProvider>
27
- * </div>
28
- * ```
29
- */
30
- export function PortalContainerProvider({ container, children }: PortalContainerProviderProps) {
31
- const contextValue = useMemo(() => ({ container }), [container]);
32
-
33
- return (
34
- <PortalContainerContext.Provider value={contextValue}>
35
- {children}
36
- </PortalContainerContext.Provider>
37
- );
38
- }
39
-
40
- /**
41
- * Hook to access the portal container from context.
42
- * Returns null if no provider is found in the tree.
43
- *
44
- * @returns The portal container element or null
45
- */
46
- export function usePortalContainer(): HTMLElement | null {
47
- const context = useContext(PortalContainerContext);
48
- return context?.container ?? null;
49
- }
50
-
@@ -1,7 +0,0 @@
1
- export * from "./useInjectStyles";
2
- export * from "./useOutsideAlerter";
3
- export * from "./useDebouncedCallback";
4
- export * from "./useDebounceCallback";
5
- export * from "./useDebounceValue";
6
-
7
- export * from "./PortalContainerContext";
@@ -1,21 +0,0 @@
1
- import { useCallback, useRef } from "react";
2
-
3
-
4
- export function useDebounceCallback<T extends (...args: any[]) => unknown>(
5
- callback?: T,
6
- delay?: number
7
- ): T {
8
- const timeoutRef = useRef<number | null>(null);
9
-
10
- const debouncedCallback = useCallback((...args: Parameters<T>) => {
11
- if (timeoutRef.current !== null) {
12
- clearTimeout(timeoutRef.current);
13
- }
14
-
15
- timeoutRef.current = window.setTimeout(() => {
16
- callback?.(...args);
17
- }, delay ?? 200);
18
- }, [callback, delay]);
19
-
20
- return debouncedCallback as T;
21
- }
@@ -1,20 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect, useState } from "react";
4
-
5
- export function useDebounceValue<T>(value: T, delay = 300): T {
6
- // State and setters for debounced value
7
- const [debouncedValue, setDebouncedValue] = useState(value);
8
- useEffect(
9
- () => {
10
- const handler = setTimeout(() => {
11
- setDebouncedValue(value);
12
- }, delay);
13
- return () => {
14
- clearTimeout(handler);
15
- };
16
- },
17
- [value, delay] // Only re-call effect if value or delay changes
18
- );
19
- return debouncedValue;
20
- }
@@ -1,39 +0,0 @@
1
- import React from "react";
2
-
3
- export function useDebouncedCallback<T>(value: T, callback: () => void, immediate: boolean, timeoutMs = 300) {
4
-
5
- const pendingUpdate = React.useRef(false);
6
-
7
- const callbackRef = React.useRef(callback);
8
- React.useEffect(() => {
9
- callbackRef.current = callback;
10
- }, [callback]);
11
-
12
- const performUpdate = React.useCallback(() => {
13
- callbackRef.current();
14
- pendingUpdate.current = false;
15
- }, []);
16
-
17
- const handlerRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
18
-
19
- React.useEffect(
20
- () => {
21
- if (immediate) {
22
- clearTimeout(handlerRef.current);
23
- if (pendingUpdate.current) {
24
- performUpdate();
25
- }
26
- return;
27
- }
28
-
29
- pendingUpdate.current = true;
30
- clearTimeout(handlerRef.current);
31
- handlerRef.current = setTimeout(performUpdate, timeoutMs);
32
- return () => {
33
- if (immediate)
34
- performUpdate();
35
- };
36
- },
37
- [immediate, value, performUpdate, timeoutMs]
38
- );
39
- }
@@ -1,31 +0,0 @@
1
- "use client";
2
- import { useEffect } from "react";
3
- import { usePortalContainer } from "./PortalContainerContext";
4
-
5
- /**
6
- * Use this hook to create a `<style>` element and inject it into the DOM.
7
- * It checks if the style already exists, and if it does, it does not inject it again.
8
- * @param key
9
- * @param styles
10
- */
11
- export function useInjectStyles(key: string, styles: string) {
12
-
13
- const portalContainer = usePortalContainer();
14
-
15
- useEffect(() => {
16
- if (typeof document === "undefined") return;
17
-
18
- const targetContainer: HTMLElement | null = portalContainer ?? document.head;
19
-
20
- // Try to find an existing style element within the target container first
21
- const existingStyle = (targetContainer as HTMLElement).querySelector?.(`#${key}`) as HTMLStyleElement | null;
22
-
23
- if (!existingStyle) {
24
- const style = document.createElement("style");
25
- style.id = key;
26
- style.innerHTML = styles;
27
- (targetContainer || document.head).appendChild(style);
28
- }
29
- }, []);
30
-
31
- }
@@ -1,46 +0,0 @@
1
- "use client";
2
-
3
- import { RefObject, useEffect } from "react";
4
-
5
- /**
6
- * Hook that alerts clicks outside the passed ref
7
- */
8
- export function useOutsideAlerter(ref: RefObject<HTMLElement | null>, onOutsideClick: () => void, active = true): void {
9
- useEffect(() => {
10
- if (!active)
11
- return;
12
-
13
- /**
14
- * Alert if clicked on outside of element
15
- */
16
- function handleClickOutside(event: Event) {
17
- if (isInPresentationLayer(event.target as Node)) {
18
- return;
19
- }
20
-
21
- if (ref.current && !ref.current.contains(event.target as Node)) {
22
- onOutsideClick();
23
- }
24
- }
25
-
26
- // Bind the event listener
27
- document.addEventListener("mousedown", handleClickOutside);
28
- return () => {
29
- // Unbind the event listener on clean up
30
- document.removeEventListener("mousedown", handleClickOutside);
31
- };
32
- }, [ref, active, onOutsideClick]);
33
- }
34
-
35
- /**
36
- * Check if any parent of the node is a presentation node
37
- * @param node
38
- */
39
- function isInPresentationLayer(node: Node | null): boolean {
40
- if (node instanceof HTMLElement) {
41
- if (node.getAttribute("role") === "presentation")
42
- return true;
43
- return isInPresentationLayer(node.parentNode);
44
- }
45
- return false;
46
- }
@@ -1,21 +0,0 @@
1
- import React from "react";
2
-
3
- import { colorClassesMapping, IconProps, iconSize } from "./Icon";
4
- import { cls } from "../util";
5
-
6
- export function GitHubIcon({ size = 24, color, className, onClick, style }: IconProps) {
7
- // `size` is `IconSize | number` — resolve the keyword, or an SVG attribute
8
- // of width="small" is emitted and the icon renders at its intrinsic size.
9
- const px = typeof size === "number" ? size : iconSize[size];
10
- return <svg xmlns="http://www.w3.org/2000/svg"
11
- className={cls(color ? colorClassesMapping[color] : "", className)}
12
- onClick={onClick}
13
- style={style}
14
- fill={"currentColor"}
15
- width={px}
16
- height={px}
17
- viewBox="0 0 24 24">
18
- <path
19
- d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
20
- </svg>;
21
- }
@@ -1,23 +0,0 @@
1
- import React from "react";
2
-
3
- import { colorClassesMapping, IconProps, iconSize } from "./Icon";
4
- import { cls } from "../util";
5
-
6
- export function HandleIcon({ size = 24, color, className, onClick, style }: IconProps) {
7
- const px = typeof size === "number" ? size : iconSize[size];
8
- return <svg xmlns="http://www.w3.org/2000/svg"
9
- className={cls(color ? colorClassesMapping[color] : "", className)}
10
- onClick={onClick}
11
- style={style}
12
- width={px}
13
- height={px}
14
- viewBox="0 0 100 100"
15
- fill="none">
16
- <circle cx="28" cy="50" r="9" fill={"currentColor"}/>
17
- <circle cx="28" cy="21" r="9" fill={"currentColor"}/>
18
- <circle cx="71" cy="21" r="9" fill={"currentColor"}/>
19
- <circle cx="71" cy="50" r="9" fill={"currentColor"}/>
20
- <circle cx="71" cy="78" r="9" fill={"currentColor"}/>
21
- <circle cx="28" cy="78" r="9" fill={"currentColor"}/>
22
- </svg>;
23
- }
@@ -1,33 +0,0 @@
1
- "use client";
2
-
3
- export type IconColor = "inherit" | "primary" | "secondary" | "disabled" | "error" | "success" | "warning";
4
- export type IconSize = "smallest" | "small" | "medium" | "large";
5
-
6
- /**
7
- * Standardized icon size map in px.
8
- * Use with direct Lucide imports: `<Database size={iconSize.small} />`
9
- */
10
- export const iconSize = {
11
- smallest: 16,
12
- small: 20,
13
- medium: 24,
14
- large: 28
15
- } as const satisfies Record<IconSize, number>;
16
-
17
- export type IconProps = {
18
- size?: IconSize | number,
19
- color?: IconColor,
20
- className?: string,
21
- onClick?: (e: React.SyntheticEvent) => void,
22
- style?: React.CSSProperties,
23
- }
24
-
25
- export const colorClassesMapping: Record<IconColor, string> = {
26
- inherit: "",
27
- primary: "text-primary",
28
- success: "text-green-500",
29
- warning: "text-yellow-500",
30
- secondary: "text-secondary",
31
- disabled: "text-text-disabled dark:text-text-disabled-dark",
32
- error: "text-red-500"
33
- }