@sebgroup/green-react 1.0.0-beta.42 → 1.0.0-beta.44

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.d.ts CHANGED
@@ -9,3 +9,4 @@ export * from './lib/link/link';
9
9
  export * from './lib/badge/badge';
10
10
  export * from './lib/stepper/stepper';
11
11
  export * from './lib/dropdown/dropdown';
12
+ export * from './lib/datepicker/datepicker';
package/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import React, { useState, useLayoutEffect, useEffect, useMemo, useRef } from 'react';
3
- import { randomId, validateClassName, createStepper, createDropdown, dropdownValues } from '@sebgroup/extract';
3
+ import { randomId, validateClassName, createStepper, createDropdown, dropdownValues, createDatepicker, months, years } from '@sebgroup/extract';
4
4
 
5
5
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6
6
 
@@ -1094,15 +1094,15 @@ const ModalHeader = ({
1094
1094
  }, {
1095
1095
  children: [jsx("h3", {
1096
1096
  children: _header
1097
- }), jsx("button", Object.assign({
1097
+ }), jsxs("button", Object.assign({
1098
1098
  className: "close",
1099
1099
  onClick: handleClose
1100
1100
  }, {
1101
- children: jsx("span", Object.assign({
1101
+ children: [jsx("span", Object.assign({
1102
1102
  className: "sr-only"
1103
1103
  }, {
1104
1104
  children: "Close"
1105
- }))
1105
+ })), jsx("i", {})]
1106
1106
  }))]
1107
1107
  }));
1108
1108
  };
@@ -1780,17 +1780,23 @@ function Alert({
1780
1780
  if (!isCloseable) {
1781
1781
  setCloseButton(null);
1782
1782
  } else {
1783
- if (closeText) setCloseButton(jsx(Button, Object.assign({
1784
- variant: "ghost"
1783
+ if (closeText) setCloseButton(jsxs("button", Object.assign({
1784
+ className: "close"
1785
1785
  }, {
1786
- children: jsx("span", Object.assign({
1786
+ children: [jsx("span", Object.assign({
1787
1787
  className: "sr-only"
1788
1788
  }, {
1789
1789
  children: closeText
1790
- }))
1791
- })));else setCloseButton(jsx("button", {
1790
+ })), jsx("i", {})]
1791
+ })));else setCloseButton(jsxs("button", Object.assign({
1792
1792
  className: "close"
1793
- }));
1793
+ }, {
1794
+ children: [jsx("span", Object.assign({
1795
+ className: "sr-only"
1796
+ }, {
1797
+ children: "Close"
1798
+ })), jsx("i", {})]
1799
+ })));
1794
1800
  }
1795
1801
  }, [isCloseable, closeText]);
