@guardian/stand 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.prettierrc +1 -0
  4. package/.storybook/main.ts +12 -0
  5. package/.storybook/preview.tsx +83 -0
  6. package/CHANGELOG.md +7 -0
  7. package/README.md +15 -0
  8. package/dist/byline/Byline.cjs +375 -0
  9. package/dist/byline/Byline.js +273 -0
  10. package/dist/byline/Preview.cjs +52 -0
  11. package/dist/byline/Preview.js +26 -0
  12. package/dist/byline/lib.cjs +240 -0
  13. package/dist/byline/lib.js +181 -0
  14. package/dist/byline/placeholder.cjs +29 -0
  15. package/dist/byline/placeholder.js +27 -0
  16. package/dist/byline/plugins.cjs +144 -0
  17. package/dist/byline/plugins.js +123 -0
  18. package/dist/byline/schema.cjs +66 -0
  19. package/dist/byline/schema.js +59 -0
  20. package/dist/byline/styles.cjs +244 -0
  21. package/dist/byline/styles.js +234 -0
  22. package/dist/index.cjs +4 -4
  23. package/dist/index.js +1 -5
  24. package/dist/types/.storybook/main.d.ts +3 -0
  25. package/dist/types/.storybook/preview.d.ts +3 -0
  26. package/dist/types/jest-setup-after-env.d.ts +1 -0
  27. package/dist/types/src/byline/Byline.d.ts +17 -0
  28. package/dist/types/src/byline/Byline.stories.d.ts +206 -0
  29. package/dist/types/src/byline/Byline.test.d.ts +1 -0
  30. package/dist/types/src/byline/Preview.d.ts +4 -0
  31. package/dist/types/src/byline/contributors-fixture.d.ts +1 -0
  32. package/dist/types/src/byline/lib.d.ts +48 -0
  33. package/dist/types/src/byline/lib.test.d.ts +1 -0
  34. package/dist/types/src/byline/placeholder.d.ts +2 -0
  35. package/dist/types/src/byline/plugins.d.ts +4 -0
  36. package/dist/types/src/byline/schema.d.ts +2 -0
  37. package/dist/types/src/byline/styles.d.ts +11 -0
  38. package/dist/types/src/byline/theme.d.ts +44 -0
  39. package/dist/types/src/byline/util.d.ts +3 -0
  40. package/dist/types/src/index.d.ts +2 -0
  41. package/dist/types/src/mocks/prosemirror-view.d.ts +10 -0
  42. package/eslint.config.js +14 -0
  43. package/jest-setup-after-env.ts +1 -0
  44. package/jest.config.js +12 -0
  45. package/package.json +60 -129
  46. package/rollup.config.js +49 -0
  47. package/src/byline/Byline.stories.tsx +186 -0
  48. package/src/byline/Byline.test.tsx +450 -0
  49. package/src/byline/Byline.tsx +524 -0
  50. package/src/byline/Preview.tsx +59 -0
  51. package/src/byline/contributors-fixture.ts +1006 -0
  52. package/src/byline/lib.test.ts +179 -0
  53. package/src/byline/lib.ts +426 -0
  54. package/src/byline/placeholder.ts +30 -0
  55. package/src/byline/plugins.ts +186 -0
  56. package/src/byline/schema.ts +62 -0
  57. package/src/byline/styles.ts +246 -0
  58. package/src/byline/theme.ts +45 -0
  59. package/src/byline/util.ts +5 -0
  60. package/src/index.ts +2 -0
  61. package/src/mocks/prosemirror-view.ts +19 -0
  62. package/tsconfig.json +19 -0
  63. package/LICENSE +0 -201
  64. package/dist/index.d.ts +0 -3
