Merge pull request 'ui/checkbox: use css modules' (#5228) from hgl-ui-checkbox into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5228 Reviewed-by: brianmcgee <brian@bmcgee.ie>
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
div.form-field {
|
||||
&.checkbox {
|
||||
@apply items-start;
|
||||
|
||||
& div.checkbox-control {
|
||||
@apply w-5 h-5 rounded-sm bg-def-1 border border-inv-1 p-[0.0625rem];
|
||||
|
||||
&:hover {
|
||||
@apply bg-def-acc-2;
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
@apply border-def-2;
|
||||
}
|
||||
|
||||
&[data-invalid] {
|
||||
@apply border-semantic-error-4;
|
||||
}
|
||||
|
||||
&[data-readonly] {
|
||||
@apply cursor-default bg-inherit border-none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.inverted {
|
||||
&.checkbox {
|
||||
& div.checkbox-control {
|
||||
@apply bg-inv-1;
|
||||
|
||||
&:hover,
|
||||
&[data-checked] {
|
||||
@apply bg-inv-acc-4;
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
@apply bg-def-4 border-none;
|
||||
}
|
||||
|
||||
&[data-readonly] {
|
||||
@apply bg-inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.s {
|
||||
& div.checkbox-control {
|
||||
@apply w-4 h-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
pkgs/clan-app/ui/src/components/Form/Checkbox.module.css
Normal file
43
pkgs/clan-app/ui/src/components/Form/Checkbox.module.css
Normal file
@@ -0,0 +1,43 @@
|
||||
.checkbox {
|
||||
@apply items-start;
|
||||
}
|
||||
|
||||
.checkboxControl {
|
||||
@apply w-5 h-5 rounded-sm bg-def-1 border border-inv-1 p-[0.0625rem];
|
||||
|
||||
&:hover {
|
||||
@apply bg-def-acc-2;
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
@apply border-def-2;
|
||||
}
|
||||
|
||||
&[data-invalid] {
|
||||
@apply border-semantic-error-4;
|
||||
}
|
||||
|
||||
&[data-readonly] {
|
||||
@apply cursor-default bg-inherit border-none;
|
||||
}
|
||||
|
||||
.checkbox.s & {
|
||||
@apply w-4 h-4;
|
||||
}
|
||||
.checkbox.inverted & {
|
||||
@apply bg-inv-1;
|
||||
|
||||
&:hover,
|
||||
&[data-checked] {
|
||||
@apply bg-inv-acc-4;
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
@apply bg-def-4 border-none;
|
||||
}
|
||||
|
||||
&[data-readonly] {
|
||||
@apply bg-inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
import {
|
||||
CheckboxInputProps as KCheckboxInputProps,
|
||||
CheckboxRootProps as KCheckboxRootProps,
|
||||
Checkbox as KCheckbox,
|
||||
} from "@kobalte/core/checkbox";
|
||||
|
||||
import { Checkbox as KCheckbox } from "@kobalte/core";
|
||||
|
||||
import Icon from "@/src/components/Icon/Icon";
|
||||
|
||||
import cx from "classnames";
|
||||
import { Label } from "./Label";
|
||||
import { PolymorphicProps } from "@kobalte/core/polymorphic";
|
||||
import "./Checkbox.css";
|
||||
import styles from "./Checkbox.module.css";
|
||||
import { FieldProps } from "./Field";
|
||||
import { Orienter } from "./Orienter";
|
||||
import { Match, splitProps, Switch } from "solid-js";
|
||||
import { Match, mergeProps, splitProps, Switch } from "solid-js";
|
||||
|
||||
export type CheckboxProps = FieldProps &
|
||||
KCheckboxRootProps & {
|
||||
@@ -21,24 +20,15 @@ export type CheckboxProps = FieldProps &
|
||||
};
|
||||
|
||||
export const Checkbox = (props: CheckboxProps) => {
|
||||
// we need to separate output the input otherwise it interferes with prop binding
|
||||
const [_, rootProps] = splitProps(props, ["input"]);
|
||||
|
||||
const [styleProps, otherRootProps] = splitProps(rootProps, [
|
||||
"class",
|
||||
"size",
|
||||
"orientation",
|
||||
"inverted",
|
||||
"ghost",
|
||||
]);
|
||||
|
||||
const alignment = () =>
|
||||
(props.orientation || "vertical") == "vertical" ? "start" : "center";
|
||||
const [local, other] = splitProps(
|
||||
mergeProps({ size: "default", orientation: "vertical" } as const, props),
|
||||
["size", "orientation", "inverted", "ghost", "input"],
|
||||
);
|
||||
|
||||
const iconChecked = (
|
||||
<Icon
|
||||
icon="Checkmark"
|
||||
inverted={props.inverted}
|
||||
inverted={local.inverted}
|
||||
color="secondary"
|
||||
size="100%"
|
||||
/>
|
||||
@@ -47,50 +37,45 @@ export const Checkbox = (props: CheckboxProps) => {
|
||||
const iconUnchecked = (
|
||||
<Icon
|
||||
icon="Close"
|
||||
inverted={props.inverted}
|
||||
inverted={local.inverted}
|
||||
color="secondary"
|
||||
size="100%"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<KCheckbox.Root
|
||||
<KCheckbox
|
||||
class={cx(
|
||||
styleProps.class,
|
||||
"form-field",
|
||||
"checkbox",
|
||||
styleProps.size,
|
||||
styleProps.orientation,
|
||||
styles.checkbox,
|
||||
local.size != "default" && styles[local.size],
|
||||
{
|
||||
inverted: styleProps.inverted,
|
||||
ghost: styleProps.ghost,
|
||||
[styles.inverted]: local.inverted,
|
||||
},
|
||||
)}
|
||||
{...otherRootProps}
|
||||
{...other}
|
||||
>
|
||||
{(state) => (
|
||||
<Orienter orientation={styleProps.orientation} align={alignment()}>
|
||||
<Orienter
|
||||
orientation={local.orientation}
|
||||
align={local.orientation == "vertical" ? "start" : "center"}
|
||||
>
|
||||
<Label
|
||||
labelComponent={KCheckbox.Label}
|
||||
descriptionComponent={KCheckbox.Description}
|
||||
{...props}
|
||||
/>
|
||||
<KCheckbox.Input {...props.input} />
|
||||
<KCheckbox.Control class="checkbox-control">
|
||||
<KCheckbox.Input {...local.input} />
|
||||
<KCheckbox.Control class={styles.checkboxControl}>
|
||||
<Switch>
|
||||
<Match when={!props.readOnly}>
|
||||
<Match when={!other.readOnly}>
|
||||
<KCheckbox.Indicator>{iconChecked}</KCheckbox.Indicator>
|
||||
</Match>
|
||||
<Match when={props.readOnly && state.checked()}>
|
||||
{iconChecked}
|
||||
</Match>
|
||||
<Match when={props.readOnly && !state.checked()}>
|
||||
{iconUnchecked}
|
||||
</Match>
|
||||
<Match when={state.checked()}>{iconChecked}</Match>
|
||||
<Match when={true}>{iconUnchecked}</Match>
|
||||
</Switch>
|
||||
</KCheckbox.Control>
|
||||
</Orienter>
|
||||
)}
|
||||
</KCheckbox.Root>
|
||||
</KCheckbox>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,15 +13,4 @@ div.form-label {
|
||||
& > label {
|
||||
@apply flex items-center gap-1;
|
||||
}
|
||||
|
||||
& > span[data-required]:not(span[data-readonly]),
|
||||
& > label[data-required]:not(label[data-readonly]) {
|
||||
.typography::after {
|
||||
@apply fg-def-4 ml-1;
|
||||
|
||||
content: "*";
|
||||
font-family: "Commit Mono", monospace;
|
||||
font-size: 0.6875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ export const Label = (props: LabelProps) => {
|
||||
color={props.validationState == "invalid" ? "error" : "primary"}
|
||||
weight={props.labelWeight || "bold"}
|
||||
inverted={props.inverted}
|
||||
in="Label"
|
||||
>
|
||||
{props.label}
|
||||
</Typography>
|
||||
|
||||
@@ -189,7 +189,15 @@
|
||||
.typography.in-Button {
|
||||
@apply max-w-full overflow-hidden whitespace-nowrap text-ellipsis;
|
||||
}
|
||||
.typography.in-Label {
|
||||
[data-required]:not([data-readonly]) &::after {
|
||||
@apply fg-def-4 ml-1;
|
||||
|
||||
content: "*";
|
||||
font-family: "Commit Mono", monospace;
|
||||
font-size: 0.6875rem;
|
||||
}
|
||||
}
|
||||
.typography.in-Modal-title {
|
||||
@apply mx-auto;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export interface TypographyProps<H extends Hierarchy> {
|
||||
align?: "left" | "center" | "right";
|
||||
in?:
|
||||
| "Button"
|
||||
| "Label"
|
||||
| "Modal-title"
|
||||
| "TagSelect-label"
|
||||
| "Select-item-label"
|
||||
|
||||
Reference in New Issue
Block a user