@chayns-ui/core 0.5.0 → 0.6.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.
@@ -12,13 +12,13 @@ export type ButtonVariant = 'primary' | 'outline' | 'ghost' | 'danger';
12
12
  */
13
13
  export declare const BUTTON_VARIANTS: readonly ["primary", "outline", "ghost", "danger"];
14
14
  /**
15
- * @description A FontAwesome Classic icon name in its Regular form (e.g.
16
- * `fa-plus`). Button and IconButton resolve the matching Solid weight
17
- * internally and cross-fade between the two on hover/active; consumers must
18
- * not pass a pre-resolved weight and must supply a name that has both a
19
- * Regular and a Solid glyph available.
15
+ * @description A FontAwesome Classic icon name (e.g. `fa-plus`) or a
16
+ * FontAwesome Brands icon including its style prefix (e.g. `fab fa-github`).
17
+ * Classic icons resolve the matching Regular and Solid weights internally;
18
+ * Brands icons are rendered as a single icon and must not be combined with
19
+ * `far` or `fas`.
20
20
  */
21
- export type ButtonIcon = `fa-${string}`;
21
+ export type ButtonIcon = `fa-${string}` | `fab fa-${string}`;
22
22
  /**
23
23
  * @description Visible content that gives a `Button` its accessible name.
24
24
  * Excludes `boolean`, `null` and `undefined` so a `Button` can never be
@@ -39,9 +39,9 @@ export interface ButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'chil
39
39
  */
40
40
  variant: ButtonVariant;
41
41
  /**
42
- * @description Optional leading FontAwesome Classic icon name. Always
43
- * rendered before `children`; there is no trailing-icon or icon-only mode
44
- * on `Button` itself — use `IconButton` for an icon-only action.
42
+ * @description Optional leading FontAwesome Classic or Brands icon name.
43
+ * Always rendered before `children`; there is no trailing-icon or icon-only
44
+ * mode on `Button` itself — use `IconButton` for an icon-only action.
45
45
  */
46
46
  icon?: ButtonIcon;