@@ -0,0 +1,244 @@
1
+ 'use strict';
2
+
3
+ var react = require('@emotion/react');
4
+
5
+ const bylineContainerStyles = react.css`
6
+ position: relative;
7
+ width: 100%;
8
+ `;
9
+ const bylineEditorStyles = (theme) => react.css`
10
+ border: ${theme?.border ?? "1px black solid"};
11
+ background-color: ${theme?.background ?? "white"};
12
+ color: ${theme?.color ?? "inherit"};
13
+
14
+ /* ProseMirror styles from prosemirror-view/styles/prosemirror.css */
15
+ .ProseMirror {
16
+ padding: 4px 4px;
17
+ word-wrap: break-word;
18
+ white-space: pre-wrap;
19
+ white-space: break-spaces;
20
+ -webkit-font-variant-ligatures: none;
21
+ font-variant-ligatures: none;
22
+ font-feature-settings: 'liga' 0; /* the above doesn't seem to work in Edge */
23
+ line-height: ${theme?.lineHeight ?? "1.8"};
24
+ }
25
+
26
+ .ProseMirror[contenteditable='false'] {
27
+ background: ${theme?.readOnlyBackground ?? "#dcdcdc"};
28
+ cursor: 'not-allowed';
29
+ }
30
+
31
+ .ProseMirror pre {
32
+ white-space: pre-wrap;
33
+ }
34
+
35
+ .ProseMirror li {
36
+ position: relative;
37
+ }
38
+
39
+ .ProseMirror-hideselection *::selection {
40
+ background: transparent;
41
+ }
42
+ .ProseMirror-hideselection *::-moz-selection {
43
+ background: transparent;
44
+ }
45
+ .ProseMirror-hideselection {
46
+ caret-color: transparent;
47
+ }
48
+
49
+ /* See https://github.com/ProseMirror/prosemirror/issues/1421#issuecomment-1759320191 */
50
+ .ProseMirror [draggable][contenteditable='false'] {
51
+ user-select: text;
52
+ }
53
+
54
+ .ProseMirror-selectednode {
55
+ outline: ${theme?.chip?.selected?.border ?? "1px solid #b4d9ff"};
56
+ }
57
+
58
+ /* Make sure li selections wrap around markers */
59
+
60
+ li.ProseMirror-selectednode {
61
+ outline: none;
62
+ }
63
+
64
+ li.ProseMirror-selectednode:after {
65
+ content: '';
66
+ position: absolute;
67
+ left: -32px;
68
+ right: -2px;
69
+ top: -2px;
70
+ bottom: -2px;
71
+ border: ${theme?.chip?.selected?.border ?? "1px solid #b4d9ff"};
72
+ pointer-events: none;
73
+ }
74
+
75
+ /* Protect against generic img rules */
76
+
77
+ img.ProseMirror-separator {
78
+ display: inline !important;
79
+ border: none !important;
80
+ margin: 0 !important;
81
+ }
82
+
83
+ .ProseMirror:focus {
84
+ outline: none;
85
+ }
86
+
87
+ /* Invisible styles from @guardian/prosemirror-invisibles/dist/style.css */
88
+
89
+ .invisible {
90
+ /* Chrome in particular dislikes doing the right thing
91
+ * with carets and inline elements when contenteditable
92
+ * is 'false'. See e.g. https://github.com/ProseMirror/prosemirror/issues/1061
93
+ */
94
+ display: inline;
95
+ position: relative;
96
+ pointer-events: none;
97
+ }
98
+
99
+ .invisible:before {
100
+ position: relative;
101
+ caret-color: inherit;
102
+ color: ${theme?.invisibles?.color ?? "gray"};
103
+ display: inline-block;
104
+ font-weight: 400;
105
+ font-style: normal;
106
+ line-height: initial;
107
+ width: 0;
108
+ top: 0;
109
+ left: 0;
110
+ z-index: 1;
111
+ }
112
+
113
+ .invisible__selected-marker {
114
+ position: absolute;
115
+ caret-color: inherit;
116
+ background-color: #dcdcdc;
117
+ display: inline-block;
118
+ font-weight: 400;
119
+ font-style: normal;
120
+ line-height: initial;
121
+ top: 0;
122
+ left: 0;
123
+ width: 10px;
124
+ height: 100%;
125
+ z-index: 0;
126
+ }
127
+
128
+ .ProseMirror-focused .invisible__selected-marker {
129
+ background-color: #b4d9ff;
130
+ }
131
+
132
+ .ProseMirror-focused .invisible--is-selected::before {
133
+ background-color: #b4d8ff;
134
+ }
135
+
136
+ .invisible--is-selected::before {
137
+ background-color: #dcdcdc;
138
+ }
139
+
140
+ .invisible--space:before {
141
+ content: '·';
142
+ }
143
+
144
+ .invisible--nb-space {
145
+ vertical-align: text-bottom;
146
+ }
147
+
148
+ .invisible--nb-space:before {
149
+ font-size: 15px;
150
+ content: '^';
151
+ position: absolute;
152
+ top: 9px;
153
+ left: -1px;
154
+ }
155
+
156
+ chip {
157
+ border: ${theme?.chip?.border ?? "2px solid lightgrey"};
158
+ border-radius: ${theme?.chip?.borderRadius ?? "8px"};
159
+ padding: ${theme?.chip?.padding ?? "2px 4px"};
160
+ color: ${theme?.chip?.color ?? "inherit"};
161
+
162
+ cursor: default;
163
+
164
+ &[data-type='tagged'] {
165
+ background-color: ${theme?.chip?.taggedBackground ?? "lightgrey"};
166
+ }
167
+
168
+ &[data-type='untagged'] {
169
+ color: ${theme?.chip?.untagged?.color ?? "inherit"};
170
+ }
171
+
172
+ ::after {
173
+ content: '';
174
+ display: inline-block;
175
+ }
176
+
177
+ span {
178
+ cursor: pointer;
179
+ margin-left: 5px;
180
+ }
181
+ }
182
+
183
+ /* Leave space between subsequent chips */
184
+ chip + chip {
185
+ margin-left: 3px;
186
+ }
187
+
188
+ .placeholder {
189
+ display: inline-block;
190
+ height: 0;
191
+ width: 0;
192
+ white-space: nowrap;
193
+ color: ${theme?.placeholder?.color ?? "#777575"};
194
+ pointer-events: none;
195
+ cursor: text;
196
+ }
197
+ `;
198
+ const dropdownContainerStyles = (showDropdown, theme) => react.css`
199
+ position: absolute;
200
+ box-sizing: border-box;
201
+ width: 100%;
202
+ z-index: 1000;
203
+ border: ${theme?.border ?? "1px solid #ccc"};
204
+ background-color: ${theme?.background ?? "rgba(255, 255, 255, 0.8)"};
205
+ display: ${showDropdown ? "block" : "none"};
206
+ max-height: ${theme?.maxHeight ?? "320px"};
207
+ overflow-y: auto;
208
+ `;
209
+ const dropdownUlStyles = react.css`
210
+ margin: 0;
211
+ padding: 0;
212
+ list-style-type: none;
213
+ `;
214
+ const dropdownLiStyles = (theme) => react.css`
215
+ cursor: pointer;
216
+ padding: 5px;
217
+ border-bottom: ${theme?.dropdown?.li?.borderBottom ?? "1px solid #ccc"};
218
+ color: ${theme?.dropdown?.li?.color ?? "inherit"};
219
+ `;
220
+ const selectedDropdownLiStyles = (theme) => react.css`
221
+ background-color: ${theme?.dropdown?.li?.selected?.background ?? "cadetblue"};
222
+ color: ${theme?.dropdown?.li?.selected?.color ?? "white"};
223
+ `;
224
+ const previewStyles = react.css`
225
+ margin-top: 5px;
226
+ white-space: pre-wrap;
227
+ `;
228
+ const previewFreeTextStyles = react.css`
229
+ font-style: italic;
230
+ `;
231
+ const previewContributorStyles = (node) => react.css`
232
+ ${node.attrs.type === "tagged" ? "text-decoration: underline;" : ""}
233
+ color: inherit;
234
+ `;
235
+
236
+ exports.bylineContainerStyles = bylineContainerStyles;
237
+ exports.bylineEditorStyles = bylineEditorStyles;
238
+ exports.dropdownContainerStyles = dropdownContainerStyles;
239
+ exports.dropdownLiStyles = dropdownLiStyles;
240
+ exports.dropdownUlStyles = dropdownUlStyles;
241
+ exports.previewContributorStyles = previewContributorStyles;
242
+ exports.previewFreeTextStyles = previewFreeTextStyles;
243
+ exports.previewStyles = previewStyles;
244
+ exports.selectedDropdownLiStyles = selectedDropdownLiStyles;
@@ -0,0 +1,234 @@
1
+ import { css } from '@emotion/react';
2
+
3
+ const bylineContainerStyles = css`
4
+ position: relative;
5
+ width: 100%;
6
+ `;
7
+ const bylineEditorStyles = (theme) => css`
8
+ border: ${theme?.border ?? "1px black solid"};
9
+ background-color: ${theme?.background ?? "white"};
10
+ color: ${theme?.color ?? "inherit"};
11
+
12
+ /* ProseMirror styles from prosemirror-view/styles/prosemirror.css */
13
+ .ProseMirror {
14
+ padding: 4px 4px;
15
+ word-wrap: break-word;
16
+ white-space: pre-wrap;
17
+ white-space: break-spaces;
18
+ -webkit-font-variant-ligatures: none;
19
+ font-variant-ligatures: none;
20
+ font-feature-settings: 'liga' 0; /* the above doesn't seem to work in Edge */
21
+ line-height: ${theme?.lineHeight ?? "1.8"};
22
+ }
23
+
24
+ .ProseMirror[contenteditable='false'] {
25
+ background: ${theme?.readOnlyBackground ?? "#dcdcdc"};
26
+ cursor: 'not-allowed';
27
+ }
28
+
29
+ .ProseMirror pre {
30
+ white-space: pre-wrap;
31
+ }
32
+
33
+ .ProseMirror li {
34
+ position: relative;
35
+ }
36
+
37
+ .ProseMirror-hideselection *::selection {
38
+ background: transparent;
39
+ }
40
+ .ProseMirror-hideselection *::-moz-selection {
41
+ background: transparent;
42
+ }
43
+ .ProseMirror-hideselection {
44
+ caret-color: transparent;
45
+ }
46
+
47
+ /* See https://github.com/ProseMirror/prosemirror/issues/1421#issuecomment-1759320191 */
48
+ .ProseMirror [draggable][contenteditable='false'] {
49
+ user-select: text;
50
+ }
51
+
52
+ .ProseMirror-selectednode {
53
+ outline: ${theme?.chip?.selected?.border ?? "1px solid #b4d9ff"};
54
+ }
55
+
56
+ /* Make sure li selections wrap around markers */
57
+
58
+ li.ProseMirror-selectednode {
59
+ outline: none;
60
+ }
61
+
62
+ li.ProseMirror-selectednode:after {
63
+ content: '';
64
+ position: absolute;
65
+ left: -32px;
66
+ right: -2px;
67
+ top: -2px;
68
+ bottom: -2px;
69
+ border: ${theme?.chip?.selected?.border ?? "1px solid #b4d9ff"};
70
+ pointer-events: none;
71
+ }
72
+
73
+ /* Protect against generic img rules */
74
+
75
+ img.ProseMirror-separator {
76
+ display: inline !important;
77
+ border: none !important;
78
+ margin: 0 !important;
79
+ }
80
+
81
+ .ProseMirror:focus {
82
+ outline: none;
83
+ }
84
+
85
+ /* Invisible styles from @guardian/prosemirror-invisibles/dist/style.css */
86
+
87
+ .invisible {
88
+ /* Chrome in particular dislikes doing the right thing
89
+ * with carets and inline elements when contenteditable
90
+ * is 'false'. See e.g. https://github.com/ProseMirror/prosemirror/issues/1061
91
+ */
92
+ display: inline;
93
+ position: relative;
94
+ pointer-events: none;
95
+ }
96
+
97
+ .invisible:before {
98
+ position: relative;
99
+ caret-color: inherit;
100
+ color: ${theme?.invisibles?.color ?? "gray"};
101
+ display: inline-block;
102
+ font-weight: 400;
103
+ font-style: normal;
104
+ line-height: initial;
105
+ width: 0;
106
+ top: 0;
107
+ left: 0;
108
+ z-index: 1;
109
+ }
110
+
111
+ .invisible__selected-marker {
112
+ position: absolute;
113
+ caret-color: inherit;
114
+ background-color: #dcdcdc;
115
+ display: inline-block;
116
+ font-weight: 400;
117
+ font-style: normal;
118
+ line-height: initial;
119
+ top: 0;
120
+ left: 0;
121
+ width: 10px;
122
+ height: 100%;
123
+ z-index: 0;
124
+ }
125
+
126
+ .ProseMirror-focused .invisible__selected-marker {
127
+ background-color: #b4d9ff;
128
+ }
129
+
130
+ .ProseMirror-focused .invisible--is-selected::before {
131
+ background-color: #b4d8ff;
132
+ }
133
+
134
+ .invisible--is-selected::before {
135
+ background-color: #dcdcdc;
136
+ }
137
+
138
+ .invisible--space:before {
139
+ content: '·';
140
+ }
141
+
142
+ .invisible--nb-space {
143
+ vertical-align: text-bottom;
144
+ }
145
+
146
+ .invisible--nb-space:before {
147
+ font-size: 15px;
148
+ content: '^';
149
+ position: absolute;
150
+ top: 9px;
151
+ left: -1px;
152
+ }
153
+
154
+ chip {
155
+ border: ${theme?.chip?.border ?? "2px solid lightgrey"};
156
+ border-radius: ${theme?.chip?.borderRadius ?? "8px"};
157
+ padding: ${theme?.chip?.padding ?? "2px 4px"};
158
+ color: ${theme?.chip?.color ?? "inherit"};
159
+
160
+ cursor: default;
161
+
162
+ &[data-type='tagged'] {
163
+ background-color: ${theme?.chip?.taggedBackground ?? "lightgrey"};
164
+ }
165
+
166
+ &[data-type='untagged'] {
167
+ color: ${theme?.chip?.untagged?.color ?? "inherit"};
168
+ }
169
+
170
+ ::after {
171
+ content: '';
172
+ display: inline-block;
173
+ }
174
+
175
+ span {
176
+ cursor: pointer;
177
+ margin-left: 5px;
178
+ }
179
+ }
180
+
181
+ /* Leave space between subsequent chips */
182
+ chip + chip {
183
+ margin-left: 3px;
184
+ }
185
+
186
+ .placeholder {
187
+ display: inline-block;
188
+ height: 0;
189
+ width: 0;
190
+ white-space: nowrap;
191
+ color: ${theme?.placeholder?.color ?? "#777575"};
192
+ pointer-events: none;
193
+ cursor: text;
194
+ }
195
+ `;
196
+ const dropdownContainerStyles = (showDropdown, theme) => css`
197
+ position: absolute;
198
+ box-sizing: border-box;
199
+ width: 100%;
200
+ z-index: 1000;
201
+ border: ${theme?.border ?? "1px solid #ccc"};
202
+ background-color: ${theme?.background ?? "rgba(255, 255, 255, 0.8)"};
203
+ display: ${showDropdown ? "block" : "none"};
204
+ max-height: ${theme?.maxHeight ?? "320px"};
205
+ overflow-y: auto;
206
+ `;
207
+ const dropdownUlStyles = css`
208
+ margin: 0;
209
+ padding: 0;
210
+ list-style-type: none;
211
+ `;
212
+ const dropdownLiStyles = (theme) => css`
213
+ cursor: pointer;
214
+ padding: 5px;
215
+ border-bottom: ${theme?.dropdown?.li?.borderBottom ?? "1px solid #ccc"};
216
+ color: ${theme?.dropdown?.li?.color ?? "inherit"};
217
+ `;
218
+ const selectedDropdownLiStyles = (theme) => css`
219
+ background-color: ${theme?.dropdown?.li?.selected?.background ?? "cadetblue"};
220
+ color: ${theme?.dropdown?.li?.selected?.color ?? "white"};
221
+ `;
222
+ const previewStyles = css`
223
+ margin-top: 5px;
224
+ white-space: pre-wrap;
225
+ `;
226
+ const previewFreeTextStyles = css`
227
+ font-style: italic;
228
+ `;
229
+ const previewContributorStyles = (node) => css`
230
+ ${node.attrs.type === "tagged" ? "text-decoration: underline;" : ""}
231
+ color: inherit;
232
+ `;
233
+
234
+ export { bylineContainerStyles, bylineEditorStyles, dropdownContainerStyles, dropdownLiStyles, dropdownUlStyles, previewContributorStyles, previewFreeTextStyles, previewStyles, selectedDropdownLiStyles };
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- function byline() {
4
- return "byline";
5
- }
3
+ var Byline = require('./byline/Byline.cjs');
6
4
 
