@scality/core-ui 0.147.0 → 0.148.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.
@@ -2,15 +2,15 @@ name: Deploy Storybook
2
2
 
3
3
  on:
4
4
  push:
5
- branches: development/1.0
5
+ branches: [development/1.0]
6
6
  jobs:
7
7
  deploy:
8
8
  runs-on: ubuntu-latest
9
9
  steps:
10
- - uses: actions/checkout@v2
11
- - uses: actions/setup-node@v2
10
+ - uses: actions/checkout@v4
11
+ - uses: actions/setup-node@v4
12
12
  with:
13
- node-version: '16'
13
+ node-version: 20
14
14
  - run: npm ci
15
15
  - run: npm run storybook:deploy -- --ci
16
16
  env:
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/accordion/Accordion.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAUxC,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AA2BF,eAAO,MAAM,SAAS,mCAAoC,cAAc,4CAkDvE,CAAC"}
1
+ {"version":3,"file":"Accordion.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/accordion/Accordion.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAUxC,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AA4BF,eAAO,MAAM,SAAS,mCAAoC,cAAc,4CAuDvE,CAAC"}
@@ -10,29 +10,30 @@ const AccordionHeader = styled.button `
10
10
  -moz-appearance: none;
11
11
  appearance: none;
12
12
  border: none;
13
- gap: ${spacing.r8};
14
13
  width: 100%;
15
14
  cursor: pointer;
16
15
  background-color: transparent;
17
16
  color: ${(props) => props.theme.textPrimary};
18
- padding: ${spacing.r4};
19
- width: 100%;
17
+ padding: 0;
20
18
  `;
21
19
  const AccordionContainer = styled.div `
22
20
  overflow: hidden;
23
21
  opacity: ${(props) => (props.isOpen ? 1 : 0)};
24
- transition: height 0.3s ease-in, opacity 0.3s ease-in, visibility 0.3s;
22
+ transition:
23
+ height 0.3s ease-in,
24
+ opacity 0.3s ease-in,
25
+ visibility 0.3s;
25
26
  visibility: ${(props) => (props.isOpen ? 'visible' : 'hidden')};
26
27
  `;
27
28
  const Wrapper = styled.div `
28
- padding-block: ${spacing.r8};
29
+ padding: ${spacing.r8} 0 ${spacing.r8} ${spacing.r20};
29
30
  `;
