@fibery/ui-kit 3.0.0 → 4.1.0

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 (102) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/esfint.config.mjs +0 -17
  3. package/package.json +18 -13
  4. package/scripts/generate-icons.mjs +45 -44
  5. package/src/actions-menu/actions-menu-item.tsx +2 -1
  6. package/src/actions-menu/actions-menu.tsx +1 -3
  7. package/src/actions-menu/context-actions-menu.tsx +1 -1
  8. package/src/animated-height-container.tsx +1 -1
  9. package/src/antd/ant-modal.tsx +158 -9
  10. package/src/antd/ant-upload.tsx +285 -27
  11. package/src/antd/auto-complete.tsx +145 -0
  12. package/src/antd/auto-width-transparent-textarea.tsx +9 -2
  13. package/src/antd/global-overrides.ts +352 -0
  14. package/src/antd/index.tsx +3 -2
  15. package/src/antd/input-number.tsx +97 -11
  16. package/src/antd/input.tsx +127 -8
  17. package/src/antd/styles.ts +92 -32
  18. package/src/antd/tabs.tsx +139 -27
  19. package/src/app-icon-with-fallback.tsx +3 -7
  20. package/src/app-icon-wrapper.tsx +1 -13
  21. package/src/avatar.tsx +2 -56
  22. package/src/breadcrumb.tsx +5 -1
  23. package/src/color-adjuster.ts +24 -1
  24. package/src/color-utils.test.ts +2 -2
  25. package/src/color-utils.ts +2 -2
  26. package/src/copy-to-clipboard.ts +14 -3
  27. package/src/count-badge.tsx +10 -1
  28. package/src/date-picker/contexts.ts +6 -3
  29. package/src/date-picker/date-range-picker.tsx +7 -8
  30. package/src/date-picker/single-date-picker.tsx +3 -5
  31. package/src/date-picker/types.ts +1 -1
  32. package/src/date-picker/with-popup-control.tsx +3 -9
  33. package/src/day-select/iso-week-day-select.tsx +2 -2
  34. package/src/design-system/colors-callout.warm-dark.test.ts +22 -22
  35. package/src/design-system/colors-callout.warm-light.test.ts +19 -19
  36. package/src/design-system/colors-css.ts +1 -1
  37. package/src/design-system/colors-enum.dark.warm.test.ts +63 -63
  38. package/src/design-system/colors-enum.light.warm.test.ts +54 -54
  39. package/src/design-system/colors-highlight.warm-dark.test.ts +21 -21
  40. package/src/design-system/colors-highlight.warm-light.test.ts +21 -21
  41. package/src/design-system/colors.ts +4 -4
  42. package/src/design-system/fns.badge.dark.warm.test.ts +34 -34
  43. package/src/design-system/fns.badge.light.warm.test.ts +31 -31
  44. package/src/design-system/fns.deneutralize.test.ts +44 -0
  45. package/src/design-system/fns.icon.dark.warm.test.ts +21 -21
  46. package/src/design-system/fns.icon.light.warm.test.ts +17 -17
  47. package/src/design-system/fns.icon.ts +21 -13
  48. package/src/design-system/fns.ts +27 -3
  49. package/src/design-system/typography.ts +1 -1
  50. package/src/design-system.ts +1 -1
  51. package/src/emoji-picker/icon-emoji-picker.tsx +3 -3
  52. package/src/fibermoji-placeholder.tsx +2 -3
  53. package/src/icons/ast/index.tsx +446 -446
  54. package/src/icons/icon.tsx +23 -1
  55. package/src/icons/icons-integrity.test.ts +145 -0
  56. package/src/icons/react/index.tsx +446 -446
  57. package/src/icons/types.ts +1 -1
  58. package/src/images-gallery/images-gallery.tsx +2 -2
  59. package/src/images-gallery/slide-buttons.tsx +2 -4
  60. package/src/layout-styles.ts +5 -1
  61. package/src/link-input/components/ant-text-area-with-custom-read-state.tsx +2 -1
  62. package/src/lists/actions-menu-row-surface.tsx +1 -1
  63. package/src/media-query-utils.ts +5 -14
  64. package/src/mobile-keyboard-aware-popup.tsx +1 -1
  65. package/src/number-input/decimal.ts +6 -9
  66. package/src/number-input/number-input-inline-with-autosize.tsx +1 -1
  67. package/src/online-users.tsx +4 -5
  68. package/src/palettes/inspect.defs.colors.neutral-arch.test.ts +4 -4
  69. package/src/palettes/inspect.defs.colors.neutral-user.test.ts +4 -4
  70. package/src/palettes/inspect.defs.colors.warm-arch.test.ts +141 -141
  71. package/src/palettes/inspect.defs.colors.warm-user.test.ts +141 -141
  72. package/src/palettes/warm.ts +2 -0
  73. package/src/popover/index.tsx +4 -4
  74. package/src/popover/mobile-popover-context.tsx +1 -1
  75. package/src/popover/modifiers.tsx +1 -1
  76. package/src/rich-input-loader.tsx +1 -1
  77. package/src/root-theme-provider.test.tsx +1 -1
  78. package/src/select/components/menu-list-virtua.tsx +15 -16
  79. package/src/select/components/menu-list-virtualized.tsx +26 -29
  80. package/src/select/components/menu.tsx +3 -3
  81. package/src/select/index.tsx +4 -4
  82. package/src/select/reflection.ts +4 -5
  83. package/src/select/select-in-popover.tsx +34 -51
  84. package/src/select/select.tsx +5 -5
  85. package/src/select/styles.ts +1 -7
  86. package/src/select/util.ts +2 -2
  87. package/src/theme-provider.test.tsx +1 -1
  88. package/src/theme-provider.tsx +3 -9
  89. package/src/theme-snapshots.test.ts +9 -13
  90. package/src/{theming/build.ts → theming.build.ts} +6 -9
  91. package/src/{theming/theming-fibery.snapshot.css → theming.generated.css} +60 -60
  92. package/src/{theming/theming-fibery.snapshot.ts → theming.generated.ts} +60 -60
  93. package/src/type-badge.tsx +1 -2
  94. package/src/{themed-ink.tsx → type-label.tsx} +2 -5
  95. package/src/use-on-screen-keyboard-data.tsx +1 -1
  96. package/src/with-data.tsx +1 -1
  97. package/src/antd/auto-complete.d.ts +0 -2
  98. package/src/antd/auto-complete.ts +0 -37
  99. package/src/antd/tabs.d.ts +0 -5
  100. package/src/theming/index.ts +0 -20
  101. package/src/theming/theming-vzdbery.snapshot.css +0 -2001
  102. package/src/theming/theming-vzdbery.snapshot.ts +0 -2519
