@stacksjs/defaults 0.70.54
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/LICENSE.md +21 -0
- package/README.md +2 -0
- package/package.json +20 -0
- package/resources/assets/fonts/013717e9.woff +0 -0
- package/resources/assets/fonts/03355817.woff2 +0 -0
- package/resources/assets/fonts/0380de7e.woff2 +0 -0
- package/resources/assets/fonts/0ba5d32a.woff +0 -0
- package/resources/assets/fonts/0bd57ddf.woff2 +0 -0
- package/resources/assets/fonts/19de0a60.woff2 +0 -0
- package/resources/assets/fonts/20b87e84.woff +0 -0
- package/resources/assets/fonts/4bbc67e1.woff +0 -0
- package/resources/assets/fonts/576fb0d7.woff +0 -0
- package/resources/assets/fonts/5ea10ee5.woff2 +0 -0
- package/resources/assets/fonts/6413fc0a.woff +0 -0
- package/resources/assets/fonts/72c114cf.woff +0 -0
- package/resources/assets/fonts/73c57e73.woff2 +0 -0
- package/resources/assets/fonts/813dca6c.woff +0 -0
- package/resources/assets/fonts/8a9b0995.woff2 +0 -0
- package/resources/assets/fonts/90b4832f.woff +0 -0
- package/resources/assets/fonts/9394ab85.woff2 +0 -0
- package/resources/assets/fonts/9b3c7d7f.woff2 +0 -0
- package/resources/assets/fonts/Monaco.ttf +0 -0
- package/resources/assets/fonts/b1b36d74.woff +0 -0
- package/resources/assets/fonts/b5d74798.woff2 +0 -0
- package/resources/assets/fonts/b9f81a4d.woff +0 -0
- package/resources/assets/fonts/c9784008.woff2 +0 -0
- package/resources/assets/fonts/cf692227.woff +0 -0
- package/resources/assets/fonts/d1c6ab51.woff2 +0 -0
- package/resources/assets/fonts/e2eb62fc.woff +0 -0
- package/resources/assets/fonts/fe21f8d8.woff2 +0 -0
- package/resources/assets/fonts/nps/CampmateScript-Regular.woff2 +0 -0
- package/resources/assets/fonts/nps/NPS_2026-variable.woff2 +0 -0
- package/resources/assets/fonts/nps/RedwoodSerif-Regular.woff2 +0 -0
- package/resources/assets/fonts/nps/SequoiaSans-Regular.woff2 +0 -0
- package/resources/assets/fonts/nps/Switchback-Regular.woff2 +0 -0
- package/resources/assets/images/app-icon.png +0 -0
- package/resources/assets/images/bg-img.png +0 -0
- package/resources/assets/images/park-ridge.svg +15 -0
- package/resources/assets/images/topography.svg +1 -0
- package/resources/assets/scripts/main.ts +2153 -0
- package/resources/assets/styles/README.md +19 -0
- package/resources/assets/styles/docs/main.css +1 -0
- package/resources/assets/styles/docs/overrides.css +1 -0
- package/resources/assets/styles/docs/vars.css +8 -0
- package/resources/assets/styles/main.css +1419 -0
- package/resources/components/Button.stx +70 -0
- package/resources/components/Buttons/BaseButton.stx +39 -0
- package/resources/components/Buttons/Counter.stx +28 -0
- package/resources/components/Buttons/ToggleDark.stx +11 -0
- package/resources/components/Container.stx +10 -0
- package/resources/components/Dashboard/.gitkeep +0 -0
- package/resources/components/Dashboard/Auth/ForgotPassword.stx +127 -0
- package/resources/components/Dashboard/Auth/Login.stx +212 -0
- package/resources/components/Dashboard/Auth/Register.stx +306 -0
- package/resources/components/Dashboard/Avatar.stx +123 -0
- package/resources/components/Dashboard/Billing/ActivePlan.stx +57 -0
- package/resources/components/Dashboard/Billing/CardBrands.stx +32 -0
- package/resources/components/Dashboard/Billing/CardForm.stx +34 -0
- package/resources/components/Dashboard/Billing/OneTimePayment.stx +28 -0
- package/resources/components/Dashboard/Billing/PaymentForm.stx +33 -0
- package/resources/components/Dashboard/Billing/PaymentMethod.stx +66 -0
- package/resources/components/Dashboard/Billing/PaymentMethodList.stx +52 -0
- package/resources/components/Dashboard/Billing/Plans.stx +136 -0
- package/resources/components/Dashboard/Buttons/AppButton.stx +48 -0
- package/resources/components/Dashboard/Buttons/IconButton.stx +20 -0
- package/resources/components/Dashboard/Card.stx +78 -0
- package/resources/components/Dashboard/Chart.stx +75 -0
- package/resources/components/Dashboard/CodeEditor.stx +41 -0
- package/resources/components/Dashboard/Commerce/BulkActionBar.stx +70 -0
- package/resources/components/Dashboard/Commerce/CategoriesTable.stx +133 -0
- package/resources/components/Dashboard/Commerce/CouponsTable.stx +161 -0
- package/resources/components/Dashboard/Commerce/CustomersTable.stx +142 -0
- package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +80 -0
- package/resources/components/Dashboard/Commerce/Delivery/DigitalDeliveryTable.stx +85 -0
- package/resources/components/Dashboard/Commerce/Delivery/DriversTable.stx +99 -0
- package/resources/components/Dashboard/Commerce/Delivery/LicenseKeysTable.stx +92 -0
- package/resources/components/Dashboard/Commerce/Delivery/LicenseTemplatesTable.stx +88 -0
- package/resources/components/Dashboard/Commerce/Delivery/Pagination.stx +122 -0
- package/resources/components/Dashboard/Commerce/Delivery/SearchFilter.stx +23 -0
- package/resources/components/Dashboard/Commerce/Delivery/ShippingMethodsTable.stx +80 -0
- package/resources/components/Dashboard/Commerce/Delivery/ShippingRatesTable.stx +59 -0
- package/resources/components/Dashboard/Commerce/Delivery/ShippingZonesTable.stx +71 -0
- package/resources/components/Dashboard/Commerce/Delivery/TabNavigation.stx +36 -0
- package/resources/components/Dashboard/Commerce/Forms/CouponsForm.stx +191 -0
- package/resources/components/Dashboard/Commerce/OrdersTable.stx +131 -0
- package/resources/components/Dashboard/Commerce/ProductsTable.stx +170 -0
- package/resources/components/Dashboard/CreateRecordModal.stx +363 -0
- package/resources/components/Dashboard/DashboardLayout.stx +155 -0
- package/resources/components/Dashboard/Deployments/ActivityFeed.stx +54 -0
- package/resources/components/Dashboard/Deployments/DeployScript.stx +23 -0
- package/resources/components/Dashboard/Deployments/DeploymentHistory.stx +97 -0
- package/resources/components/Dashboard/Deployments/DeploymentList.stx +94 -0
- package/resources/components/Dashboard/Deployments/LiveTerminalOutput.stx +18 -0
- package/resources/components/Dashboard/Elements/Dropdown.stx +57 -0
- package/resources/components/Dashboard/Email/EmailActivityChart.stx +111 -0
- package/resources/components/Dashboard/Email/EmailCompose.stx +72 -0
- package/resources/components/Dashboard/Email/EmailDetail.stx +105 -0
- package/resources/components/Dashboard/Email/EmailList.stx +117 -0
- package/resources/components/Dashboard/Email/EmailSearch.stx +40 -0
- package/resources/components/Dashboard/Email/EmailSidebar.stx +133 -0
- package/resources/components/Dashboard/GlobalSearch.stx +124 -0
- package/resources/components/Dashboard/MobileSidebar.stx +47 -0
- package/resources/components/Dashboard/Modals/BaseModal.stx +50 -0
- package/resources/components/Dashboard/Modals/Popups/Alert.stx +112 -0
- package/resources/components/Dashboard/Modals/Popups/Toast.stx +70 -0
- package/resources/components/Dashboard/Modals/ToastWrapper.stx +35 -0
- package/resources/components/Dashboard/Monitoring/ErrorDetailModal.stx +228 -0
- package/resources/components/Dashboard/Monitoring/ErrorsTable.stx +184 -0
- package/resources/components/Dashboard/Navbar.stx +194 -0
- package/resources/components/Dashboard/NavbarModern.stx +188 -0
- package/resources/components/Dashboard/NotificationErrorModal.stx +105 -0
- package/resources/components/Dashboard/NotificationStatusBadge.stx +20 -0
- package/resources/components/Dashboard/Pagination.stx +90 -0
- package/resources/components/Dashboard/Queue/QueueTable.stx +127 -0
- package/resources/components/Dashboard/Settings/Forms/AIForm.stx +126 -0
- package/resources/components/Dashboard/Settings/Forms/AnalyticsForm.stx +52 -0
- package/resources/components/Dashboard/Settings/Forms/AppForm.stx +157 -0
- package/resources/components/Dashboard/Settings/Forms/CLIForm.stx +66 -0
- package/resources/components/Dashboard/Settings/Forms/CacheForm.stx +253 -0
- package/resources/components/Dashboard/Settings/Forms/CloudForm.stx +441 -0
- package/resources/components/Dashboard/Settings/Forms/DNSForm.stx +307 -0
- package/resources/components/Dashboard/Settings/Forms/DatabaseForm.stx +168 -0
- package/resources/components/Dashboard/Settings/Forms/EmailForm.stx +100 -0
- package/resources/components/Dashboard/Settings/Forms/FileSystemForm.stx +259 -0
- package/resources/components/Dashboard/Settings/Forms/HashingForm.stx +119 -0
- package/resources/components/Dashboard/Settings/Forms/LibraryForm.stx +389 -0
- package/resources/components/Dashboard/Settings/Forms/QueueForm.stx +219 -0
- package/resources/components/Dashboard/Settings/Forms/SearchEngineForm.stx +48 -0
- package/resources/components/Dashboard/Settings/Forms/SecurityForm.stx +143 -0
- package/resources/components/Dashboard/Settings/Forms/ServicesForm.stx +194 -0
- package/resources/components/Dashboard/Settings/Forms/StorageForm.stx +191 -0
- package/resources/components/Dashboard/Settings/Forms/TeamsForm.stx +33 -0
- package/resources/components/Dashboard/Settings/SettingsFormManager.stx +181 -0
- package/resources/components/Dashboard/SettingsHeader.stx +88 -0
- package/resources/components/Dashboard/SettingsSidebar.stx +234 -0
- package/resources/components/Dashboard/Sidebar.stx +23 -0
- package/resources/components/Dashboard/SidebarModern.stx +249 -0
- package/resources/components/Dashboard/Skeleton/LoadingCard.stx +15 -0
- package/resources/components/Dashboard/Skeleton/LoadingDetails.stx +26 -0
- package/resources/components/Dashboard/Table.stx +82 -0
- package/resources/components/Dashboard/TerminalContainer.stx +97 -0
- package/resources/components/Dashboard/Tooltip.stx +166 -0
- package/resources/components/Dashboard/Transaction/index.stx +88 -0
- package/resources/components/Dashboard/UI/ActivityTable.stx +54 -0
- package/resources/components/Dashboard/UI/Avatar.stx +102 -0
- package/resources/components/Dashboard/UI/Badge.stx +66 -0
- package/resources/components/Dashboard/UI/Button.stx +73 -0
- package/resources/components/Dashboard/UI/Card.stx +51 -0
- package/resources/components/Dashboard/UI/ChartCard.stx +36 -0
- package/resources/components/Dashboard/UI/Checkbox.stx +74 -0
- package/resources/components/Dashboard/UI/ConfirmDialog.stx +74 -0
- package/resources/components/Dashboard/UI/DataTable.stx +45 -0
- package/resources/components/Dashboard/UI/Dropdown.stx +72 -0
- package/resources/components/Dashboard/UI/DropdownItem.stx +80 -0
- package/resources/components/Dashboard/UI/EmptyState.stx +50 -0
- package/resources/components/Dashboard/UI/FilterBar.stx +48 -0
- package/resources/components/Dashboard/UI/Input.stx +77 -0
- package/resources/components/Dashboard/UI/Modal.stx +75 -0
- package/resources/components/Dashboard/UI/PageHeader.stx +69 -0
- package/resources/components/Dashboard/UI/PageLayout.stx +84 -0
- package/resources/components/Dashboard/UI/Pagination.stx +126 -0
- package/resources/components/Dashboard/UI/QuickLinks.stx +31 -0
- package/resources/components/Dashboard/UI/RouterLink.stx +31 -0
- package/resources/components/Dashboard/UI/Select.stx +84 -0
- package/resources/components/Dashboard/UI/ServiceHealth.stx +38 -0
- package/resources/components/Dashboard/UI/StatsCard.stx +79 -0
- package/resources/components/Dashboard/UI/Table.stx +143 -0
- package/resources/components/Dashboard/UI/Tabs.stx +45 -0
- package/resources/components/Dashboard/UI/Textarea.stx +93 -0
- package/resources/components/Dashboard/UI/Toggle.stx +84 -0
- package/resources/components/Dashboard/UI/WindowControls.stx +135 -0
- package/resources/components/Dashboard/Widget.stx +89 -0
- package/resources/components/Dashboard/WindowControls.stx +119 -0
- package/resources/components/Dashboard/index.ts +106 -0
- package/resources/components/Docs/Demo/ComboboxCode.md +114 -0
- package/resources/components/Docs/Demo/ComboboxDemo.stx +91 -0
- package/resources/components/Docs/Demo/DialogCode.md +42 -0
- package/resources/components/Docs/Demo/DialogDemo.stx +76 -0
- package/resources/components/Docs/Demo/DocsPlayground.stx +39 -0
- package/resources/components/Docs/Demo/DropdownCode.md +109 -0
- package/resources/components/Docs/Demo/DropdownDemo.stx +82 -0
- package/resources/components/Docs/Demo/Hero.stx +100 -0
- package/resources/components/Docs/Demo/ListboxCode.md +87 -0
- package/resources/components/Docs/Demo/ListboxDemo.stx +59 -0
- package/resources/components/Docs/Demo/NotificationCode.md +173 -0
- package/resources/components/Docs/Demo/NotificationDemo.stx +99 -0
- package/resources/components/Docs/Demo/PopoverCode.md +161 -0
- package/resources/components/Docs/Demo/PopoverDemo.stx +96 -0
- package/resources/components/Docs/Demo/RadioGroupCode.md +98 -0
- package/resources/components/Docs/Demo/RadioGroupDemo.stx +53 -0
- package/resources/components/Docs/Demo/StepperCode.md +216 -0
- package/resources/components/Docs/Demo/StepperDemo.stx +137 -0
- package/resources/components/Docs/Demo/SwitchCode.md +24 -0
- package/resources/components/Docs/Demo/SwitchDemo.stx +28 -0
- package/resources/components/Docs/Home.stx +7 -0
- package/resources/components/Docs/HomeContributors.stx +23 -0
- package/resources/components/Docs/HomeSponsors.stx +17 -0
- package/resources/components/Docs/HomeTeam.stx +18 -0
- package/resources/components/Docs/TeamMember.stx +79 -0
- package/resources/components/Email/EmailButton.stx +32 -0
- package/resources/components/Email/EmailDivider.stx +20 -0
- package/resources/components/Email/EmailImage.stx +24 -0
- package/resources/components/Email/EmailLayout.stx +55 -0
- package/resources/components/Email/EmailLink.stx +22 -0
- package/resources/components/Email/EmailSection.stx +20 -0
- package/resources/components/Email/EmailText.stx +30 -0
- package/resources/components/Forum/ForumBreadcrumb.stx +38 -0
- package/resources/components/Forum/ForumCategory.stx +16 -0
- package/resources/components/Forum/ForumCategoryItem.stx +46 -0
- package/resources/components/Forum/ForumLayout.stx +36 -0
- package/resources/components/Forum/ForumPagination.stx +39 -0
- package/resources/components/Forum/ForumPost.stx +71 -0
- package/resources/components/Forum/ForumReplyForm.stx +76 -0
- package/resources/components/Forum/ForumSidebar.stx +86 -0
- package/resources/components/Forum/ForumTopicItem.stx +77 -0
- package/resources/components/Forum/ForumTopicList.stx +23 -0
- package/resources/components/HelloWorld.stx +253 -0
- package/resources/components/Logo.stx +10 -0
- package/resources/components/Marketing/CallToAction.stx +30 -0
- package/resources/components/Marketing/ComingSoon.stx +155 -0
- package/resources/components/Marketing/Faqs.stx +99 -0
- package/resources/components/Marketing/Feature.stx +32 -0
- package/resources/components/Marketing/Fields.stx +28 -0
- package/resources/components/Marketing/Footer.stx +33 -0
- package/resources/components/Marketing/Header.stx +51 -0
- package/resources/components/Marketing/Hero.stx +46 -0
- package/resources/components/Marketing/Layout.stx +26 -0
- package/resources/components/Marketing/NavLink.stx +13 -0
- package/resources/components/Marketing/Plan.stx +43 -0
- package/resources/components/Marketing/Pricing.stx +120 -0
- package/resources/components/Marketing/PrimaryFeatures.stx +80 -0
- package/resources/components/Marketing/PrimaryFeatures2.stx +98 -0
- package/resources/components/Marketing/SecondaryFeatures.stx +80 -0
- package/resources/components/Marketing/Testimonials.stx +120 -0
- package/resources/components/Pagination.stx +149 -0
- package/resources/components/Playground.stx +9 -0
- package/resources/components/README.md +87 -0
- package/resources/components/Storefront/AnnouncementBar.stx +17 -0
- package/resources/components/Storefront/CartDrawer.stx +227 -0
- package/resources/components/Storefront/CheckoutSteps.stx +50 -0
- package/resources/components/Storefront/Footer.stx +81 -0
- package/resources/components/Storefront/Header.stx +66 -0
- package/resources/components/Storefront/OrderSummary.stx +79 -0
- package/resources/components/Storefront/ProductCard.stx +63 -0
- package/resources/components/Storefront/ProductGallery.stx +88 -0
- package/resources/components/Storefront/QuantitySelector.stx +97 -0
- package/resources/components/index.ts +13 -0
- package/resources/emails/email-verification.stx +46 -0
- package/resources/emails/layouts/base.html +113 -0
- package/resources/emails/password-changed.stx +55 -0
- package/resources/emails/password-reset.stx +43 -0
- package/resources/emails/subscription-confirmation.stx +99 -0
- package/resources/emails/welcome.stx +48 -0
- package/resources/functions/README.md +28 -0
- package/resources/functions/counter.ts +13 -0
- package/resources/functions/dark.ts +4 -0
- package/resources/functions/dashboard/analytics.ts +238 -0
- package/resources/functions/dashboard/config-io.ts +316 -0
- package/resources/functions/dashboard/data.ts +375 -0
- package/resources/functions/dashboard/library.ts +250 -0
- package/resources/functions/dashboard/sidebar.ts +537 -0
- package/resources/functions/dashboard/system.ts +150 -0
- package/resources/layouts/403.stx +188 -0
- package/resources/layouts/404.stx +34 -0
- package/resources/layouts/README.md +14 -0
- package/resources/layouts/dashboard/default.stx +20 -0
- package/resources/layouts/dashboard/guest.stx +10 -0
- package/resources/layouts/default.stx +3 -0
- package/resources/layouts/maintenance.stx +11 -0
- package/resources/layouts/storefront.stx +73 -0
- package/resources/layouts/system-tray/default.stx +3 -0
- package/resources/modules/.gitkeep +0 -0
- package/resources/plugins/.gitkeep +0 -0
- package/resources/plugins/preloader.ts +308 -0
- package/resources/types/README.md +3 -0
- package/resources/views/cart.stx +149 -0
- package/resources/views/checkout/contact.stx +101 -0
- package/resources/views/checkout/payment.stx +114 -0
- package/resources/views/checkout/shipping.stx +120 -0
- package/resources/views/coming-soon.stx +9 -0
- package/resources/views/dashboard/custom-page.stx +45 -0
- package/resources/views/dashboard/index.stx +24 -0
- package/resources/views/emails/welcome.stx +0 -0
- package/resources/views/errors/tester.stx +26 -0
- package/resources/views/index.stx +2865 -0
- package/resources/views/orders/[id].stx +130 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<script server>
|
|
2
|
+
interface WindowControlsProps {
|
|
3
|
+
variant?: 'macos' | 'windows'
|
|
4
|
+
size?: 'sm' | 'md' | 'lg'
|
|
5
|
+
showLabels?: boolean
|
|
6
|
+
disabled?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { variant = 'macos', size = 'md', showLabels = false, disabled = false } = defineProps<WindowControlsProps>()
|
|
10
|
+
|
|
11
|
+
import { isCraftNative, useWindowControls } from '../../../../functions/craft'
|
|
12
|
+
|
|
13
|
+
const sizeConfig = {
|
|
14
|
+
sm: { button: 'w-3 h-3', gap: 'gap-1.5', iconSize: 'w-2 h-2' },
|
|
15
|
+
md: { button: 'w-3.5 h-3.5', gap: 'gap-2', iconSize: 'w-2.5 h-2.5' },
|
|
16
|
+
lg: { button: 'w-4 h-4', gap: 'gap-2.5', iconSize: 'w-3 h-3' },
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const defaultColors = {
|
|
20
|
+
close: { bg: '#ff5f57', hover: '#ff4136', icon: '#4c0002' },
|
|
21
|
+
minimize: { bg: '#febc2e', hover: '#ffa500', icon: '#995700' },
|
|
22
|
+
maximize: { bg: '#28c840', hover: '#00b300', icon: '#006400' },
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const config = sizeConfig[size]
|
|
26
|
+
const windowControls = useWindowControls()
|
|
27
|
+
|
|
28
|
+
// Window control handlers
|
|
29
|
+
function handleClose() {
|
|
30
|
+
windowControls.close()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function handleMinimize() {
|
|
34
|
+
windowControls.minimize()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function handleMaximize() {
|
|
38
|
+
windowControls.toggle()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Check if running in native app
|
|
42
|
+
const isNative = isCraftNative()
|
|
43
|
+
</script>
|
|
44
|
+
@if(variant == 'macos')
|
|
45
|
+
<div class="flex items-center {{ config.gap }}" data-window-controls>
|
|
46
|
+
<!-- Close button -->
|
|
47
|
+
<button
|
|
48
|
+
type="button"
|
|
49
|
+
class="{{ config.button }} rounded-full transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-red-500/50 {{ disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer' }} group"
|
|
50
|
+
style="background-color: {{ defaultColors.close.bg }}"
|
|
51
|
+
@if(disabled) disabled @endif
|
|
52
|
+
title="{{ showLabels ? '' : 'Close' }}"
|
|
53
|
+
@click="handleClose"
|
|
54
|
+
>
|
|
55
|
+
<svg class="{{ config.iconSize }} mx-auto hidden group-hover:block" viewBox="0 0 12 12" fill="none" stroke="currentColor" style="color: {{ defaultColors.close.icon }}">
|
|
56
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3 3l6 6M9 3l-6 6"></path>
|
|
57
|
+
</svg>
|
|
58
|
+
</button>
|
|
59
|
+
|
|
60
|
+
<!-- Minimize button -->
|
|
61
|
+
<button
|
|
62
|
+
type="button"
|
|
63
|
+
class="{{ config.button }} rounded-full transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-yellow-500/50 {{ disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer' }} group"
|
|
64
|
+
style="background-color: {{ defaultColors.minimize.bg }}"
|
|
65
|
+
@if(disabled) disabled @endif
|
|
66
|
+
title="{{ showLabels ? '' : 'Minimize' }}"
|
|
67
|
+
@click="handleMinimize"
|
|
68
|
+
>
|
|
69
|
+
<svg class="{{ config.iconSize }} mx-auto hidden group-hover:block" viewBox="0 0 12 12" fill="none" stroke="currentColor" style="color: {{ defaultColors.minimize.icon }}">
|
|
70
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2 6h8"></path>
|
|
71
|
+
</svg>
|
|
72
|
+
</button>
|
|
73
|
+
|
|
74
|
+
<!-- Maximize button -->
|
|
75
|
+
<button
|
|
76
|
+
type="button"
|
|
77
|
+
class="{{ config.button }} rounded-full transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-green-500/50 {{ disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer' }} group"
|
|
78
|
+
style="background-color: {{ defaultColors.maximize.bg }}"
|
|
79
|
+
@if(disabled) disabled @endif
|
|
80
|
+
title="{{ showLabels ? '' : 'Maximize' }}"
|
|
81
|
+
@click="handleMaximize"
|
|
82
|
+
>
|
|
83
|
+
<svg class="{{ config.iconSize }} mx-auto hidden group-hover:block" viewBox="0 0 12 12" fill="none" stroke="currentColor" style="color: {{ defaultColors.maximize.icon }}">
|
|
84
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M2 2l3 3M10 10l-3-3M10 2l-3 3M2 10l3-3"></path>
|
|
85
|
+
</svg>
|
|
86
|
+
</button>
|
|
87
|
+
</div>
|
|
88
|
+
@else
|
|
89
|
+
<!-- Windows style -->
|
|
90
|
+
<div class="flex items-center">
|
|
91
|
+
<!-- Minimize -->
|
|
92
|
+
<button
|
|
93
|
+
type="button"
|
|
94
|
+
class="flex items-center justify-center h-8 w-12 text-neutral-600 dark:text-neutral-400 hover:bg-neutral-200 dark:hover:bg-neutral-700 transition-colors"
|
|
95
|
+
@if(disabled) disabled @endif
|
|
96
|
+
title="Minimize"
|
|
97
|
+
@click="handleMinimize"
|
|
98
|
+
>
|
|
99
|
+
<svg class="h-0.5 w-3" fill="currentColor" viewBox="0 0 12 2">
|
|
100
|
+
<rect width="12" height="2"></rect>
|
|
101
|
+
</svg>
|
|
102
|
+
</button>
|
|
103
|
+
|
|
104
|
+
<!-- Maximize -->
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
class="flex items-center justify-center h-8 w-12 text-neutral-600 dark:text-neutral-400 hover:bg-neutral-200 dark:hover:bg-neutral-700 transition-colors"
|
|
108
|
+
@if(disabled) disabled @endif
|
|
109
|
+
title="Maximize"
|
|
110
|
+
@click="handleMaximize"
|
|
111
|
+
>
|
|
112
|
+
<svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 12 12">
|
|
113
|
+
<rect x="1" y="1" width="10" height="10" stroke-width="1.5"></rect>
|
|
114
|
+
</svg>
|
|
115
|
+
</button>
|
|
116
|
+
|
|
117
|
+
<!-- Close -->
|
|
118
|
+
<button
|
|
119
|
+
type="button"
|
|
120
|
+
class="flex items-center justify-center h-8 w-12 text-neutral-600 dark:text-neutral-400 hover:text-white hover:bg-red-600 transition-colors"
|
|
121
|
+
@if(disabled) disabled @endif
|
|
122
|
+
title="Close"
|
|
123
|
+
@click="handleClose"
|
|
124
|
+
>
|
|
125
|
+
<svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 12 12">
|
|
126
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M1 1l10 10M11 1l-10 10"></path>
|
|
127
|
+
</svg>
|
|
128
|
+
</button>
|
|
129
|
+
</div>
|
|
130
|
+
@endif
|
|
131
|
+
<style>
|
|
132
|
+
[data-window-controls]:hover button svg {
|
|
133
|
+
display: block;
|
|
134
|
+
}
|
|
135
|
+
</style>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Custom Dashboard Widget Component
|
|
3
|
+
|
|
4
|
+
Use this component to create reusable widgets for your dashboard.
|
|
5
|
+
Import this in your dashboard pages using:
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
interface WidgetProps {
|
|
9
|
+
title: string
|
|
10
|
+
value: string
|
|
11
|
+
description?: string
|
|
12
|
+
trend?: string
|
|
13
|
+
icon?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { title, value, description, trend, icon } = defineProps<WidgetProps>()
|
|
17
|
+
</script>
|
|
18
|
+
-->
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
interface WidgetProps {
|
|
22
|
+
title: string
|
|
23
|
+
value: string
|
|
24
|
+
description?: string
|
|
25
|
+
trend?: string
|
|
26
|
+
icon?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { title, value, description = '', trend = '', icon = '' } = defineProps<WidgetProps>()
|
|
30
|
+
</script>
|
|
31
|
+
<div class="widget">
|
|
32
|
+
<div class="widget-header">
|
|
33
|
+
@if (icon)
|
|
34
|
+
<div class="widget-icon">{{ icon }}</div>
|
|
35
|
+
@endif
|
|
36
|
+
<h3 class="widget-title">{{ title }}</h3>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="widget-value">{{ value }}</div>
|
|
39
|
+
@if (description)
|
|
40
|
+
<div class="widget-description">{{ description }}</div>
|
|
41
|
+
@endif
|
|
42
|
+
@if (trend)
|
|
43
|
+
<div class="widget-trend {{ trend.startsWith('+') ? 'positive' : 'negative' }}">
|
|
44
|
+
{{ trend }}
|
|
45
|
+
</div>
|
|
46
|
+
@endif
|
|
47
|
+
</div>
|
|
48
|
+
<style>
|
|
49
|
+
.widget {
|
|
50
|
+
background: var(--color-bg-card);
|
|
51
|
+
border: 1px solid var(--color-border);
|
|
52
|
+
border-radius: 0.75rem;
|
|
53
|
+
padding: 1.25rem;
|
|
54
|
+
}
|
|
55
|
+
.widget-header {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
gap: 0.5rem;
|
|
59
|
+
margin-bottom: 0.75rem;
|
|
60
|
+
}
|
|
61
|
+
.widget-icon {
|
|
62
|
+
font-size: 1.25rem;
|
|
63
|
+
}
|
|
64
|
+
.widget-title {
|
|
65
|
+
font-size: 0.875rem;
|
|
66
|
+
color: var(--color-text-muted);
|
|
67
|
+
font-weight: 500;
|
|
68
|
+
}
|
|
69
|
+
.widget-value {
|
|
70
|
+
font-size: 1.75rem;
|
|
71
|
+
font-weight: 600;
|
|
72
|
+
}
|
|
73
|
+
.widget-description {
|
|
74
|
+
font-size: 0.75rem;
|
|
75
|
+
color: var(--color-text-muted);
|
|
76
|
+
margin-top: 0.25rem;
|
|
77
|
+
}
|
|
78
|
+
.widget-trend {
|
|
79
|
+
font-size: 0.75rem;
|
|
80
|
+
font-weight: 500;
|
|
81
|
+
margin-top: 0.5rem;
|
|
82
|
+
}
|
|
83
|
+
.widget-trend.positive {
|
|
84
|
+
color: var(--color-success);
|
|
85
|
+
}
|
|
86
|
+
.widget-trend.negative {
|
|
87
|
+
color: var(--color-error);
|
|
88
|
+
}
|
|
89
|
+
</style>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
interface WindowControlsProps {
|
|
3
|
+
size?: string
|
|
4
|
+
variant?: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const { size = 'sm', variant = 'macos' } = defineProps<WindowControlsProps>()
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* WindowControls Component
|
|
11
|
+
* macOS-style traffic light window controls (close, minimize, maximize)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const sizeClasses = {
|
|
15
|
+
xs: 'w-2 h-2',
|
|
16
|
+
sm: 'w-2.5 h-2.5',
|
|
17
|
+
md: 'w-3 h-3',
|
|
18
|
+
lg: 'w-3.5 h-3.5'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const gapClasses = {
|
|
22
|
+
xs: 'gap-1',
|
|
23
|
+
sm: 'gap-1.5',
|
|
24
|
+
md: 'gap-2',
|
|
25
|
+
lg: 'gap-2'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getSizeClass() {
|
|
29
|
+
return sizeClasses[size || 'sm']
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getGapClass() {
|
|
33
|
+
return gapClasses[size || 'sm']
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getVariant() {
|
|
37
|
+
return variant || 'macos'
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
@if(getVariant() === 'macos')
|
|
41
|
+
<!-- macOS-style traffic light controls -->
|
|
42
|
+
<div class="flex items-center {{ getGapClass() }} group">
|
|
43
|
+
<!-- Close button (red) -->
|
|
44
|
+
<button
|
|
45
|
+
type="button"
|
|
46
|
+
class="relative {{ getSizeClass() }} rounded-full bg-[#ff5f57] hover:bg-[#ff5f57] transition-colors focus:outline-none focus:ring-2 focus:ring-red-500/50"
|
|
47
|
+
data-action="window-close"
|
|
48
|
+
title="Close"
|
|
49
|
+
>
|
|
50
|
+
<span class="sr-only">Close</span>
|
|
51
|
+
<!-- X icon on hover -->
|
|
52
|
+
<svg class="absolute inset-0 m-auto h-1.5 w-1.5 text-[#4d0000] opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
53
|
+
<path d="M6 18L18 6M6 6l12 12"></path>
|
|
54
|
+
</svg>
|
|
55
|
+
</button>
|
|
56
|
+
|
|
57
|
+
<!-- Minimize button (yellow) -->
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
class="relative {{ getSizeClass() }} rounded-full bg-[#febc2e] hover:bg-[#febc2e] transition-colors focus:outline-none focus:ring-2 focus:ring-yellow-500/50"
|
|
61
|
+
data-action="window-minimize"
|
|
62
|
+
title="Minimize"
|
|
63
|
+
>
|
|
64
|
+
<span class="sr-only">Minimize</span>
|
|
65
|
+
<!-- Minus icon on hover -->
|
|
66
|
+
<svg class="absolute inset-0 m-auto h-1.5 w-1.5 text-[#995700] opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
67
|
+
<path d="M5 12h14"></path>
|
|
68
|
+
</svg>
|
|
69
|
+
</button>
|
|
70
|
+
|
|
71
|
+
<!-- Maximize button (green) -->
|
|
72
|
+
<button
|
|
73
|
+
type="button"
|
|
74
|
+
class="relative {{ getSizeClass() }} rounded-full bg-[#28c840] hover:bg-[#28c840] transition-colors focus:outline-none focus:ring-2 focus:ring-green-500/50"
|
|
75
|
+
data-action="window-maximize"
|
|
76
|
+
title="Maximize"
|
|
77
|
+
>
|
|
78
|
+
<span class="sr-only">Maximize</span>
|
|
79
|
+
<!-- Expand icon on hover -->
|
|
80
|
+
<svg class="absolute inset-0 m-auto h-1.5 w-1.5 text-[#006500] opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
81
|
+
<path d="M4 14h6m0 0v6m0-6L3 21M20 10h-6m0 0V4m0 6l7-7"></path>
|
|
82
|
+
</svg>
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
85
|
+
@else
|
|
86
|
+
<!-- Windows-style controls -->
|
|
87
|
+
<div class="flex items-center">
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
class="p-1.5 hover:bg-neutral-200 dark:hover:bg-neutral-700 rounded transition-colors"
|
|
91
|
+
data-action="window-minimize"
|
|
92
|
+
title="Minimize"
|
|
93
|
+
>
|
|
94
|
+
<svg class="h-3 w-3 text-neutral-600 dark:text-neutral-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
95
|
+
<path d="M5 12h14"></path>
|
|
96
|
+
</svg>
|
|
97
|
+
</button>
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
class="p-1.5 hover:bg-neutral-200 dark:hover:bg-neutral-700 rounded transition-colors"
|
|
101
|
+
data-action="window-maximize"
|
|
102
|
+
title="Maximize"
|
|
103
|
+
>
|
|
104
|
+
<svg class="h-3 w-3 text-neutral-600 dark:text-neutral-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
105
|
+
<rect x="4" y="4" width="16" height="16" rx="2"></rect>
|
|
106
|
+
</svg>
|
|
107
|
+
</button>
|
|
108
|
+
<button
|
|
109
|
+
type="button"
|
|
110
|
+
class="p-1.5 hover:text-white hover:bg-red-500 rounded transition-colors"
|
|
111
|
+
data-action="window-close"
|
|
112
|
+
title="Close"
|
|
113
|
+
>
|
|
114
|
+
<svg class="h-3 w-3 text-neutral-600 dark:text-neutral-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
115
|
+
<path d="M6 18L18 6M6 6l12 12"></path>
|
|
116
|
+
</svg>
|
|
117
|
+
</button>
|
|
118
|
+
</div>
|
|
119
|
+
@endif
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Components
|
|
3
|
+
*
|
|
4
|
+
* Export all custom dashboard components for easy importing.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { Widget, Card, Table, Chart } from '@/components/Dashboard'
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { default as Widget } from './Widget.stx'
|
|
11
|
+
export { default as Card } from './Card.stx'
|
|
12
|
+
export { default as Table } from './Table.stx'
|
|
13
|
+
export { default as Chart } from './Chart.stx'
|
|
14
|
+
|
|
15
|
+
// UI Components
|
|
16
|
+
export { default as Badge } from './UI/Badge.stx'
|
|
17
|
+
export { default as Button } from './UI/Button.stx'
|
|
18
|
+
export { default as Input } from './UI/Input.stx'
|
|
19
|
+
export { default as Select } from './UI/Select.stx'
|
|
20
|
+
export { default as Modal } from './UI/Modal.stx'
|
|
21
|
+
export { default as Tabs } from './UI/Tabs.stx'
|
|
22
|
+
export { default as Pagination } from './UI/Pagination.stx'
|
|
23
|
+
export { default as StatsCard } from './UI/StatsCard.stx'
|
|
24
|
+
export { default as PageHeader } from './UI/PageHeader.stx'
|
|
25
|
+
export { default as EmptyState } from './UI/EmptyState.stx'
|
|
26
|
+
export { default as FilterBar } from './UI/FilterBar.stx'
|
|
27
|
+
export { default as DataTable } from './UI/DataTable.stx'
|
|
28
|
+
export { default as ChartCard } from './UI/ChartCard.stx'
|
|
29
|
+
export { default as ConfirmDialog } from './UI/ConfirmDialog.stx'
|
|
30
|
+
export { default as ActivityTable } from './UI/ActivityTable.stx'
|
|
31
|
+
export { default as ServiceHealth } from './UI/ServiceHealth.stx'
|
|
32
|
+
export { default as QuickLinks } from './UI/QuickLinks.stx'
|
|
33
|
+
|
|
34
|
+
// Re-export types
|
|
35
|
+
export interface WidgetProps {
|
|
36
|
+
title: string
|
|
37
|
+
value: string
|
|
38
|
+
description?: string
|
|
39
|
+
trend?: string
|
|
40
|
+
icon?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface CardProps {
|
|
44
|
+
title?: string
|
|
45
|
+
subtitle?: string
|
|
46
|
+
actions?: Array<{ label: string, onClick: () => void }>
|
|
47
|
+
padding?: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface TableColumn {
|
|
51
|
+
key: string
|
|
52
|
+
label: string
|
|
53
|
+
align?: 'left' | 'center' | 'right'
|
|
54
|
+
render?: (value: any, row: any) => string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface TableProps {
|
|
58
|
+
columns: TableColumn[]
|
|
59
|
+
data: any[]
|
|
60
|
+
striped?: boolean
|
|
61
|
+
hoverable?: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ChartProps {
|
|
65
|
+
type: 'line' | 'bar' | 'pie' | 'doughnut' | 'area'
|
|
66
|
+
data: object
|
|
67
|
+
options?: object
|
|
68
|
+
height?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface StatsCardProps {
|
|
72
|
+
title: string
|
|
73
|
+
value: string
|
|
74
|
+
subtitle?: string
|
|
75
|
+
trend?: number
|
|
76
|
+
trendLabel?: string
|
|
77
|
+
icon?: string
|
|
78
|
+
iconBg?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral'
|
|
79
|
+
loading?: boolean
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface BadgeProps {
|
|
83
|
+
variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
|
84
|
+
size?: 'xs' | 'sm' | 'md' | 'lg'
|
|
85
|
+
rounded?: 'default' | 'full'
|
|
86
|
+
outline?: boolean
|
|
87
|
+
dot?: boolean
|
|
88
|
+
text?: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface FilterBarProps {
|
|
92
|
+
searchPlaceholder?: string
|
|
93
|
+
searchValue?: string
|
|
94
|
+
showItemsPerPage?: boolean
|
|
95
|
+
itemsPerPage?: number
|
|
96
|
+
itemsPerPageOptions?: number[]
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface ConfirmDialogProps {
|
|
100
|
+
isOpen?: boolean
|
|
101
|
+
title?: string
|
|
102
|
+
description?: string
|
|
103
|
+
confirmLabel?: string
|
|
104
|
+
cancelLabel?: string
|
|
105
|
+
variant?: 'danger' | 'warning'
|
|
106
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
```vue
|
|
2
|
+
<script lang="ts" setup>
|
|
3
|
+
import { ref, computed } from '@stacksjs/stx'
|
|
4
|
+
import {
|
|
5
|
+
Combobox,
|
|
6
|
+
ComboboxButton,
|
|
7
|
+
ComboboxInput,
|
|
8
|
+
ComboboxOption,
|
|
9
|
+
ComboboxOptions,
|
|
10
|
+
} from '@stacksjs/combobox'
|
|
11
|
+
import { TransitionRoot } from '@stacksjs/transition'
|
|
12
|
+
|
|
13
|
+
interface Person {
|
|
14
|
+
id: number
|
|
15
|
+
name: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const defaultItems = [
|
|
19
|
+
{ id: 1, name: 'Chris Breuer' },
|
|
20
|
+
{ id: 2, name: 'Avery Hill' },
|
|
21
|
+
{ id: 3, name: 'Glenn Michael' },
|
|
22
|
+
{ id: 4, name: 'Michael Vincent' },
|
|
23
|
+
{ id: 5, name: 'Blake Ayer' },
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
const listItems = ref(defaultItems)
|
|
27
|
+
const selected = ref(null)
|
|
28
|
+
const query = ref('')
|
|
29
|
+
const isOpen = ref(false)
|
|
30
|
+
|
|
31
|
+
const items = computed(() => {
|
|
32
|
+
return query.value === ''
|
|
33
|
+
? listItems.value
|
|
34
|
+
: listItems.value.filter((item) =>
|
|
35
|
+
item.name.toLowerCase().includes(query.value.toLowerCase())
|
|
36
|
+
)
|
|
37
|
+
})
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<template>
|
|
41
|
+
<div class="relative">
|
|
42
|
+
<Combobox v-model="selected" as="div" class="relative">
|
|
43
|
+
<div class="relative">
|
|
44
|
+
<ComboboxInput
|
|
45
|
+
class="placeholder-gray-400 pl-3 pr-10 py-2.5 w-full text-base text-gray-900 bg-white border border-gray-300 rounded-lg focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 shadow-sm duration-200 transition-all"
|
|
46
|
+
:display-value="(person) => person?.name"
|
|
47
|
+
placeholder="Search people..."
|
|
48
|
+
@change="query = $event.target.value"
|
|
49
|
+
@focus="isOpen = true"
|
|
50
|
+
/>
|
|
51
|
+
<ComboboxButton
|
|
52
|
+
class="flex absolute inset-y-0 right-0 items-center pr-2 text-gray-400 hover:text-gray-500"
|
|
53
|
+
>
|
|
54
|
+
<div class="h-5 w-5 i-hugeicons-chevron-up-down-20-solid" />
|
|
55
|
+
</ComboboxButton>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<TransitionRoot
|
|
59
|
+
:show="isOpen"
|
|
60
|
+
leave="transition ease-in duration-100"
|
|
61
|
+
leave-from="opacity-100"
|
|
62
|
+
leave-to="opacity-0"
|
|
63
|
+
@after-leave="query = ''"
|
|
64
|
+
>
|
|
65
|
+
<ComboboxOptions
|
|
66
|
+
class="absolute overflow-auto z-10 mt-1 py-1 max-h-60 w-full text-base bg-white ring-1 ring-black/5 rounded-md focus:outline-none shadow-lg"
|
|
67
|
+
>
|
|
68
|
+
<div
|
|
69
|
+
v-if="items.length === 0"
|
|
70
|
+
class="relative px-4 py-2 text-gray-700 cursor-default select-none"
|
|
71
|
+
>
|
|
72
|
+
No results found.
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<ComboboxOption
|
|
76
|
+
v-for="item in items"
|
|
77
|
+
:key="item.id"
|
|
78
|
+
:value="item"
|
|
79
|
+
v-slot="{ selected: isSelected, active }"
|
|
80
|
+
as="template"
|
|
81
|
+
>
|
|
82
|
+
<li
|
|
83
|
+
class="relative pl-10 pr-4 py-2 cursor-default select-none"
|
|
84
|
+
:class="!active, 'bg-indigo-600 'text-gray-900': { } active, text-white':"
|
|
85
|
+
>
|
|
86
|
+
<span
|
|
87
|
+
class="block truncate"
|
|
88
|
+
:class="!isSelected 'font-medium': 'font-normal': { } isSelected,"
|
|
89
|
+
>
|
|
90
|
+
{{ item.name }}
|
|
91
|
+
</span>
|
|
92
|
+
<span
|
|
93
|
+
v-if="isSelected"
|
|
94
|
+
class="flex absolute inset-y-0 left-0 items-center pl-3"
|
|
95
|
+
:class="!active 'text-indigo-600': 'text-white': { } active,"
|
|
96
|
+
>
|
|
97
|
+
<div class="h-5 w-5 i-hugeicons-check-20-solid" />
|
|
98
|
+
</span>
|
|
99
|
+
</li>
|
|
100
|
+
</ComboboxOption>
|
|
101
|
+
</ComboboxOptions>
|
|
102
|
+
</TransitionRoot>
|
|
103
|
+
</Combobox>
|
|
104
|
+
|
|
105
|
+
<div v-if="selected" class="mt-4 p-4 bg-gray-50 border border-gray-200 rounded-lg">
|
|
106
|
+
<span class="font-medium text-gray-500 text-sm">Selected Person</span>
|
|
107
|
+
<div class="flex gap-2 items-center">
|
|
108
|
+
<span class="font-semibold text-gray-900 text-lg">{{ selected.name }}</span>
|
|
109
|
+
<span class="text-gray-500 text-sm">(ID: {{ selected.id }})</span>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</template>
|
|
114
|
+
```
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
interface ComboboxDemoProps {
|
|
3
|
+
listItems?: string
|
|
4
|
+
selected?: any
|
|
5
|
+
query?: string
|
|
6
|
+
isOpen?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { listItems = [, selected = null, query = '', isOpen = false } = defineProps<ComboboxDemoProps>()
|
|
10
|
+
|
|
11
|
+
{ id: 1, name: 'Chris Breuer' },
|
|
12
|
+
{ id: 2, name: 'Avery Hill' },
|
|
13
|
+
{ id: 3, name: 'Glenn Michael' },
|
|
14
|
+
{ id: 4, name: 'Michael Vincent' },
|
|
15
|
+
{ id: 5, name: 'Blake Ayer' },
|
|
16
|
+
]
|
|
17
|
+
function filterItems(items, query) {
|
|
18
|
+
if (query === '') return items
|
|
19
|
+
return items.filter(item => item.name.toLowerCase().includes(query.toLowerCase()))
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
<div class="demo-wrapper">
|
|
23
|
+
<DocsPlayground>
|
|
24
|
+
<div class="flex flex-col mx-auto py-10 max-w-full w-full">
|
|
25
|
+
<main class="grid gap-8 grid-cols-1 text-primary text-xs 2xl:text-sm">
|
|
26
|
+
<div class="relative items-center mx-auto w-1/2">
|
|
27
|
+
<div class="relative">
|
|
28
|
+
<div class="relative">
|
|
29
|
+
<input
|
|
30
|
+
type="text"
|
|
31
|
+
class="placeholder-gray-400 pl-3 pr-10 py-2.5 w-full text-base text-gray-900 bg-white border border-gray-300 rounded-lg focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 shadow-sm duration-200 transition-all"
|
|
32
|
+
placeholder="Search people..."
|
|
33
|
+
value="{{ selected ? selected.name : '' }}"
|
|
34
|
+
data-action="combobox-input"
|
|
35
|
+
>
|
|
36
|
+
<button
|
|
37
|
+
class="flex absolute inset-y-0 right-0 items-center pr-2 text-gray-400 hover:text-gray-500"
|
|
38
|
+
data-action="toggle-dropdown"
|
|
39
|
+
>
|
|
40
|
+
<div class="h-5 w-5 i-hugeicons-chevron-up-down-20-solid"></div>
|
|
41
|
+
</button>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
@if(isOpen)
|
|
45
|
+
<div class="absolute overflow-auto z-10 mt-1 py-1 max-h-60 w-full text-base bg-white ring-1 ring-black/5 rounded-md focus:outline-none shadow-lg">
|
|
46
|
+
@if(filterItems(listItems, query).length == 0)
|
|
47
|
+
<div class="relative px-4 py-2 text-gray-700 cursor-default select-none">
|
|
48
|
+
No results found.
|
|
49
|
+
</div>
|
|
50
|
+
@endif
|
|
51
|
+
|
|
52
|
+
@foreach(filterItems(listItems, query) as item)
|
|
53
|
+
<div
|
|
54
|
+
class="relative pl-10 pr-4 py-2 text-gray-900 hover:text-white hover:bg-indigo-600 cursor-default select-none"
|
|
55
|
+
data-action="select-item"
|
|
56
|
+
data-item-id="{{ item.id }}"
|
|
57
|
+
data-item-name="{{ item.name }}"
|
|
58
|
+
>
|
|
59
|
+
<span class="block truncate selected selected.id : ? 'font-medium' 'font-normal' {{ }} && == item.id">
|
|
60
|
+
{{ item.name }}
|
|
61
|
+
</span>
|
|
62
|
+
@if(selected && selected.id == item.id)
|
|
63
|
+
<span class="flex absolute inset-y-0 left-0 items-center pl-3 text-indigo-600">
|
|
64
|
+
<div class="h-5 w-5 i-hugeicons-check-20-solid"></div>
|
|
65
|
+
</span>
|
|
66
|
+
@endif
|
|
67
|
+
</div>
|
|
68
|
+
@endforeach
|
|
69
|
+
</div>
|
|
70
|
+
@endif
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</main>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div slot="code">
|
|
77
|
+
<!-- ComboboxCode component would be rendered here -->
|
|
78
|
+
</div>
|
|
79
|
+
</DocsPlayground>
|
|
80
|
+
</div>
|
|
81
|
+
<style>
|
|
82
|
+
.demo-wrapper {
|
|
83
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
|
|
84
|
+
Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif,
|
|
85
|
+
Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
button {
|
|
89
|
+
border: 0px solid #000;
|
|
90
|
+
}
|
|
91
|
+
</style>
|