feat(www): Finish up on the onboarding (#202)

## Description
This is an attempt to finish up on the onboarding and creating a team

## Type of Change

- [ ] Bug fix (non-breaking change)
- [x] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that changes existing
functionality)
- [ ] Documentation update
- [ ] Other (please describe):

## Checklist

- [ ] I have updated relevant documentation
- [x] My code follows the project's coding style
- [x] My changes generate no new warnings/errors
This commit is contained in:
Wanjohi
2025-03-05 22:44:00 +03:00
committed by GitHub
parent 1aeafec40b
commit 117503081b
19 changed files with 828 additions and 111 deletions

View File

@@ -0,0 +1,34 @@
import { theme } from "./theme";
import { styled } from "@macaron-css/solid";
export const Button = styled("button", {
base: {
borderRadius: 6,
border: "1px solid transparent",
padding: `${theme.space[2]} ${theme.space[4]}`,
fontWeight: 500,
letterSpacing: 0.1,
lineHeight: "normal",
fontFamily: theme.font.family.heading,
textAlign: "center",
transitionDelay: "0s, 0s",
transitionDuration: "0.2s, 0.2s",
transitionProperty: "background-color, border",
transitionTimingFunction: "ease-out, ease-out",
display: "inline-flex",
gap: theme.space[1.5],
alignItems: "center",
justifyContent: "center",
":disabled": {
pointerEvents: "none",
},
},
variants: {
color: {
brand: {
backgroundColor: theme.color.brand,
color: "#FFF",
}
}
}
})

View File

