@primer/components 0.0.0-202196214225 → 0.0.0-20219715822

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 (60) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/dist/browser.esm.js +721 -654
  3. package/dist/browser.esm.js.map +1 -1
  4. package/dist/browser.umd.js +411 -344
  5. package/dist/browser.umd.js.map +1 -1
  6. package/lib/FilteredActionList/FilteredActionList.d.ts +3 -2
  7. package/lib/FilteredActionList/FilteredActionList.js +3 -1
  8. package/lib/SelectMenu/SelectMenu.d.ts +7 -2
  9. package/lib/SelectPanel/SelectPanel.d.ts +1 -1
  10. package/lib/SelectPanel/SelectPanel.js +9 -11
  11. package/lib/TextInput.d.ts +5 -3
  12. package/lib/TextInput.js +8 -10
  13. package/lib/TextInputWithTokens.d.ts +326 -0
  14. package/lib/TextInputWithTokens.js +244 -0
  15. package/lib/Token/IssueLabelToken.d.ts +14 -0
  16. package/lib/Token/IssueLabelToken.js +144 -0
  17. package/lib/Token/ProfileToken.d.ts +7 -0
  18. package/lib/Token/ProfileToken.js +53 -0
  19. package/lib/Token/Token.d.ts +15 -0
  20. package/lib/Token/Token.js +94 -0
  21. package/lib/Token/TokenBase.d.ts +17 -0
  22. package/lib/Token/TokenBase.js +108 -0
  23. package/lib/Token/_RemoveTokenButton.d.ts +12 -0
  24. package/lib/Token/_RemoveTokenButton.js +77 -0
  25. package/lib/Token/_TokenTextContainer.d.ts +3 -0
  26. package/lib/Token/_TokenTextContainer.js +34 -0
  27. package/lib/Token/index.d.ts +3 -0
  28. package/lib/Token/index.js +31 -0
  29. package/lib/_UnstyledTextInput.d.ts +2 -0
  30. package/lib/_UnstyledTextInput.js +20 -0
  31. package/lib/index.d.ts +2 -0
  32. package/lib/index.js +28 -0
  33. package/lib-esm/FilteredActionList/FilteredActionList.d.ts +3 -2
  34. package/lib-esm/FilteredActionList/FilteredActionList.js +3 -1
  35. package/lib-esm/SelectMenu/SelectMenu.d.ts +7 -2
  36. package/lib-esm/SelectPanel/SelectPanel.d.ts +1 -1
  37. package/lib-esm/SelectPanel/SelectPanel.js +9 -8
  38. package/lib-esm/TextInput.d.ts +5 -3
  39. package/lib-esm/TextInput.js +7 -9
  40. package/lib-esm/TextInputWithTokens.d.ts +326 -0
  41. package/lib-esm/TextInputWithTokens.js +217 -0
  42. package/lib-esm/Token/IssueLabelToken.d.ts +14 -0
  43. package/lib-esm/Token/IssueLabelToken.js +124 -0
  44. package/lib-esm/Token/ProfileToken.d.ts +7 -0
  45. package/lib-esm/Token/ProfileToken.js +33 -0
  46. package/lib-esm/Token/Token.d.ts +15 -0
  47. package/lib-esm/Token/Token.js +73 -0
  48. package/lib-esm/Token/TokenBase.d.ts +17 -0
  49. package/lib-esm/Token/TokenBase.js +87 -0
  50. package/lib-esm/Token/_RemoveTokenButton.d.ts +12 -0
  51. package/lib-esm/Token/_RemoveTokenButton.js +60 -0
  52. package/lib-esm/Token/_TokenTextContainer.d.ts +3 -0
  53. package/lib-esm/Token/_TokenTextContainer.js +21 -0
  54. package/lib-esm/Token/index.d.ts +3 -0
  55. package/lib-esm/Token/index.js +3 -0
  56. package/lib-esm/_UnstyledTextInput.d.ts +2 -0
  57. package/lib-esm/_UnstyledTextInput.js +7 -0
  58. package/lib-esm/index.d.ts +2 -0
  59. package/lib-esm/index.js +2 -0
  60. package/package.json +2 -1