1796
1802
  return jsxs("div", Object.assign({
@@ -1837,6 +1843,7 @@ const ButtonGroup = ({
1837
1843
  });
1838
1844
  };
1839
1845
 
1846
+ /* eslint-disable-next-line */
1840
1847
  const validateInputValue = (target, rules, setError) => {
1841
1848
  const errorMessage = validateInputValueErrors(rules, target);
1842
1849
  errorMessage ? setErrorInsert(setError, target.name) : setErrorRemove(setError, target.name);
@@ -1854,17 +1861,24 @@ const validateInputValueErrors = (rules, target) => {
1854
1861
 
1855
1862
  return validateTextInputValues(value, rules);
1856
1863
  };
1864
+ /* eslint-disable-next-line */
1865
+
1857
1866
 
1858
1867
  const setErrorInsert = (setError, name) => {
1868
+ /* eslint-disable-next-line */
1859
1869
  setError(errors => {
1860
1870
  return Object.assign(Object.assign({}, errors), {
1861
1871
  [name]: true
1862
1872
  });
1863
1873
  });
1864
1874
  };
1875
+ /* eslint-disable-next-line */
1876
+
1865
1877
 
1866
1878
  const setErrorRemove = (setError, name) => {
1879
+ /* eslint-disable-next-line */
1867
1880
  setError(errors => {
1881
+ /* eslint-disable-next-line */
1868
1882
  const newError = Object.assign({}, errors);
1869
1883
  delete newError[name];
1870
1884
  return newError;
@@ -1898,9 +1912,15 @@ const FormProvider = _a => {
1898
1912
  onFormSubmit
1899
1913
  } = _a,
1900
1914
  props = __rest(_a, ["children", "direction", "formSize", "onSubmit", "onFormSubmit"]);
1915
+ /* eslint-disable-next-line */
1916
+
1901
1917
 
1902
1918
  const [values, setValues] = React.useState();
1919
+ /* eslint-disable-next-line */
1920
+
1903
1921
  const [errors, setErrors] = React.useState();
1922
+ /* eslint-disable-next-line */
1923
+
1904
1924
  const [fields, setFields] = React.useState({});
1905
1925
 
1906
1926
  const formSubmit = event => {
@@ -1960,21 +1980,29 @@ const FormItems = ({
1960
1980
  errors
1961
1981
  } = useFormContext();
1962
1982
  React.useEffect(() => {
1983
+ /* eslint-disable-next-line */
1963
1984
  setFields(fields => Object.assign(Object.assign({}, fields), {
1964
1985
  [name]: validate === null || validate === void 0 ? void 0 : validate.rules
1965
1986
  }));
1987
+ /* eslint-disable-next-line */
1966
1988
 
1967
1989
  const removeValues = values => {
1990
+ /* eslint-disable-next-line */
1968
1991
  const newValues = Object.assign({}, values);
1969
1992
  delete newValues[name];
1970
1993
  return newValues;
1971
1994
  };
1972
1995
 
1973
1996
  return () => {
1997
+ /* eslint-disable-next-line */
1974
1998
  setFields(fields => removeValues(fields));
1999
+ /* eslint-disable-next-line */
2000
+
1975
2001
  setValues(values => removeValues(values));
2002
+ /* eslint-disable-next-line */
2003
+
1976
2004
  setErrors(errors => removeValues(errors));
1977
- };
2005
+ }; // eslint-disable-next-line react-hooks/exhaustive-deps
1978
2006
  }, []);
1979
2007
 
1980
2008
  const onChange = event => {
@@ -1989,6 +2017,8 @@ const FormItems = ({
1989
2017
 
1990
2018
  if (type === 'checkbox') {
1991
2019
  inputValue = checked ? value : null;
2020
+ /* eslint-disable-next-line */
2021
+
1992
2022
  checked ? setValues(values => Object.assign(Object.assign({}, values), {
1993
2023
  [name]: value
1994
2024
  })) : setValues(values => Object.assign(Object.assign({}, values), {
@@ -1996,6 +2026,8 @@ const FormItems = ({
1996
2026
  }));
1997
2027
  } else {
1998
2028
  inputValue = value;
2029
+ /* eslint-disable-next-line */
2030
+
1999
2031
  setValues(values => Object.assign(Object.assign({}, values), {
2000
2032
  [name]: value
2001
2033
  }));
@@ -2008,6 +2040,8 @@ const FormItems = ({
2008
2040
  checked
2009
2041
  }, validate === null || validate === void 0 ? void 0 : validate.rules, setErrors);
2010
2042
  };
2043
+ /* eslint-disable-next-line */
2044
+
2011
2045
 
2012
2046
  return /*#__PURE__*/React.cloneElement(children, {
2013
2047
  validator: (errors === null || errors === void 0 ? void 0 : errors[name]) && validate,
@@ -2160,26 +2194,24 @@ const Checkbox = _a => {
2160
2194
 
2161
2195
  const inputProps = useInput(props, onChange);
2162
2196
  const validatorClassName = validateClassName(validator === null || validator === void 0 ? void 0 : validator.indicator);
2163
- return jsx(Fragment, {
2164
- children: jsxs("div", Object.assign({
2165
- className: "form-group"
2197
+ return jsxs("div", Object.assign({
2198
+ className: "form-group"
2199
+ }, {
2200
+ children: [jsxs("label", Object.assign({
2201
+ htmlFor: inputProps.id,
2202
+ className: `form-control ${validatorClassName}`
2166
2203
  }, {
2167
- children: [jsxs("label", Object.assign({
2168
- htmlFor: inputProps.id,
2169
- className: `form-control ${validatorClassName}`
2170
- }, {
2171
- children: [label, jsx("input", Object.assign({
2172
- type: "checkbox"
2173
- }, inputProps, {
2174
- className: validatorClassName
2175
- })), jsx("i", {})]
2176
- })), validator && jsx("span", Object.assign({
2177
- className: "form-info"
2178
- }, {
2179
- children: validator.message
2180
- }))]
2181
- }))
2182
- });
2204
+ children: [label, jsx("input", Object.assign({
2205
+ type: "checkbox"
2206
+ }, inputProps, {
2207
+ className: validatorClassName
2208
+ })), jsx("i", {})]
2209
+ })), validator && jsx("span", Object.assign({
2210
+ className: "form-info"
2211
+ }, {
2212
+ children: validator.message
2213
+ }))]
2214
+ }));
2183
2215
  };
2184
2216
  const RadioButton = /*#__PURE__*/React.forwardRef((_a, ref) => {
2185
2217
  var {
@@ -2358,7 +2390,8 @@ const RadioGroup = ({
2358
2390
  } else {
2359
2391
  // eslint-disable-next-line @typescript-eslint/no-empty-function
2360
2392
  return () => {};
2361
- }
2393
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
2394
+
2362
2395
  }, []);
2363
2396
  return jsxs("div", Object.assign({
2364
2397
  className: "form-group"
@@ -2469,7 +2502,7 @@ const Link = _a => {
2469
2502
  role: button ? 'button' : undefined,
2470
2503
  className: className
2471
2504
  }, props);
2472
- setAnchorProps(newProps);
2505
+ setAnchorProps(newProps); // eslint-disable-next-line react-hooks/exhaustive-deps
2473
2506
  }, [button]);
2474
2507
  return jsx("a", Object.assign({}, anchorProps, {
2475
2508
  children: children
@@ -2554,7 +2587,7 @@ function Badge(_a) {
2554
2587
  if (!!customColor || !!customBackgroundColor) {
2555
2588
  setType('');
2556
2589
  }
2557
- }, []);
2590
+ }, [badgeType, customColor, customBackgroundColor]);
2558
2591
  return !isClosed ? jsxs("span", Object.assign({}, props, {
2559
2592
  className: `badge ${type}`,
2560
2593
  style: {
@@ -2564,12 +2597,12 @@ function Badge(_a) {
2564
2597
  }, {
2565
2598
  children: [jsx("strong", {
2566
2599
  children: children
2567
- }), isCloseable && jsx("button", Object.assign({
2600
+ }), isCloseable && jsxs("button", Object.assign({
2568
2601
  type: "button",
2569
2602
  className: "close",
2570
2603
  onClick: () => setIsClosed(true)
2571
2604
  }, {
2572
- children: closeText
2605
+ children: [closeText, jsx("i", {})]
2573
2606
  }))]
2574
2607
  })) : null;
2575
2608
  }
@@ -2599,16 +2632,20 @@ const useStepper = ({
2599
2632
  min,
2600
2633
  max,
2601
2634
  step: _step
2602
- });
2635
+ }); // eslint-disable-next-line react-hooks/exhaustive-deps
2636
+
2603
2637
  useEffect(() => {
2604
2638
  if (max !== data.max) stepper.setMax(max);
2605
- }, [stepper, max]);
2639
+ }, [stepper, max]); // eslint-disable-next-line react-hooks/exhaustive-deps
2640
+
2606
2641
  useEffect(() => {
2607
2642
  if (min !== data.min) stepper.setMin(min);
2608
- }, [stepper, min]);
2643
+ }, [stepper, min]); // eslint-disable-next-line react-hooks/exhaustive-deps
2644
+
2609
2645
  useEffect(() => {
2610
2646
  if (_step !== data.step) stepper.setStep(_step || 1);
2611
- }, [stepper, _step]);
2647
+ }, [stepper, _step]); // eslint-disable-next-line react-hooks/exhaustive-deps
2648
+
2612
2649
  useEffect(() => {
2613
2650
  if (_value !== data.value) stepper.setValue(_value || 0, false);
2614
2651
  }, [stepper, _value]);
@@ -2620,7 +2657,7 @@ const useStepper = ({
2620
2657
  max,
2621
2658
  step: _step,
2622
2659
  onChange
2623
- }, setData));
2660
+ }, setData)); // eslint-disable-next-line react-hooks/exhaustive-deps
2624
2661
  }, []);
2625
2662
  return [stepper, data];
2626
2663
  };
@@ -2935,4 +2972,176 @@ const Dropdown = ({
2935
2972
  }));
2936
2973
  };
2937
2974
 
2938
- export { Alert, Badge, Button, ButtonGroup, Card, Checkbox, Dropdown, EmailInput, Flexbox, Form, FormItems, Group, Link, List, Modal, Navbar, NumberInput, RadioButton, RadioGroup, RenderInput, Stepper, Text, TextInput };
2975
+ const useDatepicker = (datepickerRef, datepickerDialogRef, dateInputRef, datepickerTriggerRef, options = {}) => {
2976
+ const dataStub = {
2977
+ formattedSelectedDate: '',
2978
+ calendar: {
2979
+ headers: [],
2980
+ calendarGrid: []
2981
+ }
2982
+ };
2983
+ const [data, setData] = useState(dataStub);
2984
+ const [state, setState] = useState({
2985
+ isActive: false
2986
+ });
2987
+ const datepickerStub = {};
2988
+ const [datepicker, setDatepicker] = useState(datepickerStub);
2989
+ useEffect(() => {
2990
+ if (!datepicker.open && datepickerRef.current && datepickerDialogRef.current && dateInputRef.current && datepickerTriggerRef.current) {
2991
+ setDatepicker(createDatepicker((data, state) => {
2992
+ if (data) setData(data);
2993
+ if (state) setState(state);
2994
+ }, options, datepickerRef.current, datepickerDialogRef.current, dateInputRef.current, datepickerTriggerRef.current));
2995
+ }
2996
+ }, [datepicker, datepickerRef, datepickerDialogRef, dateInputRef, datepickerTriggerRef, options]);
2997
+ return {
2998
+ datepicker,
2999
+ data,
3000
+ state
3001
+ };
3002
+ };
3003
+
3004
+ const Datepicker = (options = {}) => {
3005
+ const [uuid] = useState(randomId());
3006
+ const id = `sgr-datepicker-${uuid}`;
3007
+ const datepickerRef = useRef(null);
3008
+ const datepickerTriggerRef = useRef(null);
3009
+ const datepickerDialogRef = useRef(null);
3010
+ const dateInputRef = useRef(null);
3011
+ const {
3012
+ datepicker,
3013
+ data,
3014
+ state
3015
+ } = useDatepicker(datepickerRef, datepickerDialogRef, dateInputRef, datepickerTriggerRef, options);
3016
+ useEffect(() => {
3017
+ var _a;
3018
+
3019
+ const selDateSub = (_a = datepicker.selectedDate$) === null || _a === void 0 ? void 0 : _a.subscribe(newDate => options.onChange && options.onChange(newDate));
3020
+ return () => selDateSub === null || selDateSub === void 0 ? void 0 : selDateSub.unsubscribe();
3021
+ }, [datepicker, options]);
3022
+
3023
+ const classNames = day => Object.entries({
3024
+ disabled: !day.currentMonth,
3025
+ 'sg-date-today': day.today // 'sg-date-holiday': day.holiday,
3026
+
3027
+ }).map(([className, add]) => add ? className : '').join(' ');
3028
+
3029
+ return jsxs(Fragment, {
3030
+ children: [jsxs("div", Object.assign({
3031
+ className: "form-group"
3032
+ }, {
3033
+ children: [jsx("label", Object.assign({
3034
+ htmlFor: id
3035
+ }, {
3036
+ children: "Date"
3037
+ })), jsxs("div", Object.assign({
3038
+ className: "group",
3039
+ ref: datepickerRef
3040
+ }, {
3041
+ children: [jsx("input", {
3042
+ ref: dateInputRef,
3043
+ id: id,
3044
+ type: "text",
3045
+ placeholder: "yyyy-mm-dd",
3046
+ value: data.formattedSelectedDate,
3047
+ onChange: e => datepicker.select(e.target.value)
3048
+ }), jsx("button", Object.assign({
3049
+ ref: datepickerTriggerRef,
3050
+ type: "button",
3051
+ className: "primary",
3052
+ onClick: () => datepicker.toggle()
3053
+ }, {
3054
+ children: jsx("i", Object.assign({
3055
+ className: "sg-icon sg-icon-calendar"
3056
+ }, {
3057
+ children: "Select date"
3058
+ }))
3059
+ }))]
3060
+ })), jsx("span", Object.assign({
3061
+ className: "form-info"
3062
+ }, {
3063
+ children: "Select a date"
3064
+ }))]
3065
+ })), jsx("div", Object.assign({
3066
+ ref: datepickerDialogRef,
3067
+ className: `popover popover-datepicker ${state.isActive ? 'active' : ''}`,
3068
+ role: "dialog",
3069
+ "aria-modal": "true",
3070
+ "aria-label": "Choose Date"
3071
+ }, {
3072
+ children: state.isActive && jsxs("div", Object.assign({
3073
+ className: "sg-date"
3074
+ }, {
3075
+ children: [jsxs("header", {
3076
+ children: [jsx("button", Object.assign({
3077
+ className: "link",
3078
+ onClick: () => datepicker.sub(1, 'months')
3079
+ }, {
3080
+ children: jsx("i", Object.assign({
3081
+ className: "sg-icon sg-icon-previous"
3082
+ }, {
3083
+ children: "Previous month"
3084
+ }))
3085
+ })), jsx(Dropdown, {
3086
+ options: months({}),
3087
+ texts: {
3088
+ placeholder: data.monthName
3089
+ }
3090
+ }), jsx(Dropdown, {
3091
+ options: years({}),
3092
+ texts: {
3093
+ placeholder: data.year + ''
3094
+ }
3095
+ }), jsx("button", Object.assign({
3096
+ className: "link",
3097
+ onClick: () => datepicker.add(1, 'months')
3098
+ }, {
3099
+ children: jsx("i", Object.assign({
3100
+ className: "sg-icon sg-icon-next"
3101
+ }, {
3102
+ children: "Next month"
3103
+ }))
3104
+ }))]
3105
+ }), jsx("main", {
3106
+ children: jsxs("table", Object.assign({
3107
+ role: "grid"
3108
+ }, {
3109
+ children: [jsx("thead", {
3110
+ children: jsx("tr", {
3111
+ children: data.calendar.headers.map((header, ix) => jsx("th", Object.assign({
3112
+ scope: "col",
3113
+ abbr: header.abbr,
3114
+ className: header.type === 'week' ? 'sg-week-header' : 'sg-day-header'
3115
+ }, {
3116
+ children: header.displayText
3117
+ }), `week_${ix}`))
3118
+ })
3119
+ }), jsx("tbody", {
3120
+ children: data.calendar.calendarGrid.map((week, ix) => jsxs("tr", {
3121
+ children: [data.calendar.weekNumbers ? jsx("th", Object.assign({
3122
+ className: "sg-week-number"
3123
+ }, {
3124
+ children: data.calendar.weekNumbers[ix]
3125
+ })) : '', week.map(day => jsx("td", Object.assign({
3126
+ "data-date": day.formattedDate,
3127
+ className: classNames(day),
3128
+ title: day.today ? 'Today' : '',
3129
+ tabIndex: day.highlighted || day.selected && !(data === null || data === void 0 ? void 0 : data.highlightedDate) || day.today && !(data === null || data === void 0 ? void 0 : data.highlightedDate) && !(data === null || data === void 0 ? void 0 : data.selectedDate) ? 0 : -1,
3130
+ role: day.selected ? 'gridcell' : undefined,
3131
+ "aria-selected": day.selected && !(data === null || data === void 0 ? void 0 : data.highlightedDate) ? true : undefined,
3132
+ onClick: () => {
3133
+ day.currentMonth && datepicker.select(day.date);
3134
+ }
3135
+ }, {
3136
+ children: day.day
3137
+ }), day.day))]
3138
+ }, `week_${ix}`))
3139
+ })]
3140
+ }))
3141
+ })]
3142
+ }))
3143
+ }))]
3144
+ });
3145
+ };
3146
+
3147
+ export { Alert, Badge, Button, ButtonGroup, Card, Checkbox, Datepicker, Dropdown, EmailInput, Flexbox, Form, FormItems, Group, Link, List, Modal, Navbar, NumberInput, RadioButton, RadioGroup, RenderInput, Stepper, Text, TextInput };
package/index.umd.js CHANGED
@@ -1100,15 +1100,15 @@
1100
1100
  }, {
1101
1101
  children: [jsxRuntime.jsx("h3", {
1102
1102
  children: _header
1103
- }), jsxRuntime.jsx("button", Object.assign({
1103
+ }), jsxRuntime.jsxs("button", Object.assign({
1104
1104
  className: "close",
1105
1105
  onClick: handleClose
1106
1106
  }, {
1107
- children: jsxRuntime.jsx("span", Object.assign({
1107
+ children: [jsxRuntime.jsx("span", Object.assign({
1108
1108
  className: "sr-only"
1109
1109
  }, {
1110
1110
  children: "Close"
1111
- }))
1111
+ })), jsxRuntime.jsx("i", {})]
1112
1112
  }))]
1113
1113
  }));