@@ -0,0 +1,310 @@
import { theme } from "./theme";
import { styled } from "@macaron-css/solid"
import { CSSProperties } from "@macaron-css/core";
import { ComponentProps, createMemo, For, JSX, Show, splitProps } from "solid-js";
import { Container } from "./layout";
import { utility } from "./utility";
export const inputStyles: CSSProperties = {
lineHeight: theme.font.lineHeight,
appearance: "none",
fontSize: theme.font.size.sm,
borderRadius: theme.borderRadius,
padding: `0 ${theme.space[3]}`,
height: theme.input.size.base,
borderWidth: 1,
borderStyle: "solid",
borderColor: theme.color.gray.d400,
color: theme.color.d1000.gray,
backgroundColor: theme.color.background.d100,
// transition: `box-shadow ${theme.colorFadeDuration}`,
// boxShadow: `
// 0 0 0 1px inset ${theme.color.input.border},
// ${theme.color.input.shadow}
// `,
};
export const inputDisabledStyles: CSSProperties = {
opacity: 0.5,
backgroundColor: theme.color.background.d200,
color: theme.color.gray.d400,
cursor: "default",
// boxShadow: `0 0 0 1px inset ${theme.color.input.border}`,
};
export const inputFocusStyles: CSSProperties = {
outlineOffset: 3,
outline: `${theme.color.gray.d600} solid 2px`,
};
export const inputDangerTextStyles: CSSProperties = {
color: theme.color.red.d700,
};
export const inputDangerFocusStyles: CSSProperties = {
...inputDangerTextStyles,
outlineColor: theme.color.red.d700,
// boxShadow: `
// 0 0 1px 1px inset hsla(${theme.color.red.l2}, 100%),
// ${theme.color.input.shadow}
// `,
};
export const Root = styled("label", {
base: {
...utility.stack(2),
},
variants: {
color: {
primary: {
color: theme.color.gray.d900
},
danger: {
color: theme.color.red.d900
},
},
},
defaultVariants: {
color: "primary",
},
});
type FormFieldProps = ComponentProps<typeof Root> & {
hint?: JSX.Element;
label?: string;
};
export const Input = styled("input", {
base: {
...inputStyles,
":focus": {
...inputFocusStyles,
},
":disabled": {
...inputDisabledStyles,
},
"::placeholder": {
color: theme.color.gray.d800
}
// selectors: {
// [`${Root.selector({ color: "danger" })} &`]: {
// ...inputDangerFocusStyles,
// },
// },
},
variants: {
color: {
primary: {},
danger: {
...inputDangerFocusStyles,
":focus": {
...inputDangerFocusStyles,
},
},
},
size: {
sm: {
height: theme.input.size.sm,
},
},
},
defaultVariants: {
color: "primary",
},
});
export const InputRadio = styled("input", {
base: {
padding: 0,
// borderRadius: 0,
WebkitAppearance: "none",
appearance: "none",
/* For iOS < 15 to remove gradient background */
backgroundColor: theme.color.background.d100,
/* Not removed via appearance */
margin: 0,
font: "inherit",
color: "currentColor",
width: "1.15em",
height: "1.15em",
border: "0.15em solid currentColor",
borderRadius: "50%",
transform: "translateY(-0.075em)",
display: "grid",
position: "relative",
placeContent: "center",
":before": {
content: "",
width: "0.68em",
height: "0.68em",
borderRadius: "50%",
transform: " scale(0)",
transition: "120ms transform ease-in-out",
boxShadow: `inset 1em 1em ${theme.color.blue.d700}`
},
selectors: {
"&:checked::before": {
transform: "scale(1)"
}
}
}
});
const Label = styled("p", {
base: {
fontWeight: 500,
letterSpacing: -0.1,
fontSize: theme.font.size.mono_sm,
textTransform: "capitalize",
fontFamily: theme.font.family.heading,
},
});
const InputLabel = styled("label", {
base: {
letterSpacing: -0.1,
fontSize: theme.font.size.sm,
lineHeight: theme.font.lineHeight,
height: theme.input.size.base,
appearance: "none",
padding: `0 ${theme.space[3]}`,
borderWidth: 0,
borderBottomWidth: 1,
borderStyle: "solid",
borderColor: theme.color.gray.d400,
color: theme.color.gray.d800,
backgroundColor: theme.color.background.d100,
position: "relative",
display: "flex",
alignItems: "center",
cursor: "pointer",
gap: "1em",
":focus-within": {
color: theme.color.d1000.gray
},
":first-child": {
borderTopRightRadius: theme.borderRadius,
borderTopLeftRadius: theme.borderRadius,
},
":last-child": {
borderBottomWidth: 0,
borderBottomRightRadius: theme.borderRadius,
borderBottomLeftRadius: theme.borderRadius,
},
":hover": {
backgroundColor: theme.color.background.d200,
},
selectors: {
"&:has(input:checked)": {
color: theme.color.d1000.gray
}
}
},
});
const Hint = styled("p", {
base: {
fontSize: theme.font.size.sm,
lineHeight: theme.font.lineHeight,
color: theme.color.gray.d800,
},
variants: {
color: {
primary: {},
danger: {
color: theme.color.red.d700,
},
},
},
defaultVariants: {
color: "primary",
},
});
export function FormField(props: FormFieldProps) {
return (
<Root {...props}>
<Container space="2">
<Show when={props.label}>
<Label color={props.color}>{props.label}</Label>
</Show>
{props.children}
</Container>
<Show when={props.hint}>
<Hint color={props.color}>{props.hint!}</Hint>
</Show>
</Root>
);
}
type SelectProps = {
ref: (element: HTMLInputElement) => void;
name: string;
value: any;
onInput: JSX.EventHandler<HTMLInputElement, InputEvent>;
onChange: JSX.EventHandler<HTMLInputElement, Event>;
onBlur: JSX.EventHandler<HTMLInputElement, FocusEvent>;
options: { label: string; value: string }[];
badges?: { label: string; color: keyof typeof theme.color.d1000 }[];
required?: boolean;
class?: string;
};
const InputRadioContainer = styled("div", {
base: {
...inputStyles,
display: "flex",
flexDirection: "column",
height: "auto",
position: "relative",
padding: 0,
}
})
const Badge = styled("div", {
base: {
color: "#FFF",
marginLeft: "auto",
borderRadius: 9999,
letterSpacing: 0.5,
padding: "0 6px",
fontSize: theme.font.size.xs
}
})
export function Select(props: SelectProps) {
// Split select element props
const [, inputProps] = splitProps(props, [
'class',
'value',
'options',
'badges',
]);
return (
<InputRadioContainer>
<For each={props.options}>
{({ label, value }, key) => (
<InputLabel for={label}>
<InputRadio
{...inputProps}
type="radio"
value={value}
id={label}
/>
{label}
<Show when={props.badges}>
{props.badges &&
<Badge style={{"background-color": theme.color[props.badges[key()].color].d700 }}>
{props.badges[key()].label}
</Badge>
}
</Show>
</InputLabel>
)}
</For>
</InputRadioContainer >
);
}

View File

@@ -0,0 +1,6 @@
export * from "./form"
export * from "./layout"
export * from "./text"
export * from "./theme"
export * from "./utility"
export * from "./button"

View File

