@scality/core-ui 0.202.0 → 0.204.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 (38) hide show
  1. package/.github/workflows/github-pages.yml +4 -4
  2. package/.github/workflows/post-release.yml +25 -12
  3. package/__mocks__/fileMock.js +1 -1
  4. package/__mocks__/styleMock.js +1 -1
  5. package/__mocks__/uuid.js +1 -5
  6. package/dist/components/drawer/Drawer.component.d.ts +17 -0
  7. package/dist/components/drawer/Drawer.component.d.ts.map +1 -0
  8. package/dist/components/drawer/Drawer.component.js +132 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -0
  12. package/dist/next.d.ts +1 -0
  13. package/dist/next.d.ts.map +1 -1
  14. package/dist/next.js +1 -0
  15. package/dist/style/theme.d.ts +1 -0
  16. package/dist/style/theme.d.ts.map +1 -1
  17. package/dist/style/theme.js +1 -0
  18. package/dist/utils.d.ts.map +1 -1
  19. package/dist/utils.js +11 -16
  20. package/global-setup.js +1 -1
  21. package/jest.config.js +1 -1
  22. package/package.json +13 -3
  23. package/src/lib/components/drawer/Drawer.component.test.tsx +108 -0
  24. package/src/lib/components/drawer/Drawer.component.tsx +207 -0
  25. package/src/lib/index.ts +1 -0
  26. package/src/lib/next.ts +1 -0
  27. package/src/lib/style/theme.ts +1 -0
  28. package/src/lib/utils.test.ts +15 -12
  29. package/src/lib/utils.ts +15 -17
  30. package/src/lib/valalint/README.md +50 -0
  31. package/src/lib/valalint/index.js +49 -0
  32. package/src/lib/valalint/rules/modal-button-forbidden-label.js +87 -0
  33. package/src/lib/valalint/rules/modal-button-forbidden-label.test.js +157 -0
  34. package/src/lib/valalint/rules/no-raw-number-in-jsx.js +64 -0
  35. package/src/lib/valalint/rules/no-raw-number-in-jsx.test.js +237 -0
  36. package/src/lib/valalint/rules/technical-sentence-case.js +93 -0
  37. package/src/lib/valalint/rules/technical-sentence-case.test.js +167 -0
  38. package/stories/drawer.stories.tsx +135 -0