1114
1114
  };
@@ -1786,17 +1786,23 @@
1786
1786
  if (!isCloseable) {
1787
1787
  setCloseButton(null);
1788
1788
  } else {
1789
- if (closeText) setCloseButton(jsxRuntime.jsx(Button, Object.assign({
1790
- variant: "ghost"
1789
+ if (closeText) setCloseButton(jsxRuntime.jsxs("button", Object.assign({
1790
+ className: "close"
1791
1791
  }, {
1792
- children: jsxRuntime.jsx("span", Object.assign({
1792
+ children: [jsxRuntime.jsx("span", Object.assign({
1793
1793
  className: "sr-only"
1794
1794
  }, {
1795
1795
  children: closeText
1796
- }))
1797
- })));else setCloseButton(jsxRuntime.jsx("button", {
1796
+ })), jsxRuntime.jsx("i", {})]
1797
+ })));else setCloseButton(jsxRuntime.jsxs("button", Object.assign({
1798
1798
  className: "close"
1799
- }));
1799
+ }, {
1800
+ children: [jsxRuntime.jsx("span", Object.assign({
1801
+ className: "sr-only"
1802
+ }, {
1803
+ children: "Close"
1804
+ })), jsxRuntime.jsx("i", {})]
1805
+ })));
1800
1806
  }