30
31
  export const Accordion = ({ title, id, style, children }) => {
31
32
  const [isOpen, setIsOpen] = useState(false);
32
- const handleToggleContent = () => {
33
+ const handleToggleContent = (e) => {
33
34
  setIsOpen((prev) => !prev);
34
35
  };
35
- return (_jsxs(Box, { style: { width: '100%', height: 'auto' }, children: [_jsx("h3", { style: { margin: 0 }, children: _jsx(AccordionHeader, { id: `Accordion-header-${id}`, onClick: handleToggleContent, "aria-controls": id, "aria-expanded": isOpen, onKeyDown: (e) => (e.key === 'Enter' || e.key === ' ') && handleToggleContent, children: _jsxs(Stack, { direction: "horizontal", gap: "r8", children: [_jsx(Icon, { name: "Chevron-up", size: "lg", style: {
36
+ return (_jsxs(Box, { style: { width: '100%', height: 'auto' }, children: [_jsx("h3", { style: { margin: 0 }, children: _jsx(AccordionHeader, { type: "button", id: `Accordion-header-${id}`, onClick: handleToggleContent, "aria-controls": id, "aria-expanded": isOpen, onKeyDown: (e) => (e.key === 'Enter' || e.key === ' ') && handleToggleContent, children: _jsxs(Stack, { direction: "horizontal", gap: "r8", children: [_jsx(Icon, { name: "Chevron-up", size: "lg", style: {
36
37
  transform: isOpen ? 'rotate(0deg)' : 'rotate(180deg)',
37
38
  transition: 'transform 0.3s ease-in',
38
39
  } }), _jsx(Text, { isEmphazed: true, children: title })] }) }) }), _jsx(AccordionContainer, { ref: (element) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scality/core-ui",
3
- "version": "0.147.0",
3
+ "version": "0.148.0",
4
4
  "description": "Scality common React component library",
5
5
  "author": "Scality Engineering",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -20,30 +20,35 @@ const AccordionHeader = styled.button`
20
20
  -moz-appearance: none;
21
21
  appearance: none;
22
22
  border: none;
23
- gap: ${spacing.r8};
24
23
  width: 100%;
25
24
  cursor: pointer;
26
25
  background-color: transparent;
27
26
  color: ${(props) => props.theme.textPrimary};
28
- padding: ${spacing.r4};
29
- width: 100%;
27
+ padding: 0;
30
28
  `;
31
29
  const AccordionContainer = styled.div<{
32
30
  isOpen: boolean;
33
31
  }>`
34
32
  overflow: hidden;
35
33
  opacity: ${(props) => (props.isOpen ? 1 : 0)};
36
- transition: height 0.3s ease-in, opacity 0.3s ease-in, visibility 0.3s;
34
+ transition:
35
+ height 0.3s ease-in,
36
+ opacity 0.3s ease-in,
37
+ visibility 0.3s;
37
38
  visibility: ${(props) => (props.isOpen ? 'visible' : 'hidden')};
38
39
  `;
39
40
  const Wrapper = styled.div`
40
- padding-block: ${spacing.r8};
41
+ padding: ${spacing.r8} 0 ${spacing.r8} ${spacing.r20};
41
42
  `;
42
43
 
43
44
  export const Accordion = ({ title, id, style, children }: AccordionProps) => {
44
45
  const [isOpen, setIsOpen] = useState(false);
45
46
 
46
- const handleToggleContent = () => {
47
+ const handleToggleContent = (
48
+ e:
49
+ | React.MouseEvent<HTMLButtonElement>
50
+ | React.KeyboardEvent<HTMLButtonElement>,
51
+ ) => {
47
52
  setIsOpen((prev) => !prev);
48
53
  };
49
54
 
@@ -51,6 +56,7 @@ export const Accordion = ({ title, id, style, children }: AccordionProps) => {
51
56
  <Box style={{ width: '100%', height: 'auto' }}>
52
57
  <h3 style={{ margin: 0 }}>
53
58
  <AccordionHeader
59
+ type="button"
54
60
  id={`Accordion-header-${id}`}
55
61
  onClick={handleToggleContent}
56
62
  aria-controls={id}
@@ -19,6 +19,13 @@ import * as Stories from './accordion.stories';
19
19
  Accordions are used to toggle the visibility of content.
20
20
  It is used to hide non essential information or to reduce the amount of information displayed on the screen.
21
21
 
22
+ ## Style
23
+
24
+ Accordion component comes with a style prop that can be used to customize the appearance of the accordion content.
25
+ The default style of the accordion container only includes padding.
26
+
27
+ <Canvas of={Stories.WithCustomStyle} />
28
+
22
29
  ## Playground
23
30
 
24
31
  <Canvas of={Stories.Playground} layout="fullscreen" />
@@ -1,12 +1,13 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
  import React from 'react';
3
-
3
+ import { useTheme } from 'styled-components';
4
4
  import {
5
5
  Accordion,
6
6
  AccordionProps,
7
7
  } from '../../src/lib/components/accordion/Accordion.component';
8
- import { Stack } from '../../src/lib/spacing';
9
8
  import { Button } from '../../src/lib/components/buttonv2/Buttonv2.component';
9
+ import { spacing, Stack } from '../../src/lib/spacing';
10
+ import { Text } from '../../src/lib';
10
11
 
11
12
  type AccordionStory = StoryObj<AccordionProps>;
12
13
 
@@ -59,7 +60,29 @@ export const Stacked: AccordionStory = {
59
60
  <Stack direction="vertical" gap="r8">
60
61
  <Accordion {...args} />
61
62
  <Accordion {...args} />
62
- <Accordion {...args} style={{ backgroundColor: 'grey' }} />
63
+ <Accordion {...args} />
63
64
  </Stack>
64
65
  ),
65
66
  };
67
+
68
+ export const WithCustomStyle: AccordionStory = {
69
+ render: (args) => {
70
+ const { title } = args;
71
+ const theme = useTheme();
72
+
73
+ const style = {
74
+ backgroundColor: theme.statusHealthy,
75
+ borderRadius: spacing.r4,
76
+ padding: spacing.r16,
77
+ margin: spacing.r8,
78
+ };
79
+ return (
80
+ <Accordion {...args} style={style} title={title}>
81
+ <Text>The container of this accordion has a custom style</Text>
82
+ </Accordion>
83
+ );
84
+ },
85
+ args: {
86
+ title: 'Accordion with custom style',
87
+ },
88
+ };
@@ -13,6 +13,7 @@ import { Text } from '../src/lib/components/text/Text.component';
13
13
  import { Toggle } from '../src/lib/components/toggle/Toggle.component';
14
14
  import { Stack } from '../src/lib/spacing';
15
15
  import { iconArgType } from './controls';
16
+ import { Accordion } from '../src/lib/next';
16
17
 
17
18
  export default {
18
19
  title: 'Templates/Form',
@@ -251,3 +252,181 @@ export const PageFormWithIcon = {
251
252
  },
252
253
  },
253
254
  };
255
+
256
+ export const FormWithAccordion = {
257
+ render: ({ kind, title, subTitle, icon, requireMode }) => {
258
+ const layout = {
259
+ kind,
260
+ title,
261
+ subTitle,
262
+ icon,
263
+ };
264
+ const [toggle, setToggle] = useState(true);
265
+ return (
266
+ <>
267
+ <Form
268
+ layout={layout}
269
+ requireMode={requireMode}
270
+ rightActions={
271
+ <Stack gap={'r16'}>
272
+ <Button variant="outline" label="Cancel" />
273
+ <Button
274
+ variant="primary"
275
+ label="Save"
276
+ icon={<Icon name="Save" />}
277
+ />
278
+ </Stack>
279
+ }
280
+ banner={
281
+ <Banner
282
+ variant="danger"
283
+ icon={<Icon name="Exclamation-circle" />}
284
+ title={'Error'}
285
+ >
286
+ There is an error
287
+ </Banner>
288
+ }
289
+ >
290
+ <FormSection
291
+ title={{
292
+ name: 'First part entity data',
293
+ helpTooltip: 'Tooltip of the first entity',
294
+ icon: 'Search',
295
+ }}
296
+ >
297
+ <FormGroup
298
+ direction="vertical"
299
+ label="Name"
300
+ id="name"
301
+ labelHelpTooltip="Name Tooltip"
302
+ content={<Input id="name" />}
303
+ help="Optional helper text"
304
+ required
305
+ disabled
306
+ ></FormGroup>
307
+ <FormGroup
308
+ direction="horizontal"
309
+ label="Email"
310
+ id="email"
311
+ labelHelpTooltip="Email Tooltip"
312
+ content={<Input id="email" />}
313
+ error="Invalid email format. Try with a better format."
314
+ helpErrorPosition="right"
315
+ required
316
+ ></FormGroup>
317
+ </FormSection>
318
+ <FormSection
319
+ title={{
320
+ name: 'Second part entity data',
321
+ helpTooltip: 'Tooltip of the Second entity',
322
+ icon: 'Search',
323
+ }}
324
+ >
325
+ <FormGroup
326
+ direction="horizontal"
327
+ label="Name"
328
+ id="name1"
329
+ labelHelpTooltip="Name Tooltip"
330
+ content={
331
+ <Toggle
332
+ onChange={() => {
333
+ setToggle(!toggle);
334
+ }}
335
+ toggle={toggle}
336
+ name="toggle"
337
+ />
338
+ }
339
+ help="Optional helper text"
340
+ required={false}
341
+ ></FormGroup>
342
+ <FormGroup
343
+ direction="horizontal"
344
+ label="Email"
345
+ id="email1"
346
+ labelHelpTooltip="Email Tooltip"
347
+ content={<Input id="email1" />}
348
+ error="Invalid email format. Try with a better format."
349
+ helpErrorPosition="right"
350
+ required={false}
351
+ ></FormGroup>
352
+ <FormGroup
353
+ direction="horizontal"
354
+ label="Email long long long"
355
+ id="email-long1"
356
+ labelHelpTooltip="Email Tooltip"
357
+ content={<Input id="email-long1" />}
358
+ help="optional helper text"
359
+ helpErrorPosition="bottom"
360
+ required={false}
361
+ ></FormGroup>
362
+ </FormSection>
363
+ <FormSection>
364
+ <Accordion title="Advanced Settings" id="advanced-settings">
365
+ <FormGroup
366
+ direction="vertical"
367
+ label="Object Lock Mode"
368
+ id="object_lock_mode"
369
+ labelHelpTooltip="S3 Object Lock Retention"
370
+ content={
371
+ <Stack direction="vertical">
372
+ <Stack direction="vertical">
373
+ <Stack>
374
+ <input
375
+ type="radio"
376
+ name="locktype"
377
+ id="locktype-governance"
378
+ value="governance"
379
+ />
380
+ <label htmlFor="locktype-governance">Governance</label>
381
+ </Stack>
382
+ <Text isEmphazed color="textSecondary" variant="Smaller">
383
+ An user with a specific IAM permissions can
384
+ overwrite/delete protected object versions during the
385
+ retention period.
386
+ </Text>
387
+ </Stack>
388
+ <Stack>
389
+ <input
390
+ type="radio"
391
+ name="locktype"
392
+ id="locktype-compliance"
393
+ value="compliance"
394
+ />
395
+ <label htmlFor="locktype-compliance">Compliance</label>
396
+ </Stack>
397
+ <Text isEmphazed color="textSecondary" variant="Smaller">
398
+ No one can overwrite protected object versions during the
399
+ retention period.
400
+ </Text>
401
+ </Stack>
402
+ }
403
+ required={true}
404
+ ></FormGroup>
405
+ <FormGroup
406
+ id="value-example"
407
+ label="Choose a value"
408
+ helpErrorPosition="bottom"
409
+ required
410
+ content={
411
+ <Select
412
+ id="value-example"
413
+ placeholder="Select an option..."
414
+ onChange={() => {}}
415
+ value={'value-1'}
416
+ >
417
+ <Select.Option value={'value-1'}>Value 1</Select.Option>
418
+ <Select.Option value={'value-2'}>Value 2</Select.Option>
419
+ <Select.Option value={'value-3'}>Value 3</Select.Option>
420
+ </Select>
421
+ }
422
+ />
423
+ </Accordion>
424
+ </FormSection>
425
+ </Form>
426
+ </>
427
+ );
428
+ },
429
+ args: {
430
+ requireMode: 'partial',
431
+ },
432
+ };