@@ -0,0 +1,352 @@
1
+ import {css} from "@linaria/core";
2
+
3
+ import {themeVars, transitions} from "../design-system";
4
+
5
+ // Port of antd@4 antd/lib/style/default.css base reset (the section before .clearfix/.anticon
6
+ // and the animation keyframes — those belong to components we no longer ship or have inlined
7
+ // in their own wrapper styles). dt#1205 inlined the antd wrappers and dropped the antd CSS
8
+ // bundle; the whole reboot vanished. Most consequential losses were `html, body {width:100%;
9
+ // height:100%}` (absolute-positioned descendants suddenly resolve to 0×0) and the universal
10
+ // `box-sizing: border-box` (every component that omits the declaration falls back to
11
+ // content-box → padding+border overflow → clipping → "content not displayed").
12
+ export const globalOverrides = css`
13
+ :global() {
14
+ // FIXME: scope to the React root instead of html/body — current rule is what gives
15
+ // WebLayout's position:absolute inset:0 descendant a viewport-sized box.
16
+ html,
17
+ body {
18
+ width: 100%;
19
+ height: 100%;
20
+ }
21
+
22
+ input::-ms-clear,
23
+ input::-ms-reveal {
24
+ display: none;
25
+ }
26
+
27
+ *,
28
+ *::before,
29
+ *::after {
30
+ box-sizing: border-box;
31
+ }
32
+
33
+ html {
34
+ font-family: sans-serif;
35
+ line-height: 1.15;
36
+ -webkit-text-size-adjust: 100%;
37
+ -webkit-tap-highlight-color: ${themeVars.transparent};
38
+ }
39
+
40
+ // body sizing/font/color + scrollbar rules live in fibery-ui/index.html so they apply
41
+ // before the JS bundle (Linaria CSS chunk) loads — keeps loading splash and any
42
+ // pre-React DOM rendered correctly without reflow.
43
+
44
+ input[readonly] {
45
+ cursor: default;
46
+ }
47
+
48
+ // react-split-pane handle classes. Only mounted after React renders.
49
+ .Resizer {
50
+ background: ${themeVars.colorAccent};
51
+ opacity: 0;
52
+ z-index: 1000;
53
+ box-sizing: border-box;
54
+ background-clip: padding-box;
55
+ }
56
+ .Resizer:hover {
57
+ transition: all 0.2s ease-in;
58
+ opacity: 1;
59
+ }
60
+ .Resizer.vertical {
61
+ width: 10px;
62
+ margin: 0 -5px;
63
+ border-left: 4px solid ${themeVars.transparent};
64
+ border-right: 4px solid ${themeVars.transparent};
65
+ cursor: col-resize;
66
+ }
67
+ .Resizer.disabled {
68
+ cursor: not-allowed;
69
+ }
70
+ .Resizer.disabled:hover {
71
+ border-color: ${themeVars.transparent};
72
+ }
73
+
74
+ // Removes the focus ring on programmatically-focused containers (Modal, Drawer).
75
+ [tabindex="-1"]:focus {
76
+ outline: none !important;
77
+ }
78
+
79
+ hr {
80
+ box-sizing: content-box;
81
+ height: 0;
82
+ overflow: visible;
83
+ }
84
+
85
+ // FIXME: heading/paragraph/list/blockquote/figure/pre margins are antd's typography
86
+ // opinions. We mostly style headings via Linaria classes, but unstyled <h*> in plain
87
+ // markdown/HTML content rely on these. Audit + move to a typography module.
88
+ // Heading color lives in fibery-ui/index.html (load-bearing pre-React).
89
+ h1,
90
+ h2,
91
+ h3,
92
+ h4,
93
+ h5,
94
+ h6 {
95
+ margin-top: 0;
96
+ margin-bottom: 0.5em;
97
+ font-weight: 500;
98
+ }
99
+ p {
100
+ margin-top: 0;
101
+ margin-bottom: 1em;
102
+ }
103
+ abbr[title],
104
+ abbr[data-original-title] {
105
+ text-decoration: underline dotted;
106
+ border-bottom: 0;
107
+ cursor: help;
108
+ }
109
+ address {
110
+ margin-bottom: 1em;
111
+ font-style: normal;
112
+ line-height: inherit;
113
+ }
114
+ input[type="text"],
115
+ input[type="password"],
116
+ input[type="number"],
117
+ textarea {
118
+ -webkit-appearance: none;
119
+ }
120
+ ol,
121
+ ul,
122
+ dl {
123
+ margin-top: 0;
124
+ margin-bottom: 1em;
125
+ }
126
+ ol ol,
127
+ ul ul,
128
+ ol ul,
129
+ ul ol {
130
+ margin-bottom: 0;
131
+ }
132
+ dt {
133
+ font-weight: 500;
134
+ }
135
+ dd {
136
+ margin-bottom: 0.5em;
137
+ margin-left: 0;
138
+ }
139
+ blockquote {
140
+ margin: 0 0 1em;
141
+ }
142
+ dfn {
143
+ font-style: italic;
144
+ }
145
+ b,
146
+ strong {
147
+ font-weight: bolder;
148
+ }
149
+ small {
150
+ font-size: 80%;
151
+ }
152
+ sub,
153
+ sup {
154
+ position: relative;
155
+ font-size: 75%;
156
+ line-height: 0;
157
+ vertical-align: baseline;
158
+ }
159
+ sub {
160
+ bottom: -0.25em;
161
+ }
162
+ sup {
163
+ top: -0.5em;
164
+ }
165
+
166
+ // Link colors used to come from PatchAntdStylesPlugin substituting antd's #1890ff
167
+ // for our token; sourcing from themeVars now. antd's transition was 0.3s ≈ transitions.slow.
168
+ a {
169
+ color: ${themeVars.linkColor};
170
+ text-decoration: none;
171
+ background-color: transparent;
172
+ outline: none;
173
+ cursor: pointer;
174
+ transition: color ${transitions.slow};
175
+ }
176
+ a:hover {
177
+ color: ${themeVars.linkHoverColor};
178
+ }
179
+ a:active {
180
+ color: ${themeVars.linkColor};
181
+ }
182
+ a:focus {
183
+ text-decoration: none;
184
+ outline: 0;
185
+ }
186
+ a[disabled] {
187
+ color: ${themeVars.disabledInversedTextColor};
188
+ cursor: not-allowed;
189
+ pointer-events: none;
190
+ }
191
+
192
+ pre,
193
+ code,
194
+ kbd,
195
+ samp {
196
+ font-size: 1em;
197
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
198
+ }
199
+ pre {
200
+ margin-top: 0;
201
+ margin-bottom: 1em;
202
+ overflow: auto;
203
+ }
204
+ figure {
205
+ margin: 0 0 1em;
206
+ }
207
+ img {
208
+ vertical-align: middle;
209
+ border-style: none;
210
+ }
211
+ svg:not(:root) {
212
+ overflow: hidden;
213
+ }
214
+
215
+ // touch-action: manipulation suppresses the 300ms tap delay on mobile.
216
+ a,
217
+ area,
218
+ button,
219
+ [role="button"],
220
+ input:not([type="range"]),
221
+ label,
222
+ select,
223
+ summary,
224
+ textarea {
225
+ touch-action: manipulation;
226
+ }
227
+
228
+ table {
229
+ border-collapse: collapse;
230
+ }
231
+ caption {
232
+ padding-top: 0.75em;
233
+ padding-bottom: 0.3em;
234
+ color: ${themeVars.disabledTextColor};
235
+ text-align: left;
236
+ caption-side: bottom;
237
+ }
238
+
239
+ // Form-control font inheritance. Without this every <button>/<input>/<select>/<textarea>
240
+ // renders in UA font (Times-ish on most platforms) — every form in the app would break.
241
+ input,
242
+ button,
243
+ select,
244
+ optgroup,
245
+ textarea {
246
+ margin: 0;
247
+ color: inherit;
248
+ font-size: inherit;
249
+ font-family: inherit;
250
+ line-height: inherit;
251
+ }
252
+ button,
253
+ input {
254
+ overflow: visible;
255
+ }
256
+ button,
257
+ select {
258
+ text-transform: none;
259
+ }
260
+ // Restores native button rendering on iOS Safari for type=reset/submit and bare [type=button].
261
+ button,
262
+ html [type="button"],
263
+ [type="reset"],
264
+ [type="submit"] {
265
+ -webkit-appearance: button;
266
+ }
267
+ button::-moz-focus-inner,
268
+ [type="button"]::-moz-focus-inner,
269
+ [type="reset"]::-moz-focus-inner,
270
+ [type="submit"]::-moz-focus-inner {
271
+ padding: 0;
272
+ border-style: none;
273
+ }
274
+ input[type="radio"],
275
+ input[type="checkbox"] {
276
+ box-sizing: border-box;
277
+ padding: 0;
278
+ }
279
+ // Forces date/time inputs into listbox appearance (Safari otherwise collapses them).
280
+ input[type="date"],
281
+ input[type="time"],
282
+ input[type="datetime-local"],
283
+ input[type="month"] {
284
+ -webkit-appearance: listbox;
285
+ }
286
+ textarea {
287
+ overflow: auto;
288
+ resize: vertical;
289
+ }
290
+ fieldset {
291
+ min-width: 0;
292
+ margin: 0;
293
+ padding: 0;
294
+ border: 0;
295
+ }
296
+ legend {
297
+ display: block;
298
+ width: 100%;
299
+ max-width: 100%;
300
+ margin-bottom: 0.5em;
301
+ padding: 0;
302
+ color: inherit;
303
+ font-size: 1.5em;
304
+ line-height: inherit;
305
+ white-space: normal;
306
+ }
307
+ progress {
308
+ vertical-align: baseline;
309
+ }
310
+ [type="number"]::-webkit-inner-spin-button,
311
+ [type="number"]::-webkit-outer-spin-button {
312
+ height: auto;
313
+ }
314
+ [type="search"] {
315
+ outline-offset: -2px;
316
+ -webkit-appearance: none;
317
+ }
318
+ [type="search"]::-webkit-search-cancel-button,
319
+ [type="search"]::-webkit-search-decoration {
320
+ -webkit-appearance: none;
321
+ }
322
+ ::-webkit-file-upload-button {
323
+ font: inherit;
324
+ -webkit-appearance: button;
325
+ }
326
+ output {
327
+ display: inline-block;
328
+ }
329
+ summary {
330
+ display: list-item;
331
+ }
332
+ template {
333
+ display: none;
334
+ }
335
+ [hidden] {
336
+ display: none !important;
337
+ }
338
+ mark {
339
+ padding: 0.2em;
340
+ background-color: ${themeVars.infoBox};
341
+ }
342
+
343
+ ::-moz-selection {
344
+ color: ${themeVars.textColor};
345
+ background: ${themeVars.textSelectionColor};
346
+ }
347
+ ::selection {
348
+ color: ${themeVars.textColor};
349
+ background: ${themeVars.textSelectionColor};
350
+ }
351
+ }
352
+ `;
@@ -1,8 +1,9 @@
1
- import type {InputProps} from "antd/lib/input";
1
+ import type {ComponentProps} from "react";
2
2
 