1801
1807
  }, [isCloseable, closeText]);
1802
1808
  return jsxRuntime.jsxs("div", Object.assign({
@@ -1843,6 +1849,7 @@
1843
1849
  });
1844
1850
  };
1845
1851
 
1852
+ /* eslint-disable-next-line */
1846
1853
  const validateInputValue = (target, rules, setError) => {
1847
1854
  const errorMessage = validateInputValueErrors(rules, target);
1848
1855
  errorMessage ? setErrorInsert(setError, target.name) : setErrorRemove(setError, target.name);
@@ -1860,17 +1867,24 @@
1860
1867
 
1861
1868
  return validateTextInputValues(value, rules);
1862
1869
  };
1870
+ /* eslint-disable-next-line */
1871
+
1863
1872
 
1864
1873
  const setErrorInsert = (setError, name) => {
1874
+ /* eslint-disable-next-line */
1865
1875
  setError(errors => {
1866
1876
  return Object.assign(Object.assign({}, errors), {
1867
1877
  [name]: true
1868
1878
  });
1869
1879
  });
1870
1880
  };
1881
+ /* eslint-disable-next-line */
1882
+
1871
1883
 
1872
1884
  const setErrorRemove = (setError, name) => {
1885
+ /* eslint-disable-next-line */
1873
1886
  setError(errors => {
1887
+ /* eslint-disable-next-line */
1874
1888
  const newError = Object.assign({}, errors);
1875
1889
  delete newError[name];
1876
1890
  return newError;
@@ -1904,9 +1918,15 @@
1904
1918
  onFormSubmit
1905
1919
  } = _a,
1906
1920
  props = __rest(_a, ["children", "direction", "formSize", "onSubmit", "onFormSubmit"]);
1921
+ /* eslint-disable-next-line */
1922
+
1907
1923
 
1908
1924
  const [values, setValues] = React__default["default"].useState();
1925
+ /* eslint-disable-next-line */
1926
+
1909
1927
  const [errors, setErrors] = React__default["default"].useState();
1928
+ /* eslint-disable-next-line */
1929
+
1910
1930
  const [fields, setFields] = React__default["default"].useState({});
1911
1931
 
1912
1932
  const formSubmit = event => {
@@ -1966,21 +1986,29 @@
1966
1986
  errors
1967
1987
  } = useFormContext();
1968
1988
  React__default["default"].useEffect(() => {
1989
+ /* eslint-disable-next-line */
1969
1990
  setFields(fields => Object.assign(Object.assign({}, fields), {
1970
1991
  [name]: validate === null || validate === void 0 ? void 0 : validate.rules
1971
1992
  }));
1993
+ /* eslint-disable-next-line */
1972
1994
 
1973
1995
  const removeValues = values => {
1996
+ /* eslint-disable-next-line */
1974
1997
  const newValues = Object.assign({}, values);
1975
1998
  delete newValues[name];
1976
1999
  return newValues;
1977
2000
  };
1978
2001
 
1979
2002
  return () => {
2003
+ /* eslint-disable-next-line */
1980
2004
  setFields(fields => removeValues(fields));
2005
+ /* eslint-disable-next-line */
2006
+
1981
2007
  setValues(values => removeValues(values));
2008
+ /* eslint-disable-next-line */
2009
+
1982
2010
  setErrors(errors => removeValues(errors));
1983
- };
2011
+ }; // eslint-disable-next-line react-hooks/exhaustive-deps
1984
2012
  }, []);
1985
2013
 
1986
2014
  const onChange = event => {
@@ -1995,6 +2023,8 @@
1995
2023
 
1996
2024
  if (type === 'checkbox') {
1997
2025
  inputValue = checked ? value : null;
2026
+ /* eslint-disable-next-line */
2027
+
1998
2028
  checked ? setValues(values => Object.assign(Object.assign({}, values), {
1999
2029
  [name]: value
2000
2030
  })) : setValues(values => Object.assign(Object.assign({}, values), {
@@ -2002,6 +2032,8 @@
2002
2032
  }));
2003
2033
  } else {
2004
2034
  inputValue = value;
2035
+ /* eslint-disable-next-line */
2036
+
2005
2037
  setValues(values => Object.assign(Object.assign({}, values), {
2006
2038
  [name]: value
2007
2039
  }));
@@ -2014,6 +2046,8 @@
2014
2046
  checked
2015
2047
  }, validate === null || validate === void 0 ? void 0 : validate.rules, setErrors);
2016
2048
  };