@@ -0,0 +1,167 @@
1
+ import { RuleTester } from 'eslint';
2
+ import rule from './technical-sentence-case.js';
3
+ import * as tsParser from '@typescript-eslint/parser';
4
+
5
+ const tester = new RuleTester({
6
+ parser: tsParser,
7
+ parserOptions: {
8
+ ecmaFeatures: { jsx: true },
9
+ ecmaVersion: 2020,
10
+ },
11
+ });
12
+
13
+ tester.run('technical-sentence-case', rule, {
14
+ // ─── Valid ────────────────────────────────────────────────────────────────
15
+ valid: [
16
+ // Non-targeted components are never checked
17
+ { code: '<div>hello world</div>' },
18
+ { code: '<span>bucket deleted</span>' },
19
+ { code: '<label>some text</label>' },
20
+
21
+ // Correctly capitalised plain text
22
+ { code: '<Button>Save</Button>' },
23
+ { code: '<Button>Delete item</Button>' },
24
+ { code: '<Text>Welcome back</Text>' },
25
+ { code: '<Tooltip>Click here to continue</Tooltip>' },
26
+
27
+ // Correctly capitalised resource names
28
+ { code: '<Button>Delete Bucket</Button>' },
29
+ { code: '<Text>Node is unreachable</Text>' },
30
+ { code: '<Tooltip>View Cluster details</Tooltip>' },
31
+ { code: '<Button>Assign Role</Button>' },
32
+ { code: '<Text>Edit Policy</Text>' },
33
+
34
+ // Empty / whitespace-only children are ignored
35
+ { code: '<Button> </Button>' },
36
+ { code: '<Text>{variable}</Text>' },
37
+ { code: `<Text>Text with jsx text {"in the middle"} of it</Text>` },
38
+ ],
39
+
40
+ // ─── Invalid ──────────────────────────────────────────────────────────────
41
+ invalid: [
42
+ // ── Sentence case violations ──────────────────────────────────────────
43
+
44
+ {
45
+ code: '<Button>save</Button>',
46
+ errors: [
47
+ {
48
+ message: 'Text in <Button> should start with a capital letter (sentence case).',
49
+ },
50
+ ],
51
+ output: '<Button> Save </Button>',
52
+ },
53
+ {
54
+ code: '<Text>delete item</Text>',
55
+ errors: [
56
+ {
57
+ message: 'Text in <Text> should start with a capital letter (sentence case).',
58
+ },
59
+ ],
60
+ output: '<Text> Delete item </Text>',
61
+ },
62
+ {
63
+ code: '<Tooltip>click here to continue</Tooltip>',
64
+ errors: [
65
+ {
66
+ message:
67
+ 'Text in <Tooltip> should start with a capital letter (sentence case).',
68
+ },
69
+ ],
70
+ output: '<Tooltip> Click here to continue </Tooltip>',
71
+ },
72
+
73
+ // ── Resource name violations ───────────────────────────────────────────
74
+
75
+ {
76
+ code: '<Button>Delete bucket</Button>',
77
+ errors: [
78
+ {
79
+ message: 'Resource name "Bucket" in <Button> must be capitalized.',
80
+ },
81
+ ],
82
+ output: '<Button>Delete Bucket</Button>',
83
+ },
84
+ {
85
+ code: '<Text>node is unreachable</Text>',
86
+ errors: [
87
+ // sentence case violation reported first
88
+ {
89
+ message: 'Text in <Text> should start with a capital letter (sentence case).',
90
+ },
91
+ // resource name violation reported second
92
+ {
93
+ message: 'Resource name "Node" in <Text> must be capitalized.',
94
+ },
95
+ ],
96
+ // ESLint applies only the first fix in a single pass; the sentence-case
97
+ // fixer fires first and capitalises the leading "n" → "Node" is then correct,
98
+ // but we verify here that the sentence-case fix alone is consistent.
99
+ output: '<Text> Node is unreachable </Text>',
100
+ },
101
+ {
102
+ code: '<Button>Edit policy</Button>',
103
+ errors: [
104
+ {
105
+ message: 'Resource name "Policy" in <Button> must be capitalized.',
106
+ },
107
+ ],
108
+ output: '<Button>Edit Policy</Button>',
109
+ },
110
+ {
111
+ code: '<Tooltip>View cluster details</Tooltip>',
112
+ errors: [
113
+ {
114
+ message: 'Resource name "Cluster" in <Tooltip> must be capitalized.',
115
+ },
116
+ ],
117
+ output: '<Tooltip>View Cluster details</Tooltip>',
118
+ },
119
+ {
120
+ // checkResourceNames returns on the first match found in RESOURCE_NAMES order.
121
+ // RESOURCE_NAMES = [..., 'User' (index 7), ..., 'Role' (index 9), ...]
122
+ // → only "User" is reported; "Role" is shadowed by the early return.
123
+ code: '<Text>assign role to user</Text>',
124
+ errors: [
125
+ {
126
+ message: 'Text in <Text> should start with a capital letter (sentence case).',
127
+ },
128
+ {
129
+ message: 'Resource name "User" in <Text> must be capitalized.',
130
+ },
131
+ ],
132
+ // sentence-case fixer fires first; only one fix is applied per pass
133
+ output: '<Text> Assign role to user </Text>',
134
+ },
135
+
136
+ // ── All targeted components are checked ───────────────────────────────
137
+
138
+ {
139
+ code: '<Text>welcome</Text>',
140
+ errors: [
141
+ {
142
+ message: 'Text in <Text> should start with a capital letter (sentence case).',
143
+ },
144
+ ],
145
+ output: '<Text> Welcome </Text>',
146
+ },
147
+ {
148
+ code: '<Tooltip>hover for more info</Tooltip>',
149
+ errors: [
150
+ {
151
+ message:
152
+ 'Text in <Tooltip> should start with a capital letter (sentence case).',
153
+ },
154
+ ],
155
+ output: '<Tooltip> Hover for more info </Tooltip>',
156
+ },
157
+ ],
158
+ });
159
+
160
+ // RuleTester.run() throws if any case fails, so reaching this line means all
161
+ // cases passed. Jest needs at least one explicit assertion per test file.
162
+ describe('technical-sentence-case', () => {
163
+ it('passes all RuleTester cases', () => {
164
+ // Execution of tester.run() above already validated everything.
165
+ expect(true).toBe(true);
166
+ });
167
+ });
@@ -0,0 +1,135 @@
1
+ import { useState } from 'react';
2
+ import { Button } from '../src/lib/components/buttonv2/Buttonv2.component';
3
+ import { Drawer } from '../src/lib/components/drawer/Drawer.component';
4
+ import { Wrapper } from './common';
5
+
6
+ export default {
7
+ title: 'Components/Feedback/Drawer',
8
+ component: Drawer,
9
+ decorators: [
10
+ (story) => <Wrapper style={{ minHeight: '30vh' }}>{story()}</Wrapper>,
11
+ ],
12
+ argTypes: {
13
+ position: {
14
+ control: 'select',
15
+ options: ['left', 'right', 'top', 'bottom'],
16
+ },
17
+ size: { control: 'text' },
18
+ overlay: { control: 'boolean' },
19
+ showCloseButton: { control: 'boolean' },
20
+ },
21
+ };
22
+
23
+ export const Default = {
24
+ render: (args) => {
25
+ const [isOpen, setIsOpen] = useState(false);
26
+ return (
27
+ <>
28
+ <Button onClick={() => setIsOpen(true)} label="Open Drawer" />
29
+ <Drawer {...args} isOpen={isOpen} close={() => setIsOpen(false)} />
30
+ </>
31
+ );
32
+ },
33
+ args: {
34
+ title: 'Drawer Title',
35
+ position: 'left',
36
+ size: '400px',
37
+ overlay: false,
38
+ children: (
39
+ <div>
40
+ <p>This is the drawer content.</p>
41
+ <p>The app remains visible and interactive behind the drawer.</p>
42
+ </div>
43
+ ),
44
+ },
45
+ };
46
+
47
+ export const WithFooter = {
48
+ render: (args) => {
49
+ const [isOpen, setIsOpen] = useState(false);
50
+ return (
51
+ <>
52
+ <Button onClick={() => setIsOpen(true)} label="Open Drawer" />
53
+ <Drawer
54
+ {...args}
55
+ isOpen={isOpen}
56
+ close={() => setIsOpen(false)}
57
+ footer={
58
+ <>
59
+ <Button
60
+ label="Cancel"
61
+ variant="outline"
62
+ onClick={() => setIsOpen(false)}
63
+ style={{ minWidth: '6rem' }}
64
+ />
65
+ <Button
66
+ label="Save"
67
+ variant="primary"
68
+ onClick={() => setIsOpen(false)}
69
+ style={{ minWidth: '6rem' }}
70
+ />
71
+ </>
72
+ }
73
+ />
74
+ </>
75
+ );
76
+ },
77
+ args: {
78
+ title: 'Settings',
79
+ position: 'left',
80
+ size: '400px',
81
+ overlay: false,
82
+ children: (
83
+ <div>
84
+ <p>Drawer with footer actions.</p>
85
+ <p>Use footer for save, cancel, or reset buttons.</p>
86
+ </div>
87
+ ),
88
+ },
89
+ };
90
+
91
+ export const WithOverlay = {
92
+ render: (args) => {
93
+ const [isOpen, setIsOpen] = useState(false);
94
+ return (
95
+ <>
96
+ <Button
97
+ onClick={() => setIsOpen(true)}
98
+ label="Open Drawer with Overlay"
99
+ />
100
+ <Drawer {...args} isOpen={isOpen} close={() => setIsOpen(false)} />
101
+ </>
102
+ );
103
+ },
104
+ args: {
105
+ title: 'Overlay Drawer',
106
+ position: 'left',
107
+ size: '400px',
108
+ overlay: true,
109
+ children: (
110
+ <div>
111
+ <p>This drawer has a backdrop overlay.</p>
112
+ <p>Click the overlay or press Escape to close.</p>
113
+ </div>
114
+ ),
115
+ },
116
+ };
117
+
118
+ export const RightPosition = {
119
+ render: (args) => {
120
+ const [isOpen, setIsOpen] = useState(false);
121
+ return (
122
+ <>
123
+ <Button onClick={() => setIsOpen(true)} label="Open Right Drawer" />
124
+ <Drawer {...args} isOpen={isOpen} close={() => setIsOpen(false)} />
125
+ </>
126
+ );
127
+ },
128
+ args: {
129
+ title: 'Right Drawer',
130
+ position: 'right',
131
+ size: '350px',
132
+ overlay: false,
133
+ children: <p>Drawer sliding in from the right.</p>,
134
+ },
135
+ };