@altinn/altinn-components 0.1.0 → 0.2.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 (162) hide show
  1. package/.storybook/StoryDecorator.tsx +27 -0
  2. package/.storybook/ThemeProvider.tsx +16 -0
  3. package/.storybook/main.ts +4 -5
  4. package/.storybook/preview.tsx +31 -29
  5. package/.storybook/storyDecorator.module.css +20 -0
  6. package/.storybook/theme.module.css +3 -0
  7. package/CHANGELOG.md +14 -0
  8. package/CONTRIBUTING.MD +59 -0
  9. package/README.md +33 -1
  10. package/lib/components/Attachment/AttachmentLink.stories.ts +21 -0
  11. package/lib/components/Attachment/AttachmentLink.tsx +20 -0
  12. package/lib/components/Attachment/AttachmentList.stories.ts +39 -0
  13. package/lib/components/Attachment/AttachmentList.tsx +26 -0
  14. package/lib/components/Attachment/attachmentLink.module.css +20 -0
  15. package/lib/components/Attachment/attachmentList.module.css +12 -0
  16. package/lib/components/Attachment/index.ts +2 -0
  17. package/lib/components/Avatar/avatar.module.css +2 -0
  18. package/lib/components/Badge/Badge.stories.ts +32 -0
  19. package/lib/components/Badge/Badge.tsx +13 -10
  20. package/lib/components/Badge/badge.module.css +18 -27
  21. package/lib/components/Button/Button.stories.ts +6 -0
  22. package/lib/components/Button/Button.tsx +19 -1
  23. package/lib/components/Button/ButtonBase.tsx +1 -1
  24. package/lib/components/Button/button.module.css +0 -19
  25. package/lib/components/Button/buttonBase.module.css +30 -12
  26. package/lib/components/Button/comboButton.module.css +4 -2
  27. package/lib/components/ContextMenu/ContextMenu.tsx +28 -0
  28. package/lib/components/ContextMenu/contextMenu.module.css +35 -0
  29. package/lib/components/Dialog/Dialog.stories.ts +320 -0
  30. package/lib/components/Dialog/Dialog.tsx +101 -0
  31. package/lib/components/Dialog/DialogAction.stories.ts +54 -0
  32. package/lib/components/Dialog/DialogAction.tsx +79 -0
  33. package/lib/components/Dialog/DialogActivityLog.tsx +18 -0
  34. package/lib/components/Dialog/DialogArticleBase.tsx +10 -0
  35. package/lib/components/Dialog/DialogAttachments.stories.ts +40 -0
  36. package/lib/components/Dialog/DialogAttachments.tsx +25 -0
  37. package/lib/components/Dialog/DialogBase.tsx +10 -0
  38. package/lib/components/Dialog/DialogBodyBase.tsx +17 -0
  39. package/lib/components/Dialog/DialogBorder.tsx +19 -0
  40. package/lib/components/Dialog/DialogContent.stories.ts +26 -0
  41. package/lib/components/Dialog/DialogContent.tsx +24 -0
  42. package/lib/components/Dialog/DialogFooter.tsx +14 -0
  43. package/lib/components/Dialog/DialogHeader.stories.ts +26 -0
  44. package/lib/components/Dialog/DialogHeader.tsx +23 -0
  45. package/lib/components/Dialog/DialogHeaderBase.tsx +10 -0
  46. package/lib/components/Dialog/DialogHeadings.stories.ts +35 -0
  47. package/lib/components/Dialog/DialogHeadings.tsx +77 -0
  48. package/lib/components/Dialog/DialogHistory.stories.ts +67 -0
  49. package/lib/components/Dialog/DialogHistory.tsx +19 -0
  50. package/lib/components/Dialog/DialogList.stories.ts +61 -0
  51. package/lib/components/Dialog/DialogList.tsx +20 -0
  52. package/lib/components/Dialog/DialogListItem.stories.tsx +238 -0
  53. package/lib/components/Dialog/DialogListItem.tsx +114 -0
  54. package/lib/components/Dialog/DialogListItemBase.tsx +50 -0
  55. package/lib/components/Dialog/DialogMetadata.stories.ts +77 -0
  56. package/lib/components/Dialog/DialogMetadata.tsx +56 -0
  57. package/lib/components/Dialog/DialogNav.stories.ts +90 -0
  58. package/lib/components/Dialog/DialogNav.tsx +60 -0
  59. package/lib/components/Dialog/DialogSectionBase.tsx +20 -0
  60. package/lib/components/Dialog/DialogSeenBy.stories.tsx +58 -0
  61. package/lib/components/Dialog/DialogSeenBy.tsx +36 -0
  62. package/lib/components/Dialog/DialogSelect.tsx +23 -0
  63. package/lib/components/Dialog/DialogStatus.stories.ts +57 -0
  64. package/lib/components/Dialog/DialogStatus.tsx +61 -0
  65. package/lib/components/Dialog/DialogTitle.stories.ts +33 -0
  66. package/lib/components/Dialog/DialogTitle.tsx +31 -0
  67. package/lib/components/Dialog/DialogTouchedBy.stories.tsx +27 -0
  68. package/lib/components/Dialog/DialogTouchedBy.tsx +19 -0
  69. package/lib/components/Dialog/dialog.module.css +21 -0
  70. package/lib/components/Dialog/dialogAction.module.css +26 -0
  71. package/lib/components/Dialog/dialogArticleBase.module.css +5 -0
  72. package/lib/components/Dialog/dialogBodyBase.module.css +13 -0
  73. package/lib/components/Dialog/dialogBorder.module.css +42 -0
  74. package/lib/components/Dialog/dialogHeaderBase.module.css +6 -0
  75. package/lib/components/Dialog/dialogHeadings.module.css +24 -0
  76. package/lib/components/Dialog/dialogHistory.module.css +12 -0
  77. package/lib/components/Dialog/dialogListItem.module.css +81 -0
  78. package/lib/components/Dialog/dialogListItemBase.module.css +28 -0
  79. package/lib/components/Dialog/dialogSectionBase.module.css +11 -0
  80. package/lib/components/Dialog/dialogSelect.module.css +34 -0
  81. package/lib/components/Dialog/dialogTitle.module.css +47 -0
  82. package/lib/components/Dialog/index.ts +2 -0
  83. package/lib/components/Header/GlobalMenu.tsx +1 -1
  84. package/lib/components/Header/Header.tsx +3 -3
  85. package/lib/components/Header/HeaderSearch.tsx +1 -1
  86. package/lib/components/History/HistoryBorder.tsx +17 -0
  87. package/lib/components/History/HistoryItem.stories.ts +47 -0
  88. package/lib/components/History/HistoryItem.tsx +64 -0
  89. package/lib/components/History/HistoryList.stories.ts +58 -0
  90. package/lib/components/History/HistoryList.tsx +26 -0
  91. package/lib/components/History/historyBorder.module.css +8 -0
  92. package/lib/components/History/historyItem.module.css +19 -0
  93. package/lib/components/History/historyList.module.css +12 -0
  94. package/lib/components/History/index.ts +2 -0
  95. package/lib/components/Icon/CheckboxCheckedIcon.tsx +28 -0
  96. package/lib/components/Icon/CheckboxIcon.stories.ts +7 -0
  97. package/lib/components/Icon/CheckboxIcon.tsx +6 -18
  98. package/lib/components/Icon/CheckboxUncheckedIcon.tsx +38 -0
  99. package/lib/components/Icon/ProgressIcon.stories.ts +43 -0
  100. package/lib/components/Icon/ProgressIcon.tsx +44 -0
  101. package/lib/components/Icon/RadioCheckedIcon.tsx +29 -0
  102. package/lib/components/Icon/RadioIcon.stories.ts +7 -0
  103. package/lib/components/Icon/RadioIcon.tsx +7 -19
  104. package/lib/components/Icon/RadioUncheckedIcon.tsx +30 -0
  105. package/lib/components/Icon/checkboxIcon.module.css +2 -0
  106. package/lib/components/Icon/index.ts +1 -0
  107. package/lib/components/Icon/progressIcon.module.css +29 -0
  108. package/lib/components/Layout/Layout.stories.ts +0 -3
  109. package/lib/components/List/List.tsx +20 -0
  110. package/lib/components/List/ListBase.tsx +19 -0
  111. package/lib/components/List/ListItem.stories.tsx +208 -0
  112. package/lib/components/List/ListItem.tsx +70 -0
  113. package/lib/components/List/ListItemBase.tsx +62 -0
  114. package/lib/components/List/ListItemLabel.tsx +29 -0
  115. package/lib/components/List/ListItemMedia.tsx +59 -0
  116. package/lib/components/List/index.ts +4 -0
  117. package/lib/components/List/listBase.module.css +16 -0
  118. package/lib/components/List/listItemBase.module.css +86 -0
  119. package/lib/components/List/listItemLabel.module.css +55 -0
  120. package/lib/components/List/listItemMedia.module.css +41 -0
  121. package/lib/components/Menu/Menu.stories.ts +46 -27
  122. package/lib/components/Menu/Menu.tsx +3 -3
  123. package/lib/components/Menu/MenuItem.stories.ts +12 -5
  124. package/lib/components/Menu/MenuItem.tsx +4 -3
  125. package/lib/components/Menu/MenuItemBase.tsx +7 -7
  126. package/lib/components/Menu/MenuItemLabel.tsx +4 -4
  127. package/lib/components/Menu/MenuItemMedia.tsx +2 -2
  128. package/lib/components/Menu/MenuOption.stories.ts +4 -2
  129. package/lib/components/Menu/MenuOption.tsx +4 -4
  130. package/lib/components/Menu/menuItemBase.module.css +72 -0
  131. package/lib/components/Menu/menuItemLabel.module.css +22 -0
  132. package/lib/components/Menu/menuItemMedia.module.css +36 -0
  133. package/lib/components/Menu/menuOption.module.css +6 -8
  134. package/lib/components/Meta/MetaBase.tsx +15 -0
  135. package/lib/components/Meta/MetaItem.stories.ts +25 -0
  136. package/lib/components/Meta/MetaItem.tsx +31 -0
  137. package/lib/components/Meta/MetaItemBase.tsx +46 -0
  138. package/lib/components/Meta/MetaItemLabel.tsx +20 -0
  139. package/lib/components/Meta/MetaItemMedia.tsx +22 -0
  140. package/lib/components/Meta/MetaList.stories.ts +29 -0
  141. package/lib/components/Meta/MetaList.tsx +43 -0
  142. package/lib/components/Meta/MetaProgress.stories.ts +29 -0
  143. package/lib/components/Meta/MetaProgress.tsx +26 -0
  144. package/lib/components/Meta/MetaTimestamp.stories.ts +33 -0
  145. package/lib/components/Meta/MetaTimestamp.tsx +29 -0
  146. package/lib/components/Meta/index.ts +6 -0
  147. package/lib/components/Meta/meta.module.css +6 -0
  148. package/lib/components/Meta/metaItem.module.css +107 -0
  149. package/lib/components/Meta/metaList.module.css +15 -0
  150. package/lib/components/Toolbar/ToolbarAdd.tsx +1 -1
  151. package/lib/components/Typography/Typography.tsx +21 -0
  152. package/lib/components/Typography/index.ts +1 -0
  153. package/lib/components/Typography/typography.module.css +56 -0
  154. package/lib/components/index.ts +9 -0
  155. package/lib/css/global.css +2 -0
  156. package/lib/css/shadows.css +7 -0
  157. package/lib/css/theme-article.css +15 -0
  158. package/lib/css/theme.css +5 -7
  159. package/package.json +4 -2
  160. package/renovate.json +1 -3
  161. package/.storybook/preview.css +0 -18
  162. /package/lib/components/Toolbar/{index.js → index.ts} +0 -0