2049
+ /* eslint-disable-next-line */
2050
+
2017
2051
 
2018
2052
  return /*#__PURE__*/React__default["default"].cloneElement(children, {
2019
2053
  validator: (errors === null || errors === void 0 ? void 0 : errors[name]) && validate,
@@ -2166,26 +2200,24 @@
2166
2200
 
2167
2201
  const inputProps = useInput(props, onChange);
2168
2202
  const validatorClassName = extract.validateClassName(validator === null || validator === void 0 ? void 0 : validator.indicator);
2169
- return jsxRuntime.jsx(jsxRuntime.Fragment, {
2170
- children: jsxRuntime.jsxs("div", Object.assign({
2171
- className: "form-group"
2203
+ return jsxRuntime.jsxs("div", Object.assign({
2204
+ className: "form-group"
2205
+ }, {
2206
+ children: [jsxRuntime.jsxs("label", Object.assign({
2207
+ htmlFor: inputProps.id,
2208
+ className: `form-control ${validatorClassName}`
2172
2209
  }, {
2173
- children: [jsxRuntime.jsxs("label", Object.assign({
2174
- htmlFor: inputProps.id,
2175
- className: `form-control ${validatorClassName}`
2176
- }, {
2177
- children: [label, jsxRuntime.jsx("input", Object.assign({
2178
- type: "checkbox"
2179
- }, inputProps, {
2180
- className: validatorClassName
2181
- })), jsxRuntime.jsx("i", {})]
2182
- })), validator && jsxRuntime.jsx("span", Object.assign({
2183
- className: "form-info"
2184
- }, {
2185
- children: validator.message
2186
- }))]
2187
- }))
2188
- });
2210
+ children: [label, jsxRuntime.jsx("input", Object.assign({
2211
+ type: "checkbox"
2212
+ }, inputProps, {
2213
+ className: validatorClassName
2214
+ })), jsxRuntime.jsx("i", {})]
2215
+ })), validator && jsxRuntime.jsx("span", Object.assign({
2216
+ className: "form-info"
2217
+ }, {
2218
+ children: validator.message
2219
+ }))]
2220
+ }));
2189
2221
  };
2190
2222
  const RadioButton = /*#__PURE__*/React__default["default"].forwardRef((_a, ref) => {
2191
2223
  var {
@@ -2364,7 +2396,8 @@
2364
2396
  } else {
2365
2397
  // eslint-disable-next-line @typescript-eslint/no-empty-function
2366
2398
  return () => {};
2367
- }
2399
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
2400
+
2368
2401
  }, []);
2369
2402
  return jsxRuntime.jsxs("div", Object.assign({
2370
2403
  className: "form-group"
@@ -2475,7 +2508,7 @@
2475
2508
  role: button ? 'button' : undefined,
2476
2509
  className: className
2477
2510
  }, props);
2478
- setAnchorProps(newProps);
2511
+ setAnchorProps(newProps); // eslint-disable-next-line react-hooks/exhaustive-deps
2479
2512
  }, [button]);
