@workday/canvas-kit-labs-react 17.0.0-alpha.0649-next.0 → 17.0.0-alpha.0655-next.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 (72) hide show
  1. package/accessory/index.ts +6 -0
  2. package/accessory/lib/Accessory.tsx +156 -0
  3. package/accessory/lib/AccessoryCalendar.tsx +114 -0
  4. package/accessory/lib/AccessoryFavicon.tsx +156 -0
  5. package/accessory/lib/AccessoryFile.tsx +140 -0
  6. package/accessory/lib/AccessoryIcon.tsx +213 -0
  7. package/accessory/lib/AccessoryMedia.tsx +142 -0
  8. package/accessory/package.json +6 -0
  9. package/dist/commonjs/accessory/index.d.ts +7 -0
  10. package/dist/commonjs/accessory/index.d.ts.map +1 -0
  11. package/dist/commonjs/accessory/index.js +22 -0
  12. package/dist/commonjs/accessory/lib/Accessory.d.ts +157 -0
  13. package/dist/commonjs/accessory/lib/Accessory.d.ts.map +1 -0
  14. package/dist/commonjs/accessory/lib/Accessory.js +51 -0
  15. package/dist/commonjs/accessory/lib/AccessoryCalendar.d.ts +80 -0
  16. package/dist/commonjs/accessory/lib/AccessoryCalendar.d.ts.map +1 -0
  17. package/dist/commonjs/accessory/lib/AccessoryCalendar.js +48 -0
  18. package/dist/commonjs/accessory/lib/AccessoryFavicon.d.ts +75 -0
  19. package/dist/commonjs/accessory/lib/AccessoryFavicon.d.ts.map +1 -0
  20. package/dist/commonjs/accessory/lib/AccessoryFavicon.js +74 -0
  21. package/dist/commonjs/accessory/lib/AccessoryFile.d.ts +65 -0
  22. package/dist/commonjs/accessory/lib/AccessoryFile.d.ts.map +1 -0
  23. package/dist/commonjs/accessory/lib/AccessoryFile.js +58 -0
  24. package/dist/commonjs/accessory/lib/AccessoryIcon.d.ts +119 -0
  25. package/dist/commonjs/accessory/lib/AccessoryIcon.d.ts.map +1 -0
  26. package/dist/commonjs/accessory/lib/AccessoryIcon.js +61 -0
  27. package/dist/commonjs/accessory/lib/AccessoryMedia.d.ts +72 -0
  28. package/dist/commonjs/accessory/lib/AccessoryMedia.d.ts.map +1 -0
  29. package/dist/commonjs/accessory/lib/AccessoryMedia.js +59 -0
  30. package/dist/commonjs/ai-ingress-button/lib/AIIngressButton.js +5 -5
  31. package/dist/commonjs/index.d.ts +1 -0
  32. package/dist/commonjs/index.d.ts.map +1 -1
  33. package/dist/commonjs/index.js +1 -0
  34. package/dist/commonjs/kbd/lib/KBD.js +6 -6
  35. package/dist/commonjs/kbd/lib/KBDItem.js +6 -6
  36. package/dist/commonjs/selection-group/lib/SelectionGroupIcon.js +1 -1
  37. package/dist/commonjs/selection-group/lib/SelectionGroupItem.js +4 -4
  38. package/dist/commonjs/selection-group/lib/SelectionGroupList.js +6 -6
  39. package/dist/commonjs/version/lib/version.js +1 -1
  40. package/dist/es6/accessory/index.d.ts +7 -0
  41. package/dist/es6/accessory/index.d.ts.map +1 -0
  42. package/dist/es6/accessory/index.js +6 -0
  43. package/dist/es6/accessory/lib/Accessory.d.ts +157 -0
  44. package/dist/es6/accessory/lib/Accessory.d.ts.map +1 -0
  45. package/dist/es6/accessory/lib/Accessory.js +48 -0
  46. package/dist/es6/accessory/lib/AccessoryCalendar.d.ts +80 -0
  47. package/dist/es6/accessory/lib/AccessoryCalendar.d.ts.map +1 -0
  48. package/dist/es6/accessory/lib/AccessoryCalendar.js +45 -0
  49. package/dist/es6/accessory/lib/AccessoryFavicon.d.ts +75 -0
  50. package/dist/es6/accessory/lib/AccessoryFavicon.d.ts.map +1 -0
  51. package/dist/es6/accessory/lib/AccessoryFavicon.js +71 -0
  52. package/dist/es6/accessory/lib/AccessoryFile.d.ts +65 -0
  53. package/dist/es6/accessory/lib/AccessoryFile.d.ts.map +1 -0
  54. package/dist/es6/accessory/lib/AccessoryFile.js +55 -0
  55. package/dist/es6/accessory/lib/AccessoryIcon.d.ts +119 -0
  56. package/dist/es6/accessory/lib/AccessoryIcon.d.ts.map +1 -0
  57. package/dist/es6/accessory/lib/AccessoryIcon.js +58 -0
  58. package/dist/es6/accessory/lib/AccessoryMedia.d.ts +72 -0
  59. package/dist/es6/accessory/lib/AccessoryMedia.d.ts.map +1 -0
  60. package/dist/es6/accessory/lib/AccessoryMedia.js +53 -0
  61. package/dist/es6/ai-ingress-button/lib/AIIngressButton.js +5 -5
  62. package/dist/es6/index.d.ts +1 -0
  63. package/dist/es6/index.d.ts.map +1 -1
  64. package/dist/es6/index.js +1 -0
  65. package/dist/es6/kbd/lib/KBD.js +6 -6
  66. package/dist/es6/kbd/lib/KBDItem.js +6 -6
  67. package/dist/es6/selection-group/lib/SelectionGroupIcon.js +1 -1
  68. package/dist/es6/selection-group/lib/SelectionGroupItem.js +4 -4
  69. package/dist/es6/selection-group/lib/SelectionGroupList.js +6 -6
  70. package/dist/es6/version/lib/version.js +1 -1
  71. package/index.ts +1 -0
  72. package/package.json +4 -4