3
3
  import {StyledInput, StyledTextArea} from "./input";
4
4
 
5
5
  export const AntInput = StyledInput;
6
6
  export const AntTextArea = StyledTextArea;
7
7
 
8
- export type AntInputProps = InputProps;
8
+ // infer from the wrapper so status/bordered/wrapper props are included
9
+ export type AntInputProps = ComponentProps<typeof AntInput>;
@@ -1,52 +1,138 @@
1
1
  import {css} from "@linaria/core";
2
- import "antd/lib/input-number/style/css";
3
- import InputNumber from "antd/lib/input-number";
2
+ import InputNumber from "rc-input-number-v7";
3
+ import type {ComponentProps} from "react";
4
+ import {forwardRef} from "react";
4
5
 
5
- import {textStyles, themeVars} from "../design-system";
6
+ import {textStyles, themeVars, transitionDuration} from "../design-system";
7
+ import ArrowBottomIcon from "../icons/react/arrow-bottom";
8
+ import ArrowTopIcon from "../icons/react/arrow-top";
6
9
  import {getWrapper} from "./get-wrapper";
7
10
  import {inputOverrides} from "./styles";
8
11
  import {wrapWith} from "./utils";
9
12
 
13
+ type InputNumberPropsAny = ComponentProps<typeof InputNumber>;
14
+
15
+ // rc-input-number renders empty .ant-input-number-handler-up/-down-inner spans unless
16
+ // upNode/downNode are passed. antd's wrapper supplied chevron icons; we do the same.
17
+ const upNode = <ArrowTopIcon className="ant-input-number-handler-up-inner" iconSize={12} />;
18
+ const downNode = <ArrowBottomIcon className="ant-input-number-handler-down-inner" iconSize={12} />;
19
+
20
+ const PrefixedInputNumber = forwardRef<HTMLInputElement, InputNumberPropsAny>(function PrefixedInputNumber(props, ref) {
21
+ return <InputNumber prefixCls="ant-input-number" upHandler={upNode} downHandler={downNode} {...props} ref={ref} />;
22
+ });
23
+
10
24
  const inputNumberStyles = css`
11
25
  ${{
12
26
  "& .ant-input-number": {
27
+ boxSizing: "border-box",
28
+ position: "relative",
29
+ display: "inline-flex",
30
+ alignItems: "stretch",
31
+ width: "90px",
13
32
  height: "auto",
14
33
  border: "none",
15
34
  ...textStyles.regular,
16
35
  backgroundColor: themeVars.transparent,
17
36
  },
37
+ "& .ant-input-number-input-wrap": {
38
+ flex: 1,
39
+ minWidth: 0,
40
+ },
41
+ "& .ant-input-number-input": {
42
+ ...inputOverrides.main,
43
+ boxSizing: "border-box",
44
+ width: "100%",
45
+ height: "100%",
46
+ appearance: "textfield",
47
+ },
48
+ "& .ant-input-number-input:placeholder-shown": {
49
+ textOverflow: "ellipsis",
50
+ },
51
+ "& .ant-input-number-input::-webkit-inner-spin-button, & .ant-input-number-input::-webkit-outer-spin-button": {
52
+ margin: 0,
53
+ appearance: "none",
54
+ },
18
55
  "& .ant-input-number-handler-wrap": {
56
+ position: "absolute",
19
57
  top: 1,
20
58
  bottom: 1,
21
59
  right: 1,
22
- height: "auto",
60
+ width: 22,
23
61
  backgroundColor: themeVars.transparent,
24
62
  background: themeVars.transparent,
63
+ // antd hid the stepper arrows until hover/focus; reproduce that (dropped with the vendored CSS)
64
+ opacity: 0,
65
+ transition: `opacity ${transitionDuration.normal} linear ${transitionDuration.faster}`,
25
66
  },
67
+ "& .ant-input-number-handler-wrap:hover .ant-input-number-handler": {
68
+ height: "40%",
69
+ },
70
+ "& .ant-input-number:hover .ant-input-number-handler-wrap, & .ant-input-number-focused .ant-input-number-handler-wrap":
71
+ {
72
+ opacity: 1,
73
+ },
26
74
  "& .ant-input-number-focused": {boxShadow: "none"},
75
+ "& .ant-input-number-handler-up, & .ant-input-number-handler-down": {
76
+ cursor: "pointer",
77
+ },
78
+ "& .ant-input-number-handler-up:hover, & .ant-input-number-handler-down:hover": {
79
+ height: "60% !important",
80
+ },
81
+ "& .ant-input-number-handler-up-disabled, & .ant-input-number-handler-down-disabled": {
82
+ cursor: "not-allowed",
83
+ },
84
+ "& .ant-input-number-handler-up-disabled .ant-input-number-handler-up-inner, & .ant-input-number-handler-down-disabled .ant-input-number-handler-down-inner":
85
+ {
86
+ color: themeVars.disabledTextColor,
87
+ },
88
+ "& .ant-input-number-handler:not(.ant-input-number-handler-up-disabled):not(.ant-input-number-handler-down-disabled):hover .ant-input-number-handler-up-inner, & .ant-input-number-handler:not(.ant-input-number-handler-up-disabled):not(.ant-input-number-handler-down-disabled):hover .ant-input-number-handler-down-inner":
89
+ {
90
+ color: themeVars.textColor,
91
+ },
27
92
  "& .ant-input-number-handler-down": {borderTop: `${themeVars.borderSolidSeparator} !important`},
28
93
  "& .ant-input-number-input:hover": inputOverrides.hover,
29
94
  "& .ant-input-number-input:focus, & .ant-input-number-input:active, & .ant-input-number-focused .ant-input-number-input":
30
95
  inputOverrides.focus,
31
- "& .ant-input-number-input": inputOverrides.main,
32
96
  "& .ant-input-number-disabled": {backgroundColor: themeVars.transparent},
33
97
  "& .ant-input-number-disabled .ant-input-number-input": inputOverrides.disabled,
98
+ "& .ant-input-number-disabled .ant-input-number-handler-wrap, & .ant-input-number-readonly .ant-input-number-handler-wrap":
99
+ {
100
+ display: "none",
101
+ },
34
102
  "& .ant-input-number-handler-up-inner, & .ant-input-number-handler-down-inner": {
35
103
  color: themeVars.iconColor,
104
+ position: "absolute",
105
+ right: 4,
106
+ width: 12,
107
+ height: 12,
108
+ lineHeight: "12px",
109
+ transition: `all ${transitionDuration.faster} linear`,
110
+ userSelect: "none",
111
+ },
112
+ "& .ant-input-number-handler-up-inner": {
113
+ top: "50%",
114
+ marginTop: -5,
115
+ },
116
+ "& .ant-input-number-handler-down-inner": {
117
+ top: "50%",
118
+ transform: "translateY(-50%)",
36
119
  },
37
120
  "& .ant-input-number-handler": {
121
+ position: "relative",
122
+ display: "block",
123
+ width: "100%",
124
+ height: "50%",
125
+ overflow: "hidden",
38
126
  color: themeVars.iconColor,
127
+ lineHeight: 0,
128
+ textAlign: "center",
39
129
  borderLeft: themeVars.borderSolidSeparator,
130
+ transition: `all ${transitionDuration.faster} linear`,
40
131
  "&:active": {
41
132
  backgroundColor: themeVars.transparent,
42
133
  },
43
- "&:hover": {
44
- "& .ant-input-number-handler-up-inner, & .ant-input-number-handler-down-inner": {
45
- color: themeVars.textColor,
46
- },
47
- },
48
134
  },
49
135
  }}
50
136
  `;
