Skip to content

Commit

Permalink
Checkbox component
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed Jan 21, 2024
1 parent 7445f0f commit ade1671
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 70 deletions.
51 changes: 51 additions & 0 deletions src/components/CheckBox.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.CheckBox {
--cb-color-border: #888;
--cb-color-checked: #008;
--cb-color-unchecked: #fff;
--cb-size: 1.2em;
--cb-check-size: 1em;
--cb-gap: 0.4em;

display: flex;
flex-direction: row;
align-items: center;

input {
appearance: none;
-webkit-appearance: none;
margin: 0;
}

> span:first-of-type {
display: flex;
align-items: center;
justify-content: center;
background-color: var(--cb-color-unchecked);
border: 0.2em solid var(--cb-color-border);
border-radius: 0.2em;
box-sizing: border-box;
width: var(--cb-size);
height: var(--cb-size);

&::before {
content: '';
display: block;
/* https://bennettfeely.com/clippy/ */
clip-path: polygon(11% 34%, 46% 68%, 88% 1%, 100% 8%, 50% 91%, 0 48%);
width: var(--cb-check-size);
height: var(--cb-check-size);
transform: scale(0);
}
}
> span:last-of-type {
margin-left: var(--cb-gap);
}

input:checked + span {
background-color: var(--cb-color-checked);
}
input:checked + span::before {
transform: scale(1);
background-color: var(--cb-color-unchecked);
}
}
30 changes: 30 additions & 0 deletions src/components/CheckBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { JSX } from 'solid-js'
import styles from './CheckBox.module.scss'

export interface CheckBoxProps {
class?: string
isChecked: boolean
children?: JSX.Element
onChange: (checked: boolean) => void
}

export function CheckBox({
class: cl,
isChecked,
children,
onChange,
}: CheckBoxProps) {
return (
<label class={cl == null ? styles.CheckBox : `${styles.CheckBox} ${cl}`}>
<input
type="checkbox"
checked={isChecked}
onChange={(event) => {
onChange(event.target.checked)
}}
/>
<span></span>
{children && <span>{children}</span>}
</label>
)
}
13 changes: 7 additions & 6 deletions src/components/CheckList.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
overflow-y: scroll;
}

label {
display: flex;
align-items: center;
gap: var(--check-list-item-gap);
.CheckBox {
padding: var(--check-list-item-pad);
span:last-of-type {
display: flex;
gap: 8px;
}
}

.CheckListShowCompleted {
.WeekLabel {
display: block;
padding: var(--check-list-item-pad);
}
}
62 changes: 30 additions & 32 deletions src/components/CheckList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import styles from './CheckList.module.scss'
import planText from '../data/five-day.txt?raw'
import { CheckListItem, isRangeComplete, versionLink } from '../model'
import { loadCheckListState, saveCheckListState } from '../data'
import { CheckBox } from './CheckBox'

export function CheckList() {
const checkList: CheckListItem[] = planText
Expand All @@ -25,57 +26,54 @@ export function CheckList() {

return (
<div class={styles.CheckList}>
<label class={styles.CheckListShowCompleted}>
<input
type="checkbox"
checked={showCompleted()}
onChange={() =>
setCheckListState((s) => ({
...s,
showCompleted: !s.showCompleted,
}))
}
/>
<CheckBox
class={styles.CheckBox}
isChecked={showCompleted()}
onChange={() =>
setCheckListState((s) => ({
...s,
showCompleted: !s.showCompleted,
}))
}>
Show Completed
</label>
</CheckBox>

<ul>
<For each={checkList}>
{({ id, label }) => (
<>
{id % 5 === 0 ? (
showCompleted() || !isWeekComplete(id) ? (
<li>
<label>Week {id / 5 + 1}</label>
<label class={styles.WeekLabel}>Week {id / 5 + 1}</label>
</li>
) : null
) : null}
{showCompleted() || !checkListState().completed.has(id) ? (
<li>
<label>
<input
type="checkbox"
checked={checkListState().completed.has(id)}
onChange={(event) => {
setCheckListState(({ showCompleted, completed }) => {
if (event.target.checked) {
completed.add(id)
} else {
completed.delete(id)
}
<CheckBox
class={styles.CheckBox}
isChecked={checkListState().completed.has(id)}
onChange={(isChecked) => {
setCheckListState(({ showCompleted, completed }) => {
if (isChecked) {
completed.add(id)
} else {
completed.delete(id)
}

return {
showCompleted,
completed: new Set<number>(completed),
}
})
}}
/>
return {
showCompleted,
completed: new Set<number>(completed),
}
})
}}>
<span>{id + 1}</span>
{/* <span>{label}</span> */}
{label.split('; ').map((l) => (
<a href={versionLink(l)}>{l}</a>
))}
</label>
</CheckBox>
</li>
) : null}
</>
Expand Down
34 changes: 2 additions & 32 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,9 @@ body {
body,
div,
ul,
li {
li,
label {
margin: 0;
padding: 0;
box-sizing: border-box;
}

input[type='checkbox'] {
--cb-color-border: #888;
--cb-color-checked: #008;
--cb-color-unchecked: #fff;
--cb-padding: 0.2rem;
--cb-size: 1rem;

background-color: var(--cb-color-unchecked);
/* appearance: none;
-webkit-appearance: none; */
display: flex;
padding: var(--cb-padding);
border: 0.2rem solid var(--cb-color-border);
border-radius: 0.5rem;
&::before {
content: '';
/* https://bennettfeely.com/clippy/ */
clip-path: polygon(11% 34%, 46% 68%, 88% 1%, 100% 8%, 50% 91%, 0 48%);
width: var(--cb-size);
height: var(--cb-size);
transform: scale(0);
}
&:checked {
background-color: var(--cb-color-checked);
}
&:checked::before {
transform: scale(1);
background-color: var(--cb-color-unchecked);
}
}

0 comments on commit ade1671

Please sign in to comment.