@stackone/malachite 2.33.1 → 2.34.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.
- package/COMPONENTS.md +3 -3
- package/dist/components/Alert.js +77 -72
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/Button.js +27 -30
- package/dist/components/Button.js.map +1 -1
- package/dist/components/CardStrip.js +366 -301
- package/dist/components/CardStrip.js.map +1 -1
- package/dist/components/Input/Input.js +47 -46
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/PillButton.js +52 -33
- package/dist/components/PillButton.js.map +1 -1
- package/dist/components/Surface.js +100 -94
- package/dist/components/Surface.js.map +1 -1
- package/dist/components/cardStripGeometry.js +47 -0
- package/dist/components/cardStripGeometry.js.map +1 -0
- package/dist/components/linkRel.js +9 -0
- package/dist/components/linkRel.js.map +1 -0
- package/dist/index.d.ts +9 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport BaseFormComponent, { type RequiredIndicator, useFormFieldIds } from '../BaseFormComponent';\nimport { Button } from '../Button';\nimport CheckCircleFilled from '../CustomIcons/CheckCircleFilled';\nimport CopyIcon from '../CustomIcons/CopyIcon';\nimport EyeClosedIcon from '../CustomIcons/EyeClosedIcon';\nimport EyeIcon from '../CustomIcons/EyeIcon';\nimport InfoIcon from '../CustomIcons/InfoIcon';\nimport FieldMessage from '../FieldMessage';\nimport LoadingInput from '../LoadingInput';\nimport { paintedFieldValue } from '../devWarning';\nimport type { ButtonDefinition, InputSize, InputType, InputVariant } from './types';\n\ninterface InputProps {\n label?: string;\n hint?: string;\n tooltip?: string;\n placeholder?: string;\n icon?: React.ReactNode;\n readOnly?: boolean;\n name: FieldPath<FieldValues> | string;\n type?: InputType;\n description?: string;\n size?: InputSize;\n variant?: InputVariant;\n required?: boolean;\n requiredIndicator?: RequiredIndicator;\n error?: boolean;\n loading?: boolean;\n defaultValue?: string;\n disabled?: boolean;\n prefixValue?: string;\n prefixSecondaryValue?: string;\n ellipsis?: boolean;\n formControl?: Control<FieldValues, unknown>;\n buttons?: ButtonDefinition[];\n onCopyClick?: () => void;\n showCopyButton?: boolean;\n onChange?: (value: string) => void;\n /** Controlled value, for a source of truth outside the form (URL, app state). */\n value?: string;\n onBlur?: () => void;\n helperText?: React.ReactNode;\n showPasswordToggle?: boolean;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n}\n\n// Figma specs one Input, at 42px / px-16 / 15px / radius 14 — the large tier. The smaller\n// tiers have no Input master, so they follow Search, which shares the field chrome.\nconst SIZE_HEIGHT: Record<InputSize, string> = {\n small: 'h-[var(--malachite-control-height-small,28px)]',\n medium: 'h-[var(--malachite-control-height-medium,32px)]',\n large: 'h-[var(--malachite-control-height-large,42px)]',\n};\n\nconst SIZE_TEXT: Record<InputSize, string> = {\n small: 'text-[length:var(--malachite-font-size-small,13px)]',\n medium: 'text-[length:var(--malachite-font-size-small,13px)]',\n large: 'text-[length:var(--malachite-font-size-15,15px)] leading-[1.4]',\n};\n\nconst SIZE_PADDING: Record<InputSize, string> = {\n small: 'px-[10px]',\n medium: 'px-[10px]',\n large: 'px-[16px]',\n};\n\nconst SIZE_RADIUS: Record<InputSize, string> = {\n small: 'rounded-[var(--malachite-radius-10,10px)]',\n medium: 'rounded-xl',\n large: 'rounded-[var(--malachite-radius-xxl,14px)]',\n};\n\nconst getVariantClasses = (\n variant: InputVariant,\n error?: boolean,\n): {\n wrapper: string[];\n shadow: string;\n borderRadius: string;\n} => {\n switch (variant) {\n case 'ghost':\n return {\n wrapper: [\n error\n ? 'border-0 border-b border-solid border-[var(--malachite-destructive-border)]'\n : '',\n error\n ? 'focus-within:border-[var(--malachite-destructive-border-hover)] hover:border-[var(--malachite-destructive-border-hover)]'\n : '',\n ],\n shadow: 'shadow-none',\n borderRadius: 'rounded-none',\n };\n case 'default':\n default:\n return {\n wrapper: [\n 'border border-solid',\n error\n ? 'border-[var(--malachite-destructive-border)]'\n : 'border-[var(--malachite-card-border)]',\n error\n ? 'focus-within:border-[var(--malachite-destructive-border-hover)] hover:border-[var(--malachite-destructive-border-hover)]'\n : 'focus-within:border-[var(--malachite-control-border-hover)] hover:border-[var(--malachite-control-border-hover)]',\n ],\n shadow: error ? 'shadow-error' : 'shadow-default',\n borderRadius: '',\n };\n }\n};\n\nconst Input: React.FC<InputProps> = ({\n label,\n hint,\n tooltip,\n placeholder,\n icon,\n name,\n required,\n requiredIndicator,\n error,\n description,\n loading = false,\n readOnly = false,\n type = 'text',\n size = 'large',\n variant = 'default',\n defaultValue,\n disabled,\n prefixValue,\n prefixSecondaryValue,\n ellipsis = false,\n formControl,\n buttons,\n onCopyClick,\n showCopyButton,\n onChange,\n value,\n onBlur,\n helperText,\n showPasswordToggle = true,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n}) => {\n const { controlId, labelId, descriptionId, hintId, helperTextId } = useFormFieldIds({\n id,\n label,\n description,\n hint,\n helperText: true,\n });\n const [showPassword, setShowPassword] = useState(false);\n const [inputValue, setInputValue] = useState(defaultValue || '');\n const [copied, setCopied] = useState(false);\n\n useEffect(() => {\n if (copied) {\n const timer = setTimeout(() => {\n setCopied(false);\n }, 1000);\n return () => clearTimeout(timer);\n }\n }, [copied]);\n\n const handleChange =\n (reportToForm?: (value: unknown) => void) => (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n onChange?.(newValue);\n reportToForm?.(newValue);\n };\n\n const formValueRef = useRef<unknown>(undefined);\n const paintedValue = (formValue: unknown): string =>\n paintedFieldValue({\n component: 'Input',\n name,\n value,\n formValue,\n defaultValue,\n bound: !!formControl,\n uncontrolledValue: inputValue,\n });\n\n const handleCopyClick = onCopyClick\n ? () => {\n const copyValue = paintedValue(formValueRef.current);\n if (copyValue) {\n navigator.clipboard.writeText(copyValue);\n setCopied(true);\n onCopyClick();\n }\n }\n : undefined;\n\n const actualInputType = type === 'password' ? (showPassword ? 'text' : 'password') : type;\n\n const hasPrefix = icon || prefixValue || prefixSecondaryValue;\n\n // The skeleton stands in for the field, so it reads the same height the wrapper does.\n const heightClass = SIZE_HEIGHT[size];\n\n const buildWrapperClasses = (isError: boolean): string => {\n const variantStyles = getVariantClasses(variant, isError);\n\n return [\n 'relative',\n 'flex items-center',\n 'w-full',\n variantStyles.borderRadius || SIZE_RADIUS[size],\n disabled\n ? 'bg-[var(--malachite-card-dimmed-background)]'\n : 'bg-[var(--malachite-card-background)]',\n 'transition-colors duration-200 ease-in-out',\n variantStyles.shadow,\n ...(disabled ? [] : variantStyles.wrapper),\n SIZE_HEIGHT[size],\n ]\n .filter(Boolean)\n .join(' ');\n };\n\n return (\n <BaseFormComponent\n label={label}\n hint={hint}\n tooltip={tooltip}\n name={name}\n required={required}\n requiredIndicator={requiredIndicator}\n loading={loading}\n formControl={formControl}\n description={description}\n controlId={controlId}\n labelId={labelId}\n descriptionId={descriptionId}\n hintId={hintId}\n loadingComponent={\n <LoadingInput\n heightClass={heightClass}\n helperText={!!helperText}\n helperTextMarginTop\n />\n }\n >\n {({ error: fieldError, message, onFieldChange, onFieldBlur, value: formValue }) => {\n formValueRef.current = formValue;\n const displayValue = paintedValue(formValue);\n const shouldShowCopyButton =\n showCopyButton ?? !!(handleCopyClick && disabled && displayValue);\n const isError = error ?? fieldError;\n // `error={false}` opts out of the resolver entirely, message included: a\n // screen that has dealt with the rejection its own way would otherwise keep\n // reporting it in destructive text and through `aria-describedby`.\n // The message is its own line rather than a replacement for the helper text:\n // a field that explains where to find its value still has to say why what was\n // typed was rejected, and dropping one for the other left the field marked red\n // with nothing anywhere saying what was wrong.\n const errorMessage = error === false ? undefined : message;\n // The icon is the only signal a consumer-forced `error` has; beside a message it\n // is duplication, and it crowds the suffix next to a reveal or copy control.\n const showErrorIcon = isError && !errorMessage;\n const hasSuffix =\n showErrorIcon ||\n shouldShowCopyButton ||\n buttons?.length ||\n (type === 'password' && showPasswordToggle);\n const errorMessageId = `${helperTextId}-error`;\n const describedBy =\n [\n descriptionId,\n hintId,\n helperText ? helperTextId : undefined,\n errorMessage ? errorMessageId : undefined,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <>\n <div className={buildWrapperClasses(isError)}>\n {hasPrefix && (\n <div className=\"flex items-center pl-3 pr-1 flex-shrink-0 pointer-events-none\">\n <CompositeIcon\n prefixValue={prefixValue}\n prefixSecondaryValue={prefixSecondaryValue}\n icon={icon}\n />\n </div>\n )}\n\n <input\n id={controlId}\n type={actualInputType}\n placeholder={placeholder}\n value={displayValue}\n onChange={handleChange(onFieldChange)}\n onBlur={() => {\n onBlur?.();\n onFieldBlur?.();\n }}\n disabled={disabled || readOnly}\n readOnly={readOnly}\n autoComplete=\"off\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={isError || undefined}\n aria-required={required || undefined}\n aria-describedby={describedBy}\n className={`flex-1 bg-transparent border-none outline-none text-[var(--malachite-text-primary)] placeholder:text-[var(--malachite-text-placeholder)] disabled:text-[var(--malachite-text-primary)] disabled:cursor-not-allowed ${SIZE_TEXT[size]} ${SIZE_PADDING[size]} ${ellipsis ? 'min-w-0 truncate' : ''}`}\n name={name}\n />\n\n {hasSuffix && (\n <div\n className={`flex items-center pl-1 flex-shrink-0 ${type === 'password' && showPasswordToggle ? 'pr-0' : 'pr-3'}`}\n >\n <Suffix\n error={showErrorIcon}\n defaultValue={displayValue}\n onCopyClick={handleCopyClick}\n showCopyButton={shouldShowCopyButton}\n copied={copied}\n type={type}\n showPassword={showPassword}\n showPasswordToggle={showPasswordToggle}\n onTogglePassword={() => setShowPassword(!showPassword)}\n />\n <InputButtons buttons={buttons} />\n </div>\n )}\n </div>\n {helperText && (\n <div\n id={helperTextId}\n className=\"mt-1 text-[length:var(--malachite-font-size-small,13px)] text-left pl-2 text-[var(--malachite-text-dimmed,rgb(161,161,161))]\"\n >\n {helperText}\n </div>\n )}\n <FieldMessage id={errorMessageId} message={errorMessage} spaced />\n </>\n );\n }}\n </BaseFormComponent>\n );\n};\n\nconst CompositeIcon: React.FC<{\n prefixValue?: string;\n prefixSecondaryValue?: string;\n icon?: React.ReactNode;\n}> = ({ prefixValue, prefixSecondaryValue, icon }) => {\n return (\n <div className=\"flex items-center gap-1\">\n {icon && (\n <span className=\"flex items-center justify-center text-[var(--malachite-text-dimmed)] w-4 h-4 flex-shrink-0\">\n {icon}\n </span>\n )}\n {prefixValue && (\n <span className=\"text-[length:var(--malachite-font-size-medium,14px)] leading-[1.4] text-[var(--malachite-text-dimmed)] whitespace-nowrap\">\n {prefixValue}\n </span>\n )}\n {prefixSecondaryValue && (\n <span className=\"text-[length:var(--malachite-font-size-medium,14px)] leading-[1.4] text-[var(--malachite-text-dimmed)] whitespace-nowrap\">\n {prefixSecondaryValue}\n </span>\n )}\n </div>\n );\n};\n\nconst Suffix: React.FC<{\n error?: boolean;\n defaultValue?: string;\n onCopyClick?: () => void;\n showCopyButton?: boolean;\n copied?: boolean;\n type?: InputType;\n showPassword?: boolean;\n showPasswordToggle?: boolean;\n onTogglePassword?: () => void;\n}> = ({\n error,\n defaultValue,\n onCopyClick,\n showCopyButton = false,\n copied = false,\n type,\n showPassword,\n showPasswordToggle = true,\n onTogglePassword,\n}) => {\n return (\n <div className=\"flex items-center gap-1\">\n {error && (\n // Decorative: the rejection is carried by the message beneath the field, so\n // announcing an unnamed icon here would only repeat it as \"info\".\n <div\n aria-hidden=\"true\"\n className=\"flex items-center justify-center w-5 h-5 flex-shrink-0\"\n >\n <InfoIcon\n size={16}\n className=\"text-[var(--malachite-destructive-foreground,rgb(196,62,62))]\"\n />\n </div>\n )}\n {showCopyButton && onCopyClick && defaultValue && (\n <button\n onClick={onCopyClick}\n type=\"button\"\n className=\"flex items-center justify-center w-5 h-5 hover:bg-[var(--malachite-primary-border)] rounded transition-colors flex-shrink-0 cursor-pointer\"\n >\n {copied ? (\n <CheckCircleFilled\n size={16}\n style={{ color: 'var(--malachite-success-foreground)' }}\n />\n ) : (\n <CopyIcon size={16} />\n )}\n </button>\n )}\n {type === 'password' && showPasswordToggle && (\n <Button variant=\"no-style\" onClick={onTogglePassword} type=\"button\" size=\"small\">\n {showPassword ? (\n <EyeClosedIcon\n size={16}\n style={{ color: 'var(--malachite-text-dimmed)' }}\n />\n ) : (\n <EyeIcon\n size={16}\n style={{ color: 'var(--malachite-text-dimmed)' }}\n />\n )}\n </Button>\n )}\n </div>\n );\n};\n\nconst InputButtons: React.FC<{\n buttons?: ButtonDefinition[];\n}> = ({ buttons }) => {\n if (!buttons?.length) {\n return null;\n }\n\n return (\n <>\n {buttons.map((button) => (\n <Button\n key={button.label}\n variant={button.variant || (button.danger ? 'destructive' : 'outline')}\n size={button.size || 'small'}\n disabled={button.disabled}\n icon={button.icon}\n tooltip={button.tooltip}\n onClick={button.onClick}\n className=\"ml-1\"\n >\n {button.label}\n </Button>\n ))}\n </>\n );\n};\n\nexport default Input;\n"],"names":["SIZE_HEIGHT","SIZE_TEXT","SIZE_PADDING","SIZE_RADIUS","getVariantClasses","variant","error","Input","label","hint","tooltip","placeholder","icon","name","required","requiredIndicator","description","loading","readOnly","type","size","defaultValue","disabled","prefixValue","prefixSecondaryValue","ellipsis","formControl","buttons","onCopyClick","showCopyButton","onChange","value","onBlur","helperText","showPasswordToggle","id","ariaLabel","ariaLabelledBy","ariaDescribedBy","controlId","labelId","descriptionId","hintId","helperTextId","useFormFieldIds","showPassword","setShowPassword","useState","inputValue","setInputValue","copied","setCopied","useEffect","timer","handleChange","reportToForm","e","newValue","formValueRef","useRef","paintedValue","formValue","paintedFieldValue","handleCopyClick","copyValue","actualInputType","hasPrefix","heightClass","buildWrapperClasses","isError","variantStyles","jsx","BaseFormComponent","LoadingInput","fieldError","message","onFieldChange","onFieldBlur","displayValue","shouldShowCopyButton","errorMessage","showErrorIcon","hasSuffix","errorMessageId","describedBy","jsxs","Fragment","CompositeIcon","Suffix","InputButtons","FieldMessage","onTogglePassword","InfoIcon","CheckCircleFilled","CopyIcon","Button","EyeClosedIcon","EyeIcon","button"],"mappings":";;;;;;;;;;;;AAqDA,MAAMA,IAAyC;AAAA,EAC3C,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACX,GAEMC,KAAuC;AAAA,EACzC,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACX,GAEMC,KAA0C;AAAA,EAC5C,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACX,GAEMC,KAAyC;AAAA,EAC3C,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACX,GAEMC,KAAoB,CACtBC,GACAC,MAKC;AACD,UAAQD,GAAA;AAAA,IACJ,KAAK;AACD,aAAO;AAAA,QACH,SAAS;AAAA,UACLC,IACM,iFACA;AAAA,UACNA,IACM,6HACA;AAAA,QAAA;AAAA,QAEV,QAAQ;AAAA,QACR,cAAc;AAAA,MAAA;AAAA,IAEtB,KAAK;AAAA,IACL;AACI,aAAO;AAAA,QACH,SAAS;AAAA,UACL;AAAA,UACAA,IACM,iDACA;AAAA,UACNA,IACM,6HACA;AAAA,QAAA;AAAA,QAEV,QAAQA,IAAQ,iBAAiB;AAAA,QACjC,cAAc;AAAA,MAAA;AAAA,EAClB;AAEZ,GAEMC,KAA8B,CAAC;AAAA,EACjC,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,UAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,OAAAT;AAAA,EACA,aAAAU;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,UAAAC,IAAW;AAAA,EACX,MAAAC,IAAO;AAAA,EACP,MAAAC,IAAO;AAAA,EACP,SAAAf,IAAU;AAAA,EACV,cAAAgB;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,oBAAAC,IAAqB;AAAA,EACrB,IAAAC;AAAA,EACA,cAAcC;AAAA,EACd,mBAAmBC;AAAA,EACnB,oBAAoBC;AACxB,MAAM;AACF,QAAM,EAAE,WAAAC,GAAW,SAAAC,IAAS,eAAAC,GAAe,QAAAC,GAAQ,cAAAC,EAAA,IAAiBC,GAAgB;AAAA,IAChF,IAAAT;AAAA,IACA,OAAA3B;AAAA,IACA,aAAAQ;AAAA,IACA,MAAAP;AAAA,IACA,YAAY;AAAA,EAAA,CACf,GACK,CAACoC,GAAcC,EAAe,IAAIC,EAAS,EAAK,GAChD,CAACC,IAAYC,EAAa,IAAIF,EAAS1B,KAAgB,EAAE,GACzD,CAAC6B,GAAQC,CAAS,IAAIJ,EAAS,EAAK;AAE1C,EAAAK,GAAU,MAAM;AACZ,QAAIF,GAAQ;AACR,YAAMG,IAAQ,WAAW,MAAM;AAC3B,QAAAF,EAAU,EAAK;AAAA,MACnB,GAAG,GAAI;AACP,aAAO,MAAM,aAAaE,CAAK;AAAA,IACnC;AAAA,EACJ,GAAG,CAACH,CAAM,CAAC;AAEX,QAAMI,KACF,CAACC,MAA4C,CAACC,MAA2C;AACrF,UAAMC,IAAWD,EAAE,OAAO;AAC1B,IAAAP,GAAcQ,CAAQ,GACtB3B,KAAA,QAAAA,EAAW2B,IACXF,KAAA,QAAAA,EAAeE;AAAA,EACnB,GAEEC,IAAeC,GAAgB,MAAS,GACxCC,IAAe,CAACC,MAClBC,GAAkB;AAAA,IACd,WAAW;AAAA,IACX,MAAAjD;AAAA,IACA,OAAAkB;AAAA,IACA,WAAA8B;AAAA,IACA,cAAAxC;AAAA,IACA,OAAO,CAAC,CAACK;AAAA,IACT,mBAAmBsB;AAAA,EAAA,CACtB,GAECe,IAAkBnC,IAClB,MAAM;AACF,UAAMoC,IAAYJ,EAAaF,EAAa,OAAO;AACnD,IAAIM,MACA,UAAU,UAAU,UAAUA,CAAS,GACvCb,EAAU,EAAI,GACdvB,EAAA;AAAA,EAER,IACA,QAEAqC,KAAkB9C,MAAS,aAAc0B,IAAe,SAAS,aAAc1B,GAE/E+C,KAAYtD,KAAQW,KAAeC,GAGnC2C,KAAcnE,EAAYoB,CAAI,GAE9BgD,KAAsB,CAACC,MAA6B;AACtD,UAAMC,IAAgBlE,GAAkBC,GAASgE,CAAO;AAExD,WAAO;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACAC,EAAc,gBAAgBnE,GAAYiB,CAAI;AAAA,MAC9CE,IACM,iDACA;AAAA,MACN;AAAA,MACAgD,EAAc;AAAA,MACd,GAAIhD,IAAW,KAAKgD,EAAc;AAAA,MAClCtE,EAAYoB,CAAI;AAAA,IAAA,EAEf,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,EACjB;AAEA,SACI,gBAAAmD;AAAA,IAACC;AAAA,IAAA;AAAA,MACG,OAAAhE;AAAA,MACA,MAAAC;AAAA,MACA,SAAAC;AAAA,MACA,MAAAG;AAAA,MACA,UAAAC;AAAA,MACA,mBAAAC;AAAA,MACA,SAAAE;AAAA,MACA,aAAAS;AAAA,MACA,aAAAV;AAAA,MACA,WAAAuB;AAAA,MACA,SAAAC;AAAA,MACA,eAAAC;AAAA,MACA,QAAAC;AAAA,MACA,kBACI,gBAAA6B;AAAA,QAACE;AAAA,QAAA;AAAA,UACG,aAAAN;AAAA,UACA,YAAY,CAAC,CAAClC;AAAA,UACd,qBAAmB;AAAA,QAAA;AAAA,MAAA;AAAA,MAI1B,UAAA,CAAC,EAAE,OAAOyC,GAAY,SAAAC,GAAS,eAAAC,GAAe,aAAAC,GAAa,OAAOhB,QAAgB;AAC/E,QAAAH,EAAa,UAAUG;AACvB,cAAMiB,IAAelB,EAAaC,CAAS,GACrCkB,IACFlD,MAAkB,CAAC,EAAEkC,KAAmBzC,KAAYwD,IAClDT,IAAU/D,KAASoE,GAQnBM,IAAe1E,MAAU,KAAQ,SAAYqE,GAG7CM,IAAgBZ,KAAW,CAACW,GAC5BE,KACFD,KACAF,MACApD,KAAA,gBAAAA,EAAS,WACRR,MAAS,cAAce,GACtBiD,IAAiB,GAAGxC,CAAY,UAChCyC,KACF;AAAA,UACI3C;AAAA,UACAC;AAAA,UACAT,IAAaU,IAAe;AAAA,UAC5BqC,IAAeG,IAAiB;AAAA,UAChC7C;AAAA,QAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAEtB,eACI,gBAAA+C,EAAAC,GAAA,EACI,UAAA;AAAA,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAWjB,GAAoBC,CAAO,GACtC,UAAA;AAAA,YAAAH,MACG,gBAAAK,EAAC,OAAA,EAAI,WAAU,iEACX,UAAA,gBAAAA;AAAA,cAACgB;AAAA,cAAA;AAAA,gBACG,aAAAhE;AAAA,gBACA,sBAAAC;AAAA,gBACA,MAAAZ;AAAA,cAAA;AAAA,YAAA,GAER;AAAA,YAGJ,gBAAA2D;AAAA,cAAC;AAAA,cAAA;AAAA,gBACG,IAAIhC;AAAA,gBACJ,MAAM0B;AAAA,gBACN,aAAAtD;AAAA,gBACA,OAAOmE;AAAA,gBACP,UAAUxB,GAAasB,CAAa;AAAA,gBACpC,QAAQ,MAAM;AACV,kBAAA5C,KAAA,QAAAA,KACA6C,KAAA,QAAAA;AAAA,gBACJ;AAAA,gBACA,UAAUvD,KAAYJ;AAAA,gBACtB,UAAAA;AAAA,gBACA,cAAa;AAAA,gBACb,cAAYkB;AAAA,gBACZ,mBAAiBC;AAAA,gBACjB,gBAAcgC,KAAW;AAAA,gBACzB,iBAAevD,KAAY;AAAA,gBAC3B,oBAAkBsE;AAAA,gBAClB,WAAW,sNAAsNnF,GAAUmB,CAAI,CAAC,IAAIlB,GAAakB,CAAI,CAAC,IAAIK,IAAW,qBAAqB,EAAE;AAAA,gBAC5S,MAAAZ;AAAA,cAAA;AAAA,YAAA;AAAA,YAGHqE,MACG,gBAAAG;AAAA,cAAC;AAAA,cAAA;AAAA,gBACG,WAAW,wCAAwClE,MAAS,cAAce,IAAqB,SAAS,MAAM;AAAA,gBAE9G,UAAA;AAAA,kBAAA,gBAAAqC;AAAA,oBAACiB;AAAA,oBAAA;AAAA,sBACG,OAAOP;AAAA,sBACP,cAAcH;AAAA,sBACd,aAAaf;AAAA,sBACb,gBAAgBgB;AAAA,sBAChB,QAAA7B;AAAA,sBACA,MAAA/B;AAAA,sBACA,cAAA0B;AAAA,sBACA,oBAAAX;AAAA,sBACA,kBAAkB,MAAMY,GAAgB,CAACD,CAAY;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAEzD,gBAAA0B,EAACkB,MAAa,SAAA9D,EAAA,CAAkB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACpC,GAER;AAAA,UACCM,KACG,gBAAAsC;AAAA,YAAC;AAAA,YAAA;AAAA,cACG,IAAI5B;AAAA,cACJ,WAAU;AAAA,cAET,UAAAV;AAAA,YAAA;AAAA,UAAA;AAAA,4BAGRyD,IAAA,EAAa,IAAIP,GAAgB,SAASH,GAAc,QAAM,GAAA,CAAC;AAAA,QAAA,GACpE;AAAA,MAER;AAAA,IAAA;AAAA,EAAA;AAGZ,GAEMO,KAID,CAAC,EAAE,aAAAhE,GAAa,sBAAAC,GAAsB,MAAAZ,QAEnC,gBAAAyE,EAAC,OAAA,EAAI,WAAU,2BACV,UAAA;AAAA,EAAAzE,KACG,gBAAA2D,EAAC,QAAA,EAAK,WAAU,8FACX,UAAA3D,GACL;AAAA,EAEHW,KACG,gBAAAgD,EAAC,QAAA,EAAK,WAAU,4HACX,UAAAhD,GACL;AAAA,EAEHC,KACG,gBAAA+C,EAAC,QAAA,EAAK,WAAU,4HACX,UAAA/C,EAAA,CACL;AAAA,GAER,GAIFgE,KAUD,CAAC;AAAA,EACF,OAAAlF;AAAA,EACA,cAAAe;AAAA,EACA,aAAAO;AAAA,EACA,gBAAAC,IAAiB;AAAA,EACjB,QAAAqB,IAAS;AAAA,EACT,MAAA/B;AAAA,EACA,cAAA0B;AAAA,EACA,oBAAAX,IAAqB;AAAA,EACrB,kBAAAyD;AACJ,MAEQ,gBAAAN,EAAC,OAAA,EAAI,WAAU,2BACV,UAAA;AAAA,EAAA/E;AAAA;AAAA,EAGG,gBAAAiE;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,eAAY;AAAA,MACZ,WAAU;AAAA,MAEV,UAAA,gBAAAA;AAAA,QAACqB;AAAA,QAAA;AAAA,UACG,MAAM;AAAA,UACN,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACd;AAAA,EAAA;AAAA,EAGP/D,KAAkBD,KAAeP,KAC9B,gBAAAkD;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,SAAS3C;AAAA,MACT,MAAK;AAAA,MACL,WAAU;AAAA,MAET,UAAAsB,IACG,gBAAAqB;AAAA,QAACsB;AAAA,QAAA;AAAA,UACG,MAAM;AAAA,UACN,OAAO,EAAE,OAAO,sCAAA;AAAA,QAAsC;AAAA,MAAA,IAG1D,gBAAAtB,EAACuB,IAAA,EAAS,MAAM,GAAA,CAAI;AAAA,IAAA;AAAA,EAAA;AAAA,EAI/B3E,MAAS,cAAce,KACpB,gBAAAqC,EAACwB,GAAA,EAAO,SAAQ,YAAW,SAASJ,GAAkB,MAAK,UAAS,MAAK,SACpE,UAAA9C,IACG,gBAAA0B;AAAA,IAACyB;AAAA,IAAA;AAAA,MACG,MAAM;AAAA,MACN,OAAO,EAAE,OAAO,+BAAA;AAAA,IAA+B;AAAA,EAAA,IAGnD,gBAAAzB;AAAA,IAAC0B;AAAA,IAAA;AAAA,MACG,MAAM;AAAA,MACN,OAAO,EAAE,OAAO,+BAAA;AAAA,IAA+B;AAAA,EAAA,EACnD,CAER;AAAA,GAER,GAIFR,KAED,CAAC,EAAE,SAAA9D,QACCA,KAAA,QAAAA,EAAS,SAKV,gBAAA4C,EAAAe,GAAA,EACK,UAAA3D,EAAQ,IAAI,CAACuE,MACV,gBAAA3B;AAAA,EAACwB;AAAA,EAAA;AAAA,IAEG,SAASG,EAAO,YAAYA,EAAO,SAAS,gBAAgB;AAAA,IAC5D,MAAMA,EAAO,QAAQ;AAAA,IACrB,UAAUA,EAAO;AAAA,IACjB,MAAMA,EAAO;AAAA,IACb,SAASA,EAAO;AAAA,IAChB,SAASA,EAAO;AAAA,IAChB,WAAU;AAAA,IAET,UAAAA,EAAO;AAAA,EAAA;AAAA,EATHA,EAAO;AAAA,CAWnB,GACL,IAnBO;"}
|
|
1
|
+
{"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport BaseFormComponent, { type RequiredIndicator, useFormFieldIds } from '../BaseFormComponent';\nimport { Button } from '../Button';\nimport CheckCircleFilled from '../CustomIcons/CheckCircleFilled';\nimport CopyIcon from '../CustomIcons/CopyIcon';\nimport EyeClosedIcon from '../CustomIcons/EyeClosedIcon';\nimport EyeIcon from '../CustomIcons/EyeIcon';\nimport InfoIcon from '../CustomIcons/InfoIcon';\nimport FieldMessage from '../FieldMessage';\nimport LoadingInput from '../LoadingInput';\nimport { paintedFieldValue } from '../devWarning';\nimport type { ButtonDefinition, InputSize, InputType, InputVariant } from './types';\n\ninterface InputProps {\n label?: string;\n hint?: string;\n tooltip?: string;\n placeholder?: string;\n icon?: React.ReactNode;\n readOnly?: boolean;\n name: FieldPath<FieldValues> | string;\n type?: InputType;\n description?: string;\n size?: InputSize;\n variant?: InputVariant;\n required?: boolean;\n requiredIndicator?: RequiredIndicator;\n error?: boolean;\n loading?: boolean;\n defaultValue?: string;\n disabled?: boolean;\n prefixValue?: string;\n prefixSecondaryValue?: string;\n ellipsis?: boolean;\n formControl?: Control<FieldValues, unknown>;\n buttons?: ButtonDefinition[];\n onCopyClick?: () => void;\n showCopyButton?: boolean;\n onChange?: (value: string) => void;\n /** Controlled value, for a source of truth outside the form (URL, app state). */\n value?: string;\n onBlur?: () => void;\n helperText?: React.ReactNode;\n showPasswordToggle?: boolean;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n}\n\n// Figma specs one Input, at 42px / px-16 / 15px / radius 14 — the large tier. The smaller\n// tiers have no Input master, so they follow Search, which shares the field chrome.\nconst SIZE_HEIGHT: Record<InputSize, string> = {\n small: 'h-[var(--malachite-control-height-small,28px)]',\n medium: 'h-[var(--malachite-control-height-medium,32px)]',\n large: 'h-[var(--malachite-control-height-large,42px)]',\n};\n\nconst SIZE_TEXT: Record<InputSize, string> = {\n small: 'text-[length:var(--malachite-font-size-small,13px)]',\n medium: 'text-[length:var(--malachite-font-size-small,13px)]',\n large: 'text-[length:var(--malachite-font-size-15,15px)] leading-[1.4]',\n};\n\nconst SIZE_PADDING: Record<InputSize, string> = {\n small: 'px-[10px]',\n medium: 'px-[10px]',\n large: 'px-[16px]',\n};\n\nconst SIZE_RADIUS: Record<InputSize, string> = {\n small: 'rounded-[var(--malachite-radius-10,10px)]',\n medium: 'rounded-xl',\n large: 'rounded-[var(--malachite-radius-xxl,14px)]',\n};\n\nconst getVariantClasses = (\n variant: InputVariant,\n error?: boolean,\n): {\n wrapper: string[];\n shadow: string;\n borderRadius: string;\n} => {\n switch (variant) {\n case 'ghost':\n return {\n wrapper: [\n error\n ? 'border-0 border-b border-solid border-[var(--malachite-destructive-border)]'\n : '',\n error\n ? 'focus-within:border-[var(--malachite-destructive-border-hover)] hover:border-[var(--malachite-destructive-border-hover)]'\n : '',\n ],\n shadow: 'shadow-none',\n borderRadius: 'rounded-none',\n };\n case 'default':\n default:\n return {\n wrapper: [\n 'border border-solid',\n error\n ? 'border-[var(--malachite-destructive-border)]'\n : 'border-[var(--malachite-card-border)]',\n error\n ? 'focus-within:border-[var(--malachite-destructive-border-hover)] hover:border-[var(--malachite-destructive-border-hover)]'\n : 'focus-within:border-[var(--malachite-control-border-hover)] hover:border-[var(--malachite-control-border-hover)]',\n ],\n shadow: error ? 'shadow-error' : 'shadow-default',\n borderRadius: '',\n };\n }\n};\n\nconst Input: React.FC<InputProps> = ({\n label,\n hint,\n tooltip,\n placeholder,\n icon,\n name,\n required,\n requiredIndicator,\n error,\n description,\n loading = false,\n readOnly = false,\n type = 'text',\n size = 'large',\n variant = 'default',\n defaultValue,\n disabled,\n prefixValue,\n prefixSecondaryValue,\n ellipsis = false,\n formControl,\n buttons,\n onCopyClick,\n showCopyButton,\n onChange,\n value,\n onBlur,\n helperText,\n showPasswordToggle = true,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n}) => {\n const { controlId, labelId, descriptionId, hintId, helperTextId } = useFormFieldIds({\n id,\n label,\n description,\n hint,\n helperText: true,\n });\n const [showPassword, setShowPassword] = useState(false);\n const [inputValue, setInputValue] = useState(defaultValue || '');\n const [copied, setCopied] = useState(false);\n\n useEffect(() => {\n if (copied) {\n const timer = setTimeout(() => {\n setCopied(false);\n }, 1000);\n return () => clearTimeout(timer);\n }\n }, [copied]);\n\n const handleChange =\n (reportToForm?: (value: unknown) => void) => (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n onChange?.(newValue);\n reportToForm?.(newValue);\n };\n\n const formValueRef = useRef<unknown>(undefined);\n const paintedValue = (formValue: unknown): string =>\n paintedFieldValue({\n component: 'Input',\n name,\n value,\n formValue,\n defaultValue,\n bound: !!formControl,\n uncontrolledValue: inputValue,\n });\n\n const handleCopyClick = onCopyClick\n ? () => {\n const copyValue = paintedValue(formValueRef.current);\n if (copyValue) {\n navigator.clipboard.writeText(copyValue);\n setCopied(true);\n onCopyClick();\n }\n }\n : undefined;\n\n const actualInputType = type === 'password' ? (showPassword ? 'text' : 'password') : type;\n\n const hasPrefix = icon || prefixValue || prefixSecondaryValue;\n\n // The skeleton stands in for the field, so it reads the same height the wrapper does.\n const heightClass = SIZE_HEIGHT[size];\n\n const buildWrapperClasses = (isError: boolean): string => {\n const variantStyles = getVariantClasses(variant, isError);\n\n return [\n 'relative',\n 'flex items-center',\n 'w-full',\n variantStyles.borderRadius || SIZE_RADIUS[size],\n disabled\n ? 'bg-[var(--malachite-card-dimmed-background)]'\n : 'bg-[var(--malachite-card-background)]',\n 'transition-colors duration-200 ease-in-out',\n variantStyles.shadow,\n ...(disabled ? [] : variantStyles.wrapper),\n SIZE_HEIGHT[size],\n ]\n .filter(Boolean)\n .join(' ');\n };\n\n return (\n <BaseFormComponent\n label={label}\n hint={hint}\n tooltip={tooltip}\n name={name}\n required={required}\n requiredIndicator={requiredIndicator}\n loading={loading}\n formControl={formControl}\n description={description}\n controlId={controlId}\n labelId={labelId}\n descriptionId={descriptionId}\n hintId={hintId}\n loadingComponent={\n <LoadingInput\n heightClass={heightClass}\n helperText={!!helperText}\n helperTextMarginTop\n />\n }\n >\n {({ error: fieldError, message, onFieldChange, onFieldBlur, value: formValue }) => {\n formValueRef.current = formValue;\n const displayValue = paintedValue(formValue);\n const shouldShowCopyButton =\n showCopyButton ?? !!(handleCopyClick && disabled && displayValue);\n const isError = error ?? fieldError;\n // `error={false}` opts out of the resolver entirely, message included: a\n // screen that has dealt with the rejection its own way would otherwise keep\n // reporting it in destructive text and through `aria-describedby`.\n // The message is its own line rather than a replacement for the helper text:\n // a field that explains where to find its value still has to say why what was\n // typed was rejected, and dropping one for the other left the field marked red\n // with nothing anywhere saying what was wrong.\n const errorMessage = error === false ? undefined : message;\n // The icon is the only signal a consumer-forced `error` has; beside a message it\n // is duplication, and it crowds the suffix next to a reveal or copy control.\n const showErrorIcon = isError && !errorMessage;\n const hasSuffix =\n showErrorIcon ||\n shouldShowCopyButton ||\n buttons?.length ||\n (type === 'password' && showPasswordToggle);\n const errorMessageId = `${helperTextId}-error`;\n const describedBy =\n [\n descriptionId,\n hintId,\n helperText ? helperTextId : undefined,\n errorMessage ? errorMessageId : undefined,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <>\n <div className={buildWrapperClasses(isError)}>\n {hasPrefix && (\n <div className=\"flex items-center pl-3 pr-1 flex-shrink-0 pointer-events-none\">\n <CompositeIcon\n prefixValue={prefixValue}\n prefixSecondaryValue={prefixSecondaryValue}\n icon={icon}\n />\n </div>\n )}\n\n <input\n id={controlId}\n type={actualInputType}\n placeholder={placeholder}\n value={displayValue}\n onChange={handleChange(onFieldChange)}\n onBlur={() => {\n onBlur?.();\n onFieldBlur?.();\n }}\n disabled={disabled || readOnly}\n readOnly={readOnly}\n autoComplete=\"off\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={isError || undefined}\n aria-required={required || undefined}\n aria-describedby={describedBy}\n className={`flex-1 bg-transparent border-none outline-none text-[var(--malachite-text-primary)] placeholder:text-[var(--malachite-text-placeholder)] disabled:text-[var(--malachite-text-primary)] disabled:cursor-not-allowed ${SIZE_TEXT[size]} ${SIZE_PADDING[size]} ${ellipsis ? 'min-w-0 truncate' : ''}`}\n name={name}\n />\n\n {hasSuffix && (\n <div\n className={`flex items-center pl-1 flex-shrink-0 ${type === 'password' && showPasswordToggle ? 'pr-0' : 'pr-3'}`}\n >\n <Suffix\n error={showErrorIcon}\n defaultValue={displayValue}\n onCopyClick={handleCopyClick}\n showCopyButton={shouldShowCopyButton}\n copied={copied}\n type={type}\n showPassword={showPassword}\n showPasswordToggle={showPasswordToggle}\n onTogglePassword={() => setShowPassword(!showPassword)}\n />\n <InputButtons buttons={buttons} />\n </div>\n )}\n </div>\n {helperText && (\n <div\n id={helperTextId}\n className=\"mt-1 text-[length:var(--malachite-font-size-small,13px)] text-left pl-2 text-[var(--malachite-text-dimmed,rgb(161,161,161))]\"\n >\n {helperText}\n </div>\n )}\n <FieldMessage id={errorMessageId} message={errorMessage} spaced />\n </>\n );\n }}\n </BaseFormComponent>\n );\n};\n\nconst CompositeIcon: React.FC<{\n prefixValue?: string;\n prefixSecondaryValue?: string;\n icon?: React.ReactNode;\n}> = ({ prefixValue, prefixSecondaryValue, icon }) => {\n return (\n <div className=\"flex items-center gap-1\">\n {icon && (\n <span className=\"flex items-center justify-center text-[var(--malachite-text-dimmed)] w-4 h-4 flex-shrink-0\">\n {icon}\n </span>\n )}\n {prefixValue && (\n <span className=\"text-[length:var(--malachite-font-size-medium,14px)] leading-[1.4] text-[var(--malachite-text-dimmed)] whitespace-nowrap\">\n {prefixValue}\n </span>\n )}\n {prefixSecondaryValue && (\n <span className=\"text-[length:var(--malachite-font-size-medium,14px)] leading-[1.4] text-[var(--malachite-text-dimmed)] whitespace-nowrap\">\n {prefixSecondaryValue}\n </span>\n )}\n </div>\n );\n};\n\nconst Suffix: React.FC<{\n error?: boolean;\n defaultValue?: string;\n onCopyClick?: () => void;\n showCopyButton?: boolean;\n copied?: boolean;\n type?: InputType;\n showPassword?: boolean;\n showPasswordToggle?: boolean;\n onTogglePassword?: () => void;\n}> = ({\n error,\n defaultValue,\n onCopyClick,\n showCopyButton = false,\n copied = false,\n type,\n showPassword,\n showPasswordToggle = true,\n onTogglePassword,\n}) => {\n return (\n <div className=\"flex items-center gap-1\">\n {error && (\n // Decorative: the rejection is carried by the message beneath the field, so\n // announcing an unnamed icon here would only repeat it as \"info\".\n <div\n aria-hidden=\"true\"\n className=\"flex items-center justify-center w-5 h-5 flex-shrink-0\"\n >\n <InfoIcon\n size={16}\n className=\"text-[var(--malachite-destructive-foreground,rgb(196,62,62))]\"\n />\n </div>\n )}\n {showCopyButton && onCopyClick && defaultValue && (\n <button\n onClick={onCopyClick}\n type=\"button\"\n aria-label=\"Copy\"\n className=\"flex items-center justify-center w-5 h-5 hover:bg-[var(--malachite-primary-border)] rounded transition-colors flex-shrink-0 cursor-pointer\"\n >\n {copied ? (\n <CheckCircleFilled\n size={16}\n style={{ color: 'var(--malachite-success-foreground)' }}\n />\n ) : (\n <CopyIcon size={16} />\n )}\n </button>\n )}\n {type === 'password' && showPasswordToggle && (\n <Button variant=\"no-style\" onClick={onTogglePassword} type=\"button\" size=\"small\">\n {showPassword ? (\n <EyeClosedIcon\n size={16}\n style={{ color: 'var(--malachite-text-dimmed)' }}\n />\n ) : (\n <EyeIcon\n size={16}\n style={{ color: 'var(--malachite-text-dimmed)' }}\n />\n )}\n </Button>\n )}\n </div>\n );\n};\n\nconst InputButtons: React.FC<{\n buttons?: ButtonDefinition[];\n}> = ({ buttons }) => {\n if (!buttons?.length) {\n return null;\n }\n\n return (\n <>\n {buttons.map((button) => (\n <Button\n key={button.label}\n variant={button.variant || (button.danger ? 'destructive' : 'outline')}\n size={button.size || 'small'}\n disabled={button.disabled}\n icon={button.icon}\n tooltip={button.tooltip}\n onClick={button.onClick}\n className=\"ml-1\"\n >\n {button.label}\n </Button>\n ))}\n </>\n );\n};\n\nexport default Input;\n"],"names":["SIZE_HEIGHT","SIZE_TEXT","SIZE_PADDING","SIZE_RADIUS","getVariantClasses","variant","error","Input","label","hint","tooltip","placeholder","icon","name","required","requiredIndicator","description","loading","readOnly","type","size","defaultValue","disabled","prefixValue","prefixSecondaryValue","ellipsis","formControl","buttons","onCopyClick","showCopyButton","onChange","value","onBlur","helperText","showPasswordToggle","id","ariaLabel","ariaLabelledBy","ariaDescribedBy","controlId","labelId","descriptionId","hintId","helperTextId","useFormFieldIds","showPassword","setShowPassword","useState","inputValue","setInputValue","copied","setCopied","useEffect","timer","handleChange","reportToForm","e","newValue","formValueRef","useRef","paintedValue","formValue","paintedFieldValue","handleCopyClick","copyValue","actualInputType","hasPrefix","heightClass","buildWrapperClasses","isError","variantStyles","jsx","BaseFormComponent","LoadingInput","fieldError","message","onFieldChange","onFieldBlur","displayValue","shouldShowCopyButton","errorMessage","showErrorIcon","hasSuffix","errorMessageId","describedBy","jsxs","Fragment","CompositeIcon","Suffix","InputButtons","FieldMessage","onTogglePassword","InfoIcon","CheckCircleFilled","CopyIcon","Button","EyeClosedIcon","EyeIcon","button"],"mappings":"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"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { FOCUS_RING as
|
|
3
|
-
|
|
1
|
+
import { jsxs as p, jsx as x } from "react/jsx-runtime";
|
|
2
|
+
import { FOCUS_RING as S } from "./focusRing.js";
|
|
3
|
+
import { resolveRel as R } from "./linkRel.js";
|
|
4
|
+
import { safeHref as T } from "./safeHref.js";
|
|
5
|
+
const j = "inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap shrink-0 transition-colors duration-150 ease-in-out", y = {
|
|
4
6
|
pill: "rounded-[var(--malachite-radius-10,10px)]",
|
|
5
7
|
tab: "rounded-b-[var(--malachite-radius-10,10px)] rounded-t-none"
|
|
6
|
-
},
|
|
8
|
+
}, B = {
|
|
7
9
|
default: "border-0",
|
|
8
10
|
assistant: "border border-solid border-[var(--malachite-tag-assistant-border)]"
|
|
9
|
-
},
|
|
11
|
+
}, $ = "bg-[var(--malachite-card-background)] text-[var(--malachite-assistant-foreground)]", w = {
|
|
10
12
|
// For a row that labels other content rather than being read on its own — a context
|
|
11
13
|
// strip above a chat, say. The only size that drops below the 13px the others share.
|
|
12
14
|
xsmall: {
|
|
@@ -24,7 +26,7 @@ const E = "inline-flex items-center justify-center gap-1.5 font-medium whitespac
|
|
|
24
26
|
padding: "px-2.5",
|
|
25
27
|
paddingWithIcon: "pl-1.5 pr-2"
|
|
26
28
|
}
|
|
27
|
-
},
|
|
29
|
+
}, z = "bg-[var(--malachite-pillbutton-static-background)] text-[var(--malachite-pillbutton-static-foreground)]", W = "active:opacity-60 cursor-pointer", H = {
|
|
28
30
|
default: {
|
|
29
31
|
base: "bg-[var(--malachite-pillbutton-background)] text-[var(--malachite-pillbutton-foreground)]",
|
|
30
32
|
selected: "bg-[var(--malachite-pillbutton-hover-background)] text-[var(--malachite-pillbutton-hover-foreground)]",
|
|
@@ -35,36 +37,53 @@ const E = "inline-flex items-center justify-center gap-1.5 font-medium whitespac
|
|
|
35
37
|
selected: "bg-[var(--malachite-pillbutton-inverted-hover-background)] text-[var(--malachite-pillbutton-inverted-hover-foreground)]",
|
|
36
38
|
hover: "hover:bg-[var(--malachite-pillbutton-inverted-hover-background)] hover:text-[var(--malachite-pillbutton-inverted-hover-foreground)] active:bg-[var(--malachite-pillbutton-inverted-pressed-background)] active:text-[var(--malachite-pillbutton-inverted-pressed-foreground)]"
|
|
37
39
|
}
|
|
38
|
-
},
|
|
39
|
-
label:
|
|
40
|
-
icon:
|
|
41
|
-
className:
|
|
42
|
-
selected:
|
|
43
|
-
disabled:
|
|
44
|
-
interactive:
|
|
45
|
-
size:
|
|
46
|
-
variant:
|
|
47
|
-
shape:
|
|
48
|
-
tone:
|
|
49
|
-
trailingIcon:
|
|
50
|
-
onClick:
|
|
40
|
+
}, K = ({
|
|
41
|
+
label: r = "Label",
|
|
42
|
+
icon: l,
|
|
43
|
+
className: k = "",
|
|
44
|
+
selected: A = !1,
|
|
45
|
+
disabled: m = !1,
|
|
46
|
+
interactive: v = !0,
|
|
47
|
+
size: C = "small",
|
|
48
|
+
variant: L = "default",
|
|
49
|
+
shape: I = "pill",
|
|
50
|
+
tone: b = "default",
|
|
51
|
+
trailingIcon: g,
|
|
52
|
+
onClick: n,
|
|
53
|
+
href: E,
|
|
54
|
+
target: f,
|
|
55
|
+
rel: _
|
|
51
56
|
}) => {
|
|
52
|
-
const
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
const i = w[C], N = l ? i.paddingWithIcon : i.padding, t = H[L], o = v && !m, s = T(E), a = o && (!!n || !!s), c = a ? ` ${W}` : "";
|
|
58
|
+
let e;
|
|
59
|
+
b === "assistant" ? e = a ? `${$}${c}` : $ : v ? A ? e = o ? `${t.selected}${c}` : t.selected : o ? e = `${t.base} ${t.hover}${c}` : e = t.base : e = z;
|
|
60
|
+
const O = m ? "opacity-50 cursor-not-allowed pointer-events-none" : "", d = `${j} ${y[I]} ${i.text} ${N} ${B[b]} ${e} ${O} ${k}`, u = l ? /* @__PURE__ */ x("span", { className: "inline-flex items-center justify-center w-4 h-4 shrink-0 [&>img]:max-w-full [&>img]:max-h-full [&>img]:object-contain", children: l }) : null, h = g ? /* @__PURE__ */ x("span", { className: "inline-flex shrink-0 items-center justify-center", children: g }) : null;
|
|
61
|
+
return a && s ? /* @__PURE__ */ p(
|
|
62
|
+
"a",
|
|
63
|
+
{
|
|
64
|
+
href: s,
|
|
65
|
+
target: f,
|
|
66
|
+
rel: R(_, f),
|
|
67
|
+
className: `${S} ${d} no-underline`,
|
|
68
|
+
onClick: n,
|
|
69
|
+
children: [
|
|
70
|
+
u,
|
|
71
|
+
r,
|
|
72
|
+
h
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
) : a ? /* @__PURE__ */ p("button", { type: "button", className: `${S} ${d}`, onClick: n, children: [
|
|
76
|
+
u,
|
|
77
|
+
r,
|
|
78
|
+
h
|
|
79
|
+
] }) : /* @__PURE__ */ p("div", { className: d, children: [
|
|
80
|
+
u,
|
|
81
|
+
r,
|
|
82
|
+
h
|
|
64
83
|
] });
|
|
65
84
|
};
|
|
66
85
|
export {
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
K as PillButton,
|
|
87
|
+
K as default
|
|
69
88
|
};
|
|
70
89
|
//# sourceMappingURL=PillButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PillButton.js","sources":["../../src/components/PillButton.tsx"],"sourcesContent":["import React from 'react';\nimport { FOCUS_RING } from './focusRing';\n\ntype PillButtonSize = 'xsmall' | 'small' | 'medium';\ntype PillButtonVariant = 'default' | 'inverted';\n/**\n * `tab` squares the top corners so the pill reads as attached to whatever sits above it —\n * a row of controls hanging under an input, rather than free-floating pills.\n */\ntype PillButtonShape = 'pill' | 'tab';\n/**\n * `assistant` is the chrome for AI-authored chips (e.g. `ChangeReview.Jump`): a fixed\n * violet-on-white look with its own border, independent of `variant`/`selected`.\n */\ntype PillButtonTone = 'default' | 'assistant';\n\ninterface PillButtonProps {\n label: string;\n icon?: React.ReactNode;\n className?: string;\n selected?: boolean;\n disabled?: boolean;\n interactive?: boolean;\n size?: PillButtonSize;\n variant?: PillButtonVariant;\n shape?: PillButtonShape;\n tone?: PillButtonTone;\n /** Sits after the label — a caret on a pill that opens a menu. */\n trailingIcon?: React.ReactNode;\n onClick?: () => void;\n}\n\nconst BASE_CLASSES =\n 'inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap shrink-0 transition-colors duration-150 ease-in-out';\n\nconst SHAPE_CLASSES: Record<PillButtonShape, string> = {\n pill: 'rounded-[var(--malachite-radius-10,10px)]',\n tab: 'rounded-b-[var(--malachite-radius-10,10px)] rounded-t-none',\n};\n\n// Box-sizing is border-box, so trading `border-0` for a 1px border only eats into the padding\n// box — it never grows the element past the `h-[...]` each size already fixes. Only one of these\n// ever applies per render, so there's no `border-0`/`border` class collision to referee.\nconst TONE_BORDER_CLASSES: Record<PillButtonTone, string> = {\n default: 'border-0',\n assistant: 'border border-solid border-[var(--malachite-tag-assistant-border)]',\n};\n\nconst ASSISTANT_COLORS =\n 'bg-[var(--malachite-card-background)] text-[var(--malachite-assistant-foreground)]';\n\nconst SIZE_CLASSES: Record<\n PillButtonSize,\n { text: string; padding: string; paddingWithIcon: string }\n> = {\n // For a row that labels other content rather than being read on its own — a context\n // strip above a chat, say. The only size that drops below the 13px the others share.\n xsmall: {\n text: 'text-[length:var(--malachite-font-size-xsmall,11px)] h-[22px] leading-none',\n padding: 'px-2',\n paddingWithIcon: 'pl-1 pr-1.5',\n },\n small: {\n text: 'text-[length:var(--malachite-font-size-small,13px)] h-[var(--malachite-control-height-small,28px)] leading-none',\n padding: 'px-2.5',\n paddingWithIcon: 'pl-1.5 pr-2',\n },\n medium: {\n text: 'text-[length:var(--malachite-font-size-small,13px)] h-[var(--malachite-control-height-medium,32px)] leading-none',\n padding: 'px-2.5',\n paddingWithIcon: 'pl-1.5 pr-2',\n },\n};\n\nconst STATIC_COLORS =\n 'bg-[var(--malachite-pillbutton-static-background)] text-[var(--malachite-pillbutton-static-foreground)]';\n\nconst CLICKABLE_TAIL = 'active:opacity-60 cursor-pointer';\n\nconst VARIANT_COLORS: Record<PillButtonVariant, { base: string; selected: string; hover: string }> =\n {\n default: {\n base: 'bg-[var(--malachite-pillbutton-background)] text-[var(--malachite-pillbutton-foreground)]',\n selected:\n 'bg-[var(--malachite-pillbutton-hover-background)] text-[var(--malachite-pillbutton-hover-foreground)]',\n hover: 'hover:bg-[var(--malachite-pillbutton-hover-background)] hover:text-[var(--malachite-pillbutton-hover-foreground)] active:bg-[var(--malachite-pillbutton-pressed-background)] active:text-[var(--malachite-pillbutton-pressed-foreground)]',\n },\n inverted: {\n base: 'bg-[var(--malachite-pillbutton-inverted-background)] text-[var(--malachite-pillbutton-inverted-foreground)]',\n selected:\n 'bg-[var(--malachite-pillbutton-inverted-hover-background)] text-[var(--malachite-pillbutton-inverted-hover-foreground)]',\n hover: 'hover:bg-[var(--malachite-pillbutton-inverted-hover-background)] hover:text-[var(--malachite-pillbutton-inverted-hover-foreground)] active:bg-[var(--malachite-pillbutton-inverted-pressed-background)] active:text-[var(--malachite-pillbutton-inverted-pressed-foreground)]',\n },\n };\n\nexport const PillButton: React.FC<PillButtonProps> = ({\n label = 'Label',\n icon,\n className = '',\n selected = false,\n disabled = false,\n interactive = true,\n size = 'small',\n variant = 'default',\n shape = 'pill',\n tone = 'default',\n trailingIcon,\n onClick,\n}) => {\n const sizeBlock = SIZE_CLASSES[size];\n const padding = icon ? sizeBlock.paddingWithIcon : sizeBlock.padding;\n const variantBlock = VARIANT_COLORS[variant];\n const isInteractiveLook = interactive && !disabled;\n const isClickable = isInteractiveLook && !!onClick;\n const clickableTail = isClickable ? ` ${CLICKABLE_TAIL}` : '';\n\n let colorClasses: string;\n if (tone === 'assistant') {\n // Assistant chips read the same in every interaction state — the click affordance is\n // the shared `active:opacity-60` from `clickableTail`, not a colour swap.\n colorClasses = isClickable ? `${ASSISTANT_COLORS}${clickableTail}` : ASSISTANT_COLORS;\n } else if (!interactive) {\n colorClasses = STATIC_COLORS;\n } else if (selected) {\n colorClasses = isInteractiveLook\n ? `${variantBlock.selected}${clickableTail}`\n : variantBlock.selected;\n } else if (isInteractiveLook) {\n colorClasses = `${variantBlock.base} ${variantBlock.hover}${clickableTail}`;\n } else {\n colorClasses = variantBlock.base;\n }\n\n const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed pointer-events-none' : '';\n\n const merged = `${BASE_CLASSES} ${SHAPE_CLASSES[shape]} ${sizeBlock.text} ${padding} ${TONE_BORDER_CLASSES[tone]} ${colorClasses} ${disabledClasses} ${className}`;\n\n const iconSlot = icon ? (\n <span className=\"inline-flex items-center justify-center w-4 h-4 shrink-0 [&>img]:max-w-full [&>img]:max-h-full [&>img]:object-contain\">\n {icon}\n </span>\n ) : null;\n\n const trailingSlot = trailingIcon ? (\n <span className=\"inline-flex shrink-0 items-center justify-center\">{trailingIcon}</span>\n ) : null;\n\n if (isClickable) {\n return (\n <button type=\"button\" className={`${FOCUS_RING} ${merged}`} onClick={onClick}>\n {iconSlot}\n {label}\n {trailingSlot}\n </button>\n );\n }\n\n return (\n <div className={merged}>\n {iconSlot}\n {label}\n {trailingSlot}\n </div>\n );\n};\n\nexport default PillButton;\n"],"names":["BASE_CLASSES","SHAPE_CLASSES","TONE_BORDER_CLASSES","ASSISTANT_COLORS","SIZE_CLASSES","STATIC_COLORS","CLICKABLE_TAIL","VARIANT_COLORS","PillButton","label","icon","className","selected","disabled","interactive","size","variant","shape","tone","trailingIcon","onClick","sizeBlock","padding","variantBlock","isInteractiveLook","isClickable","clickableTail","colorClasses","disabledClasses","merged","iconSlot","jsx","trailingSlot","jsxs","FOCUS_RING"],"mappings":";;AAgCA,MAAMA,IACF,qIAEEC,IAAiD;AAAA,EACnD,MAAM;AAAA,EACN,KAAK;AACT,GAKMC,IAAsD;AAAA,EACxD,SAAS;AAAA,EACT,WAAW;AACf,GAEMC,IACF,sFAEEC,IAGF;AAAA;AAAA;AAAA,EAGA,QAAQ;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,iBAAiB;AAAA,EAAA;AAAA,EAErB,OAAO;AAAA,IACH,MAAM;AAAA,IACN,SAAS;AAAA,IACT,iBAAiB;AAAA,EAAA;AAAA,EAErB,QAAQ;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,iBAAiB;AAAA,EAAA;AAEzB,GAEMC,IACF,2GAEEC,IAAiB,oCAEjBC,IACF;AAAA,EACI,SAAS;AAAA,IACL,MAAM;AAAA,IACN,UACI;AAAA,IACJ,OAAO;AAAA,EAAA;AAAA,EAEX,UAAU;AAAA,IACN,MAAM;AAAA,IACN,UACI;AAAA,IACJ,OAAO;AAAA,EAAA;AAEf,GAESC,IAAwC,CAAC;AAAA,EAClD,OAAAC,IAAQ;AAAA,EACR,MAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,aAAAC,IAAc;AAAA,EACd,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,OAAAC,IAAQ;AAAA,EACR,MAAAC,IAAO;AAAA,EACP,cAAAC;AAAA,EACA,SAAAC;AACJ,MAAM;AACF,QAAMC,IAAYjB,EAAaW,CAAI,GAC7BO,IAAUZ,IAAOW,EAAU,kBAAkBA,EAAU,SACvDE,IAAehB,EAAeS,CAAO,GACrCQ,IAAoBV,KAAe,CAACD,GACpCY,IAAcD,KAAqB,CAAC,CAACJ,GACrCM,IAAgBD,IAAc,IAAInB,CAAc,KAAK;AAE3D,MAAIqB;AACJ,EAAIT,MAAS,cAGTS,IAAeF,IAAc,GAAGtB,CAAgB,GAAGuB,CAAa,KAAKvB,IAC7DW,IAEDF,IACPe,IAAeH,IACT,GAAGD,EAAa,QAAQ,GAAGG,CAAa,KACxCH,EAAa,WACZC,IACPG,IAAe,GAAGJ,EAAa,IAAI,IAAIA,EAAa,KAAK,GAAGG,CAAa,KAEzEC,IAAeJ,EAAa,OAR5BI,IAAetB;AAWnB,QAAMuB,IAAkBf,IAAW,sDAAsD,IAEnFgB,IAAS,GAAG7B,CAAY,IAAIC,EAAcgB,CAAK,CAAC,IAAII,EAAU,IAAI,IAAIC,CAAO,IAAIpB,EAAoBgB,CAAI,CAAC,IAAIS,CAAY,IAAIC,CAAe,IAAIjB,CAAS,IAE1JmB,IAAWpB,IACb,gBAAAqB,EAAC,UAAK,WAAU,yHACX,aACL,IACA,MAEEC,IAAeb,IACjB,gBAAAY,EAAC,UAAK,WAAU,oDAAoD,aAAa,IACjF;AAEJ,SAAIN,IAEI,gBAAAQ,EAAC,UAAA,EAAO,MAAK,UAAS,WAAW,GAAGC,CAAU,IAAIL,CAAM,IAAI,SAAAT,GACvD,UAAA;AAAA,IAAAU;AAAA,IACArB;AAAA,IACAuB;AAAA,EAAA,GACL,IAKJ,gBAAAC,EAAC,OAAA,EAAI,WAAWJ,GACX,UAAA;AAAA,IAAAC;AAAA,IACArB;AAAA,IACAuB;AAAA,EAAA,GACL;AAER;"}
|
|
1
|
+
{"version":3,"file":"PillButton.js","sources":["../../src/components/PillButton.tsx"],"sourcesContent":["import React from 'react';\nimport { FOCUS_RING } from './focusRing';\nimport { resolveRel } from './linkRel';\nimport { safeHref } from './safeHref';\n\ntype PillButtonSize = 'xsmall' | 'small' | 'medium';\ntype PillButtonVariant = 'default' | 'inverted';\n/**\n * `tab` squares the top corners so the pill reads as attached to whatever sits above it —\n * a row of controls hanging under an input, rather than free-floating pills.\n */\ntype PillButtonShape = 'pill' | 'tab';\n/**\n * `assistant` is the chrome for AI-authored chips (e.g. `ChangeReview.Jump`): a fixed\n * violet-on-white look with its own border, independent of `variant`/`selected`.\n */\ntype PillButtonTone = 'default' | 'assistant';\n\ninterface PillButtonProps {\n label: string;\n icon?: React.ReactNode;\n className?: string;\n selected?: boolean;\n disabled?: boolean;\n interactive?: boolean;\n size?: PillButtonSize;\n variant?: PillButtonVariant;\n shape?: PillButtonShape;\n tone?: PillButtonTone;\n /** Sits after the label — a caret on a pill that opens a menu. */\n trailingIcon?: React.ReactNode;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Renders the pill as a real anchor, so a link pill keeps cmd-click, copy-link and the status bar. */\n href?: string;\n target?: React.HTMLAttributeAnchorTarget;\n rel?: string;\n}\n\nconst BASE_CLASSES =\n 'inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap shrink-0 transition-colors duration-150 ease-in-out';\n\nconst SHAPE_CLASSES: Record<PillButtonShape, string> = {\n pill: 'rounded-[var(--malachite-radius-10,10px)]',\n tab: 'rounded-b-[var(--malachite-radius-10,10px)] rounded-t-none',\n};\n\n// Box-sizing is border-box, so trading `border-0` for a 1px border only eats into the padding\n// box — it never grows the element past the `h-[...]` each size already fixes. Only one of these\n// ever applies per render, so there's no `border-0`/`border` class collision to referee.\nconst TONE_BORDER_CLASSES: Record<PillButtonTone, string> = {\n default: 'border-0',\n assistant: 'border border-solid border-[var(--malachite-tag-assistant-border)]',\n};\n\nconst ASSISTANT_COLORS =\n 'bg-[var(--malachite-card-background)] text-[var(--malachite-assistant-foreground)]';\n\nconst SIZE_CLASSES: Record<\n PillButtonSize,\n { text: string; padding: string; paddingWithIcon: string }\n> = {\n // For a row that labels other content rather than being read on its own — a context\n // strip above a chat, say. The only size that drops below the 13px the others share.\n xsmall: {\n text: 'text-[length:var(--malachite-font-size-xsmall,11px)] h-[22px] leading-none',\n padding: 'px-2',\n paddingWithIcon: 'pl-1 pr-1.5',\n },\n small: {\n text: 'text-[length:var(--malachite-font-size-small,13px)] h-[var(--malachite-control-height-small,28px)] leading-none',\n padding: 'px-2.5',\n paddingWithIcon: 'pl-1.5 pr-2',\n },\n medium: {\n text: 'text-[length:var(--malachite-font-size-small,13px)] h-[var(--malachite-control-height-medium,32px)] leading-none',\n padding: 'px-2.5',\n paddingWithIcon: 'pl-1.5 pr-2',\n },\n};\n\nconst STATIC_COLORS =\n 'bg-[var(--malachite-pillbutton-static-background)] text-[var(--malachite-pillbutton-static-foreground)]';\n\nconst CLICKABLE_TAIL = 'active:opacity-60 cursor-pointer';\n\nconst VARIANT_COLORS: Record<PillButtonVariant, { base: string; selected: string; hover: string }> =\n {\n default: {\n base: 'bg-[var(--malachite-pillbutton-background)] text-[var(--malachite-pillbutton-foreground)]',\n selected:\n 'bg-[var(--malachite-pillbutton-hover-background)] text-[var(--malachite-pillbutton-hover-foreground)]',\n hover: 'hover:bg-[var(--malachite-pillbutton-hover-background)] hover:text-[var(--malachite-pillbutton-hover-foreground)] active:bg-[var(--malachite-pillbutton-pressed-background)] active:text-[var(--malachite-pillbutton-pressed-foreground)]',\n },\n inverted: {\n base: 'bg-[var(--malachite-pillbutton-inverted-background)] text-[var(--malachite-pillbutton-inverted-foreground)]',\n selected:\n 'bg-[var(--malachite-pillbutton-inverted-hover-background)] text-[var(--malachite-pillbutton-inverted-hover-foreground)]',\n hover: 'hover:bg-[var(--malachite-pillbutton-inverted-hover-background)] hover:text-[var(--malachite-pillbutton-inverted-hover-foreground)] active:bg-[var(--malachite-pillbutton-inverted-pressed-background)] active:text-[var(--malachite-pillbutton-inverted-pressed-foreground)]',\n },\n };\n\nexport const PillButton: React.FC<PillButtonProps> = ({\n label = 'Label',\n icon,\n className = '',\n selected = false,\n disabled = false,\n interactive = true,\n size = 'small',\n variant = 'default',\n shape = 'pill',\n tone = 'default',\n trailingIcon,\n onClick,\n href,\n target,\n rel,\n}) => {\n const sizeBlock = SIZE_CLASSES[size];\n const padding = icon ? sizeBlock.paddingWithIcon : sizeBlock.padding;\n const variantBlock = VARIANT_COLORS[variant];\n const isInteractiveLook = interactive && !disabled;\n // A rejected href (e.g. `javascript:`) takes the button or static path, never an anchor.\n const linkHref = safeHref(href);\n const isClickable = isInteractiveLook && (!!onClick || !!linkHref);\n const clickableTail = isClickable ? ` ${CLICKABLE_TAIL}` : '';\n\n let colorClasses: string;\n if (tone === 'assistant') {\n // Assistant chips read the same in every interaction state — the click affordance is\n // the shared `active:opacity-60` from `clickableTail`, not a colour swap.\n colorClasses = isClickable ? `${ASSISTANT_COLORS}${clickableTail}` : ASSISTANT_COLORS;\n } else if (!interactive) {\n colorClasses = STATIC_COLORS;\n } else if (selected) {\n colorClasses = isInteractiveLook\n ? `${variantBlock.selected}${clickableTail}`\n : variantBlock.selected;\n } else if (isInteractiveLook) {\n colorClasses = `${variantBlock.base} ${variantBlock.hover}${clickableTail}`;\n } else {\n colorClasses = variantBlock.base;\n }\n\n const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed pointer-events-none' : '';\n\n const merged = `${BASE_CLASSES} ${SHAPE_CLASSES[shape]} ${sizeBlock.text} ${padding} ${TONE_BORDER_CLASSES[tone]} ${colorClasses} ${disabledClasses} ${className}`;\n\n const iconSlot = icon ? (\n <span className=\"inline-flex items-center justify-center w-4 h-4 shrink-0 [&>img]:max-w-full [&>img]:max-h-full [&>img]:object-contain\">\n {icon}\n </span>\n ) : null;\n\n const trailingSlot = trailingIcon ? (\n <span className=\"inline-flex shrink-0 items-center justify-center\">{trailingIcon}</span>\n ) : null;\n\n // An anchor cannot be disabled, so a disabled link pill falls through to the static one.\n if (isClickable && linkHref) {\n return (\n <a\n href={linkHref}\n target={target}\n rel={resolveRel(rel, target)}\n className={`${FOCUS_RING} ${merged} no-underline`}\n onClick={onClick}\n >\n {iconSlot}\n {label}\n {trailingSlot}\n </a>\n );\n }\n\n if (isClickable) {\n return (\n <button type=\"button\" className={`${FOCUS_RING} ${merged}`} onClick={onClick}>\n {iconSlot}\n {label}\n {trailingSlot}\n </button>\n );\n }\n\n return (\n <div className={merged}>\n {iconSlot}\n {label}\n {trailingSlot}\n </div>\n );\n};\n\nexport default PillButton;\n"],"names":["BASE_CLASSES","SHAPE_CLASSES","TONE_BORDER_CLASSES","ASSISTANT_COLORS","SIZE_CLASSES","STATIC_COLORS","CLICKABLE_TAIL","VARIANT_COLORS","PillButton","label","icon","className","selected","disabled","interactive","size","variant","shape","tone","trailingIcon","onClick","href","target","rel","sizeBlock","padding","variantBlock","isInteractiveLook","linkHref","safeHref","isClickable","clickableTail","colorClasses","disabledClasses","merged","iconSlot","jsx","trailingSlot","jsxs","resolveRel","FOCUS_RING"],"mappings":"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"}
|
|
@@ -1,77 +1,81 @@
|
|
|
1
|
-
import { jsx as o, jsxs as
|
|
2
|
-
import
|
|
3
|
-
import { paintOnChild as
|
|
4
|
-
import { DisclosureArrow as
|
|
5
|
-
import { FOCUS_RING_INSET as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
1
|
+
import { jsx as o, jsxs as w } from "react/jsx-runtime";
|
|
2
|
+
import G from "react";
|
|
3
|
+
import { paintOnChild as P } from "./asChild.js";
|
|
4
|
+
import { DisclosureArrow as U } from "./DisclosureArrow.js";
|
|
5
|
+
import { FOCUS_RING_INSET as D } from "./focusRing.js";
|
|
6
|
+
import { resolveRel as $ } from "./linkRel.js";
|
|
7
|
+
import { safeHref as W } from "./safeHref.js";
|
|
8
|
+
import { isRenderableNode as X } from "./renderableNode.js";
|
|
9
|
+
import { FOREGROUND_RESET as H, SELECTED_TEXT_CONTEXT as z, SELECTED_ROW_ACCENT as K, SELECTED_ROW_FOREGROUND as q, SELECTED_ROW_BACKGROUND as T } from "./selectedRow.js";
|
|
10
|
+
const J = {
|
|
9
11
|
default: "",
|
|
10
12
|
muted: "bg-[var(--malachite-card-dimmed-background)]",
|
|
11
13
|
success: "bg-[var(--malachite-tag-success-background)]",
|
|
12
14
|
error: "bg-[var(--malachite-tag-error-background)]"
|
|
13
|
-
},
|
|
15
|
+
}, M = {
|
|
14
16
|
success: "var(--malachite-tag-success-foreground)",
|
|
15
17
|
error: "var(--malachite-tag-error-foreground)"
|
|
16
|
-
},
|
|
18
|
+
}, Q = "0px 0px 4px 0px rgba(0,0,0,0.08), 0px 4px 4px 0px rgba(0,0,0,0.08), 0px 4px 10px 0px rgba(0,0,0,0.05)", L = (t) => {
|
|
17
19
|
const {
|
|
18
20
|
children: a,
|
|
19
21
|
divider: r = !1,
|
|
20
22
|
disabled: e = !1,
|
|
21
|
-
selected:
|
|
22
|
-
selection:
|
|
23
|
+
selected: s,
|
|
24
|
+
selection: b,
|
|
23
25
|
tone: c = "default",
|
|
24
|
-
className:
|
|
26
|
+
className: u = "",
|
|
25
27
|
style: g
|
|
26
|
-
} = t, d = t.asChild === !0, { onClick:
|
|
28
|
+
} = t, d = t.asChild === !0, { onClick: l, href: E, target: i, rel: C, trailing: S, role: n } = d ? {} : t, f = W(E), p = d ? void 0 : t["aria-label"], h = d ? void 0 : t["aria-labelledby"], N = !!(l || f), B = e && (N || d) ? "" : "transition-colors hover:bg-[var(--malachite-buttonlist-hover-background)]", j = c !== "default", _ = [
|
|
27
29
|
"w-full text-left border-0",
|
|
28
|
-
|
|
30
|
+
J[c],
|
|
29
31
|
r ? "border-b border-solid border-[var(--malachite-card-border)]" : "",
|
|
30
|
-
|
|
31
|
-
].filter(Boolean).join(" "),
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
].filter(Boolean).join(" "),
|
|
35
|
-
backgroundImage: `linear-gradient(${
|
|
36
|
-
color:
|
|
37
|
-
boxShadow: `inset 2px 0 0 ${
|
|
38
|
-
...
|
|
39
|
-
} : {},
|
|
40
|
-
color:
|
|
41
|
-
"--malachite-ctx-text-primary":
|
|
42
|
-
} : {}, ...
|
|
43
|
-
role:
|
|
44
|
-
"aria-checked":
|
|
32
|
+
B
|
|
33
|
+
].filter(Boolean).join(" "), k = [
|
|
34
|
+
N ? `appearance-none ${j ? "" : "bg-transparent"} p-0 ${D}` : "",
|
|
35
|
+
N && !e ? "cursor-pointer" : ""
|
|
36
|
+
].filter(Boolean).join(" "), y = [_, k, u].filter(Boolean).join(" "), F = s && (b ? b === "highlight" : n !== "checkbox") ? {
|
|
37
|
+
backgroundImage: `linear-gradient(${T}, ${T})`,
|
|
38
|
+
color: q,
|
|
39
|
+
boxShadow: `inset 2px 0 0 ${K}`,
|
|
40
|
+
...z
|
|
41
|
+
} : {}, R = M[c], x = { ...R ? {
|
|
42
|
+
color: R,
|
|
43
|
+
"--malachite-ctx-text-primary": R
|
|
44
|
+
} : {}, ...F, ...g }, m = n === "radio" || n === "checkbox" ? !!s : void 0, v = m === void 0 && s ? !0 : void 0, O = {
|
|
45
|
+
role: n,
|
|
46
|
+
"aria-checked": m,
|
|
45
47
|
"aria-current": v,
|
|
46
48
|
"aria-label": p,
|
|
47
49
|
"aria-labelledby": h,
|
|
48
|
-
"aria-disabled":
|
|
50
|
+
"aria-disabled": n && e ? !0 : void 0
|
|
49
51
|
};
|
|
50
52
|
if (d)
|
|
51
|
-
return
|
|
52
|
-
if (
|
|
53
|
-
const
|
|
53
|
+
return P(a, y, x);
|
|
54
|
+
if (X(S)) {
|
|
55
|
+
const I = f && !e ? /* @__PURE__ */ o(
|
|
54
56
|
"a",
|
|
55
57
|
{
|
|
56
|
-
href:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
href: f,
|
|
59
|
+
target: i,
|
|
60
|
+
rel: $(C, i),
|
|
61
|
+
onClick: l,
|
|
62
|
+
className: `${k} border-0 flex-1 min-w-0 text-left no-underline text-inherit`,
|
|
63
|
+
role: n,
|
|
64
|
+
"aria-checked": m,
|
|
61
65
|
"aria-current": v,
|
|
62
66
|
"aria-label": p,
|
|
63
67
|
"aria-labelledby": h,
|
|
64
68
|
children: a
|
|
65
69
|
}
|
|
66
|
-
) :
|
|
70
|
+
) : l ? /* @__PURE__ */ o(
|
|
67
71
|
"button",
|
|
68
72
|
{
|
|
69
73
|
type: "button",
|
|
70
|
-
onClick:
|
|
74
|
+
onClick: l,
|
|
71
75
|
disabled: e,
|
|
72
|
-
className: `${
|
|
73
|
-
role:
|
|
74
|
-
"aria-checked":
|
|
76
|
+
className: `${k} border-0 flex-1 min-w-0 text-left`,
|
|
77
|
+
role: n,
|
|
78
|
+
"aria-checked": m,
|
|
75
79
|
"aria-current": v,
|
|
76
80
|
"aria-label": p,
|
|
77
81
|
"aria-labelledby": h,
|
|
@@ -80,123 +84,125 @@ const X = {
|
|
|
80
84
|
) : (
|
|
81
85
|
// The set goes here, not on the wrapper: `radio` and `checkbox` make their
|
|
82
86
|
// descendants presentational, which would bury a control in the trailing slot.
|
|
83
|
-
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", ...
|
|
87
|
+
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", ...O, children: a })
|
|
84
88
|
);
|
|
85
|
-
return /* @__PURE__ */
|
|
89
|
+
return /* @__PURE__ */ w(
|
|
86
90
|
"div",
|
|
87
91
|
{
|
|
88
|
-
className: [
|
|
92
|
+
className: [_, "flex items-center", u].filter(Boolean).join(" "),
|
|
89
93
|
style: x,
|
|
90
94
|
children: [
|
|
91
|
-
|
|
92
|
-
/* @__PURE__ */ o("div", { className: "shrink-0 flex items-center", children:
|
|
95
|
+
I,
|
|
96
|
+
/* @__PURE__ */ o("div", { className: "shrink-0 flex items-center", children: S })
|
|
93
97
|
]
|
|
94
98
|
}
|
|
95
99
|
);
|
|
96
100
|
}
|
|
97
|
-
return
|
|
101
|
+
return f && !e ? /* @__PURE__ */ o(
|
|
98
102
|
"a",
|
|
99
103
|
{
|
|
100
|
-
href:
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
href: f,
|
|
105
|
+
target: i,
|
|
106
|
+
rel: $(C, i),
|
|
107
|
+
onClick: l,
|
|
108
|
+
className: `${y} no-underline text-inherit`,
|
|
103
109
|
style: x,
|
|
104
|
-
role:
|
|
105
|
-
"aria-checked":
|
|
110
|
+
role: n,
|
|
111
|
+
"aria-checked": m,
|
|
106
112
|
"aria-current": v,
|
|
107
113
|
"aria-label": p,
|
|
108
114
|
"aria-labelledby": h,
|
|
109
115
|
children: a
|
|
110
116
|
}
|
|
111
|
-
) :
|
|
117
|
+
) : l ? /* @__PURE__ */ o(
|
|
112
118
|
"button",
|
|
113
119
|
{
|
|
114
120
|
type: "button",
|
|
115
|
-
onClick:
|
|
121
|
+
onClick: l,
|
|
116
122
|
disabled: e,
|
|
117
|
-
className:
|
|
123
|
+
className: y,
|
|
118
124
|
style: x,
|
|
119
|
-
role:
|
|
120
|
-
"aria-checked":
|
|
125
|
+
role: n,
|
|
126
|
+
"aria-checked": m,
|
|
121
127
|
"aria-current": v,
|
|
122
128
|
"aria-label": p,
|
|
123
129
|
"aria-labelledby": h,
|
|
124
130
|
children: a
|
|
125
131
|
}
|
|
126
|
-
) : /* @__PURE__ */ o("div", { className:
|
|
127
|
-
},
|
|
132
|
+
) : /* @__PURE__ */ o("div", { className: y, style: x, ...O, children: a });
|
|
133
|
+
}, V = ({ children: t, className: a = "", style: r }) => /* @__PURE__ */ o("div", { className: a, style: r, onClick: (e) => e.stopPropagation(), children: t }), be = 39, Y = Object.assign(
|
|
128
134
|
({
|
|
129
135
|
header: t,
|
|
130
136
|
children: a,
|
|
131
137
|
expanded: r,
|
|
132
138
|
onToggle: e,
|
|
133
|
-
sticky:
|
|
134
|
-
stickyTopOffset:
|
|
139
|
+
sticky: s = !1,
|
|
140
|
+
stickyTopOffset: b = 0,
|
|
135
141
|
divider: c = !1,
|
|
136
|
-
tone:
|
|
142
|
+
tone: u = "default",
|
|
137
143
|
"aria-label": g,
|
|
138
144
|
className: d = "",
|
|
139
|
-
style:
|
|
145
|
+
style: l
|
|
140
146
|
}) => {
|
|
141
|
-
const
|
|
142
|
-
return /* @__PURE__ */
|
|
143
|
-
/* @__PURE__ */
|
|
147
|
+
const E = G.useId(), i = e ? () => e(!r) : void 0;
|
|
148
|
+
return /* @__PURE__ */ w(L, { divider: c, tone: u, className: d, style: l, children: [
|
|
149
|
+
/* @__PURE__ */ w(
|
|
144
150
|
"div",
|
|
145
151
|
{
|
|
146
|
-
className: `group flex items-center w-full ${
|
|
147
|
-
style:
|
|
148
|
-
onClick:
|
|
152
|
+
className: `group flex items-center w-full ${i ? "cursor-pointer" : ""} ${s && r ? "sticky z-[1] bg-[var(--malachite-card-background)]" : ""}`,
|
|
153
|
+
style: s && r ? { top: b } : void 0,
|
|
154
|
+
onClick: i,
|
|
149
155
|
role: "presentation",
|
|
150
156
|
children: [
|
|
151
|
-
/* @__PURE__ */ o("span", { className: "shrink-0 flex items-center pl-[16px] pr-[12px]", children:
|
|
157
|
+
/* @__PURE__ */ o("span", { className: "shrink-0 flex items-center pl-[16px] pr-[12px]", children: i && /* @__PURE__ */ o(
|
|
152
158
|
"button",
|
|
153
159
|
{
|
|
154
160
|
type: "button",
|
|
155
|
-
className: `appearance-none bg-transparent border-0 p-0 flex items-center cursor-pointer ${
|
|
161
|
+
className: `appearance-none bg-transparent border-0 p-0 flex items-center cursor-pointer ${D}`,
|
|
156
162
|
"aria-expanded": r,
|
|
157
|
-
"aria-controls":
|
|
163
|
+
"aria-controls": E,
|
|
158
164
|
"aria-label": g,
|
|
159
|
-
onClick: (
|
|
160
|
-
|
|
165
|
+
onClick: (C) => {
|
|
166
|
+
C.stopPropagation(), i();
|
|
161
167
|
},
|
|
162
|
-
children: /* @__PURE__ */ o(
|
|
168
|
+
children: /* @__PURE__ */ o(U, { expanded: r })
|
|
163
169
|
}
|
|
164
170
|
) }),
|
|
165
171
|
t
|
|
166
172
|
]
|
|
167
173
|
}
|
|
168
174
|
),
|
|
169
|
-
r && /* @__PURE__ */ o("div", { id:
|
|
175
|
+
r && /* @__PURE__ */ o("div", { id: E, children: a })
|
|
170
176
|
] });
|
|
171
177
|
},
|
|
172
|
-
{ Controls:
|
|
173
|
-
),
|
|
178
|
+
{ Controls: V }
|
|
179
|
+
), A = ({
|
|
174
180
|
children: t,
|
|
175
181
|
padding: a = !1,
|
|
176
182
|
overflow: r = "hidden",
|
|
177
183
|
role: e,
|
|
178
|
-
"aria-label":
|
|
179
|
-
"aria-labelledby":
|
|
184
|
+
"aria-label": s,
|
|
185
|
+
"aria-labelledby": b,
|
|
180
186
|
className: c = "",
|
|
181
|
-
style:
|
|
187
|
+
style: u
|
|
182
188
|
}) => /* @__PURE__ */ o(
|
|
183
189
|
"div",
|
|
184
190
|
{
|
|
185
191
|
className: `w-full rounded-[var(--malachite-radius-xxl,14px)] ${r === "clip" ? "overflow-clip" : r === "visible" ? "overflow-visible" : "overflow-hidden"} bg-[var(--malachite-card-background)] border border-solid border-[var(--malachite-card-border)] ${a ? "py-3 px-4" : ""} ${c}`,
|
|
186
|
-
style: { boxShadow:
|
|
192
|
+
style: { boxShadow: Q, ...H, ...u },
|
|
187
193
|
role: e,
|
|
188
|
-
"aria-label":
|
|
189
|
-
"aria-labelledby":
|
|
194
|
+
"aria-label": s,
|
|
195
|
+
"aria-labelledby": b,
|
|
190
196
|
children: t
|
|
191
197
|
}
|
|
192
198
|
);
|
|
193
|
-
|
|
194
|
-
|
|
199
|
+
A.Row = L;
|
|
200
|
+
A.ExpandableRow = Y;
|
|
195
201
|
export {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
202
|
+
be as EXPANDABLE_ROW_LEAD_PX,
|
|
203
|
+
A as Surface,
|
|
204
|
+
Y as SurfaceExpandableRow,
|
|
205
|
+
L as SurfaceRow,
|
|
206
|
+
A as default
|
|
201
207
|
};
|
|
202
208
|
//# sourceMappingURL=Surface.js.map
|