51
137
 
52
- export const AntInputNumber = wrapWith(getWrapper(inputNumberStyles), InputNumber);
138
+ export const AntInputNumber = wrapWith(getWrapper(inputNumberStyles), PrefixedInputNumber);
@@ -1,14 +1,91 @@
1
- import {css} from "@linaria/core";
2
- import Input from "antd/lib/input";
3
- import "antd/lib/input/style/css";
1
+ import {css, cx} from "@linaria/core";
2
+ import RcInput from "rc-input";
3
+ import type {InputProps, InputRef} from "rc-input";
4
+ import RcTextArea from "rc-textarea";
5
+ import type {TextAreaProps} from "rc-textarea";
6
+ import type {ResizableTextAreaRef} from "rc-textarea/lib/ResizableTextArea";
7
+ import {forwardRef, useImperativeHandle, useMemo, useRef} from "react";
4
8
 
5
- import {tabularNumsOff, textStyles, themeVars} from "../design-system";
9
+ import {space, tabularNumsOff, textStyles, themeVars} from "../design-system";
10
+ import CloseCircleFilledIcon from "../icons/react/cross-circle";
6
11
  import {mobileRootSelector} from "../mobile-styles";
7
12
  import {getWrapper} from "./get-wrapper";
8
13
  import {inputStyles} from "./styles";