2480
2513
  return jsxRuntime.jsx("a", Object.assign({}, anchorProps, {
2481
2514
  children: children
@@ -2560,7 +2593,7 @@
2560
2593
  if (!!customColor || !!customBackgroundColor) {
2561
2594
  setType('');
2562
2595
  }
2563
- }, []);
2596
+ }, [badgeType, customColor, customBackgroundColor]);
2564
2597
  return !isClosed ? jsxRuntime.jsxs("span", Object.assign({}, props, {
2565
2598
  className: `badge ${type}`,
2566
2599
  style: {
@@ -2570,12 +2603,12 @@
2570
2603
  }, {
2571
2604
  children: [jsxRuntime.jsx("strong", {
2572
2605
  children: children
2573
- }), isCloseable && jsxRuntime.jsx("button", Object.assign({
2606
+ }), isCloseable && jsxRuntime.jsxs("button", Object.assign({
2574
2607
  type: "button",
2575
2608
  className: "close",
2576
2609
  onClick: () => setIsClosed(true)
2577
2610
  }, {
2578
- children: closeText
2611
+ children: [closeText, jsxRuntime.jsx("i", {})]
2579
2612
  }))]
2580
2613
  })) : null;
2581
2614
  }
@@ -2605,16 +2638,20 @@
2605
2638
  min,
2606
2639
  max,
2607
2640
  step: _step
2608
- });
2641
+ }); // eslint-disable-next-line react-hooks/exhaustive-deps
2642
+
2609
2643
  React.useEffect(() => {
2610
2644
  if (max !== data.max) stepper.setMax(max);
2611
- }, [stepper, max]);
2645
+ }, [stepper, max]); // eslint-disable-next-line react-hooks/exhaustive-deps
2646
+
2612
2647
  React.useEffect(() => {
2613
2648
  if (min !== data.min) stepper.setMin(min);
2614
- }, [stepper, min]);
2649
+ }, [stepper, min]); // eslint-disable-next-line react-hooks/exhaustive-deps
2650
+
2615
2651
  React.useEffect(() => {
2616
2652
  if (_step !== data.step) stepper.setStep(_step || 1);
2617
- }, [stepper, _step]);
2653
+ }, [stepper, _step]); // eslint-disable-next-line react-hooks/exhaustive-deps
2654
+
2618
2655
  React.useEffect(() => {
2619
2656
  if (_value !== data.value) stepper.setValue(_value || 0, false);
2620
2657
  }, [stepper, _value]);
@@ -2626,7 +2663,7 @@
2626
2663
  max,
