@once-ui-system/core 1.7.11 → 1.7.12
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/ai/catalog.json +1650 -0
- package/ai/catalog.seed.json +411 -0
- package/ai/components/Accordion.json +136 -0
- package/ai/components/AccordionGroup.json +128 -0
- package/ai/components/Animation.json +146 -0
- package/ai/components/Arrow.json +128 -0
- package/ai/components/AutoScroll.json +130 -0
- package/ai/components/Avatar.json +133 -0
- package/ai/components/AvatarGroup.json +129 -0
- package/ai/components/Background.json +131 -0
- package/ai/components/Badge.json +132 -0
- package/ai/components/Banner.json +122 -0
- package/ai/components/BarChart.json +123 -0
- package/ai/components/BlobFx.json +125 -0
- package/ai/components/BlockQuote.json +132 -0
- package/ai/components/Button.json +26 -0
- package/ai/components/Card.json +129 -0
- package/ai/components/Carousel.json +134 -0
- package/ai/components/CelebrationFx.json +132 -0
- package/ai/components/ChartHeader.json +130 -0
- package/ai/components/ChartStatus.json +12 -0
- package/ai/components/Checkbox.json +13 -0
- package/ai/components/Chip.json +132 -0
- package/ai/components/CodeBlock.json +122 -0
- package/ai/components/ColorInput.json +13 -0
- package/ai/components/Column.json +128 -0
- package/ai/components/CompareImage.json +126 -0
- package/ai/components/ContextMenu.json +22 -0
- package/ai/components/CountFx.json +82 -0
- package/ai/components/CountdownFx.json +11 -0
- package/ai/components/Cursor.json +9 -0
- package/ai/components/CursorCard.json +128 -0
- package/ai/components/DataTooltip.json +15 -0
- package/ai/components/DateInput.json +21 -0
- package/ai/components/DatePicker.json +143 -0
- package/ai/components/DateRangeInput.json +18 -0
- package/ai/components/DateRangePicker.json +129 -0
- package/ai/components/Dialog.json +134 -0
- package/ai/components/DialogProvider.json +8 -0
- package/ai/components/Dropdown.json +128 -0
- package/ai/components/DropdownWrapper.json +28 -0
- package/ai/components/EmojiPicker.json +129 -0
- package/ai/components/EmojiPickerDropdown.json +13 -0
- package/ai/components/Fade.json +130 -0
- package/ai/components/FadingLettersFx.json +77 -0
- package/ai/components/Feedback.json +132 -0
- package/ai/components/Flex.json +125 -0
- package/ai/components/FlipFx.json +133 -0
- package/ai/components/GlitchFx.json +128 -0
- package/ai/components/Grid.json +121 -0
- package/ai/components/Heading.json +75 -0
- package/ai/components/HeadingLink.json +127 -0
- package/ai/components/HeadingNav.json +124 -0
- package/ai/components/HoloFx.json +128 -0
- package/ai/components/Hover.json +130 -0
- package/ai/components/HoverCard.json +122 -0
- package/ai/components/Icon.json +132 -0
- package/ai/components/IconButton.json +22 -0
- package/ai/components/InfiniteScroll.json +130 -0
- package/ai/components/InlineCode.json +126 -0
- package/ai/components/Input.json +24 -0
- package/ai/components/InteractiveDetails.json +14 -0
- package/ai/components/Kbar.json +10 -0
- package/ai/components/Kbd.json +127 -0
- package/ai/components/Legend.json +14 -0
- package/ai/components/LetterFx.json +14 -0
- package/ai/components/Line.json +125 -0
- package/ai/components/LineBarChart.json +123 -0
- package/ai/components/LineChart.json +123 -0
- package/ai/components/LinearGauge.json +130 -0
- package/ai/components/LinearGradient.json +15 -0
- package/ai/components/List.json +127 -0
- package/ai/components/ListItem.json +77 -0
- package/ai/components/Logo.json +16 -0
- package/ai/components/LogoCloud.json +124 -0
- package/ai/components/Mask.json +131 -0
- package/ai/components/MasonryGrid.json +132 -0
- package/ai/components/MatrixFx.json +135 -0
- package/ai/components/Media.json +142 -0
- package/ai/components/MediaUpload.json +122 -0
- package/ai/components/MegaMenu.json +125 -0
- package/ai/components/MobileMegaMenu.json +125 -0
- package/ai/components/Modal.json +12 -0
- package/ai/components/NavIcon.json +127 -0
- package/ai/components/NumberInput.json +16 -0
- package/ai/components/OTPInput.json +13 -0
- package/ai/components/OgCard.json +135 -0
- package/ai/components/Option.json +137 -0
- package/ai/components/Particle.json +135 -0
- package/ai/components/PasswordInput.json +8 -0
- package/ai/components/PieChart.json +123 -0
- package/ai/components/ProgressBar.json +131 -0
- package/ai/components/Pulse.json +129 -0
- package/ai/components/RadialGauge.json +134 -0
- package/ai/components/RadialGradient.json +16 -0
- package/ai/components/RadioButton.json +17 -0
- package/ai/components/RevealFx.json +131 -0
- package/ai/components/Row.json +128 -0
- package/ai/components/Schema.json +17 -0
- package/ai/components/ScrollContainer.json +126 -0
- package/ai/components/ScrollToTop.json +124 -0
- package/ai/components/Scroller.json +128 -0
- package/ai/components/SegmentedControl.json +132 -0
- package/ai/components/Select.json +21 -0
- package/ai/components/ShineFx.json +80 -0
- package/ai/components/Skeleton.json +129 -0
- package/ai/components/Slider.json +17 -0
- package/ai/components/SmartLink.json +17 -0
- package/ai/components/Spinner.json +127 -0
- package/ai/components/SplitView.json +129 -0
- package/ai/components/StatusIndicator.json +128 -0
- package/ai/components/StyleOverlay.json +126 -0
- package/ai/components/StylePanel.json +125 -0
- package/ai/components/Swiper.json +130 -0
- package/ai/components/Switch.json +20 -0
- package/ai/components/Table.json +125 -0
- package/ai/components/Tag.json +129 -0
- package/ai/components/TagInput.json +12 -0
- package/ai/components/Text.json +72 -0
- package/ai/components/Textarea.json +24 -0
- package/ai/components/ThemeSwitcher.json +122 -0
- package/ai/components/TiltFx.json +126 -0
- package/ai/components/Timeline.json +126 -0
- package/ai/components/Toast.json +13 -0
- package/ai/components/Toaster.json +14 -0
- package/ai/components/ToggleButton.json +24 -0
- package/ai/components/Tooltip.json +129 -0
- package/ai/components/TypeFx.json +15 -0
- package/ai/components/User.json +15 -0
- package/ai/components/UserMenu.json +16 -0
- package/ai/components/WeatherFx.json +133 -0
- package/ai/examples/auth.tsx +105 -0
- package/ai/examples/blocks/Background6.tsx +25 -0
- package/ai/examples/blocks/Chat1.tsx +70 -0
- package/ai/examples/blocks/Dashboard1.tsx +404 -0
- package/ai/examples/blocks/Feed3.tsx +151 -0
- package/ai/examples/blocks/Footer1.tsx +30 -0
- package/ai/examples/blocks/Footer2.tsx +96 -0
- package/ai/examples/blocks/Footer3.tsx +127 -0
- package/ai/examples/blocks/Footer4.tsx +406 -0
- package/ai/examples/blocks/Header1.tsx +370 -0
- package/ai/examples/blocks/Header2.tsx +98 -0
- package/ai/examples/blocks/Header3.tsx +133 -0
- package/ai/examples/blocks/Header4.tsx +123 -0
- package/ai/examples/blocks/Productivity1.tsx +318 -0
- package/ai/examples/blocks/Roadmap1.tsx +133 -0
- package/ai/examples/blocks/Sidebar1.tsx +34 -0
- package/ai/examples/blocks/Sidebar2.tsx +17 -0
- package/ai/examples/blocks/Sidebar4.tsx +92 -0
- package/ai/examples/blocks/Sidebar5.tsx +73 -0
- package/ai/examples/blocks/Streaming1.tsx +353 -0
- package/ai/examples/blocks/Table1.tsx +303 -0
- package/ai/examples/blocks/Waitlist1.tsx +141 -0
- package/ai/examples/blocks/content/chat1content.ts +65 -0
- package/ai/examples/blocks/content/resources.ts +5 -0
- package/ai/examples/blocks/content/roadmap1content.ts +51 -0
- package/ai/examples/blocks/manifest.json +191 -0
- package/ai/examples/dashboard.tsx +150 -0
- package/ai/examples/marketing-hero.tsx +152 -0
- package/ai/examples/pricing.tsx +219 -0
- package/ai/examples/settings.tsx +140 -0
- package/ai/gotchas.json +85 -0
- package/ai/manifest.json +21 -0
- package/ai/rules.compact.md +73 -0
- package/ai/spec.json +2679 -2701
- package/ai/tasks/auth.json +23 -0
- package/ai/tasks/chat.json +28 -0
- package/ai/tasks/dashboard.json +39 -0
- package/ai/tasks/index.json +12 -0
- package/ai/tasks/marketing-hero.json +38 -0
- package/ai/tasks/pricing.json +42 -0
- package/ai/tasks/roadmap.json +22 -0
- package/ai/tasks/settings.json +34 -0
- package/dist/ai/catalog.json +1650 -0
- package/dist/ai/catalog.seed.json +411 -0
- package/dist/ai/components/Accordion.json +136 -0
- package/dist/ai/components/AccordionGroup.json +128 -0
- package/dist/ai/components/Animation.json +146 -0
- package/dist/ai/components/Arrow.json +128 -0
- package/dist/ai/components/AutoScroll.json +130 -0
- package/dist/ai/components/Avatar.json +133 -0
- package/dist/ai/components/AvatarGroup.json +129 -0
- package/dist/ai/components/Background.json +131 -0
- package/dist/ai/components/Badge.json +132 -0
- package/dist/ai/components/Banner.json +122 -0
- package/dist/ai/components/BarChart.json +123 -0
- package/dist/ai/components/BlobFx.json +125 -0
- package/dist/ai/components/BlockQuote.json +132 -0
- package/dist/ai/components/Button.json +26 -0
- package/dist/ai/components/Card.json +129 -0
- package/dist/ai/components/Carousel.json +134 -0
- package/dist/ai/components/CelebrationFx.json +132 -0
- package/dist/ai/components/ChartHeader.json +130 -0
- package/dist/ai/components/ChartStatus.json +12 -0
- package/dist/ai/components/Checkbox.json +13 -0
- package/dist/ai/components/Chip.json +132 -0
- package/dist/ai/components/CodeBlock.json +122 -0
- package/dist/ai/components/ColorInput.json +13 -0
- package/dist/ai/components/Column.json +128 -0
- package/dist/ai/components/CompareImage.json +126 -0
- package/dist/ai/components/ContextMenu.json +22 -0
- package/dist/ai/components/CountFx.json +82 -0
- package/dist/ai/components/CountdownFx.json +11 -0
- package/dist/ai/components/Cursor.json +9 -0
- package/dist/ai/components/CursorCard.json +128 -0
- package/dist/ai/components/DataTooltip.json +15 -0
- package/dist/ai/components/DateInput.json +21 -0
- package/dist/ai/components/DatePicker.json +143 -0
- package/dist/ai/components/DateRangeInput.json +18 -0
- package/dist/ai/components/DateRangePicker.json +129 -0
- package/dist/ai/components/Dialog.json +134 -0
- package/dist/ai/components/DialogProvider.json +8 -0
- package/dist/ai/components/Dropdown.json +128 -0
- package/dist/ai/components/DropdownWrapper.json +28 -0
- package/dist/ai/components/EmojiPicker.json +129 -0
- package/dist/ai/components/EmojiPickerDropdown.json +13 -0
- package/dist/ai/components/Fade.json +130 -0
- package/dist/ai/components/FadingLettersFx.json +77 -0
- package/dist/ai/components/Feedback.json +132 -0
- package/dist/ai/components/Flex.json +125 -0
- package/dist/ai/components/FlipFx.json +133 -0
- package/dist/ai/components/GlitchFx.json +128 -0
- package/dist/ai/components/Grid.json +121 -0
- package/dist/ai/components/Heading.json +75 -0
- package/dist/ai/components/HeadingLink.json +127 -0
- package/dist/ai/components/HeadingNav.json +124 -0
- package/dist/ai/components/HoloFx.json +128 -0
- package/dist/ai/components/Hover.json +130 -0
- package/dist/ai/components/HoverCard.json +122 -0
- package/dist/ai/components/Icon.json +132 -0
- package/dist/ai/components/IconButton.json +22 -0
- package/dist/ai/components/InfiniteScroll.json +130 -0
- package/dist/ai/components/InlineCode.json +126 -0
- package/dist/ai/components/Input.json +24 -0
- package/dist/ai/components/InteractiveDetails.json +14 -0
- package/dist/ai/components/Kbar.json +10 -0
- package/dist/ai/components/Kbd.json +127 -0
- package/dist/ai/components/Legend.json +14 -0
- package/dist/ai/components/LetterFx.json +14 -0
- package/dist/ai/components/Line.json +125 -0
- package/dist/ai/components/LineBarChart.json +123 -0
- package/dist/ai/components/LineChart.json +123 -0
- package/dist/ai/components/LinearGauge.json +130 -0
- package/dist/ai/components/LinearGradient.json +15 -0
- package/dist/ai/components/List.json +127 -0
- package/dist/ai/components/ListItem.json +77 -0
- package/dist/ai/components/Logo.json +16 -0
- package/dist/ai/components/LogoCloud.json +124 -0
- package/dist/ai/components/Mask.json +131 -0
- package/dist/ai/components/MasonryGrid.json +132 -0
- package/dist/ai/components/MatrixFx.json +135 -0
- package/dist/ai/components/Media.json +142 -0
- package/dist/ai/components/MediaUpload.json +122 -0
- package/dist/ai/components/MegaMenu.json +125 -0
- package/dist/ai/components/MobileMegaMenu.json +125 -0
- package/dist/ai/components/Modal.json +12 -0
- package/dist/ai/components/NavIcon.json +127 -0
- package/dist/ai/components/NumberInput.json +16 -0
- package/dist/ai/components/OTPInput.json +13 -0
- package/dist/ai/components/OgCard.json +135 -0
- package/dist/ai/components/Option.json +137 -0
- package/dist/ai/components/Particle.json +135 -0
- package/dist/ai/components/PasswordInput.json +8 -0
- package/dist/ai/components/PieChart.json +123 -0
- package/dist/ai/components/ProgressBar.json +131 -0
- package/dist/ai/components/Pulse.json +129 -0
- package/dist/ai/components/RadialGauge.json +134 -0
- package/dist/ai/components/RadialGradient.json +16 -0
- package/dist/ai/components/RadioButton.json +17 -0
- package/dist/ai/components/RevealFx.json +131 -0
- package/dist/ai/components/Row.json +128 -0
- package/dist/ai/components/Schema.json +17 -0
- package/dist/ai/components/ScrollContainer.json +126 -0
- package/dist/ai/components/ScrollToTop.json +124 -0
- package/dist/ai/components/Scroller.json +128 -0
- package/dist/ai/components/SegmentedControl.json +132 -0
- package/dist/ai/components/Select.json +21 -0
- package/dist/ai/components/ShineFx.json +80 -0
- package/dist/ai/components/Skeleton.json +129 -0
- package/dist/ai/components/Slider.json +17 -0
- package/dist/ai/components/SmartLink.json +17 -0
- package/dist/ai/components/Spinner.json +127 -0
- package/dist/ai/components/SplitView.json +129 -0
- package/dist/ai/components/StatusIndicator.json +128 -0
- package/dist/ai/components/StyleOverlay.json +126 -0
- package/dist/ai/components/StylePanel.json +125 -0
- package/dist/ai/components/Swiper.json +130 -0
- package/dist/ai/components/Switch.json +20 -0
- package/dist/ai/components/Table.json +125 -0
- package/dist/ai/components/Tag.json +129 -0
- package/dist/ai/components/TagInput.json +12 -0
- package/dist/ai/components/Text.json +72 -0
- package/dist/ai/components/Textarea.json +24 -0
- package/dist/ai/components/ThemeSwitcher.json +122 -0
- package/dist/ai/components/TiltFx.json +126 -0
- package/dist/ai/components/Timeline.json +126 -0
- package/dist/ai/components/Toast.json +13 -0
- package/dist/ai/components/Toaster.json +14 -0
- package/dist/ai/components/ToggleButton.json +24 -0
- package/dist/ai/components/Tooltip.json +129 -0
- package/dist/ai/components/TypeFx.json +15 -0
- package/dist/ai/components/User.json +15 -0
- package/dist/ai/components/UserMenu.json +16 -0
- package/dist/ai/components/WeatherFx.json +133 -0
- package/dist/ai/eval-tasks.md +71 -0
- package/dist/ai/examples/blocks/manifest.json +191 -0
- package/dist/ai/gotchas.json +85 -0
- package/dist/ai/manifest.json +21 -0
- package/dist/ai/recipes.md +149 -0
- package/dist/ai/rules.compact.md +73 -0
- package/dist/ai/rules.md +217 -0
- package/dist/ai/spec.json +2680 -0
- package/dist/ai/tasks/auth.json +23 -0
- package/dist/ai/tasks/chat.json +28 -0
- package/dist/ai/tasks/dashboard.json +39 -0
- package/dist/ai/tasks/index.json +12 -0
- package/dist/ai/tasks/marketing-hero.json +38 -0
- package/dist/ai/tasks/pricing.json +42 -0
- package/dist/ai/tasks/roadmap.json +22 -0
- package/dist/ai/tasks/settings.json +34 -0
- package/dist/data/emoji-data.json +0 -18
- package/dist/package.json +13 -2
- package/package.json +139 -127
- package/LICENSE.md +0 -21
- package/next-env.d.ts +0 -5
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Checkbox, Column, IconButton, Input, Row, Text, Card, Icon, DropdownWrapper, Button, ToggleButton, CountFx } from "@once-ui-system/core";
|
|
4
|
+
import { useEffect, useMemo, useState } from "react";
|
|
5
|
+
|
|
6
|
+
type Align = "start" | "center" | "end";
|
|
7
|
+
|
|
8
|
+
export type TableColumn<T = any> = {
|
|
9
|
+
key: string;
|
|
10
|
+
title: React.ReactNode;
|
|
11
|
+
render: (item: T, index: number) => React.ReactNode;
|
|
12
|
+
align?: Align;
|
|
13
|
+
width?: number; // in grid columns (optional)
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type Table1Props<T = any> = React.ComponentProps<typeof Column> & {
|
|
17
|
+
data: T[];
|
|
18
|
+
columns: TableColumn<T>[];
|
|
19
|
+
selectable?: boolean;
|
|
20
|
+
getId?: (item: T, index: number) => string;
|
|
21
|
+
itemsPerPageOptions?: number[];
|
|
22
|
+
initialItemsPerPage?: number;
|
|
23
|
+
heading?: React.ReactNode;
|
|
24
|
+
showSearch?: boolean;
|
|
25
|
+
filterFn?: (item: T, query: string) => boolean;
|
|
26
|
+
onSelectionChange?: (ids: Set<string>) => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Table1: React.FC<Table1Props> = ({
|
|
30
|
+
data,
|
|
31
|
+
columns,
|
|
32
|
+
selectable = false,
|
|
33
|
+
getId,
|
|
34
|
+
itemsPerPageOptions = [5, 25, 50, 100],
|
|
35
|
+
initialItemsPerPage = 5,
|
|
36
|
+
heading = "Items",
|
|
37
|
+
showSearch = true,
|
|
38
|
+
filterFn,
|
|
39
|
+
onSelectionChange,
|
|
40
|
+
...flex
|
|
41
|
+
}) => {
|
|
42
|
+
|
|
43
|
+
const [itemsPerPage, setItemsPerPage] = useState(initialItemsPerPage);
|
|
44
|
+
const [search, setSearch] = useState("");
|
|
45
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
46
|
+
const [selectedItems, setSelectedItems] = useState(new Set<string>());
|
|
47
|
+
|
|
48
|
+
// Filter by search
|
|
49
|
+
const filteredContent = useMemo(() => {
|
|
50
|
+
const q = search.trim().toLowerCase();
|
|
51
|
+
if (!q) return data;
|
|
52
|
+
if (filterFn) return data.filter((item) => filterFn(item, q));
|
|
53
|
+
// Default fallback filter: stringify
|
|
54
|
+
return data.filter((item) => JSON.stringify(item).toLowerCase().includes(q));
|
|
55
|
+
}, [search, data, filterFn]);
|
|
56
|
+
|
|
57
|
+
// Pagination calculations
|
|
58
|
+
const totalitemsPerPage = Math.max(1, Math.ceil(filteredContent.length / itemsPerPage));
|
|
59
|
+
const startIndex = (currentPage - 1) * itemsPerPage;
|
|
60
|
+
const endIndex = startIndex + itemsPerPage;
|
|
61
|
+
const paginatedItems = filteredContent.slice(startIndex, endIndex);
|
|
62
|
+
|
|
63
|
+
// Reset to first page when filters or page size change
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
setCurrentPage(1);
|
|
66
|
+
}, [search, itemsPerPage]);
|
|
67
|
+
|
|
68
|
+
// Selection helpers
|
|
69
|
+
const resolveId = (item: any, index: number) => (getId ? getId(item, index) : String(index));
|
|
70
|
+
const isSelected = (id: string) => selectedItems.has(id);
|
|
71
|
+
const toggleSelect = (id: string) => {
|
|
72
|
+
setSelectedItems((prev) => {
|
|
73
|
+
const next = new Set(prev);
|
|
74
|
+
if (next.has(id)) next.delete(id); else next.add(id);
|
|
75
|
+
onSelectionChange?.(next);
|
|
76
|
+
return next;
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const currentPageIds = paginatedItems.map((i, idx) => resolveId(i, startIndex + idx));
|
|
81
|
+
const allCurrentSelected = currentPageIds.length > 0 && currentPageIds.every((id) => selectedItems.has(id));
|
|
82
|
+
const someCurrentSelected = currentPageIds.some((id) => selectedItems.has(id));
|
|
83
|
+
const toggleSelectAllCurrent = () => {
|
|
84
|
+
setSelectedItems((prev) => {
|
|
85
|
+
const next = new Set(prev);
|
|
86
|
+
if (allCurrentSelected) {
|
|
87
|
+
currentPageIds.forEach((id) => next.delete(id));
|
|
88
|
+
} else {
|
|
89
|
+
currentPageIds.forEach((id) => next.add(id));
|
|
90
|
+
}
|
|
91
|
+
onSelectionChange?.(next);
|
|
92
|
+
return next;
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<Column fillWidth radius="l" border="neutral-alpha-weak" {...flex}>
|
|
98
|
+
<Row fillWidth horizontal="between" paddingY="12" paddingRight="12" paddingLeft="24" gap="16" vertical="center" s={{direction: "column",}}>
|
|
99
|
+
<Row fillWidth gap="12" vertical="center" horizontal="between">
|
|
100
|
+
{selectable && someCurrentSelected ? (
|
|
101
|
+
<CountFx variant="label-default-m" paddingY="12" paddingLeft="8" value={selectedItems.size} effect="smooth" speed={250}>
|
|
102
|
+
<Text marginLeft="8">selected</Text>
|
|
103
|
+
</CountFx>
|
|
104
|
+
) : (
|
|
105
|
+
typeof heading === "string" ? (
|
|
106
|
+
<Text variant="label-default-m" paddingY="12" paddingLeft="8">{heading}</Text>
|
|
107
|
+
) : (
|
|
108
|
+
<Row paddingY="12" paddingLeft="8">{heading}</Row>
|
|
109
|
+
)
|
|
110
|
+
)}
|
|
111
|
+
</Row>
|
|
112
|
+
{showSearch && (
|
|
113
|
+
<Row maxWidth={16}>
|
|
114
|
+
<Input
|
|
115
|
+
height="s"
|
|
116
|
+
id="search"
|
|
117
|
+
placeholder="Search..."
|
|
118
|
+
value={search}
|
|
119
|
+
hasPrefix={<Icon name="search" size="s" onBackground="neutral-weak"/>}
|
|
120
|
+
hasSuffix={search.length > 0 && <IconButton tooltip="Clear" tooltipPosition="left" icon="close" size="s" variant="ghost" onClick={() => setSearch("")}/>}
|
|
121
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
122
|
+
/>
|
|
123
|
+
</Row>
|
|
124
|
+
)}
|
|
125
|
+
</Row>
|
|
126
|
+
<Column fillWidth overflowX="auto">
|
|
127
|
+
<Column fillWidth radius="l" border="neutral-alpha-weak" overflow="hidden">
|
|
128
|
+
<Row fillWidth gap="16" paddingX="24" paddingY="12" borderBottom="neutral-alpha-weak">
|
|
129
|
+
{selectable && (
|
|
130
|
+
<Row textVariant="label-default-s" vertical="center" gap="16">
|
|
131
|
+
<Checkbox
|
|
132
|
+
isChecked={allCurrentSelected || (someCurrentSelected && !allCurrentSelected)}
|
|
133
|
+
isIndeterminate={someCurrentSelected && !allCurrentSelected}
|
|
134
|
+
onToggle={toggleSelectAllCurrent}
|
|
135
|
+
/>
|
|
136
|
+
</Row>
|
|
137
|
+
)}
|
|
138
|
+
{columns.map((col, cIdx) => (
|
|
139
|
+
<Row
|
|
140
|
+
key={`head-${col.key}-${cIdx}`}
|
|
141
|
+
fillWidth
|
|
142
|
+
minWidth={8}
|
|
143
|
+
textVariant="label-default-s"
|
|
144
|
+
vertical="center"
|
|
145
|
+
horizontal={col.align === "end" ? "end" : col.align === "center" ? "center" : "start"}
|
|
146
|
+
paddingRight={col.align === "end" ? "8" : undefined}
|
|
147
|
+
>
|
|
148
|
+
{col.title}
|
|
149
|
+
</Row>
|
|
150
|
+
))}
|
|
151
|
+
</Row>
|
|
152
|
+
<Column fillWidth overflow="auto">
|
|
153
|
+
<Column fitWidth style={{minWidth: "100%"}}>
|
|
154
|
+
{paginatedItems.map((item, index) => {
|
|
155
|
+
const globalIndex = startIndex + index;
|
|
156
|
+
const id = resolveId(item, globalIndex);
|
|
157
|
+
return (
|
|
158
|
+
<Row key={`row-${id}`} gap="16" fillWidth borderBottom={index === paginatedItems.length - 1 ? "transparent" : "neutral-alpha-weak"}>
|
|
159
|
+
<Card fillWidth paddingY="8" paddingX="24" gap="16" vertical="center" border="transparent" background="transparent">
|
|
160
|
+
{selectable && (
|
|
161
|
+
<Row vertical="center" gap="16">
|
|
162
|
+
<Checkbox
|
|
163
|
+
key={`cb-${id}`}
|
|
164
|
+
isChecked={isSelected(id)}
|
|
165
|
+
onToggle={() => toggleSelect(id)}
|
|
166
|
+
/>
|
|
167
|
+
</Row>
|
|
168
|
+
)}
|
|
169
|
+
{columns.map((col, cIdx) => (
|
|
170
|
+
<Row
|
|
171
|
+
key={`cell-${id}-${col.key}-${cIdx}`}
|
|
172
|
+
fillWidth
|
|
173
|
+
minWidth={8}
|
|
174
|
+
horizontal={col.align === "end" ? "end" : col.align === "center" ? "center" : "start"}
|
|
175
|
+
paddingRight={col.align === "end" ? "8" : undefined}
|
|
176
|
+
>
|
|
177
|
+
{col.render(item, globalIndex)}
|
|
178
|
+
</Row>
|
|
179
|
+
))}
|
|
180
|
+
</Card>
|
|
181
|
+
</Row>
|
|
182
|
+
);
|
|
183
|
+
})}
|
|
184
|
+
</Column>
|
|
185
|
+
{paginatedItems.length === 0 && (
|
|
186
|
+
<Column fill center padding="l" gap="24">
|
|
187
|
+
<Text variant="label-default-s" onBackground="neutral-weak">No results{search ? ` for "${search}"` : ""}</Text>
|
|
188
|
+
{showSearch && <Button size="s" variant="secondary" onClick={() => setSearch("")}>Clear search</Button>}
|
|
189
|
+
</Column>
|
|
190
|
+
)}
|
|
191
|
+
</Column>
|
|
192
|
+
</Column>
|
|
193
|
+
</Column>
|
|
194
|
+
|
|
195
|
+
<Row fillWidth horizontal="between" vertical="center" paddingX="24">
|
|
196
|
+
<Row fillWidth paddingY="12" gap="12" vertical="center">
|
|
197
|
+
<IconButton icon="chevronLeft" size="s" variant="ghost" onClick={() => setCurrentPage(currentPage - 1)} disabled={currentPage === 1}/>
|
|
198
|
+
<Row gap="4" vertical="center">
|
|
199
|
+
{/* Page 1 */}
|
|
200
|
+
<IconButton
|
|
201
|
+
key={`page-1`}
|
|
202
|
+
size="m"
|
|
203
|
+
variant={currentPage === 1 ? "primary" : "secondary"}
|
|
204
|
+
onClick={() => setCurrentPage(1)}
|
|
205
|
+
>
|
|
206
|
+
<Text variant="label-strong-s">1</Text>
|
|
207
|
+
</IconButton>
|
|
208
|
+
|
|
209
|
+
{/* Page 2 (if exists) */}
|
|
210
|
+
{totalitemsPerPage >= 2 && (
|
|
211
|
+
<IconButton
|
|
212
|
+
key={`page-2`}
|
|
213
|
+
size="m"
|
|
214
|
+
variant={currentPage === 2 ? "primary" : "secondary"}
|
|
215
|
+
onClick={() => setCurrentPage(2)}
|
|
216
|
+
>
|
|
217
|
+
<Text variant="label-strong-s">2</Text>
|
|
218
|
+
</IconButton>
|
|
219
|
+
)}
|
|
220
|
+
|
|
221
|
+
{/* More dropdown for middle pages when > 4 total pages */}
|
|
222
|
+
{totalitemsPerPage > 4 && (
|
|
223
|
+
<DropdownWrapper
|
|
224
|
+
placement="bottom-end"
|
|
225
|
+
trigger={<IconButton icon="moreHorizontal" size="s" variant="ghost"/>}
|
|
226
|
+
dropdown={
|
|
227
|
+
<Column padding="4" gap="2" width={4}>
|
|
228
|
+
{Array.from({ length: totalitemsPerPage - 4 }, (_, i) => i + 3).map((pageNum) => (
|
|
229
|
+
<ToggleButton
|
|
230
|
+
key={`page-middle-${pageNum}`}
|
|
231
|
+
fillWidth
|
|
232
|
+
horizontal="start"
|
|
233
|
+
selected={currentPage === pageNum}
|
|
234
|
+
onClick={() => setCurrentPage(pageNum)}
|
|
235
|
+
>
|
|
236
|
+
{pageNum}
|
|
237
|
+
</ToggleButton>
|
|
238
|
+
))}
|
|
239
|
+
</Column>
|
|
240
|
+
}
|
|
241
|
+
/>
|
|
242
|
+
)}
|
|
243
|
+
|
|
244
|
+
{/* Last-1 and Last */}
|
|
245
|
+
{totalitemsPerPage >= 4 ? (
|
|
246
|
+
<>
|
|
247
|
+
<IconButton
|
|
248
|
+
key={`page-${totalitemsPerPage - 1}`}
|
|
249
|
+
size="m"
|
|
250
|
+
variant={currentPage === totalitemsPerPage - 1 ? "primary" : "secondary"}
|
|
251
|
+
onClick={() => setCurrentPage(totalitemsPerPage - 1)}
|
|
252
|
+
>
|
|
253
|
+
<Text variant="label-strong-s">{totalitemsPerPage - 1}</Text>
|
|
254
|
+
</IconButton>
|
|
255
|
+
<IconButton
|
|
256
|
+
key={`page-${totalitemsPerPage}`}
|
|
257
|
+
size="m"
|
|
258
|
+
variant={currentPage === totalitemsPerPage ? "primary" : "secondary"}
|
|
259
|
+
onClick={() => setCurrentPage(totalitemsPerPage)}
|
|
260
|
+
>
|
|
261
|
+
<Text variant="label-strong-s">{totalitemsPerPage}</Text>
|
|
262
|
+
</IconButton>
|
|
263
|
+
</>
|
|
264
|
+
) : totalitemsPerPage === 3 ? (
|
|
265
|
+
<IconButton
|
|
266
|
+
key={`page-3`}
|
|
267
|
+
size="m"
|
|
268
|
+
variant={currentPage === 3 ? "primary" : "secondary"}
|
|
269
|
+
onClick={() => setCurrentPage(3)}
|
|
270
|
+
>
|
|
271
|
+
<Text variant="label-strong-s">3</Text>
|
|
272
|
+
</IconButton>
|
|
273
|
+
) : null}
|
|
274
|
+
</Row>
|
|
275
|
+
<IconButton icon="chevronRight" size="s" variant="ghost" onClick={() => setCurrentPage(currentPage + 1)} disabled={currentPage === totalitemsPerPage}/>
|
|
276
|
+
</Row>
|
|
277
|
+
|
|
278
|
+
<DropdownWrapper
|
|
279
|
+
placement="bottom-end"
|
|
280
|
+
trigger={
|
|
281
|
+
<Button size="s" variant="secondary" prefixIcon="chevronDown">
|
|
282
|
+
<Text variant="label-strong-s">{itemsPerPage}</Text>
|
|
283
|
+
</Button>
|
|
284
|
+
}
|
|
285
|
+
dropdown={
|
|
286
|
+
<Column padding="4" gap="2" width={4}>
|
|
287
|
+
{itemsPerPageOptions.map((option) => (
|
|
288
|
+
<ToggleButton
|
|
289
|
+
key={option}
|
|
290
|
+
fillWidth
|
|
291
|
+
horizontal="start"
|
|
292
|
+
onClick={() => setItemsPerPage(option)}
|
|
293
|
+
>
|
|
294
|
+
{option}
|
|
295
|
+
</ToggleButton>
|
|
296
|
+
))}
|
|
297
|
+
</Column>
|
|
298
|
+
}
|
|
299
|
+
/>
|
|
300
|
+
</Row>
|
|
301
|
+
</Column>
|
|
302
|
+
);
|
|
303
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Row,
|
|
5
|
+
Column,
|
|
6
|
+
Badge,
|
|
7
|
+
Heading,
|
|
8
|
+
Input,
|
|
9
|
+
IconButton,
|
|
10
|
+
AvatarGroup,
|
|
11
|
+
CountFx,
|
|
12
|
+
Text,
|
|
13
|
+
Logo,
|
|
14
|
+
RevealFx,
|
|
15
|
+
Line,
|
|
16
|
+
} from "@once-ui-system/core";
|
|
17
|
+
import { Background6 } from "./Background6";
|
|
18
|
+
import { useEffect, useState } from "react";
|
|
19
|
+
|
|
20
|
+
export const Waitlist1 = () => {
|
|
21
|
+
const [email, setEmail] = useState("");
|
|
22
|
+
const [subscribers, setSubscribers] = useState(0);
|
|
23
|
+
const [subscribed, setSubscribed] = useState(false);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
setSubscribers(1337);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const validateEmail = (email: any) => {
|
|
30
|
+
if (!email) return null;
|
|
31
|
+
|
|
32
|
+
const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
|
|
33
|
+
if (!emailRegex.test(email)) {
|
|
34
|
+
return "Please enter a valid email address";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const subscribe = () => {
|
|
41
|
+
if (validateEmail(email)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
setSubscribed(true);
|
|
46
|
+
setSubscribers(subscribers + 1);
|
|
47
|
+
setEmail("");
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Row fillWidth center padding="l" minHeight="100%"
|
|
52
|
+
cursor={
|
|
53
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
54
|
+
<g>
|
|
55
|
+
<path d="M7.89235 19.7113L3.33378 3.71982C3.0984 2.89409 3.95602 2.18106 4.73584 2.55413L19.8385 9.7792C20.6416 10.1634 20.5812 11.3159 19.7425 11.6131L13.5312 13.8139C13.3056 13.8938 13.1164 14.0511 12.9978 14.2574L9.73178 19.9361C9.29078 20.7029 8.13473 20.5616 7.89235 19.7113Z" fill="#15D9EF"/>
|
|
56
|
+
<path d="M2.85075 3.8544C2.49768 2.61583 3.78362 1.54674 4.95335 2.10628L20.0564 9.3314C21.2607 9.90776 21.1699 11.6359 19.9119 12.0816L13.7012 14.2825C13.5885 14.3224 13.4939 14.4012 13.4346 14.5041L10.1679 20.1829C9.50645 21.3329 7.7731 21.1214 7.40931 19.8463L2.85075 3.8544Z" stroke="#15AAEF"/>
|
|
57
|
+
</g>
|
|
58
|
+
</svg>
|
|
59
|
+
}>
|
|
60
|
+
<Background6 />
|
|
61
|
+
<Column horizontal="center" gap="40" maxWidth="xs">
|
|
62
|
+
<RevealFx horizontal="center">
|
|
63
|
+
<Badge paddingX="24" background="brand-alpha-weak" pointerEvents="none" textVariant="label-default-s" onBackground="brand-medium">
|
|
64
|
+
<Logo size="s" dark icon="/trademarks/icon-dark.svg" wordmark="/trademarks/wordmark-dark.svg"/>
|
|
65
|
+
<Logo size="s" light icon="/trademarks/icon-light.svg" wordmark="/trademarks/wordmark-light.svg"/>
|
|
66
|
+
<Line vert marginX="16" height="20" background="brand-alpha-medium"/>
|
|
67
|
+
<Text paddingX="4">Arriving soon</Text>
|
|
68
|
+
</Badge>
|
|
69
|
+
</RevealFx>
|
|
70
|
+
<Column horizontal="center" align="center" gap="24">
|
|
71
|
+
<RevealFx horizontal="center" delay={0.4}>
|
|
72
|
+
<Heading variant="display-strong-xl" onBackground="neutral-strong">
|
|
73
|
+
The all-in-one course platform
|
|
74
|
+
</Heading>
|
|
75
|
+
</RevealFx>
|
|
76
|
+
<RevealFx horizontal="center" delay={0.6}>
|
|
77
|
+
<Text onBackground="neutral-medium" variant="heading-default-xl">
|
|
78
|
+
Launch and sell your courses with ease. We handle enrollment, payments and analytics. You focus on creating.
|
|
79
|
+
</Text>
|
|
80
|
+
</RevealFx>
|
|
81
|
+
</Column>
|
|
82
|
+
<RevealFx horizontal="center" delay={0.8}>
|
|
83
|
+
<AvatarGroup
|
|
84
|
+
reverse
|
|
85
|
+
size="m"
|
|
86
|
+
avatars={[
|
|
87
|
+
{ src: "/images/creators/lorant.jpg" },
|
|
88
|
+
{ src: "/images/creators/justin.jpg" },
|
|
89
|
+
{ src: "/images/creators/light.jpg" },
|
|
90
|
+
{ src: "/images/creators/texz.jpg" },
|
|
91
|
+
{ src: "/images/creators/suhaib.jpg" },
|
|
92
|
+
]}
|
|
93
|
+
/>
|
|
94
|
+
</RevealFx>
|
|
95
|
+
|
|
96
|
+
<Column maxWidth={24} horizontal="center" align="center">
|
|
97
|
+
{subscribed ? (
|
|
98
|
+
<RevealFx key="waitlist" direction="column" horizontal="center" paddingX="64" paddingY="24" radius="l" background="brand-alpha-weak" border="brand-alpha-weak" gap="20">
|
|
99
|
+
<Text variant="label-default-m" onBackground="brand-medium">
|
|
100
|
+
You're on the list!
|
|
101
|
+
</Text>
|
|
102
|
+
<Row vertical="center" textVariant="heading-strong-l" gap="16">
|
|
103
|
+
That makes it <CountFx
|
|
104
|
+
value={subscribers}
|
|
105
|
+
variant="code-default-xl"
|
|
106
|
+
speed={4000}
|
|
107
|
+
effect="smooth"
|
|
108
|
+
easing="ease-out"
|
|
109
|
+
/>
|
|
110
|
+
</Row>
|
|
111
|
+
</RevealFx>
|
|
112
|
+
) : (
|
|
113
|
+
<RevealFx key="subscribed" direction="column" horizontal="center" delay={1} gap="16" data-border="rounded">
|
|
114
|
+
<Input
|
|
115
|
+
id="email"
|
|
116
|
+
placeholder="Enter email"
|
|
117
|
+
value={email}
|
|
118
|
+
validate={(value) => validateEmail(value as string)}
|
|
119
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
120
|
+
hasSuffix={
|
|
121
|
+
<IconButton size="l" style={{marginRight: "-0.5rem"}} icon="send" onClick={() => subscribe()}/>
|
|
122
|
+
}
|
|
123
|
+
/>
|
|
124
|
+
<Row vertical="center" gap="4" textVariant="label-default-s">
|
|
125
|
+
<Text>Join</Text>
|
|
126
|
+
<CountFx
|
|
127
|
+
value={subscribers}
|
|
128
|
+
variant="code-default-s"
|
|
129
|
+
speed={1000}
|
|
130
|
+
effect="smooth"
|
|
131
|
+
easing="ease-out"
|
|
132
|
+
/>
|
|
133
|
+
<Text>others</Text>
|
|
134
|
+
</Row>
|
|
135
|
+
</RevealFx>
|
|
136
|
+
)}
|
|
137
|
+
</Column>
|
|
138
|
+
</Column>
|
|
139
|
+
</Row>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const sidebar = [
|
|
2
|
+
{
|
|
3
|
+
items: [
|
|
4
|
+
{ label: "Members" },
|
|
5
|
+
{ label: "Files" },
|
|
6
|
+
{ label: "Pins" },
|
|
7
|
+
],
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
title: "Channels",
|
|
11
|
+
rooms: [
|
|
12
|
+
{ label: "👋 ┃ intro" },
|
|
13
|
+
{ label: "general" },
|
|
14
|
+
{ label: "design-system" },
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
export const chatMembers = [
|
|
20
|
+
{
|
|
21
|
+
title: "Online",
|
|
22
|
+
members: [
|
|
23
|
+
{
|
|
24
|
+
name: "Jane Wong",
|
|
25
|
+
status: "Active now",
|
|
26
|
+
bio: "Design engineer",
|
|
27
|
+
avatar: "/images/creators/lorant.jpg",
|
|
28
|
+
group: "Online",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "Lorant K.",
|
|
32
|
+
status: "Coding something...",
|
|
33
|
+
bio: "Building Once UI",
|
|
34
|
+
avatar: "/images/creators/lorant.jpg",
|
|
35
|
+
group: "Online",
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
export const chatMessages = [
|
|
42
|
+
{
|
|
43
|
+
author: { name: "Jane Wong", avatar: "/images/creators/lorant.jpg" },
|
|
44
|
+
postedAt: new Date("2025-01-18T09:38:00"),
|
|
45
|
+
message: "Can you sanity-check the chat density before we ship?",
|
|
46
|
+
attachments: [],
|
|
47
|
+
reactions: [{ emoji: "👍", count: 2, reacted: true }],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
author: { name: "Lorant K.", avatar: "/images/creators/lorant.jpg" },
|
|
51
|
+
postedAt: new Date("2025-01-18T09:40:00"),
|
|
52
|
+
message: "On it — Discord sidebar + Linear message rhythm.",
|
|
53
|
+
attachments: [
|
|
54
|
+
{ media: "/images/blocks/vibe-coding-dark.jpg" },
|
|
55
|
+
],
|
|
56
|
+
reactions: [],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
author: { name: "Jane Wong", avatar: "/images/creators/lorant.jpg" },
|
|
60
|
+
postedAt: new Date("2025-01-18T09:42:00"),
|
|
61
|
+
message: "",
|
|
62
|
+
attachments: [{ media: "https://docs.once-ui.com" }],
|
|
63
|
+
reactions: [{ emoji: "🔗", count: 1, reacted: false }],
|
|
64
|
+
},
|
|
65
|
+
];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const task = {
|
|
2
|
+
planned: { label: "Planned", color: "neutral" },
|
|
3
|
+
progress: { label: "In progress", color: "brand" },
|
|
4
|
+
done: { label: "Done", color: "success" },
|
|
5
|
+
blocked: { label: "Blocked", color: "danger" },
|
|
6
|
+
} as const;
|
|
7
|
+
|
|
8
|
+
export const roadmap = [
|
|
9
|
+
{
|
|
10
|
+
product: "Once UI Core",
|
|
11
|
+
brand: "brand",
|
|
12
|
+
columns: [
|
|
13
|
+
{
|
|
14
|
+
title: "Planned",
|
|
15
|
+
tasks: [
|
|
16
|
+
{
|
|
17
|
+
title: "Agent-first MCP tools",
|
|
18
|
+
description: "resolve, get_component, validate",
|
|
19
|
+
type: "progress",
|
|
20
|
+
user: { name: "Lorant", avatar: "/images/creators/lorant.jpg" },
|
|
21
|
+
href: "#",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
title: "Expanded block references",
|
|
25
|
+
description: "Pro block gold examples in harness",
|
|
26
|
+
type: "planned",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: "In progress",
|
|
32
|
+
tasks: [
|
|
33
|
+
{
|
|
34
|
+
title: "Codegen harness Phase 1",
|
|
35
|
+
type: "progress",
|
|
36
|
+
user: { name: "Lorant" },
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: "Done",
|
|
42
|
+
tasks: [
|
|
43
|
+
{
|
|
44
|
+
title: "Component catalog slices",
|
|
45
|
+
type: "done",
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
];
|