@octanejs/shadcn 0.0.8 → 0.0.10
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 +170 -3
- package/package.json +26 -9
- package/src/bases/base-ui/ui/avatar.tsrx +89 -0
- package/src/bases/base-ui/ui/badge.tsrx +56 -0
- package/src/bases/base-ui/ui/breadcrumb.tsrx +109 -0
- package/src/bases/base-ui/ui/collapsible.tsrx +25 -0
- package/src/bases/base-ui/ui/dropdown-menu.tsrx +292 -0
- package/src/bases/base-ui/ui/field.tsrx +201 -0
- package/src/bases/base-ui/ui/item.tsrx +163 -0
- package/src/bases/base-ui/ui/pagination.tsrx +125 -0
- package/src/bases/base-ui/ui/popover.tsrx +43 -4
- package/src/bases/base-ui/ui/progress.tsrx +46 -0
- package/src/bases/base-ui/ui/radio-group.tsrx +14 -2
- package/src/bases/base-ui/ui/sheet.tsrx +121 -0
- package/src/bases/base-ui/ui/slider.tsrx +111 -0
- package/src/bases/base-ui/ui/table.tsrx +85 -0
- package/src/bases/base-ui/ui/toggle-group.tsrx +124 -0
- package/src/bases/base-ui/ui/toggle.tsrx +57 -0
- package/src/bases/base-ui/ui/tooltip.tsrx +39 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Base UI base toggle-group — runs on @octanejs/base-ui's ToggleGroup.
|
|
2
|
+
//
|
|
3
|
+
// THERE IS NO `Item` PART. Verified by rendering the primitive: Base UI's ToggleGroup is a single
|
|
4
|
+
// component whose children are ordinary `Toggle`s carrying a `value`, where radix pairs
|
|
5
|
+
// `ToggleGroup.Root` with `ToggleGroup.Item`. So `ToggleGroupItem` here wraps `Toggle` — the same
|
|
6
|
+
// primitive `toggle.tsrx` uses — and the exported names and `data-slot` values stay as shadcn
|
|
7
|
+
// defines them, so consumers see no difference between bases.
|
|
8
|
+
//
|
|
9
|
+
// TWO API DIFFERENCES A CONSUMER CAN OBSERVE, both inherent to the primitive:
|
|
10
|
+
//
|
|
11
|
+
// 1. `type="single" | "multiple"` is translated to Base UI's `multiple` boolean, so markup
|
|
12
|
+
// written against the radix base keeps working.
|
|
13
|
+
//
|
|
14
|
+
// 2. VALUES ARE ALWAYS ARRAYS. Base UI's `value` / `defaultValue` / `onValueChange` speak
|
|
15
|
+
// `string[]` in both modes, where radix's single mode speaks a bare `string`. That is not
|
|
16
|
+
// translated: faking a scalar would mean inventing conversion behavior on every change, and
|
|
17
|
+
// silently reshaping the argument to the consumer's handler is worse than a documented
|
|
18
|
+
// difference. Single mode still yields at most one entry.
|
|
19
|
+
//
|
|
20
|
+
// The pressed dialect is `data-pressed`, not radix's `data-[state=on]` — see toggle.tsrx, whose
|
|
21
|
+
// `toggleVariants` this file reuses, so the two bases cannot drift apart.
|
|
22
|
+
//
|
|
23
|
+
// ToggleGroup is composed with createElement: the consumer's children must sit INSIDE the context
|
|
24
|
+
// Provider, and opaque compiled .tsrx children can only flow through the props.children channel
|
|
25
|
+
// (see breadcrumb.tsrx's comment).
|
|
26
|
+
//
|
|
27
|
+
// UNVERIFIED PROVENANCE: class strings come from this package's radix base rather than
|
|
28
|
+
// transcribed from upstream's Base UI source.
|
|
29
|
+
import { createContext, createElement, useContext, type OctaneNode } from 'octane';
|
|
30
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
31
|
+
import { ToggleGroup as ToggleGroupPrimitive } from '@octanejs/base-ui/toggle-group';
|
|
32
|
+
import { Toggle as TogglePrimitive } from '@octanejs/base-ui/toggle';
|
|
33
|
+
|
|
34
|
+
import { cn } from '../../../lib/utils';
|
|
35
|
+
import { toggleVariants } from './toggle.tsrx';
|
|
36
|
+
|
|
37
|
+
const ToggleGroupContext = createContext<
|
|
38
|
+
VariantProps<typeof toggleVariants> & {
|
|
39
|
+
spacing?: number;
|
|
40
|
+
orientation?: 'horizontal' | 'vertical';
|
|
41
|
+
}
|
|
42
|
+
>({
|
|
43
|
+
size: 'default',
|
|
44
|
+
variant: 'default',
|
|
45
|
+
spacing: 2,
|
|
46
|
+
orientation: 'horizontal',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export interface ToggleGroupProps extends Record<string, unknown> {
|
|
50
|
+
className?: string;
|
|
51
|
+
variant?: VariantProps<typeof toggleVariants>['variant'];
|
|
52
|
+
size?: VariantProps<typeof toggleVariants>['size'];
|
|
53
|
+
spacing?: number;
|
|
54
|
+
orientation?: 'horizontal' | 'vertical';
|
|
55
|
+
type?: 'single' | 'multiple';
|
|
56
|
+
children?: OctaneNode;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function ToggleGroup({
|
|
60
|
+
className,
|
|
61
|
+
variant,
|
|
62
|
+
size,
|
|
63
|
+
spacing = 2,
|
|
64
|
+
orientation = 'horizontal',
|
|
65
|
+
type,
|
|
66
|
+
children,
|
|
67
|
+
...props
|
|
68
|
+
}: ToggleGroupProps) {
|
|
69
|
+
return createElement(
|
|
70
|
+
ToggleGroupPrimitive,
|
|
71
|
+
{
|
|
72
|
+
'data-slot': 'toggle-group',
|
|
73
|
+
'data-variant': variant,
|
|
74
|
+
'data-size': size,
|
|
75
|
+
'data-spacing': spacing,
|
|
76
|
+
// Forwarded to the primitive: it drives the arrow-key axis (a vertical group must
|
|
77
|
+
// ignore left/right and use up/down). The primitive also emits `data-orientation`
|
|
78
|
+
// itself, so unlike the radix base this is not set by hand.
|
|
79
|
+
orientation,
|
|
80
|
+
multiple: type === 'multiple',
|
|
81
|
+
style: { '--gap': spacing },
|
|
82
|
+
className: cn(
|
|
83
|
+
'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',
|
|
84
|
+
className,
|
|
85
|
+
),
|
|
86
|
+
...props,
|
|
87
|
+
},
|
|
88
|
+
createElement(
|
|
89
|
+
ToggleGroupContext.Provider,
|
|
90
|
+
{ value: { variant, size, spacing, orientation } },
|
|
91
|
+
children,
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ToggleGroupItemProps extends Record<string, unknown> {
|
|
97
|
+
className?: string;
|
|
98
|
+
variant?: VariantProps<typeof toggleVariants>['variant'];
|
|
99
|
+
size?: VariantProps<typeof toggleVariants>['size'];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function ToggleGroupItem({
|
|
103
|
+
className,
|
|
104
|
+
variant = 'default',
|
|
105
|
+
size = 'default',
|
|
106
|
+
...props
|
|
107
|
+
}: ToggleGroupItemProps) @{
|
|
108
|
+
const context = useContext(ToggleGroupContext);
|
|
109
|
+
<TogglePrimitive
|
|
110
|
+
data-slot="toggle-group-item"
|
|
111
|
+
data-variant={context.variant || variant}
|
|
112
|
+
data-size={context.size || size}
|
|
113
|
+
data-spacing={context.spacing}
|
|
114
|
+
className={cn(
|
|
115
|
+
'min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l',
|
|
116
|
+
toggleVariants({
|
|
117
|
+
variant: context.variant || variant,
|
|
118
|
+
size: context.size || size,
|
|
119
|
+
}),
|
|
120
|
+
className,
|
|
121
|
+
)}
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Base UI base toggle — runs on @octanejs/base-ui's Toggle.
|
|
2
|
+
//
|
|
3
|
+
// THE PRESSED-STATE DIALECT DIFFERS, verified by rendering the primitive: Base UI emits a bare
|
|
4
|
+
// `data-pressed` attribute (alongside `aria-pressed`), where radix emits `data-state="on"`. So
|
|
5
|
+
// the radix base's `data-[state=on]:` utilities are replaced with `data-pressed:` — copying them
|
|
6
|
+
// unchanged would leave a toggle that never shows its pressed styling, with nothing failing.
|
|
7
|
+
//
|
|
8
|
+
// `disabled:` is kept rather than converted: Base UI's Toggle renders a real `<button>` (again
|
|
9
|
+
// verified by rendering), so the `:disabled` pseudo-class does match here — unlike checkbox,
|
|
10
|
+
// switch and radio, whose Roots are spans.
|
|
11
|
+
//
|
|
12
|
+
// UNVERIFIED PROVENANCE: the non-conditional utilities come from this package's radix base
|
|
13
|
+
// rather than transcribed from upstream's Base UI source.
|
|
14
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
15
|
+
import { Toggle as TogglePrimitive } from '@octanejs/base-ui/toggle';
|
|
16
|
+
|
|
17
|
+
import { cn } from '../../../lib/utils';
|
|
18
|
+
|
|
19
|
+
export const toggleVariants = cva(
|
|
20
|
+
'inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-pressed:bg-accent data-pressed:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: 'bg-transparent',
|
|
25
|
+
outline: 'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',
|
|
26
|
+
},
|
|
27
|
+
size: {
|
|
28
|
+
default: 'h-9 min-w-9 px-2',
|
|
29
|
+
sm: 'h-8 min-w-8 px-1.5',
|
|
30
|
+
lg: 'h-10 min-w-10 px-2.5',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: {
|
|
34
|
+
variant: 'default',
|
|
35
|
+
size: 'default',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
export interface ToggleProps extends Record<string, unknown> {
|
|
41
|
+
className?: string;
|
|
42
|
+
variant?: VariantProps<typeof toggleVariants>['variant'];
|
|
43
|
+
size?: VariantProps<typeof toggleVariants>['size'];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function Toggle({
|
|
47
|
+
className,
|
|
48
|
+
variant = 'default',
|
|
49
|
+
size = 'default',
|
|
50
|
+
...props
|
|
51
|
+
}: ToggleProps) @{
|
|
52
|
+
<TogglePrimitive
|
|
53
|
+
data-slot="toggle"
|
|
54
|
+
className={cn(toggleVariants({ variant, size, className }))}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
}
|
|
@@ -39,15 +39,53 @@ export interface TooltipContentProps extends Record<string, unknown> {
|
|
|
39
39
|
children?: OctaneNode;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
export interface BaseUiPositioningProps {
|
|
43
|
+
/** Forwarded to the Positioner; see the note at the top of this file. */
|
|
44
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
45
|
+
sideOffset?: number;
|
|
46
|
+
align?: 'start' | 'center' | 'end';
|
|
47
|
+
alignOffset?: number;
|
|
48
|
+
anchor?: unknown;
|
|
49
|
+
positionMethod?: 'absolute' | 'fixed';
|
|
50
|
+
collisionBoundary?: unknown;
|
|
51
|
+
collisionPadding?: unknown;
|
|
52
|
+
collisionAvoidance?: unknown;
|
|
53
|
+
arrowPadding?: number;
|
|
54
|
+
sticky?: boolean;
|
|
55
|
+
disableAnchorTracking?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
42
58
|
export function TooltipContent({
|
|
43
59
|
className,
|
|
44
60
|
sideOffset = 0,
|
|
61
|
+
align,
|
|
62
|
+
side,
|
|
63
|
+
alignOffset,
|
|
64
|
+
anchor,
|
|
65
|
+
positionMethod,
|
|
66
|
+
collisionBoundary,
|
|
67
|
+
collisionPadding,
|
|
68
|
+
collisionAvoidance,
|
|
69
|
+
arrowPadding,
|
|
70
|
+
sticky,
|
|
71
|
+
disableAnchorTracking,
|
|
45
72
|
children,
|
|
46
73
|
...props
|
|
47
|
-
}: TooltipContentProps) {
|
|
74
|
+
}: TooltipContentProps & BaseUiPositioningProps) {
|
|
48
75
|
return createElement(TooltipPrimitive.Portal, {
|
|
49
76
|
children: createElement(TooltipPrimitive.Positioner, {
|
|
77
|
+
side,
|
|
50
78
|
sideOffset,
|
|
79
|
+
align,
|
|
80
|
+
alignOffset,
|
|
81
|
+
anchor,
|
|
82
|
+
positionMethod,
|
|
83
|
+
collisionBoundary,
|
|
84
|
+
collisionPadding,
|
|
85
|
+
collisionAvoidance,
|
|
86
|
+
arrowPadding,
|
|
87
|
+
sticky,
|
|
88
|
+
disableAnchorTracking,
|
|
51
89
|
children: createElement(TooltipPrimitive.Popup, {
|
|
52
90
|
'data-slot': 'tooltip-content',
|
|
53
91
|
className: cn(
|