@@ -0,0 +1,47 @@
1
+ .title {
2
+ font-weight: 600;
3
+ margin: 0;
4
+ padding-right: 1.25rem;
5
+ display: -webkit-box;
6
+ -webkit-line-clamp: 2;
7
+ line-clamp: 2;
8
+ -webkit-box-orient: vertical;
9
+ overflow: hidden;
10
+ text-overflow: ellipsis;
11
+ }
12
+
13
+ .title[data-size="xs"] {
14
+ font-size: 1rem;
15
+ }
16
+
17
+ .title[data-size="sm"] {
18
+ font-size: 1rem;
19
+ }
20
+
21
+ .title[data-size="md"] {
22
+ font-size: 1.125rem;
23
+ line-height: 1.2;
24
+ }
25
+
26
+ .title[data-size="lg"] {
27
+ font-size: 1.25rem;
28
+ line-height: 1.2;
29
+ }
30
+
31
+ .title[data-size="xl"] {
32
+ font-size: 1.5rem;
33
+ line-height: 1.25;
34
+ }
35
+
36
+ .title[data-seen="true"] {
37
+ font-weight: 400;
38
+ }
39
+
40
+ .title[data-variant="archive"] {
41
+ font-weight: 400;
42
+ }
43
+
44
+ .title[data-variant="bin"] {
45
+ font-weight: 400;
46
+ text-decoration: line-through;
47
+ }
@@ -0,0 +1,2 @@
1
+ export * from './DialogMetadata';
2
+ export * from './DialogListItem';
@@ -116,7 +116,7 @@ export const GlobalMenu = ({
116
116
  return (
117
117
  <div className={cx(styles.button, className)}>
118
118
  <HeaderButton as="div" avatar={accountMenuItem.avatar} onClick={onToggle} expanded={expanded} label={menuLabel} />
119
- <div className={styles?.dropdown} aria-expanded={expanded}>
119
+ <div className={styles.dropdown} aria-expanded={expanded}>
120
120
  {selectAccount ? (
121
121
  <>
122
122
  <MenuItem {...backItem} />
@@ -41,19 +41,19 @@ export const Header = ({ color, search, menu }: HeaderProps) => {
41
41
 
42
42
  return (
43
43
  <header className={styles.header} data-color={color}>
44
- <HeaderLogo className={styles?.logo} />
44
+ <HeaderLogo className={styles.logo} />
45
45
  {menu && (
46
46
  <GlobalMenu
47
47
  {...menu}
48
48
  expanded={expandedType === 'account'}
49
49
  onToggle={() => onToggle('account')}
50
- className={styles?.button}
50
+ className={styles.button}
51
51
  />
52
52
  )}
53
53
  {search && (
54
54
  <HeaderSearch
55
55
  {...search}
56
- className={styles?.search}
56
+ className={styles.search}
57
57
  expanded={expandedType === 'search'}
58
58
  onBlur={onSearchBlur}
59
59
  onFocus={onSearchFocus}
@@ -34,7 +34,7 @@ export const HeaderSearch = ({
34
34
  value={value}
35
35
  onChange={onChange}
36
36
  placeholder={placeholder}
37
- className={styles?.input}
37
+ className={styles.input}
38
38
  type="search"
39
39
  />
40
40
  <Icon name="magnifying-glass" className={styles.icon} />
@@ -0,0 +1,17 @@
1
+ import cx from 'classnames';
2
+ import type { ReactNode } from 'react';
3
+ import styles from './historyBorder.module.css';
4
+
5
+ export interface HistoryBorderProps {
6
+ seen?: boolean;
7
+ className?: string;
8
+ children?: ReactNode;
9
+ }
10
+
11
+ export const HistoryBorder = ({ seen = true, className, children }: HistoryBorderProps) => {
12
+ return (
13
+ <div className={cx(styles.border, className)} data-seen={seen}>
14
+ {children}
15
+ </div>
16
+ );
17
+ };
@@ -0,0 +1,47 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
3
+
4
+ import { HistoryItem } from './HistoryItem';
5
+
6
+ const meta = {
7
+ title: 'History/HistoryItem',
8
+ component: HistoryItem,
9
+ tags: ['autodocs'],
10
+ parameters: {},
11
+ args: {
12
+ createdAt: '2004-09-22 13:34',
13
+ createdBy: {
14
+ name: 'Eirik Horneland',
15
+ },
16
+ summary: 'Brann slo Glimt 4-1 på Stadion.',
17
+ },
18
+ } satisfies Meta<typeof HistoryItem>;
19
+
20
+ export default meta;
21
+ type Story = StoryObj<typeof meta>;
22
+
23
+ export const Default: Story = {
24
+ args: {},
25
+ };
26
+
27
+ export const Attachments: Story = {
28
+ args: {
29
+ attachments: [
30
+ {
31
+ label: '1-0 Castro.pdf',
32
+ },
33
+ {
34
+ label: '2-0 Kornvig.pdf',
35
+ },
36
+ {
37
+ label: '3-0 Kartum.pdf',
38
+ },
39
+ {
40
+ label: '3-1 Zinkernagel.pdf',
41
+ },
42
+ {
43
+ label: '4-1 Castro.pdf',
44
+ },
45
+ ],
46
+ },
47
+ };
@@ -0,0 +1,64 @@
1
+ import { type AttachmentLinkProps, AttachmentList } from '../Attachment';
2
+ import { Avatar } from '../Avatar/';
3
+ import { MetaBase, MetaItem, MetaTimestamp } from '../Meta/';
4
+ import { Typography } from '../Typography';
5
+ import { HistoryBorder } from './HistoryBorder';
6
+ import styles from './historyItem.module.css';
7
+
8
+ export interface CreatedByProps {
9
+ type?: 'company' | 'person';
10
+ name?: string;
11
+ imageUrl?: string;
12
+ }
13
+
14
+ export interface HistoryItemProps {
15
+ createdBy?: CreatedByProps;
16
+ createdAt?: string;
17
+ summary?: string;
18
+ attachments?: AttachmentLinkProps[];
19
+ }
20
+
21
+ export const HistoryItem = ({
22
+ createdBy = {
23
+ type: 'person',
24
+ },
25
+ createdAt,
26
+ summary,
27
+ attachments,
28
+ }: HistoryItemProps) => {
29
+ const title = attachments?.length + ' vedlegg';
30
+
31
+ return (
32
+ <section className={styles.item}>
33
+ <header className={styles.header}>
34
+ <Avatar
35
+ type={createdBy.type || 'person'}
36
+ imageUrl={createdBy?.imageUrl}
37
+ name={createdBy.name || 'Unknown name'}
38
+ size="sm"
39
+ />
40
+ </header>
41
+ <HistoryBorder className={styles.border}>
42
+ <article className={styles.body}>
43
+ <MetaBase>
44
+ <MetaTimestamp datetime={createdAt} size="xs">
45
+ {createdBy?.name + ', '}
46
+ {createdAt}
47
+ </MetaTimestamp>
48
+ </MetaBase>
49
+ <Typography size="lg">
50
+ <p>{summary}</p>
51
+ {attachments ? (
52
+ <section>
53
+ <MetaItem size="xs">{title}</MetaItem>
54
+ <AttachmentList items={attachments} />
55
+ </section>
56
+ ) : (
57
+ ''
58
+ )}
59
+ </Typography>
60
+ </article>
61
+ </HistoryBorder>
62
+ </section>
63
+ );
64
+ };
@@ -0,0 +1,58 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
3
+
4
+ import { HistoryList } from './HistoryList';
5
+
6
+ const meta = {
7
+ title: 'History/HistoryList',
8
+ component: HistoryList,
9
+ tags: ['autodocs'],
10
+ parameters: {},
11
+ args: {
12
+ items: [
13
+ {
14
+ createdAt: '2004-09-22 13:34',
15
+ createdBy: {
16
+ name: 'Eirik Horneland',
17
+ },
18
+ summary: 'Brann slo Glimt 4-1 på Stadion.',
19
+ attachments: [
20
+ {
21
+ label: '1-0 Castro.pdf',
22
+ },
23
+ {
24
+ label: '2-0 Kornvig.pdf',
25
+ },
26
+ {
27
+ label: '3-0 Kartum.pdf',
28
+ },
29
+ {
30
+ label: '3-1 Zinkernagel.pdf',
31
+ },
32
+ {
33
+ label: '4-1 Castro.pdf',
34
+ },
35
+ ],
36
+ },
37
+ {
38
+ createdAt: '2004-09-09 13:34',
39
+ createdBy: {
40
+ name: 'Eirik Horneland',
41
+ },
42
+ summary: 'Brann vant 1-0 i Haugesund.',
43
+ attachments: [
44
+ {
45
+ label: 'Målet til Heggebø.pdf',
46
+ },
47
+ ],
48
+ },
49
+ ],
50
+ },
51
+ } satisfies Meta<typeof HistoryList>;
52
+
53
+ export default meta;
54
+ type Story = StoryObj<typeof meta>;
55
+
56
+ export const Default: Story = {
57
+ args: {},
58
+ };
@@ -0,0 +1,26 @@
1
+ import cx from 'classnames';
2
+ import { HistoryItem, type HistoryItemProps } from './HistoryItem';
3
+ import styles from './historyList.module.css';
4
+
5
+ export interface HistoryProps {
6
+ items: HistoryItemProps[];
7
+ className?: string;
8
+ }
9
+
10
+ export const HistoryList = ({ items, className }: HistoryProps) => {
11
+ if (!items.length) {
12
+ return null;
13
+ }
14
+
15
+ return (
16
+ <ul className={cx(styles.list, className)}>
17
+ {items.map((item, index) => {
18
+ return (
19
+ <li key={index} className={styles.item}>
20
+ <HistoryItem {...item} />
21
+ </li>
22
+ );
23
+ })}
24
+ </ul>
25
+ );
26
+ };
@@ -0,0 +1,8 @@
1
+ .border {
2
+ border-left: 0.25rem solid;
3
+ border-color: var(--theme-surface-active);
4
+ }
5
+
6
+ .border[data-seen="true"] {
7
+ border-color: var(--neutral-surface-default);
8
+ }
@@ -0,0 +1,19 @@
1
+ .item {
2
+ display: flex;
3
+ flex-direction: column;
4
+ }
5
+
6
+ .header {
7
+ margin: 0.375em;
8
+ }
9
+
10
+ .border {
11
+ padding-left: 1.5rem;
12
+ padding-top: 0;
13
+ margin-left: 1rem;
14
+ padding-bottom: 1.5rem;
15
+ }
16
+
17
+ .body {
18
+ margin-top: -1.875rem;
19
+ }
@@ -0,0 +1,12 @@
1
+ .list {
2
+ list-style: none;
3
+ display: flex;
4
+ flex-direction: column;
5
+ row-gap: 1rem;
6
+ padding: 0;
7
+ margin: 0;
8
+ }
9
+
10
+ .item {
11
+ margin: 0;
12
+ }
@@ -0,0 +1,2 @@
1
+ export * from './HistoryList';
2
+ export * from './HistoryItem';
@@ -0,0 +1,28 @@
1
+ export type CheckboxCheckedIconProps = {
2
+ title?: string;
3
+ className?: string;
4
+ };
5
+
6
+ /**
7
+ * Checkbox for lists and list items
8
+ */
9
+ export const CheckboxCheckedIcon = ({ title = 'Checkbox', className }: CheckboxCheckedIconProps) => {
10
+ return (
11
+ <svg
12
+ width="1em"
13
+ height="1em"
14
+ viewBox="0 0 24 24"
15
+ fill="none"
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ className={className}
18
+ >
19
+ <title>{title}</title>
20
+ <path
21
+ fillRule="evenodd"
22
+ clipRule="evenodd"
23
+ d="M2.5 0C1.11929 0 0 1.11929 0 2.5V21.5C0 22.8807 1.11929 24 2.5 24H21.5C22.8807 24 24 22.8807 24 21.5V2.5C24 1.11929 22.8807 0 21.5 0H2.5ZM18.5547 5.76815C19.0142 6.07451 19.1384 6.69538 18.8321 7.1549L11.6321 17.9549C11.4659 18.2042 11.1967 18.3658 10.8985 18.3953C10.6004 18.4249 10.3047 18.3192 10.0929 18.1073L5.29289 13.3073C4.90237 12.9168 4.90237 12.2836 5.29289 11.8931C5.68342 11.5026 6.31658 11.5026 6.70711 11.8931L10.6446 15.8306L17.1679 6.0455C17.4743 5.58598 18.0952 5.4618 18.5547 5.76815Z"
24
+ fill="black"
25
+ />
26
+ </svg>
27
+ );
28
+ };
@@ -18,6 +18,13 @@ export const Default: Story = {
18
18
  },
19
19
  };
20
20
 
21
+ export const Hover: Story = {
22
+ args: {
23
+ checked: false,
24
+ hover: true,
25
+ },
26
+ };
27
+
21
28
  export const Checked: Story = {
22
29
  args: {
23
30
  checked: true,
@@ -1,8 +1,9 @@
1
- import cx from 'classnames';
2
- import styles from './checkboxIcon.module.css';
1
+ import { CheckboxCheckedIcon } from './CheckboxCheckedIcon';
2
+ import { CheckboxUncheckedIcon } from './CheckboxUncheckedIcon';
3
3
 
4
4
  export type CheckboxIconProps = {
5
5
  checked: boolean;
6
+ hover?: boolean;
6
7
  title?: string;
7
8
  className?: string;
8
9
  };
@@ -10,20 +11,7 @@ export type CheckboxIconProps = {
10
11
  /**
11
12
  * Checkbox for lists and list items
12
13
  */
13
- export const CheckboxIcon = ({ checked, title, className }: CheckboxIconProps) => {
14
- return (
15
- <div data-checked={checked} className={cx(styles.checkbox, className)}>
16
- <svg
17
- xmlns="http://www.w3.org/2000/svg"
18
- fill="none"
19
- viewBox="0 0 24 24"
20
- strokeWidth={2.5}
21
- stroke="currentColor"
22
- className={styles.icon}
23
- >
24
- <title>{title}</title>
25
- <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
26
- </svg>
27
- </div>
28
- );
14
+ export const CheckboxIcon = ({ checked, title = 'checkbox', hover = false, className }: CheckboxIconProps) => {
15
+ const iconProps = { title, className };
16
+ return checked ? <CheckboxCheckedIcon {...iconProps} /> : <CheckboxUncheckedIcon {...iconProps} hover={hover} />;
29
17
  };
@@ -0,0 +1,38 @@
1
+ export type CheckboxUncheckedIconProps = {
2
+ title?: string;
3
+ className?: string;
4
+ hover?: boolean;
5
+ };
6
+
7
+ /**
8
+ * Checkbox for lists and list items
9
+ */
10
+ export const CheckboxUncheckedIcon = ({ title = 'Checkbox', className, hover = false }: CheckboxUncheckedIconProps) => {
11
+ return (
12
+ <svg
13
+ width="1em"
14
+ height="1em"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ xmlns="http://www.w3.org/2000/svg"
18
+ className={className}
19
+ >
20
+ <title>{title}</title>
21
+ <path
22
+ fillRule="evenodd"
23
+ clipRule="evenodd"
24
+ d="M21.5 2.5H2.5V21.5H21.5V2.5ZM2.5 0C1.11929 0 0 1.11929 0 2.5V21.5C0 22.8807 1.11929 24 2.5 24H21.5C22.8807 24 24 22.8807 24 21.5V2.5C24 1.11929 22.8807 0 21.5 0H2.5Z"
25
+ fill="black"
26
+ />
27
+ {hover && (
28
+ <path
29
+ data-hover={true}
30
+ fillRule="evenodd"
31
+ clipRule="evenodd"
32
+ d="M18.5547 5.76815C19.0142 6.07451 19.1384 6.69538 18.8321 7.1549L11.6321 17.9549C11.4659 18.2042 11.1967 18.3658 10.8985 18.3953C10.6004 18.4249 10.3047 18.3192 10.0929 18.1073L5.29289 13.3073C4.90237 12.9168 4.90237 12.2836 5.29289 11.8931C5.68342 11.5026 6.31658 11.5026 6.70711 11.8931L10.6446 15.8306L17.1679 6.0455C17.4743 5.58598 18.0952 5.4618 18.5547 5.76815Z"
33
+ fill="currentColor"
34
+ />
35
+ )}
36
+ </svg>
37
+ );
38
+ };
@@ -0,0 +1,43 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { ProgressIcon } from './ProgressIcon';
3
+
4
+ const meta = {
5
+ title: 'Atoms/Icon/ProgressIcon',
6
+ component: ProgressIcon,
7
+ tags: ['autodocs'],
8
+ parameters: {},
9
+ args: {},
10
+ } satisfies Meta<typeof ProgressIcon>;
11
+
12
+ export default meta;
13
+ type Story = StoryObj<typeof meta>;
14
+
15
+ export const Default: Story = {
16
+ args: {
17
+ value: 0,
18
+ },
19
+ };
20
+
21
+ export const Progress25: Story = {
22
+ args: {
23
+ value: 25,
24
+ },
25
+ };
26
+
27
+ export const Progress50: Story = {
28
+ args: {
29
+ value: 50,
30
+ },
31
+ };
32
+
33
+ export const Progress75: Story = {
34
+ args: {
35
+ value: 75,
36
+ },
37
+ };
38
+
39
+ export const Progress100: Story = {
40
+ args: {
41
+ value: 100,
42
+ },
43
+ };
@@ -0,0 +1,44 @@
1
+ import cx from 'classnames';
2
+ import type { CSSProperties } from 'react';
3
+ import styles from './progressIcon.module.css';
4
+ export interface ProgressIconProps {
5
+ value?: number;
6
+ total?: number;
7
+ className?: string;
8
+ }
9
+
10
+ interface CustomCSSProperties extends CSSProperties {
11
+ '--progress'?: string;
12
+ }
13
+ export const ProgressIcon = ({ value = 0, total = 100, className }: ProgressIconProps) => {
14
+ const percentage = Math.round((value / total) * 100);
15
+
16
+ if (value === total) {
17
+ return (
18
+ <svg
19
+ width="16"
20
+ height="16"
21
+ viewBox="0 0 16 16"
22
+ fill="none"
23
+ xmlns="http://www.w3.org/2000/svg"
24
+ className={styles.complete}
25
+ >
26
+ <title>
27
+ Progress {value} of {total}
28
+ </title>
29
+ <path
30
+ fill="currentColor"
31
+ fillRule="evenodd"
32
+ clipRule="evenodd"
33
+ d="M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM11.1751 5.11246C11.3892 4.87167 11.7579 4.84998 11.9987 5.06402C12.2395 5.27805 12.2612 5.64676 12.0471 5.88755L7.60268 10.8876C7.49595 11.0076 7.34442 11.0784 7.18383 11.0831C7.02324 11.0878 6.86782 11.0261 6.75421 10.9125L3.97644 8.13471C3.74863 7.9069 3.74863 7.53756 3.97644 7.30975C4.20424 7.08194 4.57359 7.08194 4.80139 7.30975L7.14172 9.65007L11.1751 5.11246Z"
34
+ />
35
+ </svg>
36
+ );
37
+ }
38
+
39
+ const progressStyle: CustomCSSProperties = {
40
+ '--progress': `${percentage}%`,
41
+ };
42
+
43
+ return <div className={cx(styles.progress, className)} style={progressStyle} data-value={`${percentage}%`} />;
44
+ };
@@ -0,0 +1,29 @@
1
+ export type RadioCheckedIconProps = {
2
+ title?: string;
3
+ className?: string;
4
+ };
5
+
6
+ /**
7
+ * Radio for lists and list items
8
+ */
9
+ export const RadioCheckedIcon = ({ title = 'Radio', className }: RadioCheckedIconProps) => {
10
+ return (
11
+ <svg
12
+ width="1em"
13
+ height="1em"
14
+ viewBox="0 0 24 24"
15
+ fill="none"
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ className={className}
18
+ >
19
+ <title>{title}</title>
20
+
21
+ <path
22
+ fillRule="evenodd"
23
+ clipRule="evenodd"
24
+ d="M12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24ZM12 17C14.7614 17 17 14.7614 17 12C17 9.23858 14.7614 7 12 7C9.23858 7 7 9.23858 7 12C7 14.7614 9.23858 17 12 17Z"
25
+ fill="black"
26
+ />
27
+ </svg>
28
+ );
29
+ };
@@ -18,6 +18,13 @@ export const Default: Story = {
18
18
  },
19
19
  };
20
20
 
21
+ export const Hover: Story = {
22
+ args: {
23
+ checked: false,
24
+ hover: true,
25
+ },
26
+ };
27
+
21
28
  export const Checked: Story = {
22
29
  args: {
23
30
  checked: true,
@@ -1,29 +1,17 @@
1
- import cx from 'classnames';
2
- import styles from './radioIcon.module.css';
1
+ import { RadioCheckedIcon } from './RadioCheckedIcon';
2
+ import { RadioUncheckedIcon } from './RadioUncheckedIcon';
3
3
 
4
4
  export type RadioIconProps = {
5
5
  checked: boolean;
6
+ hover?: boolean;
6
7
  title?: string;
7
8
  className?: string;
8
9
  };
9
10
 
10
11
  /**
11
- * Radio icon for lists and list items
12
+ * Radio for lists and list items
12
13
  */
13
- export const RadioIcon = ({ checked, title, className }: RadioIconProps) => {
14
- return (
15
- <div data-checked={checked} className={cx(styles.radio, className)}>
16
- <svg
17
- xmlns="http://www.w3.org/2000/svg"
18
- fill="none"
19
- viewBox="0 0 24 24"
20
- strokeWidth={2.5}
21
- stroke="currentColor"
22
- className={styles.icon}
23
- >
24
- <title>{title}</title>
25
- <circle cx="12" cy="12" r="6" fill="currentColor" />
26
- </svg>
27
- </div>
28
- );
14
+ export const RadioIcon = ({ checked, title = 'Radio', hover = false, className }: RadioIconProps) => {
15
+ const iconProps = { title, className };
16
+ return checked ? <RadioCheckedIcon {...iconProps} /> : <RadioUncheckedIcon {...iconProps} hover={hover} />;
29
17
  };
@@ -0,0 +1,30 @@
1
+ export type RadioUncheckedIconProps = {
2
+ title?: string;
3
+ className?: string;
4
+ hover?: boolean;
5
+ };
6
+
7
+ /**
8
+ * Radio for lists and list items
9
+ */
10
+ export const RadioUncheckedIcon = ({ title = 'Radio', className, hover = false }: RadioUncheckedIconProps) => {
11
+ return (
12
+ <svg
13
+ width="1em"
14
+ height="1em"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ xmlns="http://www.w3.org/2000/svg"
18
+ className={className}
19
+ >
20
+ <title>{title}</title>
21
+ <path
22
+ fillRule="evenodd"
23
+ clipRule="evenodd"
24
+ d="M12 21.5C17.2467 21.5 21.5 17.2467 21.5 12C21.5 6.75329 17.2467 2.5 12 2.5C6.75329 2.5 2.5 6.75329 2.5 12C2.5 17.2467 6.75329 21.5 12 21.5ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24Z"
25
+ fill="black"
26
+ />
27
+ {hover && <circle data-hover={true} cx="12" cy="12" r="5" fill="black" />}
28
+ </svg>
29
+ );
30
+ };