@spectrum-css/button
Advanced tools
Comparing version 14.0.0-next.3 to 14.0.0-next.4
{ | ||
"name": "@spectrum-css/button", | ||
"version": "14.0.0-next.3", | ||
"version": "14.0.0-next.4", | ||
"description": "The Spectrum CSS button component", | ||
@@ -16,7 +16,7 @@ "license": "Apache-2.0", | ||
}, | ||
"main": "dist/index-vars.css", | ||
"main": "dist/index.css", | ||
"peerDependencies": { | ||
"@spectrum-css/icon": ">=6", | ||
"@spectrum-css/progresscircle": ">=2", | ||
"@spectrum-css/tokens": ">=13" | ||
"@spectrum-css/tokens": "^14.0.0-next.3" | ||
}, | ||
@@ -32,4 +32,3 @@ "peerDependenciesMeta": { | ||
"devDependencies": { | ||
"@spectrum-css/commons": "^9.1.4-next.0", | ||
"@spectrum-css/component-builder-simple": "^5.0.6-next.1" | ||
"@spectrum-css/commons": "^9.1.4-next.1" | ||
}, | ||
@@ -39,3 +38,3 @@ "publishConfig": { | ||
}, | ||
"gitHead": "2216cf58a18fb79d0cb987c485f7c4c177b7925f" | ||
"gitHead": "35c5f608be3785b57e7cdfd982378fff080accc2" | ||
} |
@@ -9,9 +9,9 @@ { | ||
"compare": {}, | ||
"format": {}, | ||
"lint": {}, | ||
"validate": {}, | ||
"test": { | ||
"defaultConfiguration": "scope" | ||
} | ||
}, | ||
"validate": {} | ||
} | ||
} |
import { html } from "lit"; | ||
import { ifDefined } from "lit/directives/if-defined.js"; | ||
import { styleMap } from "lit/directives/style-map.js"; | ||
@@ -9,8 +8,10 @@ import { when } from "lit/directives/when.js"; | ||
import { Template as Typography } from "@spectrum-css/typography/stories/template.js"; | ||
import { Template } from "./template"; | ||
/** | ||
* Buttons allow users to perform an action or to navigate to another page. They have multiple styles for various needs, and are ideal for calling attention to where a user needs to do something in order to move forward in a flow. | ||
*/ | ||
export default { | ||
title: "Components/Button", | ||
description: | ||
"Buttons allow users to perform an action or to navigate to another page. They have multiple styles for various needs, and are ideal for calling attention to where a user needs to do something in order to move forward in a flow.", | ||
component: "Button", | ||
@@ -76,16 +77,38 @@ decorators: [withDownStateDimensionCapture('.spectrum-Button:not(:disabled)')], | ||
}, | ||
isPending: { | ||
name: "Pending", | ||
isHovered: { | ||
name: "Hovered", | ||
type: { name: "boolean" }, | ||
table: { | ||
disable: true | ||
type: { summary: "boolean" }, | ||
category: "State", | ||
}, | ||
control: "boolean", | ||
}, | ||
isPendingStory: { | ||
name: "Pending story", | ||
isFocused: { | ||
name: "Focused", | ||
type: { name: "boolean" }, | ||
table: { | ||
disable: true, | ||
type: { summary: "boolean" }, | ||
category: "State", | ||
}, | ||
control: "boolean", | ||
}, | ||
isActive: { | ||
name: "Active", | ||
type: { name: "boolean" }, | ||
table: { | ||
type: { summary: "boolean" }, | ||
category: "State", | ||
}, | ||
control: "boolean", | ||
}, | ||
isPending: { | ||
name: "Pending", | ||
type: { name: "boolean" }, | ||
table: { | ||
type: { summary: "boolean" }, | ||
category: "State", | ||
}, | ||
control: "boolean", | ||
}, | ||
staticColor: { | ||
@@ -102,20 +125,3 @@ name: "Static color", | ||
control: "select", | ||
if: { arg: "isPendingStory", truthy: false }, | ||
}, | ||
showIconOnlyButton: { | ||
table: { | ||
disable: true, | ||
}, | ||
}, | ||
layout: { | ||
name: "Layout", | ||
description: "How the buttons align in the preview (Storybook only).", | ||
type: { name: "string" }, | ||
table: { | ||
type: { summary: "string" }, | ||
category: "Advanced" | ||
}, | ||
options: ["stacked","inline"], | ||
control: "radio" | ||
}, | ||
}, | ||
@@ -126,8 +132,9 @@ args: { | ||
label: "Edit", | ||
treatment: "fill", | ||
variant: "accent", | ||
treatment: "fill", | ||
isDisabled: false, | ||
isPending: false, | ||
showIconOnlyButton: true, | ||
layout: "inline", | ||
isActive: false, | ||
isFocused: false, | ||
isHovered: false, | ||
}, | ||
@@ -139,22 +146,36 @@ parameters: { | ||
status: { | ||
type: process.env.MIGRATED_PACKAGES.includes("button") | ||
? "migrated" | ||
: undefined, | ||
type: "migrated", | ||
}, | ||
html: { | ||
root: "#render-root" | ||
} | ||
}, | ||
decorators: [ | ||
(Story, context) => html` | ||
<style> | ||
.spectrum-Detail { display: inline-block; } | ||
.spectrum-Typography > div { | ||
border: 1px solid var(--spectrum-gray-200); | ||
border-radius: 4px; | ||
padding: 0 10px 10px; | ||
/* Why seafoam? Because it separates it from the component styles. */ | ||
--mod-detail-font-color: var(--spectrum-seafoam-900); | ||
} | ||
</style> | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
alignItems: "flex-start", | ||
gap: "10px", | ||
"--mod-detail-margin-end": "6px", | ||
})} | ||
> | ||
${Story(context)} | ||
</div> | ||
`, | ||
], | ||
}; | ||
/** | ||
* Optional wrapper for each button used within other templates, to assist with the "stacked" | ||
* layout and the testing of wrapping text. | ||
*/ | ||
const ButtonWrap = (layout, content) => { | ||
const buttonWrapStyles = { | ||
'margin-block': '15px', | ||
'max-width': '480px', | ||
}; | ||
return layout === "stacked" ? html`<div style=${styleMap(buttonWrapStyles)}>${content}</div>` : content; | ||
}; | ||
/** | ||
* Multiple button variations displayed in one story template. | ||
@@ -165,90 +186,70 @@ * Used as the base template for the stories. | ||
iconName, | ||
staticColor, | ||
layout, | ||
showIconOnlyButton, | ||
customStyles = {}, | ||
...args | ||
}) => { | ||
return html` | ||
<div | ||
style=${ifDefined(styleMap({ | ||
padding: "1rem", | ||
backgroundColor: staticColor === "white" ? "rgb(15, 121, 125)" : staticColor === "black" ? "rgb(181, 209, 211)" : undefined, | ||
...customStyles | ||
}))} | ||
> | ||
${ButtonWrap(layout, Template({ | ||
}) => html` | ||
${Template({ | ||
...args, | ||
iconName: undefined, | ||
})} | ||
${Template({ | ||
...args, | ||
iconName: iconName ?? "Edit", | ||
})} | ||
${Template({ | ||
...args, | ||
hideLabel: true, | ||
iconName: iconName ?? "Edit", | ||
})} | ||
`; | ||
const States = (args) => | ||
html` <div> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Default"], | ||
})} | ||
${Treatment(args)} | ||
</div> | ||
<div> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Selected"], | ||
})} | ||
${Treatment({ | ||
...args, | ||
staticColor, | ||
iconName: undefined, | ||
}))} | ||
${ButtonWrap(layout, Template({ | ||
isSelected: true, | ||
})} | ||
</div> | ||
<div> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Focused"], | ||
})} | ||
${Treatment({ | ||
...args, | ||
staticColor, | ||
iconName: undefined, | ||
treatment: "outline", | ||
}))} | ||
${ButtonWrap(layout, Template({ | ||
...args, | ||
staticColor, | ||
iconName: iconName ?? "Edit", | ||
}))} | ||
${when(showIconOnlyButton, () => | ||
ButtonWrap(layout, Template({ | ||
...args, | ||
staticColor, | ||
hideLabel: true, | ||
iconName: iconName ?? "Edit", | ||
})) | ||
)} | ||
isFocused: true, | ||
})} | ||
</div> | ||
`; | ||
}; | ||
const PendingButton = ({ | ||
staticColor, | ||
customStyles = {}, | ||
layout, | ||
...args | ||
}) => html` | ||
${when(!window.isChromatic(), () => | ||
Typography({ | ||
semantics: "heading", | ||
size: "xs", | ||
content: ["Press any button to show the pending state on all buttons. Press again to remove the pending states."], | ||
}) | ||
)} | ||
<div style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: ".3rem", | ||
marginTop: "1rem" | ||
})}> | ||
<div> | ||
${Typography({ | ||
semantics: "heading", | ||
size: "xxs", | ||
content: ["Default"], | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Hovered"], | ||
})} | ||
${CustomButton({ | ||
${Treatment({ | ||
...args, | ||
isHovered: true, | ||
})} | ||
${ButtonWrap(layout = "stacked", Template({ | ||
</div> | ||
<div> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Active"], | ||
})} | ||
${Treatment({ | ||
...args, | ||
staticColor, | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
}))} | ||
${when(window.isChromatic(), () => { | ||
return html` | ||
${CustomButton({ | ||
...args, | ||
isPending: true, | ||
})} | ||
${ButtonWrap(layout = "stacked", Template({ | ||
...args, | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
isPending: true, | ||
}))} | ||
`; | ||
isActive: true, | ||
})} | ||
@@ -258,68 +259,21 @@ </div> | ||
${Typography({ | ||
semantics: "heading", | ||
size: "xxs", | ||
content: ["Static White"], | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Disabled"], | ||
})} | ||
${CustomButton({ | ||
${Treatment({ | ||
...args, | ||
staticColor: "white", | ||
isDisabled: true, | ||
})} | ||
<div | ||
style=${ifDefined(styleMap({ | ||
padding: "1rem", | ||
backgroundColor: "rgb(15, 121, 125)", | ||
...customStyles | ||
}))} | ||
> | ||
${ButtonWrap(layout = "stacked", Template({ | ||
...args, | ||
staticColor: "white", | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
}))} | ||
</div> | ||
${when(window.isChromatic(), () => { | ||
return html` | ||
${CustomButton({ | ||
...args, | ||
staticColor: "white", | ||
isPending: true, | ||
})} | ||
<div | ||
style=${ifDefined(styleMap({ | ||
padding: "1rem", | ||
backgroundColor: "rgb(15, 121, 125)", | ||
...customStyles | ||
}))} | ||
> | ||
${ButtonWrap(layout = "stacked", Template({ | ||
...args, | ||
staticColor: "white", | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
isPending: true, | ||
}))} | ||
</div> | ||
`; | ||
})} | ||
</div> | ||
</div> | ||
`; | ||
const ButtonsWithForcedColors = ({ | ||
customStyles = {}, | ||
...args | ||
}) => html` | ||
<div style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: ".3rem", | ||
})}> | ||
<div> | ||
${Typography({ | ||
semantics: "heading", | ||
size: "xxs", | ||
content: ["Default"], | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Disabled + selected"], | ||
})} | ||
${CustomButton({ | ||
${Treatment({ | ||
...args, | ||
variant: "accent" | ||
isSelected: true, | ||
isDisabled: true, | ||
})} | ||
@@ -329,68 +283,195 @@ </div> | ||
${Typography({ | ||
semantics: "heading", | ||
size: "xxs", | ||
content: ["Pending State"], | ||
semantics: "detail", | ||
size: "s", | ||
content: ["Pending"], | ||
})} | ||
${CustomButton({ | ||
${Treatment({ | ||
...args, | ||
isDisabled: true, | ||
isPending: true, | ||
})} | ||
</div> | ||
</div> | ||
`; | ||
</div>`; | ||
/** | ||
* Wrapping story template, displaying some additional variants for Chromatic. | ||
*/ | ||
const WrappingTemplate = ({layout, ...args}) => { | ||
if (window.isChromatic()) { | ||
return html` | ||
${CustomButton({layout, ...args})} | ||
<div style=${ifDefined(styleMap({ padding: "1rem" }))}> | ||
${ButtonWrap(layout, Template({ | ||
...args, | ||
iconName: "Edit", | ||
treatment: "outline", | ||
}))} | ||
${ButtonWrap(layout, Template({ | ||
...args, | ||
// Uses a UI icon that is smaller than workflow sizing, to test alignment: | ||
iconName: "Cross100", | ||
}))} | ||
${ButtonWrap(layout, Template({ | ||
...args, | ||
// UI icon that is larger than workflow sizing: | ||
iconName: "ArrowDown600", | ||
treatment: "outline", | ||
}))} | ||
</div> | ||
`; | ||
} | ||
// Otherwise use the default template. | ||
return CustomButton({layout, ...args}); | ||
}; | ||
const Sizes = (args) => | ||
html` ${["s", "m", "l", "xl"].map((size) => { | ||
return html` <div> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "s", | ||
content: [ | ||
{ | ||
xxs: "Extra-extra-small", | ||
xs: "Extra-small", | ||
s: "Small", | ||
m: "Medium", | ||
l: "Large", | ||
xl: "Extra-large", | ||
xxl: "Extra-extra-large", | ||
}[size], | ||
], | ||
})} | ||
${Treatment({ ...args, size })} | ||
</div>`; | ||
})}`; | ||
export const Accent = CustomButton.bind({}); | ||
Accent.args = { | ||
variant: "accent", | ||
}; | ||
const Treatment = (args) => | ||
html` | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
gap: "10px", | ||
})} | ||
id="render-root" | ||
> | ||
${["fill", "outline"].map((treatment) => CustomButton({ ...args, treatment }))} | ||
</div>`; | ||
export const Negative = CustomButton.bind({}); | ||
Negative.args = { | ||
variant: "negative", | ||
iconName: "Delete", | ||
}; | ||
const Wrapping = (args) => html` | ||
${Template({ | ||
...args, | ||
customStyles: { | ||
"max-inline-size": "480px", | ||
}, | ||
iconName: "Edit", | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
})} | ||
${Template({ | ||
...args, | ||
customStyles: { | ||
"max-inline-size": "480px", | ||
}, | ||
// Uses a UI icon that is smaller than workflow sizing, to test alignment: | ||
iconName: "Cross100", | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
})} | ||
${Template({ | ||
...args, | ||
customStyles: { | ||
"max-inline-size": "480px", | ||
}, | ||
// UI icon that is larger than workflow sizing: | ||
iconName: "ArrowDown600", | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
})}`; | ||
export const Primary = CustomButton.bind({}); | ||
Primary.args = { | ||
variant: "primary", | ||
}; | ||
const Variants = (args) => | ||
html` ${window.isChromatic() | ||
? html` <div class="spectrum-Typography"> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "l", | ||
content: ["Accent"], | ||
})} | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: "10px", | ||
})} | ||
> | ||
${States(args)} | ||
</div> | ||
</div> | ||
<div class="spectrum-Typography"> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "l", | ||
content: ["Negative"], | ||
})} | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: "10px", | ||
})} | ||
> | ||
${States({ | ||
...args, | ||
variant: "negative" | ||
})} | ||
</div> | ||
</div> | ||
<div class="spectrum-Typography"> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "l", | ||
content: ["Primary"], | ||
})} | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: "10px", | ||
})} | ||
> | ||
${States({ | ||
...args, | ||
variant: "primary" | ||
})} | ||
</div> | ||
</div> | ||
<div class="spectrum-Typography"> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "l", | ||
content: ["Secondary"], | ||
})} | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: "10px", | ||
})} | ||
> | ||
${States({ | ||
...args, | ||
variant: "secondary" | ||
})} | ||
</div> | ||
</div> | ||
<div class="spectrum-Typography"> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "l", | ||
content: ["Sizing"], | ||
})} | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: "10px", | ||
})} | ||
> | ||
${Sizes(args)} | ||
</div> | ||
</div> | ||
<div class="spectrum-Typography"> | ||
${Typography({ | ||
semantics: "detail", | ||
size: "l", | ||
content: ["Wrapping"], | ||
})} | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
flexDirection: "column", | ||
gap: "10px", | ||
padding: "6px" | ||
})} | ||
> | ||
${Wrapping(args)} | ||
</div> | ||
</div> | ||
` : html` | ||
<div | ||
style=${styleMap({ | ||
display: "flex", | ||
gap: "10px", | ||
})} | ||
id="render-root" | ||
>${CustomButton(args)}</div>`}`; | ||
export const Secondary = CustomButton.bind({}); | ||
Secondary.args = { | ||
variant: "secondary", | ||
}; | ||
export const Default = Variants.bind({}); | ||
Default.args = {}; | ||
export const StaticColorWhite = CustomButton.bind({}); | ||
export const StaticColorWhite = Variants.bind({}); | ||
StaticColorWhite.args = { | ||
@@ -400,3 +481,3 @@ staticColor: "white", | ||
export const StaticColorBlack = CustomButton.bind({}); | ||
export const StaticColorBlack = Variants.bind({}); | ||
StaticColorBlack.args = { | ||
@@ -406,16 +487,5 @@ staticColor: "black", | ||
export const Disabled = CustomButton.bind({}); | ||
Disabled.args = { | ||
isDisabled: true, | ||
iconName: "Actions", | ||
}; | ||
export const Pending = PendingButton.bind({}); | ||
Pending.args = { | ||
isPendingStory: true, | ||
}; | ||
export const WithForcedColors = ButtonsWithForcedColors.bind({}); | ||
export const WithForcedColors = Variants.bind({}); | ||
WithForcedColors.parameters = { | ||
chromatic: { forcedColors: "active" }, | ||
chromatic: { forcedColors: "active" }, | ||
}; | ||
@@ -425,10 +495,1 @@ WithForcedColors.args = { | ||
}; | ||
export const Wrapping = WrappingTemplate.bind({}); | ||
Wrapping.storyName = "Wrapping"; | ||
Wrapping.args = { | ||
layout: "stacked", | ||
showIconOnlyButton: false, | ||
variant: "accent", | ||
label: "An example of text overflow behavior within the button component. When the button text is too long for the horizontal space available, it wraps to form another line.", | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { useArgs } from "@storybook/client-api"; | ||
import { useArgs } from "@storybook/preview-api"; | ||
import { html } from "lit"; | ||
@@ -8,2 +8,3 @@ import { classMap } from "lit/directives/class-map.js"; | ||
import { capitalize, lowerCase } from "lodash-es"; | ||
@@ -17,21 +18,24 @@ | ||
export const Template = ({ | ||
rootClass = "spectrum-Button", | ||
id, | ||
customClasses = [], | ||
customStyles = {}, | ||
size = "m", | ||
label, | ||
hideLabel = false, | ||
iconName, | ||
iconAfterLabel = false, | ||
variant, | ||
staticColor, | ||
treatment, | ||
onclick, | ||
isDisabled = false, | ||
isPending = false, | ||
isPendingStory = false, | ||
ariaExpanded, | ||
ariaControls, | ||
...globals | ||
rootClass = "spectrum-Button", | ||
id, | ||
testId, | ||
customClasses = [], | ||
customStyles = {}, | ||
size = "m", | ||
label, | ||
hideLabel = false, | ||
iconName, | ||
iconAfterLabel = false, | ||
variant, | ||
staticColor, | ||
treatment, | ||
onclick, | ||
isDisabled = false, | ||
isHovered = false, | ||
isFocused = false, | ||
isActive = false, | ||
isPending = false, | ||
ariaExpanded, | ||
ariaControls, | ||
...globals | ||
}) => { | ||
@@ -42,9 +46,10 @@ const { express } = globals; | ||
else import(/* webpackPrefetch: true */ "../themes/spectrum.css"); | ||
} catch (e) { | ||
} | ||
catch (e) { | ||
console.warn(e); | ||
} | ||
const [, updateArgs] = useArgs(); | ||
const [, updateArgs] = useArgs(); | ||
return html` | ||
return html` | ||
<button | ||
@@ -58,3 +63,7 @@ class=${classMap({ | ||
[`${rootClass}--iconOnly`]: hideLabel, | ||
"is-pending": isPending, | ||
["is-pending"]: isPending, | ||
["is-disabled"]: isDisabled, | ||
["is-hover"]: isHovered, | ||
["is-focus-visible"]: isFocused, | ||
["is-active"]: isActive, | ||
...customClasses.reduce((a, c) => ({ ...a, [c]: true }), {}), | ||
@@ -65,6 +74,8 @@ })} | ||
?disabled=${isDisabled} | ||
@click=${!isPendingStory ? onclick : () => { | ||
isPending | ||
? updateArgs({ isPending: false }) | ||
: updateArgs({ isPending: true }); | ||
@click=${onclick ?? function() { | ||
// Toggle the is-pending state on-click | ||
updateArgs({ isPending: true }); | ||
setTimeout(() => { | ||
updateArgs({ isPending: false }); | ||
}, 3000); | ||
}} | ||
@@ -74,2 +85,3 @@ aria-label=${ifDefined(hideLabel ? iconName : undefined)} | ||
aria-controls=${ifDefined(ariaControls)} | ||
data-testid=${ifDefined(testId)} | ||
> | ||
@@ -81,11 +93,12 @@ ${when(iconName && !iconAfterLabel, () => Icon({ ...globals, iconName, size }))} | ||
${when(iconName && iconAfterLabel, () => Icon({ ...globals, iconName, size }))} | ||
${when(isPendingStory, () => { | ||
const isOverBackground = staticColor === 'white'; | ||
${when(isPending, () => { | ||
const isOverBackground = staticColor === "white"; | ||
return ProgressCircle({ | ||
...globals, | ||
size: 's', | ||
size: "s", | ||
testId: "progress-circle", | ||
overBackground: isOverBackground, | ||
isIndeterminate: true, | ||
addStaticBackground: false | ||
}) | ||
}); | ||
})} | ||
@@ -92,0 +105,0 @@ </button> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
810613
1
29
5571
0