southpaw 0.2.7
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 +51 -0
- package/api/client.ts +83 -0
- package/api/helpers/fs.ts +98 -0
- package/api/helpers/stream.ts +6 -0
- package/api/index.ts +50 -0
- package/api/server.ts +566 -0
- package/constants/fonts.ts +1583 -0
- package/constants/icons.ts +2124 -0
- package/constants/langs.ts +2592 -0
- package/constants/ssr-loading.tsx +17 -0
- package/contexts/dev.tsx +124 -0
- package/hooks/useDebounceCb.ts +21 -0
- package/modules/app.tsx +102 -0
- package/modules/behaviors.ts +161 -0
- package/modules/component.tsx +483 -0
- package/modules/config/index.ts +8 -0
- package/modules/database.ts +25 -0
- package/modules/document.tsx +23 -0
- package/modules/error.tsx +16 -0
- package/modules/page/autozoom.tsx +92 -0
- package/modules/page/browser.tsx +166 -0
- package/modules/page/index.tsx +327 -0
- package/modules/page/insert-modal.tsx +225 -0
- package/modules/page/inspect/index.tsx +237 -0
- package/modules/page/inspect/wrapper.tsx +88 -0
- package/modules/page/knobs/action.tsx +58 -0
- package/modules/page/knobs/color.tsx +78 -0
- package/modules/page/knobs/helpers.ts +71 -0
- package/modules/page/knobs/icon.tsx +85 -0
- package/modules/page/knobs/linker.tsx +188 -0
- package/modules/page/knobs/list-json.tsx +149 -0
- package/modules/page/knobs/list-text.tsx +129 -0
- package/modules/page/knobs/number.tsx +84 -0
- package/modules/page/knobs/segmented.tsx +81 -0
- package/modules/page/knobs/select.tsx +89 -0
- package/modules/page/knobs/size.tsx +106 -0
- package/modules/page/knobs/switch.tsx +75 -0
- package/modules/page/knobs/text.tsx +93 -0
- package/modules/page/left-tabs.tsx +36 -0
- package/modules/page/right-tabs.tsx +31 -0
- package/modules/page/seo.tsx +69 -0
- package/modules/page/tree.tsx +860 -0
- package/modules/state.ts +787 -0
- package/modules/store.ts +37 -0
- package/modules/theme.ts +105 -0
- package/modules/translations.ts +15 -0
- package/package.json +68 -0
- package/scripts/bin.js +607 -0
- package/scripts/test.js +145 -0
- package/themes/base.tsx +8962 -0
- package/themes/index.ts +4 -0
- package/themes/m2.ts +39 -0
- package/themes/newspaper.ts +39 -0
- package/types/api.ts +57 -0
- package/types/fiber_node.ts +69 -0
- package/types/react_element.ts +14 -0
- package/ui/accordion.tsx +70 -0
- package/ui/actionicon.tsx +41 -0
- package/ui/affix.tsx +14 -0
- package/ui/alert.tsx +37 -0
- package/ui/anchor.tsx +52 -0
- package/ui/arrow.tsx +116 -0
- package/ui/aspectratio.tsx +21 -0
- package/ui/autocomplete.tsx +34 -0
- package/ui/avatar.tsx +36 -0
- package/ui/backgroundimage.tsx +16 -0
- package/ui/badge.tsx +28 -0
- package/ui/blockquote.tsx +15 -0
- package/ui/blocks/faq.tsx +145 -0
- package/ui/blocks/features.tsx +167 -0
- package/ui/blocks/footer.tsx +182 -0
- package/ui/blocks/herobanner.tsx +391 -0
- package/ui/blocks/index.ts +44 -0
- package/ui/blocks/leftnav.tsx +141 -0
- package/ui/blocks/pricing.tsx +210 -0
- package/ui/blocks/testimonials.tsx +149 -0
- package/ui/blocks/uidocs.tsx +1429 -0
- package/ui/box.tsx +27 -0
- package/ui/breadcrumbs.tsx +33 -0
- package/ui/burger.tsx +23 -0
- package/ui/button.tsx +85 -0
- package/ui/card.tsx +28 -0
- package/ui/center.tsx +26 -0
- package/ui/checkbox.tsx +35 -0
- package/ui/chip.tsx +32 -0
- package/ui/closebutton.tsx +15 -0
- package/ui/code.tsx +104 -0
- package/ui/collapse.tsx +16 -0
- package/ui/colorinput.tsx +32 -0
- package/ui/colorpicker.tsx +26 -0
- package/ui/colorswatch.tsx +17 -0
- package/ui/combobox.tsx +80 -0
- package/ui/container.tsx +27 -0
- package/ui/dialog.tsx +15 -0
- package/ui/divider.tsx +58 -0
- package/ui/drawer.tsx +28 -0
- package/ui/fieldset.tsx +15 -0
- package/ui/filebutton.tsx +23 -0
- package/ui/fileinput.tsx +36 -0
- package/ui/flex.tsx +139 -0
- package/ui/focustrap.tsx +15 -0
- package/ui/form.tsx +26 -0
- package/ui/grid.tsx +69 -0
- package/ui/highlight.tsx +15 -0
- package/ui/hoverable.tsx +66 -0
- package/ui/hovercard.tsx +45 -0
- package/ui/icon.tsx +76 -0
- package/ui/image.tsx +32 -0
- package/ui/index.ts +1355 -0
- package/ui/indicator.tsx +42 -0
- package/ui/infobox.tsx +200 -0
- package/ui/input.tsx +18 -0
- package/ui/inviewport.tsx +23 -0
- package/ui/jsoninput.tsx +35 -0
- package/ui/kbd.tsx +20 -0
- package/ui/list.tsx +33 -0
- package/ui/loader.tsx +26 -0
- package/ui/loadingoverlay.tsx +22 -0
- package/ui/mark.tsx +15 -0
- package/ui/menu.tsx +89 -0
- package/ui/modal.tsx +27 -0
- package/ui/multiselect.tsx +42 -0
- package/ui/nativeselect.tsx +17 -0
- package/ui/navlink.tsx +40 -0
- package/ui/notification.tsx +25 -0
- package/ui/numberformatter.tsx +15 -0
- package/ui/numberinput.tsx +37 -0
- package/ui/overlay.tsx +15 -0
- package/ui/pagination.tsx +21 -0
- package/ui/paper.tsx +33 -0
- package/ui/passwordinput.tsx +36 -0
- package/ui/pill.tsx +17 -0
- package/ui/pillsinput.tsx +37 -0
- package/ui/pininput.tsx +30 -0
- package/ui/popover.tsx +43 -0
- package/ui/portal.tsx +15 -0
- package/ui/progress.tsx +49 -0
- package/ui/props.ts +91 -0
- package/ui/propsDef.ts +38 -0
- package/ui/radio.tsx +30 -0
- package/ui/rating.tsx +25 -0
- package/ui/ringprogress.tsx +17 -0
- package/ui/scrollarea.tsx +27 -0
- package/ui/segmentedcontrol.tsx +38 -0
- package/ui/select.tsx +43 -0
- package/ui/simplegrid.tsx +23 -0
- package/ui/skeleton.tsx +15 -0
- package/ui/slider.tsx +31 -0
- package/ui/space.tsx +19 -0
- package/ui/spoiler.tsx +23 -0
- package/ui/stepper.tsx +63 -0
- package/ui/switch.tsx +29 -0
- package/ui/table.tsx +93 -0
- package/ui/tabs.tsx +80 -0
- package/ui/tagsinput.tsx +19 -0
- package/ui/terminal.tsx +44 -0
- package/ui/text.tsx +168 -0
- package/ui/textarea.tsx +36 -0
- package/ui/textinput.tsx +34 -0
- package/ui/timeline.tsx +30 -0
- package/ui/title.tsx +42 -0
- package/ui/tooltip.tsx +32 -0
- package/ui/transition.tsx +21 -0
- package/ui/tree.tsx +42 -0
- package/ui/typographystylesprovider.tsx +20 -0
- package/ui/unstyledbutton.tsx +18 -0
- package/ui/video.tsx +16 -0
- package/ui/visuallyhidden.tsx +15 -0
- package/utils/index.ts +76 -0
package/ui/badge.tsx
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Badge, BadgeProps } from "@mantine/core";
|
|
2
|
+
import { create_component } from "../modules/component";
|
|
3
|
+
|
|
4
|
+
type Props = BadgeProps;
|
|
5
|
+
const Component = create_component({
|
|
6
|
+
name: "Badge",
|
|
7
|
+
description: "The badge UI element",
|
|
8
|
+
props: {
|
|
9
|
+
color: "dark",
|
|
10
|
+
children: "A badge",
|
|
11
|
+
} as Props,
|
|
12
|
+
propsDef: {
|
|
13
|
+
color: {
|
|
14
|
+
type: "color",
|
|
15
|
+
label: "Background color",
|
|
16
|
+
},
|
|
17
|
+
c: {
|
|
18
|
+
type: "color",
|
|
19
|
+
label: "Text color",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
render() {
|
|
23
|
+
delete this.props["mount_animation"];
|
|
24
|
+
const { children, ...other } = this.props;
|
|
25
|
+
return <Badge {...other}>{children}</Badge>;
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
export default Component;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Blockquote, BlockquoteProps } from "@mantine/core";
|
|
2
|
+
import { create_component } from "../modules/component";
|
|
3
|
+
|
|
4
|
+
type Props = BlockquoteProps;
|
|
5
|
+
const Component = create_component({
|
|
6
|
+
name: "Blockquote",
|
|
7
|
+
description: "The blockquote UI element",
|
|
8
|
+
props: {} as Props,
|
|
9
|
+
render() {
|
|
10
|
+
delete this.props["mount_animation"];
|
|
11
|
+
const { children, ...other } = this.props;
|
|
12
|
+
return <Blockquote {...other}>{children}</Blockquote>;
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
export default Component;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { create_component } from "southpaw/modules/component";
|
|
2
|
+
import { UI } from "..";
|
|
3
|
+
|
|
4
|
+
type FAQItem = {
|
|
5
|
+
id: string;
|
|
6
|
+
question: string;
|
|
7
|
+
answer: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
title?: string;
|
|
12
|
+
subtitle?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
questions?: FAQItem[];
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
textColor?: string;
|
|
17
|
+
accentColor?: string;
|
|
18
|
+
py?: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const Component = create_component({
|
|
22
|
+
name: "FAQ",
|
|
23
|
+
description:
|
|
24
|
+
"A section for frequently asked questions with collapsible answers",
|
|
25
|
+
props: {
|
|
26
|
+
title: "Frequently Asked Questions",
|
|
27
|
+
subtitle: "FAQ",
|
|
28
|
+
description: "Get answers to common questions about using Southpaw.",
|
|
29
|
+
accentColor: "primary",
|
|
30
|
+
py: 120,
|
|
31
|
+
questions: [
|
|
32
|
+
{
|
|
33
|
+
id: "1",
|
|
34
|
+
question: "How do I get started with Southpaw?",
|
|
35
|
+
answer:
|
|
36
|
+
"Getting started with Southpaw is easy. Just follow our quick start guide to set up your environment, and you'll be building UI blocks in minutes.",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "2",
|
|
40
|
+
question: "Does it support custom themes?",
|
|
41
|
+
answer:
|
|
42
|
+
"Absolutely! Southpaw is built with flexibility in mind. You can easily customize themes, colors, and typography to perfectly match your brand's identity.",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "3",
|
|
46
|
+
question: "Is it suitable for production applications?",
|
|
47
|
+
answer:
|
|
48
|
+
"Yes, Southpaw is designed for high-performance production workloads. It leverages Next.js and optimized UI components to ensure your app is both fast and robust.",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "4",
|
|
52
|
+
question: "How do I contribute to Southpaw?",
|
|
53
|
+
answer:
|
|
54
|
+
"We welcome contributions from the community! Check out our contribution guide on GitHub to learn how you can help improve Southpaw.",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
} as Props,
|
|
58
|
+
propsDef: {
|
|
59
|
+
title: { type: "text", label: "Main Title" },
|
|
60
|
+
subtitle: { type: "text", label: "Subtitle" },
|
|
61
|
+
description: { type: "text", label: "Description" },
|
|
62
|
+
backgroundColor: { type: "color", label: "Background Color" },
|
|
63
|
+
textColor: { type: "color", label: "Text Color" },
|
|
64
|
+
accentColor: { type: "color", label: "Accent Color" },
|
|
65
|
+
py: { type: "number", label: "Vertical Padding" },
|
|
66
|
+
questions: { type: "list-text", label: "Questions (JSON List)" } as any,
|
|
67
|
+
},
|
|
68
|
+
render() {
|
|
69
|
+
const {
|
|
70
|
+
title,
|
|
71
|
+
subtitle,
|
|
72
|
+
description,
|
|
73
|
+
questions,
|
|
74
|
+
backgroundColor,
|
|
75
|
+
textColor,
|
|
76
|
+
accentColor,
|
|
77
|
+
py,
|
|
78
|
+
} = this.props as Required<Props>;
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<UI.box py={py} px={40} style={{ backgroundColor }}>
|
|
82
|
+
<UI.container size="sm">
|
|
83
|
+
<UI.flex direction="column" align="center" gap={16} mb={80}>
|
|
84
|
+
{subtitle && (
|
|
85
|
+
<UI.badge
|
|
86
|
+
variant="light"
|
|
87
|
+
color={accentColor}
|
|
88
|
+
radius="xl"
|
|
89
|
+
size="lg"
|
|
90
|
+
>
|
|
91
|
+
{subtitle}
|
|
92
|
+
</UI.badge>
|
|
93
|
+
)}
|
|
94
|
+
<UI.title
|
|
95
|
+
text={title}
|
|
96
|
+
order={2}
|
|
97
|
+
fz={42}
|
|
98
|
+
fw={800}
|
|
99
|
+
ta="center"
|
|
100
|
+
c={textColor}
|
|
101
|
+
/>
|
|
102
|
+
<UI.text
|
|
103
|
+
text={description}
|
|
104
|
+
size="lg"
|
|
105
|
+
ta="center"
|
|
106
|
+
maw={700}
|
|
107
|
+
c={textColor}
|
|
108
|
+
opacity={0.7}
|
|
109
|
+
/>
|
|
110
|
+
</UI.flex>
|
|
111
|
+
|
|
112
|
+
<UI.accordion
|
|
113
|
+
variant="separated"
|
|
114
|
+
radius="xl"
|
|
115
|
+
mb="xl"
|
|
116
|
+
items={questions?.map((item) => ({
|
|
117
|
+
id: item.id,
|
|
118
|
+
label: (
|
|
119
|
+
<UI.text
|
|
120
|
+
text={item.question}
|
|
121
|
+
fw={600}
|
|
122
|
+
fz="lg"
|
|
123
|
+
p={12}
|
|
124
|
+
c={textColor}
|
|
125
|
+
/>
|
|
126
|
+
),
|
|
127
|
+
content: (
|
|
128
|
+
<UI.text
|
|
129
|
+
text={item.answer}
|
|
130
|
+
fz="md"
|
|
131
|
+
p={12}
|
|
132
|
+
lh={1.6}
|
|
133
|
+
opacity={0.8}
|
|
134
|
+
c={textColor}
|
|
135
|
+
/>
|
|
136
|
+
),
|
|
137
|
+
}))}
|
|
138
|
+
/>
|
|
139
|
+
</UI.container>
|
|
140
|
+
</UI.box>
|
|
141
|
+
);
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export default Component;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { create_component } from "southpaw/modules/component";
|
|
2
|
+
import { UI } from "..";
|
|
3
|
+
|
|
4
|
+
type FeatureItem = {
|
|
5
|
+
title: string;
|
|
6
|
+
description: string;
|
|
7
|
+
icon: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
title?: string;
|
|
12
|
+
subtitle?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
features?: FeatureItem[];
|
|
15
|
+
columns?: number;
|
|
16
|
+
backgroundColor?: string;
|
|
17
|
+
textColor?: string;
|
|
18
|
+
iconColor?: string;
|
|
19
|
+
py?: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const Component = create_component({
|
|
23
|
+
name: "Features",
|
|
24
|
+
description: "A premium features grid with icons and descriptions",
|
|
25
|
+
props: {
|
|
26
|
+
title: "Everything you need to build faster",
|
|
27
|
+
subtitle: "Robust Features",
|
|
28
|
+
description:
|
|
29
|
+
"Southpaw provides a complete toolkit for building modern web applications with speed and precision.",
|
|
30
|
+
columns: 3,
|
|
31
|
+
py: 120,
|
|
32
|
+
features: [
|
|
33
|
+
{
|
|
34
|
+
title: "Visual Development",
|
|
35
|
+
description:
|
|
36
|
+
"Edit your components directly in the browser with real-time preview and property controls.",
|
|
37
|
+
icon: "visibility",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
title: "TypeScript First",
|
|
41
|
+
description:
|
|
42
|
+
"Highly typed API ensures your codebase stays robust and maintainable as it scales.",
|
|
43
|
+
icon: "code",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: "Premium Blocks",
|
|
47
|
+
description:
|
|
48
|
+
"Access a library of pre-built, high-quality UI blocks to jumpstart your next project.",
|
|
49
|
+
icon: "dashboard",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
title: "Performance Optimized",
|
|
53
|
+
description:
|
|
54
|
+
"Built on Next.js with automatic code splitting and server-side rendering for peak performance.",
|
|
55
|
+
icon: "speed",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: "Customizable Design",
|
|
59
|
+
description:
|
|
60
|
+
"Easily theme your application with our flexible and powerful design system.",
|
|
61
|
+
icon: "palette",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: "Enterprise Ready",
|
|
65
|
+
description:
|
|
66
|
+
"Engineered for reliability and security, suitable for projects of any size.",
|
|
67
|
+
icon: "security",
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
} as Props,
|
|
71
|
+
propsDef: {
|
|
72
|
+
title: { type: "text", label: "Main Title" },
|
|
73
|
+
subtitle: { type: "text", label: "Subtitle" },
|
|
74
|
+
description: { type: "text", label: "Description" },
|
|
75
|
+
columns: {
|
|
76
|
+
type: "number",
|
|
77
|
+
label: "Columns",
|
|
78
|
+
min: 2,
|
|
79
|
+
step: 1,
|
|
80
|
+
max: 4,
|
|
81
|
+
},
|
|
82
|
+
backgroundColor: { type: "color", label: "Background Color" },
|
|
83
|
+
textColor: { type: "color", label: "Text Color" },
|
|
84
|
+
iconColor: { type: "color", label: "Icon Color" },
|
|
85
|
+
py: { type: "number", label: "Vertical Padding" },
|
|
86
|
+
features: { type: "list-json", label: "Features (JSON List)" },
|
|
87
|
+
},
|
|
88
|
+
render() {
|
|
89
|
+
const {
|
|
90
|
+
title,
|
|
91
|
+
subtitle,
|
|
92
|
+
description,
|
|
93
|
+
features,
|
|
94
|
+
columns,
|
|
95
|
+
backgroundColor,
|
|
96
|
+
textColor,
|
|
97
|
+
iconColor,
|
|
98
|
+
py,
|
|
99
|
+
} = this.props as Required<Props>;
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<UI.box py={py} px={40} style={{ backgroundColor }}>
|
|
103
|
+
<UI.container size="lg">
|
|
104
|
+
<UI.flex direction="column" align="center" gap={16} mb={80}>
|
|
105
|
+
{subtitle && (
|
|
106
|
+
<UI.badge
|
|
107
|
+
variant="filled"
|
|
108
|
+
color={iconColor}
|
|
109
|
+
radius="xl"
|
|
110
|
+
size="lg"
|
|
111
|
+
>
|
|
112
|
+
{subtitle}
|
|
113
|
+
</UI.badge>
|
|
114
|
+
)}
|
|
115
|
+
<UI.title
|
|
116
|
+
text={title}
|
|
117
|
+
order={2}
|
|
118
|
+
fz={42}
|
|
119
|
+
fw={800}
|
|
120
|
+
ta="center"
|
|
121
|
+
c={textColor}
|
|
122
|
+
styles={{
|
|
123
|
+
root: {
|
|
124
|
+
textWrap: "wrap",
|
|
125
|
+
},
|
|
126
|
+
}}
|
|
127
|
+
/>
|
|
128
|
+
<UI.text
|
|
129
|
+
text={description}
|
|
130
|
+
size="lg"
|
|
131
|
+
ta="center"
|
|
132
|
+
maw={700}
|
|
133
|
+
c={textColor}
|
|
134
|
+
opacity={0.7}
|
|
135
|
+
/>
|
|
136
|
+
</UI.flex>
|
|
137
|
+
|
|
138
|
+
<UI.simplegrid cols={{ base: 1, sm: 2, md: columns }} spacing={40}>
|
|
139
|
+
{features?.map((feature, index) => (
|
|
140
|
+
<UI.flex key={index} gap={20} align="flex-start">
|
|
141
|
+
<UI.box p={12}>
|
|
142
|
+
<UI.icon icon={feature.icon as any} fz={28} />
|
|
143
|
+
</UI.box>
|
|
144
|
+
<UI.flex direction="column" gap={8} style={{ flex: 1 }}>
|
|
145
|
+
<UI.text
|
|
146
|
+
text={feature.title}
|
|
147
|
+
fw={700}
|
|
148
|
+
fz="lg"
|
|
149
|
+
c={textColor}
|
|
150
|
+
/>
|
|
151
|
+
<UI.text
|
|
152
|
+
text={feature.description}
|
|
153
|
+
c={textColor}
|
|
154
|
+
opacity={0.65}
|
|
155
|
+
lh={1.5}
|
|
156
|
+
/>
|
|
157
|
+
</UI.flex>
|
|
158
|
+
</UI.flex>
|
|
159
|
+
))}
|
|
160
|
+
</UI.simplegrid>
|
|
161
|
+
</UI.container>
|
|
162
|
+
</UI.box>
|
|
163
|
+
);
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
export default Component;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { create_component } from "southpaw/modules/component";
|
|
2
|
+
import { UI } from "..";
|
|
3
|
+
|
|
4
|
+
type Link = {
|
|
5
|
+
label: string;
|
|
6
|
+
href: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type Section = {
|
|
10
|
+
title: string;
|
|
11
|
+
links: Link[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
companyName?: string;
|
|
16
|
+
tagline?: string;
|
|
17
|
+
sections?: Section[];
|
|
18
|
+
backgroundColor?: string;
|
|
19
|
+
textColor?: string;
|
|
20
|
+
accentColor?: string;
|
|
21
|
+
py?: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const Component = create_component({
|
|
25
|
+
name: "Footer",
|
|
26
|
+
description:
|
|
27
|
+
"A premium footer with multiple columns of links and company information",
|
|
28
|
+
props: {
|
|
29
|
+
companyName: "Southpaw",
|
|
30
|
+
tagline:
|
|
31
|
+
"Build beautiful web experiences faster with our powerful UI framework.",
|
|
32
|
+
accentColor: "primary",
|
|
33
|
+
py: 80,
|
|
34
|
+
sections: [
|
|
35
|
+
{
|
|
36
|
+
title: "Product",
|
|
37
|
+
links: [
|
|
38
|
+
{ label: "Features", href: "#features" },
|
|
39
|
+
{ label: "Pricing", href: "#pricing" },
|
|
40
|
+
{ label: "Documentation", href: "#docs" },
|
|
41
|
+
{ label: "API Reference", href: "#api" },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
title: "Company",
|
|
46
|
+
links: [
|
|
47
|
+
{ label: "About Us", href: "#about" },
|
|
48
|
+
{ label: "Blog", href: "#blog" },
|
|
49
|
+
{ label: "Careers", href: "#careers" },
|
|
50
|
+
{ label: "Contact Us", href: "#contact" },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: "Legal",
|
|
55
|
+
links: [
|
|
56
|
+
{ label: "Privacy Policy", href: "#privacy" },
|
|
57
|
+
{ label: "Terms of Service", href: "#terms" },
|
|
58
|
+
{ label: "Cookie Policy", href: "#cookies" },
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
} as Props,
|
|
63
|
+
propsDef: {
|
|
64
|
+
companyName: { type: "text", label: "Company Name" },
|
|
65
|
+
tagline: { type: "text", label: "Company Tagline" },
|
|
66
|
+
backgroundColor: { type: "color", label: "Background Color" },
|
|
67
|
+
textColor: { type: "color", label: "Text Color" },
|
|
68
|
+
accentColor: { type: "color", label: "Accent Color" },
|
|
69
|
+
py: { type: "number", label: "Vertical Padding" },
|
|
70
|
+
sections: { type: "list-text", label: "Sections (JSON List)" },
|
|
71
|
+
},
|
|
72
|
+
render() {
|
|
73
|
+
const {
|
|
74
|
+
companyName,
|
|
75
|
+
tagline,
|
|
76
|
+
sections,
|
|
77
|
+
backgroundColor,
|
|
78
|
+
textColor,
|
|
79
|
+
accentColor,
|
|
80
|
+
py,
|
|
81
|
+
} = this.props as Required<Props>;
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<UI.box py={py} px={40} style={{ backgroundColor }}>
|
|
85
|
+
<UI.container size="lg">
|
|
86
|
+
<UI.simplegrid cols={{ base: 1, sm: 2, md: 5 }} spacing={40} mb={60}>
|
|
87
|
+
<UI.flex
|
|
88
|
+
direction="column"
|
|
89
|
+
gap={20}
|
|
90
|
+
style={{ gridColumn: "span 2" }}
|
|
91
|
+
>
|
|
92
|
+
<UI.flex align="center" gap={12}>
|
|
93
|
+
<UI.icon icon="auto_fix_high" c={accentColor} fz={28} />
|
|
94
|
+
<UI.text
|
|
95
|
+
text={companyName}
|
|
96
|
+
fw={800}
|
|
97
|
+
fz={24}
|
|
98
|
+
c={textColor}
|
|
99
|
+
lts={-0.5}
|
|
100
|
+
/>
|
|
101
|
+
</UI.flex>
|
|
102
|
+
<UI.text
|
|
103
|
+
text={tagline}
|
|
104
|
+
fz="sm"
|
|
105
|
+
opacity={0.6}
|
|
106
|
+
maw={300}
|
|
107
|
+
c={textColor}
|
|
108
|
+
/>
|
|
109
|
+
<UI.flex gap={16} mt={8}>
|
|
110
|
+
<UI.actionicon variant="subtle" color="gray">
|
|
111
|
+
<UI.icon icon={"face"} />
|
|
112
|
+
</UI.actionicon>
|
|
113
|
+
<UI.actionicon variant="subtle" color="gray">
|
|
114
|
+
<UI.icon icon={"10k"} />
|
|
115
|
+
</UI.actionicon>
|
|
116
|
+
<UI.actionicon variant="subtle" color="gray">
|
|
117
|
+
<UI.icon icon={"airplay"} />
|
|
118
|
+
</UI.actionicon>
|
|
119
|
+
</UI.flex>
|
|
120
|
+
</UI.flex>
|
|
121
|
+
|
|
122
|
+
{sections?.map((section, index) => (
|
|
123
|
+
<UI.flex key={index} direction="column" gap={20}>
|
|
124
|
+
<UI.text
|
|
125
|
+
text={section.title}
|
|
126
|
+
fw={700}
|
|
127
|
+
fz="sm"
|
|
128
|
+
tt="uppercase"
|
|
129
|
+
lts={1.5}
|
|
130
|
+
c={textColor}
|
|
131
|
+
/>
|
|
132
|
+
<UI.flex direction="column" gap={12}>
|
|
133
|
+
{section.links.map((link, lIndex) => (
|
|
134
|
+
<UI.anchor
|
|
135
|
+
key={lIndex}
|
|
136
|
+
href={link.href}
|
|
137
|
+
fz="sm"
|
|
138
|
+
c={textColor}
|
|
139
|
+
opacity={0.6}
|
|
140
|
+
style={{ transition: "all 0.2s ease" }}
|
|
141
|
+
>
|
|
142
|
+
{link.label}
|
|
143
|
+
</UI.anchor>
|
|
144
|
+
))}
|
|
145
|
+
</UI.flex>
|
|
146
|
+
</UI.flex>
|
|
147
|
+
))}
|
|
148
|
+
</UI.simplegrid>
|
|
149
|
+
|
|
150
|
+
<UI.divider opacity={0.1} mb={40} />
|
|
151
|
+
|
|
152
|
+
<UI.flex
|
|
153
|
+
justify="space-between"
|
|
154
|
+
align="center"
|
|
155
|
+
direction={{ base: "column", sm: "row" }}
|
|
156
|
+
gap={20}
|
|
157
|
+
>
|
|
158
|
+
<UI.text
|
|
159
|
+
text={`© ${new Date().getFullYear()} ${companyName} Inc. All rights reserved.`}
|
|
160
|
+
fz="xs"
|
|
161
|
+
opacity={0.5}
|
|
162
|
+
c={textColor}
|
|
163
|
+
/>
|
|
164
|
+
<UI.flex gap={24}>
|
|
165
|
+
<UI.anchor fz="xs" href="#" opacity={0.5} c={textColor}>
|
|
166
|
+
Terms
|
|
167
|
+
</UI.anchor>
|
|
168
|
+
<UI.anchor fz="xs" href="#" opacity={0.5} c={textColor}>
|
|
169
|
+
Privacy
|
|
170
|
+
</UI.anchor>
|
|
171
|
+
<UI.anchor fz="xs" href="#" opacity={0.5} c={textColor}>
|
|
172
|
+
Cookies
|
|
173
|
+
</UI.anchor>
|
|
174
|
+
</UI.flex>
|
|
175
|
+
</UI.flex>
|
|
176
|
+
</UI.container>
|
|
177
|
+
</UI.box>
|
|
178
|
+
);
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
export default Component;
|