47
47
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/components/button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,eAAe,oDAKiB,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,MAAM,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACpF;;;;;OAKG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;;OAIG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB"}
1
+ {"version":3,"file":"Button.types.d.ts","sourceRoot":"","sources":["../../../src/components/button/Button.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,eAAe,oDAKiB,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,MAAM,EAAE,GAAG,UAAU,MAAM,EAAE,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACpF;;;;;OAKG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;;;OAIG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Button.types.js","names":[],"sources":["../../../src/components/button/Button.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from 'react';\n\n/**\n * @description Supported visual emphasis levels for {@link ButtonProps} and\n * `IconButtonProps`. Milestone 1 supports exactly these four values; there is\n * no default variant and no fifth value.\n * @see {@link https://tappqa.tobit.com/Bodywork/DesignSystem/#buttons | DesignSystem — Buttons & Aktionen}\n */\nexport type ButtonVariant = 'primary' | 'outline' | 'ghost' | 'danger';\n\n/**\n * Runtime representation of the finite Button variant contract.\n * Keep this list as the single source for Storybook controls and iteration.\n */\nexport const BUTTON_VARIANTS = [\n 'primary',\n 'outline',\n 'ghost',\n 'danger',\n] as const satisfies readonly ButtonVariant[];\n\n/**\n * @description A FontAwesome Classic icon name in its Regular form (e.g.\n * `fa-plus`). Button and IconButton resolve the matching Solid weight\n * internally and cross-fade between the two on hover/active; consumers must\n * not pass a pre-resolved weight and must supply a name that has both a\n * Regular and a Solid glyph available.\n */\nexport type ButtonIcon = `fa-${string}`;\n\n/**\n * @description Visible content that gives a `Button` its accessible name.\n * Excludes `boolean`, `null` and `undefined` so a `Button` can never be\n * rendered without real, visible label content.\n */\nexport type ButtonContent = Exclude<ReactNode, boolean | null | undefined>;\n\n/**\n * @description Props for a visible-label native action button. Renders a\n * native `<button>` and forwards all remaining native button props, events,\n * `className` and `ref`.\n */\nexport interface ButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'children'> {\n /**\n * @description Visual emphasis that communicates the action's role within\n * its action scope. At most one `primary` action should exist per closed\n * action scope (page, card, dialog, drawer, form, wizard step, or closed\n * accordion content).\n */\n variant: ButtonVariant;\n\n /**\n * @description Optional leading FontAwesome Classic icon name. Always\n * rendered before `children`; there is no trailing-icon or icon-only mode\n * on `Button` itself — use `IconButton` for an icon-only action.\n */\n icon?: ButtonIcon;\n\n /**\n * @description Visible, non-empty content used as the button label. Loading\n * state, polymorphism (rendering as something other than a native button)\n * and navigation are explicitly not part of the Milestone 1 API.\n */\n children: ButtonContent;\n}\n"],"mappings":";;;;;AAcA,IAAa,kBAAkB;CAC7B;CACA;CACA;CACA;AACF"}
1
+ {"version":3,"file":"Button.types.js","names":[],"sources":["../../../src/components/button/Button.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from 'react';\n\n/**\n * @description Supported visual emphasis levels for {@link ButtonProps} and\n * `IconButtonProps`. Milestone 1 supports exactly these four values; there is\n * no default variant and no fifth value.\n * @see {@link https://tappqa.tobit.com/Bodywork/DesignSystem/#buttons | DesignSystem — Buttons & Aktionen}\n */\nexport type ButtonVariant = 'primary' | 'outline' | 'ghost' | 'danger';\n\n/**\n * Runtime representation of the finite Button variant contract.\n * Keep this list as the single source for Storybook controls and iteration.\n */\nexport const BUTTON_VARIANTS = [\n 'primary',\n 'outline',\n 'ghost',\n 'danger',\n] as const satisfies readonly ButtonVariant[];\n\n/**\n * @description A FontAwesome Classic icon name (e.g. `fa-plus`) or a\n * FontAwesome Brands icon including its style prefix (e.g. `fab fa-github`).\n * Classic icons resolve the matching Regular and Solid weights internally;\n * Brands icons are rendered as a single icon and must not be combined with\n * `far` or `fas`.\n */\nexport type ButtonIcon = `fa-${string}` | `fab fa-${string}`;\n\n/**\n * @description Visible content that gives a `Button` its accessible name.\n * Excludes `boolean`, `null` and `undefined` so a `Button` can never be\n * rendered without real, visible label content.\n */\nexport type ButtonContent = Exclude<ReactNode, boolean | null | undefined>;\n\n/**\n * @description Props for a visible-label native action button. Renders a\n * native `<button>` and forwards all remaining native button props, events,\n * `className` and `ref`.\n */\nexport interface ButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'children'> {\n /**\n * @description Visual emphasis that communicates the action's role within\n * its action scope. At most one `primary` action should exist per closed\n * action scope (page, card, dialog, drawer, form, wizard step, or closed\n * accordion content).\n */\n variant: ButtonVariant;\n\n /**\n * @description Optional leading FontAwesome Classic or Brands icon name.\n * Always rendered before `children`; there is no trailing-icon or icon-only\n * mode on `Button` itself — use `IconButton` for an icon-only action.\n */\n icon?: ButtonIcon;\n\n /**\n * @description Visible, non-empty content used as the button label. Loading\n * state, polymorphism (rendering as something other than a native button)\n * and navigation are explicitly not part of the Milestone 1 API.\n */\n children: ButtonContent;\n}\n"],"mappings":";;;;;AAcA,IAAa,kBAAkB;CAC7B;CACA;CACA;CACA;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/button/button-icon/ButtonIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEvE,UAAU,eAAe;IACvB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,QAAA,MAAM,UAAU,GAAI,UAAU,eAAe,gCAS5C,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ButtonIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/button/button-icon/ButtonIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEvE,UAAU,eAAe;IACvB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,QAAA,MAAM,UAAU,GAAI,UAAU,eAAe,gCAqB5C,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -1,16 +1,22 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  //#region src/components/button/button-icon/ButtonIcon.tsx
3
- var ButtonIcon = ({ icon }) => /* @__PURE__ */ jsxs("span", {
4
- "aria-hidden": "true",
5
- className: "chayns-button-icon",
6
- children: [/* @__PURE__ */ jsx("span", {
7
- className: "chayns-button-icon__weight",
8
- children: /* @__PURE__ */ jsx("i", { className: `far ${icon}` })
9
- }), /* @__PURE__ */ jsx("span", {
10
- className: "chayns-button-icon__weight chayns-button-icon__weight--active",
11
- children: /* @__PURE__ */ jsx("i", { className: `fas ${icon}` })
12
- })]
13
- });
3
+ var ButtonIcon = ({ icon }) => {
4
+ const isBrandIcon = icon.startsWith("fab ");
5
+ return /* @__PURE__ */ jsx("span", {
6
+ "aria-hidden": "true",
7
+ className: "chayns-button-icon",
8
+ children: isBrandIcon ? /* @__PURE__ */ jsx("span", {
9
+ className: "chayns-button-icon__weight",
10
+ children: /* @__PURE__ */ jsx("i", { className: icon })
11
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
12
+ className: "chayns-button-icon__weight",
13
+ children: /* @__PURE__ */ jsx("i", { className: `far ${icon}` })
14
+ }), /* @__PURE__ */ jsx("span", {
15
+ className: "chayns-button-icon__weight chayns-button-icon__weight--active",
16
+ children: /* @__PURE__ */ jsx("i", { className: `fas ${icon}` })
17
+ })] })
18
+ });
19
+ };
14
20
  //#endregion
