@zentauri-ui/zentauri-components 1.4.51 → 1.4.62
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 +63 -1
- package/cli/registry.json +2 -1
- package/dist/{chunk-UXGHUBNJ.mjs → chunk-2PJF7DLJ.mjs} +3 -3
- package/dist/{chunk-UXGHUBNJ.mjs.map → chunk-2PJF7DLJ.mjs.map} +1 -1
- package/dist/{chunk-WDCIZHXY.mjs → chunk-45FCOQ63.mjs} +5 -3
- package/dist/chunk-45FCOQ63.mjs.map +1 -0
- package/dist/{chunk-RDSPHBHK.mjs → chunk-4ANBTJ5G.mjs} +49 -6
- package/dist/chunk-4ANBTJ5G.mjs.map +1 -0
- package/dist/chunk-4E66ICIR.mjs +158 -0
- package/dist/chunk-4E66ICIR.mjs.map +1 -0
- package/dist/{chunk-XLAFQ24R.js → chunk-4U6FOCFK.js} +22 -14
- package/dist/chunk-4U6FOCFK.js.map +1 -0
- package/dist/{chunk-XWM2S6VV.mjs → chunk-EQSSYK27.mjs} +12 -10
- package/dist/chunk-EQSSYK27.mjs.map +1 -0
- package/dist/{chunk-5QB2KNZQ.js → chunk-FGGYDAX3.js} +5 -3
- package/dist/chunk-FGGYDAX3.js.map +1 -0
- package/dist/{chunk-7HL3A4YF.mjs → chunk-IK75NHRX.mjs} +63 -14
- package/dist/chunk-IK75NHRX.mjs.map +1 -0
- package/dist/{chunk-BORK3BJO.mjs → chunk-J56L4ZQ3.mjs} +10 -10
- package/dist/{chunk-BORK3BJO.mjs.map → chunk-J56L4ZQ3.mjs.map} +1 -1
- package/dist/{chunk-PGH27VTL.mjs → chunk-JF3FKUUP.mjs} +21 -13
- package/dist/chunk-JF3FKUUP.mjs.map +1 -0
- package/dist/{chunk-WZKGRU3U.js → chunk-MQZB5EPD.js} +92 -27
- package/dist/chunk-MQZB5EPD.js.map +1 -0
- package/dist/{chunk-N4NO3SYL.js → chunk-NX3IHMT7.js} +22 -14
- package/dist/chunk-NX3IHMT7.js.map +1 -0
- package/dist/{chunk-BVXTOEBI.mjs → chunk-OG2WM5YK.mjs} +45 -17
- package/dist/chunk-OG2WM5YK.mjs.map +1 -0
- package/dist/{chunk-IXDJ3IPG.mjs → chunk-OXS6UJUG.mjs} +21 -13
- package/dist/chunk-OXS6UJUG.mjs.map +1 -0
- package/dist/{chunk-PCK6LX3K.js → chunk-PFOV3U7W.js} +3 -3
- package/dist/{chunk-PCK6LX3K.js.map → chunk-PFOV3U7W.js.map} +1 -1
- package/dist/{chunk-2PQEXQVR.js → chunk-THCNTPPL.js} +62 -13
- package/dist/chunk-THCNTPPL.js.map +1 -0
- package/dist/chunk-UP6S75V5.js +160 -0
- package/dist/chunk-UP6S75V5.js.map +1 -0
- package/dist/{chunk-P5HUBXUX.js → chunk-V2IWLR4O.js} +48 -5
- package/dist/chunk-V2IWLR4O.js.map +1 -0
- package/dist/{chunk-3OR47XMY.js → chunk-VSKL5LOB.js} +45 -17
- package/dist/chunk-VSKL5LOB.js.map +1 -0
- package/dist/{chunk-E3DZNJAD.js → chunk-Y4EDWZKH.js} +12 -10
- package/dist/chunk-Y4EDWZKH.js.map +1 -0
- package/dist/{chunk-YNCD6TKE.mjs → chunk-Y4IFVO46.mjs} +93 -28
- package/dist/chunk-Y4IFVO46.mjs.map +1 -0
- package/dist/{chunk-BITDSQMR.js → chunk-ZNDHS5OK.js} +10 -10
- package/dist/{chunk-BITDSQMR.js.map → chunk-ZNDHS5OK.js.map} +1 -1
- package/dist/hooks/useFocusManagement/useFocusManagement.d.ts +5 -14
- package/dist/hooks/useFocusManagement/useFocusManagement.d.ts.map +1 -1
- package/dist/hooks/useFocusManagement.js +2 -2
- package/dist/hooks/useFocusManagement.mjs +1 -1
- package/dist/ui/badge/animated.js +2 -2
- package/dist/ui/badge/animated.mjs +1 -1
- package/dist/ui/badge/badge-base.d.ts +1 -1
- package/dist/ui/badge/badge-base.d.ts.map +1 -1
- package/dist/ui/badge/types.d.ts +1 -0
- package/dist/ui/badge/types.d.ts.map +1 -1
- package/dist/ui/badge/variants.d.ts +7 -7
- package/dist/ui/badge.js +4 -4
- package/dist/ui/badge.mjs +2 -2
- package/dist/ui/buttons/animated.js +3 -3
- package/dist/ui/buttons/animated.mjs +1 -1
- package/dist/ui/buttons.js +4 -4
- package/dist/ui/buttons.mjs +2 -2
- package/dist/ui/drawer/animated/drawer-content-animated.d.ts.map +1 -1
- package/dist/ui/drawer/animated.js +17 -18
- package/dist/ui/drawer/animated.js.map +1 -1
- package/dist/ui/drawer/animated.mjs +8 -9
- package/dist/ui/drawer/animated.mjs.map +1 -1
- package/dist/ui/drawer/drawer-base.d.ts +1 -1
- package/dist/ui/drawer/drawer-base.d.ts.map +1 -1
- package/dist/ui/drawer/types.d.ts +1 -0
- package/dist/ui/drawer/types.d.ts.map +1 -1
- package/dist/ui/drawer.js +12 -12
- package/dist/ui/drawer.mjs +2 -2
- package/dist/ui/dropdown/dropdown.d.ts +1 -1
- package/dist/ui/dropdown/dropdown.d.ts.map +1 -1
- package/dist/ui/dropdown/types.d.ts +1 -0
- package/dist/ui/dropdown/types.d.ts.map +1 -1
- package/dist/ui/dropdown/variants.d.ts +1 -1
- package/dist/ui/dropdown.js +25 -7
- package/dist/ui/dropdown.js.map +1 -1
- package/dist/ui/dropdown.mjs +26 -8
- package/dist/ui/dropdown.mjs.map +1 -1
- package/dist/ui/empty-state/animated.js +2 -2
- package/dist/ui/empty-state/animated.mjs +1 -1
- package/dist/ui/empty-state/empty-state-base.d.ts.map +1 -1
- package/dist/ui/empty-state/types.d.ts +1 -0
- package/dist/ui/empty-state/types.d.ts.map +1 -1
- package/dist/ui/empty-state.js +10 -10
- package/dist/ui/empty-state.mjs +2 -2
- package/dist/ui/file-upload/file-upload.d.ts.map +1 -1
- package/dist/ui/file-upload.js +1 -3
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/file-upload.mjs +1 -3
- package/dist/ui/file-upload.mjs.map +1 -1
- package/dist/ui/inputs/input-base.d.ts.map +1 -1
- package/dist/ui/inputs/types.d.ts +3 -1
- package/dist/ui/inputs/types.d.ts.map +1 -1
- package/dist/ui/inputs.js +46 -2
- package/dist/ui/inputs.js.map +1 -1
- package/dist/ui/inputs.mjs +46 -2
- package/dist/ui/inputs.mjs.map +1 -1
- package/dist/ui/modal/animated/modal-content-animated.d.ts.map +1 -1
- package/dist/ui/modal/animated.js +10 -11
- package/dist/ui/modal/animated.js.map +1 -1
- package/dist/ui/modal/animated.mjs +7 -8
- package/dist/ui/modal/animated.mjs.map +1 -1
- package/dist/ui/modal/modal-base.d.ts +4 -2
- package/dist/ui/modal/modal-base.d.ts.map +1 -1
- package/dist/ui/modal.js +13 -13
- package/dist/ui/modal.mjs +3 -3
- package/dist/ui/pagination.js +6 -6
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/pagination.mjs +3 -3
- package/dist/ui/pagination.mjs.map +1 -1
- package/dist/ui/progress/animated/progress-animated.d.ts.map +1 -1
- package/dist/ui/progress/animated.js +49 -11
- package/dist/ui/progress/animated.js.map +1 -1
- package/dist/ui/progress/animated.mjs +44 -6
- package/dist/ui/progress/animated.mjs.map +1 -1
- package/dist/ui/progress/progress-base.d.ts.map +1 -1
- package/dist/ui/progress/types.d.ts +3 -0
- package/dist/ui/progress/types.d.ts.map +1 -1
- package/dist/ui/progress.js +9 -9
- package/dist/ui/progress.mjs +2 -2
- package/dist/ui/search/search-bar.d.ts +1 -1
- package/dist/ui/search/search-bar.d.ts.map +1 -1
- package/dist/ui/search/search-suggestion-list.d.ts.map +1 -1
- package/dist/ui/search.js +12 -6
- package/dist/ui/search.js.map +1 -1
- package/dist/ui/search.mjs +12 -6
- package/dist/ui/search.mjs.map +1 -1
- package/dist/ui/select/select.d.ts +1 -1
- package/dist/ui/select/select.d.ts.map +1 -1
- package/dist/ui/select/types.d.ts +1 -0
- package/dist/ui/select/types.d.ts.map +1 -1
- package/dist/ui/select/variants.d.ts +1 -1
- package/dist/ui/select/variants.d.ts.map +1 -1
- package/dist/ui/select.js +121 -39
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/select.mjs +122 -40
- package/dist/ui/select.mjs.map +1 -1
- package/dist/ui/skeleton/variants.d.ts +1 -1
- package/dist/ui/slider/slider.d.ts.map +1 -1
- package/dist/ui/slider/types.d.ts +8 -2
- package/dist/ui/slider/types.d.ts.map +1 -1
- package/dist/ui/slider.js +43 -7
- package/dist/ui/slider.js.map +1 -1
- package/dist/ui/slider.mjs +43 -7
- package/dist/ui/slider.mjs.map +1 -1
- package/dist/ui/spinner/animated/spinner.d.ts.map +1 -1
- package/dist/ui/spinner/animated.js +62 -50
- package/dist/ui/spinner/animated.js.map +1 -1
- package/dist/ui/spinner/animated.mjs +63 -51
- package/dist/ui/spinner/animated.mjs.map +1 -1
- package/dist/ui/stepper/stepper.d.ts +2 -7
- package/dist/ui/stepper/stepper.d.ts.map +1 -1
- package/dist/ui/stepper/types.d.ts +3 -3
- package/dist/ui/stepper/types.d.ts.map +1 -1
- package/dist/ui/stepper/variants.d.ts +1 -1
- package/dist/ui/stepper.js +7 -5
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/stepper.mjs +7 -5
- package/dist/ui/stepper.mjs.map +1 -1
- package/dist/ui/table/animated.js +8 -8
- package/dist/ui/table/animated.mjs +2 -2
- package/dist/ui/table/table-base.d.ts +1 -1
- package/dist/ui/table/table-base.d.ts.map +1 -1
- package/dist/ui/table/types.d.ts +5 -1
- package/dist/ui/table/types.d.ts.map +1 -1
- package/dist/ui/table.js +14 -14
- package/dist/ui/table.mjs +1 -1
- package/dist/ui/tabs/animated.js +2 -2
- package/dist/ui/tabs/animated.mjs +1 -1
- package/dist/ui/tabs/tabs-base.d.ts.map +1 -1
- package/dist/ui/tabs/types.d.ts +2 -1
- package/dist/ui/tabs/types.d.ts.map +1 -1
- package/dist/ui/tabs.js +9 -9
- package/dist/ui/tabs.mjs +1 -1
- package/dist/ui/toast/animated.js +7 -7
- package/dist/ui/toast/animated.mjs +1 -1
- package/dist/ui/toast.js +12 -12
- package/dist/ui/toast.mjs +1 -1
- package/dist/ui/toggle/toggle-base.d.ts.map +1 -1
- package/dist/ui/toggle.js +28 -3
- package/dist/ui/toggle.js.map +1 -1
- package/dist/ui/toggle.mjs +29 -4
- package/dist/ui/toggle.mjs.map +1 -1
- package/dist/ui/tooltip/animated.js +3 -3
- package/dist/ui/tooltip/animated.mjs +1 -1
- package/dist/ui/tooltip/tooltip-base.d.ts.map +1 -1
- package/dist/ui/tooltip/types.d.ts +1 -0
- package/dist/ui/tooltip/types.d.ts.map +1 -1
- package/dist/ui/tooltip.js +7 -7
- package/dist/ui/tooltip.mjs +1 -1
- package/dist/ui/typography/blockquote-base.d.ts +6 -0
- package/dist/ui/typography/blockquote-base.d.ts.map +1 -0
- package/dist/ui/typography/blockquote.d.ts +6 -0
- package/dist/ui/typography/blockquote.d.ts.map +1 -0
- package/dist/ui/typography/code-block-base.d.ts +6 -0
- package/dist/ui/typography/code-block-base.d.ts.map +1 -0
- package/dist/ui/typography/code-block.d.ts +6 -0
- package/dist/ui/typography/code-block.d.ts.map +1 -0
- package/dist/ui/typography/heading-base.d.ts +6 -0
- package/dist/ui/typography/heading-base.d.ts.map +1 -0
- package/dist/ui/typography/heading.d.ts +6 -0
- package/dist/ui/typography/heading.d.ts.map +1 -0
- package/dist/ui/typography/index.d.ts +9 -0
- package/dist/ui/typography/index.d.ts.map +1 -0
- package/dist/ui/typography/inline-code-base.d.ts +6 -0
- package/dist/ui/typography/inline-code-base.d.ts.map +1 -0
- package/dist/ui/typography/inline-code.d.ts +6 -0
- package/dist/ui/typography/inline-code.d.ts.map +1 -0
- package/dist/ui/typography/list-base.d.ts +10 -0
- package/dist/ui/typography/list-base.d.ts.map +1 -0
- package/dist/ui/typography/list.d.ts +12 -0
- package/dist/ui/typography/list.d.ts.map +1 -0
- package/dist/ui/typography/text-base.d.ts +6 -0
- package/dist/ui/typography/text-base.d.ts.map +1 -0
- package/dist/ui/typography/text.d.ts +6 -0
- package/dist/ui/typography/text.d.ts.map +1 -0
- package/dist/ui/typography/types.d.ts +56 -0
- package/dist/ui/typography/types.d.ts.map +1 -0
- package/dist/ui/typography/variants.d.ts +16 -0
- package/dist/ui/typography/variants.d.ts.map +1 -0
- package/dist/ui/typography.js +334 -0
- package/dist/ui/typography.js.map +1 -0
- package/dist/ui/typography.mjs +321 -0
- package/dist/ui/typography.mjs.map +1 -0
- package/package.json +1 -1
- package/src/hooks/useFocusManagement/useFocusManagement.test.tsx +8 -0
- package/src/hooks/useFocusManagement/useFocusManagement.ts +162 -33
- package/src/ui/badge/badge-base.tsx +4 -1
- package/src/ui/badge/types.ts +1 -0
- package/src/ui/badge/variants.ts +7 -7
- package/src/ui/buttons/button.test.tsx +1 -1
- package/src/ui/buttons/variants.ts +8 -8
- package/src/ui/drawer/animated/drawer-content-animated.tsx +4 -5
- package/src/ui/drawer/drawer-base.tsx +16 -8
- package/src/ui/drawer/types.ts +1 -0
- package/src/ui/dropdown/dropdown.test.tsx +1 -3
- package/src/ui/dropdown/dropdown.tsx +23 -5
- package/src/ui/dropdown/types.ts +1 -0
- package/src/ui/dropdown/variants.ts +2 -2
- package/src/ui/empty-state/empty-state-base.tsx +9 -1
- package/src/ui/empty-state/types.ts +1 -0
- package/src/ui/file-upload/file-upload.tsx +0 -2
- package/src/ui/inputs/input-base.tsx +60 -6
- package/src/ui/inputs/types.ts +3 -1
- package/src/ui/modal/animated/modal-content-animated.tsx +4 -5
- package/src/ui/modal/modal-base.tsx +19 -9
- package/src/ui/modal/modal.test.tsx +38 -0
- package/src/ui/pagination/pagination.tsx +2 -2
- package/src/ui/progress/animated/progress-animated.tsx +42 -3
- package/src/ui/progress/progress-base.tsx +59 -3
- package/src/ui/progress/types.ts +3 -0
- package/src/ui/search/search-bar.tsx +6 -1
- package/src/ui/search/search-suggestion-list.tsx +14 -6
- package/src/ui/select/select.tsx +97 -6
- package/src/ui/select/types.ts +1 -0
- package/src/ui/select/variants.ts +5 -3
- package/src/ui/slider/slider.test.tsx +25 -1
- package/src/ui/slider/slider.tsx +45 -4
- package/src/ui/slider/types.ts +8 -2
- package/src/ui/spinner/animated/spinner.tsx +4 -0
- package/src/ui/stepper/stepper.test.tsx +6 -7
- package/src/ui/stepper/stepper.tsx +11 -10
- package/src/ui/stepper/types.ts +7 -3
- package/src/ui/table/table-base.tsx +32 -6
- package/src/ui/table/types.ts +8 -1
- package/src/ui/tabs/tabs-base.tsx +71 -10
- package/src/ui/tabs/types.ts +2 -1
- package/src/ui/tabs/variants.ts +1 -1
- package/src/ui/toast/toast-base.tsx +1 -1
- package/src/ui/toggle/toggle-base.tsx +37 -4
- package/src/ui/tooltip/tooltip-base.tsx +119 -22
- package/src/ui/tooltip/types.ts +1 -0
- package/src/ui/tooltip/variants.ts +2 -2
- package/src/ui/typography/blockquote-base.tsx +39 -0
- package/src/ui/typography/blockquote.tsx +8 -0
- package/src/ui/typography/code-block-base.tsx +37 -0
- package/src/ui/typography/code-block.tsx +8 -0
- package/src/ui/typography/heading-base.tsx +59 -0
- package/src/ui/typography/heading.tsx +8 -0
- package/src/ui/typography/index.ts +28 -0
- package/src/ui/typography/inline-code-base.tsx +27 -0
- package/src/ui/typography/inline-code.tsx +8 -0
- package/src/ui/typography/list-base.tsx +88 -0
- package/src/ui/typography/list.tsx +15 -0
- package/src/ui/typography/text-base.tsx +43 -0
- package/src/ui/typography/text.tsx +8 -0
- package/src/ui/typography/types.ts +90 -0
- package/src/ui/typography/typography.test.tsx +80 -0
- package/src/ui/typography/variants.ts +72 -0
- package/dist/chunk-2PQEXQVR.js.map +0 -1
- package/dist/chunk-3OR47XMY.js.map +0 -1
- package/dist/chunk-5QB2KNZQ.js.map +0 -1
- package/dist/chunk-7HL3A4YF.mjs.map +0 -1
- package/dist/chunk-BVXTOEBI.mjs.map +0 -1
- package/dist/chunk-E3DZNJAD.js.map +0 -1
- package/dist/chunk-IXDJ3IPG.mjs.map +0 -1
- package/dist/chunk-N4NO3SYL.js.map +0 -1
- package/dist/chunk-P5HUBXUX.js.map +0 -1
- package/dist/chunk-PGH27VTL.mjs.map +0 -1
- package/dist/chunk-RDSPHBHK.mjs.map +0 -1
- package/dist/chunk-WDCIZHXY.mjs.map +0 -1
- package/dist/chunk-WL5I7RVS.mjs +0 -54
- package/dist/chunk-WL5I7RVS.mjs.map +0 -1
- package/dist/chunk-WZKGRU3U.js.map +0 -1
- package/dist/chunk-XLAFQ24R.js.map +0 -1
- package/dist/chunk-XWM2S6VV.mjs.map +0 -1
- package/dist/chunk-YNCD6TKE.mjs.map +0 -1
- package/dist/chunk-YPLVTUYL.js +0 -56
- package/dist/chunk-YPLVTUYL.js.map +0 -1
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
KeyboardEvent,
|
|
6
6
|
useContext,
|
|
7
7
|
useId,
|
|
8
|
+
useRef,
|
|
8
9
|
useState,
|
|
9
10
|
} from "react";
|
|
10
11
|
|
|
@@ -41,6 +42,7 @@ export function Tabs({
|
|
|
41
42
|
}: TabsProps) {
|
|
42
43
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
43
44
|
const idPrefix = useId();
|
|
45
|
+
const listRef = useRef<HTMLDivElement | null>(null);
|
|
44
46
|
|
|
45
47
|
const isControlled = value !== undefined;
|
|
46
48
|
const currentValue = isControlled ? value : internalValue;
|
|
@@ -60,6 +62,7 @@ export function Tabs({
|
|
|
60
62
|
value={{
|
|
61
63
|
value: currentValue,
|
|
62
64
|
setValue,
|
|
65
|
+
listRef,
|
|
63
66
|
orientation,
|
|
64
67
|
size,
|
|
65
68
|
variant,
|
|
@@ -76,10 +79,11 @@ export function Tabs({
|
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
export function TabsList({ children, className, ...props }: TabsListProps) {
|
|
79
|
-
const { orientation, size } = useTabs();
|
|
82
|
+
const { orientation, size, listRef } = useTabs();
|
|
80
83
|
|
|
81
84
|
return (
|
|
82
85
|
<div
|
|
86
|
+
ref={listRef}
|
|
83
87
|
role="tablist"
|
|
84
88
|
aria-orientation={orientation}
|
|
85
89
|
className={cn(tabsListVariants({ orientation, size }), className)}
|
|
@@ -100,6 +104,8 @@ export function TabsTrigger({
|
|
|
100
104
|
const {
|
|
101
105
|
value: activeValue,
|
|
102
106
|
setValue,
|
|
107
|
+
listRef,
|
|
108
|
+
orientation,
|
|
103
109
|
tabTriggerId,
|
|
104
110
|
tabPanelId,
|
|
105
111
|
size,
|
|
@@ -110,30 +116,84 @@ export function TabsTrigger({
|
|
|
110
116
|
const isActive = activeValue === value;
|
|
111
117
|
|
|
112
118
|
const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
const list = listRef.current;
|
|
120
|
+
const triggers =
|
|
121
|
+
list === null
|
|
122
|
+
? []
|
|
123
|
+
: Array.from(list.querySelectorAll<HTMLButtonElement>('[role="tab"]'));
|
|
124
|
+
|
|
125
|
+
const nextKeys =
|
|
126
|
+
orientation === "vertical" ? ["ArrowDown"] : ["ArrowRight"];
|
|
127
|
+
const prevKeys = orientation === "vertical" ? ["ArrowUp"] : ["ArrowLeft"];
|
|
116
128
|
|
|
117
129
|
const index = triggers.findIndex((el) => el === e.currentTarget);
|
|
130
|
+
if (index === -1) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
118
133
|
|
|
119
|
-
|
|
134
|
+
const findEnabledIndex = (
|
|
135
|
+
start: number,
|
|
136
|
+
direction: 1 | -1,
|
|
137
|
+
): number | undefined => {
|
|
138
|
+
const n = triggers.length;
|
|
139
|
+
if (n === 0) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
let i = start;
|
|
143
|
+
for (let step = 0; step < n; step += 1) {
|
|
144
|
+
i = (i + direction + n) % n;
|
|
145
|
+
if (triggers[i]?.disabled !== true) {
|
|
146
|
+
return i;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const focusAt = (i: number) => {
|
|
153
|
+
const target = triggers[i];
|
|
154
|
+
if (target !== undefined && target.disabled !== true) {
|
|
155
|
+
target.focus();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const isNext = nextKeys.includes(e.key);
|
|
160
|
+
const isPrev = prevKeys.includes(e.key);
|
|
161
|
+
|
|
162
|
+
if (isNext) {
|
|
120
163
|
e.preventDefault();
|
|
121
|
-
|
|
164
|
+
const nextIdx = findEnabledIndex(index, 1);
|
|
165
|
+
if (nextIdx !== undefined) {
|
|
166
|
+
focusAt(nextIdx);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
122
169
|
}
|
|
123
170
|
|
|
124
|
-
if (
|
|
171
|
+
if (isPrev) {
|
|
125
172
|
e.preventDefault();
|
|
126
|
-
|
|
173
|
+
const prevIdx = findEnabledIndex(index, -1);
|
|
174
|
+
if (prevIdx !== undefined) {
|
|
175
|
+
focusAt(prevIdx);
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
127
178
|
}
|
|
128
179
|
|
|
129
180
|
if (e.key === "Home") {
|
|
130
181
|
e.preventDefault();
|
|
131
|
-
triggers
|
|
182
|
+
const firstEnabledIndex = triggers.findIndex((btn) => !btn.disabled);
|
|
183
|
+
if (firstEnabledIndex !== -1) {
|
|
184
|
+
triggers[firstEnabledIndex]?.focus();
|
|
185
|
+
}
|
|
186
|
+
return;
|
|
132
187
|
}
|
|
133
188
|
|
|
134
189
|
if (e.key === "End") {
|
|
135
190
|
e.preventDefault();
|
|
136
|
-
triggers
|
|
191
|
+
for (let i = triggers.length - 1; i >= 0; i -= 1) {
|
|
192
|
+
if (!triggers[i]?.disabled) {
|
|
193
|
+
triggers[i]?.focus();
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
137
197
|
}
|
|
138
198
|
};
|
|
139
199
|
|
|
@@ -146,6 +206,7 @@ export function TabsTrigger({
|
|
|
146
206
|
aria-selected={isActive}
|
|
147
207
|
aria-controls={tabPanelId(value)}
|
|
148
208
|
disabled={disabled}
|
|
209
|
+
tabIndex={activeValue === undefined ? undefined : isActive ? 0 : -1}
|
|
149
210
|
onClick={() => setValue(value)}
|
|
150
211
|
onKeyDown={handleKeyDown}
|
|
151
212
|
className={cn(
|
package/src/ui/tabs/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ElementType, HTMLAttributes, ReactNode } from "react";
|
|
1
|
+
import type { ElementType, HTMLAttributes, ReactNode, RefObject } from "react";
|
|
2
2
|
|
|
3
3
|
export type TabsValue = string;
|
|
4
4
|
|
|
@@ -59,6 +59,7 @@ export type TabsContentProps = {
|
|
|
59
59
|
export type TabsContextType = {
|
|
60
60
|
value: TabsValue | undefined;
|
|
61
61
|
setValue: (value: TabsValue) => void;
|
|
62
|
+
listRef: RefObject<HTMLDivElement | null>;
|
|
62
63
|
orientation: "horizontal" | "vertical";
|
|
63
64
|
size?: "sm" | "md" | "lg";
|
|
64
65
|
variant?: "default" | "underline" | "pills";
|
package/src/ui/tabs/variants.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const tabsListVariants = cva("flex items-center gap-1", {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
export const tabsTriggerVariants = cva(
|
|
27
|
-
"px-3 py-1.5 rounded-md transition-all focus:outline-none focus:ring-2 focus:ring-ring",
|
|
27
|
+
"px-3 py-1.5 rounded-md transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
28
28
|
{
|
|
29
29
|
variants: {
|
|
30
30
|
appearance: {
|
|
@@ -217,7 +217,7 @@ export function ToastClose({
|
|
|
217
217
|
data-slot="toast-close"
|
|
218
218
|
aria-label="Dismiss notification"
|
|
219
219
|
className={cn(
|
|
220
|
-
"absolute right-3 top-3 inline-flex size-8 items-center justify-center rounded-md text-slate-200 transition hover:bg-white/10",
|
|
220
|
+
"absolute right-3 top-3 inline-flex size-8 items-center justify-center rounded-md text-slate-200 transition hover:bg-white/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/40 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950",
|
|
221
221
|
className,
|
|
222
222
|
)}
|
|
223
223
|
onClick={onClick}
|
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useState } from "react";
|
|
3
|
+
import { useCallback, useId, useState, type ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
6
|
|
|
7
7
|
import type { ToggleProps } from "./types";
|
|
8
8
|
import { toggleThumbVariants, toggleTrackVariants } from "./variants";
|
|
9
9
|
|
|
10
|
+
function hasToggleLabelChildren(node: ReactNode): boolean {
|
|
11
|
+
if (node === undefined || node === null) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (typeof node === "boolean") {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (typeof node === "string") {
|
|
18
|
+
return node.trim().length > 0;
|
|
19
|
+
}
|
|
20
|
+
if (typeof node === "number") {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (Array.isArray(node)) {
|
|
24
|
+
return node.some(hasToggleLabelChildren);
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
10
29
|
export function ToggleBase(props: ToggleProps) {
|
|
11
30
|
const {
|
|
12
31
|
className,
|
|
@@ -17,10 +36,11 @@ export function ToggleBase(props: ToggleProps) {
|
|
|
17
36
|
onCheckedChange,
|
|
18
37
|
disabled,
|
|
19
38
|
ref,
|
|
20
|
-
"aria-label":
|
|
39
|
+
"aria-label": ariaLabelProp,
|
|
21
40
|
children,
|
|
22
41
|
...rest
|
|
23
42
|
} = props;
|
|
43
|
+
const toggleLabelId = useId();
|
|
24
44
|
const isControlled = checked !== undefined;
|
|
25
45
|
const [uncontrolled, setUncontrolled] = useState(defaultChecked);
|
|
26
46
|
const resolved = isControlled ? Boolean(checked) : uncontrolled;
|
|
@@ -36,6 +56,15 @@ export function ToggleBase(props: ToggleProps) {
|
|
|
36
56
|
);
|
|
37
57
|
|
|
38
58
|
const thumbShiftPx = size === "sm" ? 14 : size === "lg" ? 26 : 20;
|
|
59
|
+
const labeledByChildren = hasToggleLabelChildren(children);
|
|
60
|
+
const labeling =
|
|
61
|
+
labeledByChildren ?
|
|
62
|
+
{
|
|
63
|
+
"aria-labelledby": toggleLabelId,
|
|
64
|
+
}
|
|
65
|
+
: {
|
|
66
|
+
"aria-label": ariaLabelProp ?? "Toggle",
|
|
67
|
+
};
|
|
39
68
|
|
|
40
69
|
return (
|
|
41
70
|
<button
|
|
@@ -44,10 +73,10 @@ export function ToggleBase(props: ToggleProps) {
|
|
|
44
73
|
role="switch"
|
|
45
74
|
data-slot="toggle"
|
|
46
75
|
aria-checked={resolved}
|
|
47
|
-
aria-label={ariaLabel}
|
|
48
76
|
data-state={resolved ? "checked" : "unchecked"}
|
|
49
77
|
disabled={disabled}
|
|
50
78
|
className={cn(toggleTrackVariants({ size, appearance }), className)}
|
|
79
|
+
{...labeling}
|
|
51
80
|
onClick={() => {
|
|
52
81
|
if (!disabled) {
|
|
53
82
|
setChecked(!resolved);
|
|
@@ -55,7 +84,11 @@ export function ToggleBase(props: ToggleProps) {
|
|
|
55
84
|
}}
|
|
56
85
|
{...rest}
|
|
57
86
|
>
|
|
58
|
-
|
|
87
|
+
{labeledByChildren ?
|
|
88
|
+
<span id={toggleLabelId} className="sr-only">
|
|
89
|
+
{children}
|
|
90
|
+
</span>
|
|
91
|
+
: null}
|
|
59
92
|
<span
|
|
60
93
|
className={cn(
|
|
61
94
|
toggleThumbVariants({ size }),
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
Children,
|
|
5
|
+
cloneElement,
|
|
4
6
|
createContext,
|
|
7
|
+
isValidElement,
|
|
5
8
|
useCallback,
|
|
6
9
|
useContext,
|
|
7
10
|
useEffect,
|
|
11
|
+
useId,
|
|
8
12
|
useRef,
|
|
9
13
|
useState,
|
|
14
|
+
type KeyboardEventHandler,
|
|
15
|
+
type MouseEventHandler,
|
|
16
|
+
type FocusEventHandler,
|
|
17
|
+
type ReactElement,
|
|
10
18
|
} from "react";
|
|
11
19
|
|
|
12
20
|
import { cn } from "../../lib/utils";
|
|
@@ -29,6 +37,22 @@ export const useTooltip = () => {
|
|
|
29
37
|
return context;
|
|
30
38
|
};
|
|
31
39
|
|
|
40
|
+
function mergeDescribedBy(
|
|
41
|
+
tooltipId: string,
|
|
42
|
+
existing: unknown,
|
|
43
|
+
open: boolean,
|
|
44
|
+
): string | undefined {
|
|
45
|
+
if (!open) {
|
|
46
|
+
return typeof existing === "string" ? existing : undefined;
|
|
47
|
+
}
|
|
48
|
+
const baseIds =
|
|
49
|
+
typeof existing === "string" && existing.trim().length > 0
|
|
50
|
+
? existing.split(/\s+/).filter(Boolean)
|
|
51
|
+
: [];
|
|
52
|
+
const merged = [...new Set([...baseIds, tooltipId])];
|
|
53
|
+
return merged.join(" ");
|
|
54
|
+
}
|
|
55
|
+
|
|
32
56
|
export const Tooltip = ({
|
|
33
57
|
children,
|
|
34
58
|
defaultOpen = false,
|
|
@@ -38,6 +62,7 @@ export const Tooltip = ({
|
|
|
38
62
|
delay = 100,
|
|
39
63
|
}: TooltipProps) => {
|
|
40
64
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
65
|
+
const tooltipId = `${useId()}-tooltip`;
|
|
41
66
|
|
|
42
67
|
const isControlled = controlledOpen !== undefined;
|
|
43
68
|
const open = isControlled ? controlledOpen : uncontrolledOpen;
|
|
@@ -78,6 +103,7 @@ export const Tooltip = ({
|
|
|
78
103
|
delay,
|
|
79
104
|
scheduleDelayedOpen,
|
|
80
105
|
cancelDelayedOpen,
|
|
106
|
+
tooltipId,
|
|
81
107
|
}}
|
|
82
108
|
>
|
|
83
109
|
<div className="relative inline-block">{children}</div>
|
|
@@ -89,33 +115,103 @@ export const TooltipTrigger = ({
|
|
|
89
115
|
children,
|
|
90
116
|
className,
|
|
91
117
|
}: TooltipTriggerProps) => {
|
|
92
|
-
const { setOpen, scheduleDelayedOpen, cancelDelayedOpen } =
|
|
118
|
+
const { setOpen, scheduleDelayedOpen, cancelDelayedOpen, open, tooltipId } =
|
|
119
|
+
useTooltip();
|
|
93
120
|
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
121
|
+
const onMouseEnter: MouseEventHandler = () => scheduleDelayedOpen();
|
|
122
|
+
const onMouseLeave: MouseEventHandler = () => {
|
|
123
|
+
cancelDelayedOpen();
|
|
124
|
+
setOpen(false);
|
|
125
|
+
};
|
|
126
|
+
const onFocus: FocusEventHandler = () => {
|
|
127
|
+
cancelDelayedOpen();
|
|
128
|
+
setOpen(true);
|
|
129
|
+
};
|
|
130
|
+
const onBlur: FocusEventHandler = () => {
|
|
131
|
+
cancelDelayedOpen();
|
|
132
|
+
setOpen(false);
|
|
133
|
+
};
|
|
134
|
+
const onKeyDown: KeyboardEventHandler = (event) => {
|
|
135
|
+
if (event.key === "Escape") {
|
|
105
136
|
cancelDelayedOpen();
|
|
106
137
|
setOpen(false);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const childList = Children.toArray(children).filter(
|
|
142
|
+
(node) =>
|
|
143
|
+
node !== null && node !== undefined && typeof node !== "boolean",
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const soleCandidate =
|
|
147
|
+
childList.length === 1 && isValidElement(childList[0])
|
|
148
|
+
? (childList[0] as ReactElement<{
|
|
149
|
+
className?: string;
|
|
150
|
+
"aria-describedby"?: string;
|
|
151
|
+
onMouseEnter?: MouseEventHandler;
|
|
152
|
+
onMouseLeave?: MouseEventHandler;
|
|
153
|
+
onFocus?: FocusEventHandler;
|
|
154
|
+
onBlur?: FocusEventHandler;
|
|
155
|
+
onKeyDown?: KeyboardEventHandler;
|
|
156
|
+
}>)
|
|
157
|
+
: undefined;
|
|
158
|
+
|
|
159
|
+
if (soleCandidate) {
|
|
160
|
+
const describedBy = mergeDescribedBy(
|
|
161
|
+
tooltipId,
|
|
162
|
+
soleCandidate.props["aria-describedby"],
|
|
163
|
+
open,
|
|
164
|
+
);
|
|
165
|
+
return cloneElement(soleCandidate, {
|
|
166
|
+
onMouseEnter: (event: React.MouseEvent) => {
|
|
167
|
+
soleCandidate.props.onMouseEnter?.(event);
|
|
168
|
+
if (!event.defaultPrevented) {
|
|
169
|
+
scheduleDelayedOpen();
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
onMouseLeave: (event: React.MouseEvent) => {
|
|
173
|
+
soleCandidate.props.onMouseLeave?.(event);
|
|
110
174
|
cancelDelayedOpen();
|
|
111
175
|
setOpen(false);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
176
|
+
},
|
|
177
|
+
onFocus: (event: React.FocusEvent) => {
|
|
178
|
+
soleCandidate.props.onFocus?.(event);
|
|
179
|
+
if (!event.defaultPrevented) {
|
|
180
|
+
cancelDelayedOpen();
|
|
181
|
+
setOpen(true);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
onBlur: (event: React.FocusEvent) => {
|
|
185
|
+
soleCandidate.props.onBlur?.(event);
|
|
186
|
+
cancelDelayedOpen();
|
|
187
|
+
setOpen(false);
|
|
188
|
+
},
|
|
189
|
+
onKeyDown: (event: React.KeyboardEvent) => {
|
|
190
|
+
soleCandidate.props.onKeyDown?.(event);
|
|
191
|
+
if (event.key === "Escape") {
|
|
192
|
+
cancelDelayedOpen();
|
|
193
|
+
setOpen(false);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
className: cn(className, soleCandidate.props.className),
|
|
197
|
+
"aria-describedby": describedBy,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
117
200
|
|
|
118
|
-
return
|
|
201
|
+
return (
|
|
202
|
+
<span
|
|
203
|
+
className={className}
|
|
204
|
+
tabIndex={0}
|
|
205
|
+
aria-describedby={mergeDescribedBy(tooltipId, undefined, open)}
|
|
206
|
+
onMouseEnter={onMouseEnter}
|
|
207
|
+
onMouseLeave={onMouseLeave}
|
|
208
|
+
onFocus={onFocus}
|
|
209
|
+
onBlur={onBlur}
|
|
210
|
+
onKeyDown={onKeyDown}
|
|
211
|
+
>
|
|
212
|
+
{children}
|
|
213
|
+
</span>
|
|
214
|
+
);
|
|
119
215
|
};
|
|
120
216
|
|
|
121
217
|
export const TooltipContent = ({
|
|
@@ -125,7 +221,7 @@ export const TooltipContent = ({
|
|
|
125
221
|
size,
|
|
126
222
|
width,
|
|
127
223
|
}: TooltipContentProps) => {
|
|
128
|
-
const { open, position } = useTooltip();
|
|
224
|
+
const { open, position, tooltipId } = useTooltip();
|
|
129
225
|
|
|
130
226
|
if (!open) return null;
|
|
131
227
|
|
|
@@ -138,6 +234,7 @@ export const TooltipContent = ({
|
|
|
138
234
|
|
|
139
235
|
return (
|
|
140
236
|
<div
|
|
237
|
+
id={tooltipId}
|
|
141
238
|
data-open={open}
|
|
142
239
|
role="tooltip"
|
|
143
240
|
className={cn(
|
package/src/ui/tooltip/types.ts
CHANGED
|
@@ -9,12 +9,12 @@ export const tooltipVariants = cva(
|
|
|
9
9
|
outline: "border bg-white text-black",
|
|
10
10
|
ghost: "bg-gray-800 text-white/90",
|
|
11
11
|
glass: "border border-white/15 bg-white/10 text-white backdrop-blur-md",
|
|
12
|
-
emerald: "bg-emerald-
|
|
12
|
+
emerald: "bg-emerald-800 text-white",
|
|
13
13
|
indigo: "bg-indigo-600 text-white",
|
|
14
14
|
purple: "bg-purple-600 text-white",
|
|
15
15
|
pink: "bg-pink-600 text-white",
|
|
16
16
|
rose: "bg-rose-600 text-white",
|
|
17
|
-
sky: "bg-sky-
|
|
17
|
+
sky: "bg-sky-700 text-white",
|
|
18
18
|
teal: "bg-teal-600 text-white",
|
|
19
19
|
yellow: "bg-yellow-600 text-white",
|
|
20
20
|
orange: "bg-orange-600 text-white",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
import type { BlockquoteProps } from "./types";
|
|
6
|
+
import { typographyToneVariants } from "./variants";
|
|
7
|
+
|
|
8
|
+
export const BlockquoteBase = (props: BlockquoteProps) => {
|
|
9
|
+
const {
|
|
10
|
+
tone,
|
|
11
|
+
attribution,
|
|
12
|
+
className,
|
|
13
|
+
children,
|
|
14
|
+
ref,
|
|
15
|
+
...rest
|
|
16
|
+
} = props;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<blockquote
|
|
20
|
+
ref={ref}
|
|
21
|
+
data-slot="typography-blockquote"
|
|
22
|
+
className={cn(
|
|
23
|
+
typographyToneVariants({ tone }),
|
|
24
|
+
"border-l-4 py-1 pl-4 italic",
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
27
|
+
{...rest}
|
|
28
|
+
>
|
|
29
|
+
<div className="space-y-2 leading-relaxed">{children}</div>
|
|
30
|
+
{attribution ? (
|
|
31
|
+
<footer className="mt-3 text-sm not-italic">
|
|
32
|
+
<cite>{attribution}</cite>
|
|
33
|
+
</footer>
|
|
34
|
+
) : null}
|
|
35
|
+
</blockquote>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
BlockquoteBase.displayName = "Blockquote";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
import type { CodeBlockProps } from "./types";
|
|
6
|
+
import { typographyToneVariants } from "./variants";
|
|
7
|
+
|
|
8
|
+
export const CodeBlockBase = (props: CodeBlockProps) => {
|
|
9
|
+
const {
|
|
10
|
+
tone,
|
|
11
|
+
language,
|
|
12
|
+
className,
|
|
13
|
+
children,
|
|
14
|
+
ref,
|
|
15
|
+
...rest
|
|
16
|
+
} = props;
|
|
17
|
+
|
|
18
|
+
const ariaLabel = language ? `Code sample (${language})` : "Code sample";
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<pre
|
|
22
|
+
ref={ref}
|
|
23
|
+
data-slot="typography-code-block"
|
|
24
|
+
aria-label={ariaLabel}
|
|
25
|
+
className={cn(
|
|
26
|
+
typographyToneVariants({ tone }),
|
|
27
|
+
"overflow-x-auto rounded-xl border border-white/10 bg-slate-950/80 p-4 text-sm leading-relaxed shadow-inner shadow-slate-950/40",
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...rest}
|
|
31
|
+
>
|
|
32
|
+
<code className="font-mono text-[0.95em] whitespace-pre-wrap wrap-break-word">{children}</code>
|
|
33
|
+
</pre>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
CodeBlockBase.displayName = "CodeBlock";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
import type { HeadingProps } from "./types";
|
|
6
|
+
import {
|
|
7
|
+
headingLevelVariants,
|
|
8
|
+
typographyToneVariants,
|
|
9
|
+
} from "./variants";
|
|
10
|
+
|
|
11
|
+
const HEADING_TAGS = {
|
|
12
|
+
1: "h1",
|
|
13
|
+
2: "h2",
|
|
14
|
+
3: "h3",
|
|
15
|
+
4: "h4",
|
|
16
|
+
5: "h5",
|
|
17
|
+
6: "h6",
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
export const HeadingBase = (props: HeadingProps) => {
|
|
21
|
+
const {
|
|
22
|
+
level,
|
|
23
|
+
displayLevel,
|
|
24
|
+
tone,
|
|
25
|
+
bold,
|
|
26
|
+
italic,
|
|
27
|
+
underline,
|
|
28
|
+
strikethrough,
|
|
29
|
+
ref,
|
|
30
|
+
className,
|
|
31
|
+
children,
|
|
32
|
+
...rest
|
|
33
|
+
} = props;
|
|
34
|
+
|
|
35
|
+
const Tag = HEADING_TAGS[level];
|
|
36
|
+
const scale = displayLevel ?? level;
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Tag
|
|
40
|
+
ref={ref}
|
|
41
|
+
data-slot="typography-heading"
|
|
42
|
+
data-level={level}
|
|
43
|
+
className={cn(
|
|
44
|
+
typographyToneVariants({ tone }),
|
|
45
|
+
headingLevelVariants({ level: scale }),
|
|
46
|
+
bold && "font-bold",
|
|
47
|
+
italic && "italic",
|
|
48
|
+
underline && "underline underline-offset-4",
|
|
49
|
+
strikethrough && "line-through",
|
|
50
|
+
className,
|
|
51
|
+
)}
|
|
52
|
+
{...rest}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
</Tag>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
HeadingBase.displayName = "Heading";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export { Heading } from "./heading";
|
|
2
|
+
export { Text } from "./text";
|
|
3
|
+
export { List, ListItem } from "./list";
|
|
4
|
+
export { Blockquote } from "./blockquote";
|
|
5
|
+
export { InlineCode } from "./inline-code";
|
|
6
|
+
export { CodeBlock } from "./code-block";
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
BlockquoteProps,
|
|
10
|
+
CodeBlockProps,
|
|
11
|
+
HeadingLevel,
|
|
12
|
+
HeadingProps,
|
|
13
|
+
InlineCodeProps,
|
|
14
|
+
ListItemProps,
|
|
15
|
+
ListProps,
|
|
16
|
+
TextElement,
|
|
17
|
+
TextProps,
|
|
18
|
+
TypographyTone,
|
|
19
|
+
UnorderedMarker,
|
|
20
|
+
} from "./types";
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
headingLevelVariants,
|
|
24
|
+
orderedListVariants,
|
|
25
|
+
textSizeVariants,
|
|
26
|
+
typographyToneVariants,
|
|
27
|
+
unorderedListMarkerVariants,
|
|
28
|
+
} from "./variants";
|