@flikk/ui 1.0.0-beta.25 → 1.0.0-beta.27
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/ai/CodeBlock/CodeBlock.theme.js +2 -2
- package/dist/components/ai/PromptInput/PromptInput.js +4 -0
- package/dist/components/ai/PromptInput/VoiceRecorder.js +4 -0
- package/dist/components/ai/StreamingResponse/MarkdownRenderer.js +1 -1
- package/dist/components/ai/TokenCounter/TokenCounter.theme.js +1 -1
- package/dist/components/charts/BarChart/BarChart.js +2 -2
- package/dist/components/charts/StackedBarChart/StackedBarChart.js +1 -1
- package/dist/components/charts/shared/BarRenderer/BarRenderer.js +2 -2
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +1 -1
- package/dist/components/core/Button/Button.js +1 -1
- package/dist/components/core/Button/Button.theme.js +5 -5
- package/dist/components/core/Calendar/Calendar.theme.js +1 -1
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.theme.js +1 -1
- package/dist/components/core/CommandPalette/CommandItem.js +4 -5
- package/dist/components/core/CommandPalette/CommandPalette.js +1 -1
- package/dist/components/core/CommandPalette/CommandPalette.theme.js +11 -13
- package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +0 -2
- package/dist/components/core/ContextMenu/ContextMenu.theme.js +13 -14
- package/dist/components/core/DotSeparator/DotSeparator.d.ts +3 -0
- package/dist/components/core/DotSeparator/DotSeparator.js +19 -0
- package/dist/components/core/DotSeparator/DotSeparator.theme.d.ts +2 -0
- package/dist/components/core/DotSeparator/DotSeparator.theme.js +10 -0
- package/dist/components/core/DotSeparator/DotSeparator.types.d.ts +25 -0
- package/dist/components/core/DotSeparator/index.d.ts +3 -0
- package/dist/components/core/Drawer/Drawer.theme.js +2 -2
- package/dist/components/core/Dropdown/Dropdown.theme.js +4 -5
- package/dist/components/core/Dropdown/DropdownItem.js +1 -1
- package/dist/components/core/Dropdown/DropdownMenu.js +1 -1
- package/dist/components/core/Empty/Empty.js +1 -1
- package/dist/components/core/ImagePlaceholder/ImagePlaceholder.d.ts +14 -0
- package/dist/components/core/ImagePlaceholder/ImagePlaceholder.js +28 -0
- package/dist/components/core/ImagePlaceholder/ImagePlaceholder.theme.d.ts +6 -0
- package/dist/components/core/ImagePlaceholder/ImagePlaceholder.theme.js +8 -0
- package/dist/components/core/ImagePlaceholder/ImagePlaceholder.types.d.ts +32 -0
- package/dist/components/core/ImagePlaceholder/index.d.ts +2 -0
- package/dist/components/core/MenuItem/MenuItem.js +5 -2
- package/dist/components/core/MenuItem/MenuItem.theme.d.ts +6 -0
- package/dist/components/core/MenuItem/MenuItem.theme.js +19 -16
- package/dist/components/core/MenuItem/MenuItem.types.d.ts +2 -0
- package/dist/components/core/Message/Message.theme.js +1 -1
- package/dist/components/core/Modal/Modal.theme.js +1 -1
- package/dist/components/core/NavItem/NavItem.d.ts +1 -1
- package/dist/components/core/NavItem/NavItem.js +187 -68
- package/dist/components/core/NavItem/NavItem.theme.js +31 -12
- package/dist/components/core/NavItem/NavItem.types.d.ts +17 -39
- package/dist/components/core/Pagination/Pagination.theme.js +3 -3
- package/dist/components/core/Popover/Popover.theme.js +1 -1
- package/dist/components/core/Popover/Popover.types.d.ts +6 -2
- package/dist/components/core/Popover/PopoverBody.js +10 -3
- package/dist/components/core/Progress/Progress.theme.js +1 -1
- package/dist/components/core/ScrollArea/ScrollArea.js +2 -2
- package/dist/components/core/ScrollArea/ScrollArea.theme.js +1 -1
- package/dist/components/core/Segmented/Segmented.js +8 -6
- package/dist/components/core/Segmented/Segmented.theme.js +3 -3
- package/dist/components/core/Sidebar/Sidebar.d.ts +3 -1
- package/dist/components/core/Sidebar/Sidebar.js +53 -16
- package/dist/components/core/Sidebar/Sidebar.theme.js +5 -7
- package/dist/components/core/Sidebar/Sidebar.types.d.ts +125 -8
- package/dist/components/core/Sidebar/SidebarCard.d.ts +25 -0
- package/dist/components/core/Sidebar/SidebarCard.js +68 -0
- package/dist/components/core/Sidebar/SidebarCard.theme.d.ts +8 -0
- package/dist/components/core/Sidebar/SidebarCard.theme.js +18 -0
- package/dist/components/core/Sidebar/SidebarContent.js +10 -6
- package/dist/components/core/Sidebar/SidebarContext.d.ts +17 -16
- package/dist/components/core/Sidebar/SidebarContext.js +43 -20
- package/dist/components/core/Sidebar/SidebarFooter.js +4 -6
- package/dist/components/core/Sidebar/SidebarHeader.js +12 -9
- package/dist/components/core/Sidebar/SidebarLogo.js +39 -8
- package/dist/components/core/Sidebar/SidebarNav.js +4 -3
- package/dist/components/core/Sidebar/SidebarNavGroup.js +4 -7
- package/dist/components/core/Sidebar/SidebarSearch.d.ts +22 -0
- package/dist/components/core/Sidebar/SidebarSearch.js +135 -0
- package/dist/components/core/Sidebar/SidebarToggle.js +6 -1
- package/dist/components/core/Sidebar/SidebarUserProfile.js +33 -17
- package/dist/components/core/Sidebar/index.d.ts +4 -3
- package/dist/components/core/Skeleton/Skeleton.theme.js +1 -1
- package/dist/components/core/Spinner/Spinner.theme.js +1 -1
- package/dist/components/core/Tabs/Tabs.js +6 -1
- package/dist/components/core/Tabs/Tabs.types.d.ts +2 -0
- package/dist/components/core/Tabs/TabsBody.js +5 -3
- package/dist/components/core/Tag/Tag.js +29 -5
- package/dist/components/core/Tag/Tag.theme.js +14 -9
- package/dist/components/core/Tag/Tag.types.d.ts +7 -0
- package/dist/components/core/Tooltip/Tooltip.js +1 -1
- package/dist/components/core/Tooltip/Tooltip.theme.js +1 -2
- package/dist/components/core/index.d.ts +2 -0
- package/dist/components/core/index.js +6 -2
- package/dist/components/data-display/GanttChart/GanttChart.d.ts +1 -1
- package/dist/components/data-display/GanttChart/GanttChart.js +31 -4
- package/dist/components/data-display/GanttChart/GanttChart.theme.js +19 -17
- package/dist/components/data-display/GanttChart/GanttChart.types.d.ts +19 -0
- package/dist/components/data-display/GanttChart/GanttChart.utils.js +1 -1
- package/dist/components/data-display/GanttChart/GanttChartPanel.d.ts +1 -1
- package/dist/components/data-display/GanttChart/GanttChartPanel.js +3 -3
- package/dist/components/data-display/GanttChart/GanttDependencyArrows.js +7 -4
- package/dist/components/data-display/GanttChart/GanttMilestone.js +5 -5
- package/dist/components/data-display/GanttChart/GanttTableGroupRow.js +1 -1
- package/dist/components/data-display/GanttChart/GanttTablePanel.js +1 -1
- package/dist/components/data-display/GanttChart/GanttTableTaskRow.js +2 -2
- package/dist/components/data-display/GanttChart/GanttTaskBar.js +37 -16
- package/dist/components/data-display/GanttChart/GanttTimelineGrid.js +2 -1
- package/dist/components/data-display/GanttChart/GanttTimelineHeader.js +35 -11
- package/dist/components/data-display/GanttChart/GanttToolbar.js +2 -2
- package/dist/components/data-display/GanttChart/hooks/useGanttDrag.js +3 -2
- package/dist/components/data-display/GanttChart/index.d.ts +1 -1
- package/dist/components/data-display/KPI/KPI.js +13 -3
- package/dist/components/data-display/KPI/KPI.theme.js +3 -3
- package/dist/components/data-display/Metric/Metric.theme.js +3 -3
- package/dist/components/data-display/Table/Table.js +4 -3
- package/dist/components/data-display/Table/Table.theme.js +14 -6
- package/dist/components/data-display/Table/Table.types.d.ts +15 -0
- package/dist/components/data-display/Table/TableColumnManager.js +1 -1
- package/dist/components/data-display/Table/index.d.ts +2 -2
- package/dist/components/effects/Aurora/Aurora.d.ts +6 -17
- package/dist/components/effects/Aurora/Aurora.js +310 -105
- package/dist/components/effects/Aurora/Aurora.types.d.ts +6 -0
- package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.js +3 -3
- package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.js +13 -4
- package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.js +13 -4
- package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.js +14 -4
- package/dist/components/effects/MorphingText/MorphingText.js +40 -7
- package/dist/components/effects/StripePattern/StripePattern.d.ts +18 -0
- package/dist/components/effects/StripePattern/StripePattern.js +54 -0
- package/dist/components/effects/StripePattern/StripePattern.types.d.ts +53 -0
- package/dist/components/effects/StripePattern/index.d.ts +2 -0
- package/dist/components/effects/index.d.ts +2 -0
- package/dist/components/effects/index.js +1 -0
- package/dist/components/forms/Checkbox/Checkbox.theme.js +1 -1
- package/dist/components/forms/Combobox/Combobox.js +1 -1
- package/dist/components/forms/Combobox/Combobox.theme.js +2 -4
- package/dist/components/forms/CronInput/CronInput.js +1 -1
- package/dist/components/forms/CronInput/CronInput.theme.js +22 -31
- package/dist/components/forms/DatePicker/DatePicker.theme.js +11 -18
- package/dist/components/forms/DatePicker/DatePickerTrigger.js +1 -1
- package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +7 -14
- package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +1 -1
- package/dist/components/forms/FileUpload/FileUpload.animations.d.ts +29 -0
- package/dist/components/forms/FileUpload/FileUpload.animations.js +19 -0
- package/dist/components/forms/FileUpload/FileUpload.js +88 -49
- package/dist/components/forms/FileUpload/FileUpload.theme.d.ts +2 -10
- package/dist/components/forms/FileUpload/FileUpload.theme.js +16 -30
- package/dist/components/forms/FileUpload/FileUpload.types.d.ts +26 -10
- package/dist/components/forms/FileUpload/FileUploadProgress.js +27 -20
- package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +2 -2
- package/dist/components/forms/Input/Input.theme.js +16 -15
- package/dist/components/forms/InputCounter/InputCounter.theme.js +1 -1
- package/dist/components/forms/Mention/Mention.js +152 -57
- package/dist/components/forms/Mention/Mention.theme.js +16 -23
- package/dist/components/forms/Mention/Mention.types.d.ts +12 -12
- package/dist/components/forms/Mention/Mention.utils.js +32 -4
- package/dist/components/forms/Radio/Radio.theme.js +1 -1
- package/dist/components/forms/RichTextEditor/RichTextEditor.d.ts +18 -0
- package/dist/components/forms/RichTextEditor/RichTextEditor.js +1231 -236
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.d.ts +53 -1
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +99 -25
- package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +42 -3
- package/dist/components/forms/RichTextEditor/index.d.ts +2 -2
- package/dist/components/forms/Select/Select.js +2 -2
- package/dist/components/forms/Select/Select.theme.js +3 -3
- package/dist/components/forms/Slider/Slider.theme.js +1 -1
- package/dist/components/forms/Switch/Switch.theme.js +1 -1
- package/dist/components/forms/TimePicker/TimePicker.theme.js +2 -2
- package/dist/components/forms/TimePicker/TimePickerContent.js +4 -0
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +1 -1
- package/dist/components/forms/forms.theme.js +24 -19
- package/dist/components/forms/index.js +4 -0
- package/dist/components/layout/AppShell/AppShell.d.ts +10 -0
- package/dist/components/layout/AppShell/AppShell.js +84 -0
- package/dist/components/layout/AppShell/AppShell.theme.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShell.theme.js +42 -0
- package/dist/components/layout/AppShell/AppShell.types.d.ts +127 -0
- package/dist/components/layout/AppShell/AppShellContext.d.ts +14 -0
- package/dist/components/layout/AppShell/AppShellContext.js +19 -0
- package/dist/components/layout/AppShell/AppShellFooter.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShellFooter.js +12 -0
- package/dist/components/layout/AppShell/AppShellHeader.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShellHeader.js +12 -0
- package/dist/components/layout/AppShell/AppShellMain.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShellMain.js +19 -0
- package/dist/components/layout/AppShell/AppShellRightPanel.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShellRightPanel.js +16 -0
- package/dist/components/layout/AppShell/AppShellSidebar.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShellSidebar.js +16 -0
- package/dist/components/layout/AppShell/AppShellTopbar.d.ts +3 -0
- package/dist/components/layout/AppShell/AppShellTopbar.js +12 -0
- package/dist/components/layout/AppShell/index.d.ts +3 -0
- package/dist/components/layout/FormLayout/FormLayout.js +9 -4
- package/dist/components/layout/FormLayout/FormLayout.types.d.ts +3 -3
- package/dist/components/layout/FormLayout/FormLayoutSection.js +6 -1
- package/dist/components/layout/PageLayout/PageLayout.d.ts +2 -2
- package/dist/components/layout/PageLayout/PageLayout.js +23 -5
- package/dist/components/layout/PageLayout/PageLayout.theme.d.ts +2 -1
- package/dist/components/layout/PageLayout/PageLayout.theme.js +35 -6
- package/dist/components/layout/PageLayout/PageLayout.types.d.ts +45 -0
- package/dist/components/layout/PageLayout/PageLayoutContent.js +6 -4
- package/dist/components/layout/PageLayout/PageLayoutHeader.js +3 -3
- package/dist/components/layout/PageLayout/PageLayoutSidebar.js +5 -3
- package/dist/components/layout/PageLayout/index.d.ts +1 -1
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/hooks/useSelectPortal.d.ts +10 -2
- package/dist/hooks/useSelectPortal.js +45 -24
- package/dist/index.js +8 -2
- package/dist/registry.json +10021 -0
- package/dist/styles.css +1 -1
- package/dist/utils/dateUtils.js +11 -1
- package/package.json +4 -2
- package/src/global.scss +29 -8
- package/src/styles/theme.css +174 -100
- package/dist/components/core/Sidebar/SidebarSubmenu.d.ts +0 -7
- package/dist/components/core/Sidebar/SidebarSubmenu.js +0 -12
|
@@ -1,8 +1,60 @@
|
|
|
1
1
|
import { RichTextEditorTheme, ColorOption } from "./RichTextEditor.types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Legacy 10-entry color list — kept for backwards compat with consumers that
|
|
4
|
+
* import `colorOptions` directly. The RichTextEditor's color picker now uses
|
|
5
|
+
* the full Tailwind spectrum below.
|
|
4
6
|
*/
|
|
5
7
|
export declare const colorOptions: ColorOption[];
|
|
8
|
+
/**
|
|
9
|
+
* Tailwind shade scale (same for every family). Used by both the picker
|
|
10
|
+
* UI and the `getTailwindShadeTokens` utility below.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TAILWIND_SHADE_LABELS: readonly ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950"];
|
|
13
|
+
/**
|
|
14
|
+
* The 22 Tailwind color families, in spectrum order.
|
|
15
|
+
* Tailwind v4 exposes each shade as `--color-{family}-{shade}` automatically,
|
|
16
|
+
* so we render swatches via `var(--color-...)` instead of hardcoding hex.
|
|
17
|
+
*/
|
|
18
|
+
export declare const TAILWIND_COLOR_FAMILIES: readonly ["slate", "gray", "zinc", "neutral", "stone", "red", "orange", "amber", "yellow", "lime", "green", "emerald", "teal", "cyan", "sky", "blue", "indigo", "violet", "purple", "fuchsia", "pink", "rose"];
|
|
19
|
+
/**
|
|
20
|
+
* Returns shade tokens for a given Tailwind family.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* getTailwindShadeTokens("slate")
|
|
24
|
+
* // → ["slate-50", "slate-100", "slate-200", ..., "slate-950"]
|
|
25
|
+
*/
|
|
26
|
+
export declare const getTailwindShadeTokens: (family: string) => string[];
|
|
27
|
+
/**
|
|
28
|
+
* Resolves a Tailwind shade token to a CSS color value usable in inline
|
|
29
|
+
* styles for swatch backgrounds. Reads `--color-{token}` directly; modern
|
|
30
|
+
* browsers accept the resulting `oklch(...)` (or fallback `rgb()`) in
|
|
31
|
+
* `background-color` without normalization.
|
|
32
|
+
*
|
|
33
|
+
* SSR-safe: returns `var(--color-{token})` literal when document is absent.
|
|
34
|
+
*/
|
|
35
|
+
export declare const resolveTailwindColor: (token: string) => string;
|
|
36
|
+
/**
|
|
37
|
+
* Tailwind v4 only emits `--color-{family}-{shade}` CSS vars for shades that
|
|
38
|
+
* appear as utility classes in source. Since the picker resolves them at
|
|
39
|
+
* runtime via `var(...)`, we need every shade present. This sentinel string
|
|
40
|
+
* lists `bg-{family}-{shade}` for the full 22×11 palette so Tailwind's
|
|
41
|
+
* content scanner emits all CSS variables. Not used at runtime.
|
|
42
|
+
*/
|
|
43
|
+
export declare const _TAILWIND_PALETTE_KEEPALIVE: string;
|
|
44
|
+
/**
|
|
45
|
+
* The two non-family base colors users always reach for, shown in their own row
|
|
46
|
+
* above the spectrum.
|
|
47
|
+
*
|
|
48
|
+
* `value` is the resolved background color (used to paint the swatch);
|
|
49
|
+
* `token` is the Tailwind shade fragment used to build the `text-{token}`
|
|
50
|
+
* class applied to the editor content.
|
|
51
|
+
*/
|
|
52
|
+
export declare const MONO_COLORS: {
|
|
53
|
+
name: string;
|
|
54
|
+
value: string;
|
|
55
|
+
token: string;
|
|
56
|
+
}[];
|
|
57
|
+
export declare const _RTE_CLASSES_KEEPALIVE: string;
|
|
6
58
|
/**
|
|
7
59
|
* Rich Text Editor theme - extends common forms base theme for consistency
|
|
8
60
|
*/
|
|
@@ -1,19 +1,87 @@
|
|
|
1
1
|
import { formsBaseTheme } from '../forms.theme.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Tailwind shade scale (same for every family). Used by both the picker
|
|
5
|
+
* UI and the `getTailwindShadeTokens` utility below.
|
|
5
6
|
*/
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
const TAILWIND_SHADE_LABELS = [
|
|
8
|
+
"50",
|
|
9
|
+
"100",
|
|
10
|
+
"200",
|
|
11
|
+
"300",
|
|
12
|
+
"400",
|
|
13
|
+
"500",
|
|
14
|
+
"600",
|
|
15
|
+
"700",
|
|
16
|
+
"800",
|
|
17
|
+
"900",
|
|
18
|
+
"950",
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* The 22 Tailwind color families, in spectrum order.
|
|
22
|
+
* Tailwind v4 exposes each shade as `--color-{family}-{shade}` automatically,
|
|
23
|
+
* so we render swatches via `var(--color-...)` instead of hardcoding hex.
|
|
24
|
+
*/
|
|
25
|
+
const TAILWIND_COLOR_FAMILIES = [
|
|
26
|
+
"slate",
|
|
27
|
+
"gray",
|
|
28
|
+
"zinc",
|
|
29
|
+
"neutral",
|
|
30
|
+
"stone",
|
|
31
|
+
"red",
|
|
32
|
+
"orange",
|
|
33
|
+
"amber",
|
|
34
|
+
"yellow",
|
|
35
|
+
"lime",
|
|
36
|
+
"green",
|
|
37
|
+
"emerald",
|
|
38
|
+
"teal",
|
|
39
|
+
"cyan",
|
|
40
|
+
"sky",
|
|
41
|
+
"blue",
|
|
42
|
+
"indigo",
|
|
43
|
+
"violet",
|
|
44
|
+
"purple",
|
|
45
|
+
"fuchsia",
|
|
46
|
+
"pink",
|
|
47
|
+
"rose",
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Returns shade tokens for a given Tailwind family.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* getTailwindShadeTokens("slate")
|
|
54
|
+
* // → ["slate-50", "slate-100", "slate-200", ..., "slate-950"]
|
|
55
|
+
*/
|
|
56
|
+
const getTailwindShadeTokens = (family) => TAILWIND_SHADE_LABELS.map((shade) => `${family}-${shade}`);
|
|
57
|
+
/**
|
|
58
|
+
* Resolves a Tailwind shade token to a CSS color value usable in inline
|
|
59
|
+
* styles for swatch backgrounds. Reads `--color-{token}` directly; modern
|
|
60
|
+
* browsers accept the resulting `oklch(...)` (or fallback `rgb()`) in
|
|
61
|
+
* `background-color` without normalization.
|
|
62
|
+
*
|
|
63
|
+
* SSR-safe: returns `var(--color-{token})` literal when document is absent.
|
|
64
|
+
*/
|
|
65
|
+
const resolveTailwindColor = (token) => {
|
|
66
|
+
const cssVar = `--color-${token}`;
|
|
67
|
+
if (typeof window === "undefined")
|
|
68
|
+
return `var(${cssVar})`;
|
|
69
|
+
const resolved = getComputedStyle(document.documentElement)
|
|
70
|
+
.getPropertyValue(cssVar)
|
|
71
|
+
.trim();
|
|
72
|
+
return resolved || `var(${cssVar})`;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* The two non-family base colors users always reach for, shown in their own row
|
|
76
|
+
* above the spectrum.
|
|
77
|
+
*
|
|
78
|
+
* `value` is the resolved background color (used to paint the swatch);
|
|
79
|
+
* `token` is the Tailwind shade fragment used to build the `text-{token}`
|
|
80
|
+
* class applied to the editor content.
|
|
81
|
+
*/
|
|
82
|
+
const MONO_COLORS = [
|
|
83
|
+
{ name: "white", value: "#ffffff", token: "white" },
|
|
84
|
+
{ name: "black", value: "#000000", token: "black" },
|
|
17
85
|
];
|
|
18
86
|
/**
|
|
19
87
|
* Rich Text Editor theme - extends common forms base theme for consistency
|
|
@@ -25,20 +93,26 @@ const richTextEditorTheme = {
|
|
|
25
93
|
containerStyle: `${formsBaseTheme.inputGroupBaseStyle} flex-col min-h-[120px] overflow-hidden`,
|
|
26
94
|
// Editor content area - extends common control base style
|
|
27
95
|
editorStyle: `${formsBaseTheme.controlBaseStyle} min-h-[100px] px-3 py-2 resize-none overflow-y-auto [&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0 [&_strong]:font-semibold [&_em]:italic [&_u]:underline data-[state=disabled]:cursor-not-allowed empty:before:content-[attr(data-placeholder)] empty:before:text-[var(--color-text-placeholder)] empty:before:pointer-events-none`,
|
|
28
|
-
// Toolbar styling (
|
|
29
|
-
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
96
|
+
// Toolbar styling (docked variant)
|
|
97
|
+
// `rounded-t-[var(--form-radius)]` matches the container's radius so the
|
|
98
|
+
// toolbar's own bg/backdrop-blur respects the top corners — prevents the
|
|
99
|
+
// 1px bleed past the parent's `overflow-hidden` clip in Safari/Chromium.
|
|
100
|
+
toolbarStyle: "flex items-center m-0.5 gap-0.5 p-0.5 rounded-[var(--form-radius)] dark:bg-[var(--color-surface)]/0",
|
|
101
|
+
// Toolbar styling (floating variant — selection-anchored)
|
|
102
|
+
floatingToolbarStyle: "flex items-center gap-1 p-1 rounded-xl border border-[var(--color-border)] bg-[var(--color-surface-overlay)]/70 backdrop-blur-sm shadow-real-xl overflow-hidden",
|
|
103
|
+
// Toolbar button — single source of truth via data-[state=active]
|
|
104
|
+
// (aria-pressed remains as proper ARIA on toggle buttons, but styling is decoupled)
|
|
105
|
+
toolbarButtonStyle: "inline-flex items-center justify-center rounded-[calc(var(--radius-base)*0.85)] border border-transparent bg-transparent text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-background-secondary)] transition-colors duration-300 disabled:opacity-50 disabled:cursor-not-allowed data-[state=active]:bg-[var(--color-background-secondary)] data-[state=active]:text-[var(--color-text-primary)] data-[state=active]:border-[var(--color-border)] data-[state=active]:shadow-inner",
|
|
106
|
+
// Dropdown surface (visual only — positioning handled at use site via portal)
|
|
107
|
+
dropdownStyle: "min-w-[120px] max-h-[18rem] overflow-y-auto py-1 bg-[var(--color-surface-overlay)]/70 backdrop-blur-md rounded-[var(--form-radius)] shadow-xl ring-1 ring-[var(--color-border)] focus:outline-none",
|
|
108
|
+
// Dropdown item — uses data-[active=true] for selected state
|
|
109
|
+
dropdownItemStyle: "block w-full px-3 py-2 text-left text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed data-[active=true]:bg-[var(--color-primary-50)] data-[active=true]:text-[var(--color-primary-900)] data-[active=true]:dark:bg-[var(--color-primary-400)]/10 data-[active=true]:dark:text-[var(--color-primary-400)]",
|
|
36
110
|
// Separator between toolbar sections
|
|
37
111
|
separatorStyle: "w-px h-6 bg-[var(--color-border)] mx-1",
|
|
38
|
-
// Color picker
|
|
39
|
-
colorPickerStyle: "flex flex-
|
|
40
|
-
// Color swatch button
|
|
41
|
-
colorSwatchStyle: "size-6 rounded-[calc(var(--radius-base)*0.75)] cursor-pointer hover:scale-105 transition-transform focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:ring-offset-1",
|
|
112
|
+
// Color picker layout — column of family rows, plus optional Recent + Mono rows
|
|
113
|
+
colorPickerStyle: "flex flex-col gap-1 p-2 w-fit",
|
|
114
|
+
// Color swatch button (original size + rounding)
|
|
115
|
+
colorSwatchStyle: "size-6 rounded-[calc(var(--radius-base)*0.75)] cursor-pointer hover:scale-105 transition-transform focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] focus:ring-offset-1 data-[active=true]:ring-2 data-[active=true]:ring-[var(--color-primary)] data-[active=true]:ring-offset-1 border border-[var(--color-border)]",
|
|
42
116
|
// Size variants - use common form sizes for consistency
|
|
43
117
|
sizes: {
|
|
44
118
|
sm: `${formsBaseTheme.sizes.sm.text} min-h-[80px]`,
|
|
@@ -51,4 +125,4 @@ const richTextEditorTheme = {
|
|
|
51
125
|
helperText: formsBaseTheme.helperText,
|
|
52
126
|
};
|
|
53
127
|
|
|
54
|
-
export {
|
|
128
|
+
export { MONO_COLORS, TAILWIND_COLOR_FAMILIES, TAILWIND_SHADE_LABELS, getTailwindShadeTokens, resolveTailwindColor, richTextEditorTheme };
|
|
@@ -48,6 +48,19 @@ export interface RichTextEditorProps extends Omit<React.HTMLAttributes<HTMLDivEl
|
|
|
48
48
|
toolbar?: ToolbarConfig;
|
|
49
49
|
/** Component-level theme overrides */
|
|
50
50
|
theme?: RichTextEditorThemeOverrides;
|
|
51
|
+
/**
|
|
52
|
+
* Custom list of font families shown by the `fontFamily` toolbar tool.
|
|
53
|
+
* If omitted, ships with a curated default set (system Default + 8 Google Fonts).
|
|
54
|
+
* Provide your own list when you self-host fonts or want a custom curation.
|
|
55
|
+
*/
|
|
56
|
+
fontFamilies?: FontFamilyOption[];
|
|
57
|
+
/**
|
|
58
|
+
* Whether the editor should lazy-load Google Fonts when picked.
|
|
59
|
+
* Defaults to `true`. Set to `false` if you load fonts yourself
|
|
60
|
+
* (e.g. via `next/font` or a `<link>` in your app head) — the picker still
|
|
61
|
+
* applies the font, but no network request is fired.
|
|
62
|
+
*/
|
|
63
|
+
loadFontsOnDemand?: boolean;
|
|
51
64
|
/**
|
|
52
65
|
* Optional HTML sanitizer function applied before setting innerHTML.
|
|
53
66
|
* Receives raw HTML string, must return sanitized HTML string.
|
|
@@ -78,8 +91,27 @@ export interface ToolbarConfig {
|
|
|
78
91
|
/**
|
|
79
92
|
* Available toolbar tools
|
|
80
93
|
*/
|
|
81
|
-
export type ToolbarTool = 'bold' | 'italic' | 'underline' | 'fontSize' | 'textColor' | 'alignLeft' | 'alignCenter' | 'alignRight' | 'undo' | 'redo' | 'separator';
|
|
82
|
-
|
|
94
|
+
export type ToolbarTool = 'bold' | 'italic' | 'underline' | 'fontWeight' | 'fontFamily' | 'fontSize' | 'lineHeight' | 'letterSpacing' | 'textColor' | 'alignLeft' | 'alignCenter' | 'alignRight' | 'undo' | 'redo' | 'separator';
|
|
95
|
+
/**
|
|
96
|
+
* Font family option used by the RichTextEditor font picker.
|
|
97
|
+
* - `key` is the stable identifier matched against the current selection.
|
|
98
|
+
* - `family` is the canonical Google Fonts family name (used to build the load URL).
|
|
99
|
+
* Omit for system fonts (e.g. "Default" or "Sans") — they will not be lazy-loaded.
|
|
100
|
+
* - `stack` is the CSS font-family value applied to the selection. Always include
|
|
101
|
+
* safe fallbacks so text remains readable while the font is loading.
|
|
102
|
+
* - `weights` is the optional list of weights to request (defaults to all 9).
|
|
103
|
+
*/
|
|
104
|
+
export interface FontFamilyOption {
|
|
105
|
+
key: string;
|
|
106
|
+
label: string;
|
|
107
|
+
stack: string;
|
|
108
|
+
family?: string;
|
|
109
|
+
weights?: number[];
|
|
110
|
+
}
|
|
111
|
+
export type RichTextFontSizeKey = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl' | '9xl';
|
|
112
|
+
export type RichTextFontWeightKey = 'thin' | 'extralight' | 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold' | 'black';
|
|
113
|
+
export type RichTextLineHeightKey = 'tight' | 'snug' | 'normal' | 'relaxed' | 'loose';
|
|
114
|
+
export type RichTextLetterSpacingKey = 'tighter' | 'tight' | 'normal' | 'wide' | 'wider' | 'widest';
|
|
83
115
|
/**
|
|
84
116
|
* Text formatting state
|
|
85
117
|
*/
|
|
@@ -89,6 +121,10 @@ export interface FormattingState {
|
|
|
89
121
|
underline: boolean;
|
|
90
122
|
textAlign: 'left' | 'center' | 'right' | 'justify';
|
|
91
123
|
fontSize: RichTextFontSizeKey;
|
|
124
|
+
fontWeight: RichTextFontWeightKey;
|
|
125
|
+
fontFamily: string;
|
|
126
|
+
lineHeight: RichTextLineHeightKey;
|
|
127
|
+
letterSpacing: RichTextLetterSpacingKey;
|
|
92
128
|
textColor: string;
|
|
93
129
|
}
|
|
94
130
|
/**
|
|
@@ -109,8 +145,10 @@ export interface RichTextEditorThemeOverrides {
|
|
|
109
145
|
containerStyle?: string;
|
|
110
146
|
/** ContentEditable element style */
|
|
111
147
|
editorStyle?: string;
|
|
112
|
-
/** Toolbar container style */
|
|
148
|
+
/** Toolbar container style (docked variant) */
|
|
113
149
|
toolbarStyle?: string;
|
|
150
|
+
/** Floating toolbar container style (selection-anchored variant) */
|
|
151
|
+
floatingToolbarStyle?: string;
|
|
114
152
|
/** Toolbar button style */
|
|
115
153
|
toolbarButtonStyle?: string;
|
|
116
154
|
/** Size variants */
|
|
@@ -132,6 +170,7 @@ export interface RichTextEditorTheme {
|
|
|
132
170
|
containerStyle: string;
|
|
133
171
|
editorStyle: string;
|
|
134
172
|
toolbarStyle: string;
|
|
173
|
+
floatingToolbarStyle: string;
|
|
135
174
|
toolbarButtonStyle: string;
|
|
136
175
|
dropdownStyle: string;
|
|
137
176
|
dropdownItemStyle: string;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { RichTextEditor } from './RichTextEditor';
|
|
2
|
-
export type { RichTextEditorProps, RichTextEditorSize, RichTextEditorState, ToolbarConfig, ToolbarTool, FormattingState, ColorOption, RichTextEditorTheme, RichTextEditorThemeOverrides, } from './RichTextEditor.types';
|
|
1
|
+
export { RichTextEditor, DEFAULT_FONT_FAMILY_OPTIONS, loadGoogleFont, } from './RichTextEditor';
|
|
2
|
+
export type { RichTextEditorProps, RichTextEditorSize, RichTextEditorState, ToolbarConfig, ToolbarTool, FormattingState, FontFamilyOption, ColorOption, RichTextEditorTheme, RichTextEditorThemeOverrides, } from './RichTextEditor.types';
|
|
3
3
|
export { richTextEditorTheme, colorOptions } from './RichTextEditor.theme';
|
|
@@ -96,7 +96,7 @@ const SelectButton = ({ id, disabled, isOpen, state = "default", size = "md", ic
|
|
|
96
96
|
// Use either the themed focus state or directly apply the focus classes if the theme is not working
|
|
97
97
|
const activeFocusState = isOpen
|
|
98
98
|
? focusStateStyle ||
|
|
99
|
-
"
|
|
99
|
+
"shadow-[inset_0_0_0_1px_var(--color-primary)] ring-4 ring-[var(--color-primary)]/10"
|
|
100
100
|
: "";
|
|
101
101
|
return (jsxs("div", { className: cn(buttonWrapperStyle, "flex items-stretch"), children: [contentStart && (jsx("div", { "data-slot": "content-start", className: cn(contentSlotStyle, "pr-0 border-r border-[var(--color-border)]"), children: contentStart })), jsxs("button", { ref: buttonRef, id: id, type: "button", className: cn(baseStyle, sizeStyle, stateStyle, hoverStateStyle, activeFocusState, iconStartPadding, iconEndPadding, buttonStyle, "flex-1 min-w-0", className), onClick: onClick, onFocus: onFocus, onBlur: onBlur, disabled: disabled, "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-controls": isOpen && id ? `${id}-listbox` : undefined, "aria-labelledby": ariaLabelledby, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, children: [iconStart && jsx("span", { className: iconStartStyle, children: iconStart }), children, iconEnd && jsx("span", { className: iconEndStyle, children: iconEnd })] }), contentEnd && (jsx("div", { "data-slot": "content-end", className: cn(contentSlotStyle, "pl-0 border-l border-[var(--color-border)]"), children: contentEnd }))] }));
|
|
102
102
|
};
|
|
@@ -287,7 +287,7 @@ const SelectOptions = ({ isOpen, maxHeight = "15rem", className = "", onClose, c
|
|
|
287
287
|
} }) })), children] })) }));
|
|
288
288
|
// Use portal if enabled and client-side - wrap with dark class for dark mode support
|
|
289
289
|
if (portal && isClient) {
|
|
290
|
-
return createPortal(jsx("div", { className: isDarkMode ? "dark" : undefined, children: optionsContent }), document.body);
|
|
290
|
+
return createPortal(jsx("div", { "data-flikkui-portal": "", className: isDarkMode ? "dark" : undefined, children: optionsContent }), document.body);
|
|
291
291
|
}
|
|
292
292
|
return optionsContent;
|
|
293
293
|
};
|
|
@@ -11,12 +11,12 @@ const selectTheme = {
|
|
|
11
11
|
baseStyle: formsBaseTheme.inputGroupBaseStyle + " items-center justify-between",
|
|
12
12
|
// Button wrapper style
|
|
13
13
|
buttonWrapperStyle: "relative w-full",
|
|
14
|
-
// Button style -
|
|
15
|
-
buttonStyle: "w-full cursor-pointer bg-
|
|
14
|
+
// Button style - surface flips automatically between light/dark
|
|
15
|
+
buttonStyle: "w-full cursor-pointer bg-[var(--color-surface)]",
|
|
16
16
|
// Placeholder text style - matches Input placeholder styling
|
|
17
17
|
placeholderTextStyle: formsBaseTheme.placeholderStyle,
|
|
18
18
|
// Selected value text style
|
|
19
|
-
valueTextStyle: "text-[var(--color-text-primary)]
|
|
19
|
+
valueTextStyle: "text-[var(--color-text-primary)]",
|
|
20
20
|
// Size variants - composed from atomic tokens
|
|
21
21
|
sizes: {
|
|
22
22
|
sm: `${formsBaseTheme.sizes.sm.text} ${formsBaseTheme.sizes.sm.padding} ${formsBaseTheme.sizes.sm.height}`,
|
|
@@ -10,7 +10,7 @@ const sliderTheme = {
|
|
|
10
10
|
// Root container with layout
|
|
11
11
|
rootStyle: "relative flex items-center w-full touch-none select-none data-[orientation=vertical]:flex-col data-[orientation=vertical]:h-full",
|
|
12
12
|
// Track (background)
|
|
13
|
-
trackStyle: "relative w-full h-2 grow rounded-full bg-[var(--color-
|
|
13
|
+
trackStyle: "relative w-full h-2 grow rounded-full bg-[var(--color-surface-sunken)] overflow-hidden data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[orientation=vertical]:w-2 data-[orientation=vertical]:h-full shadow-inner",
|
|
14
14
|
// Range (filled portion) - rounded to match track clipping
|
|
15
15
|
rangeStyle: "absolute h-full bg-gradient-to-r from-[var(--color-primary-500)] to-[var(--color-primary-700)] transition-all rounded-full data-[disabled]:bg-[var(--color-background-disabled)] data-[invalid]:bg-[var(--color-danger)]",
|
|
16
16
|
// Thumb (draggable handle)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const switchTheme = {
|
|
5
5
|
container: "flex w-full justify-between items-center gap-4",
|
|
6
|
-
track: "rounded-full cursor-pointer shadow-inner bg-[var(--color-
|
|
6
|
+
track: "rounded-full cursor-pointer shadow-inner bg-[var(--color-surface-sunken)] data-[state=checked]:bg-[var(--color-primary)] data-[state=disabled]:bg-[var(--color-background-disabled)] data-[state=disabled]:cursor-not-allowed data-[state=invalid]:border-2 data-[state=invalid]:border-[var(--color-danger)] outline outline-[var(--color-border)] transition-colors duration-300",
|
|
7
7
|
thumb: "rounded-full bg-transparent overflow-hidden border border-[var(--color-border)]/40 shadow-lg",
|
|
8
8
|
description: "text-sm text-[var(--color-text-muted)] -mt-1.5",
|
|
9
9
|
trackSizes: {
|
|
@@ -78,8 +78,8 @@ const timePickerTheme = {
|
|
|
78
78
|
"dark:text-[var(--color-neutral-200)] dark:placeholder:text-[var(--color-neutral-500)]",
|
|
79
79
|
// AM/PM period toggle button
|
|
80
80
|
periodToggleStyle: "px-1.5 py-0.5 text-xs font-semibold rounded " +
|
|
81
|
-
"bg-[var(--color-
|
|
82
|
-
"hover:bg-[var(--color-
|
|
81
|
+
"bg-[var(--color-surface-sunken)] text-[var(--color-text-primary)] " +
|
|
82
|
+
"hover:bg-[var(--color-surface-hover)] transition-colors cursor-pointer select-none " +
|
|
83
83
|
"dark:bg-[var(--color-neutral-700)] dark:text-[var(--color-neutral-200)] " +
|
|
84
84
|
"dark:hover:bg-[var(--color-neutral-600)]",
|
|
85
85
|
};
|
|
@@ -35,6 +35,7 @@ import '../../core/Dropdown/DropdownItem.js';
|
|
|
35
35
|
import '../../core/Dropdown/DropdownSection.js';
|
|
36
36
|
import '../../core/Dropdown/DropdownSeparator.js';
|
|
37
37
|
import '../../core/Dropdown/Dropdown.theme.js';
|
|
38
|
+
import '../../core/DotSeparator/DotSeparator.js';
|
|
38
39
|
import '../../core/Kbd/Kbd.js';
|
|
39
40
|
import '../../core/MenuItem/MenuItem.js';
|
|
40
41
|
import '../../core/Link/Link.js';
|
|
@@ -86,12 +87,15 @@ import '../../core/Sidebar/SidebarToggle.js';
|
|
|
86
87
|
import '../../core/Sidebar/SidebarMobileTrigger.js';
|
|
87
88
|
import '../../core/Sidebar/SidebarUserProfile.js';
|
|
88
89
|
import '../../core/Sidebar/SidebarLogo.js';
|
|
90
|
+
import '../../core/Sidebar/SidebarSearch.js';
|
|
91
|
+
import '../../core/Sidebar/SidebarCard.js';
|
|
89
92
|
import '../../core/Sidebar/SidebarContext.js';
|
|
90
93
|
import '../../core/OfflineIndicator/OfflineIndicator.js';
|
|
91
94
|
import '../../core/ContextMenu/ContextMenu.js';
|
|
92
95
|
import '../../core/ContextMenu/ContextMenu.theme.js';
|
|
93
96
|
import '../../core/Pill/Pill.js';
|
|
94
97
|
import '../../core/Icon/Icon.js';
|
|
98
|
+
import '../../core/ImagePlaceholder/ImagePlaceholder.js';
|
|
95
99
|
import { useIsClient } from '../../../hooks/useIsClient.js';
|
|
96
100
|
import { useDarkMode } from '../../../hooks/useDarkMode.js';
|
|
97
101
|
|
|
@@ -25,7 +25,7 @@ const TimePickerTrigger = ({ id, disabled, isOpen, state = 'default', size = 'md
|
|
|
25
25
|
const periodToggleStyle = theme.periodToggleStyle || "";
|
|
26
26
|
// Apply focused styles when open — same pattern as SelectButton and DatePickerTrigger
|
|
27
27
|
const activeFocusState = isOpen
|
|
28
|
-
? ((_d = theme.triggerFocusStates) === null || _d === void 0 ? void 0 : _d[state]) || "
|
|
28
|
+
? ((_d = theme.triggerFocusStates) === null || _d === void 0 ? void 0 : _d[state]) || "shadow-[inset_0_0_0_1px_var(--color-primary-600)] ring-4 ring-[var(--color-primary)]/10 dark:shadow-[inset_0_0_0_1px_var(--color-primary-500)] dark:ring-[var(--color-primary-500)]/20"
|
|
29
29
|
: "";
|
|
30
30
|
// Determine whether start icon is present (for input padding)
|
|
31
31
|
const hasStartIcon = iconStart !== undefined ? Boolean(iconStart) : true;
|
|
@@ -8,12 +8,14 @@ const formsBaseTheme = {
|
|
|
8
8
|
// Common wrapper style
|
|
9
9
|
wrapperStyle: "relative w-full",
|
|
10
10
|
// Common input group style with focus, hover, and state variations
|
|
11
|
-
inputGroupBaseStyle: "relative flex rounded-[var(--form-radius)] outline
|
|
12
|
-
"focus-within:
|
|
13
|
-
"focus-within:ring-4 focus-within:ring-[var(--color-primary)]/10 bg-
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
"
|
|
11
|
+
inputGroupBaseStyle: "relative flex rounded-[var(--form-radius)] outline-none shadow-[inset_0_0_0_1px_var(--color-border)] " +
|
|
12
|
+
"focus-within:shadow-[inset_0_0_0_1px_var(--color-primary-600)] " +
|
|
13
|
+
"focus-within:ring-4 focus-within:ring-[var(--color-primary)]/10 bg-[var(--color-surface)] transition-all " +
|
|
14
|
+
// Hover edge: strengthen the border to --color-border-secondary on hover. Scoped with
|
|
15
|
+
// not-focus-within so focus (primary border) always wins; the token flips for dark mode.
|
|
16
|
+
"not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-border-secondary)] " +
|
|
17
|
+
// Dark focus mirror (fill comes from --color-surface, which flips automatically)
|
|
18
|
+
"dark:focus-within:shadow-[inset_0_0_0_1px_var(--color-primary-500)] dark:focus-within:ring-[var(--color-primary-500)]/20",
|
|
17
19
|
// Common base input/control style
|
|
18
20
|
controlBaseStyle: "w-full bg-transparent text-sm text-[var(--color-text-primary)] " +
|
|
19
21
|
"placeholder:text-[var(--color-text-placeholder)] focus:outline-none " +
|
|
@@ -44,25 +46,29 @@ const formsBaseTheme = {
|
|
|
44
46
|
// Common state variants
|
|
45
47
|
states: {
|
|
46
48
|
default: "",
|
|
47
|
-
disabled: "cursor-not-allowed bg-[var(--color-background-disabled)]
|
|
49
|
+
disabled: "cursor-not-allowed bg-[var(--color-background-disabled)] shadow-[inset_0_0_0_1px_var(--color-border)] " +
|
|
50
|
+
// Suppress the hover-edge change while disabled (keep the resting border)
|
|
51
|
+
"not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-border)] " +
|
|
48
52
|
"[&_input]:text-[var(--color-text-disabled)] [&_textarea]:text-[var(--color-text-disabled)] " +
|
|
49
53
|
"[&_select]:text-[var(--color-text-disabled)] [&_input]:cursor-not-allowed " +
|
|
50
54
|
"[&_textarea]:cursor-not-allowed [&_select]:cursor-not-allowed " +
|
|
51
55
|
"[&_input]:placeholder:text-[var(--color-text-placeholder)] " +
|
|
52
56
|
"[&_textarea]:placeholder:text-[var(--color-text-placeholder)] " +
|
|
53
|
-
"[&_select]:placeholder:text-[var(--color-text-placeholder)] [&_button]:cursor-not-allowed
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
"[&_select]:placeholder:text-[var(--color-text-placeholder)] [&_button]:cursor-not-allowed",
|
|
58
|
+
// (--color-background-disabled already flips for dark mode)
|
|
59
|
+
invalid: "shadow-[inset_0_0_0_1px_var(--color-danger)] bg-[var(--color-danger-50)] focus-within:shadow-[inset_0_0_0_1px_var(--color-danger)] " +
|
|
60
|
+
// Keep the danger border on hover (don't let the hover edge override it)
|
|
61
|
+
"not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-danger)] " +
|
|
57
62
|
// Dark mode
|
|
58
|
-
"dark:bg-[var(--color-danger-950)]/30 dark:
|
|
63
|
+
"dark:bg-[var(--color-danger-950)]/30 dark:shadow-[inset_0_0_0_1px_var(--color-danger-500)] " +
|
|
64
|
+
"dark:not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-danger-500)]",
|
|
59
65
|
},
|
|
60
66
|
// Common focus state variants
|
|
61
67
|
focusStates: {
|
|
62
|
-
default: "
|
|
63
|
-
"dark:
|
|
64
|
-
disabled: "
|
|
65
|
-
invalid: "
|
|
68
|
+
default: "shadow-[inset_0_0_0_1px_var(--color-primary-600)] ring-4 ring-[var(--color-primary)]/10 " +
|
|
69
|
+
"dark:shadow-[inset_0_0_0_1px_var(--color-primary-500)] dark:ring-[var(--color-primary-500)]/20",
|
|
70
|
+
disabled: "shadow-none",
|
|
71
|
+
invalid: "shadow-[inset_0_0_0_1px_var(--color-danger-500)] ring-4 ring-[var(--color-danger-500)]/10 " +
|
|
66
72
|
"dark:ring-[var(--color-danger-500)]/20",
|
|
67
73
|
},
|
|
68
74
|
// Common hover state variants
|
|
@@ -89,9 +95,8 @@ const formsBaseTheme = {
|
|
|
89
95
|
dropdownStyles: {
|
|
90
96
|
// Container for dropdown panel
|
|
91
97
|
container: "fixed z-[1000] max-h-[var(--select-content-available-height,20rem)] overflow-auto overscroll-contain " +
|
|
92
|
-
"rounded-[var(--form-radius)] bg-
|
|
93
|
-
"shadow-real-lg ring-1 ring-[var(--color-border)] focus:outline-none
|
|
94
|
-
"dark:bg-[var(--color-neutral-900)]/90 dark:ring-[var(--color-neutral-700)]",
|
|
98
|
+
"rounded-[var(--form-radius)] bg-[var(--color-surface-overlay)]/90 backdrop-blur-md text-sm border border-[var(--color-border)] " +
|
|
99
|
+
"shadow-real-lg ring-1 ring-[var(--color-border)] focus:outline-none",
|
|
95
100
|
// Base option style
|
|
96
101
|
option: "relative cursor-pointer select-none py-2 px-3 text-[var(--color-text-primary)] " +
|
|
97
102
|
"hover:text-[var(--color-primary)] hover:bg-[var(--color-primary-50)]/50 " +
|
|
@@ -58,6 +58,7 @@ import '../core/Dropdown/DropdownItem.js';
|
|
|
58
58
|
import '../core/Dropdown/DropdownSection.js';
|
|
59
59
|
import '../core/Dropdown/DropdownSeparator.js';
|
|
60
60
|
import '../core/Dropdown/Dropdown.theme.js';
|
|
61
|
+
import '../core/DotSeparator/DotSeparator.js';
|
|
61
62
|
import '../core/Kbd/Kbd.js';
|
|
62
63
|
import '../core/MenuItem/MenuItem.js';
|
|
63
64
|
import '../core/Link/Link.js';
|
|
@@ -108,12 +109,15 @@ import '../core/Sidebar/SidebarToggle.js';
|
|
|
108
109
|
import '../core/Sidebar/SidebarMobileTrigger.js';
|
|
109
110
|
import '../core/Sidebar/SidebarUserProfile.js';
|
|
110
111
|
import '../core/Sidebar/SidebarLogo.js';
|
|
112
|
+
import '../core/Sidebar/SidebarSearch.js';
|
|
113
|
+
import '../core/Sidebar/SidebarCard.js';
|
|
111
114
|
import '../core/Sidebar/SidebarContext.js';
|
|
112
115
|
import '../core/OfflineIndicator/OfflineIndicator.js';
|
|
113
116
|
import '../core/ContextMenu/ContextMenu.js';
|
|
114
117
|
import '../core/ContextMenu/ContextMenu.theme.js';
|
|
115
118
|
import '../core/Pill/Pill.js';
|
|
116
119
|
import '../core/Icon/Icon.js';
|
|
120
|
+
import '../core/ImagePlaceholder/ImagePlaceholder.js';
|
|
117
121
|
import './TimePicker/WheelColumn.js';
|
|
118
122
|
export { timePickerTheme } from './TimePicker/TimePicker.theme.js';
|
|
119
123
|
export { Slider } from './Slider/Slider.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { AppShellProps } from "./AppShell.types";
|
|
3
|
+
export declare const AppShell: React.ForwardRefExoticComponent<AppShellProps & React.RefAttributes<HTMLDivElement>> & {
|
|
4
|
+
Topbar: React.ForwardRefExoticComponent<import("./AppShell.types").AppShellTopbarProps & React.RefAttributes<HTMLElement>>;
|
|
5
|
+
Sidebar: React.ForwardRefExoticComponent<import("./AppShell.types").AppShellSidebarProps & React.RefAttributes<HTMLElement>>;
|
|
6
|
+
Header: React.ForwardRefExoticComponent<import("./AppShell.types").AppShellHeaderProps & React.RefAttributes<HTMLElement>>;
|
|
7
|
+
Main: React.ForwardRefExoticComponent<import("./AppShell.types").AppShellMainProps & React.RefAttributes<HTMLElement>>;
|
|
8
|
+
RightPanel: React.ForwardRefExoticComponent<import("./AppShell.types").AppShellRightPanelProps & React.RefAttributes<HTMLElement>>;
|
|
9
|
+
Footer: React.ForwardRefExoticComponent<import("./AppShell.types").AppShellFooterProps & React.RefAttributes<HTMLElement>>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { cn } from '../../../utils/cn.js';
|
|
4
|
+
import { getAppShellTheme } from './AppShell.theme.js';
|
|
5
|
+
import { AppShellProvider } from './AppShellContext.js';
|
|
6
|
+
import { AppShellTopbar } from './AppShellTopbar.js';
|
|
7
|
+
import { AppShellSidebar } from './AppShellSidebar.js';
|
|
8
|
+
import { AppShellHeader } from './AppShellHeader.js';
|
|
9
|
+
import { AppShellMain } from './AppShellMain.js';
|
|
10
|
+
import { AppShellRightPanel } from './AppShellRightPanel.js';
|
|
11
|
+
import { AppShellFooter } from './AppShellFooter.js';
|
|
12
|
+
|
|
13
|
+
const AppShellRoot = React__default.forwardRef(({ className, theme: customTheme, scroll = "viewport", topbarSpan = "full", footerSpan = "full", contentWidth = "full", contentPadding = "md", children, ...props }, ref) => {
|
|
14
|
+
const theme = getAppShellTheme(customTheme);
|
|
15
|
+
const contextValue = React__default.useMemo(() => ({ scroll, contentWidth, contentPadding }), [scroll, contentWidth, contentPadding]);
|
|
16
|
+
// Bucket children by slot type. Header is intentionally NOT bucketed —
|
|
17
|
+
// it is user-composed inside AppShell.Main.
|
|
18
|
+
let topbar = null;
|
|
19
|
+
let sidebar = null;
|
|
20
|
+
let main = null;
|
|
21
|
+
let rightPanel = null;
|
|
22
|
+
let footer = null;
|
|
23
|
+
React__default.Children.forEach(children, (child) => {
|
|
24
|
+
if (!React__default.isValidElement(child))
|
|
25
|
+
return;
|
|
26
|
+
const type = child.type;
|
|
27
|
+
if (type === AppShellTopbar) {
|
|
28
|
+
if (topbar === null)
|
|
29
|
+
topbar = child;
|
|
30
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
31
|
+
console.warn("[AppShell]: multiple AppShell.Topbar children; keeping the first.");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (type === AppShellSidebar) {
|
|
35
|
+
if (sidebar === null)
|
|
36
|
+
sidebar = child;
|
|
37
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
38
|
+
console.warn("[AppShell]: multiple AppShell.Sidebar children; keeping the first.");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (type === AppShellMain) {
|
|
42
|
+
if (main === null)
|
|
43
|
+
main = child;
|
|
44
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
45
|
+
console.warn("[AppShell]: multiple AppShell.Main children; keeping the first.");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (type === AppShellRightPanel) {
|
|
49
|
+
if (rightPanel === null)
|
|
50
|
+
rightPanel = child;
|
|
51
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
52
|
+
console.warn("[AppShell]: multiple AppShell.RightPanel children; keeping the first.");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (type === AppShellFooter) {
|
|
56
|
+
if (footer === null)
|
|
57
|
+
footer = child;
|
|
58
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
59
|
+
console.warn("[AppShell]: multiple AppShell.Footer children; keeping the first.");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
63
|
+
console.warn("[AppShell]: unknown child rendered; expected one of " +
|
|
64
|
+
"AppShell.Topbar / Sidebar / Main / RightPanel / Footer. " +
|
|
65
|
+
"AppShell.Header is composed inside AppShell.Main.");
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const topbarInChrome = topbar !== null && topbarSpan === "full";
|
|
69
|
+
const topbarInMain = topbar !== null && topbarSpan === "main";
|
|
70
|
+
const footerInChrome = footer !== null && footerSpan === "full";
|
|
71
|
+
const footerInMain = footer !== null && footerSpan === "main";
|
|
72
|
+
return (jsx(AppShellProvider, { value: contextValue, children: jsxs("div", { ref: ref, className: cn(theme.root, scroll === "viewport" && theme.rootViewport, className), ...props, children: [topbarInChrome && topbar, jsxs("div", { className: theme.shell, children: [sidebar, jsxs("div", { className: theme.mainColumn, children: [topbarInMain && topbar, main, footerInMain && footer] }), rightPanel] }), footerInChrome && footer] }) }));
|
|
73
|
+
});
|
|
74
|
+
AppShellRoot.displayName = "AppShell";
|
|
75
|
+
const AppShell = Object.assign(AppShellRoot, {
|
|
76
|
+
Topbar: AppShellTopbar,
|
|
77
|
+
Sidebar: AppShellSidebar,
|
|
78
|
+
Header: AppShellHeader,
|
|
79
|
+
Main: AppShellMain,
|
|
80
|
+
RightPanel: AppShellRightPanel,
|
|
81
|
+
Footer: AppShellFooter,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export { AppShell };
|