diff --git a/player/react/src/lib/components/index.ts b/player/react/src/lib/components/index.ts
index a94397b61..6966f954e 100644
--- a/player/react/src/lib/components/index.ts
+++ b/player/react/src/lib/components/index.ts
@@ -9,6 +9,7 @@ import * as column from './ui-column';
import * as combobox from './ui-combobox';
import * as contentSwitcher from './ui-content-switcher';
import * as dropdown from './ui-dropdown';
+import * as datePicker from './ui-date-picker';
import * as grid from './ui-grid';
import * as numberinput from './ui-number-input';
import * as radio from './ui-radio';
@@ -45,6 +46,7 @@ export const allComponents = {
contentSwitcher,
column,
dropdown,
+ datePicker,
grid,
loading,
inlineLoading,
diff --git a/player/react/src/lib/components/ui-date-picker.tsx b/player/react/src/lib/components/ui-date-picker.tsx
new file mode 100644
index 000000000..f722e13f7
--- /dev/null
+++ b/player/react/src/lib/components/ui-date-picker.tsx
@@ -0,0 +1,128 @@
+import React from 'react';
+import {
+ DatePicker,
+ DatePickerInput
+} from '@carbon/react';
+import { commonSlots, slotsDisabled } from '../common-slots';
+import { SendSignal, CssClasses } from '../types';
+import { stringToCssClassName } from '../utils';
+
+export interface DatePickerState {
+ type: string;
+ id: string;
+ placeholder?: string;
+ disabled?: boolean;
+ invalid?: boolean;
+ invalidText?: string;
+ rangeInvalidText?: string;
+ light?: boolean;
+ size?: string;
+ kind?: string;
+ dateFormat?: string;
+ value?: string;
+ rangeStartLabel?: string;
+ rangeEndLabel?: string;
+ rangePlaceholder?: string;
+ cssClasses?: CssClasses[];
+ codeContext: {
+ name: string;
+ };
+ style?: any;
+}
+
+export const type = 'date-picker';
+
+export const slots = {
+ ...commonSlots,
+ ...slotsDisabled,
+ dateFormat: 'string',
+ kind: 'string',
+ placeholder: 'string',
+ size: 'string',
+ invalidText: 'string',
+ rangeStartLabel: 'string',
+ rangeEndLabel: 'string',
+ rangePlaceholder: 'string',
+ rangeInvalidText: 'string',
+ value: 'string',
+ invalid: 'boolean',
+ setInvalid: (state: DatePickerState) => ({
+ ...state,
+ invalid: true
+ }),
+ setValid: (state: DatePickerState) => ({
+ ...state,
+ invalid: false
+ }),
+ toggleValid: (state: DatePickerState) => ({
+ ...state,
+ invalid: !state.invalid
+ }),
+ light: 'boolean',
+ setLight: (state: DatePickerState) => ({
+ ...state,
+ light: true
+ }),
+ setDark: (state: DatePickerState) => ({
+ ...state,
+ light: false
+ }),
+ toggleLight: (state: DatePickerState) => ({
+ ...state,
+ light: !state.light
+ })
+};
+
+export const signals = ['valueChange', 'click'];
+
+export const UIDatePicker = ({ state, sendSignal }: {
+ state: DatePickerState;
+ setState: (state: any) => void;
+ setGlobalState: (state: any) => void;
+ sendSignal: SendSignal;
+}) => {
+ if (state.type !== 'date-picker') {
+ // eslint-disable-next-line react/jsx-no-useless-fragment
+ return <>>;
+ }
+
+ let cssClasses = state.cssClasses?.map((cc: any) => cc.id).join(' ') || '';
+
+ if (state.style) {
+ if (cssClasses.length > 0) {
+ cssClasses += ' ';
+ }
+ cssClasses += stringToCssClassName(state.codeContext.name);
+ }
+
+ return sendSignal(state.id, 'click')}
+ onChange={(event: any) => {
+ sendSignal(state.id, 'valueChange', [event[0].toISOString()], { ...state, value: event[0].toISOString() });
+ }}>
+
+ {
+ state.kind === 'range'
+ &&
+ }
+ ;
+};
diff --git a/player/react/src/lib/utils.tsx b/player/react/src/lib/utils.tsx
index 7c335518a..ace85aafe 100644
--- a/player/react/src/lib/utils.tsx
+++ b/player/react/src/lib/utils.tsx
@@ -10,6 +10,7 @@ import { UICodeSnippet } from './components/ui-code-snippet';
import { UIColumn } from './components/ui-column';
import { UIComboBox } from './components/ui-combobox';
import { UIContentSwitcher } from './components/ui-content-switcher';
+import { UIDatePicker } from './components/ui-date-picker';
import { UIDropdown } from './components/ui-dropdown';
import { UIExpandableTile } from './components/ui-expandable-tile';
import { UIGrid } from './components/ui-grid';
@@ -238,6 +239,9 @@ export const renderComponents = (
case 'content-switcher':
return ;
+ case 'date-picker':
+ return ;
+
case 'dropdown':
return ;
diff --git a/sdk/react/src/lib/assets/component-icons/date-picker.svg b/sdk/react/src/lib/assets/component-icons/date-picker.svg
new file mode 100644
index 000000000..f06ba1887
--- /dev/null
+++ b/sdk/react/src/lib/assets/component-icons/date-picker.svg
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/sdk/react/src/lib/components/settings-context-pane.tsx b/sdk/react/src/lib/components/settings-context-pane.tsx
index c099bfa18..88b7bc0cd 100644
--- a/sdk/react/src/lib/components/settings-context-pane.tsx
+++ b/sdk/react/src/lib/components/settings-context-pane.tsx
@@ -237,7 +237,7 @@ export const SettingsContextPane = ({
>
}
{
- !selectedComponent && <>
+ !selectedComponent &&
micro layout
- >
+
}
}
diff --git a/sdk/react/src/lib/fragment-components/a-date-picker.tsx b/sdk/react/src/lib/fragment-components/a-date-picker.tsx
new file mode 100644
index 000000000..b11f8c630
--- /dev/null
+++ b/sdk/react/src/lib/fragment-components/a-date-picker.tsx
@@ -0,0 +1,416 @@
+import React, { useState } from 'react';
+import {
+ DatePicker,
+ DatePickerInput,
+ Dropdown,
+ Checkbox,
+ TextInput
+} from '@carbon/react';
+import { AComponent, ComponentInfo } from './a-component';
+import image from './../assets/component-icons/date-picker.svg';
+import {
+ angularClassNamesFromComponentObj,
+ nameStringToVariableString,
+ reactClassNamesFromComponentObj
+} from '../helpers/tools';
+import { css, cx } from 'emotion';
+
+const preventCheckEventStyle = css`
+ pointer-events: none;
+`;
+
+const checkboxStyle = css`
+ padding-top: 0.5rem;
+`;
+
+export const ADatePickerSettingsUI = ({ selectedComponent, setComponent }: any) => {
+ const [showRangePlaceholder, setShowRangePlaceholder] = useState(false);
+ const [rangePlaceholder, setRangePlaceholder] = useState('Range placeholder');
+
+ const size = [
+ { id: 'sm', text: 'Small' },
+ { id: 'md', text: 'Medium' },
+ { id: 'lg', text: 'Large' }
+ ];
+
+ const datePickerType = [
+ { id: 'simple', text: 'Simple' },
+ { id: 'single', text: 'Single with calender' },
+ { id: 'range', text: 'Range with calender' }
+ ];
+
+ return <>
+ setComponent({
+ ...selectedComponent,
+ light: !selectedComponent.light
+ })} />
+ setComponent({
+ ...selectedComponent,
+ disabled: !selectedComponent.disabled
+ })} />
+ item.id === selectedComponent.kind)}
+ itemToString={(item: any) => (item ? item.text : '')}
+ onChange={(event: any) => setComponent({
+ ...selectedComponent,
+ kind: event.selectedItem.id,
+ rangeEndLabel: event.selectedItem.id === 'range' ? 'Range end' : undefined
+ })} />
+ {
+ (selectedComponent.kind === 'single' || selectedComponent.kind === 'range') &&
+ setComponent({
+ ...selectedComponent,
+ dateFormat: event.currentTarget.value
+ })} />
+ }
+ setComponent({
+ ...selectedComponent,
+ placeholder: event.currentTarget.value
+ })} />
+ {selectedComponent.kind === 'range' &&
+ {
+ setShowRangePlaceholder(checked);
+ setComponent({
+ ...selectedComponent,
+ rangePlaceholder: checked ? rangePlaceholder : undefined
+ });
+ }} />
+ }
+ {
+ showRangePlaceholder
+ && {
+ setRangePlaceholder(event.currentTarget.value);
+ setComponent({
+ ...selectedComponent,
+ rangePlaceholder: event.currentTarget.value
+ });
+ }} />
+ }
+ item.id === selectedComponent.size)}
+ itemToString={(item: any) => (item ? item.text : '')}
+ onChange={(event: any) => setComponent({
+ ...selectedComponent,
+ size: event.selectedItem.id
+ })} />
+ setComponent({
+ ...selectedComponent,
+ rangeStartLabel: event.currentTarget.value
+ })} />
+ {
+ selectedComponent.kind === 'range'
+ && setComponent({
+ ...selectedComponent,
+ rangeEndLabel: event.currentTarget.value
+ })} />
+ }
+ setComponent({
+ ...selectedComponent,
+ invalid: !selectedComponent.invalid
+ })} />
+ setComponent({
+ ...selectedComponent,
+ invalidText: event.currentTarget.value
+ })} />
+ {
+ selectedComponent.kind === 'range'
+ && setComponent({
+ ...selectedComponent,
+ rangeInvalidText: event.currentTarget.value
+ })} />
+ }
+ >;
+};
+
+export const ADatePickerCodeUI = ({ selectedComponent, setComponent }: any) => setComponent({
+ ...selectedComponent,
+ codeContext: {
+ ...selectedComponent.codeContext,
+ name: event.currentTarget.value
+ }
+ })}
+/>;
+
+export const ADatePicker = ({
+ componentObj,
+ ...rest
+}: any) => {
+ return (
+
+ {
+ cc.id).join(' '))}
+ dateFormat={componentObj.dateFormat}
+ datePickerType={componentObj.kind}
+ light={componentObj.light}>
+
+ {
+ componentObj.kind === 'range'
+ &&
+ }
+
+ }
+
+ );
+};
+
+export const componentInfo: ComponentInfo = {
+ component: ADatePicker,
+ settingsUI: ADatePickerSettingsUI,
+ codeUI: ADatePickerCodeUI,
+ keywords: ['datepicker', 'date', 'picker'],
+ name: 'Date Picker',
+ type: 'date-picker',
+ defaultComponentObj: {
+ type: 'date-picker',
+ rangeStartLabel: 'Label'
+ },
+ image,
+ codeExport: {
+ angular: {
+ latest: {
+ inputs: ({ json }) => `@Input() ${nameStringToVariableString(json.codeContext?.name)}Value: (string | Date)[]
+ = ${json.value ? json.value : "['']"};
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}Theme: "light" | "dark" = "${json.light ? 'light' : 'dark'}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}RangeStartLabel = "${json.rangeStartLabel}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}RangeEndLabel = "${json.rangeEndLabel ?? ''}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}IsDisabled = ${!!json.disabled};
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}IsInvalid = ${!!json.invalid};
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}InvalidText = "${json.invalidText ?? ''}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}Placeholder = "${json.placeholder ?? 'mm/dd/yyyy'}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}RangePlaceholder = "${json.rangePlaceholder ?? ''}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}Size: "sm" | "md" | "lg" = "${json.size || 'md'}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}DateFormat = "${json.dateFormat || 'm/d/Y'}";`,
+ outputs: ({ json }) => `@Output() ${nameStringToVariableString(json.codeContext?.name)}ValueChange = new EventEmitter();`,
+ imports: ['DatePickerModule'],
+ code: ({ json }) => {
+ return `
+
+ `;
+ }
+ },
+ v10: {
+ inputs: ({ json }) => `@Input() ${nameStringToVariableString(json.codeContext?.name)}Value: (string | Date)[]
+ = ${json.value ? json.value : "['']"};
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}Theme: "light" | "dark" = "${json.light ? 'light' : 'dark'}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}RangeStartLabel = "${json.rangeStartLabel}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}RangeEndLabel = "${json.rangeEndLabel ?? ''}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}IsDisabled = ${!!json.disabled};
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}IsInvalid = ${!!json.invalid};
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}InvalidText = "${json.invalidText ?? ''}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}Placeholder = "${json.placeholder ?? 'mm/dd/yyyy'}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}RangePlaceholder = "${json.rangePlaceholder ?? ''}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}Size: "sm" | "md" | "lg" = "${json.size || 'md'}";
+ @Input() ${nameStringToVariableString(json.codeContext?.name)}DateFormat = "${json.dateFormat || 'm/d/Y'}";`,
+ outputs: ({ json }) => `@Output() ${nameStringToVariableString(json.codeContext?.name)}ValueChange = new EventEmitter();`,
+ imports: ['DatePickerModule'],
+ code: ({ json }) => {
+ return `
+
+ `;
+ }
+ }
+ },
+ react: {
+ latest: {
+ imports: ['DatePicker', 'DatePickerInput'],
+ code: ({ json }) => {
+ return ` handleInputChange({
+ target: {
+ name: "${json.codeContext?.name}",
+ value: dates
+ }
+ })}`: ''}>
+ handleInputChange({
+ target: {
+ name: "${json.codeContext?.name}",
+ value: dates
+ }})}`
+ : ''
+ }
+ />
+ ${
+ json.kind === 'range'
+ ? ``
+ : ''
+ }
+ `;
+ }
+ },
+ v10: {
+ imports: ['DatePicker', 'DatePickerInput'],
+ code: ({ json }) => {
+ return ` handleInputChange({
+ target: {
+ name: "${json.codeContext?.name}",
+ value: dates
+ }
+ })}`: ''}>
+ handleInputChange({
+ target: {
+ name: "${json.codeContext?.name}",
+ value: dates
+ }})}`
+ : ''
+ }
+ />
+ ${
+ json.kind === 'range'
+ ? ``
+ : ''
+ }
+ `;
+ }
+ }
+ }
+ }
+};
diff --git a/sdk/react/src/lib/fragment-components/index.ts b/sdk/react/src/lib/fragment-components/index.ts
index e4308a3fe..74d120da8 100644
--- a/sdk/react/src/lib/fragment-components/index.ts
+++ b/sdk/react/src/lib/fragment-components/index.ts
@@ -8,6 +8,7 @@ import * as codeSnippet from './a-code-snippet';
import * as column from './a-column';
import * as combobox from './a-combobox';
import * as contentSwitcher from './a-content-switcher';
+import * as datepicker from './a-date-picker';
import * as dropdown from './a-dropdown';
import * as fragment from './a-fragment';
import * as grid from './a-grid';
@@ -45,6 +46,7 @@ export { ACheckbox, ACheckboxSettingsUI, ACheckboxCodeUI } from './a-checkbox';
export { AColumn, AColumnCodeUI, AColumnSettingsUI } from './a-column';
export { AComboBox, AComboBoxSettingsUI, AComboBoxCodeUI } from './a-combobox';
export { AContentSwitcher, AContentSwitcherSettingsUI, AContentSwitcherCodeUI } from './a-content-switcher';
+export { ADatePicker, ADatePickerSettingsUI, ADatePickerCodeUI } from './a-date-picker';
export { ADropdown, ADropdownSettingsUI, ADropdownCodeUI } from './a-dropdown';
export * from './a-component';
export { AFragment, AFragmentSettingsUI, AFragmentCodeUI } from './a-fragment';
@@ -85,6 +87,7 @@ export const allComponents = {
combobox,
contentSwitcher,
column,
+ datepicker,
dropdown,
fragment,
grid,