15
21
  export { ButtonIcon as default };
16
22
 
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonIcon.js","names":[],"sources":["../../../../src/components/button/button-icon/ButtonIcon.tsx"],"sourcesContent":["import type { ButtonIcon as ButtonIconName } from '../Button.types.js';\n\ninterface ButtonIconProps {\n icon: ButtonIconName;\n}\n\nconst ButtonIcon = ({ icon }: ButtonIconProps) => (\n <span aria-hidden=\"true\" className=\"chayns-button-icon\">\n <span className=\"chayns-button-icon__weight\">\n <i className={`far ${icon}`} />\n </span>\n <span className=\"chayns-button-icon__weight chayns-button-icon__weight--active\">\n <i className={`fas ${icon}`} />\n </span>\n </span>\n);\n\nexport default ButtonIcon;\n"],"mappings":";;AAMA,IAAM,cAAc,EAAE,WACpB,qBAAC,QAAD;CAAM,eAAY;CAAO,WAAU;CAAnC,UAAA,CACE,oBAAC,QAAD;EAAM,WAAU;EACd,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;CAC1B,CAAA,GACN,oBAAC,QAAD;EAAM,WAAU;EACd,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;CAC1B,CAAA,CACF"}
1
+ {"version":3,"file":"ButtonIcon.js","names":[],"sources":["../../../../src/components/button/button-icon/ButtonIcon.tsx"],"sourcesContent":["import type { ButtonIcon as ButtonIconName } from '../Button.types.js';\n\ninterface ButtonIconProps {\n icon: ButtonIconName;\n}\n\nconst ButtonIcon = ({ icon }: ButtonIconProps) => {\n const isBrandIcon = icon.startsWith('fab ');\n\n return (\n <span aria-hidden=\"true\" className=\"chayns-button-icon\">\n {isBrandIcon ? (\n <span className=\"chayns-button-icon__weight\">\n <i className={icon} />\n </span>\n ) : (\n <>\n <span className=\"chayns-button-icon__weight\">\n <i className={`far ${icon}`} />\n </span>\n <span className=\"chayns-button-icon__weight chayns-button-icon__weight--active\">\n <i className={`fas ${icon}`} />\n </span>\n </>\n )}\n </span>\n );\n};\n\nexport default ButtonIcon;\n"],"mappings":";;AAMA,IAAM,cAAc,EAAE,WAA4B;CAChD,MAAM,cAAc,KAAK,WAAW,MAAM;CAE1C,OACE,oBAAC,QAAD;EAAM,eAAY;EAAO,WAAU;EAChC,UAAA,cACC,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAAC,KAAD,EAAG,WAAW,KAAO,CAAA;EACjB,CAAA,IAEN,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;EAC1B,CAAA,GACN,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;EAC1B,CAAA,CACN,EAAA,CAAA;CAEA,CAAA;AAEV"}
@@ -1,13 +1,13 @@
1
1
  import { ComboBoxContext, getOptionLabel, useComboBoxContext } from "./ComboBoxContext.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { Children, Fragment, forwardRef, isValidElement, useEffect, useId, useMemo, useRef, useState } from "react";
