@axinom/mosaic-ui 0.63.0-rc.0 → 0.63.0-rc.2
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/dist/components/FormElements/DateTimeField/DateTimeText.d.ts +1 -1
- package/dist/components/FormElements/DateTimeField/DateTimeText.d.ts.map +1 -1
- package/dist/components/FormElements/DateTimeField/DateTimeTextField.d.ts.map +1 -1
- package/dist/index.es.js +4 -4
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Accordion/Accordion.stories.tsx +44 -2
- package/src/components/Accordion/AccordionItem/AccordionItem.scss +1 -0
- package/src/components/FormElements/DateTimeField/DateTimeText.tsx +8 -14
- package/src/components/FormElements/DateTimeField/DateTimeTextField.tsx +18 -5
- package/src/components/FormStation/Create/Create.stories.tsx +9 -0
- package/src/components/FormStation/FormStation.stories.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-ui",
|
|
3
|
-
"version": "0.63.0-rc.
|
|
3
|
+
"version": "0.63.0-rc.2",
|
|
4
4
|
"description": "UI components for building Axinom Mosaic applications",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -112,5 +112,5 @@
|
|
|
112
112
|
"publishConfig": {
|
|
113
113
|
"access": "public"
|
|
114
114
|
},
|
|
115
|
-
"gitHead": "
|
|
115
|
+
"gitHead": "1138af3f812dff3185f92de01ef6104640711bc8"
|
|
116
116
|
}
|
|
@@ -5,6 +5,7 @@ import { default as React, ReactNode, useEffect, useState } from 'react';
|
|
|
5
5
|
import { createGroups, generateItemArray } from '../../helpers/storybook';
|
|
6
6
|
import { TextButton } from '../Buttons/TextButton/TextButton';
|
|
7
7
|
import { Divider } from '../FormElements';
|
|
8
|
+
import { List } from '../List';
|
|
8
9
|
import { Accordion } from './Accordion';
|
|
9
10
|
import { AccordionItem } from './AccordionItem/AccordionItem';
|
|
10
11
|
|
|
@@ -17,12 +18,13 @@ const groups = createGroups({
|
|
|
17
18
|
const generateItems = (
|
|
18
19
|
startIndex?: number,
|
|
19
20
|
sticky?: boolean,
|
|
21
|
+
children?: JSX.Element,
|
|
20
22
|
): JSX.Element[] => {
|
|
21
23
|
return generateItemArray(10, (index) => {
|
|
22
24
|
const key = index + (startIndex ?? 1);
|
|
23
25
|
return (
|
|
24
26
|
<AccordionItem key={key} header={<b>Item {key}</b>} sticky={sticky}>
|
|
25
|
-
<p>{faker.lorem.paragraph(20)}</p>
|
|
27
|
+
{children ?? <p>{faker.lorem.paragraph(20)}</p>}
|
|
26
28
|
</AccordionItem>
|
|
27
29
|
);
|
|
28
30
|
});
|
|
@@ -56,7 +58,7 @@ export const Default: StoryObj<typeof Accordion> = {
|
|
|
56
58
|
render: (args) => <Accordion {...args} header={<b>{args.header}</b>} />,
|
|
57
59
|
args: {
|
|
58
60
|
children: generateItems(),
|
|
59
|
-
header: 'Header' as
|
|
61
|
+
header: 'Header' as unknown as JSX.Element,
|
|
60
62
|
},
|
|
61
63
|
name: 'Default',
|
|
62
64
|
};
|
|
@@ -103,3 +105,43 @@ export const AddingAndShuffling: StoryObj<typeof Accordion> = {
|
|
|
103
105
|
},
|
|
104
106
|
name: 'Adding and shuffling',
|
|
105
107
|
};
|
|
108
|
+
|
|
109
|
+
export const NestedSticky: StoryObj<typeof Accordion> = {
|
|
110
|
+
args: {
|
|
111
|
+
...Default.args,
|
|
112
|
+
children: generateItems(
|
|
113
|
+
1,
|
|
114
|
+
true,
|
|
115
|
+
<div style={{ height: '350px' }}>
|
|
116
|
+
<List
|
|
117
|
+
columns={[
|
|
118
|
+
{
|
|
119
|
+
propertyName: 'id',
|
|
120
|
+
label: 'Id',
|
|
121
|
+
size: '50px',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
propertyName: 'title',
|
|
125
|
+
label: 'Title',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
propertyName: 'desc',
|
|
129
|
+
label: 'Description',
|
|
130
|
+
},
|
|
131
|
+
]}
|
|
132
|
+
data={generateItemArray(10, (index) => ({
|
|
133
|
+
id: index + 1,
|
|
134
|
+
desc: `Description ${index + 1}: ${faker.lorem.words(
|
|
135
|
+
faker.datatype.number({ min: 10, max: 50 }),
|
|
136
|
+
)}`,
|
|
137
|
+
title: `Item ${index + 1}: ${faker.random.words(
|
|
138
|
+
faker.datatype.number({ min: 1, max: 3 }),
|
|
139
|
+
)}`,
|
|
140
|
+
}))}
|
|
141
|
+
/>
|
|
142
|
+
</div>,
|
|
143
|
+
),
|
|
144
|
+
stickyRows: true,
|
|
145
|
+
},
|
|
146
|
+
name: 'Nested Sticky',
|
|
147
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { DateTime } from 'luxon';
|
|
3
3
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { noop } from '../../../helpers/utils';
|
|
4
5
|
import { Button, ButtonContext } from '../../Buttons';
|
|
5
6
|
import { DateTimePicker } from '../../DateTime/DateTimePicker';
|
|
6
7
|
import { IconName } from '../../Icons';
|
|
@@ -18,7 +19,7 @@ export interface DateTimeTextProps extends BaseFormControl {
|
|
|
18
19
|
autoFocus?: boolean;
|
|
19
20
|
/** Whether or not the control supports auto complete */
|
|
20
21
|
autoComplete?: 'on' | 'off';
|
|
21
|
-
/** Whether the control modifies the time portion of the value */
|
|
22
|
+
/** Whether the control modifies the time portion of the value (default: true) */
|
|
22
23
|
modifyTime?: boolean;
|
|
23
24
|
/** Callback when the datepicker popup is closed or the date field value is changed */
|
|
24
25
|
onChange?: (value: string | null, isValidDate: boolean) => void;
|
|
@@ -39,7 +40,7 @@ export const DateTimeText: React.FC<DateTimeTextProps> = ({
|
|
|
39
40
|
error = undefined,
|
|
40
41
|
autoFocus = false,
|
|
41
42
|
autoComplete,
|
|
42
|
-
onChange,
|
|
43
|
+
onChange = noop,
|
|
43
44
|
modifyTime = true,
|
|
44
45
|
className = '',
|
|
45
46
|
...rest
|
|
@@ -60,34 +61,27 @@ export const DateTimeText: React.FC<DateTimeTextProps> = ({
|
|
|
60
61
|
|
|
61
62
|
const onBlurHandler = useCallback(
|
|
62
63
|
(e: React.FocusEvent<HTMLInputElement>) => {
|
|
63
|
-
// `display` represents the formatted version of the `value` prop and is updated whenever `value` changes.
|
|
64
|
-
// Comparing `e.target.value` with `display` ensures that onChange is only triggered when the input value has changed.
|
|
65
|
-
if (e.target.value === display) {
|
|
66
|
-
// If the value hasn't changed, do not trigger onChange
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
64
|
const textValue = e.target.value;
|
|
71
65
|
const parsedValue = modifyTime
|
|
72
66
|
? DateTime.fromFormat(textValue, 'f')
|
|
73
67
|
: DateTime.fromFormat(textValue, 'D');
|
|
74
68
|
|
|
75
69
|
if (parsedValue.isValid) {
|
|
76
|
-
onChange
|
|
70
|
+
onChange(parsedValue.toISO(), parsedValue.isValid);
|
|
77
71
|
} else if (textValue === '') {
|
|
78
|
-
onChange
|
|
72
|
+
onChange(null, true);
|
|
79
73
|
} else {
|
|
80
74
|
// Fallback parser if the user types in an ISO date
|
|
81
75
|
const isoParsedValue = DateTime.fromISO(textValue);
|
|
82
76
|
|
|
83
77
|
if (isoParsedValue.isValid) {
|
|
84
|
-
onChange
|
|
78
|
+
onChange(isoParsedValue.toISO(), isoParsedValue.isValid);
|
|
85
79
|
} else {
|
|
86
|
-
onChange
|
|
80
|
+
onChange(textValue, parsedValue.isValid);
|
|
87
81
|
}
|
|
88
82
|
}
|
|
89
83
|
},
|
|
90
|
-
[
|
|
84
|
+
[modifyTime, onChange],
|
|
91
85
|
);
|
|
92
86
|
|
|
93
87
|
return (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useField } from 'formik';
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { useFormikError } from '../useFormikError';
|
|
4
5
|
import { DateTimeText, DateTimeTextProps } from './DateTimeText';
|
|
@@ -14,16 +15,28 @@ export const DateTimeTextField: React.FC<
|
|
|
14
15
|
const error = useFormikError(props.name);
|
|
15
16
|
const [, meta, helpers] = useField(props.name);
|
|
16
17
|
|
|
17
|
-
const handleChange = (value: string | null, valid
|
|
18
|
+
const handleChange = (value: string | null, valid: boolean): void => {
|
|
18
19
|
if (!valid) {
|
|
19
20
|
helpers.setError('Invalid Date');
|
|
20
21
|
helpers.setValue(value, false);
|
|
21
22
|
} else {
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
const initialDateTime = DateTime.fromISO(meta.initialValue);
|
|
24
|
+
const newDateTime = DateTime.fromISO(value ?? '');
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
if (newDateTime.setZone(initialDateTime.zone).equals(initialDateTime)) {
|
|
27
|
+
// If the new date is the same as the initial value and the timezone is the only change,
|
|
28
|
+
// set it to the initial value
|
|
29
|
+
helpers.setValue(meta.initialValue);
|
|
30
|
+
} else if (
|
|
31
|
+
(value === null || value === '') &&
|
|
32
|
+
(!meta.initialValue || meta.initialValue === '')
|
|
33
|
+
) {
|
|
34
|
+
// If the value is null or empty and the initial value is also null or empty,
|
|
35
|
+
// set it to the initial value
|
|
36
|
+
helpers.setValue(meta.initialValue);
|
|
37
|
+
} else {
|
|
38
|
+
helpers.setValue(value);
|
|
39
|
+
}
|
|
27
40
|
}
|
|
28
41
|
};
|
|
29
42
|
|
|
@@ -7,6 +7,7 @@ import * as Yup from 'yup';
|
|
|
7
7
|
import { createGroups } from '../../../helpers/storybook';
|
|
8
8
|
import {
|
|
9
9
|
CustomTagsField,
|
|
10
|
+
DateTimeTextField,
|
|
10
11
|
FileUpload,
|
|
11
12
|
SelectField,
|
|
12
13
|
SingleLineTextField,
|
|
@@ -23,6 +24,7 @@ interface CreateValues {
|
|
|
23
24
|
shortDescription?: string;
|
|
24
25
|
longDescription?: string;
|
|
25
26
|
cast?: string[];
|
|
27
|
+
released?: string;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
interface APIResponse {
|
|
@@ -108,6 +110,12 @@ export const Default: StoryObj<CreateStoryType> = {
|
|
|
108
110
|
as={SingleLineTextField}
|
|
109
111
|
type="password"
|
|
110
112
|
/>
|
|
113
|
+
<Field
|
|
114
|
+
name="released"
|
|
115
|
+
label="Released"
|
|
116
|
+
as={DateTimeTextField}
|
|
117
|
+
modifyTime={false}
|
|
118
|
+
/>
|
|
111
119
|
</>
|
|
112
120
|
),
|
|
113
121
|
title: 'Create a Movie',
|
|
@@ -127,6 +135,7 @@ export const Default: StoryObj<CreateStoryType> = {
|
|
|
127
135
|
shortDescription: '',
|
|
128
136
|
longDescription: '',
|
|
129
137
|
cast: [],
|
|
138
|
+
released: '',
|
|
130
139
|
},
|
|
131
140
|
},
|
|
132
141
|
cancelNavigationUrl: '/',
|
|
@@ -169,7 +169,7 @@ export const Extended: StoryObj<typeof Details> = (() => {
|
|
|
169
169
|
shortDescription: 'Some short abstract...',
|
|
170
170
|
longDescription: '',
|
|
171
171
|
cast: ['Jane Doe', 'John Doe'],
|
|
172
|
-
released: '2020-04-
|
|
172
|
+
released: '2020-04-03',
|
|
173
173
|
list: listData,
|
|
174
174
|
archived: false,
|
|
175
175
|
timestamp: '00:00:00.001',
|
|
@@ -227,7 +227,7 @@ export const Extended: StoryObj<typeof Details> = (() => {
|
|
|
227
227
|
name="released"
|
|
228
228
|
label="Released"
|
|
229
229
|
as={DateTimeTextField}
|
|
230
|
-
|
|
230
|
+
modifyTime={false}
|
|
231
231
|
/>
|
|
232
232
|
<Field
|
|
233
233
|
name="password"
|