From c1278109c9600ded4ab937686d4c7288fda2524d Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:46:46 -0500 Subject: wip: desktop work --- packages/ui/src/components/checkbox.css | 121 ++++++++++++++++++++++++++++++++ packages/ui/src/components/checkbox.tsx | 44 ++++++++++++ packages/ui/src/components/index.ts | 1 + packages/ui/src/demo.tsx | 25 +++++++ packages/ui/src/styles/index.css | 1 + 5 files changed, 192 insertions(+) create mode 100644 packages/ui/src/components/checkbox.css create mode 100644 packages/ui/src/components/checkbox.tsx (limited to 'packages/ui') diff --git a/packages/ui/src/components/checkbox.css b/packages/ui/src/components/checkbox.css new file mode 100644 index 000000000..6e1e5ddd5 --- /dev/null +++ b/packages/ui/src/components/checkbox.css @@ -0,0 +1,121 @@ +[data-component="checkbox"] { + display: flex; + align-items: center; + gap: 12px; + cursor: default; + + [data-slot="checkbox-input"] { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + [data-slot="checkbox-control"] { + display: flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + padding: 2px; + aspect-ratio: 1; + flex-shrink: 0; + border-radius: 4px; + border: 1px solid var(--border-weak-base); + /* background-color: var(--surface-weak); */ + } + + [data-slot="checkbox-indicator"] { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + color: var(--icon-base); + opacity: 0; + } + + /* [data-slot="checkbox-content"] { */ + /* } */ + + [data-slot="checkbox-label"] { + user-select: none; + color: var(--text-base); + + /* text-12-regular */ + font-family: var(--font-family-sans); + font-size: var(--font-size-small); + font-style: normal; + font-weight: var(--font-weight-regular); + line-height: var(--line-height-large); /* 166.667% */ + letter-spacing: var(--letter-spacing-normal); + } + + [data-slot="checkbox-description"] { + color: var(--text-base); + font-family: var(--font-family-sans); + font-size: 12px; + font-weight: var(--font-weight-regular); + line-height: var(--line-height-normal); + letter-spacing: var(--letter-spacing-normal); + } + + [data-slot="checkbox-error"] { + color: var(--text-error); + font-family: var(--font-family-sans); + font-size: 12px; + font-weight: var(--font-weight-regular); + line-height: var(--line-height-normal); + letter-spacing: var(--letter-spacing-normal); + } + + &:hover:not([data-disabled], [data-readonly]) [data-slot="checkbox-control"] { + border-color: var(--border-hover); + background-color: var(--surface-hover); + } + + &:focus-within:not([data-readonly]) [data-slot="checkbox-control"] { + border-color: var(--border-focus); + box-shadow: 0 0 0 2px var(--surface-focus); + } + + &[data-checked] [data-slot="checkbox-control"], + &[data-indeterminate] [data-slot="checkbox-control"] { + border-color: var(--border-base); + background-color: var(--surface-weak); + } + + &[data-checked]:hover:not([data-disabled], [data-readonly]) [data-slot="checkbox-control"], + &[data-indeterminate]:hover:not([data-disabled]) [data-slot="checkbox-control"] { + border-color: var(--border-hover); + background-color: var(--surface-hover); + } + + &[data-checked] [data-slot="checkbox-indicator"], + &[data-indeterminate] [data-slot="checkbox-indicator"] { + opacity: 1; + } + + &[data-disabled] { + cursor: not-allowed; + } + + &[data-disabled] [data-slot="checkbox-control"] { + border-color: var(--border-disabled); + background-color: var(--surface-disabled); + } + + &[data-invalid] [data-slot="checkbox-control"] { + border-color: var(--border-error); + } + + &[data-readonly] { + cursor: default; + pointer-events: none; + } +} diff --git a/packages/ui/src/components/checkbox.tsx b/packages/ui/src/components/checkbox.tsx new file mode 100644 index 000000000..2009a430b --- /dev/null +++ b/packages/ui/src/components/checkbox.tsx @@ -0,0 +1,44 @@ +import { Checkbox as Kobalte } from "@kobalte/core/checkbox" +import { children, Show, splitProps } from "solid-js" +import type { ComponentProps, JSX, ParentProps } from "solid-js" + +export interface CheckboxProps extends ParentProps> { + hideLabel?: boolean + description?: string + icon?: JSX.Element +} + +export function Checkbox(props: CheckboxProps) { + const [local, others] = splitProps(props, ["children", "class", "label", "hideLabel", "description", "icon"]) + const resolved = children(() => local.children) + return ( + + + + + {local.icon || ( + + + + )} + + +
+ + + {resolved()} + + + + {local.description} + + +
+
+ ) +} diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 31672001b..0024c9e76 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -1,5 +1,6 @@ export * from "./accordion" export * from "./button" +export * from "./checkbox" export * from "./collapsible" export * from "./dialog" export * from "./icon" diff --git a/packages/ui/src/demo.tsx b/packages/ui/src/demo.tsx index 791281815..5893ca751 100644 --- a/packages/ui/src/demo.tsx +++ b/packages/ui/src/demo.tsx @@ -3,6 +3,7 @@ import { createSignal } from "solid-js" import { Accordion, Button, + Checkbox, Select, Tabs, Tooltip, @@ -21,6 +22,8 @@ const Demo: Component = () => { const [dialogOpen, setDialogOpen] = createSignal(false) const [selectDialogOpen, setSelectDialogOpen] = createSignal(false) const [inputValue, setInputValue] = createSignal("") + const [checked, setChecked] = createSignal(false) + const [termsAccepted, setTermsAccepted] = createSignal(false) const Content = (props: { dark?: boolean }) => (
@@ -143,6 +146,28 @@ const Demo: Component = () => { +

Checkbox

+
+ + + + + + + + +

Icons

diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css index 7d426a83e..7ae6b73e4 100644 --- a/packages/ui/src/styles/index.css +++ b/packages/ui/src/styles/index.css @@ -7,6 +7,7 @@ @import "../components/accordion.css" layer(components); @import "../components/button.css" layer(components); +@import "../components/checkbox.css" layer(components); @import "../components/collapsible.css" layer(components); @import "../components/dialog.css" layer(components); @import "../components/icon.css" layer(components); -- cgit v1.2.3