9
14
  import {wrapWith} from "./utils";
10
15
 
11
- const TextArea = Input.TextArea;
16
+ const clearIconNode = <CloseCircleFilledIcon />;
17
+
18
+ export type {InputRef};
19
+
20
+ export interface InputFocusOptions extends FocusOptions {
21
+ cursor?: "start" | "end" | "all";
22
+ }
23
+
24
+ export interface TextAreaRef {
25
+ focus: (options?: InputFocusOptions) => void;
26
+ blur: () => void;
27
+ resizableTextArea?: ResizableTextAreaRef;
28
+ }
29
+
30
+ type AntInputProps = Omit<InputProps, "status"> & {
31
+ status?: "error";
32
+ bordered?: boolean;
33
+ };
34
+
35
+ const Input = forwardRef<InputRef, AntInputProps>(function Input(
36
+ {status, className, allowClear, bordered = true, ...props},
37
+ ref
38
+ ) {
39
+ const statusClass = status === "error" ? "ant-input-status-error" : undefined;
40
+ const allowClearProp = useMemo(() => {
41
+ if (allowClear === true) {
42
+ return {clearIcon: clearIconNode};
43
+ }
44
+ return allowClear;
45
+ }, [allowClear]);
46
+ return (
47
+ <RcInput
48
+ prefixCls="ant-input"
49
+ ref={ref}
50
+ allowClear={allowClearProp}
51
+ className={cx(className, statusClass, !bordered && "ant-input-borderless")}
52
+ {...props}
53
+ />
54
+ );
55
+ });
56
+
57
+ type AntTextAreaProps = Omit<TextAreaProps, "status"> & {
58
+ status?: "error";
59
+ };
60
+
61
+ const TextArea = forwardRef<TextAreaRef, AntTextAreaProps>(function TextArea({status, className, ...props}, ref) {
62
+ const innerRef = useRef<RcTextArea>(null);
63
+ useImperativeHandle(ref, () => ({
64
+ focus: (options) => {
65
+ const textarea = innerRef.current?.resizableTextArea?.textArea;
66
+ if (!textarea) {
67
+ return;
68
+ }
69
+ textarea.focus(options);
70
+ const len = textarea.value.length;
71
+ if (options?.cursor === "start") {
72
+ textarea.setSelectionRange(0, 0);
73
+ } else if (options?.cursor === "end") {
74
+ textarea.setSelectionRange(len, len);
75
+ } else if (options?.cursor === "all") {
76
+ textarea.setSelectionRange(0, len);
77
+ }
78
+ },
79
+ blur: () => innerRef.current?.blur(),
80
+ get resizableTextArea() {
81
+ return innerRef.current?.resizableTextArea;
82
+ },
83
+ }));
84
+ const statusClass = status === "error" ? "ant-input-status-error" : undefined;
85
+ return (
86
+ <RcTextArea prefixCls="ant-input" ref={innerRef} className={cx("ant-input", className, statusClass)} {...props} />
87
+ );
88
+ });
12
89
 
