@torch-ui/solid 0.1.3
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/README.md +166 -0
- package/package.json +67 -0
- package/src/components/actions/Button.tsx +612 -0
- package/src/components/actions/ButtonGroup.tsx +728 -0
- package/src/components/actions/Copy.tsx +98 -0
- package/src/components/actions/DarkModeToggle.tsx +80 -0
- package/src/components/actions/Link.tsx +37 -0
- package/src/components/actions/index.ts +19 -0
- package/src/components/actions/useCopyToClipboard.ts +90 -0
- package/src/components/charts/Chart.tsx +331 -0
- package/src/components/charts/Sparkline.tsx +156 -0
- package/src/components/charts/index.ts +13 -0
- package/src/components/data-display/Avatar.tsx +208 -0
- package/src/components/data-display/AvatarGroup.tsx +228 -0
- package/src/components/data-display/Badge.tsx +70 -0
- package/src/components/data-display/Carousel.tsx +214 -0
- package/src/components/data-display/ColorSwatch.tsx +56 -0
- package/src/components/data-display/DataTable.tsx +886 -0
- package/src/components/data-display/EmptyState.tsx +61 -0
- package/src/components/data-display/Image.tsx +277 -0
- package/src/components/data-display/Kbd.tsx +114 -0
- package/src/components/data-display/Persona.tsx +78 -0
- package/src/components/data-display/StatCard.tsx +338 -0
- package/src/components/data-display/Table.tsx +147 -0
- package/src/components/data-display/Tag.tsx +91 -0
- package/src/components/data-display/Timeline.tsx +200 -0
- package/src/components/data-display/TreeView.tsx +172 -0
- package/src/components/data-display/Video.tsx +95 -0
- package/src/components/data-display/avatar-utils.ts +32 -0
- package/src/components/data-display/index.ts +81 -0
- package/src/components/feedback/Loading.tsx +159 -0
- package/src/components/feedback/Progress.tsx +321 -0
- package/src/components/feedback/Skeleton.tsx +62 -0
- package/src/components/feedback/SkeletonBlocks.tsx +222 -0
- package/src/components/feedback/Toast.tsx +648 -0
- package/src/components/feedback/index.ts +44 -0
- package/src/components/feedback/password/PasswordStrengthIndicator.tsx +232 -0
- package/src/components/feedback/password/password-strength.ts +115 -0
- package/src/components/feedback/password/password-validation-data.ts +66 -0
- package/src/components/feedback/password/password-validation.ts +93 -0
- package/src/components/forms/Autocomplete.tsx +268 -0
- package/src/components/forms/Checkbox.tsx +155 -0
- package/src/components/forms/CodeInput.tsx +237 -0
- package/src/components/forms/ColorPicker/ColorPicker.tsx +469 -0
- package/src/components/forms/ColorPicker/color-utils.ts +75 -0
- package/src/components/forms/ColorPicker/index.ts +2 -0
- package/src/components/forms/DatePicker.tsx +516 -0
- package/src/components/forms/DateRangePicker.tsx +464 -0
- package/src/components/forms/FieldPicker.tsx +64 -0
- package/src/components/forms/FileUpload.tsx +614 -0
- package/src/components/forms/FilterBuilder/FilterGroupBlock.ts +6 -0
- package/src/components/forms/FilterBuilder.tsx +16 -0
- package/src/components/forms/FilterRuleRow.tsx +68 -0
- package/src/components/forms/Input.tsx +200 -0
- package/src/components/forms/MultiSelect.tsx +361 -0
- package/src/components/forms/NumberField.tsx +145 -0
- package/src/components/forms/RadioGroup.tsx +135 -0
- package/src/components/forms/RelativeDateDefaultInput.tsx +62 -0
- package/src/components/forms/ReorderableList.tsx +163 -0
- package/src/components/forms/Select.tsx +268 -0
- package/src/components/forms/Slider.tsx +260 -0
- package/src/components/forms/Switch.tsx +135 -0
- package/src/components/forms/TextArea.tsx +202 -0
- package/src/components/forms/ViewCustomizer.tsx +44 -0
- package/src/components/forms/index.ts +43 -0
- package/src/components/layout/Accordion.tsx +110 -0
- package/src/components/layout/Alert.tsx +156 -0
- package/src/components/layout/BlockQuote.tsx +70 -0
- package/src/components/layout/Card.tsx +166 -0
- package/src/components/layout/CodeBlock/CodeBlock.tsx +477 -0
- package/src/components/layout/CodeBlock/code-block-tokens.css +104 -0
- package/src/components/layout/CodeBlock/prism.ts +81 -0
- package/src/components/layout/Collapsible.tsx +84 -0
- package/src/components/layout/Container.tsx +55 -0
- package/src/components/layout/Divider.tsx +64 -0
- package/src/components/layout/Form.tsx +39 -0
- package/src/components/layout/FormActions.tsx +50 -0
- package/src/components/layout/Grid.tsx +53 -0
- package/src/components/layout/PageHeading.tsx +46 -0
- package/src/components/layout/PromptWithAction.tsx +49 -0
- package/src/components/layout/Section.tsx +60 -0
- package/src/components/layout/TablePanel.tsx +24 -0
- package/src/components/layout/TableView/TableView.tsx +1018 -0
- package/src/components/layout/TableView/index.ts +3 -0
- package/src/components/layout/TableView/types.ts +51 -0
- package/src/components/layout/WizardStep.tsx +40 -0
- package/src/components/layout/WizardStepper.tsx +173 -0
- package/src/components/layout/index.ts +96 -0
- package/src/components/navigation/Breadcrumbs.tsx +66 -0
- package/src/components/navigation/DropdownMenu.tsx +86 -0
- package/src/components/navigation/MegaMenu.tsx +480 -0
- package/src/components/navigation/NavigationMenu.tsx +305 -0
- package/src/components/navigation/Pagination.tsx +298 -0
- package/src/components/navigation/Sidebar.tsx +280 -0
- package/src/components/navigation/Tabs.tsx +122 -0
- package/src/components/navigation/ViewSwitcher.tsx +314 -0
- package/src/components/navigation/index.ts +66 -0
- package/src/components/overlays/AlertDialog.tsx +174 -0
- package/src/components/overlays/ContextMenu.tsx +65 -0
- package/src/components/overlays/Dialog.tsx +279 -0
- package/src/components/overlays/Drawer.tsx +370 -0
- package/src/components/overlays/HoverCard.tsx +107 -0
- package/src/components/overlays/Popover.tsx +73 -0
- package/src/components/overlays/Tooltip.tsx +31 -0
- package/src/components/overlays/index.ts +71 -0
- package/src/components/typography/Code.tsx +72 -0
- package/src/components/typography/Icon.tsx +36 -0
- package/src/components/typography/index.ts +10 -0
- package/src/env.d.ts +9 -0
- package/src/index.ts +13 -0
- package/src/styles/theme.css +226 -0
- package/src/types/avatar-types.ts +11 -0
- package/src/types/filter-types.ts +35 -0
- package/src/utilities/classNames.ts +6 -0
- package/src/utilities/componentSize.ts +46 -0
- package/src/utilities/i18n.tsx +60 -0
- package/src/utilities/mergeRefs.ts +12 -0
- package/src/utilities/relativeDateDefault.ts +14 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { FilterGroup } from '../../../types/filter-types'
|
|
2
|
+
import type { ViewCustomizerField } from '../../forms/ViewCustomizer'
|
|
3
|
+
import type { FilterFieldConfig } from '../../forms/FilterBuilder/FilterGroupBlock'
|
|
4
|
+
|
|
5
|
+
export interface ViewConfig {
|
|
6
|
+
id: string
|
|
7
|
+
label: string
|
|
8
|
+
fields: string[]
|
|
9
|
+
groupBy: string
|
|
10
|
+
filters: FilterGroup
|
|
11
|
+
scope: 'user' | 'tenant'
|
|
12
|
+
/** When true, this view is used as the default when opening. System default view is fallback when no view is pinned. */
|
|
13
|
+
pinned?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** API for persisting views. When provided, TableView fetches/saves views via these methods. */
|
|
17
|
+
export interface TableViewsApi {
|
|
18
|
+
fetchViews: (entityType: string) => Promise<ViewConfig[]>
|
|
19
|
+
createView: (entityType: string, view: Omit<ViewConfig, 'id'>) => Promise<ViewConfig>
|
|
20
|
+
updateView: (entityType: string, view: ViewConfig) => Promise<void>
|
|
21
|
+
deleteView: (entityType: string, viewId: string) => Promise<void>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface TableViewConfig {
|
|
25
|
+
/** Entity type for API (e.g. 'contacts', 'jobs'). Required when viewsApi is provided. */
|
|
26
|
+
entityType?: string
|
|
27
|
+
/** Default/system views. Must include the system default view (e.g. id: 'all'). */
|
|
28
|
+
defaultViews: ViewConfig[]
|
|
29
|
+
/** ID of the system default view shown when no view is pinned (e.g. 'all') */
|
|
30
|
+
systemDefaultViewId: string
|
|
31
|
+
/** All fields available for columns (used in ViewCustomizer) */
|
|
32
|
+
allFields: ViewCustomizerField[]
|
|
33
|
+
/** Fields for the filter builder */
|
|
34
|
+
filterFields: FilterFieldConfig[]
|
|
35
|
+
/** Get operator options for a filter field type */
|
|
36
|
+
getOperatorsForType: (type: string) => { value: string; label: string }[]
|
|
37
|
+
/** Initial field IDs for new views */
|
|
38
|
+
initialFields: string[]
|
|
39
|
+
/** Row count for the count badge on tabs (fallback when getFilteredCountForView not provided) */
|
|
40
|
+
rowCount?: number
|
|
41
|
+
/** Return filtered row count for a specific view. When provided, each tab shows its own filtered count. */
|
|
42
|
+
getFilteredCountForView?: (view: ViewConfig) => number
|
|
43
|
+
/** Customize drawer title */
|
|
44
|
+
customizeTitle?: string
|
|
45
|
+
/** Customize drawer description */
|
|
46
|
+
customizeDescription?: string
|
|
47
|
+
/** Filter drawer title */
|
|
48
|
+
filterTitle?: string
|
|
49
|
+
/** Filter drawer description */
|
|
50
|
+
filterDescription?: string
|
|
51
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { JSX, ParentComponent } from 'solid-js'
|
|
2
|
+
|
|
3
|
+
export interface WizardStepProps {
|
|
4
|
+
/** Step number (1-based) for display */
|
|
5
|
+
stepNumber?: number
|
|
6
|
+
/** Step title */
|
|
7
|
+
title: string
|
|
8
|
+
/** Optional description below title */
|
|
9
|
+
description?: string
|
|
10
|
+
/** Optional class for the wrapper */
|
|
11
|
+
class?: string
|
|
12
|
+
children: JSX.Element
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Wraps one wizard step's content with optional step badge, title, and description. */
|
|
16
|
+
export const WizardStep: ParentComponent<WizardStepProps> = (props) => {
|
|
17
|
+
return (
|
|
18
|
+
<div class={props.class}>
|
|
19
|
+
<div class="mb-1 flex items-center gap-3">
|
|
20
|
+
{props.stepNumber != null && (
|
|
21
|
+
<span
|
|
22
|
+
class="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary-500/10 text-sm font-semibold text-primary-600 dark:bg-primary-500/20 dark:text-primary-400"
|
|
23
|
+
aria-hidden
|
|
24
|
+
>
|
|
25
|
+
{props.stepNumber}
|
|
26
|
+
</span>
|
|
27
|
+
)}
|
|
28
|
+
<h2 class="font-semibold tracking-tight text-xl text-ink-900">
|
|
29
|
+
{props.title}
|
|
30
|
+
</h2>
|
|
31
|
+
</div>
|
|
32
|
+
{props.description && (
|
|
33
|
+
<p class="mb-6 text-[0.9375rem] text-ink-500">
|
|
34
|
+
{props.description}
|
|
35
|
+
</p>
|
|
36
|
+
)}
|
|
37
|
+
{props.children}
|
|
38
|
+
</div>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { Check, ChevronRight } from 'lucide-solid'
|
|
2
|
+
import { cn } from '../../utilities/classNames'
|
|
3
|
+
|
|
4
|
+
export type WizardStepperVariant = 'default' | 'compact' | 'pills' | 'chevrons'
|
|
5
|
+
|
|
6
|
+
export interface WizardStepperProps {
|
|
7
|
+
/** Current step (1-based) */
|
|
8
|
+
step: number
|
|
9
|
+
/** Total number of steps */
|
|
10
|
+
totalSteps: number
|
|
11
|
+
/** Step labels (e.g. ['About you', 'Your company']) */
|
|
12
|
+
stepLabels: string[]
|
|
13
|
+
/** 'horizontal' | 'vertical' */
|
|
14
|
+
orientation?: 'horizontal' | 'vertical'
|
|
15
|
+
/** Visual style: default (circles + line), compact (smaller), pills (tag-style + progress bar), or chevrons (chevron separators). Default: default. */
|
|
16
|
+
variant?: WizardStepperVariant
|
|
17
|
+
/** Optional class for the root */
|
|
18
|
+
class?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Reusable stepper: numbered steps with labels and connector. */
|
|
22
|
+
export function WizardStepper(props: WizardStepperProps) {
|
|
23
|
+
const orientation = () => props.orientation ?? 'horizontal'
|
|
24
|
+
const currentStep = () => props.step
|
|
25
|
+
const variant = () => props.variant ?? 'default'
|
|
26
|
+
const isCompact = () => variant() === 'compact'
|
|
27
|
+
const isPills = () => variant() === 'pills'
|
|
28
|
+
const isChevrons = () => variant() === 'chevrons'
|
|
29
|
+
|
|
30
|
+
// Pills: horizontal only, tag-style labels with progress bar underneath
|
|
31
|
+
if (isPills() && orientation() === 'horizontal') {
|
|
32
|
+
const progressPercent = (currentStep() / props.stepLabels.length) * 100
|
|
33
|
+
return (
|
|
34
|
+
<nav class={cn('wizard-stepper wizard-stepper--pills', props.class)} aria-label="Progress">
|
|
35
|
+
<div class="flex flex-col gap-3">
|
|
36
|
+
<ol class="m-0 flex list-none gap-2 p-0">
|
|
37
|
+
{props.stepLabels.map((label, index) => {
|
|
38
|
+
const stepNum = index + 1
|
|
39
|
+
const isActive = currentStep() === stepNum
|
|
40
|
+
const isCompleted = currentStep() > stepNum
|
|
41
|
+
return (
|
|
42
|
+
<li
|
|
43
|
+
class="flex min-w-0 flex-1 flex-col items-stretch gap-1.5"
|
|
44
|
+
aria-current={isActive ? 'step' : undefined}
|
|
45
|
+
>
|
|
46
|
+
<div class="flex h-5 w-full shrink-0 items-center justify-center">
|
|
47
|
+
{isCompleted ? (
|
|
48
|
+
<span class="flex h-5 w-5 items-center justify-center rounded-full bg-primary-500 text-white" aria-hidden="true">
|
|
49
|
+
<Check size={12} strokeWidth={2.5} />
|
|
50
|
+
</span>
|
|
51
|
+
) : isActive ? (
|
|
52
|
+
<span class="h-2 w-2 shrink-0 rounded-full bg-primary-500" aria-hidden="true" />
|
|
53
|
+
) : (
|
|
54
|
+
<span class="h-2 w-2 shrink-0 rounded-full bg-transparent" aria-hidden="true" />
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
<span
|
|
58
|
+
class={cn(
|
|
59
|
+
'w-full rounded-full px-3 py-1.5 text-center text-sm font-medium',
|
|
60
|
+
isActive && 'bg-primary-500/15 text-primary-700 dark:bg-primary-400/20 dark:text-primary-300',
|
|
61
|
+
isCompleted && 'bg-surface-overlay text-ink-700',
|
|
62
|
+
!isActive && !isCompleted && 'bg-surface-overlay text-ink-500'
|
|
63
|
+
)}
|
|
64
|
+
>
|
|
65
|
+
{label}
|
|
66
|
+
</span>
|
|
67
|
+
</li>
|
|
68
|
+
)
|
|
69
|
+
})}
|
|
70
|
+
</ol>
|
|
71
|
+
<div class="h-1.5 w-full overflow-hidden rounded-full bg-surface-dim">
|
|
72
|
+
<div
|
|
73
|
+
class="h-full rounded-full bg-primary-500 transition-[width] duration-300 ease-out"
|
|
74
|
+
style={{ width: `${progressPercent}%` }}
|
|
75
|
+
aria-hidden
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</nav>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<nav class={cn('wizard-stepper', props.class)} aria-label="Progress">
|
|
85
|
+
<ol
|
|
86
|
+
class={cn(
|
|
87
|
+
'm-0 flex list-none items-center p-0',
|
|
88
|
+
orientation() === 'vertical' && 'flex-col items-stretch gap-0',
|
|
89
|
+
orientation() === 'horizontal' && isChevrons() && 'w-full gap-2 sm:gap-6'
|
|
90
|
+
)}
|
|
91
|
+
>
|
|
92
|
+
{props.stepLabels.map((label, index) => {
|
|
93
|
+
const stepNum = index + 1
|
|
94
|
+
const isActive = currentStep() === stepNum
|
|
95
|
+
const isCompleted = currentStep() > stepNum
|
|
96
|
+
return (
|
|
97
|
+
<li
|
|
98
|
+
class={cn(
|
|
99
|
+
'flex items-center',
|
|
100
|
+
orientation() === 'horizontal' &&
|
|
101
|
+
(isChevrons()
|
|
102
|
+
? 'min-w-0 flex-1 flex-shrink-0 basis-0 justify-center gap-2 sm:gap-3'
|
|
103
|
+
: 'min-w-0 flex-1 first:min-w-0 first:flex-initial'),
|
|
104
|
+
orientation() === 'vertical' && 'flex-col items-start gap-0'
|
|
105
|
+
)}
|
|
106
|
+
aria-current={isActive ? 'step' : undefined}
|
|
107
|
+
>
|
|
108
|
+
{orientation() === 'horizontal' && index > 0 &&
|
|
109
|
+
(isChevrons() ? (
|
|
110
|
+
<span class="flex shrink-0 items-center text-ink-300" aria-hidden="true">
|
|
111
|
+
<ChevronRight size={isCompact() ? 16 : 20} />
|
|
112
|
+
</span>
|
|
113
|
+
) : (
|
|
114
|
+
<span
|
|
115
|
+
class={cn(
|
|
116
|
+
'h-0.5 min-w-[1rem] flex-1 shrink rounded transition-colors',
|
|
117
|
+
isCompact() ? 'ml-2 mr-2 sm:ml-2.5 sm:mr-2.5' : 'ml-3 mr-3 sm:ml-4 sm:mr-4',
|
|
118
|
+
isCompleted ? 'bg-primary-500' : 'bg-surface-dim'
|
|
119
|
+
)}
|
|
120
|
+
aria-hidden="true"
|
|
121
|
+
/>
|
|
122
|
+
))
|
|
123
|
+
}
|
|
124
|
+
<div
|
|
125
|
+
class={cn(
|
|
126
|
+
'flex shrink-0 items-center gap-3',
|
|
127
|
+
isCompact() && 'gap-2',
|
|
128
|
+
orientation() === 'vertical' && 'py-2 first:pt-0',
|
|
129
|
+
isCompact() && orientation() === 'vertical' && 'py-1.5 first:pt-0'
|
|
130
|
+
)}
|
|
131
|
+
>
|
|
132
|
+
<span
|
|
133
|
+
class={cn(
|
|
134
|
+
'flex shrink-0 items-center justify-center rounded-full text-sm font-semibold transition-colors',
|
|
135
|
+
isCompact() ? 'h-6 w-6 text-xs' : 'h-8 w-8',
|
|
136
|
+
isCompleted && 'bg-primary-500 text-white',
|
|
137
|
+
isActive && 'bg-primary-500 text-white ring-4 ring-primary-500/20 dark:ring-primary-500/30',
|
|
138
|
+
isCompact() && isActive && 'ring-2',
|
|
139
|
+
!isActive && !isCompleted && 'bg-ink-200 text-ink-500'
|
|
140
|
+
)}
|
|
141
|
+
>
|
|
142
|
+
{isCompleted ? <Check size={isCompact() ? 12 : 16} strokeWidth={2.5} /> : stepNum}
|
|
143
|
+
</span>
|
|
144
|
+
<span
|
|
145
|
+
class={cn(
|
|
146
|
+
'font-medium',
|
|
147
|
+
isCompact() ? 'text-sm' : 'text-xs sm:text-sm',
|
|
148
|
+
orientation() === 'vertical' && !isCompact() && 'text-sm',
|
|
149
|
+
isActive && 'text-ink-900',
|
|
150
|
+
isCompleted && 'text-ink-600',
|
|
151
|
+
!isActive && !isCompleted && 'text-ink-400'
|
|
152
|
+
)}
|
|
153
|
+
>
|
|
154
|
+
{label}
|
|
155
|
+
</span>
|
|
156
|
+
</div>
|
|
157
|
+
{orientation() === 'vertical' && index < props.stepLabels.length - 1 && (
|
|
158
|
+
<span
|
|
159
|
+
class={cn(
|
|
160
|
+
'shrink-0 rounded transition-colors',
|
|
161
|
+
isCompact() ? 'ml-3 h-3 w-0.5' : 'ml-4 h-4 w-0.5',
|
|
162
|
+
isCompleted ? 'bg-primary-500' : 'bg-surface-dim'
|
|
163
|
+
)}
|
|
164
|
+
aria-hidden="true"
|
|
165
|
+
/>
|
|
166
|
+
)}
|
|
167
|
+
</li>
|
|
168
|
+
)
|
|
169
|
+
})}
|
|
170
|
+
</ol>
|
|
171
|
+
</nav>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export { Alert } from './Alert'
|
|
2
|
+
export type { AlertProps, AlertStatus, AlertAppearance } from './Alert'
|
|
3
|
+
|
|
4
|
+
export { AlertDialog } from '../overlays/AlertDialog'
|
|
5
|
+
export type { AlertDialogProps } from '../overlays/AlertDialog'
|
|
6
|
+
|
|
7
|
+
export { Divider } from './Divider'
|
|
8
|
+
export type { DividerProps, DividerStyle, DividerWeight } from './Divider'
|
|
9
|
+
|
|
10
|
+
export { Drawer } from '../overlays/Drawer'
|
|
11
|
+
export type { DrawerProps, DrawerSize, DrawerSide, DrawerOffset, DrawerActionsPosition } from '../overlays/Drawer'
|
|
12
|
+
|
|
13
|
+
export { Dialog } from '../overlays/Dialog'
|
|
14
|
+
export type { DialogProps, DialogSize, DialogOverlayAnimation, DialogPanelAnimation } from '../overlays/Dialog'
|
|
15
|
+
export { WizardStep } from './WizardStep'
|
|
16
|
+
export type { WizardStepProps } from './WizardStep'
|
|
17
|
+
export { WizardStepper } from './WizardStepper'
|
|
18
|
+
export type { WizardStepperProps, WizardStepperVariant } from './WizardStepper'
|
|
19
|
+
export { PromptWithAction } from './PromptWithAction'
|
|
20
|
+
export type { PromptWithActionAllProps } from './PromptWithAction'
|
|
21
|
+
export { Section } from './Section'
|
|
22
|
+
export type { SectionProps } from './Section'
|
|
23
|
+
export { Form } from './Form'
|
|
24
|
+
export type { FormProps } from './Form'
|
|
25
|
+
export { BlockQuote } from './BlockQuote'
|
|
26
|
+
export type { BlockQuoteProps, BlockQuoteJustify } from './BlockQuote'
|
|
27
|
+
|
|
28
|
+
export { PageHeading } from './PageHeading'
|
|
29
|
+
export type { PageHeadingProps } from './PageHeading'
|
|
30
|
+
export { Card } from './Card'
|
|
31
|
+
export type {
|
|
32
|
+
CardProps,
|
|
33
|
+
CardComponent,
|
|
34
|
+
CardHeaderProps,
|
|
35
|
+
CardImageProps,
|
|
36
|
+
CardAvatarTitleProps,
|
|
37
|
+
CardContentProps,
|
|
38
|
+
CardBodyProps,
|
|
39
|
+
} from './Card'
|
|
40
|
+
export { Container } from './Container'
|
|
41
|
+
export type { ContainerProps, ContainerSize, ContainerAlign } from './Container'
|
|
42
|
+
export { Grid } from './Grid'
|
|
43
|
+
export type { GridProps, GridCols, GridGap } from './Grid'
|
|
44
|
+
export { FormActions } from './FormActions'
|
|
45
|
+
export type { FormActionsAllProps } from './FormActions'
|
|
46
|
+
export { TablePanel } from './TablePanel'
|
|
47
|
+
export type { TablePanelProps } from './TablePanel'
|
|
48
|
+
|
|
49
|
+
export { TableView, useTableView, emptyFilterGroup } from './TableView'
|
|
50
|
+
export type { TableViewProps, TableViewContextValue } from './TableView'
|
|
51
|
+
export type { TableViewConfig, ViewConfig } from './TableView/types'
|
|
52
|
+
|
|
53
|
+
export { CodeBlock } from './CodeBlock/CodeBlock'
|
|
54
|
+
export type { CodeBlockProps, CodeBlockLanguage } from './CodeBlock/CodeBlock'
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
AccordionRoot,
|
|
58
|
+
AccordionItem,
|
|
59
|
+
AccordionHeader,
|
|
60
|
+
AccordionTrigger,
|
|
61
|
+
AccordionContent,
|
|
62
|
+
AccordionContentStyled,
|
|
63
|
+
AccordionTriggerStyled,
|
|
64
|
+
AccordionItemStyled,
|
|
65
|
+
} from './Accordion'
|
|
66
|
+
export type { AccordionContentProps, AccordionTriggerStyledProps, AccordionItemStyledProps } from './Accordion'
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
TooltipRoot,
|
|
70
|
+
TooltipTrigger,
|
|
71
|
+
TooltipPortal,
|
|
72
|
+
TooltipContentPrimitive,
|
|
73
|
+
TooltipArrow,
|
|
74
|
+
TooltipContent,
|
|
75
|
+
} from '../overlays/Tooltip'
|
|
76
|
+
export type { TooltipContentProps } from '../overlays/Tooltip'
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
PopoverRoot,
|
|
80
|
+
PopoverTrigger,
|
|
81
|
+
PopoverAnchor,
|
|
82
|
+
PopoverPortal,
|
|
83
|
+
PopoverContentPrimitive,
|
|
84
|
+
PopoverArrow,
|
|
85
|
+
PopoverContent,
|
|
86
|
+
} from '../overlays/Popover'
|
|
87
|
+
export type { PopoverContentProps, PopoverRootProps, PopoverSide, PopoverAlign } from '../overlays/Popover'
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
CollapsibleRoot,
|
|
91
|
+
CollapsibleTrigger,
|
|
92
|
+
CollapsibleContent,
|
|
93
|
+
CollapsibleContentStyled,
|
|
94
|
+
CollapsibleTriggerStyled,
|
|
95
|
+
} from './Collapsible'
|
|
96
|
+
export type { CollapsibleContentProps, CollapsibleTriggerStyledProps } from './Collapsible'
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type JSX, For, Show, splitProps } from 'solid-js'
|
|
2
|
+
import { ChevronRight } from 'lucide-solid'
|
|
3
|
+
import { Breadcrumbs as KobalteBreadcrumbs } from '@kobalte/core/breadcrumbs'
|
|
4
|
+
import { cn } from '../../utilities/classNames'
|
|
5
|
+
|
|
6
|
+
export interface BreadcrumbItem {
|
|
7
|
+
/** Label to show. */
|
|
8
|
+
label: string
|
|
9
|
+
/** If set, rendered as a link (anchor). Use your router's Link in the app if needed. */
|
|
10
|
+
href?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface BreadcrumbsProps {
|
|
14
|
+
/** List of items. Last item is typically current page (no href). */
|
|
15
|
+
items: BreadcrumbItem[]
|
|
16
|
+
/** Optional separator between items. Default ChevronRight. */
|
|
17
|
+
separator?: JSX.Element
|
|
18
|
+
/** Root class. */
|
|
19
|
+
class?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function DefaultSeparator(): JSX.Element {
|
|
23
|
+
return <ChevronRight class="h-4 w-4 shrink-0 text-ink-400" aria-hidden="true" />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function Breadcrumbs(props: BreadcrumbsProps) {
|
|
27
|
+
const [local] = splitProps(props, ['items', 'separator', 'class'])
|
|
28
|
+
|
|
29
|
+
const separator = () => local.separator ?? <DefaultSeparator />
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<KobalteBreadcrumbs class={cn('flex flex-wrap items-center gap-1 text-sm', local.class)}>
|
|
33
|
+
<ol class="flex flex-wrap items-center gap-1">
|
|
34
|
+
<For each={local.items}>
|
|
35
|
+
{(item, i) => {
|
|
36
|
+
const isLast = () => i() === local.items.length - 1
|
|
37
|
+
return (
|
|
38
|
+
<li class="flex items-center gap-1" classList={{ 'text-ink-500': !isLast() }}>
|
|
39
|
+
<Show when={i() > 0}>
|
|
40
|
+
<KobalteBreadcrumbs.Separator class="flex shrink-0">
|
|
41
|
+
{separator()}
|
|
42
|
+
</KobalteBreadcrumbs.Separator>
|
|
43
|
+
</Show>
|
|
44
|
+
<Show
|
|
45
|
+
when={!!item.href && !isLast()}
|
|
46
|
+
fallback={
|
|
47
|
+
<span class="font-medium text-ink-800" {...(isLast() && { 'aria-current': 'page' })}>
|
|
48
|
+
{item.label}
|
|
49
|
+
</span>
|
|
50
|
+
}
|
|
51
|
+
>
|
|
52
|
+
<KobalteBreadcrumbs.Link
|
|
53
|
+
href={item.href!}
|
|
54
|
+
class="text-ink-600 hover:text-ink-900 dark:hover:text-ink-100 underline-offset-2 hover:underline"
|
|
55
|
+
>
|
|
56
|
+
{item.label}
|
|
57
|
+
</KobalteBreadcrumbs.Link>
|
|
58
|
+
</Show>
|
|
59
|
+
</li>
|
|
60
|
+
)
|
|
61
|
+
}}
|
|
62
|
+
</For>
|
|
63
|
+
</ol>
|
|
64
|
+
</KobalteBreadcrumbs>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type JSX, splitProps } from 'solid-js'
|
|
2
|
+
import { DropdownMenu as KobalteDropdownMenu } from '@kobalte/core/dropdown-menu'
|
|
3
|
+
import type {
|
|
4
|
+
DropdownMenuContentProps as KobalteDropdownMenuContentProps,
|
|
5
|
+
DropdownMenuItemProps as KobalteDropdownMenuItemProps,
|
|
6
|
+
DropdownMenuSeparatorProps as KobalteDropdownMenuSeparatorProps,
|
|
7
|
+
DropdownMenuTriggerProps as KobalteDropdownMenuTriggerProps
|
|
8
|
+
} from '@kobalte/core/dropdown-menu'
|
|
9
|
+
import { cn } from '../../utilities/classNames'
|
|
10
|
+
|
|
11
|
+
export interface DropdownMenuContentProps extends KobalteDropdownMenuContentProps {
|
|
12
|
+
class?: string
|
|
13
|
+
children: JSX.Element
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function DropdownMenuContent(props: DropdownMenuContentProps) {
|
|
17
|
+
const [local, others] = splitProps(props, ['class', 'children'])
|
|
18
|
+
return (
|
|
19
|
+
<KobalteDropdownMenu.Portal>
|
|
20
|
+
<KobalteDropdownMenu.Content
|
|
21
|
+
class={cn(
|
|
22
|
+
'z-50 min-w-[160px] rounded-lg border border-surface-border bg-surface-raised p-1 shadow-lg',
|
|
23
|
+
local.class,
|
|
24
|
+
)}
|
|
25
|
+
{...others}
|
|
26
|
+
>
|
|
27
|
+
{local.children}
|
|
28
|
+
</KobalteDropdownMenu.Content>
|
|
29
|
+
</KobalteDropdownMenu.Portal>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface DropdownMenuItemProps extends KobalteDropdownMenuItemProps {
|
|
34
|
+
class?: string
|
|
35
|
+
children: JSX.Element
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function DropdownMenuItem(props: DropdownMenuItemProps) {
|
|
39
|
+
const [local, others] = splitProps(props, ['class', 'children'])
|
|
40
|
+
return (
|
|
41
|
+
<KobalteDropdownMenu.Item
|
|
42
|
+
class={cn(
|
|
43
|
+
'flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 text-sm text-ink-700 outline-none',
|
|
44
|
+
'data-[highlighted]:bg-surface-overlay data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed',
|
|
45
|
+
local.class,
|
|
46
|
+
)}
|
|
47
|
+
{...others}
|
|
48
|
+
>
|
|
49
|
+
{local.children}
|
|
50
|
+
</KobalteDropdownMenu.Item>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface DropdownMenuSeparatorProps extends KobalteDropdownMenuSeparatorProps {
|
|
55
|
+
class?: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function DropdownMenuSeparator(props: DropdownMenuSeparatorProps) {
|
|
59
|
+
const [local, others] = splitProps(props, ['class'])
|
|
60
|
+
return (
|
|
61
|
+
<KobalteDropdownMenu.Separator
|
|
62
|
+
class={cn('my-1 h-px bg-surface-dim', local.class)}
|
|
63
|
+
{...others}
|
|
64
|
+
/>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface DropdownMenuTriggerProps extends Omit<KobalteDropdownMenuTriggerProps, 'class' | 'children'> {
|
|
69
|
+
class?: string
|
|
70
|
+
children: JSX.Element
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function DropdownMenuTrigger(props: DropdownMenuTriggerProps) {
|
|
74
|
+
const [local, others] = splitProps(props, ['class', 'children'])
|
|
75
|
+
return (
|
|
76
|
+
<KobalteDropdownMenu.Trigger
|
|
77
|
+
class={cn(local.class)}
|
|
78
|
+
{...others}
|
|
79
|
+
>
|
|
80
|
+
{local.children}
|
|
81
|
+
</KobalteDropdownMenu.Trigger>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Re-export the root Kobalte DropdownMenu for convenience
|
|
86
|
+
export { DropdownMenu } from '@kobalte/core/dropdown-menu'
|