2627
2664
  step: _step,
2628
2665
  onChange
2629
- }, setData));
2666
+ }, setData)); // eslint-disable-next-line react-hooks/exhaustive-deps
2630
2667
  }, []);
2631
2668
  return [stepper, data];
2632
2669
  };
@@ -2941,12 +2978,185 @@
2941
2978
  }));
2942
2979
  };
2943
2980
 
2981
+ const useDatepicker = (datepickerRef, datepickerDialogRef, dateInputRef, datepickerTriggerRef, options = {}) => {
2982
+ const dataStub = {
2983
+ formattedSelectedDate: '',
2984
+ calendar: {
2985
+ headers: [],
2986
+ calendarGrid: []
2987
+ }
2988
+ };
2989
+ const [data, setData] = React.useState(dataStub);
2990
+ const [state, setState] = React.useState({
2991
+ isActive: false
2992
+ });
2993
+ const datepickerStub = {};
2994
+ const [datepicker, setDatepicker] = React.useState(datepickerStub);
2995
+ React.useEffect(() => {
2996
+ if (!datepicker.open && datepickerRef.current && datepickerDialogRef.current && dateInputRef.current && datepickerTriggerRef.current) {
2997
+ setDatepicker(extract.createDatepicker((data, state) => {
2998
+ if (data) setData(data);
2999
+ if (state) setState(state);
3000
+ }, options, datepickerRef.current, datepickerDialogRef.current, dateInputRef.current, datepickerTriggerRef.current));
3001
+ }
3002
+ }, [datepicker, datepickerRef, datepickerDialogRef, dateInputRef, datepickerTriggerRef, options]);
3003
+ return {
3004
+ datepicker,
3005
+ data,
3006
+ state
3007
+ };
3008
+ };
3009
+
3010
+ const Datepicker = (options = {}) => {
3011
+ const [uuid] = React.useState(extract.randomId());
3012
+ const id = `sgr-datepicker-${uuid}`;
3013
+ const datepickerRef = React.useRef(null);
3014
+ const datepickerTriggerRef = React.useRef(null);
3015
+ const datepickerDialogRef = React.useRef(null);
3016
+ const dateInputRef = React.useRef(null);
3017
+ const {
3018
+ datepicker,
3019
+ data,
3020
+ state
3021
+ } = useDatepicker(datepickerRef, datepickerDialogRef, dateInputRef, datepickerTriggerRef, options);
3022
+ React.useEffect(() => {
3023
+ var _a;
3024
+
3025
+ const selDateSub = (_a = datepicker.selectedDate$) === null || _a === void 0 ? void 0 : _a.subscribe(newDate => options.onChange && options.onChange(newDate));
3026
+ return () => selDateSub === null || selDateSub === void 0 ? void 0 : selDateSub.unsubscribe();
3027
+ }, [datepicker, options]);
3028
+
3029
+ const classNames = day => Object.entries({
3030
+ disabled: !day.currentMonth,
3031
+ 'sg-date-today': day.today // 'sg-date-holiday': day.holiday,
3032
+
3033
+ }).map(([className, add]) => add ? className : '').join(' ');
3034
+
3035
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
3036
+ children: [jsxRuntime.jsxs("div", Object.assign({
3037
+ className: "form-group"
3038
+ }, {
3039
+ children: [jsxRuntime.jsx("label", Object.assign({
3040
+ htmlFor: id
3041
+ }, {
3042
+ children: "Date"
3043
+ })), jsxRuntime.jsxs("div", Object.assign({
3044
+ className: "group",
3045
+ ref: datepickerRef
3046
+ }, {
3047
+ children: [jsxRuntime.jsx("input", {
3048
+ ref: dateInputRef,
3049
+ id: id,
3050
+ type: "text",
3051
+ placeholder: "yyyy-mm-dd",
3052
+ value: data.formattedSelectedDate,
3053
+ onChange: e => datepicker.select(e.target.value)
3054
+ }), jsxRuntime.jsx("button", Object.assign({
3055
+ ref: datepickerTriggerRef,
3056
+ type: "button",
3057
+ className: "primary",
3058
+ onClick: () => datepicker.toggle()
3059
+ }, {
3060
+ children: jsxRuntime.jsx("i", Object.assign({
3061
+ className: "sg-icon sg-icon-calendar"
3062
+ }, {
3063
+ children: "Select date"
3064
+ }))
3065
+ }))]
3066
+ })), jsxRuntime.jsx("span", Object.assign({
3067
+ className: "form-info"
3068
+ }, {
3069
+ children: "Select a date"
3070
+ }))]
3071
+ })), jsxRuntime.jsx("div", Object.assign({
3072
+ ref: datepickerDialogRef,
3073
+ className: `popover popover-datepicker ${state.isActive ? 'active' : ''}`,
3074
+ role: "dialog",
3075
+ "aria-modal": "true",
3076
+ "aria-label": "Choose Date"
3077
+ }, {
3078
+ children: state.isActive && jsxRuntime.jsxs("div", Object.assign({
3079
+ className: "sg-date"
3080
+ }, {
3081
+ children: [jsxRuntime.jsxs("header", {
3082
+ children: [jsxRuntime.jsx("button", Object.assign({
3083
+ className: "link",
3084
+ onClick: () => datepicker.sub(1, 'months')
3085
+ }, {
3086
+ children: jsxRuntime.jsx("i", Object.assign({
3087
+ className: "sg-icon sg-icon-previous"
3088
+ }, {
3089
+ children: "Previous month"
3090
+ }))
3091
+ })), jsxRuntime.jsx(Dropdown, {
3092
+ options: extract.months({}),
3093
+ texts: {
3094
+ placeholder: data.monthName
3095
+ }
3096
+ }), jsxRuntime.jsx(Dropdown, {
3097
+ options: extract.years({}),
3098
+ texts: {
3099
+ placeholder: data.year + ''
3100
+ }
3101
+ }), jsxRuntime.jsx("button", Object.assign({
3102
+ className: "link",
3103
+ onClick: () => datepicker.add(1, 'months')
3104
+ }, {
3105
+ children: jsxRuntime.jsx("i", Object.assign({
3106
+ className: "sg-icon sg-icon-next"
3107
+ }, {
3108
+ children: "Next month"
3109
+ }))
3110
+ }))]
3111
+ }), jsxRuntime.jsx("main", {
3112
+ children: jsxRuntime.jsxs("table", Object.assign({
3113
+ role: "grid"
3114
+ }, {
3115
+ children: [jsxRuntime.jsx("thead", {
3116
+ children: jsxRuntime.jsx("tr", {
3117
+ children: data.calendar.headers.map((header, ix) => jsxRuntime.jsx("th", Object.assign({
3118
+ scope: "col",
3119
+ abbr: header.abbr,
3120
+ className: header.type === 'week' ? 'sg-week-header' : 'sg-day-header'
3121
+ }, {
3122
+ children: header.displayText
3123
+ }), `week_${ix}`))
3124
+ })
3125
+ }), jsxRuntime.jsx("tbody", {
3126
+ children: data.calendar.calendarGrid.map((week, ix) => jsxRuntime.jsxs("tr", {
3127
+ children: [data.calendar.weekNumbers ? jsxRuntime.jsx("th", Object.assign({
3128
+ className: "sg-week-number"
3129
+ }, {
3130
+ children: data.calendar.weekNumbers[ix]
3131
+ })) : '', week.map(day => jsxRuntime.jsx("td", Object.assign({
3132
+ "data-date": day.formattedDate,
3133
+ className: classNames(day),
3134
+ title: day.today ? 'Today' : '',
3135
+ tabIndex: day.highlighted || day.selected && !(data === null || data === void 0 ? void 0 : data.highlightedDate) || day.today && !(data === null || data === void 0 ? void 0 : data.highlightedDate) && !(data === null || data === void 0 ? void 0 : data.selectedDate) ? 0 : -1,
3136
+ role: day.selected ? 'gridcell' : undefined,
3137
+ "aria-selected": day.selected && !(data === null || data === void 0 ? void 0 : data.highlightedDate) ? true : undefined,
3138
+ onClick: () => {
3139
+ day.currentMonth && datepicker.select(day.date);
3140
+ }
3141
+ }, {
3142
+ children: day.day
3143
+ }), day.day))]
3144
+ }, `week_${ix}`))
3145
+ })]
3146
+ }))
3147
+ })]
3148
+ }))
3149
+ }))]
3150
+ });
3151
+ };
3152
+
2944
3153
  exports.Alert = Alert;
