This repository has been archived by the owner on Jul 31, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FLOW-970 f-color-picker component (#203)
* FLOW-970 f-color-picker component created * FLOW-970 playground controls added * FLOW-970 playground controls added * FLOW-970 color picker integrated with form builder * FLOW-970 unit tests added * FLOW-970 changelog updated
- Loading branch information
1 parent
ecda224
commit c67565c
Showing
19 changed files
with
551 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
packages/flow-core/src/components/f-color-picker/f-color-picker-global.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@import "./../../mixins/scss/mixins"; | ||
|
||
f-color-picker { | ||
@include base(); | ||
width: fit-content; | ||
height: fit-content; | ||
max-width: 100%; | ||
max-height: 100%; | ||
} |
35 changes: 35 additions & 0 deletions
35
packages/flow-core/src/components/f-color-picker/f-color-picker.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
@use "sass:map"; | ||
$states: ( | ||
"primary": ( | ||
"border": 1px solid var(--color-primary-default) | ||
), | ||
"default": ( | ||
"border": none | ||
), | ||
"success": ( | ||
"border": 1px solid var(--color-success-default) | ||
), | ||
"warning": ( | ||
"border": 1px solid var(--color-warning-default) | ||
), | ||
"danger": ( | ||
"border": 1px solid var(--color-danger-default) | ||
) | ||
); | ||
|
||
:host { | ||
#f-color-picker-input { | ||
cursor: pointer; | ||
&.focused { | ||
border: 1px solid var(--color-primary-default); | ||
} | ||
&[read-only] { | ||
cursor: default; | ||
} | ||
@each $state, $color in $states { | ||
&[border-state="#{$state}"]:not(.focused) { | ||
border: map.get($color, "border"); | ||
} | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
packages/flow-core/src/components/f-color-picker/f-color-picker.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { html, fixture, expect } from "@open-wc/testing"; | ||
|
||
// import flow-core elements | ||
import "@cldcvr/flow-core"; | ||
|
||
import { FColorPicker, FInput } from "@cldcvr/flow-core"; | ||
|
||
describe("f-color-picker", () => { | ||
// check if component is defined | ||
it("is defined", () => { | ||
const el = document.createElement("f-color-picker"); | ||
expect(el).instanceOf(FColorPicker); | ||
}); | ||
it("should render with default attributes", async () => { | ||
const el = await fixture(html`<f-color-picker></f-color-picker>`); | ||
|
||
expect(el.getAttribute("variant")).to.equal("curved"); | ||
expect(el.getAttribute("size")).to.equal("medium"); | ||
expect(el.getAttribute("state")).to.equal("default"); | ||
}); | ||
|
||
it("should display color value in input box", async () => { | ||
const el = await fixture(html`<f-color-picker value="#CCCCCC"></f-color-picker>`); | ||
|
||
const input = el.shadowRoot?.querySelector<FInput>("#hex-input"); | ||
expect(input.value).to.equal("#CCCCCC"); | ||
}); | ||
}); |
197 changes: 197 additions & 0 deletions
197
packages/flow-core/src/components/f-color-picker/f-color-picker.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
import { html, PropertyValueMap, unsafeCSS } from "lit"; | ||
import { property, query, state } from "lit/decorators.js"; | ||
import globalStyle from "./f-color-picker-global.scss?inline"; | ||
import eleStyle from "./f-color-picker.scss?inline"; | ||
import { FRoot } from "../../mixins/components/f-root/f-root"; | ||
import { flowElement } from "./../../utils"; | ||
import { injectCss } from "@cldcvr/flow-core-config"; | ||
|
||
import "vanilla-colorful"; | ||
import { FPopover } from "../f-popover/f-popover"; | ||
import { FDiv } from "../f-div/f-div"; | ||
import { FInput } from "../f-input/f-input"; | ||
import { classMap } from "lit-html/directives/class-map.js"; | ||
|
||
injectCss("f-color-picker", globalStyle); | ||
|
||
export type FColorPickerState = "primary" | "default" | "success" | "warning" | "danger"; | ||
export type FColorPickerInputEvent = { | ||
value?: string; | ||
}; | ||
|
||
@flowElement("f-color-picker") | ||
export class FColorPicker extends FRoot { | ||
/** | ||
* css loaded from scss file | ||
*/ | ||
static styles = [ | ||
unsafeCSS(eleStyle), | ||
unsafeCSS(globalStyle), | ||
...FPopover.styles, | ||
...FDiv.styles, | ||
...FInput.styles | ||
]; | ||
|
||
/** | ||
* @attribute Variants are various visual representations of an input field. | ||
*/ | ||
@property({ reflect: true, type: String }) | ||
variant?: "curved" | "round" | "block" = "curved"; | ||
|
||
/** | ||
* @attribute States are used to communicate purpose and connotations. | ||
*/ | ||
@property({ reflect: true, type: String }) | ||
state?: FColorPickerState = "default"; | ||
|
||
/** | ||
* @attribute f-input can have 2 sizes. By default size is inherited by the parent f-field. | ||
*/ | ||
@property({ reflect: true, type: String }) | ||
size?: "medium" | "small" = "medium"; | ||
|
||
/** | ||
* @attribute Defines the value of an f-input. Validation rules are applied on the value depending on the type property of the f-text-input. | ||
*/ | ||
@property({ reflect: true, type: String }) | ||
value?: string; | ||
|
||
/** | ||
* @attribute Shows disabled state of input element | ||
*/ | ||
@property({ reflect: true, type: Boolean }) | ||
disabled?: boolean = false; | ||
|
||
/** | ||
* @attribute When true the user can not select the input element. | ||
*/ | ||
@property({ reflect: true, type: Boolean, attribute: "read-only" }) | ||
readOnly?: boolean = false; | ||
|
||
@query("#f-color-picker-popover") | ||
popoverElement!: FPopover; | ||
|
||
@state() | ||
isOpen = false; | ||
|
||
@query("#f-color-picker-input") | ||
inputElement!: FDiv; | ||
|
||
defaultHexColor: string = "#000000"; | ||
|
||
handleColorChange(event: CustomEvent<{ value: string }>) { | ||
this.value = event.detail.value; | ||
this.dispatchInputEvent(this.value); | ||
} | ||
handleFocus(_event: FocusEvent) { | ||
if (!this.readOnly) { | ||
this.isOpen = true; | ||
} | ||
} | ||
handleOverlayClick() { | ||
this.isOpen = false; | ||
} | ||
|
||
handleHexInput(event: CustomEvent) { | ||
this.value = event.detail.value; | ||
this.dispatchInputEvent(this.value); | ||
} | ||
handleKeydown(event: KeyboardEvent) { | ||
if (event.key === "Enter") { | ||
this.isOpen = false; | ||
} | ||
} | ||
|
||
dispatchInputEvent(value?: string) { | ||
const event = new CustomEvent<FColorPickerInputEvent>("input", { | ||
detail: { | ||
value | ||
}, | ||
bubbles: true, | ||
composed: true | ||
}); | ||
|
||
this.dispatchEvent(event); | ||
} | ||
|
||
get isValueEmpty() { | ||
return ( | ||
this.value === undefined || this.value === null || (this.value && this.value.trim() === "") | ||
); | ||
} | ||
|
||
sizeMap = { | ||
small: "28px", | ||
medium: "36px" | ||
}; | ||
get colorPickerTypeTemplate() { | ||
return html`<hex-color-picker | ||
style="width:100%;" | ||
.color=${this.value ?? this.defaultHexColor} | ||
@color-changed=${this.handleColorChange} | ||
></hex-color-picker> | ||
<f-div gap="small"> | ||
<f-input | ||
id="hex-input" | ||
prefix="HEX" | ||
@input=${this.handleHexInput} | ||
size="small" | ||
.clear=${false} | ||
.value=${this.value ?? this.defaultHexColor} | ||
> | ||
</f-input> | ||
</f-div>`; | ||
} | ||
|
||
render() { | ||
const classes = { focused: this.isOpen, "no-color": this.isValueEmpty }; | ||
// render empty string, since there no need of any child element | ||
return html`<f-div direction="column" gap="x-small" width="hug-content"> | ||
<f-form-field> | ||
<f-div | ||
.width=${this.sizeMap[this.size ?? "medium"]} | ||
.height=${this.sizeMap[this.size ?? "medium"]} | ||
state="custom,${this.value ?? this.defaultHexColor}" | ||
border-state="${this.state}" | ||
.variant=${this.variant} | ||
.disabled=${this.disabled} | ||
?read-only=${this.readOnly} | ||
class=${classMap(classes)} | ||
@click=${this.handleFocus} | ||
id="f-color-picker-input" | ||
data-qa-element=${this.getAttribute("data-qa-element-id")} | ||
></f-div> | ||
<f-div slot="label"><slot name="label"></slot></f-div> | ||
<f-div slot="description"><slot name="description"></slot></f-div> | ||
<f-div slot="icon-tooltip"><slot name="icon-tooltip"></slot></f-div> | ||
<f-div slot="help"><slot name="help"></slot></f-div> | ||
</f-form-field> | ||
<f-popover | ||
id="f-color-picker-popover" | ||
@overlay-click=${this.handleOverlayClick} | ||
@keydown=${this.handleKeydown} | ||
.overlay=${false} | ||
.open=${this.isOpen} | ||
size="small" | ||
> | ||
<f-div direction="column" state="secondary" padding="large" gap="medium" variant="curved"> | ||
${this.colorPickerTypeTemplate} | ||
</f-div> | ||
</f-popover> | ||
</f-div>`; | ||
} | ||
protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void { | ||
super.updated(changedProperties); | ||
this.popoverElement.target = this.inputElement; | ||
} | ||
} | ||
|
||
/** | ||
* Required for typescript | ||
*/ | ||
declare global { | ||
interface HTMLElementTagNameMap { | ||
"f-color-picker": FColorPicker; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.