UNPKG

@helpwave/hightide

Version:

helpwave's component and theming library

585 lines (571 loc) 17.5 kB
// src/components/properties/CheckboxProperty.tsx import { Check as Check2 } from "lucide-react"; // src/util/noop.ts var noop = () => void 0; // src/components/user-action/Checkbox.tsx import { useState } from "react"; import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; import { Check, Minus } from "lucide-react"; import clsx2 from "clsx"; // src/components/user-action/Label.tsx import clsx from "clsx"; import { jsx } from "react/jsx-runtime"; var styleMapping = { labelSmall: "textstyle-label-sm", labelMedium: "textstyle-label-md", labelBig: "textstyle-label-lg" }; var Label = ({ children, name, labelType = "labelSmall", className, ...props }) => { return /* @__PURE__ */ jsx("label", { ...props, className: clsx(styleMapping[labelType], className), children: children ? children : name }); }; // src/components/user-action/Checkbox.tsx import { jsx as jsx2, jsxs } from "react/jsx-runtime"; var checkboxSizeMapping = { small: "size-5", medium: "size-6", large: "size-8" }; var checkboxIconSizeMapping = { small: "size-4", medium: "size-5", large: "size-7" }; var Checkbox = ({ id, label, checked, disabled, onChange, onChangeTristate, size = "medium", className = "", containerClassName }) => { const usedSizeClass = checkboxSizeMapping[size]; const innerIconSize = checkboxIconSizeMapping[size]; const propagateChange = (checked2) => { if (onChangeTristate) { onChangeTristate(checked2); } if (onChange) { onChange(checked2 === "indeterminate" ? false : checked2); } }; const changeValue = () => { if (disabled) { return; } const newValue = checked === "indeterminate" ? false : !checked; propagateChange(newValue); }; return /* @__PURE__ */ jsxs( "div", { className: clsx2("group flex-row-2 items-center", { "cursor-pointer": !disabled, "cursor-not-allowed": disabled }, containerClassName), onClick: changeValue, children: [ /* @__PURE__ */ jsx2( CheckboxPrimitive.Root, { onCheckedChange: propagateChange, checked, disabled, id, className: clsx2(usedSizeClass, `items-center border-2 rounded outline-none `, { "text-disabled-text border-disabled-outline bg-disabled-background cursor-not-allowed": disabled, "focus:border-primary group-hover:border-primary ": !disabled, "bg-input-background": !disabled && !checked, "bg-primary/30 border-primary text-primary": !disabled && checked === true || checked === "indeterminate" }, className), children: /* @__PURE__ */ jsxs(CheckboxPrimitive.Indicator, { children: [ checked === true && /* @__PURE__ */ jsx2(Check, { className: innerIconSize }), checked === "indeterminate" && /* @__PURE__ */ jsx2(Minus, { className: innerIconSize }) ] }) } ), label && /* @__PURE__ */ jsx2( Label, { ...label, className: clsx2( label.className, { "cursor-pointer": !disabled, "cursor-not-allowed": disabled } ), htmlFor: id } ) ] } ); }; // src/localization/LanguageProvider.tsx import { createContext, useContext, useEffect, useState as useState3 } from "react"; // src/hooks/useLocalStorage.ts import { useCallback, useState as useState2 } from "react"; // src/localization/util.ts var languages = ["en", "de"]; var languagesLocalNames = { en: "English", de: "Deutsch" }; var DEFAULT_LANGUAGE = "en"; var LanguageUtil = { languages, DEFAULT_LANGUAGE, languagesLocalNames }; // src/localization/LanguageProvider.tsx import { jsx as jsx3 } from "react/jsx-runtime"; var LanguageContext = createContext({ language: LanguageUtil.DEFAULT_LANGUAGE, setLanguage: (v) => v }); var useLanguage = () => useContext(LanguageContext); // src/localization/useTranslation.ts var TranslationPluralCount = { zero: 0, one: 1, two: 2, few: 3, many: 11, other: -1 }; var useTranslation = (translations, overwriteTranslation = {}) => { const { language: languageProp, translation: overwrite } = overwriteTranslation; const { language: inferredLanguage } = useLanguage(); const usedLanguage = languageProp ?? inferredLanguage; const usedTranslations = [...translations]; if (overwrite) { usedTranslations.push(overwrite); } return (key, options) => { const { count, replacements } = { ...{ count: 0, replacements: {} }, ...options }; try { for (let i = translations.length - 1; i >= 0; i--) { const translation = translations[i]; const localizedTranslation = translation[usedLanguage]; if (!localizedTranslation) { continue; } const value = localizedTranslation[key]; if (!value) { continue; } let forProcessing; if (typeof value !== "string") { if (count === TranslationPluralCount.zero && value?.zero) { forProcessing = value.zero; } else if (count === TranslationPluralCount.one && value?.one) { forProcessing = value.one; } else if (count === TranslationPluralCount.two && value?.two) { forProcessing = value.two; } else if (TranslationPluralCount.few <= count && count < TranslationPluralCount.many && value?.few) { forProcessing = value.few; } else if (count > TranslationPluralCount.many && value?.many) { forProcessing = value.many; } else { forProcessing = value.other; } } else { forProcessing = value; } forProcessing = forProcessing.replace(/\{\{(\w+)}}/g, (_, placeholder) => { return replacements[placeholder] ?? `{{key:${placeholder}}}`; }); return forProcessing; } } catch (e) { console.error(e); } return `{{${usedLanguage}:${key}}}`; }; }; // src/components/properties/PropertyBase.tsx import { AlertTriangle } from "lucide-react"; import clsx4 from "clsx"; // src/components/user-action/Button.tsx import { forwardRef } from "react"; import clsx3 from "clsx"; import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime"; var ButtonColorUtil = { solid: ["primary", "secondary", "tertiary", "positive", "warning", "negative", "neutral"], text: ["primary", "negative", "neutral"], outline: ["primary"] }; var IconButtonUtil = { icon: [...ButtonColorUtil.solid, "transparent"] }; var paddingMapping = { small: "btn-sm", medium: "btn-md", large: "btn-lg" }; var iconPaddingMapping = { tiny: "icon-btn-xs", small: "icon-btn-sm", medium: "icon-btn-md", large: "icon-btn-lg" }; var ButtonUtil = { paddingMapping, iconPaddingMapping }; var SolidButton = forwardRef(function SolidButton2({ children, color = "primary", size = "medium", startIcon, endIcon, onClick, className, ...restProps }, ref) { const colorClasses = { primary: "not-disabled:bg-button-solid-primary-background not-disabled:text-button-solid-primary-text", secondary: "not-disabled:bg-button-solid-secondary-background not-disabled:text-button-solid-secondary-text", tertiary: "not-disabled:bg-button-solid-tertiary-background not-disabled:text-button-solid-tertiary-text", positive: "not-disabled:bg-button-solid-positive-background not-disabled:text-button-solid-positive-text", warning: "not-disabled:bg-button-solid-warning-background not-disabled:text-button-solid-warning-text", negative: "not-disabled:bg-button-solid-negative-background not-disabled:text-button-solid-negative-text", neutral: "not-disabled:bg-button-solid-neutral-background not-disabled:text-button-solid-neutral-text" }[color]; const iconColorClasses = { primary: "not-group-disabled:text-button-solid-primary-icon", secondary: "not-group-disabled:text-button-solid-secondary-icon", tertiary: "not-group-disabled:text-button-solid-tertiary-icon", positive: "not-group-disabled:text-button-solid-positive-icon", warning: "not-group-disabled:text-button-solid-warning-icon", negative: "not-group-disabled:text-button-solid-negative-icon", neutral: "not-group-disabled:text-button-solid-neutral-icon" }[color]; return /* @__PURE__ */ jsxs2( "button", { ref, onClick, className: clsx3( "group font-semibold", colorClasses, "not-disabled:hover:brightness-90", "disabled:text-disabled-text disabled:bg-disabled-background", ButtonUtil.paddingMapping[size], className ), ...restProps, children: [ startIcon && /* @__PURE__ */ jsx4( "span", { className: clsx3( iconColorClasses, "group-disabled:text-disabled-icon" ), children: startIcon } ), children, endIcon && /* @__PURE__ */ jsx4( "span", { className: clsx3( iconColorClasses, "group-disabled:text-disabled-icon" ), children: endIcon } ) ] } ); }); var TextButton = ({ children, color = "neutral", size = "medium", startIcon, endIcon, onClick, coloredHoverBackground = true, className, ...restProps }) => { const colorClasses = { primary: "not-disabled:bg-transparent not-disabled:text-button-text-primary-text", negative: "not-disabled:bg-transparent not-disabled:text-button-text-negative-text", neutral: "not-disabled:bg-transparent not-disabled:text-button-text-neutral-text" }[color]; const backgroundColor = { primary: "not-disabled:hover:bg-button-text-primary-text/20", negative: "not-disabled:hover:bg-button-text-negative-text/20", neutral: "not-disabled:hover:bg-button-text-neutral-text/20" }[color]; const iconColorClasses = { primary: "not-group-disabled:text-button-text-primary-icon", negative: "not-group-disabled:text-button-text-negative-icon", neutral: "not-group-disabled:text-button-text-neutral-icon" }[color]; return /* @__PURE__ */ jsxs2( "button", { onClick, className: clsx3( "group font-semibold", "disabled:text-disabled-text", colorClasses, { [backgroundColor]: coloredHoverBackground, "not-disabled:hover:bg-button-text-hover-background": !coloredHoverBackground }, ButtonUtil.paddingMapping[size], className ), ...restProps, children: [ startIcon && /* @__PURE__ */ jsx4( "span", { className: clsx3( iconColorClasses, "group-disabled:text-disabled-icon" ), children: startIcon } ), children, endIcon && /* @__PURE__ */ jsx4( "span", { className: clsx3( iconColorClasses, "group-disabled:text-disabled-icon" ), children: endIcon } ) ] } ); }; // src/localization/defaults/form.ts var formTranslation = { en: { add: "Add", all: "All", apply: "Apply", back: "Back", cancel: "Cancel", change: "Change", clear: "Clear", click: "Click", clickToCopy: "Click to Copy", close: "Close", confirm: "Confirm", copy: "Copy", copied: "Copied", create: "Create", decline: "Decline", delete: "Delete", discard: "Discard", discardChanges: "Discard Changes", done: "Done", edit: "Edit", enterText: "Enter text here", error: "Error", exit: "Exit", fieldRequiredError: "This field is required.", invalidEmailError: "Please enter a valid email address.", less: "Less", loading: "Loading", maxLengthError: "Maximum length exceeded.", minLengthError: "Minimum length not met.", more: "More", next: "Next", no: "No", none: "None", of: "of", optional: "Optional", pleaseWait: "Please wait...", previous: "Previous", remove: "Remove", required: "Required", reset: "Reset", save: "Save", saved: "Saved", search: "Search", select: "Select", selectOption: "Select an option", show: "Show", showMore: "Show more", showLess: "Show less", submit: "Submit", success: "Success", update: "Update", unsavedChanges: "Unsaved Changes", unsavedChangesSaveQuestion: "Do you want to save your changes?", yes: "Yes" }, de: { add: "Hinzuf\xFCgen", all: "Alle", apply: "Anwenden", back: "Zur\xFCck", cancel: "Abbrechen", change: "\xC4ndern", clear: "L\xF6schen", click: "Klicken", clickToCopy: "Zum kopieren klicken", close: "Schlie\xDFen", confirm: "Best\xE4tigen", copy: "Kopieren", copied: "Kopiert", create: "Erstellen", decline: "Ablehnen", delete: "L\xF6schen", discard: "Verwerfen", discardChanges: "\xC4nderungen Verwerfen", done: "Fertig", edit: "Bearbeiten", enterText: "Text hier eingeben", error: "Fehler", exit: "Beenden", fieldRequiredError: "Dieses Feld ist erforderlich.", invalidEmailError: "Bitte geben Sie eine g\xFCltige E-Mail-Adresse ein.", less: "Weniger", loading: "L\xE4dt", maxLengthError: "Maximale L\xE4nge \xFCberschritten.", minLengthError: "Mindestl\xE4nge nicht erreicht.", more: "Mehr", next: "Weiter", no: "Nein", none: "Nichts", of: "von", optional: "Optional", pleaseWait: "Bitte warten...", previous: "Vorherige", remove: "Entfernen", required: "Erforderlich", reset: "Zur\xFCcksetzen", save: "Speichern", saved: "Gespeichert", search: "Suche", select: "Select", selectOption: "Option ausw\xE4hlen", show: "Anzeigen", showMore: "Mehr anzeigen", showLess: "Weniger anzeigen", submit: "Abschicken", success: "Erfolg", update: "Update", unsavedChanges: "Ungespeicherte \xC4nderungen", unsavedChangesSaveQuestion: "M\xF6chtest du die \xC4nderungen speichern?", yes: "Ja" } }; // src/components/properties/PropertyBase.tsx import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime"; var PropertyBase = ({ overwriteTranslation, name, input, softRequired = false, hasValue, icon, readOnly, onRemove, className = "" }) => { const translation = useTranslation([formTranslation], overwriteTranslation); const requiredAndNoValue = softRequired && !hasValue; return /* @__PURE__ */ jsxs3("div", { className: clsx4("flex-row-0 group", className), children: [ /* @__PURE__ */ jsxs3( "div", { className: clsx4( "flex-row-2 max-w-48 min-w-48 px-3 py-2 items-center rounded-l-xl border-2 border-r-0", { "bg-property-title-background text-property-title-text group-hover:border-primary": !requiredAndNoValue, "bg-warning text-surface-warning group-hover:border-warning border-warning/90": requiredAndNoValue }, className ), children: [ /* @__PURE__ */ jsx5("div", { className: "max-w-6 min-w-6 text-text-primary", children: icon }), /* @__PURE__ */ jsx5("span", { className: "font-semibold", children: name }) ] } ), /* @__PURE__ */ jsxs3( "div", { className: clsx4( "flex-row-2 grow px-3 py-2 justify-between items-center rounded-r-xl border-2 border-l-0 min-h-15", { "bg-input-background text-input-text group-hover:border-primary": !requiredAndNoValue, "bg-surface-warning group-hover:border-warning border-warning/90": requiredAndNoValue }, className ), children: [ input({ softRequired, hasValue }), requiredAndNoValue && /* @__PURE__ */ jsx5("div", { className: "text-warning", children: /* @__PURE__ */ jsx5(AlertTriangle, { size: 24 }) }), onRemove && hasValue && /* @__PURE__ */ jsx5( TextButton, { onClick: onRemove, color: "negative", className: clsx4("items-center", { "!text-transparent": !hasValue || readOnly }), disabled: !hasValue || readOnly, children: translation("remove") } ) ] } ) ] }); }; // src/components/properties/CheckboxProperty.tsx import { jsx as jsx6 } from "react/jsx-runtime"; var CheckboxProperty = ({ overwriteTranslation, value, onChange = noop, readOnly, ...baseProps }) => { const translation = useTranslation([formTranslation], overwriteTranslation); return /* @__PURE__ */ jsx6( PropertyBase, { ...baseProps, hasValue: true, readOnly, icon: /* @__PURE__ */ jsx6(Check2, { size: 24 }), input: () => /* @__PURE__ */ jsx6( Checkbox, { checked: value ?? true, disabled: readOnly, onChange, label: { name: `${translation("yes")}/${translation("no")}`, labelType: "labelMedium" }, containerClassName: "w-full" } ) } ); }; export { CheckboxProperty }; //# sourceMappingURL=CheckboxProperty.mjs.map