Skip to content

Commit

Permalink
feat: new ColorArea component (#508)
Browse files Browse the repository at this point in the history
* feat: new ColorSlider component
* feat: new ColorChannelField component
* feat: new ColorSwatch component
  • Loading branch information
HBS999 authored Nov 2, 2024
1 parent 7e845c8 commit 3674cfe
Show file tree
Hide file tree
Showing 37 changed files with 5,345 additions and 0 deletions.
35 changes: 35 additions & 0 deletions apps/docs/src/examples/color-area.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.ColorAreaRoot {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
user-select: none;
touch-action: none;
width: 200px;
}

.ColorAreaBackground {
position: relative;
border-radius: 6px;
height: 150px;
width: 150px;
}

.ColorAreaThumb {
display: block;
width: 16px;
height: 16px;
border-radius: 9999px;
border: 2px solid #fff;
box-shadow: 0 0 0 1px #0000006b;
}

.ColorAreaThumb:focus {
outline: none;
}

.ColorAreaLabel {
display: flex;
justify-content: space-between;
width: 100%;
}
123 changes: 123 additions & 0 deletions apps/docs/src/examples/color-area.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { createSignal } from "solid-js";
import { ColorArea } from "../../../../packages/core/src/colors/color-area";
import { parseColor } from "../../../../packages/core/src/colors/utils";
import style from "./color-area.module.css";

export function BasicExample() {
return (
<ColorArea
class={style.ColorAreaRoot}
defaultValue={parseColor("rgb(2, 132, 197)")}
>
<ColorArea.Background class={style.ColorAreaBackground}>
<ColorArea.Thumb class={style.ColorAreaThumb}>
<ColorArea.HiddenInputX />
<ColorArea.HiddenInputY />
</ColorArea.Thumb>
</ColorArea.Background>
</ColorArea>
);
}

export function DefaultValueExample() {
return (
<ColorArea
class={style.ColorAreaRoot}
defaultValue={parseColor("hsb(219, 58%, 93%)")}
>
<ColorArea.Background class={style.ColorAreaBackground}>
<ColorArea.Thumb class={style.ColorAreaThumb}>
<ColorArea.HiddenInputX />
<ColorArea.HiddenInputY />
</ColorArea.Thumb>
</ColorArea.Background>
</ColorArea>
);
}

export function ControlledValueExample() {
const [value, setValue] = createSignal(parseColor("hsl(0, 100%, 50%)"));
return (
<>
<ColorArea
class={style.ColorAreaRoot}
value={value()}
onChange={setValue}
>
<ColorArea.Background class={style.ColorAreaBackground}>
<ColorArea.Thumb class={style.ColorAreaThumb}>
<ColorArea.HiddenInputX />
<ColorArea.HiddenInputY />
</ColorArea.Thumb>
</ColorArea.Background>
</ColorArea>
<p class="not-prose text-sm mt-4">
Current color value: {value().toString("hsl")}
</p>
</>
);
}

export function XAndYChannelExample() {
const [value, setValue] = createSignal(parseColor("rgb(100, 149, 237)"));
const [rChannel, gChannel, bChannel] = value().getColorChannels();
return (
<ColorArea
class={style.ColorAreaRoot}
value={value()}
onChange={setValue}
xChannel={gChannel}
yChannel={bChannel}
>
<ColorArea.Background class={style.ColorAreaBackground}>
<ColorArea.Thumb class={style.ColorAreaThumb}>
<ColorArea.HiddenInputX />
<ColorArea.HiddenInputY />
</ColorArea.Thumb>
</ColorArea.Background>
</ColorArea>
);
}

export function HTMLFormExample() {
let formRef: HTMLFormElement | undefined;

const onSubmit = (e: SubmitEvent) => {
e.preventDefault();
e.stopPropagation();

const formData = new FormData(formRef);

alert(JSON.stringify(Object.fromEntries(formData), null, 2));
};

return (
<form
ref={formRef}
onSubmit={onSubmit}
class="flex flex-col items-center space-y-6"
>
<ColorArea
class={style.ColorAreaRoot}
defaultValue={parseColor("rgb(100, 149, 237)")}
xName="red"
yName="green"
>
<ColorArea.Background class={style.ColorAreaBackground}>
<ColorArea.Thumb class={style.ColorAreaThumb}>
<ColorArea.HiddenInputX />
<ColorArea.HiddenInputY />
</ColorArea.Thumb>
</ColorArea.Background>
</ColorArea>
<div class="flex space-x-2">
<button type="reset" class="kb-button">
Reset
</button>
<button type="submit" class="kb-button-primary">
Submit
</button>
</div>
</form>
);
}
184 changes: 184 additions & 0 deletions apps/docs/src/examples/color-channel-field.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
.color-channel-field {
display: flex;
flex-direction: column;
gap: 4px;
}

.color-channel-field__label {
color: hsl(240 6% 10%);
font-size: 14px;
font-weight: 500;
user-select: none;
}

.color-channel-field__input {
display: inline-flex;
width: 200px;
border-radius: 6px;
padding: 6px 12px;
font-size: 16px;
outline: none;
background-color: white;
border: 1px solid hsl(240 6% 90%);
color: hsl(240 4% 16%);
transition:
border-color 250ms,
color 250ms;
}

.color-channel-field__group {
position: relative;
border-radius: 6px;
}

.color-channel-field__increment {
top: 0.25rem;
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
}

.color-channel-field__decrement {
bottom: 0.25rem;
border-bottom-left-radius: 0.25rem;
border-bottom-right-radius: 0.25rem;
}

.color-channel-field__increment,
.color-channel-field__decrement {
right: 0.25rem;
position: absolute;
height: 1rem;
width: 1rem;
background: rgba(0, 0, 0, 0.1);
cursor: default;
}

.color-channel-field__increment:hover,
.color-channel-field__decrement:hover {
background: rgba(0, 0, 0, 0.2);
}

[data-kb-theme="dark"] .color-channel-field__increment,
[data-kb-theme="dark"] .color-channel-field__decrement {
background: rgba(0, 0, 0, 0.5);
}

[data-kb-theme="dark"] .color-channel-field__increment:hover,
[data-kb-theme="dark"] .color-channel-field__decrement:hover {
background: rgba(0, 0, 0, 0.25);
}

.color-channel-field__decrement svg,
.color-channel-field__increment svg {
height: 150%;
left: -25%;
position: relative;
top: -25%;
}

.color-channel-field__custom-trigger-decrement,
.color-channel-field__custom-trigger-increment {
appearance: none;
display: inline-flex;
justify-content: center;
align-items: center;
height: 40px;
width: auto;
outline: none;
border-radius: 6px;
padding: 0 16px;
background-color: hsl(200 98% 39%);
color: white;
font-size: 16px;
line-height: 0;
transition: 250ms background-color;
border: 1px solid hsl(240 6% 90%);
box-sizing: content-box;
}

.color-channel-field__custom-trigger-decrement:hover,
.color-channel-field__custom-trigger-increment:hover {
background-color: hsl(201 96% 32%);
}

.color-channel-field__custom-trigger-decrement {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right-style: none;
}

.color-channel-field__custom-trigger-increment {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left-style: none;
}

.color-channel-field__custom-trigger-decrement + input {
border-radius: 0;
}

[data-kb-theme="dark"] .color-channel-field__custom-trigger-decrement,
[data-kb-theme="dark"] .color-channel-field__custom-trigger-increment {
border-color: hsl(240 5% 34%);
}

.color-channel-field__input:hover {
border-color: hsl(240 5% 65%);
}

.color-channel-field__input:focus-visible {
outline: none;
}

.color-channel-field__group:focus-within {
outline: 2px solid hsl(200 98% 39%);
outline-offset: 2px;
}

.color-channel-field__input[data-invalid] {
border-color: hsl(0 72% 51%);
color: hsl(0 72% 51%);
}

.color-channel-field__input::placeholder {
color: hsl(240 4% 46%);
}

.color-channel-field__description {
color: hsl(240 5% 26%);
font-size: 12px;
user-select: none;
}

.color-channel-field__error-message {
color: hsl(0 72% 51%);
font-size: 12px;
user-select: none;
}

[data-kb-theme="dark"] .color-channel-field__input {
background-color: hsl(240 4% 16%);
border: 1px solid hsl(240 5% 34%);
color: hsl(0 100% 100% / 0.9);
}

[data-kb-theme="dark"] .color-channel-field__input:hover {
border-color: hsl(240 4% 46%);
}

[data-kb-theme="dark"] .color-channel-field__input[data-invalid] {
border-color: hsl(0 72% 51%);
color: hsl(0 72% 51%);
}

[data-kb-theme="dark"] .color-channel-field__input::placeholder {
color: hsl(0 100% 100% / 0.5);
}

[data-kb-theme="dark"] .color-channel-field__label {
color: hsl(240 5% 84%);
}

[data-kb-theme="dark"] .color-channel-field__description {
color: hsl(240 5% 65%);
}
Loading

0 comments on commit 3674cfe

Please sign in to comment.