2945
3154
  exports.Badge = Badge;
2946
3155
  exports.Button = Button;
2947
3156
  exports.ButtonGroup = ButtonGroup;
2948
3157
  exports.Card = Card;
2949
3158
  exports.Checkbox = Checkbox;
3159
+ exports.Datepicker = Datepicker;
2950
3160
  exports.Dropdown = Dropdown;
2951
3161
  exports.EmailInput = EmailInput;
2952
3162
  exports.Flexbox = Flexbox;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ interface AccordionItemProps {
3
+ item: AccordionItemInterface;
4
+ index: number;
5
+ uuid: string;
6
+ }
7
+ export interface AccordionItemInterface {
8
+ label: string;
9
+ labelElementLevel: 2 | 3 | 4 | 5 | 6;
10
+ subLabel?: string;
11
+ content: JSX.Element;
12
+ onClick?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
13
+ onOpen?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
14
+ onClose?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
15
+ }
16
+ declare const AccordionItem: ({ item, index, uuid }: AccordionItemProps) => JSX.Element;
17
+ export default AccordionItem;
@@ -0,0 +1,6 @@
1
+ import { AccordionItemInterface } from './accordion-item';
2
+ export interface AccordionInterface {
3
+ items: AccordionItemInterface[];
4
+ }
5
+ declare const Accordion: ({ items }: AccordionInterface) => JSX.Element;
6
+ export default Accordion;
@@ -1,5 +1,5 @@
1
- import { AlertType } from '@sebgroup/extract';
2
1
  import { ReactNode } from 'react';
2
+ import { AlertType } from '@sebgroup/extract';
3
3
  export interface AlertProps {
4
4
  children: ReactNode;
5
5
  type: AlertType;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@sebgroup/green-react",
3
- "version": "1.0.0-beta.42",
3
+ "version": "1.0.0-beta.44",
4
4
  "peerDependencies": {
5
5
  "react": "^17 || ^18",
6
6
  "react-dom": "^17 || ^18"
7
7
  },
8
8
  "dependencies": {
9
- "@sebgroup/chlorophyll": "^1.0.0-beta.43",
10
- "@sebgroup/extract": "^1.0.0-beta.42"
9
+ "@sebgroup/chlorophyll": "^1.0.0-beta.45",
10
+ "@sebgroup/extract": "^1.0.0-beta.44"
11
11
  },
12
12
  "description": "React components built on top of @sebgroup/chlorophyll.",
13
13
  "repository": {