@guardian/stand 0.0.20 → 0.0.21

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 (29) hide show
  1. package/dist/components/menu/Menu.cjs +1 -7
  2. package/dist/components/menu/Menu.js +1 -9
  3. package/dist/components/menu/styles.cjs +25 -11
  4. package/dist/components/menu/styles.js +25 -11
  5. package/dist/components/text-input/TextInput.cjs +28 -0
  6. package/dist/components/text-input/TextInput.js +12 -0
  7. package/dist/components/text-input/styles.cjs +35 -0
  8. package/dist/components/text-input/styles.js +32 -0
  9. package/dist/index.cjs +2 -0
  10. package/dist/index.js +1 -0
  11. package/dist/styleD/build/css/component/menu.css +2 -0
  12. package/dist/styleD/build/css/component/textInput.css +29 -0
  13. package/dist/styleD/build/typescript/component/menu.cjs +5 -1
  14. package/dist/styleD/build/typescript/component/menu.js +5 -1
  15. package/dist/styleD/build/typescript/component/textInput.cjs +45 -0
  16. package/dist/styleD/build/typescript/component/textInput.js +43 -0
  17. package/dist/text-input.cjs +9 -0
  18. package/dist/text-input.js +2 -0
  19. package/dist/types/components/menu/styles.d.ts +1 -1
  20. package/dist/types/components/text-input/TextInput.d.ts +2 -0
  21. package/dist/types/components/text-input/sandbox.d.ts +5 -0
  22. package/dist/types/components/text-input/styles.d.ts +7 -0
  23. package/dist/types/components/text-input/types.d.ts +4 -0
  24. package/dist/types/index.d.ts +2 -0
  25. package/dist/types/menu.d.ts +0 -1
  26. package/dist/types/styleD/build/typescript/component/menu.d.ts +4 -0
  27. package/dist/types/styleD/build/typescript/component/textInput.d.ts +45 -0
  28. package/dist/types/text-input.d.ts +20 -0
  29. package/package.json +11 -7
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('@emotion/react/jsx-runtime');
4
- var focus = require('@react-aria/focus');
5
4
  var React = require('react');
6
5
  var reactAriaComponents = require('react-aria-components');
7
6
  var mergeDeep = require('../../util/mergeDeep.cjs');
