Skip to content

Commit

Permalink
feat: KForm supports KColorPicker component (#422)
Browse files Browse the repository at this point in the history
* feat: KForm supports KColorPicker component

* chore: updated unit test snap

* chore: updated KForm unit test
  • Loading branch information
baiwusanyu-c committed Mar 22, 2024
1 parent dab5f80 commit 8d78218
Show file tree
Hide file tree
Showing 24 changed files with 335 additions and 111 deletions.

Large diffs are not rendered by default.

15 changes: 6 additions & 9 deletions components/ColorPicker/__test__/color-picker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,15 @@ describe('Test: KColorPicker', () => {

expect(host!.innerHTML.includes('k-color-picker-block-w--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-content--sm')).toBeTruthy();

expect(host!.innerHTML.includes('k-color-picker-block-w--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-content--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-w--md')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--md')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-content--md')).toBeTruthy();

expect(host!.innerHTML.includes('k-color-picker-block-w--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-content--sm')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-w--lg')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block--lg')).toBeTruthy();
expect(host!.innerHTML.includes('k-color-picker-block-content--lg')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});

Expand Down
3 changes: 2 additions & 1 deletion components/ColorPicker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@
"@ikun-ui/popover": "workspace:*",
"@ikun-ui/input": "workspace:*",
"@ikun-ui/input-number": "workspace:*",
"@ikun-ui/dropdown": "workspace:*",
"@ikun-ui/checkbox": "workspace:*",
"@ikun-ui/checkbox-group": "workspace:*",
"@ikun-ui/form": "workspace:*",
"@ikun-ui/dropdown": "workspace:*",
"@ikun-ui/utils": "workspace:*",
"esm-env": "^1.0.0",
"tinycolor2": "^1.6.0",
Expand Down
7 changes: 3 additions & 4 deletions components/ColorPicker/src/block.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { toRgbString } from './utils';
export let focus: KColorPickerBlockProps['focus'] = false;
export let error: KColorPickerBlockProps['error'] = false;
export let trigger: KColorPickerBlockProps['trigger'] = false;
export let disabled: KColorPickerBlockProps['disabled'] = false;
export let isClear: KColorPickerBlockProps['isClear'] = false;
Expand All @@ -26,17 +27,15 @@
$: wrapperCls = clsx(`${prefixCls}-w`, {
[`${prefixCls}-w--disabled`]: disabled,
[`${prefixCls}-w--${size}`]: trigger,
[`${prefixCls}-w--focus`]: focus
[`${prefixCls}-w--focus`]: focus && !error,
[`${prefixCls}-w--error`]: error
});
$: cnamesSize = clsx(
{
[`${prefixCls}`]: !isClear,
[`${prefixCls}-clear`]: isClear,
[`${prefixCls}--${size}`]: trigger
},
{
[`${prefixCls}--${size}`]: trigger
},
cls
);
</script>
Expand Down
27 changes: 20 additions & 7 deletions components/ColorPicker/src/format.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,15 @@
}
if (formatValue === 'hex') {
const hsv = toHsv(`#${valueHex}`);
hsv.a = alpha;
dispatch('change', {
value: hsv,
format: formatValue
});
type === 'hex' && (valueHex = e.detail);
if (valueHex.length === 6) {
const hsv = toHsv(`#${valueHex}`);
hsv.a = alpha;
dispatch('change', {
value: hsv,
format: formatValue
});
}
}
}
Expand Down Expand Up @@ -143,12 +146,14 @@
max={hRMaxValue}
on:input={(e) => handleInput(e, 'hr')}
cls={inputNumCls}
ignoreForm
size="sm"
></KInputNumber>
<KInputNumber
value={sGValue}
min={0}
step={1}
ignoreForm
max={sGMaxValue}
stepStrictly
on:input={(e) => handleInput(e, 'sg')}
Expand All @@ -165,10 +170,17 @@
on:input={(e) => handleInput(e, 'vb')}
cls={inputNumCls}
size="sm"
ignoreForm
></KInputNumber>
{/if}
{#if formatValue === 'hex'}
<KInput value={valueHex} cls={inputCls} on:input={(e) => handleInput(e, 'hex')} size="sm">
<KInput
value={valueHex}
ignoreForm
cls={inputCls}
on:input={(e) => handleInput(e, 'hex')}
size="sm"
>
<span slot="prefix">#</span>
</KInput>
{/if}
Expand All @@ -179,6 +191,7 @@
max={100}
step={1}
stepStrictly
ignoreForm
on:input={(e) => handleInput(e, 'a')}
cls={inputNumCls}
size="sm"
Expand Down
111 changes: 101 additions & 10 deletions components/ColorPicker/src/index.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { getPrefixCls } from '@ikun-ui/utils';
import { formKey, getPrefixCls } from '@ikun-ui/utils';
import type { IKunSize } from '@ikun-ui/utils';
import { clsx } from 'clsx';
import type { HsvaColor, KColorPickerProps } from './types';
import { KPopover } from '@ikun-ui/popover';
Expand All @@ -9,7 +10,9 @@
import KColorPickerBlock from './block.svelte';
import KColorPickerFormat from './format.svelte';
import KColorPickerPreset from './preset.svelte';
import { createEventDispatcher } from 'svelte';
import { createEventDispatcher, getContext } from 'svelte';
import type { IKunFormInstance } from '@ikun-ui/form';
import { formItemKey } from '@ikun-ui/utils';
export let allowClear: KColorPickerProps['allowClear'] = false;
export let title: KColorPickerProps['title'] = '';
export let value: KColorPickerProps['value'] = '';
Expand Down Expand Up @@ -44,7 +47,12 @@
blockColor = res;
formatterColor = res;
isClear = false;
dispatch('changeComplete', formatColor(formatValue, blockColor));
const resolveColor = formatColor(formatValue, blockColor);
dispatch('changeComplete', resolveColor);
if (formInstance) {
formInstance.updateField(field!, resolveColor, !formInstance.__manual_validate);
value = resolveColor;
}
}
let isDragging = false;
Expand All @@ -55,7 +63,13 @@
blockColor = res;
formatterColor = res;
isClear = false;
dispatch('change', formatColor(formatValue, blockColor));
const resolveColor = formatColor(formatValue, blockColor);
dispatch('change', resolveColor);
if (formInstance) {
formInstance.updateField(field!, resolveColor, !formInstance.__manual_validate);
value = resolveColor;
}
}
function handleHValueInput(e: CustomEvent) {
Expand All @@ -71,14 +85,23 @@
const resolveColor = formatColor(formatValue, blockColor);
dispatch('change', resolveColor);
dispatch('changeComplete', resolveColor);
if (formInstance) {
formInstance.updateField(field!, resolveColor, !formInstance.__manual_validate);
value = resolveColor;
}
}
function handleAValueInput(e: CustomEvent) {
aColor.a = e.detail.a;
blockColor = e.detail;
formatterColor = e.detail;
isClear = false;
dispatch('changeComplete', formatColor(formatValue, blockColor));
const resolveColor = formatColor(formatValue, blockColor);
dispatch('changeComplete', resolveColor);
if (formInstance) {
formInstance.updateField(field!, resolveColor, !formInstance.__manual_validate);
value = resolveColor;
}
}
let focus = false;
Expand All @@ -95,24 +118,35 @@
isClear = true;
dispatch('clear');
dispatch('change', null);
if (formInstance) {
formInstance.updateField(field!, null, !formInstance.__manual_validate);
}
}
let paletteRef: any = null;
$: formatValue = format;
function handleFormatInput(e: CustomEvent) {
const hsv = toHsv(e.detail.value) as HsvaColor;
formatValue = e.detail.format;
blockColor = hsv;
paletteColor = hsv;
aColor = hsv;
hColor = hsv;
defaultPaletteColor = { ...hColor, s: 1, v: 1, a: 1 };
formatterColor = hsv;
isClear = false;
if (paletteRef) {
paletteRef.setPickerPos(paletteColor);
}
dispatch('change', formatColor(formatValue, blockColor));
const resolveColor = formatColor(formatValue, blockColor);
console.log(resolveColor);
dispatch('change', resolveColor);
if (formInstance) {
formInstance.updateField(field!, resolveColor, !formInstance.__manual_validate);
value = resolveColor;
}
}
function handleFormatChange(e: CustomEvent) {
Expand All @@ -135,6 +169,10 @@
const resolveColor = formatColor(formatValue, blockColor);
dispatch('change', resolveColor);
dispatch('changeComplete', resolveColor);
if (formInstance) {
formInstance.updateField(field!, resolveColor, !formInstance.__manual_validate);
value = resolveColor;
}
}
let hsvValue: HsvaColor = { h: 0, s: 0, v: 0, a: 1 };
Expand All @@ -156,6 +194,51 @@
$: formatterColor = hsvValue;
$: presetColor = hsvValue;
/*********************** KForm logic start ************************/
let disabledFrom = false;
$: disabledInner = disabledFrom || disabled;
let sizeFrom: IKunSize | string = '';
$: sizeInner = (sizeFrom || size) as IKunSize;
let isErrorForm = false;
$: isErrorInner = isErrorForm;
const formContext = getContext(formItemKey) as string;
const formInstance = getContext(formKey) as IKunFormInstance;
let field: string | undefined = '';
// Initialize the KSwitch value based
// on the form value in the KFormItem context
async function formUpdateField(init = false) {
field = formContext.split('&').pop();
value = formInstance.getValueByPath(
field,
init ? formInstance.__default_value : formInstance.__value
);
hsvValue = toHsv(value);
if (!init) {
hsvDefaultValue = toHsv(defaultValue);
isClear = false;
}
}
function formPropsChangeCb(props: Record<any, any>) {
disabledFrom = props.disabled;
sizeFrom = props.size;
}
function fromFieldError(error: boolean) {
isErrorForm = error;
}
// Register event, KForm can set KColorPicker value
if (formContext && formInstance) {
formUpdateField(true);
formPropsChangeCb(formInstance.__dynamicProps);
formInstance.__itemCompMap[field] = {
update: formUpdateField,
type: 'color-picker'
};
formInstance.__errorCompEvtMap[field] = fromFieldError;
formInstance.__propHandleEvtMap.push(formPropsChangeCb);
}
/*********************** KForm logic end ************************/
const prefixCls = getPrefixCls('color-picker');
const hsbCls = getPrefixCls('color-picker--hsb');
const hsCls = getPrefixCls('color-picker--hs');
Expand All @@ -164,7 +247,7 @@
const lineCls = getPrefixCls('color-picker-line');
$: triggerCls = clsx(
{
[`${prefixCls}-trigger--disabled`]: disabled
[`${prefixCls}-trigger--disabled`]: disabledInner
},
triggerClass
);
Expand Down Expand Up @@ -200,7 +283,7 @@
<KPopover
bind:this={popoverRef}
{placement}
{disabled}
disabled={disabledInner}
{trigger}
on:change={onDisplayChange}
arrow={false}
Expand All @@ -209,7 +292,15 @@
{#if $$slots.default}
<slot {blockColor} />
{:else}
<KColorPickerBlock {disabled} value={blockColor} trigger {size} {focus} {isClear}>
<KColorPickerBlock
disabled={disabledInner}
value={blockColor}
trigger
size={sizeInner}
{focus}
error={isErrorInner}
{isClear}
>
<div slot="text" class={txtCls} style:display={showText ? 'initial' : 'none'}>
{#if showText}
<slot name="text">
Expand Down
3 changes: 3 additions & 0 deletions components/ColorPicker/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export type KColorPickerSliderProps = {
export type KColorPickerBlockProps = {
disabled: boolean;
focus: boolean;
error: boolean;
isClear: boolean;
trigger: boolean;
/**
Expand Down Expand Up @@ -157,6 +158,8 @@ export type KColorPickerFormatProps = {
};

// TODO: form support
// TODO: form 文档更新
// TODO: form 单测更新

export interface RgbaColor {
r: number;
Expand Down
Loading

0 comments on commit 8d78218

Please sign in to comment.