@xyd-js/components 0.1.0-xyd.7 → 0.1.0-xyd.94
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/.idea/git_toolbox_blame.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/xyd-components.iml +12 -0
- package/CHANGELOG.md +718 -0
- package/LICENSE +21 -0
- package/TODO.md +1 -0
- package/content.ts +0 -2
- package/dist/CTABanner-Bc77pnms.js +2 -0
- package/dist/CTABanner-Bc77pnms.js.map +1 -0
- package/dist/CTABanner-DzO62aGj.js +2 -0
- package/dist/CTABanner-DzO62aGj.js.map +1 -0
- package/dist/CodeSample-BWPDgd2G.js +2 -0
- package/dist/CodeSample-BWPDgd2G.js.map +1 -0
- package/dist/CodeSample-DLnR-knP.js +2 -0
- package/dist/CodeSample-DLnR-knP.js.map +1 -0
- package/dist/HomeView-C8QlNdKh.js +2 -0
- package/dist/HomeView-C8QlNdKh.js.map +1 -0
- package/dist/HomeView-ZAP5saNy.js +2 -0
- package/dist/HomeView-ZAP5saNy.js.map +1 -0
- package/dist/Icon-BESh23UN.js +2 -0
- package/dist/Icon-BESh23UN.js.map +1 -0
- package/dist/Icon-xNucOqd2.js +2 -0
- package/dist/Icon-xNucOqd2.js.map +1 -0
- package/dist/Text-CfN9RkYA.js +2 -0
- package/dist/Text-CfN9RkYA.js.map +1 -0
- package/dist/Text-DKycD2zu.js +2 -0
- package/dist/Text-DKycD2zu.js.map +1 -0
- package/dist/Update-0XruJHjj.js +2 -0
- package/dist/Update-0XruJHjj.js.map +1 -0
- package/dist/Update-DKOAw8p9.js +2 -0
- package/dist/Update-DKOAw8p9.js.map +1 -0
- package/dist/VideoGuide-BUyomFVz.js +2 -0
- package/dist/VideoGuide-BUyomFVz.js.map +1 -0
- package/dist/VideoGuide-B_iUKKv7.js +2 -0
- package/dist/VideoGuide-B_iUKKv7.js.map +1 -0
- package/dist/_rollupPluginBabelHelpers-CxSUtGup.js +4 -0
- package/dist/_rollupPluginBabelHelpers-CxSUtGup.js.map +1 -0
- package/dist/_rollupPluginBabelHelpers-DZ-ucadG.js +4 -0
- package/dist/_rollupPluginBabelHelpers-DZ-ucadG.js.map +1 -0
- package/dist/brand.d.ts +9 -9
- package/dist/brand.js +1 -1
- package/dist/brand.js.map +1 -1
- package/dist/coder/themes/cosmo-light.js.map +1 -1
- package/dist/coder.d.ts +29 -9
- package/dist/coder.js +1 -1
- package/dist/coder.js.map +1 -1
- package/dist/content.d.ts +268 -204
- package/dist/content.js +1 -1
- package/dist/content.js.map +1 -1
- package/dist/index.css +267 -216
- package/dist/layouts.d.ts +20 -21
- package/dist/layouts.js +1 -1
- package/dist/layouts.js.map +1 -1
- package/dist/pages.js +1 -1
- package/dist/pages.js.map +1 -1
- package/dist/system.d.ts +10 -0
- package/dist/system.js +2 -0
- package/dist/system.js.map +1 -0
- package/dist/tslib.es6-DyL9kPq9.js +2 -0
- package/dist/{tslib.es6-DDIOdJiV.js.map → tslib.es6-DyL9kPq9.js.map} +1 -1
- package/dist/tslib.es6-Hqk-Mdr9.js +2 -0
- package/dist/{tslib.es6-DUrRPhZd.js.map → tslib.es6-Hqk-Mdr9.js.map} +1 -1
- package/dist/views.js +1 -1
- package/dist/writer.d.ts +411 -78
- package/dist/writer.js +1 -1
- package/dist/writer.js.map +1 -1
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +22 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1640 -0
- package/docs/functions/GuideCard.html +6 -0
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +2 -0
- package/docs/interfaces/GuideCardProps.html +18 -0
- package/docs/modules.html +1 -0
- package/index.ts +0 -1
- package/package.json +13 -18
- package/project.json +677 -0
- package/rollup.config.js +32 -3
- package/src/brand/Button/Button.styles.tsx +28 -0
- package/src/brand/Button/Button.tsx +3 -35
- package/src/brand/CTABanner/CTABanner.styles.tsx +80 -0
- package/src/brand/CTABanner/CTABanner.tsx +34 -112
- package/src/brand/Footer/Footer.styles.tsx +18 -0
- package/src/brand/Footer/Footer.tsx +4 -24
- package/src/brand/TODO.md +1 -0
- package/src/coder/Code/Code.styles.tsx +134 -35
- package/src/coder/Code/Code.tsx +131 -40
- package/src/coder/Code/CodeLoader.tsx +4 -4
- package/src/coder/Code/annotations.tsx +28 -8
- package/src/coder/Code/highlight.ts +38 -0
- package/src/coder/Code/index.ts +2 -1
- package/src/coder/CodeCopy/{CodeCopy.style.tsx → CodeCopy.styles.tsx} +6 -6
- package/src/coder/CodeCopy/CodeCopy.tsx +6 -6
- package/src/coder/CodeSample/CodeSample.tsx +83 -27
- package/src/coder/CodeTabs/CodeTabs.styles.tsx +99 -78
- package/src/coder/CodeTabs/CodeTabs.tsx +71 -56
- package/src/coder/CodeTheme/CodeTheme.tsx +89 -49
- package/src/coder/CodeTheme/index.ts +0 -1
- package/src/coder/CoderProvider.tsx +26 -0
- package/src/coder/index.ts +8 -4
- package/src/content/ContentDecoator.styles.tsx +113 -0
- package/src/content/ContentDecorator.tsx +17 -0
- package/src/content/GridDecorator.styles.tsx +67 -0
- package/src/content/GridDecorator.tsx +21 -0
- package/src/content/ReactContent.tsx +575 -0
- package/src/content/index.ts +10 -2
- package/src/icons/index.ts +0 -0
- package/src/kit/Loader/Loader.styles.tsx +53 -0
- package/src/kit/Loader/Loader.tsx +22 -0
- package/src/kit/TODO.md +2 -0
- package/src/kit/index.ts +1 -0
- package/src/layouts/LayoutPrimary/LayoutPrimary.styles.tsx +263 -278
- package/src/layouts/LayoutPrimary/LayoutPrimary.tsx +173 -96
- package/src/layouts/LayoutPrimary/index.ts +0 -2
- package/src/layouts/index.ts +0 -7
- package/src/pages/HomePage/HomePage.styles.tsx +16 -0
- package/src/pages/HomePage/HomePage.tsx +7 -21
- package/src/pages/TODO.md +1 -0
- package/src/system/SearchButton/SearchButton.styles.tsx +86 -0
- package/src/system/SearchButton/SearchButton.tsx +116 -0
- package/src/system/SearchButton/index.ts +1 -0
- package/src/system/index.ts +1 -0
- package/src/utils/useStyle.ts +19 -0
- package/src/views/HomeView/HomeView.styles.tsx +37 -0
- package/src/views/HomeView/HomeView.tsx +5 -45
- package/src/views/TODO.md +1 -0
- package/src/writer/Anchor/Anchor.styles.tsx +11 -0
- package/src/writer/Anchor/Anchor.tsx +51 -0
- package/src/writer/Anchor/index.tsx +1 -0
- package/src/writer/Badge/Badge.styles.tsx +39 -28
- package/src/writer/Badge/Badge.tsx +37 -20
- package/src/writer/Banner/Banner.styles.tsx +91 -0
- package/src/writer/Banner/Banner.tsx +70 -0
- package/src/writer/Banner/index.ts +1 -0
- package/src/writer/Blockquote/Blockquote.styles.tsx +4 -4
- package/src/writer/Blockquote/Blockquote.tsx +6 -3
- package/src/writer/Breadcrumbs/Breadcrumbs.styles.ts +22 -21
- package/src/writer/Breadcrumbs/Breadcrumbs.tsx +19 -13
- package/src/writer/Button/Button.styles.tsx +137 -0
- package/src/writer/Button/Button.tsx +75 -0
- package/src/writer/Button/index.ts +2 -0
- package/src/writer/Callout/Callout.styles.tsx +29 -40
- package/src/writer/Callout/Callout.tsx +31 -16
- package/src/writer/Card/Card.styles.tsx +47 -0
- package/src/writer/Card/Card.tsx +69 -0
- package/src/writer/Card/index.ts +1 -0
- package/src/writer/Code/Code.styles.tsx +10 -11
- package/src/writer/Code/Code.tsx +7 -4
- package/src/writer/ColorSchemeButton/ColorSchemeButton.tsx +172 -0
- package/src/writer/ColorSchemeButton/index.ts +1 -0
- package/src/writer/Details/Details.styles.tsx +84 -84
- package/src/writer/Details/Details.tsx +71 -51
- package/src/writer/Example/index.tsx +5 -0
- package/src/writer/GuideCard/GuideCard.styles.tsx +108 -107
- package/src/writer/GuideCard/GuideCard.tsx +72 -37
- package/src/writer/Heading/Heading.styles.tsx +69 -49
- package/src/writer/Heading/Heading.tsx +92 -22
- package/src/writer/Hr/Hr.styles.tsx +5 -5
- package/src/writer/Hr/Hr.tsx +3 -6
- package/src/writer/Icon/Icon.tsx +48 -0
- package/src/writer/Icon/index.ts +1 -0
- package/src/writer/Image/Image.styles.tsx +9 -0
- package/src/writer/Image/Image.tsx +19 -0
- package/src/writer/Image/index.ts +1 -0
- package/src/writer/List/List.styles.tsx +47 -0
- package/src/writer/List/List.tsx +29 -0
- package/src/writer/List/index.ts +4 -0
- package/src/writer/NavLinks/NavLinks.styles.ts +23 -24
- package/src/writer/NavLinks/NavLinks.tsx +66 -19
- package/src/writer/Pre/Pre.styles.tsx +5 -5
- package/src/writer/Pre/Pre.tsx +4 -3
- package/src/writer/Steps/Steps.styles.tsx +14 -12
- package/src/writer/Steps/Steps.tsx +39 -10
- package/src/writer/Table/Table.styles.tsx +62 -30
- package/src/writer/Table/Table.tsx +121 -11
- package/src/writer/Table/index.ts +0 -11
- package/src/writer/Tabs/Tabs.styles.tsx +63 -70
- package/src/writer/Tabs/Tabs.tsx +31 -29
- package/src/writer/Text/Text.styles.tsx +66 -0
- package/src/writer/Text/Text.tsx +79 -0
- package/src/writer/Text/index.ts +3 -0
- package/src/writer/TocCard/TocCard.module.css +44 -0
- package/src/writer/TocCard/TocCard.tsx +42 -0
- package/src/writer/TocCard/index.ts +3 -0
- package/src/writer/UnderlineNav/Tabs.tsx +51 -0
- package/src/writer/UnderlineNav/TabsPrimary.styles.tsx +184 -0
- package/src/writer/UnderlineNav/TabsPrimary.tsx +209 -0
- package/src/writer/UnderlineNav/TabsSecondary.styles.tsx +77 -0
- package/src/writer/UnderlineNav/TabsSecondary.tsx +171 -0
- package/src/writer/UnderlineNav/UnderlineNav.styles.tsx +181 -45
- package/src/writer/UnderlineNav/UnderlineNav.tsx +258 -23
- package/src/writer/UnderlineNav/index.ts +2 -1
- package/src/writer/UnderlineNav/useValueChange.ts +60 -0
- package/src/writer/Update/Update.styles.tsx +33 -0
- package/src/writer/Update/Update.tsx +37 -0
- package/src/writer/Update/index.ts +1 -0
- package/src/writer/VideoGuide/VideoGuide.module.css +105 -0
- package/src/writer/VideoGuide/VideoGuide.tsx +75 -0
- package/src/writer/VideoGuide/index.ts +1 -0
- package/src/writer/index.ts +23 -1
- package/tsconfig.json +11 -6
- package/types.d.ts +50 -0
- package/writer.ts +1 -1
- package/dist/CTABanner-BrdYlhnD.js +0 -2
- package/dist/CTABanner-BrdYlhnD.js.map +0 -1
- package/dist/CTABanner-XQNnnpUx.js +0 -2
- package/dist/CTABanner-XQNnnpUx.js.map +0 -1
- package/dist/CodeSample-Cp42Adjc.js +0 -2
- package/dist/CodeSample-Cp42Adjc.js.map +0 -1
- package/dist/CodeSample-DxPp80ID.js +0 -2
- package/dist/CodeSample-DxPp80ID.js.map +0 -1
- package/dist/HomeView-BN9mZXh9.js +0 -2
- package/dist/HomeView-BN9mZXh9.js.map +0 -1
- package/dist/HomeView-BVaaV0uE.js +0 -2
- package/dist/HomeView-BVaaV0uE.js.map +0 -1
- package/dist/UnderlineNav-Bs7Ot9Ch.js +0 -2
- package/dist/UnderlineNav-Bs7Ot9Ch.js.map +0 -1
- package/dist/UnderlineNav-C2aEVraN.js +0 -2
- package/dist/UnderlineNav-C2aEVraN.js.map +0 -1
- package/dist/_rollupPluginBabelHelpers-BMmCG_qQ.js +0 -2
- package/dist/_rollupPluginBabelHelpers-BMmCG_qQ.js.map +0 -1
- package/dist/_rollupPluginBabelHelpers-DsEzE6Ab.js +0 -2
- package/dist/_rollupPluginBabelHelpers-DsEzE6Ab.js.map +0 -1
- package/dist/index-BVUz77Tm.js +0 -2
- package/dist/index-BVUz77Tm.js.map +0 -1
- package/dist/index-jxd3nv2J.js +0 -2
- package/dist/index-jxd3nv2J.js.map +0 -1
- package/dist/tslib.es6-DDIOdJiV.js +0 -2
- package/dist/tslib.es6-DUrRPhZd.js +0 -2
- package/src/content/Anchor/Anchor.tsx +0 -63
- package/src/content/Anchor/index.tsx +0 -3
- package/src/content/Content/Content.tsx +0 -21
- package/src/content/Content/index.tsx +0 -3
- package/src/content/Content.tsx +0 -180
- package/src/content/Subtitle/Subtitle.tsx +0 -21
- package/src/content/Subtitle/index.tsx +0 -3
- package/src/layouts/Layout.styles.tsx +0 -151
- package/src/layouts/Layout.tsx +0 -121
- package/src/ui/Loader/Loader.styles.tsx +0 -52
- package/src/ui/Loader/Loader.tsx +0 -26
- package/src/ui/index.ts +0 -1
- package/src/writer/Icon/index.tsx +0 -355
- package/src/writer/Table/TableV2.styles.tsx +0 -117
- package/src/writer/Table/TableV2.tsx +0 -83
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { createContext, useContext } from "react"
|
|
2
|
+
|
|
3
|
+
import { TabsPrimary, TabsPrimaryProps } from "./TabsPrimary"
|
|
4
|
+
import { TabsSecondary, TabsSecondaryProps } from "./TabsSecondary";
|
|
5
|
+
|
|
6
|
+
interface TabsPropsCommon {
|
|
7
|
+
kind?: 'secondary' | null
|
|
8
|
+
}
|
|
9
|
+
// TODO: in the future unify the TabsPrimary and TabsSecondary components?
|
|
10
|
+
type TabsProps<T> = T & TabsPropsCommon
|
|
11
|
+
|
|
12
|
+
const TabsContext = createContext<TabsPropsCommon>({
|
|
13
|
+
kind: null
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export function Tabs(props: TabsProps<TabsSecondaryProps | TabsPrimaryProps>) {
|
|
17
|
+
if (props.kind === 'secondary') {
|
|
18
|
+
return (
|
|
19
|
+
<TabsContext value={{ kind: 'secondary' }}>
|
|
20
|
+
<TabsSecondary {...props} />
|
|
21
|
+
</TabsContext>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<TabsContext value={{}}>
|
|
27
|
+
<TabsPrimary {...props} />
|
|
28
|
+
</TabsContext>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Tabs.Item = function TabsItem(props: any) {
|
|
34
|
+
const { kind } = useContext(TabsContext)
|
|
35
|
+
|
|
36
|
+
if (kind === 'secondary') {
|
|
37
|
+
return <TabsSecondary.Item {...props} />
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return <TabsPrimary.Item {...props} />
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Tabs.Content = function TabsContent(props: any) {
|
|
44
|
+
const { kind } = useContext(TabsContext)
|
|
45
|
+
|
|
46
|
+
if (kind === 'secondary') {
|
|
47
|
+
return <TabsSecondary.Content {...props} />
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return <TabsPrimary.Content {...props} />
|
|
51
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {css} from "@linaria/core"
|
|
2
|
+
|
|
3
|
+
export const TabsPrimaryHost = css`
|
|
4
|
+
@layer defaults {
|
|
5
|
+
[part="nav"] {
|
|
6
|
+
align-items: center;
|
|
7
|
+
display: flex;
|
|
8
|
+
height: 42px;
|
|
9
|
+
background-color: var(--xyd-underlinenav-bgcolor);
|
|
10
|
+
border-bottom: 1px solid var(--xyd-underlinenav-border-color);
|
|
11
|
+
z-index: 99;
|
|
12
|
+
|
|
13
|
+
&[data-kind="secondary"] {
|
|
14
|
+
border-bottom: none;
|
|
15
|
+
border-radius: 8px;
|
|
16
|
+
padding: 4px;
|
|
17
|
+
background-color: var(--xyd-tabs-bgcolor);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[part="list"] {
|
|
22
|
+
display: flex;
|
|
23
|
+
gap: 10px;
|
|
24
|
+
height: 100%;
|
|
25
|
+
color: var(--xyd-underlinenav-list-color);
|
|
26
|
+
list-style: none;
|
|
27
|
+
padding: 0;
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
|
|
30
|
+
[data-kind="secondary"] & {
|
|
31
|
+
gap: 4px;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[part="item"] {
|
|
36
|
+
height: 100%;
|
|
37
|
+
position: relative;
|
|
38
|
+
|
|
39
|
+
a, button {
|
|
40
|
+
height: 100%;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&[data-state="active"] {
|
|
44
|
+
a {
|
|
45
|
+
border-bottom-color: var(--xyd-underlinenav-color--active);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[data-kind="secondary"] & a {
|
|
49
|
+
border-bottom-color: transparent;
|
|
50
|
+
color: var(--xyd-tabs-color--active);
|
|
51
|
+
background-color: var(--xyd-tabs-bgcolor--active);
|
|
52
|
+
box-shadow: 0 1px 2px 0 var(--xyd-tabs-shadow-color--active);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&[data-state="inactive"] {
|
|
57
|
+
a, button {
|
|
58
|
+
color: unset;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
[part="link"] {
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
border-bottom: 3px solid transparent;
|
|
66
|
+
text-decoration: none;
|
|
67
|
+
height: 100%;
|
|
68
|
+
padding: 10px;
|
|
69
|
+
transition: all 0.3s ease;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
|
|
72
|
+
&:hover {
|
|
73
|
+
color: var(--xyd-underlinenav-color--active);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[data-kind="secondary"] & {
|
|
77
|
+
border-bottom: none;
|
|
78
|
+
padding: 5px 16px;
|
|
79
|
+
border-radius: 0.375rem;
|
|
80
|
+
color: var(--xyd-tabs-color);
|
|
81
|
+
|
|
82
|
+
&:hover {
|
|
83
|
+
color: var(--xyd-tabs-color--active);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
[part="content"] {
|
|
89
|
+
position: relative;
|
|
90
|
+
overflow: hidden;
|
|
91
|
+
|
|
92
|
+
[data-kind="secondary"] & {
|
|
93
|
+
margin-top: 16px;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
|
|
99
|
+
export const TabsPrimaryContent = css`
|
|
100
|
+
@layer defaults {
|
|
101
|
+
position: relative;
|
|
102
|
+
width: 100%;
|
|
103
|
+
|
|
104
|
+
&[data-state="inactive"] {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Only apply animations when parent has data-slide="true" */
|
|
109
|
+
[data-slide="true"] & {
|
|
110
|
+
/* Forward direction (left to right) */
|
|
111
|
+
|
|
112
|
+
&[data-direction="forward"][data-state="active"] {
|
|
113
|
+
position: relative;
|
|
114
|
+
animation: fadeInFromRight 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
&[data-direction="forward"][data-state="inactive"] {
|
|
118
|
+
position: absolute;
|
|
119
|
+
animation: fadeOutToLeft 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Backward direction (right to left) */
|
|
123
|
+
|
|
124
|
+
&[data-direction="backward"][data-state="active"] {
|
|
125
|
+
position: relative;
|
|
126
|
+
animation: fadeInFromLeft 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
&[data-direction="backward"][data-state="inactive"] {
|
|
130
|
+
position: absolute;
|
|
131
|
+
animation: fadeOutToRight 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@keyframes fadeInFromRight {
|
|
136
|
+
from {
|
|
137
|
+
opacity: 0;
|
|
138
|
+
transform: translateX(75px);
|
|
139
|
+
}
|
|
140
|
+
to {
|
|
141
|
+
opacity: 1;
|
|
142
|
+
transform: translateX(0);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@keyframes fadeOutToLeft {
|
|
147
|
+
from {
|
|
148
|
+
opacity: 1;
|
|
149
|
+
transform: translateX(0);
|
|
150
|
+
}
|
|
151
|
+
to {
|
|
152
|
+
opacity: 0;
|
|
153
|
+
transform: translateX(-75px);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@keyframes fadeInFromLeft {
|
|
158
|
+
from {
|
|
159
|
+
opacity: 0;
|
|
160
|
+
transform: translateX(-75px);
|
|
161
|
+
}
|
|
162
|
+
to {
|
|
163
|
+
opacity: 1;
|
|
164
|
+
transform: translateX(0);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@keyframes fadeOutToRight {
|
|
169
|
+
from {
|
|
170
|
+
opacity: 1;
|
|
171
|
+
transform: translateX(0);
|
|
172
|
+
}
|
|
173
|
+
to {
|
|
174
|
+
opacity: 0;
|
|
175
|
+
transform: translateX(75px);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
[part="child"] {
|
|
180
|
+
padding: 20px;
|
|
181
|
+
transition: all 0.3s ease;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import React, {useState, useRef, useEffect, createContext, useContext} from "react"
|
|
2
|
+
import {Tabs as RadixTabs} from "radix-ui"; // TODO: remove and use separation
|
|
3
|
+
|
|
4
|
+
import * as cn from "./TabsPrimary.styles"
|
|
5
|
+
import {useValueChange} from "./useValueChange";
|
|
6
|
+
import { Tabs } from "./Tabs";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Context for managing the navigation direction in the TabsPrimary component
|
|
10
|
+
*/
|
|
11
|
+
const TabsPrimaryContext = createContext<{
|
|
12
|
+
direction: 'forward' | 'backward'
|
|
13
|
+
}>({
|
|
14
|
+
direction: 'forward'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the TabsPrimary component
|
|
19
|
+
*/
|
|
20
|
+
export interface TabsPrimaryProps {
|
|
21
|
+
/** Child elements to be rendered within the navigation */
|
|
22
|
+
children: React.ReactNode
|
|
23
|
+
|
|
24
|
+
/** The currently selected tab value */
|
|
25
|
+
value?: string
|
|
26
|
+
|
|
27
|
+
/** Callback function triggered when a tab is selected */
|
|
28
|
+
onChange?: (value: string) => void
|
|
29
|
+
|
|
30
|
+
/** Whether to enable sliding animation between tabs */
|
|
31
|
+
slide?: boolean
|
|
32
|
+
|
|
33
|
+
/** Additional CSS class name for the component */
|
|
34
|
+
className?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A navigation component that displays tabs with an underline indicator
|
|
39
|
+
*
|
|
40
|
+
* @category Component
|
|
41
|
+
*/
|
|
42
|
+
export function TabsPrimary({
|
|
43
|
+
children,
|
|
44
|
+
value: controlledValue,
|
|
45
|
+
onChange,
|
|
46
|
+
slide = true,
|
|
47
|
+
className,
|
|
48
|
+
}: TabsPrimaryProps) {
|
|
49
|
+
const childrenArray = React.Children.toArray(children);
|
|
50
|
+
const navItems = childrenArray.filter(
|
|
51
|
+
child => {
|
|
52
|
+
return React.isValidElement(child) &&
|
|
53
|
+
(child.type === TabsPrimary.Item ||
|
|
54
|
+
(typeof child.type === 'function' && 'displayName' in child.type && child.type.displayName === "UnderlineNav.Item"))
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
const otherChildren = childrenArray.filter(
|
|
58
|
+
child => !React.isValidElement(child) ||
|
|
59
|
+
(child.type !== TabsPrimary.Item &&
|
|
60
|
+
!(typeof child.type === 'function' && 'displayName' in child.type && child.type.displayName === "UnderlineNav.Item"))
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const [direction, value, handleValueChange] = useValueChange(
|
|
64
|
+
controlledValue,
|
|
65
|
+
onChange,
|
|
66
|
+
navItems
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<TabsPrimaryContext.Provider value={{direction}}>
|
|
71
|
+
<RadixTabs.Root value={value} onValueChange={handleValueChange}>
|
|
72
|
+
<xyd-tabs
|
|
73
|
+
className={`${cn.TabsPrimaryHost} ${className || ""}`}
|
|
74
|
+
>
|
|
75
|
+
<nav part="nav">
|
|
76
|
+
<RadixTabs.List asChild>
|
|
77
|
+
<ul part="list">
|
|
78
|
+
{navItems}
|
|
79
|
+
</ul>
|
|
80
|
+
</RadixTabs.List>
|
|
81
|
+
</nav>
|
|
82
|
+
<div
|
|
83
|
+
part="content"
|
|
84
|
+
data-slide={slide ? "true" : "false"}
|
|
85
|
+
>
|
|
86
|
+
{otherChildren}
|
|
87
|
+
</div>
|
|
88
|
+
</xyd-tabs>
|
|
89
|
+
</RadixTabs.Root>
|
|
90
|
+
</TabsPrimaryContext.Provider>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Props for the TabsPrimary.Item component
|
|
96
|
+
*/
|
|
97
|
+
export interface TabsPrimaryItemProps {
|
|
98
|
+
/** Child elements to be rendered within the navigation item */
|
|
99
|
+
children: React.ReactNode
|
|
100
|
+
|
|
101
|
+
/** Unique identifier for the navigation item */
|
|
102
|
+
value: string
|
|
103
|
+
|
|
104
|
+
/** URL for the navigation item link */
|
|
105
|
+
href?: string
|
|
106
|
+
|
|
107
|
+
/** Custom component to render as the link element */
|
|
108
|
+
as?: React.ElementType
|
|
109
|
+
|
|
110
|
+
/** Whether this item should be active by default */
|
|
111
|
+
defaultActive?: boolean
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Individual navigation item component
|
|
116
|
+
*
|
|
117
|
+
* @category Component
|
|
118
|
+
*/
|
|
119
|
+
TabsPrimary.Item = function TabsPrimaryItem({children, value, href, as, defaultActive}: TabsPrimaryItemProps) {
|
|
120
|
+
const Link = as || _Link;
|
|
121
|
+
const controlByItem = typeof defaultActive === "boolean"
|
|
122
|
+
const [defaultActiveState, setDefaultActiveState] = useState(controlByItem ? (defaultActive ? "active" : "inactive") : undefined)
|
|
123
|
+
|
|
124
|
+
let activeProps = controlByItem && defaultActiveState != undefined
|
|
125
|
+
? {"data-state": defaultActiveState}
|
|
126
|
+
: undefined
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (!controlByItem) {
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
setDefaultActiveState(undefined)
|
|
134
|
+
}, [])
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<RadixTabs.Trigger value={value} asChild {...activeProps}>
|
|
138
|
+
<li part="item">
|
|
139
|
+
<Link part="link" href={href}>
|
|
140
|
+
{children}
|
|
141
|
+
</Link>
|
|
142
|
+
</li>
|
|
143
|
+
</RadixTabs.Trigger>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Props for the TabsPrimary.Content component
|
|
149
|
+
*/
|
|
150
|
+
export interface TabsPrimaryContentProps {
|
|
151
|
+
/** Child elements to be rendered within the content area */
|
|
152
|
+
children: React.ReactNode
|
|
153
|
+
|
|
154
|
+
/** Unique identifier for the content section */
|
|
155
|
+
value: string
|
|
156
|
+
|
|
157
|
+
/** Whether this content should be active by default */
|
|
158
|
+
defaultActive?: boolean
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Content section component for the TabsPrimary
|
|
163
|
+
*
|
|
164
|
+
* @category Component
|
|
165
|
+
*/
|
|
166
|
+
TabsPrimary.Content = function TabsPrimaryContent({
|
|
167
|
+
children,
|
|
168
|
+
value,
|
|
169
|
+
defaultActive
|
|
170
|
+
}: TabsPrimaryContentProps) {
|
|
171
|
+
const {direction} = useContext(TabsPrimaryContext);
|
|
172
|
+
|
|
173
|
+
const controlByItem = typeof defaultActive === "boolean"
|
|
174
|
+
const [defaultActiveState, setDefaultActiveState] = useState(controlByItem ? (defaultActive ? "active" : "inactive") : undefined)
|
|
175
|
+
|
|
176
|
+
let activeProps = controlByItem && defaultActiveState != undefined
|
|
177
|
+
? {"data-state": defaultActiveState}
|
|
178
|
+
: undefined
|
|
179
|
+
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
if (!controlByItem) {
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
setDefaultActiveState(undefined)
|
|
186
|
+
}, [])
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<RadixTabs.Content
|
|
190
|
+
value={value}
|
|
191
|
+
forceMount={true}
|
|
192
|
+
asChild
|
|
193
|
+
{...activeProps}
|
|
194
|
+
>
|
|
195
|
+
<div
|
|
196
|
+
className={cn.TabsPrimaryContent}
|
|
197
|
+
data-direction={direction}
|
|
198
|
+
>
|
|
199
|
+
<div part="child">
|
|
200
|
+
{children}
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</RadixTabs.Content>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function _Link({...props}) {
|
|
208
|
+
return <a {...props}>{props.children}</a>
|
|
209
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { css } from "@linaria/core";
|
|
2
|
+
|
|
3
|
+
export const TabsSecondaryHost = css`
|
|
4
|
+
@layer defaults {
|
|
5
|
+
display: block;
|
|
6
|
+
position: relative;
|
|
7
|
+
max-width: 100%;
|
|
8
|
+
|
|
9
|
+
[part="buttons"] {
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
[part="arrow"] {
|
|
15
|
+
padding: 8px;
|
|
16
|
+
background-color: var(--xyd-tabs-arrow-bgcolor);
|
|
17
|
+
box-shadow: 0 1px 2px 0 var(--xyd-tabs-shadow-color--active);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[part="arrow-icon"] {
|
|
21
|
+
width: 16px;
|
|
22
|
+
height: 16px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[part="scroller"] {
|
|
26
|
+
overflow-x: auto;
|
|
27
|
+
flex-grow: 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[part="scroller-container"] {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
gap: 4px;
|
|
33
|
+
|
|
34
|
+
border-radius: 8px;
|
|
35
|
+
background-color: var(--xyd-tabs-bgcolor);
|
|
36
|
+
|
|
37
|
+
padding: 4px;
|
|
38
|
+
margin-left: 4px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[part="content"] {
|
|
42
|
+
margin-top: 16px;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
export const TabsSecondaryItem = css`
|
|
48
|
+
@layer defaults {
|
|
49
|
+
&[data-state="inactive"] {
|
|
50
|
+
a, button {
|
|
51
|
+
color: unset;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
display: inline-block;
|
|
56
|
+
padding: 5px 16px;
|
|
57
|
+
|
|
58
|
+
border-radius: 0.375rem;
|
|
59
|
+
white-space: nowrap;
|
|
60
|
+
|
|
61
|
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
|
62
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
63
|
+
transition-duration: 300ms;
|
|
64
|
+
|
|
65
|
+
color: var(--xyd-tabs-color);
|
|
66
|
+
|
|
67
|
+
&:hover {
|
|
68
|
+
color: var(--xyd-tabs-color--active);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&[data-state="active"] {
|
|
72
|
+
color: var(--xyd-tabs-color--active);
|
|
73
|
+
background-color: var(--xyd-tabs-bgcolor--active);
|
|
74
|
+
box-shadow: 0 1px 2px 0 var(--xyd-tabs-shadow-color--active);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react'
|
|
2
|
+
import { Tabs as RadixTabs } from "radix-ui"; // TODO: remove and use separation
|
|
3
|
+
import { ChevronLeft, ChevronRight } from "lucide-react"
|
|
4
|
+
|
|
5
|
+
import * as cn from "./TabsSecondary.styles";
|
|
6
|
+
import { useValueChange } from './useValueChange';
|
|
7
|
+
import { TabsPrimary } from './TabsPrimary';
|
|
8
|
+
|
|
9
|
+
export interface TabsSecondaryProps {
|
|
10
|
+
/** The currently selected tab value */
|
|
11
|
+
value?: string
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
className?: string;
|
|
14
|
+
onChange?: (value: string) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function TabsSecondary({ children, value: controlledValue, onChange, className }: TabsSecondaryProps) {
|
|
18
|
+
const [showLeftArrow, setShowLeftArrow] = useState(false)
|
|
19
|
+
const [showRightArrow, setShowRightArrow] = useState(false)
|
|
20
|
+
const scrollContainerRef = useRef<HTMLDivElement>(null)
|
|
21
|
+
|
|
22
|
+
const childrenArray = React.Children.toArray(children);
|
|
23
|
+
const navItems = childrenArray.filter(
|
|
24
|
+
child => {
|
|
25
|
+
return React.isValidElement(child) &&
|
|
26
|
+
(child.type === TabsSecondary.Item ||
|
|
27
|
+
(typeof child.type === 'function' && 'displayName' in child.type && child.type.displayName === "UnderlineNav.Item"))
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
const otherChildren = childrenArray.filter(
|
|
31
|
+
child => !React.isValidElement(child) ||
|
|
32
|
+
(child.type !== TabsSecondary.Item &&
|
|
33
|
+
!(typeof child.type === 'function' && 'displayName' in child.type && child.type.displayName === "UnderlineNav.Item"))
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const [_, value, handleValueChange] = useValueChange(
|
|
37
|
+
controlledValue,
|
|
38
|
+
onChange,
|
|
39
|
+
navItems
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const handleScroll = () => {
|
|
43
|
+
if (scrollContainerRef.current) {
|
|
44
|
+
const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current
|
|
45
|
+
setShowLeftArrow(scrollLeft > 0)
|
|
46
|
+
setShowRightArrow(scrollLeft < scrollWidth - clientWidth)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
handleScroll()
|
|
52
|
+
window.addEventListener('resize', handleScroll)
|
|
53
|
+
return () => window.removeEventListener('resize', handleScroll)
|
|
54
|
+
}, [])
|
|
55
|
+
|
|
56
|
+
const scroll = (direction: 'left' | 'right') => {
|
|
57
|
+
if (scrollContainerRef.current) {
|
|
58
|
+
const scrollAmount = direction === 'left' ? -200 : 200
|
|
59
|
+
scrollContainerRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' })
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<RadixTabs.Root asChild value={value} onValueChange={handleValueChange}>
|
|
65
|
+
<xyd-tabs
|
|
66
|
+
data-kind="secondary"
|
|
67
|
+
className={`${cn.TabsSecondaryHost} ${className || ""}`}
|
|
68
|
+
>
|
|
69
|
+
<div part="buttons">
|
|
70
|
+
{showLeftArrow && (
|
|
71
|
+
<button
|
|
72
|
+
onClick={() => scroll('left')}
|
|
73
|
+
part="arrow"
|
|
74
|
+
>
|
|
75
|
+
<ChevronLeft part="arrow-icon" />
|
|
76
|
+
</button>
|
|
77
|
+
)}
|
|
78
|
+
|
|
79
|
+
<div
|
|
80
|
+
ref={scrollContainerRef}
|
|
81
|
+
onScroll={handleScroll}
|
|
82
|
+
part="scroller"
|
|
83
|
+
>
|
|
84
|
+
<div
|
|
85
|
+
part="scroller-container"
|
|
86
|
+
>
|
|
87
|
+
<RadixTabs.List>
|
|
88
|
+
{navItems}
|
|
89
|
+
</RadixTabs.List>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
{showRightArrow && (
|
|
94
|
+
<button
|
|
95
|
+
onClick={() => scroll('right')}
|
|
96
|
+
part="arrow"
|
|
97
|
+
>
|
|
98
|
+
<ChevronRight part="arrow-icon" />
|
|
99
|
+
</button>
|
|
100
|
+
)}
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div part="content">
|
|
104
|
+
{otherChildren}
|
|
105
|
+
</div>
|
|
106
|
+
</xyd-tabs>
|
|
107
|
+
</RadixTabs.Root>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Props for the TabsPrimary.Item component
|
|
113
|
+
*/
|
|
114
|
+
export interface TabsSecondaryItemProps {
|
|
115
|
+
/** Child elements to be rendered within the navigation item */
|
|
116
|
+
children: React.ReactNode
|
|
117
|
+
|
|
118
|
+
/** Unique identifier for the navigation item */
|
|
119
|
+
value: string
|
|
120
|
+
|
|
121
|
+
/** URL for the navigation item link */
|
|
122
|
+
href?: string
|
|
123
|
+
|
|
124
|
+
/** Custom component to render as the link element */
|
|
125
|
+
as?: React.ElementType
|
|
126
|
+
|
|
127
|
+
/** Whether this item should be active by default */
|
|
128
|
+
defaultActive?: boolean
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
TabsSecondary.Item = function TabsPrimaryItem({ children, value, href, as, defaultActive }: TabsSecondaryItemProps) {
|
|
132
|
+
const Link = as || _Link;
|
|
133
|
+
const controlByItem = typeof defaultActive === "boolean"
|
|
134
|
+
const [defaultActiveState, setDefaultActiveState] = useState(controlByItem ? (defaultActive ? "active" : "inactive") : undefined)
|
|
135
|
+
|
|
136
|
+
let activeProps = controlByItem && defaultActiveState != undefined
|
|
137
|
+
? { "data-state": defaultActiveState }
|
|
138
|
+
: undefined
|
|
139
|
+
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (!controlByItem) {
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setDefaultActiveState(undefined)
|
|
146
|
+
}, [])
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<RadixTabs.Trigger className={cn.TabsSecondaryItem} value={value} asChild {...activeProps}>
|
|
150
|
+
<div>
|
|
151
|
+
<Link href={href}>
|
|
152
|
+
{children}
|
|
153
|
+
</Link>
|
|
154
|
+
</div>
|
|
155
|
+
</RadixTabs.Trigger>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function _Link({ ...props }) {
|
|
160
|
+
return <a {...props}>{props.children}</a>
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
TabsSecondary.Content = function TabsContent({ children, value }) {
|
|
165
|
+
return <RadixTabs.Content asChild value={value}>
|
|
166
|
+
<div>
|
|
167
|
+
{children}
|
|
168
|
+
</div>
|
|
169
|
+
</RadixTabs.Content>
|
|
170
|
+
}
|
|
171
|
+
|