@@ -0,0 +1,124 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React, { forwardRef, useMemo } from 'react';
4
+ import TokenBase, { defaultTokenSize, isTokenInteractive } from './TokenBase';
5
+ import RemoveTokenButton from './_RemoveTokenButton';
6
+ import { parseToHsla, parseToRgba } from 'color2k';
7
+ import { useTheme } from '../ThemeProvider';
8
+ import TokenTextContainer from './_TokenTextContainer';
9
+ const tokenBorderWidthPx = 1;
10
+ const lightModeStyles = {
11
+ '--lightness-threshold': '0.453',
12
+ '--border-threshold': '0.96',
13
+ '--border-alpha': 'max(0, min(calc((var(--perceived-lightness) - var(--border-threshold)) * 100), 1))',
14
+ background: 'rgb(var(--label-r), var(--label-g), var(--label-b))',
15
+ color: 'hsl(0, 0%, calc(var(--lightness-switch) * 100%))',
16
+ borderWidth: tokenBorderWidthPx,
17
+ borderStyle: 'solid',
18
+ borderColor: 'hsla(var(--label-h),calc(var(--label-s) * 1%),calc((var(--label-l) - 25) * 1%),var(--border-alpha))'
19
+ };
20
+ const darkModeStyles = {
21
+ '--lightness-threshold': '0.6',
22
+ '--background-alpha': '0.18',
23
+ '--border-alpha': '0.3',
24
+ '--lighten-by': 'calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch))',
25
+ borderWidth: tokenBorderWidthPx,
26
+ borderStyle: 'solid',
27
+ background: 'rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha))',
28
+ color: 'hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%))',
29
+ borderColor: 'hsla(var(--label-h), calc(var(--label-s) * 1%),calc((var(--label-l) + var(--lighten-by)) * 1%),var(--border-alpha))'
30
+ };
31
+ const IssueLabelToken = /*#__PURE__*/forwardRef((props, forwardedRef) => {
32
+ const {
33
+ as,
34
+ fillColor = '#999',
35
+ onRemove,
36
+ id,
37
+ isSelected,
38
+ text,
39
+ size,
40
+ hideRemoveButton,
41
+ href,
42
+ onClick,
43
+ ...rest
44
+ } = props;
45
+ const interactiveTokenProps = {
46
+ as,
47
+ href,
48
+ onClick
49
+ };
50
+ const {
51
+ colorScheme
52
+ } = useTheme();
53
+ const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(onRemove) && !hideRemoveButton;
54
+
55
+ const onRemoveClick = e => {
56
+ e.stopPropagation();
57
+ onRemove && onRemove();
58
+ };
59
+
60
+ const labelStyles = useMemo(() => {
61
+ const [r, g, b] = parseToRgba(fillColor);
62
+ const [h, s, l] = parseToHsla(fillColor); // label hack taken from https://github.com/github/github/blob/master/app/assets/stylesheets/hacks/hx_primer-labels.scss#L43-L108
63
+ // this logic should eventually live in primer/components. Also worthy of note is that the dotcom hack code will be moving to primer/css soon.
64
+
65
+ return {
66
+ '--label-r': String(r),
67
+ '--label-g': String(g),
68
+ '--label-b': String(b),
69
+ '--label-h': String(Math.round(h)),
70
+ '--label-s': String(Math.round(s * 100)),
71
+ '--label-l': String(Math.round(l * 100)),
72
+ '--perceived-lightness': 'calc(((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255)',
73
+ '--lightness-switch': 'max(0, min(calc((var(--perceived-lightness) - var(--lightness-threshold)) * -1000), 1))',
74
+ paddingRight: hideRemoveButton || !onRemove ? undefined : 0,
75
+ position: 'relative',
76
+ ...(colorScheme === 'light' ? lightModeStyles : darkModeStyles),
77
+ ...(isSelected ? {
78
+ background: colorScheme === 'light' ? 'hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) - 5) * 1%))' : darkModeStyles.background,
79
+ ':focus': {
80
+ outline: 'none'
81
+ },
82
+ ':after': {
83
+ content: '""',
84
+ position: 'absolute',
85
+ zIndex: 1,
86
+ top: `-${tokenBorderWidthPx * 2}px`,
87
+ right: `-${tokenBorderWidthPx * 2}px`,
88
+ bottom: `-${tokenBorderWidthPx * 2}px`,
89
+ left: `-${tokenBorderWidthPx * 2}px`,
90
+ display: 'block',
91
+ pointerEvents: 'none',
92
+ boxShadow: `0 0 0 ${tokenBorderWidthPx * 2}px ${colorScheme === 'light' ? 'rgb(var(--label-r), var(--label-g), var(--label-b))' : 'hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%))'}`,
93
+ borderRadius: '999px'
94
+ }
95
+ } : {})
96
+ };
97
+ }, [colorScheme, fillColor, isSelected, hideRemoveButton, onRemove]);
98
+ return /*#__PURE__*/React.createElement(TokenBase, _extends({
99
+ onRemove: onRemove,
100
+ id: id === null || id === void 0 ? void 0 : id.toString(),
101
+ isSelected: isSelected,
102
+ text: text,
103
+ size: size,
104
+ sx: labelStyles
105
+ }, !hasMultipleActionTargets ? interactiveTokenProps : {}, rest, {
106
+ ref: forwardedRef
107
+ }), /*#__PURE__*/React.createElement(TokenTextContainer, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, {
108
+ borderOffset: tokenBorderWidthPx,
109
+ onClick: onRemoveClick,
110
+ size: size,
111
+ "aria-hidden": hasMultipleActionTargets ? 'true' : 'false',
112
+ isParentInteractive: isTokenInteractive(props),
113
+ sx: hasMultipleActionTargets ? {
114
+ position: 'relative',
115
+ zIndex: '1'
116
+ } : {}
117
+ }) : null);
118
+ });
119
+ IssueLabelToken.defaultProps = {
120
+ fillColor: '#999',
121
+ size: defaultTokenSize
122
+ };
123
+ IssueLabelToken.displayName = 'IssueLabelToken';
124
+ export default IssueLabelToken;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { TokenBaseProps } from './TokenBase';
3
+ export interface ProfileTokenProps extends TokenBaseProps {
4
+ avatarSrc: string;
5
+ }
6
+ declare const ProfileToken: React.ForwardRefExoticComponent<Pick<ProfileTokenProps, "sizes" | "color" | "content" | "height" | "translate" | "width" | "hidden" | "children" | "value" | "cite" | "data" | "form" | "label" | "slot" | "span" | "style" | "summary" | "title" | "pattern" | "text" | "list" | "default" | "type" | "name" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "start" | "step" | "size" | "wrap" | "open" | "max" | "media" | "method" | "min" | "target" | "crossOrigin" | "href" | "classID" | "useMap" | "wmode" | "download" | "hrefLang" | "rel" | "alt" | "coords" | "shape" | "autoPlay" | "controls" | "loop" | "mediaGroup" | "muted" | "playsInline" | "preload" | "src" | "autoFocus" | "disabled" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "dateTime" | "acceptCharset" | "action" | "autoComplete" | "encType" | "noValidate" | "manifest" | "allowFullScreen" | "allowTransparency" | "frameBorder" | "marginHeight" | "marginWidth" | "sandbox" | "scrolling" | "seamless" | "srcDoc" | "srcSet" | "async" | "accept" | "capture" | "checked" | "maxLength" | "minLength" | "multiple" | "readOnly" | "required" | "challenge" | "keyType" | "keyParams" | "htmlFor" | "as" | "integrity" | "charSet" | "httpEquiv" | "high" | "low" | "optimum" | "reversed" | "selected" | "defer" | "nonce" | "scoped" | "cellPadding" | "cellSpacing" | "colSpan" | "headers" | "rowSpan" | "scope" | "cols" | "rows" | "kind" | "srcLang" | "poster" | "onRemove" | "isSelected" | "avatarSrc"> & React.RefAttributes<HTMLElement>>;
7
+ export default ProfileToken;
@@ -0,0 +1,33 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React, { forwardRef } from 'react';
4
+ import primitives from '@primer/primitives';
5
+ import { get } from '../constants';
6
+ import { defaultTokenSize, tokenSizes } from './TokenBase';
7
+ import Token from './Token';
8
+ import { Avatar } from '..';
9
+ const ProfileToken = /*#__PURE__*/forwardRef(({
10
+ avatarSrc,
11
+ id,
12
+ size,
13
+ ...rest
14
+ }, forwardedRef) => {
15
+ return /*#__PURE__*/React.createElement(Token, _extends({
16
+ leadingVisual: () => /*#__PURE__*/React.createElement(Avatar, {
17
+ src: avatarSrc,
18
+ size: parseInt(tokenSizes[size || defaultTokenSize], 10) - parseInt(primitives.spacing.normal.spacer[1], 10) * 2
19
+ }),
20
+ size: size,
21
+ id: id === null || id === void 0 ? void 0 : id.toString(),
22
+ sx: {
23
+ paddingLeft: get('space.1')
24
+ }
25
+ }, rest, {
26
+ ref: forwardedRef
27
+ }));
28
+ });
29
+ ProfileToken.defaultProps = {
30
+ size: defaultTokenSize
31
+ };
32
+ ProfileToken.displayName = 'ProfileToken';
33
+ export default ProfileToken;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { SxProp } from '../sx';
3
+ import { TokenBaseProps } from './TokenBase';
4
+ export interface TokenProps extends TokenBaseProps {
5
+ /**
6
+ * A function that renders a component before the token text
7
+ */
8
+ leadingVisual?: React.ComponentType<any>;
9
+ /**
10
+ * Whether the remove button should be rendered in the token
11
+ */
12
+ hideRemoveButton?: boolean;
13
+ }
14
+ declare const Token: React.ForwardRefExoticComponent<Pick<TokenProps & SxProp, "sizes" | "color" | "content" | "height" | "translate" | "width" | "hidden" | "children" | "value" | "cite" | "data" | "form" | "label" | "slot" | "span" | "style" | "summary" | "title" | "pattern" | "text" | "list" | "default" | "type" | "name" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "start" | "step" | "size" | "wrap" | "open" | "sx" | "max" | "media" | "method" | "min" | "target" | "crossOrigin" | "href" | "classID" | "useMap" | "wmode" | "download" | "hrefLang" | "rel" | "alt" | "coords" | "shape" | "autoPlay" | "controls" | "loop" | "mediaGroup" | "muted" | "playsInline" | "preload" | "src" | "autoFocus" | "disabled" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "dateTime" | "acceptCharset" | "action" | "autoComplete" | "encType" | "noValidate" | "manifest" | "allowFullScreen" | "allowTransparency" | "frameBorder" | "marginHeight" | "marginWidth" | "sandbox" | "scrolling" | "seamless" | "srcDoc" | "srcSet" | "async" | "accept" | "capture" | "checked" | "maxLength" | "minLength" | "multiple" | "readOnly" | "required" | "challenge" | "keyType" | "keyParams" | "htmlFor" | "as" | "integrity" | "charSet" | "httpEquiv" | "high" | "low" | "optimum" | "reversed" | "selected" | "defer" | "nonce" | "scoped" | "cellPadding" | "cellSpacing" | "colSpan" | "headers" | "rowSpan" | "scope" | "cols" | "rows" | "kind" | "srcLang" | "poster" | "leadingVisual" | "onRemove" | "isSelected" | "hideRemoveButton"> & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | HTMLSpanElement>>;
15
+ export default Token;
@@ -0,0 +1,73 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React, { forwardRef } from 'react';
4
+ import styled, { css } from 'styled-components';
5
+ import { get } from '../constants';
6
+ import sx from '../sx';
7
+ import TokenBase, { defaultTokenSize, isTokenInteractive } from './TokenBase';
8
+ import RemoveTokenButton from './_RemoveTokenButton';
9
+ import TokenTextContainer from './_TokenTextContainer';
10
+ const tokenBorderWidthPx = 1;
11
+ const DefaultTokenStyled = styled(TokenBase).withConfig({
12
+ displayName: "Token__DefaultTokenStyled",
13
+ componentId: "sc-1dg52pw-0"
14
+ })(["background-color:", ";border-color:", ";border-style:solid;border-width:", "px;color:", ";max-width:100%;padding-right:", ";position:relative;", " ", ""], get('colors.neutral.subtle'), props => props.isSelected ? get('colors.fg.default') : get('colors.border.subtle'), tokenBorderWidthPx, props => props.isSelected ? get('colors.fg.default') : get('colors.fg.muted'), props => !props.hideRemoveButton ? 0 : undefined, sx, props => {
15
+ if (props.isTokenInteractive) {
16
+ return css(["&:hover{background-color:", ";box-shadow:", ";color:", ";}"], get('colors.neutral.muted'), get('colors.shadow.medium'), get('colors.fg.default'));
17
+ }
18
+ });
19
+ const LeadingVisualContainer = styled('span').withConfig({
20
+ displayName: "Token__LeadingVisualContainer",
21
+ componentId: "sc-1dg52pw-1"
22
+ })(["flex-shrink:0;line-height:0;"]);
23
+ const Token = /*#__PURE__*/forwardRef((props, forwardedRef) => {
24
+ const {
25
+ as,
26
+ onRemove,
27
+ id,
28
+ leadingVisual: LeadingVisual,
29
+ text,
30
+ size,
31
+ hideRemoveButton,
32
+ href,
33
+ onClick,
34
+ ...rest
35
+ } = props;
36
+ const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(onRemove) && !hideRemoveButton;
37
+
38
+ const onRemoveClick = e => {
39
+ e.stopPropagation();
40
+ onRemove && onRemove();
41
+ };
42
+
43
+ const interactiveTokenProps = {
44
+ as,
45
+ href,
46
+ onClick
47
+ };
48
+ return /*#__PURE__*/React.createElement(DefaultTokenStyled, _extends({
49
+ onRemove: onRemove,
50
+ hideRemoveButton: hideRemoveButton || !onRemove,
51
+ id: id === null || id === void 0 ? void 0 : id.toString(),
52
+ text: text,
53
+ size: size,
54
+ isTokenInteractive: isTokenInteractive(props)
55
+ }, !hasMultipleActionTargets ? interactiveTokenProps : {}, rest, {
56
+ ref: forwardedRef
57
+ }), LeadingVisual ? /*#__PURE__*/React.createElement(LeadingVisualContainer, null, /*#__PURE__*/React.createElement(LeadingVisual, null)) : null, /*#__PURE__*/React.createElement(TokenTextContainer, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, {
58
+ borderOffset: tokenBorderWidthPx,
59
+ onClick: onRemoveClick,
60
+ size: size,
61
+ isParentInteractive: isTokenInteractive(props),
62
+ "aria-hidden": hasMultipleActionTargets ? 'true' : 'false',
63
+ sx: hasMultipleActionTargets ? {
64
+ position: 'relative',
65
+ zIndex: '1'
66
+ } : {}
67
+ }) : null);
68
+ });
69
+ Token.displayName = 'Token';
70
+ Token.defaultProps = {
71
+ size: defaultTokenSize
72
+ };
73
+ export default Token;
@@ -0,0 +1,17 @@
1
+ /// <reference types="react" />
2
+ import { SxProp } from '../sx';
3
+ export declare type TokenSizeKeys = 'small' | 'medium' | 'large' | 'xlarge';
4
+ export declare const tokenSizes: Record<TokenSizeKeys, string>;
5
+ export declare const defaultTokenSize: TokenSizeKeys;
6
+ export interface TokenBaseProps extends Omit<React.HTMLProps<HTMLSpanElement | HTMLButtonElement | HTMLAnchorElement>, 'size' | 'id'> {
7
+ as?: 'button' | 'a' | 'span';
8
+ onRemove?: () => void;
9
+ isSelected?: boolean;
10
+ tabIndex?: number;
11
+ text: string;
12
+ id?: number | string;
13
+ size?: TokenSizeKeys;
14
+ }
15
+ export declare const isTokenInteractive: ({ as, onClick, onFocus, tabIndex }: TokenBaseProps) => boolean;
16
+ declare const TokenBase: import("styled-components").StyledComponent<"span", any, TokenBaseProps & SxProp, never>;
17
+ export default TokenBase;
@@ -0,0 +1,87 @@
1
+ import styled from 'styled-components';
2
+ import { variant } from 'styled-system';
3
+ import { get } from '../constants';
4
+ import sx from '../sx';
5
+ export const tokenSizes = {
6
+ small: '16px',
7
+ medium: '20px',
8
+ large: '24px',
9
+ xlarge: '32px'
10
+ };
11
+ export const defaultTokenSize = 'medium';
12
+ export const isTokenInteractive = ({
13
+ as = 'span',
14
+ onClick,
15
+ onFocus,
16
+ tabIndex = -1
17
+ }) => Boolean(onFocus || onClick || tabIndex > -1 || ['a', 'button'].includes(as));
18
+ const variants = variant({
19
+ prop: 'size',
20
+ variants: {
21
+ small: {
22
+ fontSize: 0,
23
+ gap: 1,
24
+ height: tokenSizes.small,
25
+ // without setting lineHeight to match height, the "x" appears vertically mis-aligned
26
+ lineHeight: tokenSizes.small,
27
+ paddingLeft: 1,
28
+ paddingRight: 1,
29
+ // need to explicitly set padding top and bottom to "0" to override default `<button>` element styles
30
+ // without setting these, the "x" appears vertically mis-aligned
31
+ paddingTop: 0,
32
+ paddingBottom: 0
33
+ },
34
+ medium: {
35
+ fontSize: 0,
36
+ gap: 1,
37
+ height: tokenSizes.medium,
38
+ lineHeight: tokenSizes.medium,
39
+ paddingLeft: 2,
40
+ paddingRight: 2,
41
+ paddingTop: 0,
42
+ paddingBottom: 0
43
+ },
44
+ large: {
45
+ fontSize: 0,
46
+ gap: 2,
47
+ height: tokenSizes.large,
48
+ lineHeight: tokenSizes.large,
49
+ paddingLeft: 2,
50
+ paddingRight: 2,
51
+ paddingTop: 0,
52
+ paddingBottom: 0
53
+ },
54
+ xlarge: {
55
+ fontSize: 1,
56
+ gap: 2,
57
+ height: tokenSizes.xlarge,
58
+ lineHeight: tokenSizes.xlarge,
59
+ paddingLeft: 3,
60
+ paddingRight: 3,
61
+ paddingTop: 0,
62
+ paddingBottom: 0
63
+ }
64
+ }
65
+ });
66
+ const TokenBase = styled.span.attrs(({
67
+ text,
68
+ onRemove,
69
+ onKeyDown
70
+ }) => ({
71
+ onKeyDown: event => {
72
+ onKeyDown && onKeyDown(event);
73
+
74
+ if ((event.key === 'Backspace' || event.key === 'Delete') && onRemove) {
75
+ onRemove();
76
+ }
77
+ },
78
+ 'aria-label': onRemove ? `${text}, press backspace or delete to remove` : undefined
79
+ })).withConfig({
80
+ displayName: "TokenBase",
81
+ componentId: "opajvp-0"
82
+ })(["align-items:center;border-radius:999px;cursor:", ";display:inline-flex;font-weight:", ";text-decoration:none;white-space:nowrap;", " ", ""], props => isTokenInteractive(props) ? 'pointer' : 'auto', get('fontWeights.bold'), variants, sx);
83
+ TokenBase.defaultProps = {
84
+ as: 'span',
85
+ size: defaultTokenSize
86
+ };
87
+ export default TokenBase;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { SxProp } from '../sx';
3
+ import { ComponentProps } from '../utils/types';
4
+ import { TokenSizeKeys } from './TokenBase';
5
+ interface TokenButtonProps {
6
+ borderOffset?: number;
7
+ size?: TokenSizeKeys;
8
+ isParentInteractive?: boolean;
9
+ }
10
+ declare const StyledTokenButton: import("styled-components").StyledComponent<"span", any, TokenButtonProps & SxProp, never>;
11
+ declare const RemoveTokenButton: React.FC<ComponentProps<typeof StyledTokenButton>>;
12
+ export default RemoveTokenButton;
@@ -0,0 +1,60 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React from 'react';
4
+ import { XIcon } from '@primer/octicons-react';
5
+ import styled from 'styled-components';
6
+ import { variant } from 'styled-system';
7
+ import { get } from '../constants';
8
+ import sx from '../sx';
9
+ import { tokenSizes, defaultTokenSize } from './TokenBase';
10
+ const variants = variant({
11
+ prop: 'size',
12
+ variants: {
13
+ small: {
14
+ height: tokenSizes.small,
15
+ width: tokenSizes.small
16
+ },
17
+ medium: {
18
+ height: tokenSizes.medium,
19
+ width: tokenSizes.medium
20
+ },
21
+ large: {
22
+ height: tokenSizes.large,
23
+ width: tokenSizes.large
24
+ },
25
+ xlarge: {
26
+ height: tokenSizes.xlarge,
27
+ width: tokenSizes.xlarge
28
+ }
29
+ }
30
+ });
31
+
32
+ const getTokenButtonIconSize = size => parseInt(tokenSizes[size || defaultTokenSize], 10) * 0.75;
33
+
34
+ const StyledTokenButton = styled.span.withConfig({
35
+ displayName: "_RemoveTokenButton__StyledTokenButton",
36
+ componentId: "sc-14lvcw1-0"
37
+ })(["background-color:transparent;font-family:inherit;color:currentColor;cursor:pointer;display:inline-flex;justify-content:center;align-items:center;user-select:none;appearance:none;text-decoration:none;padding:0;transform:", ";align-self:baseline;border:0;border-radius:999px;&:hover,&:focus{background-color:", ";}&:active{background-color:", ";}", " ", ""], props => `translate(${props.borderOffset}px, -${props.borderOffset}px)`, get('colors.fade.fg10'), get('colors.fade.fg15'), variants, sx);
38
+
39
+ const RemoveTokenButton = ({
40
+ 'aria-label': ariaLabel,
41
+ isParentInteractive,
42
+ size,
43
+ ...rest
44
+ }) => {
45
+ delete rest.children;
46
+ return /*#__PURE__*/React.createElement(StyledTokenButton, _extends({
47
+ as: isParentInteractive ? 'span' : 'button',
48
+ tabIndex: isParentInteractive ? -1 : undefined,
49
+ "aria-label": !isParentInteractive ? 'Remove token' : ariaLabel,
50
+ size: size
51
+ }, rest), /*#__PURE__*/React.createElement(XIcon, {
52
+ size: getTokenButtonIconSize(size)
53
+ }));
54
+ };
55
+
56
+ RemoveTokenButton.displayName = "RemoveTokenButton";
57
+ RemoveTokenButton.defaultProps = {
58
+ size: defaultTokenSize
59
+ };
60
+ export default RemoveTokenButton;
@@ -0,0 +1,3 @@
1
+ import { TokenBaseProps } from './TokenBase';
2
+ declare const TokenTextContainer: import("styled-components").StyledComponent<"span", any, Partial<TokenBaseProps>, never>;
3
+ export default TokenTextContainer;
@@ -0,0 +1,21 @@
1
+ import styled, { css } from 'styled-components';
2
+ const TokenTextContainer = styled('span').withConfig({
3
+ displayName: "_TokenTextContainer__TokenTextContainer",
4
+ componentId: "sc-4t2bev-0"
5
+ })(["flex-grow:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;", ""], props => {
6
+ if (props.as === 'a') {
7
+ return css(["color:currentColor;text-decoration:none;"]);
8
+ }
9
+
10
+ if (props.as === 'button') {
11
+ // reset button styles, make the cursor a pointer, and add line-height
12
+ return css(["background:transparent;border:none;color:inherit;font:inherit;margin:0;overflow:visible;padding:0;width:auto;-webkit-font-smoothing:inherit;-moz-osx-font-smoothing:inherit;-webkit-appearance:none;cursor:pointer;line-height:1;"]);
13
+ } // position psuedo-element above text content
14
+ // so it gets the click
15
+
16
+
17
+ if (props.as !== 'span') {
18
+ return css(["&:after{content:'';position:absolute;left:0;top:0;right:0;bottom:0;}"]);
19
+ }
20
+ });
21
+ export default TokenTextContainer;
@@ -0,0 +1,3 @@
1
+ export { default } from './Token';
2
+ export { default as IssueLabelToken } from './IssueLabelToken';
3
+ export { default as ProfileToken } from './ProfileToken';
@@ -0,0 +1,3 @@
1
+ export { default } from './Token';
2
+ export { default as IssueLabelToken } from './IssueLabelToken';
3
+ export { default as ProfileToken } from './ProfileToken';
@@ -0,0 +1,2 @@
1
+ declare const UnstyledTextInput: import("styled-components").StyledComponent<"input", any, import("./sx").SxProp, never>;
2
+ export default UnstyledTextInput;
@@ -0,0 +1,7 @@
1
+ import styled from 'styled-components';
2
+ import sx from './sx';
3
+ const UnstyledTextInput = styled.input.withConfig({
4
+ displayName: "_UnstyledTextInput__UnstyledTextInput",
5
+ componentId: "sc-1jgl33s-0"
6
+ })(["border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;&:focus{outline:0;}", ";"], sx);
7
+ export default UnstyledTextInput;
@@ -98,10 +98,12 @@ export { default as TabNav } from './TabNav';
98
98
  export type { TabNavProps, TabNavLinkProps } from './TabNav';
