@modernpoacher/gremlins 0.0.311 → 1.0.1

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.
Files changed (173) hide show
  1. package/.prettierignore +4 -0
  2. package/babel.config.cjs +4 -1
  3. package/eslint.config.mjs +33 -71
  4. package/index.d.mts +169 -2
  5. package/jest.after-each.mjs +10 -0
  6. package/jest.before-each.mjs +10 -0
  7. package/jest.config.mjs +11 -1
  8. package/package.json +84 -29
  9. package/src/{components → js/components}/common/disabled/index.cjs +5 -2
  10. package/src/js/components/common/disabled/index.d.cts +1 -0
  11. package/src/js/components/common/disabled/index.jsx +11 -0
  12. package/src/{components → js/components}/common/readonly/index.cjs +5 -2
  13. package/src/js/components/common/readonly/index.d.cts +1 -0
  14. package/src/js/components/common/readonly/index.jsx +11 -0
  15. package/src/{components → js/components}/common/required/index.cjs +5 -2
  16. package/src/js/components/common/required/index.d.cts +1 -0
  17. package/src/js/components/common/required/index.jsx +11 -0
  18. package/src/{components → js/components}/common/text-content/index.cjs +5 -2
  19. package/src/js/components/common/text-content/index.d.cts +2 -0
  20. package/src/{components → js/components}/common/text-content/index.d.mts +1 -3
  21. package/src/{components → js/components}/common/text-content/index.jsx +6 -5
  22. package/src/{components → js/components}/field/index.cjs +10 -2
  23. package/src/js/components/field/index.d.cts +1 -0
  24. package/src/js/components/field/index.d.mts +24 -0
  25. package/src/js/components/field/index.jsx +98 -0
  26. package/src/{components → js/components}/group/index.cjs +5 -2
  27. package/src/js/components/group/index.d.cts +2 -0
  28. package/src/js/components/group/index.d.mts +9 -0
  29. package/src/js/components/group/index.jsx +5 -0
  30. package/src/js/components/index.cjs +29 -0
  31. package/src/js/components/index.d.cts +2 -0
  32. package/src/js/components/index.d.mts +2 -0
  33. package/src/js/components/index.mjs +8 -0
  34. package/src/{gremlins → js/gremlins}/checkbox/field/index.cjs +5 -2
  35. package/src/js/gremlins/checkbox/field/index.d.cts +2 -0
  36. package/src/js/gremlins/checkbox/field/index.d.mts +14 -0
  37. package/src/{gremlins → js/gremlins}/checkbox/field/index.jsx +21 -10
  38. package/src/{gremlins → js/gremlins}/checkbox/index.cjs +5 -2
  39. package/src/js/gremlins/checkbox/index.d.cts +2 -0
  40. package/src/js/gremlins/checkbox/index.d.mts +24 -0
  41. package/src/{gremlins → js/gremlins}/checkbox/index.jsx +31 -23
  42. package/src/{gremlins → js/gremlins}/email/field/index.cjs +5 -2
  43. package/src/js/gremlins/email/field/index.d.cts +2 -0
  44. package/src/js/gremlins/email/field/index.d.mts +14 -0
  45. package/src/js/gremlins/email/field/index.jsx +83 -0
  46. package/src/{gremlins → js/gremlins}/email/index.cjs +5 -2
  47. package/src/js/gremlins/email/index.d.cts +2 -0
  48. package/src/js/gremlins/email/index.d.mts +18 -0
  49. package/src/{gremlins → js/gremlins}/email/index.jsx +25 -12
  50. package/src/{gremlins → js/gremlins}/fieldset/group/index.cjs +5 -2
  51. package/src/js/gremlins/fieldset/group/index.d.cts +2 -0
  52. package/src/js/gremlins/fieldset/group/index.d.mts +12 -0
  53. package/src/js/gremlins/fieldset/group/index.jsx +19 -0
  54. package/src/{gremlins → js/gremlins}/fieldset/index.cjs +5 -2
  55. package/src/js/gremlins/fieldset/index.d.cts +2 -0
  56. package/src/js/gremlins/fieldset/index.d.mts +14 -0
  57. package/src/js/gremlins/fieldset/index.jsx +37 -0
  58. package/src/{gremlins → js/gremlins}/index.cjs +9 -4
  59. package/src/js/gremlins/index.d.cts +5 -0
  60. package/src/js/gremlins/index.d.mts +27 -0
  61. package/src/js/gremlins/index.jsx +162 -0
  62. package/src/{gremlins → js/gremlins}/number/field/index.cjs +5 -2
  63. package/src/js/gremlins/number/field/index.d.cts +2 -0
  64. package/src/js/gremlins/number/field/index.d.mts +14 -0
  65. package/src/{gremlins → js/gremlins}/number/field/index.jsx +40 -7
  66. package/src/{gremlins → js/gremlins}/number/index.cjs +5 -2
  67. package/src/js/gremlins/number/index.d.cts +2 -0
  68. package/src/js/gremlins/number/index.d.mts +18 -0
  69. package/src/{gremlins → js/gremlins}/number/index.jsx +25 -8
  70. package/src/{gremlins → js/gremlins}/password/field/index.cjs +5 -2
  71. package/src/js/gremlins/password/field/index.d.cts +2 -0
  72. package/src/js/gremlins/password/field/index.d.mts +14 -0
  73. package/src/js/gremlins/password/field/index.jsx +83 -0
  74. package/src/{gremlins → js/gremlins}/password/index.cjs +5 -2
  75. package/src/js/gremlins/password/index.d.cts +2 -0
  76. package/src/js/gremlins/password/index.d.mts +18 -0
  77. package/src/{gremlins → js/gremlins}/password/index.jsx +25 -12
  78. package/src/{gremlins → js/gremlins}/radio/field/index.cjs +5 -2
  79. package/src/js/gremlins/radio/field/index.d.cts +2 -0
  80. package/src/js/gremlins/radio/field/index.d.mts +14 -0
  81. package/src/{gremlins → js/gremlins}/radio/field/index.jsx +20 -9
  82. package/src/{gremlins → js/gremlins}/radio/index.cjs +5 -2
  83. package/src/js/gremlins/radio/index.d.cts +2 -0
  84. package/src/js/gremlins/radio/index.d.mts +24 -0
  85. package/src/{gremlins → js/gremlins}/radio/index.jsx +33 -17
  86. package/src/{gremlins → js/gremlins}/select/field/index.cjs +5 -2
  87. package/src/js/gremlins/select/field/index.d.cts +2 -0
  88. package/src/js/gremlins/select/field/index.d.mts +18 -0
  89. package/src/js/gremlins/select/field/index.jsx +200 -0
  90. package/src/{gremlins → js/gremlins}/select/index.cjs +5 -2
  91. package/src/js/gremlins/select/index.d.cts +2 -0
  92. package/src/js/gremlins/select/index.d.mts +18 -0
  93. package/src/{gremlins → js/gremlins}/select/index.jsx +53 -16
  94. package/src/{gremlins → js/gremlins}/text/field/index.cjs +5 -2
  95. package/src/js/gremlins/text/field/index.d.cts +2 -0
  96. package/src/js/gremlins/text/field/index.d.mts +14 -0
  97. package/src/js/gremlins/text/field/index.jsx +83 -0
  98. package/src/{gremlins → js/gremlins}/text/index.cjs +5 -2
  99. package/src/js/gremlins/text/index.d.cts +2 -0
  100. package/src/js/gremlins/text/index.d.mts +18 -0
  101. package/src/{gremlins → js/gremlins}/text/index.jsx +25 -12
  102. package/src/{gremlins → js/gremlins}/textarea/field/index.cjs +5 -2
  103. package/src/js/gremlins/textarea/field/index.d.cts +2 -0
  104. package/src/js/gremlins/textarea/field/index.d.mts +18 -0
  105. package/src/js/gremlins/textarea/field/index.jsx +81 -0
  106. package/src/{gremlins → js/gremlins}/textarea/index.cjs +5 -2
  107. package/src/js/gremlins/textarea/index.d.cts +2 -0
  108. package/src/js/gremlins/textarea/index.d.mts +18 -0
  109. package/src/{gremlins → js/gremlins}/textarea/index.jsx +25 -12
  110. package/src/js/super/components/field/index.cjs +20 -0
  111. package/src/js/super/components/field/index.d.cts +2 -0
  112. package/src/js/super/components/field/index.d.mts +23 -0
  113. package/src/{components → js/super/components}/field/index.jsx +44 -87
  114. package/src/js/super/components/group/index.cjs +20 -0
  115. package/src/js/super/components/group/index.d.cts +2 -0
  116. package/src/js/super/components/group/index.d.mts +18 -0
  117. package/src/js/super/components/group/index.jsx +59 -0
  118. package/src/js/super/components/index.cjs +23 -0
  119. package/src/js/super/components/index.d.cts +2 -0
  120. package/src/js/super/components/index.d.mts +2 -0
  121. package/src/js/super/components/index.mjs +8 -0
  122. package/src/js/super/gremlins/index.cjs +22 -0
  123. package/src/js/super/gremlins/index.d.cts +4 -0
  124. package/src/js/super/gremlins/index.d.mts +36 -0
  125. package/src/js/super/gremlins/index.jsx +176 -0
  126. package/src/sass/.stylelintrc +14 -0
  127. package/src/sass/_gremlins.scss +59 -0
  128. package/src/sass/gremlins/_checkbox.scss +87 -0
  129. package/src/sass/gremlins/_disabled.scss +15 -0
  130. package/src/sass/gremlins/_error.scss +48 -0
  131. package/src/sass/gremlins/_radio.scss +93 -0
  132. package/.publish/README.md +0 -20
  133. package/src/common/index.d.mts +0 -9
  134. package/src/common/index.mjs +0 -7
  135. package/src/components/common/disabled/index.jsx +0 -9
  136. package/src/components/common/readonly/index.jsx +0 -9
  137. package/src/components/common/required/index.jsx +0 -9
  138. package/src/components/field/index.d.mts +0 -23
  139. package/src/components/group/index.d.mts +0 -16
  140. package/src/components/group/index.jsx +0 -59
  141. package/src/gremlins/checkbox/field/index.d.mts +0 -9
  142. package/src/gremlins/checkbox/index.d.mts +0 -9
  143. package/src/gremlins/email/field/index.d.mts +0 -9
  144. package/src/gremlins/email/field/index.jsx +0 -54
  145. package/src/gremlins/email/index.d.mts +0 -9
  146. package/src/gremlins/fieldset/group/index.d.mts +0 -9
  147. package/src/gremlins/fieldset/group/index.jsx +0 -16
  148. package/src/gremlins/fieldset/index.d.mts +0 -9
  149. package/src/gremlins/fieldset/index.jsx +0 -41
  150. package/src/gremlins/index.d.mts +0 -45
  151. package/src/gremlins/index.jsx +0 -291
  152. package/src/gremlins/number/field/index.d.mts +0 -9
  153. package/src/gremlins/number/index.d.mts +0 -9
  154. package/src/gremlins/password/field/index.d.mts +0 -9
  155. package/src/gremlins/password/field/index.jsx +0 -54
  156. package/src/gremlins/password/index.d.mts +0 -9
  157. package/src/gremlins/radio/field/index.d.mts +0 -9
  158. package/src/gremlins/radio/index.d.mts +0 -9
  159. package/src/gremlins/select/field/index.d.mts +0 -9
  160. package/src/gremlins/select/field/index.jsx +0 -111
  161. package/src/gremlins/select/index.d.mts +0 -9
  162. package/src/gremlins/text/field/index.d.mts +0 -9
  163. package/src/gremlins/text/field/index.jsx +0 -54
  164. package/src/gremlins/text/index.d.mts +0 -9
  165. package/src/gremlins/textarea/field/index.d.mts +0 -9
  166. package/src/gremlins/textarea/field/index.jsx +0 -53
  167. package/src/gremlins/textarea/index.d.mts +0 -9
  168. /package/src/{components → js/components}/common/disabled/index.d.mts +0 -0
  169. /package/src/{components → js/components}/common/readonly/index.d.mts +0 -0
  170. /package/src/{components → js/components}/common/required/index.d.mts +0 -0
  171. /package/src/{index.cjs → js/index.cjs} +0 -0
  172. /package/src/{index.d.mts → js/index.d.mts} +0 -0
  173. /package/src/{index.mjs → js/index.mjs} +0 -0
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @typedef {GremlinsTypes.Components.Field.ValueProps} ValueProps
3
+ * @typedef {GremlinsTypes.Components.Field.Password.PasswordProps} PasswordProps
4
+ */
5
+
6
+ /**
7
+ * PasswordField component
8
+ */
9
+ import React from 'react'
10
+ import classnames from 'classnames'
11
+
12
+ import {
13
+ ValueField,
14
+ toInputValue
15
+ } from '#gremlins/components/field'
16
+
17
+ /**
18
+ * @extends {ValueField<ValueProps & PasswordProps>}
19
+ */
20
+ export default class PasswordField extends ValueField {
21
+ getClassName () {
22
+ return classnames(super.getClassName(), 'password')
23
+ }
24
+
25
+ render () {
26
+ const {
27
+ name,
28
+ id,
29
+ defaultValue,
30
+ required = false,
31
+ disabled = false,
32
+ readOnly = false,
33
+ tabIndex,
34
+ accessKey,
35
+ placeholder,
36
+ fieldRef
37
+ } = this.props
38
+
39
+ const className = this.getClassName()
40
+
41
+ if (defaultValue === undefined) {
42
+ const {
43
+ value
44
+ } = this.props
45
+
46
+ return (
47
+ <input
48
+ name={name}
49
+ id={id}
50
+ value={toInputValue(value)}
51
+ required={required}
52
+ disabled={disabled}
53
+ readOnly={readOnly}
54
+ tabIndex={tabIndex}
55
+ accessKey={accessKey}
56
+ placeholder={placeholder}
57
+ onChange={this.handleChange}
58
+ className={className}
59
+ type='password'
60
+ ref={fieldRef}
61
+ />
62
+ )
63
+ }
64
+
65
+ return (
66
+ <input
67
+ name={name}
68
+ id={id}
69
+ defaultValue={String(defaultValue)}
70
+ required={required}
71
+ disabled={disabled}
72
+ readOnly={readOnly}
73
+ tabIndex={tabIndex}
74
+ accessKey={accessKey}
75
+ placeholder={placeholder}
76
+ onChange={this.handleChange}
77
+ className={className}
78
+ type='password'
79
+ ref={fieldRef}
80
+ />
81
+ )
82
+ }
83
+ }
@@ -11,7 +11,10 @@ const log = debug('@modernpoacher/gremlins/gremlins/password')
11
11
  log('`gremlins` is awake')