@@ -83,15 +82,10 @@ function MenuItem({
83
82
  }) {
84
83
  const mergedTheme = mergeDeep.mergeDeep(styles.defaultMenuItemTheme, theme);
85
84
  const textValue = props.textValue ?? (typeof label === "string" ? label : void 0);
86
- const { isFocusVisible, focusProps } = focus.useFocusRing();
87
85
  return /* @__PURE__ */ jsxRuntime.jsx(
88
86
  reactAriaComponents.MenuItem,
89
87
  {
90
- ...focusProps,
91
- css: [
92
- styles.menuItemStyles(mergedTheme, { description }, isFocusVisible),
93
- cssOverrides
94
- ],
88
+ css: [styles.menuItemStyles(mergedTheme, { description }), cssOverrides],
95
89
  ...props,
96
90
  textValue,
97
91
  children: ({ isSelected, selectionMode }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -1,5 +1,4 @@
1
1
  import { jsxs, jsx, Fragment } from '@emotion/react/jsx-runtime';
2
- import { useFocusRing } from '@react-aria/focus';
3
2
  import React from 'react';
4
3
  import { MenuTrigger, Menu as Menu$1, MenuItem as MenuItem$1, MenuSection as MenuSection$1, Header, Separator, Popover as Popover$1 } from 'react-aria-components';
5
4
  import { mergeDeep } from '../../util/mergeDeep.js';
@@ -36,14 +35,7 @@ function MenuSection({ name, size = "md", theme = {}, cssOverrides, children, ..
36
35
  function MenuItem({ label, description, aside, icon, size = "md", theme = {}, cssOverrides, ...props }) {
37
36
  const mergedTheme = mergeDeep(defaultMenuItemTheme, theme);
38
37
  const textValue = props.textValue ?? (typeof label === "string" ? label : void 0);
39
- const { isFocusVisible, focusProps } = useFocusRing();
40
- return jsx(
41
- MenuItem$1,
42
- { ...focusProps, css: [
43
- menuItemStyles(mergedTheme, { description }, isFocusVisible),
44
- cssOverrides
45
- ], ...props, textValue, children: ({ isSelected, selectionMode }) => jsxs(Fragment, { children: [icon && selectionMode === "none" ? jsx(Icon, { size, cssOverrides: menuItemIconStyles(mergedTheme, { size }), children: icon }) : null, isSelected && selectionMode === "multiple" ? jsx(Icon, { size, symbol: "check_box", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, !isSelected && selectionMode === "multiple" ? jsx(Icon, { size, symbol: "check_box_outline_blank", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, isSelected && selectionMode === "single" ? jsx(Icon, { size, symbol: "radio_button_checked", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, !isSelected && selectionMode === "single" ? jsx(Icon, { size, symbol: "radio_button_unchecked", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, jsx("div", { css: menuItemLabelStyles(mergedTheme), children: label }), description && jsx("div", { css: menuItemDescriptionStyles(mergedTheme), children: description }), aside && jsx("div", { css: menuItemAsideStyles(mergedTheme), children: aside })] }) }
46
- );
38
+ return jsx(MenuItem$1, { css: [menuItemStyles(mergedTheme, { description }), cssOverrides], ...props, textValue, children: ({ isSelected, selectionMode }) => jsxs(Fragment, { children: [icon && selectionMode === "none" ? jsx(Icon, { size, cssOverrides: menuItemIconStyles(mergedTheme, { size }), children: icon }) : null, isSelected && selectionMode === "multiple" ? jsx(Icon, { size, symbol: "check_box", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, !isSelected && selectionMode === "multiple" ? jsx(Icon, { size, symbol: "check_box_outline_blank", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, isSelected && selectionMode === "single" ? jsx(Icon, { size, symbol: "radio_button_checked", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, !isSelected && selectionMode === "single" ? jsx(Icon, { size, symbol: "radio_button_unchecked", cssOverrides: menuItemIconStyles(mergedTheme, { size }) }) : null, jsx("div", { css: menuItemLabelStyles(mergedTheme), children: label }), description && jsx("div", { css: menuItemDescriptionStyles(mergedTheme), children: description }), aside && jsx("div", { css: menuItemAsideStyles(mergedTheme), children: aside })] }) });
47
39
  }
48
40
  function Menu({ theme = {}, size = "md", popoverProps, menuTriggerProps, children, cssOverrides, ...props }) {
49
41
  const mergedTheme = mergeDeep(defaultMenuTheme, theme);
@@ -24,7 +24,7 @@ const menuSectionHeaderStyles = (theme, { size }) => react.css`
24
24
  ${typography.convertTypographyToEmotionStringStyle(theme.header[size].typography)}
25
25
  `;
26
26
  const defaultMenuItemTheme = menu.componentMenu.menuItem;
27
- const menuItemStyles = (theme, { description }, isFocusVisible = false) => react.css`
27
+ const menuItemStyles = (theme, { description }) => react.css`
28
28
  display: ${theme.shared.display};
29
29
  grid-template-columns: ${theme.shared["grid-template-columns"]};
30
30
  grid-template-areas: ${description ? theme.shared["grid-template-areas-with-description"] : theme.shared["grid-template-areas"]};
@@ -37,17 +37,31 @@ const menuItemStyles = (theme, { description }, isFocusVisible = false) => react
37
37
  &:last-child {
38
38
  border-bottom: ${theme.shared[":last-child"]["border-bottom"]};
39
39
  }
40
- &[data-hovered],
41
- &:hover {
42
- background: ${theme.shared[":hover"]["background-color"]};
40
+
41
+ /* Hovering adds data-focused and the item stays focused after hovering away */
42
+ &[data-focused] {
43
+ background-color: ${theme.shared[":hover"]["background-color"]};
44
+ }
45
+ &[data-hovered] {
46
+ outline: ${theme.shared[":hover"].outline};
47
+ }
48
+
49
+ /* Override default browser focus behaviour */
50
+ :focus-visible {
51
+ outline: none;
52
+ }
53
+
54
+ /* focus visible used for keyboard focus */
55
+ &[data-focus-visible] {
56
+ outline: ${theme.shared[":focus-visible"]["outline"]};
57
+ outline-offset: ${theme.shared[":focus-visible"]["outline-offset"]};
58
+ background-color: ${theme.shared[":hover"]["background-color"]};
59
+ }
60
+
61
+ /* Must be last to take precedence */
62
+ &[data-pressed] {
63
+ background-color: ${theme.shared[":pressed"]["background-color"]};
43
64
  }
44
- ${isFocusVisible ? react.css`
45
- outline: ${theme.shared[":focus-visible"]["outline"]};
46
- outline-offset: ${theme.shared[":focus-visible"]["outline-offset"]};
47
- background: ${theme.shared[":hover"]["background-color"]};
48
- ` : react.css`
49
- outline: none;
50
- `}
51
65
  `;
52
66
  const menuItemIconStyles = (theme, { size }) => react.css`
53
67
  grid-area: ${theme.shared.icon["grid-area"]};
@@ -22,7 +22,7 @@ const menuSectionHeaderStyles = (theme, { size }) => css`
22
22
  ${convertTypographyToEmotionStringStyle(theme.header[size].typography)}
23
23
  `;
24
24
  const defaultMenuItemTheme = componentMenu.menuItem;
25
- const menuItemStyles = (theme, { description }, isFocusVisible = false) => css`
25
+ const menuItemStyles = (theme, { description }) => css`
26
26
  display: ${theme.shared.display};
27
27
  grid-template-columns: ${theme.shared["grid-template-columns"]};
28
28
  grid-template-areas: ${description ? theme.shared["grid-template-areas-with-description"] : theme.shared["grid-template-areas"]};
@@ -35,17 +35,31 @@ const menuItemStyles = (theme, { description }, isFocusVisible = false) => css`
35
35
  &:last-child {
36
36
  border-bottom: ${theme.shared[":last-child"]["border-bottom"]};
37
37
  }
38
- &[data-hovered],
39
- &:hover {
40
- background: ${theme.shared[":hover"]["background-color"]};
38
+
39
+ /* Hovering adds data-focused and the item stays focused after hovering away */
40
+ &[data-focused] {
41
+ background-color: ${theme.shared[":hover"]["background-color"]};
42
+ }
43
+ &[data-hovered] {
44
+ outline: ${theme.shared[":hover"].outline};
45
+ }
46
+
47
+ /* Override default browser focus behaviour */
48
+ :focus-visible {
49
+ outline: none;
50
+ }
51
+
52
+ /* focus visible used for keyboard focus */
53
+ &[data-focus-visible] {
54
+ outline: ${theme.shared[":focus-visible"]["outline"]};
55
+ outline-offset: ${theme.shared[":focus-visible"]["outline-offset"]};
56
+ background-color: ${theme.shared[":hover"]["background-color"]};
57
+ }
58
+
59
+ /* Must be last to take precedence */
60
+ &[data-pressed] {
61
+ background-color: ${theme.shared[":pressed"]["background-color"]};
41
62
  }
42
- ${isFocusVisible ? css`
43
- outline: ${theme.shared[":focus-visible"]["outline"]};
44
- outline-offset: ${theme.shared[":focus-visible"]["outline-offset"]};
45
- background: ${theme.shared[":hover"]["background-color"]};
46
- ` : css`
47
- outline: none;
48
- `}
49
63
  `;
50
64
  const menuItemIconStyles = (theme, { size }) => css`
51
65
  grid-area: ${theme.shared.icon["grid-area"]};
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('@emotion/react/jsx-runtime');
4
+ var reactAriaComponents = require('react-aria-components');
5
+ var mergeDeep = require('../../util/mergeDeep.cjs');
6
+ var Form = require('../form/Form.cjs');
7
+ var styles = require('./styles.cjs');
8
+
9
+ function TextInput({
10
+ size = "md",
11
+ isInvalid = false,
12
+ theme = {},
13
+ ...props
14
+ }) {
15
+ const mergedTheme = mergeDeep.mergeDeep(styles.defaultTextInputTheme, theme);
16
+ return /* @__PURE__ */ jsxRuntime.jsx(
17
+ Form.FormInputContainer,
18
+ {
19
+ as: reactAriaComponents.TextField,
20
+ size,
21
+ isInvalid,
22
+ ...props,
23
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Input, { css: styles.textInputStyles(mergedTheme, { size, isInvalid }) })
24
+ }
25
+ );
26
+ }
27
+
28
+ exports.TextInput = TextInput;
@@ -0,0 +1,12 @@
1
+ import { jsx } from '@emotion/react/jsx-runtime';
2
+ import { TextField, Input } from 'react-aria-components';
3
+ import { mergeDeep } from '../../util/mergeDeep.js';
4
+ import { FormInputContainer } from '../form/Form.js';
5
+ import { textInputStyles, defaultTextInputTheme } from './styles.js';
6
+
7
+ function TextInput({ size = "md", isInvalid = false, theme = {}, ...props }) {
8
+ const mergedTheme = mergeDeep(defaultTextInputTheme, theme);
9
+ return jsx(FormInputContainer, { as: TextField, size, isInvalid, ...props, children: jsx(Input, { css: textInputStyles(mergedTheme, { size, isInvalid }) }) });
10
+ }
11
+
12
+ export { TextInput };
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ var react = require('@emotion/react');
4
+ var textInput = require('../../styleD/build/typescript/component/textInput.cjs');
5
+ var typography = require('../../styleD/utils/semantic/typography.cjs');
6
+
7
+ const defaultTextInputTheme = textInput.componentTextInput;
8
+ const textInputStyles = (theme, { size, isInvalid }) => {
9
+ return react.css`
10
+ ${typography.convertTypographyToEmotionStringStyle(theme[size].typography)}
11
+ background-color: ${theme.shared["background-color"]};
12
+ border-radius: ${theme.shared["border-radius"]};
13
+ border: ${theme.shared.border};
14
+ color: ${theme.shared.color};
15
+ cursor: ${theme.shared.cursor};
16
+ height: ${theme[size].height};
17
+ margin-top: ${theme.shared["margin-top"]};
18
+ padding: ${theme.shared.padding.top} ${theme.shared.padding.right}
19
+ ${theme.shared.padding.bottom} ${theme.shared.padding.left};
20
+
21
+ &[data-disabled] {
22
+ background-color: ${theme.shared.disabled.backgroundColor};
23
+ border: ${theme.shared.disabled.border};
24
+ color: ${theme.shared.disabled.color};
25
+ cursor: ${theme.shared.disabled.cursor};
26
+ }
27
+
28
+ ${isInvalid && react.css`
29
+ border: ${theme.shared.error.border};
30
+ `}
31
+ `;
32
+ };
33
+
34
+ exports.defaultTextInputTheme = defaultTextInputTheme;
35
+ exports.textInputStyles = textInputStyles;
@@ -0,0 +1,32 @@
1
+ import { css } from '@emotion/react';
2
+ import { componentTextInput } from '../../styleD/build/typescript/component/textInput.js';
3
+ import { convertTypographyToEmotionStringStyle } from '../../styleD/utils/semantic/typography.js';
4
+
5
+ const defaultTextInputTheme = componentTextInput;
6
+ const textInputStyles = (theme, { size, isInvalid }) => {
7
+ return css`
8
+ ${convertTypographyToEmotionStringStyle(theme[size].typography)}
9
+ background-color: ${theme.shared["background-color"]};
10
+ border-radius: ${theme.shared["border-radius"]};
11
+ border: ${theme.shared.border};
12
+ color: ${theme.shared.color};
13
+ cursor: ${theme.shared.cursor};
14
+ height: ${theme[size].height};
15
+ margin-top: ${theme.shared["margin-top"]};
16
+ padding: ${theme.shared.padding.top} ${theme.shared.padding.right}
17
+ ${theme.shared.padding.bottom} ${theme.shared.padding.left};
18
+
19
+ &[data-disabled] {
20
+ background-color: ${theme.shared.disabled.backgroundColor};
21
+ border: ${theme.shared.disabled.border};
22
+ color: ${theme.shared.disabled.color};
23
+ cursor: ${theme.shared.disabled.cursor};
24
+ }
25
+
26
+ ${isInvalid && css`
27
+ border: ${theme.shared.error.border};
28
+ `}
29
+ `;
30
+ };
31
+
32
+ export { defaultTextInputTheme, textInputStyles };
package/dist/index.cjs CHANGED
@@ -9,6 +9,7 @@ var button = require('./styleD/build/typescript/component/button.cjs');
9
9
  var typography$1 = require('./styleD/build/typescript/component/typography.cjs');
10
10
  var icon = require('./styleD/build/typescript/component/icon.cjs');
11
11
  var favicon = require('./styleD/build/typescript/component/favicon.cjs');
12
+ var textInput = require('./styleD/build/typescript/component/textInput.cjs');
12
13
  var inlineMessage = require('./styleD/build/typescript/component/inlineMessage.cjs');
13
14
  var select = require('./styleD/build/typescript/component/select.cjs');
14
15
  var menu = require('./styleD/build/typescript/component/menu.cjs');
@@ -35,6 +36,7 @@ exports.componentButton = button.componentButton;
35
36
  exports.componentTypography = typography$1.componentTypography;
36
37
  exports.componentIcon = icon.componentIcon;
37
38
  exports.componentFavicon = favicon.componentFavicon;
39
+ exports.componentTextInput = textInput.componentTextInput;
38
40
  exports.componentInlineMessage = inlineMessage.componentInlineMessage;
39
41
  exports.componentSelect = select.componentSelect;
40
42
  exports.componentMenu = menu.componentMenu;
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ export { componentButton } from './styleD/build/typescript/component/button.js';
7
7
  export { componentTypography } from './styleD/build/typescript/component/typography.js';
8
8
  export { componentIcon } from './styleD/build/typescript/component/icon.js';
9
9
  export { componentFavicon } from './styleD/build/typescript/component/favicon.js';
10
+ export { componentTextInput } from './styleD/build/typescript/component/textInput.js';
10
11
  export { componentInlineMessage } from './styleD/build/typescript/component/inlineMessage.js';
11
12
  export { componentSelect } from './styleD/build/typescript/component/select.js';
12
13
  export { componentMenu } from './styleD/build/typescript/component/menu.js';
@@ -63,9 +63,11 @@
63
63
  --component-menu-menu-item-shared-aside-typography-font-width: 95;
64
64
  --component-menu-menu-item-shared-last-child-border-bottom: none;
65
65
  --component-menu-menu-item-shared-hover-background-color: #f6f6f6;
66
+ --component-menu-menu-item-shared-hover-outline: none; /** Override outline focus styles on hover */
66
67
  --component-menu-menu-item-shared-focus-visible-outline: 0.125rem solid
67
68
  #0072a9;
68
69
  --component-menu-menu-item-shared-focus-visible-outline-offset: -0.125rem;
70
+ --component-menu-menu-item-shared-pressed-background-color: #ededed;
69
71
  --component-menu-menu-item-sm-icon-size: 1.125rem;
70
72
  --component-menu-menu-item-sm-icon-line-height: 1.3;
71
73
  --component-menu-menu-item-md-icon-size: 1.25rem;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Do not edit directly, this file was auto-generated.
3
+ */
4
+
5
+ :root {
6
+ --component-text-input-shared-color: #000000;
7
+ --component-text-input-shared-cursor: text;
8
+ --component-text-input-shared-padding-top: 0;
9
+ --component-text-input-shared-padding-right: 0.75rem;
10
+ --component-text-input-shared-padding-bottom: 0;
11
+ --component-text-input-shared-padding-left: 0.75rem;
12
+ --component-text-input-shared-margin-top: 0.5rem; /** spacing between the input itself and the previous element (label or description) minus the flex gap (default 4px), e.g. if the spacing between label and input should be 12px, then margin-top should be 8px */
13
+ --component-text-input-shared-border-radius: 0.25rem;
14
+ --component-text-input-shared-border: 0.0625rem solid #545454;
15
+ --component-text-input-shared-background-color: #ffffff;
16
+ --component-text-input-shared-disabled-background-color: #ffffff;
17
+ --component-text-input-shared-disabled-cursor: not-allowed;
18
+ --component-text-input-shared-disabled-color: #999999;
19
+ --component-text-input-shared-disabled-border: 0.0625rem solid #dcdcdc;
20
+ --component-text-input-shared-error-border: 0.0625rem solid #b42a19;
21
+ --component-text-input-sm-height: 2rem;
22
+ --component-text-input-sm-typography-font: normal 460 0.875rem/1.3 'Open Sans';
23
+ --component-text-input-sm-typography-letter-spacing: 0;
24
+ --component-text-input-sm-typography-font-width: 95;
25
+ --component-text-input-md-height: 2.5rem;
26
+ --component-text-input-md-typography-font: normal 460 1rem/1.3 'Open Sans';
27
+ --component-text-input-md-typography-letter-spacing: 0;
28
+ --component-text-input-md-typography-font-width: 95;
29
+ }
@@ -95,11 +95,15 @@ const componentMenu = {
95
95
  "border-bottom": "none"
96
96
  },
97
97
  ":hover": {
98
- "background-color": "#f6f6f6"
98
+ "background-color": "#f6f6f6",
99
+ outline: "none"
99
100
  },
100
101
  ":focus-visible": {
101
102
  outline: "0.125rem solid #0072a9",
102
103
  "outline-offset": "-0.125rem"
104
+ },
105
+ ":pressed": {
106
+ "background-color": "#ededed"
103
107
  }
104
108
  },
105
109
  sm: {
@@ -93,11 +93,15 @@ const componentMenu = {
93
93
  "border-bottom": "none"
94
94
  },
95
95
  ":hover": {
96
- "background-color": "#f6f6f6"
96
+ "background-color": "#f6f6f6",
97
+ outline: "none"
97
98
  },
98
99
  ":focus-visible": {
99
100
  outline: "0.125rem solid #0072a9",
100
101
  "outline-offset": "-0.125rem"
102
+ },
103
+ ":pressed": {
104
+ "background-color": "#ededed"
101
105
  }
102
106
  },
103
107
  sm: {
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ const componentTextInput = {
4
+ shared: {
5
+ color: "#000000",
6
+ cursor: "text",
7
+ padding: {
8
+ top: "0",
9
+ right: "0.75rem",
10
+ bottom: "0",
11
+ left: "0.75rem"
12
+ },
13
+ "margin-top": "0.5rem",
14
+ "border-radius": "0.25rem",
15
+ border: "0.0625rem solid #545454",
16
+ "background-color": "#ffffff",
17
+ disabled: {
18
+ backgroundColor: "#ffffff",
19
+ cursor: "not-allowed",
20
+ color: "#999999",
21
+ border: "0.0625rem solid #dcdcdc"
22
+ },
23
+ error: {
24
+ border: "0.0625rem solid #b42a19"
25
+ }
26
+ },
27
+ sm: {
28
+ height: "2rem",
29
+ typography: {
30
+ font: "normal 460 0.875rem/1.3 Open Sans",
31
+ letterSpacing: "0rem",
32
+ fontWidth: 95
33
+ }
34
+ },
35
+ md: {
36
+ height: "2.5rem",
37
+ typography: {
38
+ font: "normal 460 1rem/1.3 Open Sans",
39
+ letterSpacing: "0rem",
40
+ fontWidth: 95
41
+ }
42
+ }
43
+ };
44
+
45
+ exports.componentTextInput = componentTextInput;
@@ -0,0 +1,43 @@
1
+ const componentTextInput = {
2
+ shared: {
3
+ color: "#000000",
4
+ cursor: "text",
5
+ padding: {
6
+ top: "0",
7
+ right: "0.75rem",
8
+ bottom: "0",
9
+ left: "0.75rem"
10
+ },
11
+ "margin-top": "0.5rem",
12
+ "border-radius": "0.25rem",
13
+ border: "0.0625rem solid #545454",
14
+ "background-color": "#ffffff",
15
+ disabled: {
16
+ backgroundColor: "#ffffff",
17
+ cursor: "not-allowed",
18
+ color: "#999999",
19
+ border: "0.0625rem solid #dcdcdc"
20
+ },
21
+ error: {
22
+ border: "0.0625rem solid #b42a19"
23
+ }
24
+ },
25
+ sm: {
26
+ height: "2rem",
27
+ typography: {
28
+ font: "normal 460 0.875rem/1.3 Open Sans",
29
+ letterSpacing: "0rem",
30
+ fontWidth: 95
31
+ }
32
+ },
33
+ md: {
34
+ height: "2.5rem",
35
+ typography: {
36
+ font: "normal 460 1rem/1.3 Open Sans",
37
+ letterSpacing: "0rem",
38
+ fontWidth: 95
39
+ }
40
+ }
41
+ };
42
+
43
+ export { componentTextInput };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var TextInput = require('./components/text-input/TextInput.cjs');
4
+ var textInput = require('./styleD/build/typescript/component/textInput.cjs');
5
+
6
+
7
+
8
+ exports.TextInput = TextInput.TextInput;
9
+ exports.componentTextInput = textInput.componentTextInput;
@@ -0,0 +1,2 @@
1
+ export { TextInput } from './components/text-input/TextInput.js';
2
+ export { componentTextInput } from './styleD/build/typescript/component/textInput.js';
@@ -13,7 +13,7 @@ export declare const menuSectionHeaderStyles: (theme: MenuSectionTheme, { size }
13
13
  export type MenuItemTheme = Prettify<ComponentMenu['menuItem']>;
14
14
  export type PartialMenuItemTheme = DeepPartial<MenuItemTheme>;
15
15
  export declare const defaultMenuItemTheme: MenuItemTheme;
16
- export declare const menuItemStyles: (theme: MenuItemTheme, { description }: Pick<MenuItemProps, 'description'>, isFocusVisible?: boolean) => SerializedStyles;
16
+ export declare const menuItemStyles: (theme: MenuItemTheme, { description }: Pick<MenuItemProps, 'description'>) => SerializedStyles;
17
17
  export declare const menuItemIconStyles: (theme: MenuItemTheme, { size }: Required<Pick<MenuItemProps, 'size'>>) => SerializedStyles;
18
18
  export declare const menuItemLabelStyles: (theme: MenuItemTheme) => SerializedStyles;
19
19
  export declare const menuItemDescriptionStyles: (theme: MenuItemTheme) => SerializedStyles;
@@ -0,0 +1,2 @@
1
+ import type { TextInputProps } from './types';
2
+ export declare function TextInput({ size, isInvalid, theme, ...props }: TextInputProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export declare const componentName = "TextInput";
2
+ export declare const componentTsx = "import { TextInput } from '@guardian/stand/text-input';\n\nexport const Component = () => (\n\t<>\n\t\t<TextInput\n\t\t\tlabel=\"Name\"\n\t\t\tdescription=\"This is a description for the text input.\"\n\t\t/>\n\n\t\t<TextInput\n\t\t\tsize=\"sm\"\n\t\t\tlabel=\"Username\"\n\t\t\tisInvalid\n\t\t\tdefaultValue=\"guardian_user\"\n\t\t\terror=\"Username is already taken\"\n\t\t/>\n\n\t\t<TextInput\n\t\t\tlabel=\"Password\"\n\t\t\tdescription=\"Showing a different type\"\n\t\t\ttype=\"password\"\n\t\t/>\n\n\t\t<TextInput label=\"Notes\" isDisabled defaultValue=\"Read only content\" />\n\t</>\n);\n";
3
+ export declare const componentCss = "\n/* import the text input, form, inline message styles */\n@import '@guardian/stand/component/inlineMessage.css';\n@import '@guardian/stand/component/form.css';\n@import '@guardian/stand/component/textInput.css';\n\n/* inline message styles - error */\n.stand-inline-message {\n display: var(--component-inline-message-shared-display);\n align-items: var(--component-inline-message-shared-align-items);\n gap: var(--component-inline-message-shared-gap);\n font: var(--component-inline-message-shared-typography-font);\n letter-spacing: var(\n --component-inline-message-shared-typography-letter-spacing\n );\n font-variation-settings: \"wdth\"\n var(--component-inline-message-shared-typography-font-width);\n}\n\n.stand-inline-message > .material-symbols {\n font-size: var(--component-inline-message-shared-icon-size);\n}\n\n.stand-inline-message > svg {\n width: var(--component-inline-message-shared-icon-size);\n height: var(--component-inline-message-shared-icon-size);\n}\n\n.stand-inline-message-error {\n color: var(--component-inline-message-error-color);\n fill: var(--component-inline-message-error-color);\n}\n\n/* form input container styles */\n\n.stand-form-input-container {\n\tdisplay: var(--component-form-input-shared-container-display);\n\tflex-direction: var(--component-form-input-shared-container-flex-direction);\n\tgap: var(--component-form-input-shared-container-gap);\n\twidth: var(--component-form-input-shared-container-width);\n}\n\n.stand-form-input-container.sm {\n\tmax-width: var(--component-form-input-sm-container-max-width);\n}\n\n.stand-form-input-container.md {\n\tmax-width: var(--component-form-input-md-container-max-width);\n}\n\n.stand-form-input-container > label {\n\tcolor: var(--component-form-input-shared-label-color);\n\tfont: var(--component-form-input-md-label-typography-font);\n\tletter-spacing: var(--component-form-input-md-label-typography-letter-spacing);\n\tfont-variation-settings: \"wdth\" var(--component-form-input-md-label-typography-font-width);\n}\n\n.stand-form-input-container[data-disabled] > label {\n\tcolor: var(--component-form-input-shared-label-disabled-color);\n}\n\n.stand-form-input-container > span.description {\n\tcolor: var(--component-form-input-shared-description-color);\n\tfont: var(--component-form-input-shared-description-typography-font);\n\tletter-spacing: var(--component-form-input-shared-description-typography-letter-spacing);\n\tfont-variation-settings: \"wdth\" var(--component-form-input-shared-description-typography-font-width);\n}\n\n.stand-form-input-container[data-disabled] > span.description {\n\tcolor: var(--component-form-input-shared-description-disabled-color);\n}\n\n/* text input styles */\n\n.stand-text-input {\n\tbackground-color: var(--component-text-input-shared-background-color);\n\tborder-radius: var(--component-text-input-shared-border-radius);\n\tborder: var(--component-text-input-shared-border);\n\tcolor: var(--component-text-input-shared-color);\n\tcursor: var(--component-text-input-shared-cursor);\n\tmargin-top: var(--component-text-input-shared-margin-top);\n\tpadding-top: var(--component-text-input-shared-padding-top);\n\tpadding-right: var(--component-text-input-shared-padding-right);\n\tpadding-bottom: var(--component-text-input-shared-padding-bottom);\n\tpadding-left: var(--component-text-input-shared-padding-left);\n}\n\n.stand-text-input[disabled] {\n\tbackground-color: var(--component-text-input-shared-disabled-background-color);\n\tborder: var(--component-text-input-shared-disabled-border);\n\tcolor: var(--component-text-input-shared-disabled-color);\n\tcursor: var(--component-text-input-shared-disabled-cursor);\n}\n\n.stand-text-input[data-invalid] {\n\tborder: var(--component-text-input-shared-error-border);\n}\n\n.stand-text-input.md {\n\theight: var(--component-text-input-md-height);\n\tfont: var(--component-text-input-md-typography-font);\n\tletter-spacing: var(--component-text-input-md-typography-letter-spacing);\n\tfont-variation-settings: \"wdth\" var(--component-text-input-md-typography-font-width);\n}\n\n.stand-text-input.sm {\n\theight: var(--component-text-input-sm-height);\n\tfont: var(--component-text-input-sm-typography-font);\n\tletter-spacing: var(--component-text-input-sm-typography-letter-spacing);\n\tfont-variation-settings: \"wdth\" var(--component-text-input-sm-typography-font-width);\n}\n";
4
+ export declare const componentHtml = "<div class=\"container flow-column\">\n\t<div class=\"stand-form-input-container md\">\n\t\t<label for=\"name\">Name</label>\n\t\t<span class=\"description\">This is a description for the text input.</span>\n\t\t<input id=\"name\" class=\"stand-text-input md\" type=\"text\" />\n\t</div>\n\t<div class=\"stand-form-input-container sm\">\n\t\t<label for=\"username\">Username</label>\n\t\t<input\n\t\t\tid=\"username\"\n\t\t\tclass=\"stand-text-input sm\"\n\t\t\ttype=\"text\"\n\t\t\tvalue=\"guardian_user\"\n\t\t\tdata-invalid\n\t\t/>\n\t\t<span class=\"stand-inline-message stand-inline-message-error\"><span class=\"material-symbols\">warning</span> Username is already taken</span>\n\t</div>\n\t<div class=\"stand-form-input-container md\">\n\t\t<label for=\"password\">Password</label>\n\t\t<span class=\"description\">Showing a different type</span>\n\t\t<input id=\"password\" class=\"stand-text-input md\" type=\"password\" />\n\t</div>\n\t<div class=\"stand-form-input-container md\" data-disabled>\n\t\t<label for=\"notes\">Notes</label>\n\t\t<input\n\t\t\tid=\"notes\"\n\t\t\tclass=\"stand-text-input md\"\n\t\t\ttype=\"text\"\n\t\t\tvalue=\"Read only content\"\n\t\t\tdisabled\n\t\t/>\n\t</div>\n</div>\n";
5
+ export declare const componentJs = "\nimport { componentTextInput, componentForm, componentInlineMessage } from \"@guardian/stand\";\n\n// example of creating a stylesheet in js\nconst sheet = new CSSStyleSheet();\n\n// apply the rules to the sheet\nsheet.replaceSync(`\n/* inline message styles - error */\n.js-stand-inline-message {\n display: ${componentInlineMessage.shared.display};\n align-items: ${componentInlineMessage.shared['align-items']};\n gap: ${componentInlineMessage.shared.gap};\n font: ${componentInlineMessage.shared.typography.font};\n letter-spacing: ${componentInlineMessage.shared.typography.letterSpacing};\n font-variation-settings: \"wdth\" ${componentInlineMessage.shared.typography.fontWidth};\n}\n\n.js-stand-inline-message > .material-symbols {\n font-size: ${componentInlineMessage.shared.icon.size};\n}\n\n.js-stand-inline-message > svg {\n width: ${componentInlineMessage.shared.icon.size};\n height: ${componentInlineMessage.shared.icon.size};\n}\n\n.js-stand-inline-message-error {\n color: ${componentInlineMessage.error.color};\n fill: ${componentInlineMessage.error.color};\n}\n\n/* form input container styles */\n\n.js-stand-form-input-container {\n\tdisplay: ${componentForm.input.shared.container.display};\n\tflex-direction: ${componentForm.input.shared.container['flex-direction']};\n\tgap: ${componentForm.input.shared.container.gap};\n\twidth: ${componentForm.input.shared.container.width};\n}\n\n.js-stand-form-input-container.sm {\n\tmax-width: ${componentForm.input.sm.container['max-width']};\n}\n\n.js-stand-form-input-container.md {\n\tmax-width: ${componentForm.input.md.container['max-width']};\n}\n\n.js-stand-form-input-container > label {\n\tcolor: ${componentForm.input.shared.label.color};\n\tfont: ${componentForm.input.md.label.typography.font};\n\tletter-spacing: ${componentForm.input.md.label.typography.letterSpacing};\n\tfont-variation-settings: \"wdth\" ${componentForm.input.md.label.typography.fontWidth};\n}\n\n.js-stand-form-input-container[data-disabled] > label {\n\tcolor: ${componentForm.input.shared.label.disabled.color};\n}\n\n.js-stand-form-input-container > span.description {\n\tcolor: ${componentForm.input.shared.description.color};\n\tfont: ${componentForm.input.shared.description.typography.font};\n\tletter-spacing: ${componentForm.input.shared.description.typography.letterSpacing};\n\tfont-variation-settings: \"wdth\" ${componentForm.input.shared.description.typography.fontWidth};\n}\n\n.js-stand-form-input-container[data-disabled] > span.description {\n\tcolor: ${componentForm.input.shared.description.disabled.color};\n}\n\n/* text input styles */\n\n.js-stand-text-input {\n\tbackground-color: ${componentTextInput.shared['background-color']};\n\tborder-radius: ${componentTextInput.shared['border-radius']};\n\tborder: ${componentTextInput.shared.border};\n\tcolor: ${componentTextInput.shared.color};\n\tcursor: ${componentTextInput.shared.cursor};\n\tmargin-top: ${componentTextInput.shared['margin-top']};\n\tpadding-top: ${componentTextInput.shared.padding.top};\n\tpadding-right: ${componentTextInput.shared.padding.right};\n\tpadding-bottom: ${componentTextInput.shared.padding.bottom};\n\tpadding-left: ${componentTextInput.shared.padding.left};\n}\n\n.js-stand-text-input[disabled] {\n\tbackground-color: ${componentTextInput.shared.disabled.backgroundColor};\n\tborder: ${componentTextInput.shared.disabled.border};\n\tcolor: ${componentTextInput.shared.disabled.color};\n\tcursor: ${componentTextInput.shared.disabled.cursor};\n}\n\n.js-stand-text-input[data-invalid] {\n\tborder: ${componentTextInput.shared.errorBorder};\n}\n\n.js-stand-text-input.md {\n\theight: ${componentTextInput.md.height};\n\tfont: ${componentTextInput.md.typography.font};\n\tletter-spacing: ${componentTextInput.md.typography.letterSpacing};\n\tfont-variation-settings: \"wdth\" ${componentTextInput.md.typography.fontWidth};\n}\n\n.js-stand-text-input.sm {\n\theight: ${componentTextInput.sm.height};\n\tfont: ${componentTextInput.sm.typography.font};\n\tletter-spacing: ${componentTextInput.sm.typography.letterSpacing};\n\tfont-variation-settings: \"wdth\" ${componentTextInput.sm.typography.fontWidth};\n}\n`);\n\n// update the document with the sheet\ndocument.adoptedStyleSheets.push(sheet);\n\n// modify the dom with the button components using the generated stylesheet\ndocument.getElementById(\"app\").innerHTML = `\n<div class=\"container flow-column\">\n\t<div class=\"js-stand-form-input-container md\">\n\t\t<label for=\"name\">Name</label>\n\t\t<span class=\"description\">This is a description for the text input.</span>\n\t\t<input id=\"name\" class=\"js-stand-text-input md\" type=\"text\" />\n\t</div>\n\t<div class=\"js-stand-form-input-container sm\">\n\t\t<label for=\"username\">Username</label>\n\t\t<input\n\t\t\tid=\"username\"\n\t\t\tclass=\"js-stand-text-input sm\"\n\t\t\ttype=\"text\"\n\t\t/>\n\t\t<span class=\"js-stand-inline-message js-stand-inline-message-error\"><span class=\"material-symbols\">warning</span> Username is already taken</span>\n\t</div>\n\t<div class=\"js-stand-form-input-container md\">\n\t\t<label for=\"password\">Password</label>\n\t\t<span class=\"description\">Showing a different type</span>\n\t\t<input id=\"password\" class=\"js-stand-text-input md\" type=\"password\" />\n\t</div>\n\t<div class=\"js-stand-form-input-container md\" data-disabled>\n\t\t<label for=\"notes\">Notes</label>\n\t\t<input\n\t\t\tid=\"notes\"\n\t\t\tclass=\"js-stand-text-input md\"\n\t\t\ttype=\"text\"\n\t\t\tvalue=\"Read only content\"\n\t\t\tdisabled\n\t\t />\n\t</div>\n</div>\n`;\n";
@@ -0,0 +1,7 @@
1
+ import type { SerializedStyles } from '@emotion/react';
2
+ import type { ComponentTextInput } from '../../styleD/build/typescript/component/textInput';
3
+ import type { Prettify } from '../../util/types';
4
+ import type { TextInputProps } from './types';
5
+ export type TextInputTheme = Prettify<ComponentTextInput>;
6
+ export declare const defaultTextInputTheme: TextInputTheme;
7
+ export declare const textInputStyles: (theme: TextInputTheme, { size, isInvalid }: Required<Pick<TextInputProps, 'size' | 'isInvalid'>>) => SerializedStyles;
@@ -0,0 +1,4 @@
1
+ import type { TextFieldProps as RACTextInputProps } from 'react-aria-components';
2
+ import type { FormInputContainerDefaultProps } from '../form/types';
3
+ import type { TextInputTheme } from './styles';
4
+ export type TextInputProps = FormInputContainerDefaultProps<RACTextInputProps, TextInputTheme>;
@@ -26,6 +26,8 @@ export { componentIcon } from './styleD/build/typescript/component/icon';
26
26
  export type { ComponentIcon } from './styleD/build/typescript/component/icon';
27
27
  export { componentFavicon } from './styleD/build/typescript/component/favicon';
28
28
  export type { ComponentFavicon } from './styleD/build/typescript/component/favicon';
29
+ export { componentTextInput } from './styleD/build/typescript/component/textInput';
30
+ export type { ComponentTextInput } from './styleD/build/typescript/component/textInput';
29
31
  export { componentInlineMessage } from './styleD/build/typescript/component/inlineMessage';
30
32
  export type { ComponentInlineMessage } from './styleD/build/typescript/component/inlineMessage';
31
33
  export { componentSelect } from './styleD/build/typescript/component/select';
@@ -7,7 +7,6 @@
7
7
  * - `react-dom`
8
8
  * - `typescript`
9
9
  * - `react-aria-components`
10
- * - `@react-aria/focus`
11
10
  *
12
11
  * See the `peerDependencies` section of package.json for compatible versions.
13
12
  *
@@ -97,11 +97,15 @@ export declare const componentMenu: {
97
97
  };
98
98
  ':hover': {
99
99
  'background-color': string;
100
+ outline: string;
100
101
  };
101
102
  ':focus-visible': {
102
103
  outline: string;
103
104
  'outline-offset': string;
104
105
  };
106
+ ':pressed': {
107
+ 'background-color': string;
108
+ };
105
109
  };
106
110
  sm: {
107
111
  icon: {
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Do not edit directly, this file was auto-generated.
3
+ */
4
+ export declare const componentTextInput: {
5
+ shared: {
6
+ color: string;
7
+ cursor: string;
8
+ padding: {
9
+ top: string;
10
+ right: string;
11
+ bottom: string;
12
+ left: string;
13
+ };
14
+ 'margin-top': string;
15
+ 'border-radius': string;
16
+ border: string;
17
+ 'background-color': string;
18
+ disabled: {
19
+ backgroundColor: string;
20
+ cursor: string;
21
+ color: string;
22
+ border: string;
23
+ };
24
+ error: {
25
+ border: string;
26
+ };
27
+ };
28
+ sm: {
29
+ height: string;
30
+ typography: {
31
+ font: string;
32
+ letterSpacing: string;
33
+ fontWidth: number;
34
+ };
35
+ };
36
+ md: {
37
+ height: string;
38
+ typography: {
39
+ font: string;
40
+ letterSpacing: string;
41
+ fontWidth: number;
42
+ };
43
+ };
44
+ };
45
+ export type ComponentTextInput = typeof componentTextInput;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * TextInput component entry point
3
+ *
4
+ * Peer dependencies required to use these components:
5
+ * - `@emotion/react`
6
+ * - `react`
7
+ * - `react-dom`
8
+ * - `typescript`
9
+ * - `react-aria-components`
10
+ *
11
+ * See the `peerDependencies` section of package.json for compatible versions.
12
+ *
13
+ * If you only need the built CSS (./component/textInput.css),
14
+ * you don't need to install these.
15
+ */
16
+ export { TextInput } from './components/text-input/TextInput';
17
+ export type { TextInputProps } from './components/text-input/types';
18
+ export type { TextInputTheme } from './components/text-input/styles';
19
+ export { componentTextInput } from './styleD/build/typescript/component/textInput';
20
+ export type { ComponentTextInput } from './styleD/build/typescript/component/textInput';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guardian/stand",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "type": "module",
5
5
  "//exports": "Each component has its own entry point for optimal tree-shaking. Main entry point only includes design tokens and utilities. New components/foundations should follow the same pattern.",
6
6
  "exports": {
@@ -84,6 +84,11 @@
84
84
  "import": "./dist/select.js",
85
85
  "require": "./dist/select.cjs"
86
86
  },
87
+ "./text-input": {
88
+ "types": "./dist/types/text-input.d.ts",
89
+ "import": "./dist/text-input.js",
90
+ "require": "./dist/text-input.cjs"
91
+ },
87
92
  "./byline": {
88
93
  "types": "./dist/types/byline.d.ts",
89
94
  "import": "./dist/byline.js",
@@ -131,7 +136,8 @@
131
136
  "./component/TopBar.css": "./dist/styleD/build/css/component/TopBar.css",
132
137
  "./component/form.css": "./dist/styleD/build/css/component/form.css",
133
138
  "./component/inlineMessage.css": "./dist/styleD/build/css/component/inlineMessage.css",
134
- "./component/select.css": "./dist/styleD/build/css/component/select.css"
139
+ "./component/select.css": "./dist/styleD/build/css/component/select.css",
140
+ "./component/textInput.css": "./dist/styleD/build/css/component/textInput.css"
135
141
  },
136
142
  "//typesVersions": "Provides backward compatibility for TypeScript moduleResolution: node - maps subpath imports to correct type definition files. When adding new components with their own entry points, ensure to add them here.",
137
143
  "typesVersions": {
@@ -192,6 +198,9 @@
192
198
  ],
193
199
  "select": [
194
200
  "./dist/types/select.d.ts"
201
+ ],
202
+ "text-input": [
203
+ "./dist/types/text-input.d.ts"
195
204
  ]
196
205
  }
197
206
  },
@@ -216,7 +225,6 @@
216
225
  "@guardian/tsconfig": "1.0.1",
217
226
  "@material-design-icons/svg": "^0.14.15",
218
227
  "@playwright/experimental-ct-react17": "^1.59.1",
219
- "@react-aria/focus": "3.21.5",
220
228
  "@rollup/plugin-commonjs": "29.0.2",
221
229
  "@rollup/plugin-node-resolve": "16.0.3",
222
230
  "@rollup/plugin-typescript": "12.3.0",
@@ -262,7 +270,6 @@
262
270
  "peerDependencies": {
263
271
  "@emotion/react": ">=11.11.4 <=11.14.0",
264
272
  "@guardian/prosemirror-invisibles": "3.1.1",
265
- "@react-aria/focus": "^3.21.5",
266
273
  "prosemirror-dropcursor": "1.8.2",
267
274
  "prosemirror-history": "1.4.1",
268
275
  "prosemirror-keymap": "1.2.2",
@@ -281,9 +288,6 @@
281
288
  "@guardian/prosemirror-invisibles": {
282
289
  "optional": true
283
290
  },
284
- "@react-aria/focus": {
285
- "optional": true
286
- },
287
291
  "prosemirror-dropcursor": {
288
292
  "optional": true
289
293
  },