99
99
  export { default as TextInput } from './TextInput';
100
100
  export type { TextInputProps } from './TextInput';
101
+ export { default as TextInputWithTokens } from './TextInputWithTokens';
101
102
  export { default as Text } from './Text';
102
103
  export type { TextProps } from './Text';
103
104
  export { default as Timeline } from './Timeline';
104
105
  export type { TimelineProps, TimelineBadgeProps, TimelineBodyProps, TimelineBreakProps, TimelineItemsProps } from './Timeline';
106
+ export { default as Token, IssueLabelToken, ProfileToken } from './Token';
105
107
  export { default as Tooltip } from './Tooltip';
106
108
  export type { TooltipProps } from './Tooltip';
107
109
  export { default as Truncate } from './Truncate';
package/lib-esm/index.js CHANGED
@@ -61,8 +61,10 @@ export { default as StyledOcticon } from './StyledOcticon';
61
61
  export { default as SubNav } from './SubNav';
62
62
  export { default as TabNav } from './TabNav';
63
63
  export { default as TextInput } from './TextInput';
64
+ export { default as TextInputWithTokens } from './TextInputWithTokens';
64
65
  export { default as Text } from './Text';
65
66
  export { default as Timeline } from './Timeline';
67
+ export { default as Token, IssueLabelToken, ProfileToken } from './Token';
66
68
  export { default as Tooltip } from './Tooltip';
67
69
  export { default as Truncate } from './Truncate';
68
70
  export { default as UnderlineNav } from './UnderlineNav';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/components",
3
- "version": "0.0.0-202196214225",
3
+ "version": "0.0.0-20219715822",
4
4
  "description": "Primer react components",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",
@@ -56,6 +56,7 @@
56
56
  "@types/styled-system__css": "5.0.16",
57
57
  "@types/styled-system__theme-get": "5.0.1",
58
58
  "classnames": "2.3.1",
59
+ "color2k": "1.2.4",
59
60
  "deepmerge": "4.2.2",
60
61
  "focus-visible": "5.2.0",
61
62
  "styled-system": "5.1.5"