@@ -4,7 +4,6 @@ import { styled } from "@macaron-css/solid";
export const FullScreen = styled("div", {
base: {
inset: 0,
zIndex: 0,
display: "flex",
position: "fixed",
alignItems: "center",
@@ -21,28 +20,97 @@ export const FullScreen = styled("div", {
},
})
// export const Container = styled("div", {
// base: {
// backgroundColor: theme.color.background.d100,
// borderColor: theme.color.gray.d400,
// padding: "64px 80px 48px",
// justifyContent: "center",
// borderStyle: "solid",
// position: "relative",
// borderRadius: 12,
// alignItems: "center",
// maxWidth: 550,
// borderWidth: 1,
// display: "flex",
// },
// variants: {
// flow: {
// column: {
// flexDirection: "column"
// },
// row: {
// flexDirection: "row"
// }
// }
// }
// })
export const Container = styled("div", {
base: {
backgroundColor: theme.color.background.d100,
borderColor: theme.color.gray.d400,
padding: "64px 80px 48px",
justifyContent: "center",
borderStyle: "solid",
position: "relative",
borderRadius: 12,
alignItems: "center",
maxWidth: 550,
borderWidth: 1,
display: "flex",
flexDirection: "column",
},
variants: {
flow: {
column: {
flexDirection: "column"
},
row: {
flexDirection: "row"
space: (() => {
const result = {} as Record<`${keyof (typeof theme)["space"]}`, any>;
for (const key in theme.space) {
const value = theme.space[key as keyof typeof theme.space];
result[key as keyof typeof theme.space] = {
gap: value,
};
}
}
}
})
return result;
})(),
rounded: (() => {
const result = {} as Record<`${keyof (typeof theme)["space"]}`, any>;
for (const key in theme.space) {
const value = theme.space[key as keyof typeof theme.space];
result[key as keyof typeof theme.space] = {
borderRadius: value,
};
}
return result;
})(),
highlighted: {
true: {
borderColor: theme.color.gray.d400,
backgroundColor: theme.color.background.d100,
borderStyle: "solid",
borderWidth: 1,
padding: "64px 80px 48px",
maxWidth: 550,
}
},
flex: {
true: {
flex: "1 1 auto",
},
false: {
flex: "0 0 auto",
},
},
horizontal: {
center: {
alignItems: "center",
},
start: {
alignItems: "flex-start",
},
end: {
alignItems: "flex-end",
},
},
vertical: {
center: {
justifyContent: "center",
},
start: {
justifyContent: "flex-start",
},
end: {
justifyContent: "flex-end",
},
},
},
});

View File

@@ -4,9 +4,9 @@ import { utility } from "./utility";
import { CSSProperties } from "@macaron-css/core";
export const Text = styled("span", {
base: {
textWrap: "balance"
},
// base: {
// textWrap: "balance"
// },
variants: {
leading: {
base: {
@@ -122,6 +122,15 @@ export const Text = styled("span", {
}
return result;
})(),
font: (() => {
const result = {} as Record<`${keyof typeof theme.font.family}`, any>;
for (const [key, value] of Object.entries(theme.font.family)) {
result[key as keyof typeof theme.font.family] = {
fontFamily: value,
};
}
return result;
})(),
color: (() => {
const record = {} as Record<keyof typeof theme.color.text, CSSProperties>;
for (const [key, _value] of Object.entries(theme.color.text)) {

View File

@@ -2,7 +2,7 @@ import { createTheme } from "@macaron-css/core";
const constants = {
colorFadeDuration: "0.15s",
borderRadius: "4px",
borderRadius: "6px",
textBoldWeight: "600",
iconOpacity: "0.85",
modalWidth: {
@@ -16,6 +16,13 @@ const constants = {
},
};
const formInput = {
size: {
base: "40px",
sm: "32px",
},
};
const space = {
px: "1px",
0: "0px",
@@ -96,7 +103,7 @@ const light = (() => {
d100: 'hsla(0,0%,95%)',
d200: 'hsla(0,0%,92%)',
d300: 'hsla(0,0%,90%)',
d400: 'hsla(0,0%,92%)',
d400: 'hsla(0,0%,82%)',
d500: 'hsla(0,0%,79%)',
d600: 'hsla(0,0%,66%)',
d700: 'hsla(0,0%,56%)',
@@ -206,12 +213,13 @@ const light = (() => {
teal: "hsla(171,80%,13%)",
purple: "hsla(276,100%,15)",
pink: "hsla(333,74%,15%)",
grayAlpha: " hsla(0,0%,0%,0.91)"
grayAlpha: " hsla(0,0%,0%,0.91)",
}
const brand = "#FF4F01"
const background = {
d100: 'hsla(0,0%,100%)',
d200: 'hsla(0,0%,98%)'
d100: '#f5f5f5',
d200: 'oklch(from #f5f5f5 calc(l + (-0.06 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.03)) c h)'
};
const contrastFg = '#ffffff';
@@ -248,6 +256,7 @@ const light = (() => {
focusBorder,
focusColor,
d1000,
brand,
text
};
})()
@@ -365,13 +374,16 @@ const dark = (() => {
teal: "hsla(166,71%,93%)",
purple: "hsla(281,73%,96%)",
pink: "hsla( 333,90%,96%)",
grayAlpha: "hsla(0,0%,100%,0.92)"
grayAlpha: "hsla(0,0%,100%,0.92)",
}
const brand = "#FF4F01"
const background = {
d100: 'hsla(0,0%,4%)',
d200: 'hsla(0,0%,0%)'
d200: '#171717',
d100: "oklch(from #171717 calc(l + (-0.06 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.03)) c h)"
};
const contrastFg = '#ffffff';
const focusBorder = `0 0 0 1px ${grayAlpha.d600}, 0px 0px 0px 4px rgba(255,255,255,0.24)`;
const focusColor = blue.d900
@@ -406,7 +418,8 @@ const dark = (() => {
focusBorder,
focusColor,
d1000,
text
text,
brand
};
})()
@@ -415,6 +428,7 @@ export const [lightClass, theme] = createTheme({
space,
font,
color: light,
input: formInput
});
export const darkClass = createTheme(theme, {
@@ -423,4 +437,5 @@ export const darkClass = createTheme(theme, {
space,
font,
color: dark,
input: formInput
});