12
12
 
13
13
  const {
14
- default: component
14
+ default: Password
15
15
  } = require('./index.jsx')
16
16
 
17
- module.exports = component
17
+ /**
18
+ * Exports only default
19
+ */
20
+ module.exports = Password
@@ -0,0 +1,2 @@
1
+ export { default } from '#gremlins/gremlins/password'
2
+ export * from '#gremlins/gremlins/password'
@@ -0,0 +1,18 @@
1
+ declare module '#gremlins/gremlins/password' {
2
+ import {
3
+ ValueGremlin
4
+ } from '#gremlins/gremlins'
5
+
6
+ export type PasswordProps = GremlinsTypes.Gremlins.Password.PasswordProps
7
+
8
+ export default class PasswordGremlin<P extends PasswordProps> extends ValueGremlin<P> {
9
+ handleChange (
10
+ value?: string | string[]
11
+ ): void
12
+ }
13
+ }
14
+
15
+ declare module '@modernpoacher/gremlins/gremlins/password' {
16
+ export { default } from '#gremlins/gremlins/password'
17
+ export * from '#gremlins/gremlins/password'
18
+ }
@@ -1,25 +1,42 @@
1
1
  /**
2
- * PasswordGremlin component
2
+ * @typedef {GremlinsTypes.OnEventType} OnEventType
3
+ * @typedef {GremlinsTypes.Gremlins.ValueProps} ValueProps
4
+ * @typedef {GremlinsTypes.Gremlins.Password.PasswordProps} PasswordProps
5
+ */
6
+
7
+ /**
8
+ * PasswordGremlin component
3
9
  */