3
+ import { Children, Fragment as Fragment$1, forwardRef, isValidElement, useEffect, useId, useMemo, useRef, useState } from "react";
4
4
  //#region src/components/combo-box/ComboBox.tsx
5
5
  function getOptionElements(children) {
6
6
  const options = [];
7
7
  Children.forEach(children, (child) => {
8
8
  if (!isValidElement(child)) return;
9
9
  const element = child;
10
- if (element.type === Fragment) options.push(...getOptionElements(element.props.children));
10
+ if (element.type === Fragment$1) options.push(...getOptionElements(element.props.children));
11
11
  else if (typeof element.props.value === "string") options.push(element);
12
12
  });
13
13
  return options;
@@ -1 +1 @@
1
- {"version":3,"file":"ComboBox.js","names":[],"sources":["../../../src/components/combo-box/ComboBox.tsx"],"sourcesContent":["import {\n Children,\n forwardRef,\n Fragment,\n isValidElement,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { ComboBoxContext, getOptionLabel, useComboBoxContext } from './ComboBoxContext.js';\nimport type { ComboBoxOptionProps, ComboBoxProps } from './ComboBox.types.js';\n\nfunction getOptionElements(children: ComboBoxProps['children']) {\n const options: ReactElement<ComboBoxOptionProps>[] = [];\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n return;\n }\n\n const element = child as ReactElement<{ children?: ReactNode; value?: string }>;\n\n if (element.type === Fragment) {\n options.push(...getOptionElements(element.props.children));\n } else if (typeof element.props.value === 'string') {\n options.push(element as ReactElement<ComboBoxOptionProps>);\n }\n });\n\n return options;\n}\n\nconst Option = forwardRef<HTMLDivElement, ComboBoxOptionProps>(function Option(\n { children, className, value, ...optionProps },\n ref,\n) {\n const comboBox = useComboBoxContext();\n const isVisible = comboBox.visibleValues.includes(value);\n const isSelected = comboBox.isSelected(value);\n const resolvedClassName = [\n 'chayns-combo-box__option',\n isSelected ? 'chayns-combo-box__option--selected' : '',\n comboBox.activeValue === value ? 'chayns-combo-box__option--active' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <div\n {...optionProps}\n aria-selected={isSelected}\n className={resolvedClassName}\n id={comboBox.optionId(value)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => comboBox.select(value)}\n ref={ref}\n role=\"option\"\n >\n {comboBox.multiple ? (\n <span\n aria-hidden=\"true\"\n className=\"chayns-combo-box__checkbox\"\n data-checked={isSelected || undefined}\n />\n ) : null}\n {children}\n </div>\n );\n});\n\nconst ComboBoxRoot = forwardRef<HTMLInputElement, ComboBoxProps>(function ComboBoxRoot(props, ref) {\n const {\n 'aria-label': ariaLabel,\n children,\n className,\n defaultValue,\n disabled,\n id,\n multiple = false,\n onValueChange,\n openOnFocus = true,\n placeholder,\n value,\n ...inputProps\n } = props;\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const listboxId = `${inputId}-listbox`;\n const rootRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const optionElements = useMemo(() => getOptionElements(children), [children]);\n const optionMap = useMemo(\n () => new Map(optionElements.map((option) => [option.props.value, option])),\n [optionElements],\n );\n const defaultValues = multiple\n ? ((defaultValue as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const controlledValues = multiple\n ? ((value as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const [uncontrolledValue, setUncontrolledValue] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [uncontrolledValues, setUncontrolledValues] = useState(defaultValues);\n const [inputText, setInputText] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [open, setOpen] = useState(false);\n const [activeValue, setActiveValue] = useState<string>();\n const isControlled = value !== undefined;\n const selectedValue = multiple ? '' : isControlled ? (value as string) : uncontrolledValue;\n const selectedValues = multiple ? (isControlled ? controlledValues : uncontrolledValues) : [];\n const normalizedFilter = inputText.trim().toLocaleLowerCase();\n const visibleValues = optionElements\n .filter((option) => {\n const label = getOptionLabel(option.props.children).toLocaleLowerCase();\n return normalizedFilter === '' || label.includes(normalizedFilter);\n })\n .map((option) => option.props.value);\n\n useEffect(() => {\n if (open && activeValue === undefined) {\n setActiveValue(visibleValues[0]);\n }\n }, [activeValue, open, visibleValues]);\n\n useEffect(() => {\n if (!open) {\n return undefined;\n }\n\n function closeOnOutsidePress(event: PointerEvent) {\n if (event.target instanceof Node && !rootRef.current?.contains(event.target)) {\n commitInput();\n setOpen(false);\n }\n }\n\n document.addEventListener('pointerdown', closeOnOutsidePress);\n return () => document.removeEventListener('pointerdown', closeOnOutsidePress);\n });\n\n function setInputElement(element: HTMLInputElement | null) {\n inputRef.current = element;\n\n if (typeof ref === 'function') {\n ref(element);\n } else if (ref !== null) {\n ref.current = element;\n }\n }\n\n function emitValue(nextValue: string) {\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n\n (onValueChange as ((next: string) => void) | undefined)?.(nextValue);\n }\n\n function emitValues(nextValues: string[]) {\n if (!isControlled) {\n setUncontrolledValues(nextValues);\n }\n\n const nextOptions = nextValues\n .map((nextValue) => optionMap.get(nextValue))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n (onValueChange as ((next: ReactElement<ComboBoxOptionProps>[]) => void) | undefined)?.(\n nextOptions,\n );\n }\n\n function commitInput() {\n if (!multiple && inputText !== selectedValue) {\n emitValue(inputText);\n }\n }\n\n function select(nextValue: string) {\n if (multiple) {\n const nextValues = selectedValues.includes(nextValue)\n ? selectedValues.filter((selected) => selected !== nextValue)\n : [...selectedValues, nextValue];\n emitValues(nextValues);\n setInputText('');\n setActiveValue(undefined);\n setOpen(true);\n return;\n }\n\n const option = optionMap.get(nextValue);\n emitValue(nextValue);\n setInputText(option === undefined ? nextValue : getOptionLabel(option.props.children));\n setActiveValue(undefined);\n setOpen(false);\n }\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n setInputText(event.target.value);\n setActiveValue(undefined);\n setOpen(true);\n props.onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n props.onBlur?.(event);\n if (!rootRef.current?.contains(event.relatedTarget)) {\n commitInput();\n setOpen(false);\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n const currentIndex = activeValue === undefined ? -1 : visibleValues.indexOf(activeValue);\n let nextIndex = currentIndex;\n\n if (event.key === 'ArrowDown') nextIndex = Math.min(currentIndex + 1, visibleValues.length - 1);\n if (event.key === 'ArrowUp') nextIndex = Math.max(currentIndex - 1, 0);\n if (event.key === 'Home') nextIndex = 0;\n if (event.key === 'End') nextIndex = visibleValues.length - 1;\n\n if (nextIndex !== currentIndex && visibleValues[nextIndex] !== undefined) {\n event.preventDefault();\n setActiveValue(visibleValues[nextIndex]);\n setOpen(true);\n } else if (event.key === 'Enter' && activeValue !== undefined) {\n event.preventDefault();\n select(activeValue);\n } else if (event.key === 'Escape') {\n event.preventDefault();\n setInputText(multiple ? '' : selectedValue);\n setActiveValue(undefined);\n setOpen(false);\n }\n\n props.onKeyDown?.(event);\n }\n\n const resolvedClassName = ['chayns-combo-box', open ? 'chayns-combo-box--open' : '']\n .filter(Boolean)\n .join(' ');\n const describedLabel = placeholder === undefined ? undefined : `${inputId}-label`;\n const selectedOptions = selectedValues\n .map((selected) => optionMap.get(selected))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n const inputClassName = ['chayns-combo-box__input', className].filter(Boolean).join(' ');\n\n return (\n <ComboBoxContext.Provider\n value={{\n activeValue,\n close: () => setOpen(false),\n inputText,\n isSelected: (optionValue) =>\n multiple ? selectedValues.includes(optionValue) : selectedValue === optionValue,\n multiple,\n optionId: (optionValue) => `${listboxId}-${optionValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`,\n select,\n visibleValues,\n }}\n >\n <div className={resolvedClassName} ref={rootRef}>\n {multiple ? (\n <div className=\"chayns-combo-box__chips\" aria-hidden=\"true\">\n {selectedOptions.map((option) => (\n <span className=\"chayns-combo-box__chip\" key={option.props.value}>\n {option.props.children}\n </span>\n ))}\n </div>\n ) : null}\n <input\n {...inputProps}\n aria-activedescendant={\n open && activeValue\n ? `${listboxId}-${activeValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel}\n className={inputClassName}\n disabled={disabled}\n id={inputId}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={() => openOnFocus && setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder === undefined ? undefined : ' '}\n ref={setInputElement}\n role=\"combobox\"\n value={inputText}\n />\n {placeholder !== undefined ? (\n <label className=\"chayns-combo-box__label\" htmlFor={inputId} id={describedLabel}>\n {placeholder}\n </label>\n ) : null}\n {open ? (\n <div\n aria-multiselectable={multiple || undefined}\n className=\"chayns-combo-box__popup\"\n id={listboxId}\n role=\"listbox\"\n >\n {children}\n </div>\n ) : null}\n </div>\n </ComboBoxContext.Provider>\n );\n});\n\nconst ComboBox = Object.assign(ComboBoxRoot, { Option });\n\nexport default ComboBox;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ComboBox.js","names":[],"sources":["../../../src/components/combo-box/ComboBox.tsx"],"sourcesContent":["import {\n Children,\n forwardRef,\n Fragment,\n isValidElement,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, ReactNode } from 'react';\n\nimport { ComboBoxContext, getOptionLabel, useComboBoxContext } from './ComboBoxContext.js';\nimport type { ComboBoxOptionProps, ComboBoxProps } from './ComboBox.types.js';\n\nfunction getOptionElements(children: ComboBoxProps['children']) {\n const options: ReactElement<ComboBoxOptionProps>[] = [];\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n return;\n }\n\n const element = child as ReactElement<{ children?: ReactNode; value?: string }>;\n\n if (element.type === Fragment) {\n options.push(...getOptionElements(element.props.children));\n } else if (typeof element.props.value === 'string') {\n options.push(element as ReactElement<ComboBoxOptionProps>);\n }\n });\n\n return options;\n}\n\nconst Option = forwardRef<HTMLDivElement, ComboBoxOptionProps>(function Option(\n { children, className, value, ...optionProps },\n ref,\n) {\n const comboBox = useComboBoxContext();\n const isVisible = comboBox.visibleValues.includes(value);\n const isSelected = comboBox.isSelected(value);\n const resolvedClassName = [\n 'chayns-combo-box__option',\n isSelected ? 'chayns-combo-box__option--selected' : '',\n comboBox.activeValue === value ? 'chayns-combo-box__option--active' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <div\n {...optionProps}\n aria-selected={isSelected}\n className={resolvedClassName}\n id={comboBox.optionId(value)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => comboBox.select(value)}\n ref={ref}\n role=\"option\"\n >\n {comboBox.multiple ? (\n <span\n aria-hidden=\"true\"\n className=\"chayns-combo-box__checkbox\"\n data-checked={isSelected || undefined}\n />\n ) : null}\n {children}\n </div>\n );\n});\n\nconst ComboBoxRoot = forwardRef<HTMLInputElement, ComboBoxProps>(function ComboBoxRoot(props, ref) {\n const {\n 'aria-label': ariaLabel,\n children,\n className,\n defaultValue,\n disabled,\n id,\n multiple = false,\n onValueChange,\n openOnFocus = true,\n placeholder,\n value,\n ...inputProps\n } = props;\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const listboxId = `${inputId}-listbox`;\n const rootRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const optionElements = useMemo(() => getOptionElements(children), [children]);\n const optionMap = useMemo(\n () => new Map(optionElements.map((option) => [option.props.value, option])),\n [optionElements],\n );\n const defaultValues = multiple\n ? ((defaultValue as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const controlledValues = multiple\n ? ((value as ReactElement<ComboBoxOptionProps>[] | undefined)?.map(\n (option) => option.props.value,\n ) ?? [])\n : [];\n const [uncontrolledValue, setUncontrolledValue] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [uncontrolledValues, setUncontrolledValues] = useState(defaultValues);\n const [inputText, setInputText] = useState(\n multiple ? '' : ((defaultValue as string | undefined) ?? ''),\n );\n const [open, setOpen] = useState(false);\n const [activeValue, setActiveValue] = useState<string>();\n const isControlled = value !== undefined;\n const selectedValue = multiple ? '' : isControlled ? (value as string) : uncontrolledValue;\n const selectedValues = multiple ? (isControlled ? controlledValues : uncontrolledValues) : [];\n const normalizedFilter = inputText.trim().toLocaleLowerCase();\n const visibleValues = optionElements\n .filter((option) => {\n const label = getOptionLabel(option.props.children).toLocaleLowerCase();\n return normalizedFilter === '' || label.includes(normalizedFilter);\n })\n .map((option) => option.props.value);\n\n useEffect(() => {\n if (open && activeValue === undefined) {\n setActiveValue(visibleValues[0]);\n }\n }, [activeValue, open, visibleValues]);\n\n useEffect(() => {\n if (!open) {\n return undefined;\n }\n\n function closeOnOutsidePress(event: PointerEvent) {\n if (event.target instanceof Node && !rootRef.current?.contains(event.target)) {\n commitInput();\n setOpen(false);\n }\n }\n\n document.addEventListener('pointerdown', closeOnOutsidePress);\n return () => document.removeEventListener('pointerdown', closeOnOutsidePress);\n });\n\n function setInputElement(element: HTMLInputElement | null) {\n inputRef.current = element;\n\n if (typeof ref === 'function') {\n ref(element);\n } else if (ref !== null) {\n ref.current = element;\n }\n }\n\n function emitValue(nextValue: string) {\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n\n (onValueChange as ((next: string) => void) | undefined)?.(nextValue);\n }\n\n function emitValues(nextValues: string[]) {\n if (!isControlled) {\n setUncontrolledValues(nextValues);\n }\n\n const nextOptions = nextValues\n .map((nextValue) => optionMap.get(nextValue))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n (onValueChange as ((next: ReactElement<ComboBoxOptionProps>[]) => void) | undefined)?.(\n nextOptions,\n );\n }\n\n function commitInput() {\n if (!multiple && inputText !== selectedValue) {\n emitValue(inputText);\n }\n }\n\n function select(nextValue: string) {\n if (multiple) {\n const nextValues = selectedValues.includes(nextValue)\n ? selectedValues.filter((selected) => selected !== nextValue)\n : [...selectedValues, nextValue];\n emitValues(nextValues);\n setInputText('');\n setActiveValue(undefined);\n setOpen(true);\n return;\n }\n\n const option = optionMap.get(nextValue);\n emitValue(nextValue);\n setInputText(option === undefined ? nextValue : getOptionLabel(option.props.children));\n setActiveValue(undefined);\n setOpen(false);\n }\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n setInputText(event.target.value);\n setActiveValue(undefined);\n setOpen(true);\n props.onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n props.onBlur?.(event);\n if (!rootRef.current?.contains(event.relatedTarget)) {\n commitInput();\n setOpen(false);\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n const currentIndex = activeValue === undefined ? -1 : visibleValues.indexOf(activeValue);\n let nextIndex = currentIndex;\n\n if (event.key === 'ArrowDown') nextIndex = Math.min(currentIndex + 1, visibleValues.length - 1);\n if (event.key === 'ArrowUp') nextIndex = Math.max(currentIndex - 1, 0);\n if (event.key === 'Home') nextIndex = 0;\n if (event.key === 'End') nextIndex = visibleValues.length - 1;\n\n if (nextIndex !== currentIndex && visibleValues[nextIndex] !== undefined) {\n event.preventDefault();\n setActiveValue(visibleValues[nextIndex]);\n setOpen(true);\n } else if (event.key === 'Enter' && activeValue !== undefined) {\n event.preventDefault();\n select(activeValue);\n } else if (event.key === 'Escape') {\n event.preventDefault();\n setInputText(multiple ? '' : selectedValue);\n setActiveValue(undefined);\n setOpen(false);\n }\n\n props.onKeyDown?.(event);\n }\n\n const resolvedClassName = ['chayns-combo-box', open ? 'chayns-combo-box--open' : '']\n .filter(Boolean)\n .join(' ');\n const describedLabel = placeholder === undefined ? undefined : `${inputId}-label`;\n const selectedOptions = selectedValues\n .map((selected) => optionMap.get(selected))\n .filter((option): option is ReactElement<ComboBoxOptionProps> => option !== undefined);\n const inputClassName = ['chayns-combo-box__input', className].filter(Boolean).join(' ');\n\n return (\n <ComboBoxContext.Provider\n value={{\n activeValue,\n close: () => setOpen(false),\n inputText,\n isSelected: (optionValue) =>\n multiple ? selectedValues.includes(optionValue) : selectedValue === optionValue,\n multiple,\n optionId: (optionValue) => `${listboxId}-${optionValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`,\n select,\n visibleValues,\n }}\n >\n <div className={resolvedClassName} ref={rootRef}>\n {multiple ? (\n <div className=\"chayns-combo-box__chips\" aria-hidden=\"true\">\n {selectedOptions.map((option) => (\n <span className=\"chayns-combo-box__chip\" key={option.props.value}>\n {option.props.children}\n </span>\n ))}\n </div>\n ) : null}\n <input\n {...inputProps}\n aria-activedescendant={\n open && activeValue\n ? `${listboxId}-${activeValue.replace(/[^a-zA-Z0-9_-]/g, '-')}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel}\n className={inputClassName}\n disabled={disabled}\n id={inputId}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={() => openOnFocus && setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder === undefined ? undefined : ' '}\n ref={setInputElement}\n role=\"combobox\"\n value={inputText}\n />\n {placeholder !== undefined ? (\n <label className=\"chayns-combo-box__label\" htmlFor={inputId} id={describedLabel}>\n {placeholder}\n </label>\n ) : null}\n {open ? (\n <div\n aria-multiselectable={multiple || undefined}\n className=\"chayns-combo-box__popup\"\n id={listboxId}\n role=\"listbox\"\n >\n {children}\n </div>\n ) : null}\n </div>\n </ComboBoxContext.Provider>\n );\n});\n\nconst ComboBox = Object.assign(ComboBoxRoot, { Option });\n\nexport default ComboBox;\n"],"mappings":"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"}
@@ -27,9 +27,10 @@ interface IconButtonBaseProps extends Omit<ComponentPropsWithRef<'button'>, 'ari
27
27
  */
28
28
  variant: ButtonVariant;
29
29
  /**
30
- * @description Required FontAwesome Classic icon name rendered Regular at
31
- * rest and Solid on hover/active. `IconButton` has no visible label, so
32
- * this is its only visible content.
30
+ * @description Required FontAwesome Classic or Brands icon name. Classic
31
+ * icons render Regular at rest and Solid on hover/active; Brands icons
32
+ * render without Classic weight classes. `IconButton` has no visible label,
33
+ * so this is its only visible content.
33
34
  */
34
35
  icon: ButtonIcon;
35
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.types.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;;GAIG;AACH,KAAK,wBAAwB,GACzB;IACE;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,GACD;IACE,YAAY,CAAC,EAAE,KAAK,CAAC;IAErB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,UAAU,mBAAoB,SAAQ,IAAI,CACxC,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,YAAY,GAAG,iBAAiB,GAAG,UAAU,CAC9C;IACC;;;OAGG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,wBAAwB,CAAC"}
1
+ {"version":3,"file":"IconButton.types.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;;GAIG;AACH,KAAK,wBAAwB,GACzB;IACE;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,GACD;IACE,YAAY,CAAC,EAAE,KAAK,CAAC;IAErB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,UAAU,mBAAoB,SAAQ,IAAI,CACxC,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,YAAY,GAAG,iBAAiB,GAAG,UAAU,CAC9C;IACC;;;OAGG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;;OAKG;IACH,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,wBAAwB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chayns-ui/core",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Accessible React core components for chayns UI",
5
5
  "license": "MIT",
6
6
  "type": "module",