@@ -0,0 +1,6 @@
1
+ export * from './lib/Accessory';
2
+ export * from './lib/AccessoryCalendar';
3
+ export * from './lib/AccessoryFavicon';
4
+ export * from './lib/AccessoryFile';
5
+ export * from './lib/AccessoryIcon';
6
+ export * from './lib/AccessoryMedia';
@@ -0,0 +1,156 @@
1
+ import {cornerShapeStencil, createComponent} from '@workday/canvas-kit-react/common';
2
+ import {systemIconStencil} from '@workday/canvas-kit-react/icon';
3
+ import {CSProps, createStencil, cssVar, handleCsProp} from '@workday/canvas-kit-styling';
4
+ import {base, component, system} from '@workday/canvas-tokens-web';
5
+
6
+ /**
7
+ * The size of an `Accessory` tile.
8
+ *
9
+ * * `extraSmall` — 16px tile, 16px icon
10
+ * * `small` — 20px tile, 18px icon
11
+ * * `medium` — 24px tile, 16px icon
12
+ * * `large` — 32px tile, 18px icon
13
+ * * `extraLarge` — 40px tile, 20px icon
14
+ */
15
+ export type AccessorySize = 'extraSmall' | 'small' | 'medium' | 'large' | 'extraLarge';
16
+
17
+ export interface AccessoryProps extends CSProps {
18
+ /**
19
+ * The size of the tile. Icon glyph size follows the tile through the icon `data-part`: 16px,
20
+ * 18px, 16px, 18px, and 20px from `extraSmall` to `extraLarge`.
21
+ *
22
+ * * `extraSmall` — 16px
23
+ * * `small` — 20px
24
+ * * `medium` — 24px
25
+ * * `large` — 32px
26
+ * * `extraLarge` — 40px
27
+ *
28
+ * @default 'extraLarge'
29
+ */
30
+ size?: AccessorySize;
31
+ /**
32
+ * The color of the icon. When set, this overrides the icon color from `variant` on
33
+ * `AccessoryIcon`. Inherited by the icon `data-part` via a CSS variable.
34
+ */
35
+ color?: string;
36
+ /**
37
+ * The background color of the icon tile. When set, this overrides the fill from `variant` and is
38
+ * painted at every size, including `small` and `extraSmall`. Inherited by the icon `data-part`
39
+ * via a CSS variable.
40
+ */
41
+ background?: string;
42
+ }
43
+
44
+ /**
45
+ * Tile shell for accessory visuals. Owns size, corner radius, icon glyph size, and optional icon
46
+ * color / fill overrides through the icon `data-part`. Prefer `AccessoryIcon`, `AccessoryFile`, or
47
+ * `AccessoryMedia`, which render this shell.
48
+ */
49
+ export const accessoryStencil = createStencil({
50
+ extends: cornerShapeStencil,
51
+ vars: {
52
+ iconColor: '',
53
+ tileBackground: '',
54
+ },
55
+ parts: {
56
+ icon: 'accessory-icon',
57
+ },
58
+ base: ({iconColor, iconPart, shape}) => ({
59
+ display: 'inline-flex',
60
+ position: 'relative',
61
+ alignItems: 'center',
62
+ justifyContent: 'center',
63
+ flexShrink: 0,
64
+ verticalAlign: 'middle',
65
+ [iconPart]: {
66
+ position: 'absolute',
67
+ inset: 0,
68
+ display: 'flex',
69
+ alignItems: 'center',
70
+ justifyContent: 'center',
71
+ borderRadius: shape,
72
+ cornerShape: 'superellipse(1.1)',
73
+ [systemIconStencil.vars.color]: cssVar(iconColor),
74
+ },
75
+ }),
76
+ modifiers: {
77
+ size: {
78
+ extraSmall: ({iconPart, tileBackground}) => ({
79
+ width: system.legacy.size.xxxs,
80
+ height: system.legacy.size.xxxs,
81
+ [cornerShapeStencil.vars.shape]: system.legacy.shape.sm,
82
+ [iconPart]: {
83
+ [systemIconStencil.vars.size]: base.legacy.size200,
84
+ backgroundColor: cssVar(tileBackground, 'transparent'),
85
+ borderWidth: 0,
86
+ },
87
+ }),
88
+ small: ({iconPart, tileBackground}) => ({
89
+ width: system.legacy.size.xxs,
90
+ height: system.legacy.size.xxs,
91
+ [cornerShapeStencil.vars.shape]: system.legacy.shape.sm,
92
+ [iconPart]: {
93
+ [systemIconStencil.vars.size]: base.legacy.size225,
94
+ backgroundColor: cssVar(tileBackground, 'transparent'),
95
+ borderWidth: 0,
96
+ },
97
+ }),
98
+ medium: ({iconPart}) => ({
99
+ width: system.legacy.size.xs,
100
+ height: system.legacy.size.xs,
101
+ [cornerShapeStencil.vars.shape]: system.legacy.shape.md,
102
+ [iconPart]: {
103
+ [systemIconStencil.vars.size]: component.legacy.systemIcon.size.xs,
104
+ },
105
+ }),
106
+ large: ({iconPart}) => ({
107
+ width: system.legacy.size.sm,
108
+ height: system.legacy.size.sm,
109
+ [cornerShapeStencil.vars.shape]: base.legacy.size125,
110
+ [iconPart]: {
111
+ [systemIconStencil.vars.size]: component.legacy.systemIcon.size.sm,
112
+ },
113
+ }),
114
+ extraLarge: ({iconPart}) => ({
115
+ width: system.legacy.size.md,
116
+ height: system.legacy.size.md,
117
+ [cornerShapeStencil.vars.shape]: system.legacy.shape.lg,
118
+ [iconPart]: {
119
+ [systemIconStencil.vars.size]: component.legacy.systemIcon.size.md,
120
+ },
121
+ }),
122
+ },
123
+ },
124
+ });
125
+
126
+ /**
127
+ * `Accessory` is the small rounded visual that sits beside text, most often the leading element in
128
+ * a list item or other row. It owns the tile size and corner radius so a system icon, file type,
129
+ * image, site favicon, calendar date, or custom content stays one consistent shape.
130
+ * `AccessoryIcon`, `AccessoryFile`, `AccessoryMedia`, `AccessoryFavicon`, and `AccessoryCalendar`
131
+ * render this shell. Accessories are
132
+ * decorative and always hidden from assistive technology.
133
+ *
134
+ * ```tsx
135
+ * <AccessoryIcon icon={activityIcon} />
136
+ * ```
137
+ */
138
+ export const Accessory = createComponent('span')({
139
+ displayName: 'Accessory',
140
+ Component: (
141
+ {size = 'extraLarge', color, background, ...elemProps}: AccessoryProps,
142
+ ref,
143
+ Element
144
+ ) => {
145
+ return (
146
+ <Element
147
+ ref={ref}
148
+ {...handleCsProp(
149
+ elemProps,
150
+ accessoryStencil({size, iconColor: color, tileBackground: background})
151
+ )}
152
+ aria-hidden={true}
153
+ />
154
+ );
155
+ },
156
+ });
@@ -0,0 +1,114 @@
1
+ import {createComponent} from '@workday/canvas-kit-react/common';
2
+ import {createStencil, cssVar, handleCsProp, px2rem} from '@workday/canvas-kit-styling';
3
+ import {system} from '@workday/canvas-tokens-web';
4
+
5
+ import {Accessory, AccessoryProps, accessoryStencil} from './Accessory';
6
+
7
+ export interface AccessoryCalendarProps extends AccessoryProps {
8
+ /**
9
+ * The month label, such as `Apr`.
10
+ */
11
+ month: string;
12
+ /**
13
+ * The day of the month, such as `30`.
14
+ */
15
+ date: number | string;
16
+ }
17
+
18
+ /**
19
+ * Calendar treatment for `AccessoryCalendar`. The month uses a critical color. The day uses the
20
+ * default foreground color. `size` scales both. `color` overrides the month. `background`
21
+ * overrides the tile fill.
22
+ */
23
+ export const accessoryCalendarStencil = createStencil({
24
+ parts: {
25
+ icon: 'accessory-icon',
26
+ month: 'accessory-calendar-month',
27
+ date: 'accessory-calendar-date',
28
+ },
29
+ base: ({datePart, iconPart, monthPart}) => ({
30
+ [iconPart]: {
31
+ flexDirection: 'column',
32
+ // 3px stack gap on the 40px tile, scaled with the tile.
33
+ gap: '0.075em',
34
+ overflow: 'hidden',
35
+ backgroundColor: cssVar(
36
+ accessoryStencil.vars.tileBackground,
37
+ system.legacy.color.surface.default
38
+ ),
39
+ borderWidth: px2rem(1),
40
+ borderStyle: 'solid',
41
+ borderColor: system.legacy.color.border.default,
42
+ },
43
+ [monthPart]: {
44
+ color: cssVar(accessoryStencil.vars.iconColor, system.legacy.color.fg.danger.default),
45
+ fontSize: '0.25em',
46
+ fontWeight: system.fontWeight.medium,
47
+ lineHeight: 1,
48
+ whiteSpace: 'nowrap',
49
+ },
50
+ [datePart]: {
51
+ color: system.color.fg.default,
52
+ fontSize: '0.4em',
53
+ fontWeight: system.fontWeight.normal,
54
+ lineHeight: 1,
55
+ whiteSpace: 'nowrap',
56
+ },
57
+ }),
58
+ modifiers: {
59
+ /**
60
+ * The icon part's font size matches the tile so month (`0.25em`) and day (`0.4em`) stay in
61
+ * proportion. At `extraLarge` that is 10px and 16px (`subtext.sm` and `body.sm`). Type tokens
62
+ * do not go below 10px, so smaller tiles keep the ratio instead of a fixed type level.
63
+ */
64
+ size: {
65
+ extraSmall: ({iconPart}) => ({
66
+ [iconPart]: {fontSize: system.legacy.fontSize.body.sm},
67
+ }),
68
+ small: ({iconPart}) => ({
69
+ [iconPart]: {fontSize: system.legacy.fontSize.body.lg},
70
+ }),
71
+ medium: ({iconPart}) => ({
72
+ [iconPart]: {fontSize: system.legacy.fontSize.heading.sm},
73
+ }),
74
+ large: ({iconPart}) => ({
75
+ [iconPart]: {fontSize: system.legacy.fontSize.heading.lg},
76
+ }),
77
+ extraLarge: ({iconPart}) => ({
78
+ [iconPart]: {fontSize: system.legacy.fontSize.title.sm},
79
+ }),
80
+ },
81
+ },
82
+ defaultModifiers: {
83
+ size: 'extraLarge',
84
+ },
85
+ });
86
+
87
+ /**
88
+ * `AccessoryCalendar` renders a month and day in an accessory tile. The month is critical and the
89
+ * day is the default foreground color. Both scale with `size`. Always decorative.
90
+ */
91
+ export const AccessoryCalendar = createComponent('span')({
92
+ displayName: 'AccessoryCalendar',
93
+ Component: (
94
+ {month, date, size = 'extraLarge', color, background, ...elemProps}: AccessoryCalendarProps,
95
+ ref,
96
+ Element
97
+ ) => {
98
+ return (
99
+ <Accessory
100
+ as={Element}
101
+ ref={ref}
102
+ background={background}
103
+ color={color}
104
+ size={size}
105
+ {...handleCsProp(elemProps, accessoryCalendarStencil({size}))}
106
+ >
107
+ <span {...accessoryStencil.parts.icon}>
108
+ <span {...accessoryCalendarStencil.parts.month}>{month}</span>
109
+ <span {...accessoryCalendarStencil.parts.date}>{date}</span>
110
+ </span>
111
+ </Accessory>
112
+ );
113
+ },
114
+ });
@@ -0,0 +1,156 @@
1
+ import {createComponent} from '@workday/canvas-kit-react/common';
2
+ import {createStencil, cssVar, handleCsProp, px2rem} from '@workday/canvas-kit-styling';
3
+ import {system} from '@workday/canvas-tokens-web';
4
+
5
+ import {Accessory, AccessoryProps, AccessorySize, accessoryStencil} from './Accessory';
6
+
7
+ /** Hostname from a site URL or a bare domain such as `workday.com`. */
8
+ function hostnameFromSiteUrl(siteUrl: string): string {
9
+ const trimmed = siteUrl.trim();
10
+ if (!trimmed) {
11
+ return '';
12
+ }
13
+
14
+ try {
15
+ const withProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
16
+ return new URL(withProtocol).hostname || '';
17
+ } catch {
18
+ return '';
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Brand favicon URL for a site, resolved through the public Google favicon endpoint. Tiles larger
24
+ * than 32px request a 180px source. Smaller tiles request 64px.
25
+ */
26
+ function faviconSrcFromSiteUrl(siteUrl: string, size: AccessorySize): string {
27
+ const host = hostnameFromSiteUrl(siteUrl);
28
+ if (!host) {
29
+ return '';
30
+ }
31
+
32
+ const sourceSize = size === 'extraLarge' ? 180 : 64;
33
+ return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(host)}&sz=${sourceSize}`;
34
+ }
35
+
36
+ export interface AccessoryFaviconProps extends AccessoryProps {
37
+ /**
38
+ * The site URL or bare domain, such as `https://design.workday.com` or `workday.com`. The hostname is
39
+ * used to resolve the favicon.
40
+ */
41
+ url: string;
42
+ }
43
+
44
+ /**
45
+ * Favicon treatment for `AccessoryFavicon`. At `large` and `extraLarge` the mark is inset in an
46
+ * outlined tile. At `medium` and smaller the mark fills the tile and the frame is removed.
47
+ * `background` overrides the tile fill.
48
+ */
49
+ export const accessoryFaviconStencil = createStencil({
50
+ parts: {
51
+ icon: 'accessory-icon',
52
+ image: 'accessory-favicon-image',
53
+ },
54
+ base: ({iconPart, imagePart}) => ({
55
+ [iconPart]: {
56
+ overflow: 'hidden',
57
+ backgroundColor: cssVar(
58
+ accessoryStencil.vars.tileBackground,
59
+ system.legacy.color.surface.default
60
+ ),
61
+ borderWidth: px2rem(1),
62
+ borderStyle: 'solid',
63
+ borderColor: system.legacy.color.border.default,
64
+ },
65
+ [imagePart]: {
66
+ width: `calc(100% - ${system.legacy.padding.sm})`,
67
+ height: `calc(100% - ${system.legacy.padding.sm})`,
68
+ objectFit: 'contain',
69
+ borderRadius: system.legacy.shape.md,
70
+ cornerShape: 'superellipse(1.1)',
71
+ },
72
+ }),
73
+ modifiers: {
74
+ size: {
75
+ extraSmall: ({iconPart, imagePart}) => ({
76
+ [iconPart]: {
77
+ backgroundColor: cssVar(accessoryStencil.vars.tileBackground, 'transparent'),
78
+ borderWidth: 0,
79
+ },
80
+ [imagePart]: {
81
+ width: '100%',
82
+ height: '100%',
83
+ borderRadius: 0,
84
+ },
85
+ }),
86
+ small: ({iconPart, imagePart}) => ({
87
+ [iconPart]: {
88
+ backgroundColor: cssVar(accessoryStencil.vars.tileBackground, 'transparent'),
89
+ borderWidth: 0,
90
+ },
91
+ [imagePart]: {
92
+ width: '100%',
93
+ height: '100%',
94
+ borderRadius: 0,
95
+ },
96
+ }),
97
+ medium: ({iconPart, imagePart}) => ({
98
+ [iconPart]: {
99
+ backgroundColor: cssVar(accessoryStencil.vars.tileBackground, 'transparent'),
100
+ borderWidth: 0,
101
+ },
102
+ [imagePart]: {
103
+ width: '100%',
104
+ height: '100%',
105
+ borderRadius: 0,
106
+ },
107
+ }),
108
+ large: {},
109
+ extraLarge: {},
110
+ },
111
+ },
112
+ defaultModifiers: {
113
+ size: 'extraLarge',
114
+ },
115
+ });
116
+
117
+ /**
118
+ * `AccessoryFavicon` renders a site favicon in an accessory tile. Pass a site URL or domain as
119
+ * `url`. The mark is inset in an outlined frame at `large` and `extraLarge`, and fills the tile at
120
+ * smaller sizes. Always decorative.
121
+ *
122
+ * The image is requested from the user's browser at `https://www.google.com/s2/favicons`. Google
123
+ * receives the hostname and the user's IP address. `referrerPolicy="no-referrer"` keeps the app
124
+ * origin off that request. It does not proxy the request.
125
+ */
126
+ export const AccessoryFavicon = createComponent('span')({
127
+ displayName: 'AccessoryFavicon',
128
+ Component: (
129
+ {url, size = 'extraLarge', background, ...elemProps}: AccessoryFaviconProps,
130
+ ref,
131
+ Element
132
+ ) => {
133
+ const src = faviconSrcFromSiteUrl(url, size);
134
+
135
+ return (
136
+ <Accessory
137
+ as={Element}
138
+ ref={ref}
139
+ background={background}
140
+ size={size}
141
+ {...handleCsProp(elemProps, accessoryFaviconStencil({size}))}
142
+ >
143
+ {src ? (
144
+ <span {...accessoryStencil.parts.icon}>
145
+ <img
146
+ alt=""
147
+ src={src}
148
+ {...accessoryFaviconStencil.parts.image}
149
+ referrerPolicy="no-referrer"
150
+ />
151
+ </span>
152
+ ) : null}
153
+ </Accessory>
154
+ );
155
+ },
156
+ });
@@ -0,0 +1,140 @@
1
+ import {createComponent} from '@workday/canvas-kit-react/common';
2
+ import {SystemIcon, SystemIconProps, systemIconStencil} from '@workday/canvas-kit-react/icon';
3
+ import {createStencil, cssVar, handleCsProp, px2rem} from '@workday/canvas-kit-styling';
4
+ import {
5
+ documentIcon,
6
+ pdfIcon,
7
+ playCircleIcon,
8
+ stackIcon,
9
+ tableExpandIcon,
10
+ txtIcon,
11
+ } from '@workday/canvas-system-icons-web';
12
+ import {system} from '@workday/canvas-tokens-web';
13
+
14
+ import {Accessory, AccessoryProps, accessoryStencil} from './Accessory';
15
+
16
+ /**
17
+ * The kind of file `AccessoryFile` represents.
18
+ */
19
+ export type AccessoryFileType =
20
+ | 'pdf'
21
+ | 'spreadsheet'
22
+ | 'document'
23
+ | 'presentation'
24
+ | 'video'
25
+ | 'file'
26
+ | 'txt';
27
+
28
+ export interface AccessoryFileProps extends AccessoryProps {
29
+ /**
30
+ * The file type. Chooses the glyph and sets the tile fill and icon color through a stencil
31
+ * modifier. Colored types keep their accent fill at every size. `file` and `txt` use
32
+ * `surface.alt` with a `border.default` stroke. `video` uses `surface.alt` and an inverse icon.
33
+ * `color` and `background` override the type colors.
34
+ * @default 'file'
35
+ */
36
+ type?: AccessoryFileType;
37
+ }
38
+
39
+ /**
40
+ * File-type treatment for `AccessoryFile`. Each `type` sets the tile fill and icon color.
41
+ * `outline` adds the default border used by `file` and `txt`. `color` and `background` on
42
+ * `Accessory` still override the type colors.
43
+ */
44
+ export const accessoryFileStencil = createStencil({
45
+ parts: {
46
+ icon: 'accessory-icon',
47
+ },
48
+ base: ({iconPart}) => ({
49
+ [iconPart]: {
50
+ backgroundColor: cssVar(accessoryStencil.vars.tileBackground),
51
+ [systemIconStencil.vars.color]: cssVar(accessoryStencil.vars.iconColor),
52
+ },
53
+ }),
54
+ modifiers: {
55
+ type: {
56
+ pdf: {
57
+ [accessoryStencil.vars.iconColor]: system.color.fg.inverse,
58
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.accent.danger,
59
+ },
60
+ spreadsheet: {
61
+ [accessoryStencil.vars.iconColor]: system.color.fg.inverse,
62
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.accent.success,
63
+ },
64
+ document: {
65
+ [accessoryStencil.vars.iconColor]: system.color.fg.inverse,
66
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.accent.info,
67
+ },
68
+ presentation: {
69
+ // Amber is too light for an inverse glyph (about 2:1). `accent.contrast` is the dark
70
+ // foreground paired with accent fills.
71
+ [accessoryStencil.vars.iconColor]: system.legacy.color.accent.contrast,
72
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.accent.warning,
73
+ },
74
+ video: {
75
+ [accessoryStencil.vars.iconColor]: system.color.fg.default,
76
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.surface.alt.default,
77
+ },
78
+ file: {
79
+ [accessoryStencil.vars.iconColor]: system.color.fg.default,
80
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.surface.alt.default,
81
+ },
82
+ txt: {
83
+ [accessoryStencil.vars.iconColor]: system.color.fg.default,
84
+ [accessoryStencil.vars.tileBackground]: system.legacy.color.surface.alt.default,
85
+ },
86
+ },
87
+ outline: {
88
+ true: ({iconPart}) => ({
89
+ [iconPart]: {
90
+ borderWidth: px2rem(1),
91
+ borderStyle: 'solid',
92
+ borderColor: system.legacy.color.border.default,
93
+ },
94
+ }),
95
+ },
96
+ },
97
+ defaultModifiers: {
98
+ type: 'file',
99
+ },
100
+ });
101
+
102
+ const fileIcons: Record<AccessoryFileType, SystemIconProps['icon']> = {
103
+ pdf: pdfIcon,
104
+ spreadsheet: tableExpandIcon,
105
+ document: documentIcon,
106
+ presentation: stackIcon,
107
+ video: playCircleIcon,
108
+ file: documentIcon,
109
+ txt: txtIcon,
110
+ };
111
+
112
+ /**
113
+ * `AccessoryFile` renders a file-type tile. `type` chooses the glyph and sets the fill and icon
114
+ * color. Colored types keep their fill at every size. Generic file and text use `surface.alt` and
115
+ * a `border.default` stroke. Always decorative.
116
+ */
117
+ export const AccessoryFile = createComponent('span')({
118
+ displayName: 'AccessoryFile',
119
+ Component: (
120
+ {type = 'file', size = 'extraLarge', color, background, ...elemProps}: AccessoryFileProps,
121
+ ref,
122
+ Element
123
+ ) => {
124
+ return (
125
+ <Accessory
126
+ as={Element}
127
+ ref={ref}
128
+ background={background}
129
+ color={color}
130
+ size={size}
131
+ {...handleCsProp(
132
+ elemProps,
133
+ accessoryFileStencil({type, outline: type === 'file' || type === 'txt'})
134
+ )}
135
+ >
136
+ <SystemIcon icon={fileIcons[type]} {...accessoryStencil.parts.icon} />
137
+ </Accessory>
138
+ );
139
+ },
140
+ });