superdesk-ui-framework 3.0.1-beta.9 → 3.0.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/app/fonts/sd_icons.eot +0 -0
- package/app/fonts/sd_icons.svg +1 -0
- package/app/fonts/sd_icons.ttf +0 -0
- package/app/fonts/sd_icons.woff +0 -0
- package/app/scripts/toggleBoxNext.js +1 -1
- package/app/styles/_big-icon-font.scss +1 -1
- package/app/styles/_buttons.scss +11 -6
- package/app/styles/_content-divider.scss +63 -8
- package/app/styles/_helpers.scss +24 -1
- package/app/styles/_icon-font.scss +11 -10
- package/app/styles/_labels.scss +0 -1
- package/app/styles/_master-desk.scss +5 -4
- package/app/styles/_modals.scss +7 -3
- package/app/styles/_normalize.scss +4 -0
- package/app/styles/_sd-tag-input.scss +56 -2
- package/app/styles/_simple-list.scss +0 -2
- package/app/styles/_table-list.scss +116 -12
- package/app/styles/app.scss +3 -0
- package/app/styles/components/_list-item.scss +23 -16
- package/app/styles/components/_sd-collapse-box.scss +6 -6
- package/app/styles/components/_sd-comment-box.scss +8 -4
- package/app/styles/components/_sd-editor-popup.scss +4 -4
- package/app/styles/components/_sd-media-carousel.scss +37 -2
- package/app/styles/components/_sd-pagination.scss +41 -0
- package/app/styles/components/_sd-photo-preview.scss +2 -2
- package/app/styles/components/_subnav.scss +470 -470
- package/app/styles/design-tokens/_new-colors.scss +29 -12
- package/app/styles/dropdowns/_basic-dropdown.scss +6 -0
- package/app/styles/form-elements/_input-wrap.scss +138 -0
- package/app/styles/form-elements/_inputs.scss +230 -61
- package/app/styles/grids/_grid-layout.scss +13 -14
- package/app/styles/interface-elements/_side-panel.scss +1 -1
- package/app/styles/layout/_editor.scss +6 -0
- package/app/styles/menus/_sd-sidebar-menu.scss +1 -1
- package/app/styles/primereact/_pr-datepicker.scss +16 -2
- package/app/styles/primereact/_pr-dialog.scss +9 -0
- package/app/styles/primereact/_pr-menu.scss +6 -5
- package/app/styles/variables/_colors.scss +47 -47
- package/app/template/search-handler.html +2 -2
- package/app-typescript/components/ContentDivider.tsx +3 -0
- package/app-typescript/components/DatePicker.tsx +8 -9
- package/app-typescript/components/Dropdown.tsx +127 -82
- package/app-typescript/components/DurationInput.tsx +39 -14
- package/app-typescript/components/Form/FormLabel.tsx +8 -1
- package/app-typescript/components/Form/InputBase.tsx +12 -2
- package/app-typescript/components/Input.tsx +4 -4
- package/app-typescript/components/Label.tsx +17 -1
- package/app-typescript/components/Layouts/AuthoringFrame.tsx +2 -1
- package/app-typescript/components/Layouts/AuthoringFrameRightBar.tsx +21 -2
- package/app-typescript/components/Layouts/AuthoringInnerHeader.tsx +1 -1
- package/app-typescript/components/Layouts/AuthoringMain.tsx +4 -2
- package/app-typescript/components/Layouts/CoreLayout.tsx +3 -1
- package/app-typescript/components/Layouts/CoreLayoutMain.tsx +10 -1
- package/app-typescript/components/Lists/ContentList.tsx +64 -30
- package/app-typescript/components/Lists/TableList.tsx +255 -53
- package/app-typescript/components/Menu.tsx +2 -2
- package/app-typescript/components/Modal.tsx +6 -2
- package/app-typescript/components/MultiSelect.tsx +2 -2
- package/app-typescript/components/NavButton.tsx +2 -1
- package/app-typescript/components/Navigation/SideBarMenu.tsx +30 -4
- package/app-typescript/components/SearchBar.tsx +11 -3
- package/app-typescript/components/Spacer.tsx +87 -0
- package/app-typescript/components/TimePicker.tsx +2 -13
- package/app-typescript/components/TreeSelect.tsx +286 -180
- package/app-typescript/index.ts +1 -0
- package/dist/examples.bundle.css +110 -71
- package/dist/examples.bundle.js +24358 -22168
- package/dist/playgrounds/react-playgrounds/CoreLayout.tsx +505 -2
- package/dist/playgrounds/react-playgrounds/Index.tsx +1 -0
- package/dist/playgrounds/react-playgrounds/Multiedit.tsx +321 -0
- package/dist/playgrounds/react-playgrounds/RundownEditor.tsx +17 -19
- package/dist/playgrounds/react-playgrounds/Rundowns.tsx +22 -23
- package/dist/playgrounds/react-playgrounds/TestGround.tsx +226 -25
- package/dist/react/ContentDivider.tsx +22 -18
- package/dist/react/ContentList.tsx +188 -12
- package/dist/react/DatePicker.tsx +50 -2
- package/dist/react/Dropdowns.tsx +580 -48
- package/dist/react/DurationInput.tsx +7 -3
- package/dist/react/Inputs.tsx +1 -7
- package/dist/react/Modal.tsx +154 -22
- package/dist/react/MultiSelect.tsx +5 -5
- package/dist/react/NavButtons.tsx +31 -1
- package/dist/react/TableList.tsx +52 -139
- package/dist/react/Togglebox.tsx +1 -1
- package/dist/react/TreeSelect.tsx +167 -176
- package/dist/sd_icons.eot +0 -0
- package/dist/sd_icons.svg +1 -0
- package/dist/sd_icons.ttf +0 -0
- package/dist/sd_icons.woff +0 -0
- package/dist/superdesk-ui.bundle.css +1100 -407
- package/dist/superdesk-ui.bundle.js +6594 -4035
- package/dist/vendor.bundle.js +27 -27
- package/examples/css/docs-page.css +4 -4
- package/examples/index.js +4 -0
- package/examples/pages/playgrounds/react-playgrounds/CoreLayout.tsx +505 -2
- package/examples/pages/playgrounds/react-playgrounds/Index.tsx +1 -0
- package/examples/pages/playgrounds/react-playgrounds/Multiedit.tsx +321 -0
- package/examples/pages/playgrounds/react-playgrounds/RundownEditor.tsx +17 -19
- package/examples/pages/playgrounds/react-playgrounds/Rundowns.tsx +22 -23
- package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +226 -25
- package/examples/pages/react/ContentDivider.tsx +22 -18
- package/examples/pages/react/ContentList.tsx +188 -12
- package/examples/pages/react/DatePicker.tsx +50 -2
- package/examples/pages/react/Dropdowns.tsx +580 -48
- package/examples/pages/react/DurationInput.tsx +7 -3
- package/examples/pages/react/Inputs.tsx +1 -7
- package/examples/pages/react/Modal.tsx +154 -22
- package/examples/pages/react/MultiSelect.tsx +5 -5
- package/examples/pages/react/NavButtons.tsx +31 -1
- package/examples/pages/react/TableList.tsx +52 -139
- package/examples/pages/react/Togglebox.tsx +1 -1
- package/examples/pages/react/TreeSelect.tsx +167 -176
- package/package.json +3 -5
- package/react/components/ContentDivider.d.ts +1 -0
- package/react/components/ContentDivider.js +2 -0
- package/react/components/DatePicker.d.ts +2 -2
- package/react/components/DatePicker.js +3 -3
- package/react/components/Dropdown.d.ts +6 -5
- package/react/components/Dropdown.js +57 -30
- package/react/components/DurationInput.d.ts +1 -1
- package/react/components/DurationInput.js +46 -17
- package/react/components/Form/FormLabel.d.ts +4 -1
- package/react/components/Form/FormLabel.js +9 -3
- package/react/components/Form/InputBase.d.ts +0 -1
- package/react/components/Form/InputBase.js +15 -1
- package/react/components/Input.d.ts +3 -3
- package/react/components/Input.js +2 -1
- package/react/components/Label.d.ts +1 -0
- package/react/components/Label.js +17 -2
- package/react/components/Layouts/AuthoringFrame.d.ts +1 -0
- package/react/components/Layouts/AuthoringFrame.js +1 -1
- package/react/components/Layouts/AuthoringFrameRightBar.d.ts +9 -2
- package/react/components/Layouts/AuthoringFrameRightBar.js +14 -3
- package/react/components/Layouts/AuthoringInnerHeader.js +1 -1
- package/react/components/Layouts/AuthoringMain.js +1 -1
- package/react/components/Layouts/CoreLayout.d.ts +2 -0
- package/react/components/Layouts/CoreLayout.js +1 -1
- package/react/components/Layouts/CoreLayoutMain.d.ts +2 -0
- package/react/components/Layouts/CoreLayoutMain.js +8 -1
- package/react/components/Lists/ContentList.d.ts +6 -0
- package/react/components/Lists/ContentList.js +42 -16
- package/react/components/Lists/TableList.d.ts +30 -8
- package/react/components/Lists/TableList.js +127 -24
- package/react/components/Menu.js +1 -1
- package/react/components/Modal.d.ts +2 -0
- package/react/components/Modal.js +3 -3
- package/react/components/MultiSelect.d.ts +40 -0
- package/react/components/MultiSelect.js +73 -0
- package/react/components/NavButton.d.ts +1 -1
- package/react/components/Navigation/SideBarMenu.d.ts +6 -0
- package/react/components/Navigation/SideBarMenu.js +19 -2
- package/react/components/SearchBar.d.ts +1 -1
- package/react/components/SearchBar.js +15 -7
- package/react/components/TimePicker.d.ts +1 -5
- package/react/components/TimePicker.js +3 -7
- package/react/components/TreeSelect.d.ts +12 -5
- package/react/components/TreeSelect.js +189 -116
- package/react/index.d.ts +1 -0
- package/react/index.js +3 -0
- package/patches/@superdesk+primereact+5.0.2-4.patch +0 -66
@@ -2,30 +2,30 @@
|
|
2
2
|
// -------------------------------------------------------------------------
|
3
3
|
|
4
4
|
// Refernce Colours
|
5
|
-
$ref-color-primary: hsla(198, 50%, 50%, 1);
|
6
|
-
$ref-color-success: hsla(120, 40%, 50%, 1);
|
7
|
-
$ref-color-alert: hsla(358, 79%, 50%, 1);
|
8
|
-
$ref-color-warning: hsla(35, 100%, 50%, 1);
|
9
|
-
$ref-color-highlight: hsla(291, 64%, 50%, 1);
|
10
|
-
$ref-color-neutral: hsla(0, 0%, 50%, 1);
|
5
|
+
// $ref-color-primary: hsla(198, 50%, 50%, 1);
|
6
|
+
// $ref-color-success: hsla(120, 40%, 50%, 1);
|
7
|
+
// $ref-color-alert: hsla(358, 79%, 50%, 1);
|
8
|
+
// $ref-color-warning: hsla(35, 100%, 50%, 1);
|
9
|
+
// $ref-color-highlight: hsla(291, 64%, 50%, 1);
|
10
|
+
// $ref-color-neutral: hsla(0, 0%, 50%, 1);
|
11
11
|
|
12
12
|
// Refernce Colours -- DARK BGs & Lines
|
13
|
-
$ref-color-cool-grey--00: hsl(214, 13%, 12%);
|
14
|
-
$ref-color-cool-grey--01: hsl(214, 13%, 16%);
|
15
|
-
$ref-color-cool-grey--02: hsl(214, 13%, 20%);
|
16
|
-
$ref-color-cool-grey--03: hsl(214, 13%, 25%);
|
17
|
-
$ref-color-cool-grey--04: hsl(214, 13%, 30%);
|
13
|
+
// $ref-color-cool-grey--00: hsl(214, 13%, 12%);
|
14
|
+
// $ref-color-cool-grey--01: hsl(214, 13%, 16%);
|
15
|
+
// $ref-color-cool-grey--02: hsl(214, 13%, 20%);
|
16
|
+
// $ref-color-cool-grey--03: hsl(214, 13%, 25%);
|
17
|
+
// $ref-color-cool-grey--04: hsl(214, 13%, 30%);
|
18
18
|
|
19
19
|
// Refernce Colours -- LIGHT BGs & Lines
|
20
|
-
$ref-color-light-grey--00: hsl(214, 13%, 100%);
|
21
|
-
$ref-color-light-grey--01: hsl(214, 13%, 96%);
|
22
|
-
$ref-color-light-grey--02: hsl(214, 13%, 92%);
|
23
|
-
$ref-color-light-grey--03: hsl(214, 13%, 85%);
|
24
|
-
$ref-color-light-grey--04: hsl(214, 13%, 80%);
|
25
|
-
$ref-color-light-grey--05: hsl(214, 13%, 75%);
|
26
|
-
$ref-color-light-grey--06: hsl(214, 13%, 70%);
|
27
|
-
$ref-color-light-grey--07: hsl(214, 13%, 65%);
|
28
|
-
$ref-color-light-grey--08: hsl(214, 13%, 60%);
|
20
|
+
// $ref-color-light-grey--00: hsl(214, 13%, 100%);
|
21
|
+
// $ref-color-light-grey--01: hsl(214, 13%, 96%);
|
22
|
+
// $ref-color-light-grey--02: hsl(214, 13%, 92%);
|
23
|
+
// $ref-color-light-grey--03: hsl(214, 13%, 85%);
|
24
|
+
// $ref-color-light-grey--04: hsl(214, 13%, 80%);
|
25
|
+
// $ref-color-light-grey--05: hsl(214, 13%, 75%);
|
26
|
+
// $ref-color-light-grey--06: hsl(214, 13%, 70%);
|
27
|
+
// $ref-color-light-grey--07: hsl(214, 13%, 65%);
|
28
|
+
// $ref-color-light-grey--08: hsl(214, 13%, 60%);
|
29
29
|
|
30
30
|
///// ==============
|
31
31
|
|
@@ -81,29 +81,29 @@ $yellow: hsla(45, 100%, 53%, 1);
|
|
81
81
|
$orange: hsla(35, 100%, 43%, 1);
|
82
82
|
$purple: hsla(291, 64%, 42%, 1);
|
83
83
|
|
84
|
-
$black:
|
85
|
-
$grayDarker:
|
86
|
-
$grayDark:
|
87
|
-
$grayMedium:
|
88
|
-
$gray:
|
89
|
-
$grayNeutral:
|
90
|
-
$grayText:
|
91
|
-
$grayLight:
|
92
|
-
$grayLighter:
|
93
|
-
$white:
|
84
|
+
$black: hsl(214, 13%, 0%);
|
85
|
+
$grayDarker: hsl(214, 13%, 13%);
|
86
|
+
$grayDark: hsl(214, 13%, 20%);
|
87
|
+
$grayMedium: hsl(214, 13%, 27%);
|
88
|
+
$gray: hsl(214, 13%, 40%);
|
89
|
+
$grayNeutral: hsl(214, 13%, 48%);
|
90
|
+
$grayText: hsl(214, 13%, 45%);
|
91
|
+
$grayLight: hsl(214, 13%, 60%);
|
92
|
+
$grayLighter: hsl(214, 13%, 96%);
|
93
|
+
$white: hsl(214, 13%, 100%);
|
94
94
|
|
95
95
|
// Greys
|
96
|
-
$gray--900:
|
97
|
-
$gray--800:
|
98
|
-
$gray--700:
|
99
|
-
$gray--600:
|
100
|
-
$gray--500:
|
101
|
-
$gray--400:
|
102
|
-
$gray--300:
|
103
|
-
$gray--200:
|
104
|
-
$gray--100:
|
105
|
-
$gray--75:
|
106
|
-
$grey--50:
|
96
|
+
// $gray--900: hsl(214, 13%, 20%);
|
97
|
+
// $gray--800: hsl(214, 13%, 27%);
|
98
|
+
// $gray--700: hsl(214, 13%, 33%);
|
99
|
+
// $gray--600: hsl(214, 13%, 40%);
|
100
|
+
// $gray--500: hsl(214, 13%, 45%);
|
101
|
+
// $gray--400: hsl(214, 13%, 53%);
|
102
|
+
// $gray--300: hsl(214, 13%, 60%);
|
103
|
+
// $gray--200: hsl(214, 13%, 80%);
|
104
|
+
// $gray--100: hsl(214, 13%, 87%);
|
105
|
+
// $gray--75: hsl(214, 13%, 93%);
|
106
|
+
// $grey--50: hsl(214, 13%, 96%);
|
107
107
|
|
108
108
|
// Extended colors
|
109
109
|
$fernGreen: hsla(91, 47%, 34%, 1);
|
@@ -116,12 +116,12 @@ $darkViolet: hsla(280, 100%, 34%, 1);
|
|
116
116
|
$navy: hsla(240, 100%, 25%, 1);
|
117
117
|
|
118
118
|
// Panel backgrounds
|
119
|
-
$panel-bg--00: #fff;
|
120
|
-
$panel-bg--01: #f8f8f8;
|
121
|
-
$panel-bg--02: #f5f5f5;
|
122
|
-
$panel-bg--03: #ededed;
|
123
|
-
$panel-bg--04: #dedede;
|
124
|
-
$panel-bg--05: #a1a1a1;
|
119
|
+
// $panel-bg--00: #fff;
|
120
|
+
// $panel-bg--01: #f8f8f8;
|
121
|
+
// $panel-bg--02: #f5f5f5;
|
122
|
+
// $panel-bg--03: #ededed;
|
123
|
+
// $panel-bg--04: #dedede;
|
124
|
+
// $panel-bg--05: #a1a1a1;
|
125
125
|
|
126
126
|
// Text specific colors
|
127
127
|
//Subnav colours
|
@@ -1,6 +1,6 @@
|
|
1
|
-
<div class="flat-searchbar
|
1
|
+
<div class="flat-searchbar extended">
|
2
2
|
<div class="search-handler" ng-class="{'search-handler--left-border': borderleft}">
|
3
|
-
<label for="search-input" class="trigger-icon"
|
3
|
+
<label for="search-input" class="trigger-icon"><i class="icon-search"></i></label>
|
4
4
|
<input id="search-input" type="text" placeholder="{{ :: label || 'Search' }}" ng-model="model" ng-model-options="{debounce: debounce}">
|
5
5
|
<button class="search-close" ng-if="model.length" ng-click="clearInput()" ng-class="{visible: model.length}"><i class="icon-remove-sign"></i></button>
|
6
6
|
|
@@ -6,6 +6,7 @@ interface IProps {
|
|
6
6
|
orientation?: 'horizontal' |'vertical'; // defaults to 'horizontal'
|
7
7
|
align?: 'center' | 'left' | 'right'; // defaults to 'center'
|
8
8
|
border?: boolean;
|
9
|
+
margin?: 'x-small' | 'small' |'medium' | 'large' | 'none';
|
9
10
|
children?: React.ReactNode;
|
10
11
|
}
|
11
12
|
|
@@ -19,6 +20,8 @@ export class ContentDivider extends React.PureComponent<IProps> {
|
|
19
20
|
[`sd-content-divider--text-${this.props.align}`]: this.props.align || this.props.align !== undefined,
|
20
21
|
[`sd-content-divider--${this.props.orientation}`]:
|
21
22
|
this.props.orientation || this.props.orientation !== undefined,
|
23
|
+
'sd-content-divider--margin-medium': this.props.margin === undefined,
|
24
|
+
[`sd-content-divider--margin-${this.props.margin}`]: this.props.margin || this.props.margin !== undefined,
|
22
25
|
});
|
23
26
|
|
24
27
|
if (this.props.children) {
|
@@ -10,12 +10,11 @@ import { InputWrapper } from './Form';
|
|
10
10
|
export type DatePickerLocaleSettings = Omit<LocaleSettings, 'today' | 'clear'>;
|
11
11
|
|
12
12
|
interface IDatePickerBase {
|
13
|
-
disabled?: boolean;
|
14
13
|
dateFormat: string; // a combination of YYYY, MM, and DD with a custom separator e.g. 'MM/DD/YYYY'
|
15
14
|
|
16
15
|
// shortcuts can be used to jump to a date relative to today
|
17
16
|
// for example [{label: 'tomorrow', days: 1}, {label: 'yesterday', days: -1}]
|
18
|
-
|
17
|
+
headerButtonBar?: Array<{days: number, label: string}>;
|
19
18
|
|
20
19
|
// ability to provide localisation. for example (see https://primefaces.org/primereact/showcase/#/calendar):
|
21
20
|
/*
|
@@ -34,6 +33,7 @@ interface IDatePickerBase {
|
|
34
33
|
locale?: DatePickerLocaleSettings;
|
35
34
|
|
36
35
|
// label props
|
36
|
+
disabled?: boolean;
|
37
37
|
inlineLabel?: boolean;
|
38
38
|
required?: boolean;
|
39
39
|
fullWidth?: boolean;
|
@@ -180,23 +180,22 @@ export class DatePicker extends React.PureComponent<IDatePicker, IState> {
|
|
180
180
|
dateFormat={this.props.dateFormat.replace('YYYY', 'yy').replace('MM', 'mm').replace('DD', 'dd')}
|
181
181
|
showIcon={true}
|
182
182
|
icon="icon-calendar"
|
183
|
-
headerTemplate={() => this.props.
|
183
|
+
headerTemplate={() => this.props.headerButtonBar == null ? null : (
|
184
184
|
<div
|
185
|
-
|
186
|
-
{this.props.
|
185
|
+
className="datepicker-header-toolbar">
|
186
|
+
{this.props.headerButtonBar.map(({label, days}, i) => (
|
187
187
|
<button
|
188
188
|
key={i}
|
189
|
-
className="btn btn--
|
189
|
+
className="btn btn--small"
|
190
190
|
onClick={() => {
|
191
191
|
this.props.onChange(addDays(new Date(), days));
|
192
|
-
|
193
192
|
if (this.instance != null && typeof this.instance.hideOverlay === 'function') {
|
194
193
|
this.instance.hideOverlay();
|
195
194
|
}
|
196
195
|
}}>
|
197
196
|
{label}
|
198
197
|
</button>
|
199
|
-
|
198
|
+
))}
|
200
199
|
</div>
|
201
200
|
)}
|
202
201
|
appendTo={document.body} // making it work inside `overflow:hidden`
|
@@ -234,7 +233,7 @@ export class DatePickerISO extends React.PureComponent<IDatePickerISO> {
|
|
234
233
|
}
|
235
234
|
}}
|
236
235
|
disabled={this.props.disabled}
|
237
|
-
|
236
|
+
headerButtonBar={this.props.headerButtonBar}
|
238
237
|
dateFormat={this.props.dateFormat}
|
239
238
|
locale={this.props.locale}
|
240
239
|
inlineLabel={this.props.inlineLabel}
|
@@ -4,35 +4,42 @@ import { createPopper } from '@popperjs/core';
|
|
4
4
|
import { useId } from "react-id-generator";
|
5
5
|
|
6
6
|
export interface IMenuItem {
|
7
|
-
label: string;
|
7
|
+
label: string | React.ReactNode;
|
8
8
|
icon?: string;
|
9
9
|
active?: boolean;
|
10
10
|
onSelect(): void;
|
11
11
|
}
|
12
12
|
|
13
|
+
interface IMenuItemRes extends IMenuItem {
|
14
|
+
onChange?(event?: any): void;
|
15
|
+
}
|
16
|
+
|
13
17
|
export interface ISubmenu {
|
14
18
|
type: 'submenu';
|
15
|
-
label: string;
|
19
|
+
label: string | React.ReactNode;
|
16
20
|
icon?: string;
|
17
21
|
items: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
18
22
|
}
|
19
23
|
|
20
24
|
export interface IMenuGroup {
|
21
25
|
type: 'group';
|
22
|
-
label?: string;
|
26
|
+
label?: string | React.ReactNode;
|
23
27
|
items: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
24
28
|
}
|
25
29
|
|
26
30
|
interface IMenu {
|
27
|
-
label?: string;
|
31
|
+
label?: string | React.ReactNode;
|
28
32
|
align?: 'left' | 'right';
|
29
33
|
items: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
30
34
|
header?: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
31
35
|
footer?: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
32
36
|
append?: boolean;
|
33
37
|
children: React.ReactNode;
|
38
|
+
onChange?(event?: any): void;
|
34
39
|
}
|
35
40
|
|
41
|
+
const DROPDOWN_ID_CONTAINER = "sd-dropdown-constainer";
|
42
|
+
|
36
43
|
export const Dropdown = ({
|
37
44
|
items,
|
38
45
|
header,
|
@@ -40,15 +47,13 @@ export const Dropdown = ({
|
|
40
47
|
children,
|
41
48
|
append,
|
42
49
|
align,
|
50
|
+
onChange,
|
43
51
|
}: IMenu) => {
|
44
52
|
const [open, setOpen] = React.useState(false);
|
45
53
|
const [change, setChange] = React.useState(false);
|
46
54
|
const [menuID] = useId();
|
47
|
-
const DROPDOWN_ID = "react-placeholder";
|
48
55
|
const ref = React.useRef(null);
|
49
|
-
const refSubMenu = React.useRef(null);
|
50
56
|
const buttonRef = React.useRef(null);
|
51
|
-
const refButtonSubMenu = React.useRef(null);
|
52
57
|
const headerElements = header?.map((el, index) => {
|
53
58
|
return each(el, index);
|
54
59
|
});
|
@@ -60,12 +65,12 @@ export const Dropdown = ({
|
|
60
65
|
const footerElements = footer?.map((el, index) => {
|
61
66
|
return each(el, index);
|
62
67
|
});
|
68
|
+
|
63
69
|
React.useEffect(() => {
|
64
|
-
const existingElement = document.getElementById(
|
70
|
+
const existingElement = document.getElementById(DROPDOWN_ID_CONTAINER);
|
65
71
|
if (!existingElement) {
|
66
72
|
const el = document.createElement("div");
|
67
|
-
el.id =
|
68
|
-
// style placeholder
|
73
|
+
el.id = DROPDOWN_ID_CONTAINER;
|
69
74
|
el.style.position = 'absolute';
|
70
75
|
el.style.top = '0';
|
71
76
|
el.style.left = '0';
|
@@ -74,7 +79,6 @@ export const Dropdown = ({
|
|
74
79
|
|
75
80
|
document.body.appendChild(el);
|
76
81
|
}
|
77
|
-
|
78
82
|
}, [change]);
|
79
83
|
|
80
84
|
React.useLayoutEffect(() => {
|
@@ -82,17 +86,12 @@ export const Dropdown = ({
|
|
82
86
|
addInPlaceholder();
|
83
87
|
}
|
84
88
|
setChange(true);
|
85
|
-
|
86
89
|
}, [open]);
|
87
90
|
|
88
|
-
// structure for append menu
|
89
91
|
function createAppendMenu() {
|
90
92
|
if (header && footer) {
|
91
93
|
return (
|
92
|
-
<div className='dropdown__menu dropdown__menu--has-head-foot'
|
93
|
-
id={menuID}
|
94
|
-
role='menu'
|
95
|
-
ref={ref}>
|
94
|
+
<div className='dropdown__menu dropdown__menu--has-head-foot' id={menuID} role='menu' ref={ref}>
|
96
95
|
<ul className='dropdown__menu-header'>
|
97
96
|
{headerElements}
|
98
97
|
</ul>
|
@@ -106,10 +105,7 @@ export const Dropdown = ({
|
|
106
105
|
);
|
107
106
|
} else if (header) {
|
108
107
|
return (
|
109
|
-
<div className='dropdown__menu dropdown__menu--has-head-foot'
|
110
|
-
id={menuID}
|
111
|
-
role='menu'
|
112
|
-
ref={ref}>
|
108
|
+
<div className='dropdown__menu dropdown__menu--has-head-foot' id={menuID} role='menu' ref={ref}>
|
113
109
|
<ul className='dropdown__menu-header'>
|
114
110
|
{headerElements}
|
115
111
|
</ul>
|
@@ -120,10 +116,7 @@ export const Dropdown = ({
|
|
120
116
|
);
|
121
117
|
} else if (footer) {
|
122
118
|
return (
|
123
|
-
<div className='dropdown__menu dropdown__menu--has-head-foot'
|
124
|
-
id={menuID}
|
125
|
-
role='menu'
|
126
|
-
ref={ref}>
|
119
|
+
<div className='dropdown__menu dropdown__menu--has-head-foot' id={menuID} role='menu' ref={ref}>
|
127
120
|
<ul className='dropdown__menu-body'>
|
128
121
|
{dropdownElements}
|
129
122
|
</ul>
|
@@ -134,17 +127,13 @@ export const Dropdown = ({
|
|
134
127
|
);
|
135
128
|
} else {
|
136
129
|
return (
|
137
|
-
<ul className='dropdown__menu '
|
138
|
-
id={menuID}
|
139
|
-
role='menu'
|
140
|
-
ref={ref}>
|
130
|
+
<ul className='dropdown__menu ' id={menuID} role='menu' ref={ref}>
|
141
131
|
{dropdownElements}
|
142
132
|
</ul>
|
143
133
|
);
|
144
134
|
}
|
145
135
|
}
|
146
136
|
|
147
|
-
// toggle menu
|
148
137
|
function toggleDisplay() {
|
149
138
|
if (!open) {
|
150
139
|
let menuRef: any;
|
@@ -193,14 +182,13 @@ export const Dropdown = ({
|
|
193
182
|
}
|
194
183
|
|
195
184
|
function addInPlaceholder() {
|
196
|
-
const placeholder = document.getElementById(
|
185
|
+
const placeholder = document.getElementById(DROPDOWN_ID_CONTAINER);
|
197
186
|
let menu = createAppendMenu();
|
198
187
|
if (open) {
|
199
188
|
return ReactDOM.render(menu, placeholder);
|
200
189
|
} else {
|
201
|
-
|
202
|
-
|
203
|
-
menuDOM.style.display = 'none';
|
190
|
+
if (placeholder) {
|
191
|
+
ReactDOM.unmountComponentAtNode(placeholder);
|
204
192
|
}
|
205
193
|
}
|
206
194
|
}
|
@@ -212,33 +200,13 @@ export const Dropdown = ({
|
|
212
200
|
submenuItems.push(each(el, key));
|
213
201
|
});
|
214
202
|
return (
|
215
|
-
<
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
onMouseOver={() => {
|
223
|
-
let subMenuRef = refSubMenu.current;
|
224
|
-
let subToggleRef = refButtonSubMenu.current;
|
225
|
-
if (subMenuRef && subToggleRef) {
|
226
|
-
createPopper(subToggleRef, subMenuRef, {
|
227
|
-
placement: 'right-start',
|
228
|
-
});
|
229
|
-
}
|
230
|
-
}}
|
231
|
-
onClick={item['onSelect']}>
|
232
|
-
{item['icon'] ? <i className={'icon-' + item['icon']}></i> : null}
|
233
|
-
{item['label']}
|
234
|
-
</button>
|
235
|
-
<ul ref={refSubMenu}
|
236
|
-
role='menu'
|
237
|
-
className='dropdown__menu'>
|
238
|
-
{submenuItems}
|
239
|
-
</ul>
|
240
|
-
</div>
|
241
|
-
</li>
|
203
|
+
<DropdownItemWithSubmenu
|
204
|
+
key={index}
|
205
|
+
index={index}
|
206
|
+
item={item}
|
207
|
+
menuID={menuID}
|
208
|
+
subMenuItems={submenuItems}
|
209
|
+
onChange={onChange} />
|
242
210
|
);
|
243
211
|
} else if (item['type'] === 'group') {
|
244
212
|
let groupItems: any = [];
|
@@ -258,16 +226,18 @@ export const Dropdown = ({
|
|
258
226
|
} else {
|
259
227
|
return (
|
260
228
|
<DropdownItem
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
229
|
+
key={index}
|
230
|
+
label={item['label']}
|
231
|
+
icon={item['icon']}
|
232
|
+
active={item['active']}
|
233
|
+
onSelect={item['onSelect']}
|
234
|
+
onChange={onChange} />
|
235
|
+
);
|
266
236
|
}
|
267
237
|
}
|
268
238
|
|
269
239
|
return (
|
270
|
-
<div className={'dropdown ' + (open ? 'open' : '')}
|
240
|
+
<div className={'dropdown ' + (open ? 'open' : '')}>
|
271
241
|
{typeof children === 'object' ?
|
272
242
|
(React.isValidElement(children) ?
|
273
243
|
<div ref={buttonRef} style={{ display: 'content' }}>
|
@@ -281,11 +251,11 @@ export const Dropdown = ({
|
|
281
251
|
</div> : null)
|
282
252
|
:
|
283
253
|
<button ref={buttonRef}
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
254
|
+
className=' dropdown__toggle dropdown-toggle'
|
255
|
+
aria-haspopup="menu"
|
256
|
+
tabIndex={0}
|
257
|
+
aria-expanded={open}
|
258
|
+
onClick={toggleDisplay}>
|
289
259
|
{children}
|
290
260
|
<span className="dropdown__caret"></span>
|
291
261
|
</button>}
|
@@ -294,7 +264,7 @@ export const Dropdown = ({
|
|
294
264
|
null : (function() {
|
295
265
|
if (header && footer) {
|
296
266
|
return (
|
297
|
-
<div className='dropdown__menu dropdown__menu--has-head-foot' role='menu' ref={ref}
|
267
|
+
<div className='dropdown__menu dropdown__menu--has-head-foot' role='menu' ref={ref}>
|
298
268
|
<ul className='dropdown__menu-header'>
|
299
269
|
{headerElements}
|
300
270
|
</ul>
|
@@ -308,7 +278,7 @@ export const Dropdown = ({
|
|
308
278
|
);
|
309
279
|
} else if (header) {
|
310
280
|
return (
|
311
|
-
<div className='dropdown__menu dropdown__menu--has-head-foot' role='menu' ref={ref}
|
281
|
+
<div className='dropdown__menu dropdown__menu--has-head-foot' role='menu' ref={ref}>
|
312
282
|
<ul className='dropdown__menu-header'>
|
313
283
|
{headerElements}
|
314
284
|
</ul>
|
@@ -319,7 +289,7 @@ export const Dropdown = ({
|
|
319
289
|
);
|
320
290
|
} else if (footer) {
|
321
291
|
return (
|
322
|
-
<div className='dropdown__menu dropdown__menu--has-head-foot' role='menu' ref={ref}
|
292
|
+
<div className='dropdown__menu dropdown__menu--has-head-foot' role='menu' ref={ref}>
|
323
293
|
<ul className='dropdown__menu-body'>
|
324
294
|
{dropdownElements}
|
325
295
|
</ul>
|
@@ -330,7 +300,7 @@ export const Dropdown = ({
|
|
330
300
|
);
|
331
301
|
} else {
|
332
302
|
return (
|
333
|
-
<ul className='dropdown__menu' role='menu' ref={ref}
|
303
|
+
<ul className='dropdown__menu' role='menu' ref={ref}>
|
334
304
|
{dropdownElements}
|
335
305
|
</ul>
|
336
306
|
);
|
@@ -341,18 +311,93 @@ export const Dropdown = ({
|
|
341
311
|
};
|
342
312
|
|
343
313
|
const DropdownItem = ({
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
314
|
+
label,
|
315
|
+
icon,
|
316
|
+
active,
|
317
|
+
onSelect,
|
318
|
+
onChange,
|
319
|
+
}: IMenuItemRes) => {
|
349
320
|
return (
|
350
321
|
<li role='none' className={active ? 'dropdown__menu-item--active' : ''}>
|
351
|
-
<button tabIndex={0}
|
322
|
+
<button tabIndex={0}
|
323
|
+
role='menuitem'
|
324
|
+
onClick={() => {
|
325
|
+
setTimeout(() => {
|
326
|
+
onSelect();
|
327
|
+
});
|
328
|
+
if (onChange) {
|
329
|
+
onChange();
|
330
|
+
}
|
331
|
+
}}>
|
352
332
|
<i className={icon ? ('icon-' + icon) : ''}></i>
|
353
333
|
{label}
|
354
334
|
</button>
|
355
335
|
</li>
|
356
336
|
);
|
337
|
+
};
|
338
|
+
|
339
|
+
const DropdownItemWithSubmenu = ({
|
340
|
+
index,
|
341
|
+
item,
|
342
|
+
menuID,
|
343
|
+
subMenuItems,
|
344
|
+
onChange,
|
345
|
+
}: IMenuItem | any) => {
|
346
|
+
const [open, setOpen] = React.useState<undefined | boolean>(undefined);
|
347
|
+
|
348
|
+
const refButtonSubMenu = React.useRef(null);
|
349
|
+
const refSubMenu = React.useRef(null);
|
350
|
+
const placeholder = document.getElementById(menuID);
|
357
351
|
|
352
|
+
React.useEffect(() => {
|
353
|
+
let subMenuRef: any = refSubMenu.current;
|
354
|
+
let subToggleRef = refButtonSubMenu.current;
|
355
|
+
|
356
|
+
if (open === true) {
|
357
|
+
placeholder?.appendChild(subMenuRef);
|
358
|
+
subMenuRef.style.display = 'block';
|
359
|
+
} else if (open === false) {
|
360
|
+
placeholder?.removeChild(subMenuRef);
|
361
|
+
subMenuRef.style.display = 'none';
|
362
|
+
}
|
363
|
+
|
364
|
+
if (subMenuRef && subToggleRef) {
|
365
|
+
createPopper(subToggleRef, subMenuRef, {
|
366
|
+
placement: 'right-start',
|
367
|
+
});
|
368
|
+
}
|
369
|
+
}, [open]);
|
370
|
+
|
371
|
+
return (
|
372
|
+
<li key={index} ref={refButtonSubMenu}>
|
373
|
+
<div className='dropdown'
|
374
|
+
onMouseLeave={() => setOpen(false)}>
|
375
|
+
<button
|
376
|
+
className='dropdown__toggle dropdown-toggle'
|
377
|
+
aria-haspopup="menu"
|
378
|
+
tabIndex={0}
|
379
|
+
onClick={() => {
|
380
|
+
if (item.onSelect) {
|
381
|
+
setTimeout(() => {
|
382
|
+
item.onSelect();
|
383
|
+
});
|
384
|
+
}
|
385
|
+
if (onChange) {
|
386
|
+
onChange();
|
387
|
+
}
|
388
|
+
}}
|
389
|
+
onMouseOver={() => setOpen(true) }>
|
390
|
+
{item['icon'] ? <i className={'icon-' + item['icon']}></i> : null}
|
391
|
+
{item['label']}
|
392
|
+
</button>
|
393
|
+
<ul
|
394
|
+
role='menu'
|
395
|
+
ref={refSubMenu}
|
396
|
+
style={{display: 'none'}}
|
397
|
+
className='dropdown__menu'>
|
398
|
+
{subMenuItems}
|
399
|
+
</ul>
|
400
|
+
</div>
|
401
|
+
</li>
|
402
|
+
);
|
358
403
|
};
|