4
10
  import React from 'react'
5
11
  import classnames from 'classnames'
6
12
 
7
- import { ValueGremlin } from '#gremlins/gremlins'
8
-
9
13
  import {
10
- DEFAULT_HANDLE_CHANGE
11
- } from '#gremlins/common'
14
+ ValueGremlin
15
+ } from '#gremlins/gremlins'
12
16
 
13
- import Field from './field/index.jsx'
17
+ import Field from '#gremlins/gremlins/password/field'
18
+
19
+ /**
20
+ * @type {OnEventType}
21
+ */
22
+ function DEFAULT_HANDLE_EVENT () {
23
+ //
24
+ }
14
25
 
26
+ /**
27
+ * @extends {ValueGremlin<ValueProps & PasswordProps>}
28
+ */
15
29
  export default class PasswordGremlin extends ValueGremlin {
16
30
  getClassName () {
17
31
  return classnames(super.getClassName(), 'password')
18
32
  }
19
33
 
34
+ /**
35
+ * @param {string | string[]} [value]
36
+ */
20
37
  handleChange = (value) => {
21
38
  const {
22
- onChange = DEFAULT_HANDLE_CHANGE
39
+ onChange = DEFAULT_HANDLE_EVENT
23
40
  } = this.props
24
41
 
25
42
  onChange(value)
@@ -43,8 +60,8 @@ export default class PasswordGremlin extends ValueGremlin {
43
60
 
44
61
  return (
45
62
  <Field
46
- id={id}
47
63
  name={name}
64
+ id={id}
48
65
  value={value}
49
66
  defaultValue={defaultValue}
50
67
  required={required}
@@ -59,7 +76,3 @@ export default class PasswordGremlin extends ValueGremlin {
59
76
  )
60
77
  }
61
78
  }
62
-
63
- PasswordGremlin.propTypes = {
64
- ...ValueGremlin.propTypes
65
- }
@@ -11,7 +11,10 @@ const log = debug('@modernpoacher/gremlins/gremlins/radio/field')
11
11
  log('`gremlins` is awake')
12
12
 
13
13
  const {
14
- default: component
14
+ default: Field
15
15
  } = require('./index.jsx')
16
16
 
17
- module.exports = component
17
+ /**
18
+ * Exports only default
19
+ */
20
+ module.exports = Field
@@ -0,0 +1,2 @@
1
+ export { default } from '#gremlins/gremlins/radio/field'
2
+ export * from '#gremlins/gremlins/radio/field'
@@ -0,0 +1,14 @@
1
+ declare module '#gremlins/gremlins/radio/field' {
2
+ import {
3
+ CheckField
4
+ } from '#gremlins/components/field'
5
+
6
+ export type RadioProps = GremlinsTypes.Components.Field.Radio.RadioProps
7
+
8
+ export default class RadioField<P extends RadioProps> extends CheckField<P> {}
9
+ }
10
+
11
+ declare module '@modernpoacher/gremlins/gremlins/radio/field' {
12
+ export { default } from '#gremlins/gremlins/radio/field'
13
+ export * from '#gremlins/gremlins/radio/field'
14
+ }
@@ -1,12 +1,23 @@
1
1
  /**
2
- * RadioField component
2
+ * @typedef {GremlinsTypes.Components.Field.CheckProps} CheckProps
3
+ * @typedef {GremlinsTypes.Components.Field.Radio.RadioProps} RadioProps
4
+ */
5
+
6
+ /**
7
+ * RadioField component
3
8
  */
4
9
  import React from 'react'
5
10
  import PropTypes from 'prop-types'
6
11
  import classnames from 'classnames'
7
12
 
8
- import { CheckField } from '#gremlins/components/field'
13
+ import {
14
+ CheckField,
15
+ toInputValue
16
+ } from '#gremlins/components/field'
9
17
 
18
+ /**
19
+ * @extends {CheckField<CheckProps & RadioProps>}
20
+ */
10
21
  export default class RadioField extends CheckField {
11
22
  getClassName () {
12
23
  return classnames(super.getClassName(), 'radio')
@@ -15,8 +26,8 @@ export default class RadioField extends CheckField {
15
26
  render () {
16
27
  const {
17
28
  checked,
18
- id,
19
29
  name,
30
+ id,
20
31
  value,
21
32
  required = false,
22
33
  disabled = false,
@@ -32,10 +43,10 @@ export default class RadioField extends CheckField {
32
43
  return (
33
44
  <>
34
45
  <input
35
- checked={checked}
36
- id={id}
37
46
  name={name}
38
- value={value}
47
+ id={id}
48
+ value={toInputValue(value)}
49
+ checked={checked}
39
50
  required={required}
40
51
  disabled={disabled}
41
52
  readOnly={readOnly}
@@ -61,10 +72,10 @@ export default class RadioField extends CheckField {
61
72
  return (
62
73
  <>
63
74
  <input
64
- defaultChecked={defaultChecked}
65
- id={id}
66
75
  name={name}
67
- value={value}
76
+ id={id}
77
+ value={toInputValue(value)}
78
+ defaultChecked={defaultChecked}
68
79
  required={required}
69
80
  disabled={disabled}
70
81
  readOnly={readOnly}
@@ -11,7 +11,10 @@ const log = debug('@modernpoacher/gremlins/gremlins/radio')
11
11
  log('`gremlins` is awake')
12
12
 
13
13
  const {
14
- default: component
14
+ default: Radio
15
15
  } = require('./index.jsx')
16
16
 
17
- module.exports = component
17
+ /**
18
+ * Exports only default
19
+ */
20
+ module.exports = Radio
@@ -0,0 +1,2 @@
1
+ export { default } from '#gremlins/gremlins/radio'
2
+ export * from '#gremlins/gremlins/radio'
@@ -0,0 +1,24 @@
1
+ declare module '#gremlins/gremlins/radio' {
2
+ import {
3
+ CheckGremlin
4
+ } from '#gremlins/gremlins'
5
+
6
+ export type RadioProps = GremlinsTypes.Gremlins.Radio.RadioProps
7
+
8
+ export default class RadioGremlin<P extends RadioProps> extends CheckGremlin<P> {
9
+ handleChange (
10
+ value?: string | string[],
11
+ checked?: boolean
12
+ ): void
13
+
14
+ handleClick (
15
+ value?: string | string[],
16
+ checked?: boolean
17
+ ): void
18
+ }
19
+ }
20
+
21
+ declare module '@modernpoacher/gremlins/gremlins/radio' {
22
+ export { default } from '#gremlins/gremlins/radio'
23
+ export * from '#gremlins/gremlins/radio'
24
+ }
@@ -1,47 +1,63 @@
1
1
  /**
2
- * Radio component
2
+ * @typedef {GremlinsTypes.OnEventType} OnEventType
3
+ * @typedef {GremlinsTypes.Gremlins.CheckProps} CheckProps
4
+ * @typedef {GremlinsTypes.Gremlins.Radio.RadioProps} RadioProps
5
+ */
6
+
7
+ /**
8
+ * Radio component
3
9
  */
4
10
  import React from 'react'
5
11
  import PropTypes from 'prop-types'
6
12
  import classnames from 'classnames'
7
13
 
8
- import { CheckGremlin } from '#gremlins/gremlins'
9
-
10
14
  import {
11
- DEFAULT_HANDLE_CHANGE,
12
- DEFAULT_HANDLE_CLICK
13
- } from '#gremlins/common'
15
+ CheckGremlin
16
+ } from '#gremlins/gremlins'
14
17
 
15
- import Field from './field/index.jsx'
18
+ import Field from '#gremlins/gremlins/radio/field'
19
+
20
+ /**
21
+ * @type {OnEventType}
22
+ */
23
+ function DEFAULT_HANDLE_EVENT () {
24
+ //
25
+ }
16
26
 
27
+ /**
28
+ * @extends {CheckGremlin<CheckProps & RadioProps>}
29
+ */
17
30
  export default class Radio extends CheckGremlin {
18
31
  getClassName () {
19
32
  return classnames(super.getClassName(), 'radio')
20
33
  }
21
34
 
35
+ /**
36
+ * @param {string} name
37
+ * @param {string | string[]} [value]
38
+ * @param {boolean} [checked]
39
+ */
22
40
  handleChange = (value, checked) => {
23
41
  const {
24
- onChange = DEFAULT_HANDLE_CHANGE
42
+ onChange = DEFAULT_HANDLE_EVENT
25
43
  } = this.props
26
44
 
27
45
  onChange(value, checked)
28
46
  }
29
47
 
48
+ /**
49
+ * @param {string} name
50
+ * @param {string | string[]} [value]
51
+ * @param {boolean} [checked]
52
+ */
30
53
  handleClick = (value, checked) => {
31
54
  const {
32
- onClick = DEFAULT_HANDLE_CLICK
55
+ onClick = DEFAULT_HANDLE_EVENT
33
56
  } = this.props
34
57
 
35
58
  onClick(value, checked)
36
59
  }
37
60
 
38
- shouldComponentUpdate (props, state) {
39
- return (
40
- super.shouldComponentUpdate(props) ||
41
- (props.value !== this.props.value)
42
- )
43
- }
44
-
45
61
  renderField () {
46
62
  const id = this.getId()
47
63
 
@@ -61,8 +77,8 @@ export default class Radio extends CheckGremlin {
61
77
 
62
78
  return (
63
79
  <Field
64
- id={id}
65
80
  name={name}
81
+ id={id}
66
82
  value={value}
67
83
  checked={checked}
68
84
  defaultChecked={defaultChecked}
@@ -11,7 +11,10 @@ const log = debug('@modernpoacher/gremlins/gremlins/select/field')
11
11
  log('`gremlins` is awake')
12
12
 
13
13
  const {
14
- default: component
14
+ default: Field
15
15
  } = require('./index.jsx')
16
16
 
17
- module.exports = component
17
+ /**
18
+ * Exports only default
19
+ */
20
+ module.exports = Field
@@ -0,0 +1,2 @@
1
+ export { default } from '#gremlins/gremlins/select/field'
2
+ export * from '#gremlins/gremlins/select/field'
@@ -0,0 +1,18 @@
1
+ declare module '#gremlins/gremlins/select/field' {
2
+ import type { ChangeEvent } from 'react'
3
+
4
+ import {
5
+ ValueField
6
+ } from '#gremlins/components/field'
7
+
8
+ export type SelectProps = GremlinsTypes.Components.Field.Select.SelectProps
9
+
10
+ export default class SelectField<P extends SelectProps> extends ValueField<P> {
11
+ handleChange (event: ChangeEvent<HTMLSelectElement>): void
12
+ }
13
+ }
14
+
15
+ declare module '@modernpoacher/gremlins/gremlins/select/field' {
16
+ export { default } from '#gremlins/gremlins/select/field'
17
+ export * from '#gremlins/gremlins/select/field'
18
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * @typedef {GremlinsTypes.OnEventType} OnEventType
3
+ * @typedef {GremlinsTypes.Components.Field.ValueProps} ValueProps
4
+ * @typedef {GremlinsTypes.Components.Field.Select.SelectProps} SelectProps
5
+ */
6
+
7
+ /**
8
+ * SelectField component
9
+ */
10
+ import React from 'react'
11
+ import PropTypes from 'prop-types'
12
+ import classnames from 'classnames'
13
+
14
+ import {
15
+ ValueField,
16
+ toInputValue
17
+ } from '#gremlins/components/field'
18
+
19
+ /**
20
+ * @type {OnEventType}
21
+ */
22
+ function DEFAULT_HANDLE_EVENT () {
23
+ //
24
+ }
25
+
26
+ /**
27
+ * @param {HTMLOptionElement[]} selectedOptions
28
+ * @returns {string[]}
29
+ */
30
+ function fromSelectedOptions (selectedOptions) {
31
+ return (
32
+ Array.from(selectedOptions)
33
+ .map(({ value, text }) => (value || text) ?? '')
34
+ )
35
+ }
36
+
37
+ /**
38
+ * @param {{ target: { selectedOptions: HTMLOptionElement[] } }} event
39
+ * @returns {string[]}
40
+ */
41
+ function getSelectedValues ({ target: { selectedOptions } }) {
42
+ return (
43
+ fromSelectedOptions(selectedOptions)
44
+ )
45
+ }
46
+
47
+ /**
48
+ * @param {{ target: { value?: string } }} event
49
+ * @returns {string}
50
+ */
51
+ function getSelectedValue ({ target: { value } }) {
52
+ return value ?? ''
53
+ }
54
+
55
+ /**
56
+ * @extends {ValueField<ValueProps & SelectProps>}
57
+ */
58
+ export default class SelectField extends ValueField {
59
+ getClassName () {
60
+ return classnames(super.getClassName(), 'select')
61
+ }
62
+
63
+ /**
64
+ * @param {SelectProps} props
65
+ * @returns {boolean}
66
+ */
67
+ shouldComponentUpdate (props) {
68
+ const {
69
+ multiple,
70
+ children,
71
+ ...superProps
72
+ } = props
73
+
74
+ return (
75
+ super.shouldComponentUpdate(superProps) || // , state ||
76
+ (multiple !== this.props.multiple) ||
77
+ (children !== this.props.children)
78
+ )
79
+ }
80
+
81
+ /**
82
+ * @overload
83
+ * @param {{ target: { selectedOptions: { value?: string, text?: string }[] } }} event
84
+ * @returns {void}
85
+ *
86
+ * @overload
87
+ * @param {{ target: { value?: string } }} event
88
+ * @returns {void}
89
+ *
90
+ * @param {any} event
91
+ * @returns {void}
92
+ */
93
+ handleChange = (event) => {
94
+ const {
95
+ multiple = false,
96
+ onChange = DEFAULT_HANDLE_EVENT
97
+ } = this.props
98
+
99
+ if (multiple) {
100
+ onChange(getSelectedValues(event))
101
+ } else {
102
+ onChange(getSelectedValue(event))
103
+ }
104
+ }
105
+
106
+ render () {
107
+ const {
108
+ name,
109
+ id,
110
+ defaultValue,
111
+ required = false,
112
+ disabled = false,
113
+ readOnly = false,
114
+ tabIndex,
115
+ accessKey,
116
+ multiple = false,
117
+ children,
118
+ fieldRef
119
+ } = this.props
120
+
121
+ const className = this.getClassName()
122
+
123
+ if (defaultValue === undefined) {
124
+ const {
125
+ value
126
+ } = this.props
127
+
128
+ return (
129
+ <select
130
+ name={name}
131
+ id={id}
132
+ value={(
133
+ multiple
134
+ ? Array.isArray(value)
135
+ ? value
136
+ : [toInputValue(value)]
137
+ : toInputValue(value)
138
+ )}
139
+ required={required}
140
+ disabled={disabled} // @ts-ignore
141
+ readOnly={readOnly}
142
+ tabIndex={tabIndex}
143
+ accessKey={accessKey}
144
+ multiple={multiple}
145
+ onChange={this.handleChange}
146
+ className={className}
147
+ ref={fieldRef}>
148
+ {children}
149
+ </select>
150
+ )
151
+ }
152
+
153
+ return (
154
+ <select
155
+ name={name}
156
+ id={id}
157
+ defaultValue={(
158
+ multiple
159
+ ? Array.isArray(defaultValue)
160
+ ? defaultValue
161
+ : [String(defaultValue)]
162
+ : String(defaultValue)
163
+ )}
164
+ required={required}
165
+ disabled={disabled} // @ts-ignore
166
+ readOnly={readOnly}
167
+ tabIndex={tabIndex}
168
+ accessKey={accessKey}
169
+ multiple={multiple}
170
+ onChange={this.handleChange}
171
+ className={className}
172
+ ref={fieldRef}>
173
+ {children}
174
+ </select>
175
+ )
176
+ }
177
+ }
178
+
179
+ SelectField.propTypes = {
180
+ ...ValueField.propTypes,
181
+ multiple: PropTypes.bool,
182
+ value: PropTypes.oneOfType([
183
+ PropTypes.string,
184
+ PropTypes.arrayOf(
185
+ PropTypes.string
186
+ )
187
+ ]),
188
+ defaultValue: PropTypes.oneOfType([
189
+ PropTypes.string,
190
+ PropTypes.arrayOf(
191
+ PropTypes.string
192
+ )
193
+ ]),
194
+ children: PropTypes.oneOfType([
195
+ PropTypes.node,
196
+ PropTypes.arrayOf(
197
+ PropTypes.node
198
+ )
199
+ ])
200
+ }
@@ -11,7 +11,10 @@ const log = debug('@modernpoacher/gremlins/gremlins/select')
11
11
  log('`gremlins` is awake')
12
12
 
13
13
  const {
14
- default: component
14
+ default: Select
15
15
  } = require('./index.jsx')
16
16
 
17
- module.exports = component
17
+ /**
18
+ * Exports only default
19
+ */
20
+ module.exports = Select
@@ -0,0 +1,2 @@
1
+ export { default } from '#gremlins/gremlins/select'
2
+ export * from '#gremlins/gremlins/select'
@@ -0,0 +1,18 @@
1
+ declare module '#gremlins/gremlins/select' {
2
+ import {
3
+ ValueGremlin
4
+ } from '#gremlins/gremlins'
5
+
6
+ export type SelectProps = GremlinsTypes.Gremlins.Select.SelectProps
7
+
8
+ export default class SelectGremlin<P extends SelectProps> extends ValueGremlin<Omit<Omit<P, 'value'>, 'defaultValue'>> {
9
+ handleChange (
10
+ value?: string | string[]
11
+ ): void
12
+ }
13
+ }
14
+
15
+ declare module '@modernpoacher/gremlins/gremlins/select' {
16
+ export { default } from '#gremlins/gremlins/select'
17
+ export * from '#gremlins/gremlins/select'
18
+ }