13
90
  export const transparentInputStyle = css`
14
91
  ${{
@@ -18,6 +95,7 @@ export const transparentInputStyle = css`
18
95
  "& input, & textarea, & .ant-input-affix-wrapper": {
19
96
  padding: 0,
20
97
  border: "none",
98
+ outline: "none",
21
99
  width: "100%",
22
100
  resize: "none",
23
101
  borderRadius: 0,
@@ -29,6 +107,50 @@ export const transparentInputStyle = css`
29
107
  ...textStyles.big,
30
108
  },
31
109
  },
110
+ "& .ant-input-affix-wrapper": {
111
+ display: "inline-flex",
112
+ alignItems: "center",
113
+ position: "relative",
114
+ minWidth: 0,
115
+ },
116
+ "& .ant-input-affix-wrapper > .ant-input": {
117
+ flex: 1,
118
+ minWidth: 0,
119
+ fontSize: "inherit",
120
+ border: "none",
121
+ outline: "none",
122
+ },
123
+ "& .ant-input-affix-wrapper > .ant-input:focus": {
124
+ boxShadow: "none !important",
125
+ },
126
+ "& .ant-input-affix-wrapper::before": {
127
+ width: 0,
128
+ visibility: "hidden",
129
+ content: "'\\a0'",
130
+ },
131
+ "& .ant-input-prefix, & .ant-input-suffix": {
132
+ display: "flex",
133
+ flex: "none",
134
+ alignItems: "center",
135
+ },
136
+ "& .ant-input-prefix > *:not(:last-child), & .ant-input-suffix > *:not(:last-child)": {
137
+ marginRight: space.s8,
138
+ },
139
+ "& .ant-input-prefix": {
140
+ marginRight: space.s4,
141
+ },
142
+ "& .ant-input-suffix": {
143
+ marginLeft: space.s4,
144
+ },
145
+ "& .ant-input-clear-icon": {
146
+ display: "inline-flex",
147
+ alignItems: "center",
148
+ lineHeight: 1,
149
+ cursor: "pointer",
150
+ },
151
+ "& .ant-input-clear-icon-hidden": {
152
+ visibility: "hidden",
153
+ },
32
154
  "& textarea.ant-input": {
33
155
  fontVariant: "inherit",
34
156
  },
@@ -54,8 +176,5 @@ export const StyledTextArea = wrapWith(InputWrapper, TextArea);
54
176
 
55
177
  export const TransparentInputWrapper = getWrapper(transparentInputStyle);
56
178
 
57
- export type TextAreaRef = React.ElementRef<typeof TextArea>;
58
179
  export const AntTransparentTextArea = wrapWith(TransparentInputWrapper, TextArea);
59
-
60
- export type InputRef = React.ElementRef<typeof Input>;
61
180
  export const AntTransparentInput = wrapWith(TransparentInputWrapper, Input);