@dvrd/dvr-controls 1.0.37 → 1.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -55,6 +55,7 @@ import DvrdSelectController from './src/js/select/dvrdSelectController';
55
55
  import DvrdSwitch from './src/js/switch/dvrdSwitch';
56
56
  import DvrdHeaderController from './src/js/header/v2/dvrdHeaderController';
57
57
  import FileUpload from './src/js/fileUpload/fileUpload';
58
+ import DvrdRadioController from './src/js/radio/dvrdRadioController';
58
59
 
59
60
  export {
60
61
  // Components
@@ -102,6 +103,7 @@ export {
102
103
  DvrdSwitch,
103
104
  DvrdHeaderController as DvrdHeader,
104
105
  FileUpload,
106
+ DvrdRadioController as DvrdRadio,
105
107
 
106
108
  // Interfaces / Enums
107
109
  DialogActionShape,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvrd/dvr-controls",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
4
4
  "description": "Custom web controls",
5
5
  "main": "index.ts",
6
6
  "files": [
@@ -16,6 +16,7 @@ import {Button} from "../../../index";
16
16
 
17
17
  interface Props extends ColorPickerProps<any> {
18
18
  onSubmit: (color: Color) => void;
19
+ onSubmitColorResult?: (colorResult: ColorResult | null) => void;
19
20
  onPreChange?: (color: Color) => void;
20
21
  onClose: MouseEventHandler;
21
22
  pickerType: ColorPickerType;
@@ -27,6 +28,7 @@ interface Props extends ColorPickerProps<any> {
27
28
 
28
29
  interface State {
29
30
  color: Color;
31
+ colorResult: ColorResult | null;
30
32
  }
31
33
 
32
34
  export default class ColorPicker extends PureComponent<Props, State> {
@@ -39,14 +41,17 @@ export default class ColorPicker extends PureComponent<Props, State> {
39
41
 
40
42
  state: State = {
41
43
  color: this.props.color || '#000',
44
+ colorResult: null,
42
45
  };
43
46
 
44
47
  onSubmit = () => {
45
- const {onSubmit} = this.props, {color} = this.state;
48
+ const {onSubmit, onSubmitColorResult} = this.props, {color, colorResult} = this.state;
46
49
  onSubmit(color);
50
+ onSubmitColorResult?.(colorResult);
47
51
  };
48
52
 
49
53
  onChange = (color: ColorResult) => {
54
+ this.setState({colorResult: color});
50
55
  let newColor: Color;
51
56
  switch (this.props.resultType) {
52
57
  case ColorPickerResultType.HEX:
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Copyright (c) Dave van Rijn Development 2023.
3
+ */
4
+ import './style/dvrdRadio.scss';
5
+
6
+ import classNames from 'classnames';
7
+ import React, {MouseEventHandler, useContext, useMemo} from 'react';
8
+ import {ControlContext} from "../util/controlContext";
9
+ import {editColor} from "../util/colorUtil";
10
+
11
+ interface Props {
12
+ onClick: MouseEventHandler;
13
+ onMouseEnter: MouseEventHandler;
14
+ onMouseLeave: MouseEventHandler;
15
+ checked: boolean;
16
+ hasHover: boolean;
17
+ id: string;
18
+ labelPosition: 'left' | 'right';
19
+ disabled?: boolean;
20
+ label?: string;
21
+ baseColor?: string;
22
+ title?: string;
23
+ className?: string;
24
+ }
25
+
26
+ export default function DvrdRadio(props: Props) {
27
+ const context = useContext(ControlContext);
28
+ const {
29
+ checked, label, labelPosition, hasHover, onClick, title, disabled, onMouseLeave, onMouseEnter, className, id
30
+ } = props;
31
+ const baseColor = useMemo(() => {
32
+ return props.baseColor ?? context.baseColor
33
+ }, [props.baseColor, context.baseColor]);
34
+
35
+ function getBulletContainerStyle() {
36
+ let borderColor: string = baseColor;
37
+ if (disabled) borderColor = 'color-gray-4';
38
+ else if (hasHover) borderColor = editColor(-.2, baseColor);
39
+ return {borderColor};
40
+ }
41
+
42
+ function getBulletStyle() {
43
+ let color: string = baseColor;
44
+ if (disabled) color = 'color-gray-4';
45
+ else if (hasHover) color = editColor(-.2, baseColor);
46
+ return {backgroundColor: color};
47
+ }
48
+
49
+ function renderLabel(position: 'left' | 'right') {
50
+ if (!label?.length || position !== labelPosition) return;
51
+ return <label className='dvrd-radio-button-label'>{label}</label>;
52
+ }
53
+
54
+ function renderBullet() {
55
+ return (
56
+ <div className='dvrd-radio-bullet-container' style={getBulletContainerStyle()}>
57
+ <div className='ripple' style={{backgroundColor: baseColor}}/>
58
+ <div className={classNames('dvrd-radio-bullet', checked && 'checked')} style={getBulletStyle()}/>
59
+ </div>
60
+ )
61
+ }
62
+
63
+ return (
64
+ <div
65
+ className={classNames('dvrd-radio-button', disabled && 'disbled', !!context.noAnimations && 'no-animations', className)}
66
+ onClick={onClick} id={id} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} title={title}>
67
+ {renderLabel('left')}
68
+ {renderBullet()}
69
+ {renderLabel('right')}
70
+ </div>
71
+ )
72
+ }
@@ -0,0 +1,79 @@
1
+ /*
2
+ * Copyright (c) Dave van Rijn Development 2023.
3
+ */
4
+
5
+ import React, {useCallback, useContext, useRef, useState} from 'react';
6
+ import {ChangeFunction} from "../util/interfaces";
7
+ import {generateComponentId} from "../util/componentUtil";
8
+ import {ControlContext} from "../util/controlContext";
9
+ import DvrdRadio from "./dvrdRadio";
10
+
11
+ interface Props {
12
+ onChange: ChangeFunction<string | number | bigint>;
13
+ value: string | number | bigint;
14
+ checked: boolean;
15
+ disabled?: boolean;
16
+ label?: string;
17
+ labelPosition?: 'left' | 'right';
18
+ baseColor?: string;
19
+ id?: string;
20
+ title?: string;
21
+ className?: string;
22
+ }
23
+
24
+ export default function DvrdRadioController(props: Props) {
25
+ const context = useContext(ControlContext);
26
+ const {disabled, onChange, value, checked, labelPosition, label, className, baseColor, title} = props;
27
+ const [hasHover, setHasHover] = useState(false);
28
+ const id = useRef(generateComponentId(props.id));
29
+
30
+ const getContainer = useCallback(() => {
31
+ return document.getElementById(id.current);
32
+ }, [id.current]);
33
+
34
+ const getRipple = useCallback(() => {
35
+ const container = getContainer();
36
+ if (container === null) return null;
37
+ return container.querySelector('div.ripple');
38
+ }, [id.current]);
39
+
40
+ function onClick() {
41
+ if (disabled) return;
42
+ onChange(value);
43
+ if (!context.noAnimations)
44
+ addRipple();
45
+ }
46
+
47
+ function onMouseEnter() {
48
+ if (!disabled)
49
+ setHasHover(true);
50
+ }
51
+
52
+ function onMouseLeave() {
53
+ setHasHover(false);
54
+ }
55
+
56
+ function addRipple() {
57
+ const container = getContainer();
58
+ const ripple = this.getRipple();
59
+ if (!container || !ripple) return;
60
+ if (container.classList.contains('rippling'))
61
+ container.classList.remove('rippling');
62
+ ripple.addEventListener('transitionend', removeRipple);
63
+ container.classList.add('rippling');
64
+ }
65
+
66
+ function removeRipple() {
67
+ const ripple = getRipple();
68
+ const container = getContainer();
69
+ if (!container || !ripple) return;
70
+ ripple.removeEventListener('transitionend', this.removeRipple);
71
+ container.classList.remove('rippling');
72
+ }
73
+
74
+ return (
75
+ <DvrdRadio onClick={onClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} checked={checked}
76
+ hasHover={hasHover} id={id.current} labelPosition={labelPosition ?? 'right'} label={label}
77
+ baseColor={baseColor} className={className} title={title} disabled={disabled}/>
78
+ );
79
+ }
@@ -0,0 +1,80 @@
1
+ /*!
2
+ * Copyright (c) Dave van Rijn Development 2023.
3
+ */
4
+
5
+ @import '../../../style/variables';
6
+
7
+ .dvrd-radio-button {
8
+ cursor: pointer;
9
+ display: flex;
10
+ column-gap: .5rem;
11
+ align-items: center;
12
+
13
+ .dvrd-radio-button-label {
14
+ font-size: .9rem;
15
+ color: $color-blue-text;
16
+ cursor: inherit;
17
+ user-select: none;
18
+ transition: color .2s ease;
19
+ }
20
+
21
+ .dvrd-radio-bullet-container {
22
+ @include backgroundShadow2;
23
+ width: 22px;
24
+ height: 22px;
25
+ position: relative;
26
+ border-radius: 50%;
27
+ border: 2px solid;
28
+ cursor: inherit;
29
+ background-color: white;
30
+ display: flex;
31
+ justify-content: center;
32
+ align-items: center;
33
+
34
+ .dvrd-radio-bullet {
35
+ width: 10px;
36
+ height: 10px;
37
+ border-radius: 50%;
38
+ visibility: hidden;
39
+ opacity: 0;
40
+ transition: visibility .2s ease-in-out, opacity .2s ease-in-out;
41
+
42
+ &.checked {
43
+ visibility: visible;
44
+ opacity: 1;
45
+ }
46
+ }
47
+
48
+ .ripple {
49
+ @include centerXY;
50
+ @include borderRadius(50%);
51
+ opacity: 1;
52
+ width: 8px;
53
+ height: 8px;
54
+ visibility: hidden;
55
+ pointer-events: none;
56
+ }
57
+ }
58
+
59
+ &.disabled {
60
+ cursor: default;
61
+ }
62
+
63
+ &.no-animations {
64
+ &, * {
65
+ transition: none !important;
66
+ }
67
+ }
68
+
69
+ &.rippling {
70
+ .dvrd-radio-bullet-container {
71
+ .ripple {
72
+ width: 56px;
73
+ height: 56px;
74
+ visibility: visible;
75
+ opacity: 0;
76
+ transition: opacity .5s ease-in-out, opacity .5s ease, width .5s ease-in-out, height .5s ease-in-out;
77
+ }
78
+ }
79
+ }
80
+ }
@@ -8,9 +8,9 @@ import {defer} from 'lodash';
8
8
 
9
9
  // noinspection JSUnusedGlobalSymbols
10
10
  export interface ThemeContextShape {
11
- baseColor: string,
12
- contrastColor: string,
13
- onChange: Function,
11
+ baseColor: string;
12
+ contrastColor: string;
13
+ onChange: Function;
14
14
  }
15
15
 
16
16
  export interface ProviderProps {
@@ -23,6 +23,7 @@ export interface ThemeShape {
23
23
  controlVariant?: ControlVariant;
24
24
  borderColor?: string;
25
25
  onChange?: (theme?: ThemeShape) => void;
26
+ noAnimations?: boolean;
26
27
  }
27
28
 
28
29
  export const ControlContext: Context<ThemeShape> = React.createContext<ThemeShape>(
@@ -136,8 +136,8 @@ export const shuffleArray = (arr: any[]): any[] => {
136
136
  return arr;
137
137
  };
138
138
 
139
- export function nullify<T extends string | Array<any> | Set<any> | number>(value?: T | null): T | null {
140
- if (typeof value === 'number') {
139
+ export function nullify<T extends string | Array<any> | Set<any> | number | bigint>(value?: T | null): T | null {
140
+ if (typeof value === 'number' || typeof value === 'bigint') {
141
141
  if (value > 0) return value;
142
142
  return null;
143
143
  }
@@ -5,6 +5,15 @@
5
5
  import moment, {Moment} from "moment";
6
6
 
7
7
  export const MOMENT_FORMATS: string[] = [
8
+ 'MM/DD/YYYY HH:mm:ssZ',
9
+ 'MM-DD-YYYY HH:mm:ssZ',
10
+ 'DD/MM/YYYY HH:mm:ssZ',
11
+ 'DD-MM-YYYY HH:mm:ssZ',
12
+ 'YYYY-MM-DD HH:mm:ssZ',
13
+ 'YYYY/MM/DD HH:mm:ssZ',
14
+ 'DD/MM/YYYYTHH:mm:ssZ',
15
+ 'DD-MM-YYYYTHH:mm:ssZ',
16
+ 'YYYY-MM-DDTHH:mm:ssZ',
8
17
  'MM/DD/YYYY HH:mm:ss',
9
18
  'MM-DD-YYYY HH:mm:ss',
10
19
  'DD/MM/YYYY HH:mm:ss',