7
- exports.byline = byline;
5
+
6
+
7
+ exports.Byline = Byline.Byline;
package/dist/index.js CHANGED
@@ -1,5 +1 @@
1
- function byline() {
2
- return "byline";
3
- }
4
-
5
- export { byline };
1
+ export { Byline } from './byline/Byline.js';
@@ -0,0 +1,3 @@
1
+ import type { StorybookConfig } from '@storybook/react-vite';
2
+ declare const config: StorybookConfig;
3
+ export default config;
@@ -0,0 +1,3 @@
1
+ import type { Preview } from '@storybook/react-vite';
2
+ declare const preview: Preview;
3
+ export default preview;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,17 @@
1
+ import type { FocusEventHandler } from 'react';
2
+ import type { BylineModel, TaggedContributor } from './lib';
3
+ import type { PartialBylineTheme } from './theme';
4
+ type BylineProps = {
5
+ theme?: PartialBylineTheme;
6
+ allowUntaggedContributors?: boolean;
7
+ contributorLimit?: number;
8
+ enablePreview?: boolean;
9
+ placeholder?: string;
10
+ initialValue?: BylineModel;
11
+ readOnly?: boolean;
12
+ handleSave: (newValue: BylineModel) => void;
13
+ searchContributors?: (selectedText: string) => Promise<TaggedContributor[]>;
14
+ onBlur?: FocusEventHandler<HTMLDivElement>;
15
+ };
16
+ export declare const Byline: ({ theme, allowUntaggedContributors, contributorLimit, enablePreview, placeholder, initialValue, readOnly, handleSave, searchContributors, onBlur, }: BylineProps) => import("@emotion/react/jsx-runtime").JSX.Element;
17
+ export {};